First 24 hours with Elm

Late last night (or very early morning), I began learning Elm. A few days ago I read The Syntax Cliff and got persuaded to learn Elm. After a few hours I began to document questions I had while learning.

My main motivation, for learning Elm, is to learn how to structure Functional JS in larger projects. My attempts so far has quickly turned into an organized mess.

While I have only written down “pain points” and confusion, I want to assure you all, that I’m thrilled to be here and that, overall, learning Elm is a very pleasant experience. I hit a bump the last few hours. The issue, I found out, was a simple Bool value that I got wrong. But without being able to use Debug.log for Bool value and added my confusion with learning a new language, it took me 4 hours to solve!

My notes are in the README in my dotnetcarpenter/elmtut repository, along with all the code I wrote and copied from guide.elm-lang.org. So far (Day 1) I have read until the Forms chapter.

If anyone, who are working on making Elm more accessible, has any questions, I am happy to answer them here or in the repository issue list. I will keep a close eye on the list and here, the next few days.

I hope this can shed some light on how Elm is for a completely new comer to the language.

14 Likes

Your Questions are very interesting.

Here are some answers:

  • True |> Debug.log "My Bool Value"

    returns True and prints My Bool Value: True to the console

  • when using lambda expressions, you need to wrap them in brackets:
    list |> List.map (\x -> 2 * x).
    Else the parser reads the line like this:
    list |> (List.map) (\x) (->) (2 * x) and gets confused.
    This does not only happen for lambda expressions but for let in, case of and if then else. ( I hope I haven’t forgotten something)

If you have some questions, please feel free to ask them here on discourse. We love to help.

1 Like

The bootstrap code var app = Elm.Main.init({ node: document.getElementById("elm") }) is mentioned in guide at JavaScript Interop chapter, which is quite late.

2 Likes

Thank you.

Just so I understand you Debug.log answer. If I want to log the result of a function called no with 2 arguments, I can insert no pw Char.isAlphaNum |> Debug.log "no pw Char.isAlphaNum" where no pw Char.isAlphaNum is suppose to be and get the same result as if there was no Debug.log and still get printed no pw Char.isAlphaNum: True to the devtools console.

But if I try to debug several calls to no in OR expressions, then the compiler will not allow it.

weakPassword : String -> Bool
weakPassword pw =
  no pw Char.isLower |> Debug.log "no pw Char.isLower"
  || no pw Char.isUpper |> Debug.log "no pw Char.isUpper"
  || no pw Char.isDigit |> Debug.log "no pw Char.isDigit"

Ok. I have to set parenthesis around expressions, like so:

weakPassword pw =
  (no pw Char.isLower |> Debug.log "no pw Char.isLower")
  || (no pw Char.isUpper |> Debug.log "no pw Char.isUpper")
  || no pw Char.isDigit |> Debug.log "no pw Char.isDigit"
2 Likes

Yes, you are right. I might have gotten ahead of myself. I would not have considered trying to figure it out, had it not been because I was surprised by the size of the framework and that elm make --optimize did nothing measurable to shrink the size. I am still not sure that I have not done something wrong in my optimization setup but it almost looks like a bug. Why else would the Elm compiler output functions called something like _Utils_Tuple2_UNUSED and not just remove them?

when using lambda expressions, you need to wrap them in brackets:

Thank you for clarifying. I did try to wrap the lambda expression but today, I tried the same thing and I can not for the life in me reproduce the errors I got yesterday. Perhaps I was tired…

@lydell gave me the same advice on the elm/error-message-catalog bug tracker.

Thank you all for responding to all my questions. The Elm community feels like a warm and good place to be :slight_smile:

This community is so nice!
@pdamoc created an issue Regarding the Dead Code Elimination and pointed me to https://dev.to/skinney/improving-elm-s-compiler-output-5e1h

I feel that no question goes unanswered here! This is the first community where I have felt so attended to.

A big THANK YOU

9 Likes
  1. elm CLI does not have tab completion for commands or flags

If you use an sh derived shell, see https://github.com/dmy/elm-sh-completion.

Normal anchor (hash) links does not work in the Guide. While headings do have IDs, the following https://guide.elm-lang.org/types/reading_types.html#type-annotations does not scroll to <h2 id="type-annotations">Type Annotations</h2> . I think it is because Elm apps are dynamic rendered and the browser can not scroll to an element that does not exist yet. A scrollTo function might be considered…

Most elm-lang web sites are Elm apps, but the guide uses gitbook, also dynamically rendered though. Other elm-lang web sites implemented in Elm do have indeed a scrollTo function most of the time, for example this scrollIfNeeded.

2 Likes

Thanks for posting here. I think that as a new comer, your impression and experience is super valuable.

I did find it surprising and a little implausible that the compiler wasnt eliminating dead code. Maybe the elm compiler doesnt eliminate unused code from core, such as the tuple functions in your readme example?

I just checked in my own project to verify that dead code elimination was working:

  • I added an unused value called xyz and compiled my code, and sure enough, it was not in the compiled JS.
  • In my project, I am using elm-css, but I know I am not using the float function from it. Sure enough, there were plenty of values from elm-css, but no instance of float.
2 Likes

Yes, that is exactly what is happening. @pdamoc explains it very well here: https://github.com/dotnetCarpenter/elmtut/issues/1#issue-608064913

Thank you! I’ve added it to my bash completion and it works perfectly. :smiley:

1 Like

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.