Earlier quoted context omitted.
What is so scary about monoid? A classical monoid is precisely a category with one object, hence the name. "Addable" and "Joinable" do not quite cut it - not all monoids are defined on numbers (or generalizations of them such as vectors or matrices) or sets (or generalizations of them such as categories or topological spaces).
Like I said, it's a scary term, because hearing the word "monoid" conveys exactly zilch about what it is, and it sounds strange and abstract. And like I said, the definition I gave is not a precise one, but it's an intuitive one. Once you have an intuitive understanding as a starting point, you can abstract to other things. This is just my opinion, of course.
Deconstructing Functional Programming [video]
71–80 of 116 posts
Re: Deconstructing Functional Programming [video]
#72Earlier quoted context omitted.
>The points he makes against obtuse names based in category theory are valid No, they aren't. When you have a class of "things" that doesn't have a name most people are familiar with, you are left with two options. Either choose a name people are familiar with, but which is wrong and misleading. Or choose the correct name and people have to learn a name. Are we seriously so pathetic as an industry that learning 3 new…
Part of his critique is that they do use terms that people are familiar with but which are misleading, like "return".
After all compilers don't compile, they translate.
Re: Deconstructing Functional Programming [video]
#73Earlier quoted context omitted.
Currying can obfuscate what is applied to what. Consider in any ML language "a b c d" – we can see that "a" is a function, but we have no idea of its arity. Uncurried, it could be: "a(b, c, d)", "a(b, c)(d)", "a(b)(c, d)", "a(b)(c)(d)" (oh, that's the curried form again). Especially when function definitions are implied through pattern matching, it is hard to understand the contract of a function at a glance. As a re…
> more of a criticism of ML syntax than of currying – all things are good in moderation. I don't follow this. My understanding is that currying is pure syntactic sugar: it's a cheap way to expression partial application. What am I missing?
Re: Deconstructing Functional Programming [video]
#74In his talk on currying, he mentioned replying on type system to not be a good thing. Does anyone know the reasons behind his view?
Currying can obfuscate what is applied to what. Consider in any ML language "a b c d" – we can see that "a" is a function, but we have no idea of its arity. Uncurried, it could be: "a(b, c, d)", "a(b, c)(d)", "a(b)(c, d)", "a(b)(c)(d)" (oh, that's the curried form again). Especially when function definitions are implied through pattern matching, it is hard to understand the contract of a function at a glance. As a re…
Bracha's critique, as usual, is missing the point.
Re: Deconstructing Functional Programming [video]
#75Earlier quoted context omitted.
It's actually simpler in some ways, because we know that "a" must have arity 1. What we know is that "a" should be a function which takes a "b", that "a b" should be a function which takes a "c", and "a b c" should take a "d". As a practical consideration, this rarely if ever becomes an issue, and if it does, the type checker will tell you straight away. Type annotations can make clear what isn't intuitively clear wi…
The argument that every function has arity 1 is technically true (this is the whole point of currying) but is not useful when definitions like "let a b c = ..." suggest other semantics. It's possible you've had a difference experience with this, but I tend to get confused when the semantic argument list isn't delimited. There is nothing wrong with relying on the type checker, except that it tends to add cognitive ove…
It's very natural, and as Lisp/Scheme/Racket shows, it's perfectly fine in a dynamically typed context as well.
Re: Deconstructing Functional Programming [video]
#76Earlier quoted context omitted.
To an extent, I think it's a valid criticism. There are two main problems with the mathy names that many concepts in Haskell have. The first is that they hide the meaning. For example, "Monoid" is a really scary term, and explaining it further as "something with an identity and an associative operation" really doesn't help much either. Calling it instead "Addable" or "Joinable", and explaining it instead as "things w…
You are using the exact reasoning I was talking about. Monoids are monoids. That is what they are. 99% of programmers are not familiar with them. If you call it "addable" or "joinable" or "appendable" then you are just making people think that one subset of some monoids is the definition of monoids when it isn't. They still don't know what monoids are, now they just also don't know what they are called. You are liter…
http://hackage.haskell.org/package/base-4.6.0.1/docs/Data-Mo...
Methods
mempty
mappend
mconcat
Haskell people like their mathy terms. Mathy terms aren't universally unambigious ("group"? "ring"? "field"?), but they are mostly unambiguous within math. Haskell people tend to pretend Haskell is the same as math, ignoring the programming part of its heritage.Re: Deconstructing Functional Programming [video]
#77Earlier quoted context omitted.
Currying can obfuscate what is applied to what. Consider in any ML language "a b c d" – we can see that "a" is a function, but we have no idea of its arity. Uncurried, it could be: "a(b, c, d)", "a(b, c)(d)", "a(b)(c, d)", "a(b)(c)(d)" (oh, that's the curried form again). Especially when function definitions are implied through pattern matching, it is hard to understand the contract of a function at a glance. As a re…
I'm not following you here. In ML-like languages a b c d is clearcut: it's means (((a b) c) d). No ambiguity whatsoever. Bracha's critique, as usual, is missing the point.
For some reason it seems parent post would like to specifically indicate the case where a function application results in a value that is specifically not a function? Seem quite strange to me.
Re: Deconstructing Functional Programming [video]
#78Interesting talk! Bracha has some good arguments against features that I generally enjoy in programming languages, like Damas–Hindley–Milner type inference and pattern matching. Regarding Haskell: The points he makes against obtuse names based in category theory are valid, but then again, Haskell has its roots in research programming languages. Math-based terminology makes more sense for an academic audience.
>The points he makes against obtuse names based in category theory are valid No, they aren't. When you have a class of "things" that doesn't have a name most people are familiar with, you are left with two options. Either choose a name people are familiar with, but which is wrong and misleading. Or choose the correct name and people have to learn a name. Are we seriously so pathetic as an industry that learning 3 new…
http://en.wikipedia.org/wiki/On_the_Cruelty_of_Really_Teachi...
http://www.cs.utexas.edu/users/EWD/transcriptions/EWD10xx/EW...
example:
"""My next linguistical suggestion is more rigorous. It is to fight the "if-this-guy-wants-to-talk-to-that-guy" syndrome: never refer to parts of programs or pieces of equipment in an anthropomorphic terminology, nor allow your students to do so. ..
I have now encountered programs wanting things, knowing things, expecting things, believing things, etc., and each time that gave rise to avoidable confusions."""
Re: Deconstructing Functional Programming [video]
#79- He claimed that tail recursion could be seen as the essence of functional programming. How so?
- He complained that tail recursion has problems with debugging. Well, tail recursion throws away stack information, so it should not be a surprise. You don't get better debug information in while loops either. And you can use a 'debug' flag to get the compiler to retain the debug information (at the cost of slower execution).
- His remarks about Hindley-Milner being bad are bizarre. Exactly what is his argument?
- His claims about pattern-matching are equally poor. Yes, pattern matching does some dynamic checks, and in some sense are similar to reflection. But the types constrain what you can do, removing large classes of error possibilities. Moreover, typing of patterns can give you compile-time exhaustiveness checks. Pattern matching has various other advantages, such as locally scoped names for subcomponents of the thing you are matching against, and compile-time optimisation of matching strategies.
- He also repeatedly made fun of Milner's "well-typed programs do not go wrong", implying that Milner's statement is obviously non-sense. Had he studied Milner's "A Theory of Type Polymorphism in Programming" where the statement originated, Bracha would have learned that Milner uses a particular understanding of going wrong which does not mean complete absence of any errors whatsoever. Milner uses a peculiar meaning, and in Milner's sense, well-typed programs do indeed not go wrong.
- He also criticises patterns for not being first-class citizens. Of course first-class patterns are nice, and some languages have them, but there are performance implications of having them.
- His critique of monads was focussed on something superficial, how they are named in Haskell. But the interesting question is: are monads a good abstraction to provide in a programming language? Most languages provide special cases: C has the state monad, Java has the state and exception monad etc. There are good reasons for that.
- And yes, normal programmers could have invented monads. But they didn't. Maybe there's a message in this failure?
Re: Deconstructing Functional Programming [video]
#80- He claimed that tail recursion could be seen as the essence of functional programming. How so?
- He complained that tail recursion has problems with debugging. Well, tail recursion throws away stack information, so it should not be a surprise. You don't get better debug information in while loops either. And you can use a 'debug' flag to get the compiler to retain the debug information (at the cost of slower execution).
- His remarks about Hindley-Milner being bad are bizarre. Exactly what is his argument?
- His claims about pattern-matching are equally poor. Yes, pattern matching does some dynamic checks, and in some sense are similar to reflection. But the types constrain what you can do, removing large classes of error possibilities. Moreover, typing of patterns can give you compile-time exhaustiveness checks. Pattern matching has various other advantages, such as locally scoped names for subcomponents of the thing you are matching against, and compile-time optimisation of matching strategies.
- He also repeatedly made fun of Milner's "well-typed programs do not go wrong", implying that Milner's statement is obviously non-sense. Had he studied Milner's "A Theory of Type Polymorphism in Programming" where the statement originated, Bracha would have learned that Milner uses a particular understanding of going wrong which does not mean complete absence of any errors whatsoever. Milner uses a peculiar meaning, and in Milner's sense, well-typed programs do indeed not go wrong.
- He also criticises patterns for not being first-class citizens. Of course first-class patterns are nice, and some languages have them, but there are performance implications of having them.
- His critique of monads was focussed on something superficial, how they are named in Haskell. But the interesting question is: are monads a good abstraction to provide in a programming language? Most languages provide special cases: C has the state monad, Java has the state and exception monad etc. There are good reasons for that.
- And yes, normal programmers could have invented monads. But they didn't. Maybe there's a message in this failure?