google / haskell-trainings

Haskell 101 and 102: slides and codelabs

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Need a better example for immutability

xnning opened this issue · comments

In slide 7 in Haskell 101, it uses the following example to show immutability:

let a = 3
in a = a + 1

I think we need a better example than this one. Because of the following reasons:

(1) This is syntactically wrong. And the syntactic failure has nothing to do with immutability. We can, for example, rewrite it to

let a = 3
in b = c + 1

and it just fails.

(2) We can, actually, slightly revise the example to:

let a = 3
in let a = 4
in a + 1

This works. But this is, of course, related to shadowing rather than immutability. Then this example is quite confusing.

(3) We can, actually, further revise the example to:

let a = 3
in let a = a + 1
in a + 1

This works. But it just loops forever, because in the definition a = a + 1, the a being defined is brought into the scope of a + 1. So it just recurs forever. Again, this example is being confusing.

I do not mind better examples, but the thinking that went into this particular case is as follows.
I assume that people are not familiar with Haskell syntax and are familiar with the C-like syntax.
There is a need to show some code. And most people will not be able to remember all the examples anyways.

So, based on the above, this slide got a fictional expression that is indeed an invalid syntax, but looks like something someone with experience with C-like syntax might try to write.
The fact that it is invalid Haskell, I think, does not matter that much yet.

I totally support better examples, but I do not think that any of the code snippets you proposed are better. And it seems you are also not saying they are better. Unless I am missing your points. For every code snippet you proposed you are also saying "This works, but ..." and then comes a downside.

So, I am a bit confusing as to the intent here. Do you think that all 3 proposed versions are better than what we currently have? Or are you just trying to start a discussion?

We can augment the slide to make it more obvious that this is an invalid syntax. There is a comment that says so, but maybe it is not enough.

On a related topic, what I have noticed is that a lot of people are confused by the in keyword. Exactly because the are so used to the C-like patterns of variable assignment.
It would be nice to add more focus to the fact that in is required and introduces a nested scope. Maybe with some background colors, or some "animation" - we can show and hide this keyword and talk a bit about the fact that it is required.

Oh, my 3 examples are not what I think are better. Instead, they are the reasons why I think the original example is not good enough.
The first example just indicates the original example is syntactically wrong, which means the original example has nothing to do with immutability -- we all agree on this.
The second and the third example are variants of the original code sample that the user might try and find confusing. Because the original example is syntactically wrong, the user might want to fix it by correct the syntax and then it leads to these 2 variants. Then they find these 2 variants type-checks! And (2) even works! Then they might get confused because it seems the variable is still "mutable". And (3) hangs forever -- but they have no idea why.

Maybe this is just a mild issue. After all this is Haskell 101 so we don't want to go so deep in this topic anyway. I do like the idea that "this is C-like syntax and please notice this doesn't work in Haskell". Since I don't have a better suggestion in the example so probably let's live with it as it is :).

How about displaying these two examples side by side?

main = do
  let a = 3
  let a = 5
  print a
main = do
  let a = 3
  let a = 2 * a
  print a

This illustrates C syntax, doesn't use the in keyword (though this is implicit because of do notation). I think this shows better that the only way to reassign to a name is to shadow the old one (can even add more examples) as the second example just prints <<loop>> when compiled

While it is a fact that the example is syntactically wrong, the way we can look at it is quite different.
I do not think it is bad. Consider that these slides are targeted at people who are seeing the syntax for the first time. And are expected to have experience with C-like languages.

There is nothing bad in showing something that people might try to write using intuition obtained from writing C++, Java, Python or JavaScript - this is the target audience.

I also do not think that anybody are going to pay this much attention to an example that is marked as been invalid syntax. Most people do not posses absolute memory, so this particular example will just fade away. It is there only for demonstration purposes. I would not expect people to try to correct it - most people (29 out of 30) do not even finish the codelab, should we not finish it in class. So only a very tiny fraction will try to fix an invalid example, and if they do - there are other learning materials to correct them.

I also do not think that introducing do syntax at this point makes sense. We do it at the end of 102 and it requires a lot more explanation. Otherwise, it is just confusing. Most people find it confusing they have to write in between let and the expression that uses the bindings. A second competing syntax will just be an overkill.

To be honest, this discussion seems to be targeted at solving a problem that I do not think exists. Nobody has complained or has been confused by this example so far.
Once again, I do not mind better examples, but I do not think this one is bad or has any issues. If you can provide a better example that would make more sense considering the assumptions I have outlined above or in my previous post I will be glad to support it. But I do not think it is worth spending time fixing it just because it is invalid syntax.