Hacker News new | comments | show | ask | jobs | submit login

With apologies to the author, the piece was very well-written but I didn't find any of the arguments or observations in this article comepelling :-(

> This is just a guess, but at the time he wrote Clojure, those type systems most likely were Java-style (Java, C++, C#) and Haskell

SML and OCaml pre-date some of the languages in that list, and certainly pre-date clojure.

The "positional semantics" section -- and that whole class of arguments -- never made any sense to me. All languages have hash maps, so this is about program design rather than language design. Or perhaps, at most, an argument for having nice syntactic sugar for hash maps. In any case, I'm not sure what this has to do with fundamental language design issues. The "can Haskell..." stuff has a similar smell to it. The answer is always "yes, Haskell (and everyone else) have hash maps and HOFs."

At best, it's an argument that those languages should provide a bit of extra syntax around the "everything is a map" programming style. Which, I won't disagree with :)

> In the kinds of systems Rich is talking about, any data could possibly be missing... At the limit, you would need to make everything Maybe

Which is why ML-family languages have both exceptions and algebraic data types.

The discussion of abstraction is just confusing. The author seems to define "abstraction" as "literally any list of information". And I guess it's true that pathologically bad abstractions do exist, but... what point is being made here? I don't get it.

The "screwing around in the type system syndrome" thing actually makes sense, but you can see the same thing in dynamic languages (e.g., with meta-object protocols or macros). There's something more fundamental here, and it's more about human psychology than language design.

I have to agree with keymone, though, that the really interesting thing about clojure is not its design but rather clojure.spec. Sure, you lose a lot of static guarantees, and along with them some of the maintainability/correctness that come along with statically typed languages. But perhaps recovering static checks, and tooling based on static checks, is best done on a library-by-library basis via compositional specification checkers specialized to the particular library. Rather than by a single general-purpose type theory that's rich enough for the "real problems in the messy world" type of programming. And the article kinda starts hinting at this toward the end. But I think keymone really hits the nail on the head when it comes to what you should take away from learning/working in clojure.

> The "can Haskell..." stuff has a similar smell to it. The answer is always "yes, Haskell (and everyone else) have hash maps and HOFs."

+1 !

If necessary you don't need to use and ADT+pattern matching on JSON. You just work with the hashmap directly.

What is the type signature for json hashmap in Haskell and how using it is different from using a dynamically typed language?

The easiest way to use JSON as dynamically typed data in Haskell is with the lens[1] and lens-aeson[2] packages. The type signatures those use are astounding, and not trivial to understand.

But the code that results is very simple while remaining strongly typed.

It ends up being not that different in style from something like hpricot in ruby.

[1] https://hackage.haskell.org/package/lens

[2] https://hackage.haskell.org/package/lens-aeson

A json object has the type signature:

    type Object = HashMap Text Value
which is A JSON "object" (key/value map).

The keys of the hashmap are Text and the leaves are "Value" which contain more JSON

here are different well-formed json values that both resolve to the same type, A.Object (either you get a parse error String for not-well-formed json, or an A.Object)

    >>> A.eitherDecode "{ \"name\": \"Joe\", \"age\": 12 }" :: Either String A.Object

    Right (fromList [("age",Number 12.0),("name",String "Joe")])

    >>> A.eitherDecode "{ \"name\": \"Joe\", \"age\": {\"foo\": \"12\"} }" :: Either String A.Object

    Right (fromList [("age",Object (fromList [("foo",String "12")])),("name",String "Joe")])
Then you can access values in the HashMap by key just like a hashmap in any other language.

Or, as noted by chowells, you can use lens-aeson which can be thought of as a DSL to perform queries in a dynamic fashion:

retrieve value of "foo" in "age"

    >>> s = "{ \"name\": \"Joe\", \"age\": {\"foo\": \"12\"} }" :: String
    >>> s ^? key "age" . key "foo"
    Just (String "12")

> how using it is different from using a dynamically typed language

It's not different for that type. The point of using a statically typed language is you can give static types to other entities in your program!

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