Live data from Hacker News

Dueling Rhetoric of Clojure and Haskell

tech.frontrowed.com

51–60 of 107 posts

Re: Dueling Rhetoric of Clojure and Haskell

#51

The dueling rhetoric is the same rhetoric that has been around for decades: Some people really feel type systems add value; others, feel it's a ball and chain. So which is it? The answer is probably "yes." We should all believe by now since history has proven this correct. Most of the time you start with no type system for speed. Then you start adding weird checks and hacks (here's lookin' at you clojure.spec). Then…

>"a monad is just a monoid in the category of endofunctors"

Once I discovered the Monad thing in Haskell has pretty much nothing to do with the Monad in Category Theory, everything made much more sense. As a bonus I now (sort of) understand Category Theory. Much the same as Relational Databases have not very much to do with Relational Algebra.

Re: Dueling Rhetoric of Clojure and Haskell

#52
post #45

Earlier quoted context omitted.

The Haskell REPL is pretty good for a static language, but the experience is dramatically different to how a Clojure programmer would use want to use it. To be fair, Node and Python also have totally not usable REPLs for this style.

If no other language has any functionality similar to how Clojure does things then I think we'll need references to explanations or videos before we can even begin to understand your claims!

Clojure is following in the tradition of lisps that do this right. The important bit is the extra indirection on top-level names. I wrote more about it here a long time ago: https://www.brandonbloom.name/blog/2012/12/21/the-nodejs-rep...

Also interesting is the other end of the spectrum: Forth. Instead of mutation, offers snapshots and restores of the “dictionary”. See this video: https://youtu.be/mvrE2ZGe-rs

Re: Dueling Rhetoric of Clojure and Haskell

#53

Earlier quoted context omitted.

The Haskell REPL is pretty good for a static language, but the experience is dramatically different to how a Clojure programmer would use want to use it. To be fair, Node and Python also have totally not usable REPLs for this style.

GHC's repl is completely fine. The thing with dynamic languages is that the development style is basically println-driven. It goes like this: because you can't keep anything longer than a 1-page script in your head and because you can't remember the APIs of other people and hence you can't trust anything you write, in order to keep some sanity, you have to execute every freaking line of code that you write in order t…

These are old tired arguments.

I prefer being forced to keep my program simple by making complexity intolerable over encapsulating it. Your preference may differ.

I find I have to refactor my dynamically typed programs less frequently than my statically typed ones. Your mileage may vary.

No amount of type safety will prove my game is fun, or that my user can understand the UI. I want fast iteration times, since I can’t wait on the compiler to test a new enemy behavior or GUI layout.

Re: Dueling Rhetoric of Clojure and Haskell

#54
post #21

Earlier quoted context omitted.

I'd gladly storm into the breach with you :) Hopefully we all agree that static types and dynamic types are useful. Those who use hyperbole are attempting some form of splitting. I think the point where we disagree is what the default should be. The truth is this discussion will rage on into oblivion because dynamic types and static types form a duality. One cannot exist without the other and they will forever be ent…

Well, I think that static types are much more useful than dynamic ones. Static types allow you to find errors with your program before execution and that is very important. And if you are going to go through the effort of defining types, it is much better to use static types because then you get this additional error checking. Furthermore, with static types the compiler can help in other ways, e.g. by organizing your…

One can exist without the other and most statically typed languages either forbid or strongly discourage dynamic typing.

It never seemed like that much of a prohibition to me. Dynamic types take one grand universe of "values" and divide it up in ways that (ideally) reflect differences in those values -- the number six is a different kind of thing than the string with the three letters s i x -- but what the types are is sort of arbitrary. Is an int/string pair a different type than a float/float pair? Is positive-integer a type in its own right? Is every int a rational, or just convertible into a rational? What if you have union types? After using enough dynamically typed languages, the only common factor that I'm confident holds across the whole design space is that a dynamic type is a set of values. That means static typing still leaves you free to define dynamic types that refine the classification of values imposed by your static types, and people do program with pre-/postconditions not stated in types. You just don't get the compiler's help ensuring your code is safe with regard to your own distinctions (unless maybe you build your own refinement type system on top of your language of choice).

By a similar process, dynamic typing leaves you free to define and follow your own static discipline even if a lot of programmers prefer not to. This is more or less why How to Design Programs is written/taught using a dynamic language. The static type-like discipline is a huge aspect of the curriculum, but the authors don't want to force students to commit to one specific language's typing discipline.

Re: Dueling Rhetoric of Clojure and Haskell

#55

Earlier quoted context omitted.

GHC's repl is completely fine. The thing with dynamic languages is that the development style is basically println-driven. It goes like this: because you can't keep anything longer than a 1-page script in your head and because you can't remember the APIs of other people and hence you can't trust anything you write, in order to keep some sanity, you have to execute every freaking line of code that you write in order t…

These are old tired arguments. I prefer being forced to keep my program simple by making complexity intolerable over encapsulating it. Your preference may differ. I find I have to refactor my dynamically typed programs less frequently than my statically typed ones. Your mileage may vary. No amount of type safety will prove my game is fun, or that my user can understand the UI. I want fast iteration times, since I can…

> No amount of type safety will prove my game is fun, or that my user can understand the UI

No, but what it can ensure to some extent is that your game runs, and doesn't crash randomly. If the game crashes constantly, no one is going to play it no matter how fun it is.

Re: Dueling Rhetoric of Clojure and Haskell

#56
post #34

Earlier quoted context omitted.

The fact that Haskell is smarter than me is exactly why I have been keeping at it! I tend to think of Haskell as an eccentric professor. Sometimes it's brilliant and what it's developed lets you do things that would be much harder in other ways. Sometimes it just thinks it's clever, like the guy who uses long words and makes convoluted arguments about technicalities that no-one else can understand to look impressive,…

No, not " thinks it's clever", but overly clever, yes, often.

I tend to ignore 99% of the clever haskell stuff and get by just fine in Haskell.

I keep learning about stuff like GADTs and whatnot, but they're more like the top of the tool drawer special tools than the ones you break out every day.

I think people learning/using haskell tend to go for crazy generalized code first, versus what gets me to a minimal working thing that I can expand/change out later.

Or I just suck at haskell, probably a little from column a and b, for me more sucking at haskell than anything.

Re: Dueling Rhetoric of Clojure and Haskell

#57
Watching Hickey's talk, many of the complaints seemed to be valuable, but they didnt seem to be about static types. Rather, it was about some problems with existing data types locking one into a rigid data model when the domain is constantly expanding.

This post by DeGoes makes the same point. http://degoes.net/articles/kill-data

The default model of algebraic data types is too inflexible.

There are different extensions which work with this issue. Good record system, Extensible cases, using free monads etc. We can have concise syntax for automatically declaring an interface for a algebraic data type based on some field values (ie, customizable deriving statements). Namespace qualified keywords, so we have rdf like attribute based semantics.

The post doesnt respond to the issue but suggests that if you want to do the same thing in clojure with error handling etc, you will need to think about this stuff.

Also, Hickey's mention of Monads was again not about static types. Monad laws are not typechecked. Their motivation is purity. The only slight inconvenience in a dynamic context is that you dont have return type polymorphism, so you have to type IOreturn instead of return.

Re: Dueling Rhetoric of Clojure and Haskell

#58

Earlier quoted context omitted.

I love how I just keep learning Haskell, and keep improving, despite how much I already did it. That said, Python is also smarter than me. The possibilities with monkey patching and duck typing are endless. But differently from Haskell, Python is not a good teacher, so I tend to only create messes when I go out of the way exploring them.

> That said, Python is also smarter than me. The possibilities with monkey patching and duck typing are endless. Don't do it, 99.9% of the time. It's that simple. There is seldom a reason to use more than just defs - and a little syntactic sugar (like list comprehensions) just to keep it readable. Even the use of classes is typically bad idea (if I do say so). Just because: there is no advantage to using it, except w…

Classes definitely give you a lot of rope to hang yourself with (metaclasses, inheritance, MULTIPLE inheritance), but they have their place. I'll usually start with a function, but when it gets too big, you need to split it up. Sometimes helper functions is enough, but sometimes you have a lot of state that you need to keep track of. If the options are passing around a kwargs dictionary, and storing all that state on the class, I know which I'd pick.

You can memoize methods to the instance to get lazy evaluation, properties can be explicitly defined up-front, and the fact that everything is namespaced is nice. You can also make judicious use of @staticmethod to write functional code whenever possible.

Re: Dueling Rhetoric of Clojure and Haskell

#59

Earlier quoted context omitted.

> That said, Python is also smarter than me. The possibilities with monkey patching and duck typing are endless. Don't do it, 99.9% of the time. It's that simple. There is seldom a reason to use more than just defs - and a little syntactic sugar (like list comprehensions) just to keep it readable. Even the use of classes is typically bad idea (if I do say so). Just because: there is no advantage to using it, except w…

Classes definitely give you a lot of rope to hang yourself with (metaclasses, inheritance, MULTIPLE inheritance), but they have their place. I'll usually start with a function, but when it gets too big, you need to split it up. Sometimes helper functions is enough, but sometimes you have a lot of state that you need to keep track of. If the options are passing around a kwargs dictionary, and storing all that state on…

You can always opt for explicit dict passing. You are right that it's more typing work (and one can get it wrong...), but the resulting complexity is constant in the sense that it is obvious upfront, never growing, not dependent on other factors like number of dependencies etc.

When opting for explicit, complexity is not hidden and functions are not needlessly coupled to actual data. Personally I'm much more productive this way. Also because it makes me think through properly so I usually end up not needing a dict at all.

Regarding namespacing, python modules act as namespaces already. Also manual namespacing (namespacename+underscore) is not that bad, and technically avoids an indirection. I'm really a C programmer, and there I have to prefix manually and that's not a problem.

Re: Dueling Rhetoric of Clojure and Haskell

#60

The dueling rhetoric is the same rhetoric that has been around for decades: Some people really feel type systems add value; others, feel it's a ball and chain. So which is it? The answer is probably "yes." We should all believe by now since history has proven this correct. Most of the time you start with no type system for speed. Then you start adding weird checks and hacks (here's lookin' at you clojure.spec). Then…

>"a monad is just a monoid in the category of endofunctors" Once I discovered the Monad thing in Haskell has pretty much nothing to do with the Monad in Category Theory, everything made much more sense. As a bonus I now (sort of) understand Category Theory. Much the same as Relational Databases have not very much to do with Relational Algebra.

Indeed. And this is a great comment.
Post reply on HN