I agree 100% that schema is a great tool, and solves some of the problems I still think the absence of (optional) types is a big missing piece in the Clojure story, because of the following reasons: 1. The ideal time to check types is at compile time - you want immediate feedback if you do something wrong [ e.g. ((map inc) 1) ], not at runtime or in a separate static analysis check 2. Separate checking tools don't help with performance optimisation (one of the key benefits of static type systems) 3. Without types in the compiler, types will always be second class citizens and subject to proliferation 4. The compiler can infer many types automatically. Why should we spend human effort annotating types that the compiler should infer? 5. There are plenty of people who really like Clojure, but for whom the lack of static typing is a big downside
In reality, we already have some ad-hoc typing in the Clojure compiler (type hints, primitives etc.) as well as "types" that are well understood and widely used in Clojure libraries but not explicit (sequence abstraction etc.) I think the ideal solution would be some kind of extensible optional type system, with the following properties: 1. Any expression has an optional type. If the type is nil or "Any" then it behaves just as regular current untyped Clojure code 2. Types are pluggable (e.g. you can have prismatic schema types, core.typed types, java class types, custom "abstraction" types like Sequence) 3. Types can be defined as named first class objects, and used as type hints 4. Functions can (optionally) be typed, with the rule that the resulting type is a (fn [type-signature-or-args]) which returns a new type (or indicates impossibility somehow) 5. Types support some standard operations sufficient to allow optimisations (intersection, union, instance? etc.) 6. You can choose your level of type checking (off, check at runtime, compiler warn on type error, compiler fail on type error etc.) for people who prefer different positions on the dynamic / static typing spectrum I believe it would be possible to add this kind of typing scheme to Clojure incrementally without breaking existing untyped code. It could be added incrementally to libraries, so that the ecosystem could evolve over time to have statically defined types as libraries mature and the definition of abstractions becomes clearer. Obviously only going to happen if clojure/core is behind it, but if there is interest I'm happy to write a hammock proposal. On Tuesday, 1 December 2015 09:47:49 UTC+8, Colin Yates wrote: > > +1 to everything said so far. > > I also found that types are great for articulating a well-known, static > set of structures, but almost all of the projects I worked in in a strongly > and statically typed language (Java) involved living on the edge of typing > _just_ the right level of abstraction - specifically, code which really > only cared about one aspect of a type versus having so many types you > couldn’t see the wood for the trees. Structural typing (or duck typing if > you prefer) would have gone a long way. Typing the _end_ result - sure, but > discovering the end result quickly - not so much. > > In Clojure I can still name and describe my abstractions through Schema (I > use it religiously and it has solved so many pain points, particularly ‘6 > months down the line’ - and it is turned on in production as the overhead > is negligible for my usage) but I have the flexibility to _not_ name them > as well and the ‘Any’ predicate is a fantastic nod to pragmatism. > > To put it another way, almost all of my pain points are looking at forms, > particularly long ’threaded’ forms and thinking ‘how on earth does that > sequence of transformations work’ rather than ‘exactly what data is that > expecting’. > > To be clear - the rigour of being forced to come up with a decent name for > an important abstraction is great, and (Java’s) types force you to do that, > but it also quickly becomes the demoralising stick that leads to > ‘ICantBeBotheredToThinkOfAnotherName’. > > When it comes to _consuming_ unfamiliar code then yeah, types are > incredibly potent as a form of documentation, assuming those types have > good names of course :-). > > So for me, Clojure maps and Prismatic Schema give me pretty much all of > the good stuff I got from typing in the first place. I miss the > ‘correctness’ check that strong and static types give you but that is a > small pain for the increased expressiveness I have of describing my > data/abstractions. > > On 1 Dec 2015, at 01:15, Timothy Baldridge <tbald...@gmail.com > <javascript:>> wrote: > > I believe that working with maps is a lot like working with locals and > function names...nothing will help you with bad naming. So don't do stuff > like {:foo 42 :bar 33} when you can do stuff like {:min-age 42 :max-age > 33}. Also stick with sane naming conventions. Don't do {:maxAge 42} in some > places and {:MaxAge 42 :max-age 33} in others. And finally using namespaced > keywords can really help, so perhaps even consider {:age/min 42 :age/max > 33} or perhaps even {:age-range [42 33]}. In short, think about how you > structure your data and you will go far. > > And to be frank, on the average project I work on I very rarely run into > the "bag of data" problem. Intact I spend way less time working on the > structure of the data than I do actually getting work done. And in the > past, when I've used strongly typed data I often found myself arguing with > my co-workers about type inheritance and co-variance/contra-variance (sp?), > instead of actually coding the logic I was being paid for. So to quote a > wise saying I heard once...."statically typed languages don't solve the > problems I have". Perhaps I'm unique in this regard, but my time spent with > other Clojure programmers tells me otherwise. > > As an aside, I recommend playing with stuff like tools.analyzer to see > how far the "bag of data" can take you: > https://www.youtube.com/watch?v=KhRQmT22SSg > > Timothy > > On Mon, Nov 30, 2015 at 5:49 PM, Sean Corfield <se...@corfield.org > <javascript:>> wrote: > >> Gary Trakhman wrote on Monday, November 30, 2015 at 2:26 PM: >> >> I'd like to try haskell, but I'm not sure types in general would provide >> enough benefit to be worth it for small projects and well-written/tested >> large ones. >> >> >> There’s always https://github.com/Frege/frege-lein-plugin and >> https://github.com/Frege/frege-lein-template if you want to try Haskell >> (Frege) inside your Clojure app! >> >> Sean >> >> >> -- >> You received this message because you are subscribed to the Google >> Groups "Clojure" group. >> To post to this group, send email to clo...@googlegroups.com >> <javascript:> >> Note that posts from new members are moderated - please be patient with >> your first post. >> To unsubscribe from this group, send email to >> clojure+u...@googlegroups.com <javascript:> >> For more options, visit this group at >> http://groups.google.com/group/clojure?hl=en >> --- >> You received this message because you are subscribed to the Google Groups >> "Clojure" group. >> To unsubscribe from this group and stop receiving emails from it, send an >> email to clojure+u...@googlegroups.com <javascript:>. >> For more options, visit https://groups.google.com/d/optout. >> > > > > -- > “One of the main causes of the fall of the Roman Empire was that–lacking > zero–they had no way to indicate successful termination of their C > programs.” > (Robert Firth) > > -- > You received this message because you are subscribed to the Google > Groups "Clojure" group. > To post to this group, send email to clo...@googlegroups.com <javascript:> > Note that posts from new members are moderated - please be patient with > your first post. > To unsubscribe from this group, send email to > clojure+u...@googlegroups.com <javascript:> > For more options, visit this group at > http://groups.google.com/group/clojure?hl=en > --- > You received this message because you are subscribed to the Google Groups > "Clojure" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to clojure+u...@googlegroups.com <javascript:>. > For more options, visit https://groups.google.com/d/optout. > > > -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.