3 ms·
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
by throwawayjava 9y ago
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.
- platz 9y ago> 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.
- keymone 9y agoWhat is the type signature for json hashmap in Haskell and how using it is different from using a dynamically typed language?
- chowells 9y agoThe 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 https://hackage.haskell.org/package/lens [2] https://hackage.haskell.org/package/lens-aeson https://hackage.haskell.org/package/lens-aeson
- platz 9y agoA 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")