Discussion:
[elm-discuss] Why `let`?
Akio Burns
2017-04-14 20:00:30 UTC
Permalink
It's not clear to me why Elm uses `let`, instead of simply scoping
definitions to the expression below them.


With `let`:

foo =
let
a = 1
b = 2
in
a + b

Scoping definitions to the expression below them:

foo =
a = 1
b = 2

a + b


I understand that each function must contain a single expression. In Elm,
although they contain expressions, definitions are not expressions.


Visualized:

foo =
<EXPRESSION HERE>

foo =
a + 2 <- EXPRESSION

foo =
a = 1 <- DEFINITION SCOPED TO THE a + 2 EXPRESSION
a + 2


Another way to demonstrate scope is:

let
a = 1
b = 2
in
a + b

would become (parenthesis to demonstrate scope):

(
a = 1
b = 2

a + b
)


It seems to me that `let` and `in` are unnecessary and verbose. Put another
way, I think few people would agree that requiring a keyword before
variable assignment `set a = 1` would be a good idea. The `=` makes the
intent explicit. Likewise, indentation—or parenthesis—could make scopes
explicit, and `let` and `in` unnecessary.

Some have argued that without `let`, we could not have arbitrarily nested
scopes. I don't have significant experience with Elm, but I would guess
that nesting `let`s today is pretty big code smell. Instead of nesting
`let`s to reuse variable names, developers should either pick more
descriptive variable names, or abstract into a function.


This could—of course—apply anywhere an expression is expected:

True ->
x = 0
y = 0

(x, y)
...


@rtfeldman on the Slack pointed out that this syntax is more diff friendly:

if I write a view function like
view model =
div []
[ ... lots of other stuff ]

and then I want to introduce a nested constant like so:
view model =
let
foo = ...
in
div []
[ ... lots of other stuff ]

the fact that I indented the final expression makes the VCS diff explode
this happens to me all the time, and it's pretty annoying
with [this] idea it wouldn't happen anymore


Lastly, here's elm-todomvc with scoped definitions, courtesy of @rtfeldman
again:

https://github.com/rtfeldman/elm-todomvc/blob/8678c8bcaeb5cb4b3f87dbefb7a01b5fe492dbc7/Todo.elm
--
You received this message because you are subscribed to the Google Groups "Elm Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elm-discuss+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Noah Hall
2017-04-22 20:23:49 UTC
Permalink
Two notes:

Let bindings do not have order. Using them in the way suggested
implies order. In this world, they would have to be ordered or
confusion would reign. This is more imperative style.

I've actually really disliked this in CoffeeScript/Ruby, that
implicitly the last item in the block is the thing returned. Makes it
a lot harder to parse mentally.

-1.
Post by Akio Burns
It's not clear to me why Elm uses `let`, instead of simply scoping
definitions to the expression below them.
foo =
let
a = 1
b = 2
in
a + b
foo =
a = 1
b = 2
a + b
I understand that each function must contain a single expression. In Elm,
although they contain expressions, definitions are not expressions.
foo =
<EXPRESSION HERE>
foo =
a + 2 <- EXPRESSION
foo =
a = 1 <- DEFINITION SCOPED TO THE a + 2 EXPRESSION
a + 2
let
a = 1
b = 2
in
a + b
(
a = 1
b = 2
a + b
)
It seems to me that `let` and `in` are unnecessary and verbose. Put another
way, I think few people would agree that requiring a keyword before variable
assignment `set a = 1` would be a good idea. The `=` makes the intent
explicit. Likewise, indentation—or parenthesis—could make scopes explicit,
and `let` and `in` unnecessary.
Some have argued that without `let`, we could not have arbitrarily nested
scopes. I don't have significant experience with Elm, but I would guess that
nesting `let`s today is pretty big code smell. Instead of nesting `let`s to
reuse variable names, developers should either pick more descriptive
variable names, or abstract into a function.
True ->
x = 0
y = 0
(x, y)
...
if I write a view function like
view model =
div []
[ ... lots of other stuff ]
view model =
let
foo = ...
in
div []
[ ... lots of other stuff ]
the fact that I indented the final expression makes the VCS diff explode
this happens to me all the time, and it's pretty annoying
with [this] idea it wouldn't happen anymore
https://github.com/rtfeldman/elm-todomvc/blob/8678c8bcaeb5cb4b3f87dbefb7a01b5fe492dbc7/Todo.elm
--
You received this message because you are subscribed to the Google Groups
"Elm Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an
For more options, visit https://groups.google.com/d/optout.
--
You received this message because you are subscribed to the Google Groups "Elm Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elm-discuss+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Witold Szczerba
2017-04-23 00:23:14 UTC
Permalink
I would agree with Noah Hall, the let/in keywords make parsing easier. In a
simple expression like you provided:
a = 5
b = 6
a + b
it's all clear, but in real code things are much more complicated and
confusing. I have looked at the Todo.elm you prepared and (for me) it is
much harder to reason about.

Regards,
Witold Szczerba
Post by Noah Hall
Let bindings do not have order. Using them in the way suggested
implies order. In this world, they would have to be ordered or
confusion would reign. This is more imperative style.
I've actually really disliked this in CoffeeScript/Ruby, that
implicitly the last item in the block is the thing returned. Makes it
a lot harder to parse mentally.
-1.
Post by Akio Burns
It's not clear to me why Elm uses `let`, instead of simply scoping
definitions to the expression below them.
foo =
let
a = 1
b = 2
in
a + b
foo =
a = 1
b = 2
a + b
I understand that each function must contain a single expression. In Elm,
although they contain expressions, definitions are not expressions.
foo =
<EXPRESSION HERE>
foo =
a + 2 <- EXPRESSION
foo =
a = 1 <- DEFINITION SCOPED TO THE a + 2 EXPRESSION
a + 2
let
a = 1
b = 2
in
a + b
(
a = 1
b = 2
a + b
)
It seems to me that `let` and `in` are unnecessary and verbose. Put
another
Post by Akio Burns
way, I think few people would agree that requiring a keyword before
variable
Post by Akio Burns
assignment `set a = 1` would be a good idea. The `=` makes the intent
explicit. Likewise, indentation—or parenthesis—could make scopes
explicit,
Post by Akio Burns
and `let` and `in` unnecessary.
Some have argued that without `let`, we could not have arbitrarily nested
scopes. I don't have significant experience with Elm, but I would guess
that
Post by Akio Burns
nesting `let`s today is pretty big code smell. Instead of nesting `let`s
to
Post by Akio Burns
reuse variable names, developers should either pick more descriptive
variable names, or abstract into a function.
True ->
x = 0
y = 0
(x, y)
...
@rtfeldman on the Slack pointed out that this syntax is more diff
if I write a view function like
view model =
div []
[ ... lots of other stuff ]
view model =
let
foo = ...
in
div []
[ ... lots of other stuff ]
the fact that I indented the final expression makes the VCS diff explode
this happens to me all the time, and it's pretty annoying
with [this] idea it wouldn't happen anymore
Lastly, here's elm-todomvc with scoped definitions, courtesy of
@rtfeldman
Post by Akio Burns
https://github.com/rtfeldman/elm-todomvc/blob/
8678c8bcaeb5cb4b3f87dbefb7a01b5fe492dbc7/Todo.elm
Post by Akio Burns
--
You received this message because you are subscribed to the Google Groups
"Elm Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an
For more options, visit https://groups.google.com/d/optout.
--
You received this message because you are subscribed to the Google Groups
"Elm Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an
For more options, visit https://groups.google.com/d/optout.
--
You received this message because you are subscribed to the Google Groups "Elm Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elm-discuss+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Jan Tojnar
2017-04-23 09:17:24 UTC
Permalink
in real code things are much more complicated and confusing. I have looked
at the Todo.elm you prepared and (for me) it is much harder to reason about.
I agree, it is especially confusing once we get to *destructing*:

https://github.com/rtfeldman/elm-todomvc/blob/8678c8bcaeb5cb4b3f87dbefb7a01b5fe492dbc7/Todo.elm#L44

let – in allows quick visual distinction between definitions and the main
statement.

Cheers,

Jan Tojnar
--
You received this message because you are subscribed to the Google Groups "Elm Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elm-discuss+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Tom Ayerst
2017-04-23 09:34:22 UTC
Permalink
"where" would be nice though...

foo a b =
x + y
where
x = a
y = b
Post by Akio Burns
in real code things are much more complicated and confusing. I have
looked at the Todo.elm you prepared and (for me) it is much harder to
reason about.
https://github.com/rtfeldman/elm-todomvc/blob/
8678c8bcaeb5cb4b3f87dbefb7a01b5fe492dbc7/Todo.elm#L44
let – in allows quick visual distinction between definitions and the main
statement.
Cheers,
Jan Tojnar
--
You received this message because you are subscribed to the Google Groups
"Elm Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an
For more options, visit https://groups.google.com/d/optout.
--
You received this message because you are subscribed to the Google Groups "Elm Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elm-discuss+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Wojciech S. Czarnecki
2017-04-23 10:22:09 UTC
Permalink
Dnia 2017-04-23, o godz. 10:34:22
Post by Tom Ayerst
"where" would be nice though...
foo a b =
x + y
where
x = a
y = b
Most people read from top to bottom not otherwise.

So let - in gives information in proper order:

Let -- using this
saw, plane, hammer, nails, two boards, two planks
in -- do that
make bookshelf

https://github.com/elm-lang/elm-compiler/issues/621
https://groups.google.com/forum/?fromgroups=#!topic/elm-discuss/KiKF6K9gBKU

:)
--
Wojciech S. Czarnecki
^oo^ OHIR-RIPE
--
You received this message because you are subscribed to the Google Groups "Elm Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elm-discuss+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Loading...