5 ms·
I did one personal project in it just to get my feet wet. Unfortunately the tooling was not great at the time so it soured my impression a bit (I'm told it's go
by _bxg1 6y ago
I did one personal project in it just to get my feet wet. Unfortunately the tooling was not great at the time so it soured my impression a bit (I'm told it's gotten better since then).
But also, I just have a really hard time giving up static types these days. Even for small projects, I always feel anxious about code that doesn't have annotations on function boundaries. It may have more to do with personal sensibilities than actual need, but regardless, it makes things unpleasant for me.
- hannofcart 6y agoSame here: having gone from C++ to JS+Python and back to Golang/Rust, I just can't imagine life without types. However, of all the not-static-typed language ecosystems I see, Clojurists seem to miss types the least. I have dabbled with the language and I know about `spec` but I don't quite seem to grasp why even shops using Clojure without spec don't seem to miss types much either. Perhaps people more experienced with Clojure can shed light on this?
- _bxg1 6y agoA pure functional style does help somewhat; things are more predictable and consistent, expressions can be evaluated inline to test them out, etc. And I think Clojure teams (Lisp teams in general, really) are already forced to be on the small side because of how flexible things can become with macros and such. You have to have a stronger shared headspace compared to, say, a Java project. So that also lends itself to being more dynamic-types-tolerant. Finally, that very flexibility (with macros, etc.) is only fully possible in the absence of static types. So there is a genuine tradeoff. Still, even with all of the above I'd rather have them than not have them.
- slifin 6y agoIf you want something to let you know you've made a silly mistake like putting a string in a number function or missed an argument use clj-kondo it will catch those problems for you in the editor If you want to make a Person class or type I would recommend instead making your information model as a Datomic schema and have all your functions use associative destructuring with defaults values for missing data with function comments for good measure For dev I would recommend Datahike over Datomic initially
- lorddoig 6y agoIt depends what you want to use types for, really. If your motivation for using types is provable correctness and you can grok Haskell (or better yet, Idris), then you should do that. If you want performant dispatch, Clojure can give you JVM-level perf through the use of protocols. If, however, you want input validation (in the sense that you can be sure that a function argument you've been given will allow you to do what you intend with it) then static typing isn't the only player in that game. In my experience (which I think resonates with RH and most Clojurists) is that for the vast majority of _information-driven_ systems, types are used as the latter. If you have a `Customer` class that gives you guarantees about the availability of, say, an `accountNumber` field, that is useful for correctness as you can be sure the information you need is there. However, if some future downstream coder wants to use your customer in the more general sense of being a human, then (s)he has to worry about sub/super/abstract-classing, may have to make upstream modifications to expose previously hidden data, and similar faffage. In Clojure the idiomatic solution to this problem is to "just use a map"; the real-world downside to this, however, is extremely weak contracts between functions. In this example, what `spec` allows you to do is strengthen those contracts by verifying that the data your function is provided is sufficient for your uses (as in the map contains all the keys you'll need with suitable data types in the fields) _without_ constraining what downstream consumers can also do with this data (extra map keys are ignored). These checks are only done at runtime and only when enabled, however writing a spec gives you (very-nearly-almost) free generative testing that will run your function a default of 1000 times with random data in the correct shape to make sure it doesn't blow up—this isn't a guarantee of correctness, but it does provide extremely high levels of confidence (most type systems are also not even close to guaranteeing correctness either, only compliance with the type system). Spec also gives you (for free) performant runtime coercion for use in actual real-world code. You get a lot of bang for your buck. `spec` is definitely not a type system, but it very capably fulfils a similar role in the kinds of programs Clojure was intended to be good at. It gives you all the flexibility and dynamism of Clojure with most of the confidence of static typing, without constraining either.
- _bxg1 6y ago> by verifying that the data your function is provided is sufficient for your uses (as in the map contains all the keys you'll need with suitable data types in the fields) _without_ constraining what downstream consumers can also do with this data (extra map keys are ignored) This assumes a very class-oriented type system. Duck-typing and the like don't have the upstream ontology problems. My main desire from types is as an iteration assistant (with editor integration). Even if I wrote a function myself, I may not remember the exact order of arguments, or the exact name of that one property on the returned map. I want to a) be able to quickly peek and see what those things are - either by visiting the definition or, even better, via a pop-over in my editor - and b) have my editor tell me immediately if I did something dumb so I can correct it and keep moving. In a dynamic language, whenever I need to double-check the contract for some code, I can't just go look look at its type signature, I have to go read through it. I have to fully load that whole subtree of information into my brain (recursively to any functions it may itself call), when I'm really trying to focus my thoughts on something else. This can be a huge, needless drain on mental resources. Spec would help with this some, assuming the author follows a good convention of putting all of their assertions at the top of the function. But maybe those assertions are done inside conditionals, creating a more complex type. And maybe my editor doesn't know what to make of them (do any editors? genuinely curious). Etc. It just creates a bunch of little speedbumps to cognition that add up.
- Scarbutt 6y agoI have come to appreciate static types for browser programming(UI development) and won't go back to a dynamic language in that area by choice. For server side stuff, like a HTTP API, Clojure really shines IMO. But then you hit the database layer and the benefits of Clojure diminished greatly, compared to just doing the thing in JS. You could extend Clojure's "programming model" to the database with Datomic, but choosing it is not decision to take slightly(for various reasons), it also has many production horror stories. Clojure has good foundations but the ecosystem just isn't there.
- bsaul 6y agoI can't believe people that actually actively used a compile-time type-checked PL in a real-world long term project can even consider using a dynamic language for anything serious. I've worked with both, and i wouldn't ever move away from the ease of refactoring and confidence that a statically typed language offers you.
- invalidOrTaken 6y agoAn idle wonder: one non-criticism of Clojure (and lisps in general) is "the parens." Anyone who's used Clojure finds that a) this is totally handled by the editor, and b) the parens are actually an advantage, because all language structures are the same, which means the same hotkeys, etc, can be used universally. Now the reason I mention this is: I "hate" static types. But then again, the only place I've actually used them was when writing Java in plugin-less Vim in college ten years ago. Am I the outsider who just got a bad taste because I was lacking proper editor/IDE support?
- andrewflnr 6y agoYou got a bad taste because Java tastes bad. :) Almost any other statically typed language will be more pleasant than Java. Java barely counts at all, in my biased opinion, because null references are so pervasive. OCaml is a better intro (or if you're into the new hotness, Rust). But yes, tooling helps too.
- millimeterman 6y agoI'd actually point the finger at Java itself, though I imagine the editor didn't help. Java's type system is (IMO) about as cumbersome and unhelpful as they come. A good type system should be minimally obtrusive while preventing lots of programming errors (both when writing code and, perhaps more importantly, during maintenance by a different person a year down the line). For languages with good type systems, I'd recommend something like OCaml (or maybe F# - I know it's very similar and probably has a better ecosystem but I haven't personally used it). Elm also seems decent - it's designed to be pretty simple and has JS interop but it doesn't have good tooling. Typescript is an alternative that has an okay type system but pretty quality tooling. I'd recommend staying away from Haskell even though it's commonly recommended. The type system is quite complex and its use of monadic I/O makes writing "real" programs, even toy ones, difficult for many people. If you want to learn Haskell, I'd say start with OCaml/F#/Elm. Those are all very similar and will let you learn the fundamentals of ML-style programming before diving into Haskell-specific details.