DEV Community

Kristian Pedersen
Kristian Pedersen

Posted on

#30daysofelm Day 26: Debug.log, Debug.toString and the REPL

This is day 26 of my 30 day Elm challenge

Today I learned how to test my functions in the REPL, instead of logging them with Debug.log or displaying them in the view function with text (myVariable |> Debug.toString).

My project is just a new directory where I've entered elm init and created a src/Main.elm file.

The REPL can be launched from the project root if there's an elm.json file, by entering elm repl. Note how it says Say :help for help and :exit to exit! More at https://elm-lang.org/0.19.1/repl.

CTRL+C didn't work on my Mac, but :exit did.

1. Debug.log: Like console.log(), but only in the browser

This one had me confused at first. In JavaScript, you can just put console.log() wherever you want.

In Elm, Debug.log has to be within a let block (edit: not accurate - see comments). Most code I've seen just refer to it with an underscore _ since its value isn't important (does it even have a value?):

rangeEcho =
    List.range 1 5
        |> List.map
            (\n ->
                let
                    _ = Debug.log "The number is: " n
                in
                n
            )
Enter fullscreen mode Exit fullscreen mode

The lonely n is there because we have to return something.

Interestingly, the numbers come out backwards! I'd love to know why this is.

Keep in mind, this only displays in the browser dev tools, not in the terminal.

2. text (variableOfAnyType |> Debug.toString)

The above function can also be displayed in the DOM, like this:

view = 
    text (rangeEcho |> Debug.toString)
-- [1,2,3,4,5]
Enter fullscreen mode Exit fullscreen mode

It's a bit nicer than Debug.log, but I've found the REPL to be the far most engaging and flexible experience.

3. My Main.elm code

If you're using VS Code with the Elm Tooling extension, it will probably add a line like this to the top:

module Main exposing (..)
Enter fullscreen mode Exit fullscreen mode

With this in place, you can test anything you want from your file, try passing it different parameters, or try combining functions.

Here's the file I was working on: https://ellie-app.com/c4cRdN4y4Pta1

4. Starting and using the REPL

  1. Open a terminal and enter elm repl in your project root. There has to be an elm.json file there.
  2. Enter import Main exposing (..) (or whatever your filename is)
  3. Now you can just type function names from your project.
  4. You can even modify or create new functions in Main.elm, and the REPL will automatically have access to them without needing to restart!

I gotta say, this is a much nicer way of working than what I've done up until now.

To learn more, here's the REPL documentation: https://github.com/elm/compiler/blob/master/hints/repl.md

5. Screenshot

Screenshot of code and REPL

First, you can see that test results in an error, but works after I've entered import Main exposing (..).

That last line with grid |> List.filter (\xy -> ...)) was particularly nice. Testing stuff interactively like this feels better than regular logging, although they all have their place, I suppose.

6. Conclusion

This was a fun thing to learn! I just wish I could get tab completion for Main.elm functions, not just for the ones that are created during the REPL runtime.

Happy logging, and see you tomorrow!

Top comments (2)

Collapse
 
wolfadex profile image
Wolfgang Schuster

In Elm, Debug.log has to be within a let block.

That's not accurate, though it is common. Debug.log has the type Debug.log : String -> a -> a which means it takes a String and anything and returns that last thing. This can be really handy with pipes as an example

myThing
    |> doSomething
    |> Debug.log "my modified thing"
    |> otherFunc
    |> Debug.log "after otherFunc change"
Enter fullscreen mode Exit fullscreen mode

This way you can log your thing between steps. Another example could be wanting to log the value being passed into a case .. of

case Debug.log "my value" someVal of
    ...
Enter fullscreen mode Exit fullscreen mode

Also kinda sad that this series is almost over!

Collapse
 
kristianpedersen profile image
Kristian Pedersen

Ah, thanks! As always, your input is highly appreciated!

It does feel weird that the 30 days are almost done. Maybe 30 weeks next? :D

I'm happy though - I can easily spend 10-15 minutes re-writing a paragraph, so it will be nice to have more energy to focus on code and projects. :)

Writing is a great tool for learning, so I wouldn't be surprised if I make more posts.