I've made an introductory article about Haskell - help me improve it?

Hi everyone!

I am currently in the process of (re)learning Haskell, after taking considerable break from doing FP.

I thought that it will be a good exercise for me to write some introductory articles. I am doing them mostly to accelerate my learning, but hopefully they will server others as well.

I am however no Haskell expert, I have intermediate knowledge at best, so I would like to show this article to you first, before promoting it anywhere.

Perhaps someone could help me proofread it. I would be interested in catching errors, misconceptions as well as finding places where things could be explained in a cleaner manner, especially since I am not an English native.

Anyways here it is - https://mpodlasin.com/articles/haskell-i

Very curious to hear your thoughts. Thanks! :pray:

7 Likes

Looks like a really nice article so far!

One thing that I would point out is that if in Haskell is not a statement, but an expression. This is an important distinction, as expressions evaluate to values, whereas statements do not. For instance, I can’t write the following in python:

return if x:
  False
else:
  True

This is invalid specifically because that’s an if statement, rather than a if expression. Python does have an expression form as well:

return False if x else True

1 Like

“The main point of this series will be to highlight the differences between Haskell and those “typical” languages that I’ve mentioned.”

This is important. Some introductions to Haskell try to start from nothing. That doesn’t make a lot of sense to me. Most people coming to Haskell probably know more than one programming language already. Why not leverage that?

As with natural languages, new programming languages are most easily learned by studying the differences. This is why it’s pretty easy to learn Italian if you know Spanish and vice versa, while learning Japanese if you’re coming from English will be hard. Having learned a fair amount of Japanese as a native English speaker (in classrooms where the Koreans zoomed right past me – they had that language-similarity advantage), learning Haskell – which I’m still doing – has a lot of the same feeling. It’s just very different. I learned maybe a dozen programming languages before I learned Erlang. Erlang is also pretty different, and sort of a struggle. But not too bad. Haskell feels well beyond even Erlang in foreign-ness. Tell people early and often: if you feel like your intuitions are failing you, it’s because they are. The intuitive is the familiar. Haskell is very unfamiliar. Haskell is from another planet. It’s only natural that you’re having trouble.

Some suggestions (from not yet reading to the end, mind you)

VS Code – I tried to get started with this on Windows 10, to get a nicer Haskell debugging environment, but it broke mysteriously. After struggling for a while, I had an intuition (from past hard experience). I checked how the interface handles embedded blanks in file paths. Yep, it doesn’t handle those correctly. I was starting from my user account, which is my name, which has a space between “Michael” and “Turner”. Knowing this in advance could save some people a few hours getting started.

instance” – a term that’s different enough in Haskell that I think some explanation of the error message is in order. Here is a good place to say what an instance is in Haskell. After all, in most programming languages, instances are actual chunks of data of some type – instantiated from class definitions with ‘constructors’ (another problematic difference in terminology.) In Haskell, they are something that “arises” (a pretty unfortunate choice of verb, if you ask me.) You don’t have to go into great detail. You just have to say something like, “If you bonked on ‘instance’, you’re not alone. What it means here is . . .”

General comments:

I got impatient with Learning a Haskell for Great Good because it’s so chatty. Too chatty by half. I’m all in favor of friendly introductions to programming languages. You’re very close to the right tone. But I think you could cut your wordcount by 10-15% and make it even more readable and approachable than it already is. Bonus: this gives you more breathing room to go into those all-important differences.

2 Likes

@Yakushima @sullyj3 - thank you very much for your comments!

I will improve the current article over the weekend, according to your suggestions.

@Yakushima I will keep in mind your general comments when writing the next articles.

Thanks!

1 Like

Yes, it looks good.

As an observation, it assumes that you are using Linux / MacOS. Many beginners use Windows. That can be confusing.

1 Like

@FrancisKing that’s a great point.

I will try to get my hands on a Windows machine and test how installation looks there. :+1:

It is gentle :smiley:

1) “This shows that, indeed, we assigned the value True to the variable x.” (followed by the error message you get with “Multiple declarations of ‘x’.”)
Don’t know if you intend to explain (later in the series) what it means for Haskell to be lazy in terms of the evaluation strategy? If you do, it might be beneficial to say that you are not really assigning a value to a variable but that the left-hand side of the expression is simply giving a name to the right-hand side. (The compiler is complaining that you first said that you gave one expression a certain name and later a different expression the same name … so which is it? Make up your mind! Names have to be unique.)

2) instead of parenthesis
In 3 places you wrote “parenthesis” where you meant 2 of them. Plural, which is “parentheses”.

3) data MyBool = MyTrue | MyFalse deriving (Show)
This is a valid declaration of course, but I would suggest swapping MyFalse and MyTrue. If the values of a datatype have some natural order to them, it is best to enumerate them that way. People might want to automatically derive Ord … and then things can get confusing. Suppose you define Peano numbers like this:

data Peano = Succ Peano | Zero deriving (Eq, Ord, Show)

Then Succ Zero < Zero would be True. Probably not what people would expect :wink:

1 Like

Hey. A bit of time has passed.

I finally motivated myself to do a followup article - https://mpodlasin.com/articles/haskell-ii

I don’t want to spam the forum, so I will be posting all the new episodes of the “series” here.

The article is still not “officially” published, I struggled a bit with some sections, but I will not say anything and just let you judge it (or use it) on its own merits. :slight_smile:

Thank you very much for all the reactions and comments on the previous one :pray: The feedback and support were invaluable and really helped me going forward. :raised_hands:

2 Likes

Really nice exposition!

Some grammar nitpicks and typos:
“Not only Haskell has” -> something like “not only does Haskell have”

“Let’s on the part” - missing a word, I’m assuming “focus”

1 Like

Couple of typos/suggestions:

  • Indeed, you can do the reverse, and call the + operator …
  • Let’s focus on the part that is outside of the parentheses first:
  • We can however check the type of the add 5 expression and this way convince ourselves that this indeed works:
  • Earlier you said “we can use the fact that -> is right-associative”, maybe also mention explicitly that function application is left-associative? [Near here “(add 5) 7”?]
  • “To further emphasize how all of this works, let’s just add that you can store the result of such “partial application” in a variable.” Personally I never think of ‘storing in a variable’ but ‘naming an expression’. And then later, when explaining lazy evaluation, going from call-by-value to call-by-reference to call-by-name (with sharing) there is an intuition to latch onto.
  • After that you can use the configuredImaginaryFunction directly, without the need to carry that config object explicitly everywhere! [Because it will be carried implicitly.]
  • And in the future article, … [“a future article” or “the next article”?]

HTH

1 Like

@sullyj3 @arpl I incorporated your fixes, thanks!

@arpl I especially loved the comments about mentioning left-associativity explicitly and about not using the phrase “storing in variable”. I incorporated both of those. :pray:

2 Likes