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

> If your language has classes, you should probably be using them for your entities and domain models.

Two years ago, I would have agreed with you. Now after some heavy, realistic usage of Clojure, I don't think I'll ever go back to modeling my domains with classes.

Maps are just so much more flexible! Granted, you frequently have a "type" like key. In the ClojureScript compiler, for example, AST nodes look like {:op :if :test ... :then ...} You can say that the :op :if is a "type", but in reality, the type of that object is a Map.

I'm working on a system now where there wasn't an obvious discriminated union or hierarchy of types. I fought the urge to introduce a type-like key in my map; the result has been quite pleasant.



The Clojure type of the object is a map, but for the AST-manipulating part of the compiler, isn't it in fact more accurate to say that the type of the object (the logical type, you might say, rather than the host type) is, in fact, `:if`?

After some reasonable, realistic usage of Clojure, I'm quite glad of protocols and multimethods, which I have found make several complex things much easier to work through.


Paraphrasing: "Isn't the logical type, in fact, `:if`?"

Yes.

Clojure's types are, generally, of the solution domains. The primary solution domain being: computation. That's the domain that all of Clojure built in types belong to.

The nature of Clojure and its community discourages the use of platform types for modeling the problem domain. Sometimes using platform types is desirable for optimizations like protocol dispatch and well-known structured fields. However, even when you're doing that, you're still operating in the solution domain. You're making an explicit decision about representation and evaluation: data structures and algorithms.

However, any substantial application is going to need some custom code for inspecting and debugging values. You'll wind up designing some schema and writing some custom validation. There can be tools to help you with this: consider XML's (very ugly) XSD schema system. Or consider W3C validators for HTML and CSS. For an example in the OOP world, look at AstValidator.java in the Google Closure code base. You simply can't escape it. A rich, strong type system can give you a leg up and get you 70% of the way there, but it will actively fight you when you want to go the last mile.

When and if you need it, you can basically make your own type system, tailored to your application.


> When and if you need it, you can basically make your own type system, tailored to your application.

When you do decide you need to think about and enforce types though, it helps a lot to have a clean, well-thought-out formally-specified framework to do this in. I hear there's some work on an optional type system for Clojure which might help with this.

Brings to mind the flip-side of that old chestnut about any sufficiently complicated C program containing an ad-hoc, informally-specified, bug-ridden, slow implementation of half of Common Lisp.

Any sufficiently complicated Lisp program contains an ad hoc, informally-specified, bug-ridden, slow implementation of a type system...


"When and if you need it, you can basically make your own type system, tailored to your application."

Only given an exiguous understanding of what a type system is. Maybe if Typed Clojure gets to the state of Typed Racket, sure, you could do that. But at the moment lots of things that would be statically discoverable in a language like Haskell---where, too, the types are of the solution domains---will pop up, to your woe, at runtime, in Clojure. This can be mitigated with some minor macrology and some major discipline, but the Typed Clojure route is major, major macrology (and not just macrology, obviously).




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

Search: