As I see it it’s actually not very nice.
With the utmost respect, truly, humbly: I am against this custom that it’s just fine to call well-meaning people for condescending. As it appears to me, claiming condescendence is more of a statement of the claimant, but this is still an unfortunate custom. Who are we really to claim condescension? Really?
The article linked to in the post starts off with quotes from people who directly state that they feel like they would need to be smarter to use Haskell. It’s a common thing. The article addresses that. It is literally the opposite of condescension.
Then there’s the burrito tutorials with pictures. I for one actually think in weird abstract sloppy metaphors and colors. My head really is full of burritos and inaccuracies. I was helped enormously by the burrito concept. Textbooks generally don’t speak in burritos. I work with people to whom the burrito class of analogies is not helpful. They think in a more direct and crystalline way. I wish I were more like them. And I try try to be. And I can. And it makes me better. And I really do think I also bring something to the table by spraying flaming burrito concepts and lateral jumps into the team zeitgeist.
OK fair enough, I can only speak for myself and the way I learn concepts. The way I learn a new language or platform is always to try to write a real program that does something. I am only able to lean concepts when I can see their usefulness. But I should recognize that other people learn in different ways.
Not such a bad life, if you ask me.
The only condescension I see in Haskell-related discussion is condescension towards Haskellers,
fwiw I've heard exactly the same claims by and about lispers.Could you perhaps link to one? I know of plenty of misguided tutorials that try to be helpful but aren't. I've never come across one I'd call "condescending".
> I can't recollect I have ever learned a programming concept through metaphors. The only way I have learned concepts is though solving tasks in a language and thereby learning to use the tools available.
Yet for some reason newcomers (reputedly) want to know what a monad is before trying to use one! I agree with you: they should go ahead and use one and not worry about what it is!
Ultimately most of these are just imitations of the 'poignant guide to ruby' which is probably responsible for starting the trend of whimsical and zany programming guides.
#include <stdio.h>
int main(int argc, char *argv[]) {
printf("Hello World!\n");
return 0;
}
class HelloWorld {
static public void main(String args[]) {
System.out.println("Hello World!");
}
}
main :: IO ()
main = print "hello world"
Hello worlds in C, Java and Haskell. I can write them and run them without needing to fully understand what's behind "*argv[]", "static public void" or "IO ()".This isn't actually true. You need to use a value of the `IO ()` type. Your program would still work if `IO` was not an instance of `Monad`. In a similar way, you also need to use a value of type `String` but you don't care that it implements `Read` or `Ord` or `Semigroup`.
This doesn't entirely invalidate the rest of what you've written - you do need some basic understanding of how to combine IO actions to do any more interesting IO.
But I feel like your presentation is still misleading. "Learn You A Haskell" starts with the REPL, and has you running code in the first tutorial.
I've taught some Java classes. I can get people writing and running trivially useful code before explaining the concepts of "class" and "static". I explain that parts of the code will remain a mystery for a little while until I explain them, I promise to do so, and of course I fulfill that promise as soon as I can.
I feel neither Java nor Haskell are intrinsically bad just because there's no practical way to teach them completely on progressively layered concepts. Even (e.g.) Lisp has a risk of using special forms before understanding them.
I guess I should write a Haskell tutorial which starts with "hello world" without trying to teach monads beforehand!
To write any program in Haskell, you define `main`, the IO action that does the work of your program. `putStrLn` is a function that takes a String and returns an IO action that prints the string.
So we can write "hello world" simply:
main = putStrLn "Hello, World"
I'm curious whether you actually think that's more useful than building understanding at the REPL.Again, I think this depends on you way of learning. For some people it might be possible to "build understanding" gradually over weeks until you are finally ready to write "hello world" having learnt all the fundamentals of the language. That just doesn't work for me. I need to learn through writing programs which actually does something.
You keep describing the alternative as if it's a bunch of theory before any practice. It's actually just a slightly different form of practice than maybe you are used to.
I am sympathetic to the notion that it might not work for you, but you haven't spoken at all to the actual distinction. If it really does make a big difference for you, I'm very interested in any unpacking you can do.
For example Rust is another language which have a reputation for being hard to learn, due to novel and complex concepts like the borrow checker. But in my experience you see none of this "talking down" to the audience. They just explain how the stuff works with practical examples.
It is not an accident that almost any tutorial for any language or framework or platform starts with "hello world". Because you want to start with the minimal but real, working program - and build from there.
In either case you are simply printing a string to the terminal. The standalone program is easier to compose in your shell, which in some contexts matters a lot, but I don't see that it does here. Where is the difference?
Further, if we define "interact with the outside world" in a way that excludes the programmer reading things off the screen, then it's plainly wrong that all such programs are "literally useless". Calculators, for instance, have delivered a tremendous amount of value. I've personally run something at a REPL (in various languages) plenty of times because I had actual use for the value to be printed and didn't need to persist the program.
"A complex system that works is invariably found to have evolved from a simple system that worked."
I understand that from a certain theoretical perspective it is just the same thing to echo a string literal in a REPL, but from a software development perspective it is completely different.
> The standalone program is easier to compose in your shell, which in some contexts matters a lot, but I don't see that it does here.
I kind of see where you are coming from. You are assuming the program is only ever used by yourself. I understand this is just a different culture and hadn't even thought about that perspective.
Not at all. Haskell has a REPL, so anything involving output is defined as pure functions, then executed at the REPL. For example, here's Quicksort: http://learnyouahaskell.com/recursion#quick-sort That's from Chapter 5.
> I certainly wouldn't be able to learn anything that way.
Certainly not by only reading the table of contents, sure.
For academics, the purpose of a program is to exhibit some clever abstraction. So a quicksort which can't take any input to sort and can't produce any output is a perfectly fine program - almost the platonic ideal of a program.
But for developers, the purpose of programs is to do something useful. So learning how to read input and produce output is basically the first thing I want to learn when learning a new language or platform. Because then I can start building small toy programs, gradually doing more and more stuff and learning by tackling the challenges along the way. And implementing quicksort comes way down the line of things I need to learn to write a useful application.
Chapter 9: Input and Output
Chapter 12: A Fistful of Monads
No, that doesn't seem to be the case to me.
> Yet for some reason newcomers (reputedly) want to know what a monad is before trying to use one! I agree with you: they should go ahead and use one and not worry about what it is!
It's probably condescending for haskellers because it shows that monads are not some enshrined primary concept but just a kind of dumb wrapper you can write in any language and you do when it's useful for you.
I get it though. The concepts are so advanced that you have to internalize the concept first before it can even be used.
I can't recollect I have ever learned a programming concept through metaphors. The only way I have learned concepts is though solving tasks in a language and thereby learning to use the tools available.
I actually think Haskell is a very enjoyable language, but there is a culture around it which treats the type concepts (arrows, monads etc.) like goals in themselves rather than tools to achieve something useful.