Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Yeah, as the author implied: languages you don't know are hard to read. Let's just pause for a moment and reflect on how Haskell is also beat up over this, but as one twitter user recently pointed out[0], we pretend that stuff like this:

    concatMap :: [a] -> (a -> [b]) -> [b]
is somehow less readable and "harder to learn" than common expressions in more mainstream languages where we see absolutely inscrutable equivalent constructions:

    SelectMany<TSource,TCollection,TResult> IEnumerable<TSource>, Func<TSource,IEnumerable<TCollection>>, Func<TSource,TCollection,TResult>)

The sin of these languages is not that they're hard to read, it's that you're irritated with unicode syntax. But languages that support dense constructs will always need to appeal to symbolic artifice to not end up being totally unreadable strings of useless syllables, as above.

You might argue in the Pythonic tradition that such code shouldn't be allowed to exist. But that's a bit of a lie from Python. They just want to push it up and up the library chain to where someone anointed as "sufficiently smart" eventually just has to write a dozen lines to do the same thing we could have taught everyone to do with the conveniences of notation that lean on natural language.

[0]: https://twitter.com/MxLambda/status/1147150220876308480



The latter looks gross, but has something the former doesnt: words and names. Even if it's verbose and ugly, I can at least puzzle it out just based on the information at hand (I can figure out that <> is similar to (), and Enumerable/Select/Func/Collection/Result are all words I can figure out). I wouldn't be able to write that expression without knowing the language, but, I can read it, even if it's gross. It's also much easier to lookup. I can google IEnumerable a lot more easily than "what is -> after ::".

The haskell version on the other hand is undeniably more elegant, but if I don't know those symbols I'm ENTIRELY lost. There's nothing about :: that means anything to me if I don't look it up. Likewise -> only implies... a transform of some sort? And [a] might mean a list, or, it might mean optional, or it might mean... lots of things.

To be clear, I like the haskell version better, but it is more opaque to a beginner.


> Even if it's verbose and ugly, I can at least puzzle it out just based on the information at hand (I can figure out that <> is similar to ()

But you can't make similar inferences about [] and ->? I mean... it's an arrow. People generally get what arrows imply about processes, right? Most kids are exposed to a flow chart somewhere in their lives.

> Enumerable/Select/Func/Collection/Result are all words I can figure out

Only because of extensive exposure to a world where that works. And I submit SOME of those words are quite sketchy. For example, what exactly is a "Select" and what on earth does "Result" mean on this? Why do we need such a special type? And what's the semantics significance of "T" vs "I"?

I think you're ignoring what you know. In terms of the number of symbols at play that you'd need to know, the Haskell is more familiar because you need far fewer symbols AND fewer words AND it actually constrains the implementation much less!

> There's nothing about :: that means anything to me if I don't look it up.

But you can just work out what <> means? Especially given that this code could easily be in one of 3 languages that all have significantly different semantics for <>?

> Likewise -> only implies... a transform of some sort? nd [a] might mean a list, or, it might mean optional, or it might mean... lots of things.

That's probably a less opaque concept than "IEnumerable".

> To be clear, I like the haskell version better, but it is more opaque to a beginner.

This fictive beginner who doesn't know what a function is but naturally can work out what "Select", "Func" and "Enumerable" are is a very strange story to me. If you're expecting me to just accept this person exists, I'm afraid I'm going to disappoint you by saying it sounds unlikely.


> But you can't make similar inferences about [] and ->?

Words are WAY less ambiguous. -> means pointer dereference, or function call, or an associative mapping in other languages I know. [] is often an indexer, or an indication of a fixed allocation, or an indicator in documentation that a value is optional...

Both of those symbols have very overloaded meanings.

> For example, what exactly is a "Select" and what on earth does "Result" mean on this?

I mean, Result is pretty straightforward. Especially in the context of "Func" which is already there. Select is a common phrase used in, well, english, but also sql, smalltalk, C#, ruby ... and a bunch of others. If I know any of those it's a pretty big hint. It's also a common word for anyone that uses computers. If I say "select a group of files" you know that I mean, grab some files based on some criteria. If I tell you to concat map a group of files, you would probably have no idea what the hell I'm talking about.

> But you can just work out what <> means?

It's roughly the same shape as () and [] and I already know it from html.

> That's probably a less opaque concept than "IEnumerable".

Subjective really. Enumerable means a thing that can be numbered. That's pretty unambiguous. [a] in unix docs often means "optional". Or it's an indexer. Or it's.. it's used in a lot of different ways.

> This fictive beginner who doesn't know what a function is but naturally can work out what "Select", "Func" and "Enumerable" are is a very strange creature to me.

To most programmers, a function looks like:

f(a,b,c)

The alternative:

a -> b -> c

Is REALLY unfamiliar to most programmers that have never been exposed to a functional language like haskell or F# (which is to say, most programmers). Select and enumerable are commonly used vocabulary (well, maybe the former more than the latter, but enumerable is an easy word to lookup). Func is a very common abbrev.

I've read some intro to haskell docs, and even I don't remember what :: means. There's nothing implicitly about :: that means anything at all. In C++ it's a namespace separator. In other languages it apparently just gets used because a single ":" just doesn't quite get the point across well enough.


> I mean, Result is pretty straightforward. Especially in the context of "Func" which is already there. Select is a common phrase used in, well, english, but also sql, smalltalk, C#, ruby ... and a bunch of others. If I know any of those it's a pretty big hint.

> It's roughly the same shape as () and [] and I already know it from html.

The entire point of this is that folks who are educated in a language forget how much they had to learn to render a piece of code obvious, instead appealing to "simplicity" and imaginary beginners.

I think these quotes demonstrate that's how you're thinking here too.


My point, which you seem to be avoiding, is that words are a lot less ambiguous than symbols.

EDIT for additional point: also, since your examples are haskell and C#, let me point out that reality seems to agree with me here, since C# is vastly more popular than haskell. If you're learning something, learning something with less ambiguity is usually easier. Considering that F# is similar(ish) to haskell and has the full power of the .NET platform and is still vastly less popular than C#, I think it's clear which option people think is easier. Easy may not be better, but that's a separate discussion.


> My point, which you seem to be avoiding, is that words are a lot less ambiguous than symbols.

Sorry, I don't accept this and you haven't demonstrated it except to say "well we can use an appeal to other things for words, but not for symbols." That really dosn't fly at all, for me.

> let me point out that reality seems to agree with me here, since C# is vastly more popular than haskell. If you're learning something, learning something with less ambiguity is usually easier.

This isn't actually an argument. It's a hope.

Besides, many of the folks in industry learned to program in other languages than the ones they use today in industry, but not languages that didn't exist at all.

> Considering that F# is similar(ish) to haskell and has the full power of the .NET platform and is still vastly less popular than C#,

Imagine, if you please, a world where people in industry and on Hacker News repea an untrue mantra that one language is "simpler" from first principles, confusing familiarity with simplicity? In such a world, educators would look to what the industry demands and feel that in good faith, they should give those languages some treatment in courses over time. We might also see these universities (under pressure from an increasingly competitive market for the bulk of undergrad education), start to set aside time-tested teaching languages and regretfully move to courseware that prepares people for these industry jobs.

I feel like maybe my story matches reality at least as well as yours. It also explains why a simpleton like me might be able to learn these supposedly unapproachable languages like Forth, Lisp, F# and Haskell without appealing to me being a genius.


> > My point, which you seem to be avoiding, is that words are a lot less ambiguous than symbols.

> Sorry, I don't accept this and you haven't demonstrated it except to say "well we can use an appeal to other things for words, but not for symbols." That really dosn't fly at all, for me.

Nobody is a blank slate. When we learn things we associate with what we already know. The power of symbols is that they are inherently abstract and are not associated with what we previously knew, but when we're learning things that makes symbols harder to understand, not easier. "Sum" is a lot clearer than "Σ" if you're starting out. Quick, what do you think this means?

    {↑1 ⍵∨.∧3 4=+/,¯1 0 1∘.⊖¯1 0 1∘.⌽⊂⍵}
(That's an actual program, btw, I didn't mash my keyboard). If you don't know any of those symbols, where would you even START?

But wait, let me make it easier on you:

    life←{↑1 ⍵∨.∧3 4=+/,¯1 0 1∘.⊖¯1 0 1∘.⌽⊂⍵}
Now what do you think it means? Does it give you a place to start, at least? (That's the APL version of the game of life)

That version of the game of life is much simpler than if I were to write it in C#, which would be hundreds of lines longer. But is it easier? Of course not. It's absolutely baffling.

> Imagine, if you please, a world where people in industry and on Hacker News repea an untrue mantra that one language is "simpler" from first principles, confusing familiarity with simplicity?

Simple and easy are not the same things. Familiar IS easier, even if it's not simpler. I can imagine that world, but I also live in this world, where people have a current set of knowledge and it's easier to bridge the gap between what they don't know and what they do know by using what they already know.


Sure you know what `sum` means, and maybe even what `product` means.

`sum` is applying `add` repeatedly to a list. `product` is applying `multiply` repeatedly to a list.

The thing is most people use `+` instead of `add`.

Also why use two different things for `add` and `sum`?

How about we use `+` for both `add` and `sum`, since they are basically the same thing:

    1 + 2 + 3
    [+] 1, 2, 3
While we are at it, let's make it so you can also do the same for `multiply` and `product`:

    1 * 2 * 3
    [*] 1, 2, 3
Or perhaps even make it so that you can use any associative infix operator:

    1 ** 2 ** 3
    [**] 1, 2, 3

    1 < 2 < 3
    [<] 1, 2, 3

    (1,2) ⊆ (1,2,3) ⊆ (1,2,3,4,5)
    [⊆] (1,2), (1,2,3), (1,2,3,4,5)

    0 || 0e0 || Nil || 1
    [||] 0, 0e0, Nil, 1
I'm sure you know what exponentiation means, but do you know what word you would use to mean repeatedly applying it to a list? (If you know please tell me, because I sure don't.)

---

After you learn what `sum` means, you still have to learn what `product` means.

However once you learn that you can put any associative infix operator between `[]` and have it apply to a list, you've just learned one thing that is really both of the above, and also many more things.

This makes it quick to learn Perl6. You learn about one thing in one place, and that knowledge applies to everything everywhere. (This is true about almost every feature of Perl6.)

---

If you really don't like the syntax, you don't have to use it.

    # alias the `+` infix operator to a subroutine named `add`
    my &add = &infix:<+>;

    reduce( &add, 1, 2, 3 );
---

I would like to point out that this higher-order feature is basically the same one that allows `+=`.

    my $a = 1;
    $a += 2;
That is because `=` is a meta operator. Meaning it can take an infix operator as a sort-of argument.

    sub infix:<IOP> ( $l, $r ){
        $l + $r
    }

    my $a = 1;
    $a IOP= 2;


    $a *= 1;
    $a /= 2;
    $a max= 10;
I just taught you a second thing that you can now use for most infix operators.

What's more, is that you might have figured out that infix operators are just subroutines with a special name. I didn't even really mean to teach you that.

---

I mean sure a novice is more likely to know what `sum` means. But they have only to read this comment to learn a much larger chunk of Perl6.

Frankly I want newcomers to Perl6 to be confused about `[+]`, because then they are more likely to come to a place where I can quickly teach them everything above.

(Teach a man to fish and he eats for a lifetime. Teach a man to use a net and he can feed his family.)


> {↑1 ⍵∨.∧3 4=+/,¯1 0 1∘.⊖¯1 0 1∘.⌽⊂⍵}

This is such a contrived argument. Firstly, I'd argue that it's only because of extensive exposure to a C#-ish language that you have a mental dictionary capable of fully describing IEnumerable. To most novices, both this and my prior example would be equally impermeable.

> Now what do you think it means? Does it give you a place to start, at least? (That's the APL version of the game of life)

I actually do know this program. It's part of Conway's Game of Life in APL. I know this not because I know APL, but because I copied part of the code into Google. Which is how most folks these days solve programming problems anyways.

And once I know that, I can type "APL ↑ documentation" and tada, I found a wikipedia page! "Select the first (or last) A elements of B according to ×A"

Feels roughly about the same amount of effort as trying to coerce some meaning out of obscure Python library errors, if I'm honest.

> Simple and easy are not the same things.

Thanks for that. Why are you so eager to take the eas yway out?

> but I also live in this world, where people have a current set of knowledge and it's easier to bridge the gap between what they don't know and what they do know by using what they already know.

A world where you're actively discouraging anyone from learning anything new by writing hundreds of words on websites about how they shouldn't do it because it's simpler and not easier, for what it's worth.


>Sorry, I don't accept this and you haven't demonstrated it except to say "well we can use an appeal to other things for words, but not for symbols." That really dosn't fly at all, for me.

Words are easier to lookup than symbols. Symbols can be easy to reference when you know where to look, but unless you know what other words to stick into Google (especially if you don't know what language a particular snippet is), ":: programming" will be utterly useless, while searching IEnumerable will return results for C# immediately. When you are new to programming, the ease of finding relevant documentation can make things a lot less ambiguous.

>In such a world, educators would look to what the industry demands and feel that in good faith, they should give those languages some treatment in courses over time. We might also see these universities (under pressure from an increasingly competitive market for the bulk of undergrad education), start to set aside time-tested teaching languages and regretfully move to courseware that prepares people for these industry jobs.

You mean like Java? It's time-tested and the bulk of the developer positions in my area want Java experience. Coincidentally, it's also a common language to teach in undergrad. I've only seen functional languages listed by companies that list every language under the sun, and research positions.


> Words are easier to lookup than symbols. Symbols can be easy to reference when you know where to look, but unless you know what other words to stick into Google (especially if you don't know what language a particular snippet is), ":: programming" will be utterly useless, while searching IEnumerable will return results for C# immediately. When you are new to programming, the ease of finding relevant documentation can make things a lot less ambiguous

Weird because the other poster posted an APL snippet and I worked it out with a search engine without content.

> You mean like Java? It's time-tested and the bulk of the developer positions in my area want Java experience. Coincidentally, it's also a common language to teach in undergrad. I've only seen functional languages listed by companies that list every language under the sun, and research positions

I was there when Java started appearing in Universities. They didn't choose it because it was easier than scheme. They chose it in hopes of making it easier for graduates to find work with employers increasingly not giving a shit about training and graduates increasingly being reluctant when askedd to learn new things outside of school.


It's a trade-off, though: Compactness and visual variety can help readability. There's a reason why symbolic math notation won out, and why the most regular and/or verbal languages (eg Lisp, Cobol) haven't won over everyone's hearts and minds.


> I can google IEnumerable a lot more easily than "what is -> after ::"

That's not really a fair comparison. You're comparing an identifier in one language with the basic syntax of the other. The correct comparison would be whether : {} <> [] , ++ ; & * and other syntax structures of the C-like counterpart are more easily searchable or understandable than those of Haskell, which I don't think is the case.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: