At your clojure job, we’re y’all using spec? I haven’t looked into it yet, and I’m wondering how much it mitigates the annoyances of dynamic types
At your clojure job, we’re y’all using spec? I haven’t looked into it yet, and I’m wondering how much it mitigates the annoyances of dynamic types
Spec is about asserting structure at domain boundaries; once you're inside a context, it will not do anything.
i.e. If you're connecting stuff together and you want to make sure the state is correct as you pass between contexts -> great!
If you're writing stuff and internally you miss having a strong type system... uh... I don't think it's really going to help you.
For complex data structures I typically just hide details behind a protocol and deal with the set of interface functions.
You can then freely mess with the internals and not worry about details
Similarly nothing prevents invoking missing functions of a protocol, you will only know during runtime.
The goal isn't to introduce .. a compilation step? but to have the program blow up in the spot where there is an type mismatch. If you don't use a protocol you may not blow up, you may generate a nil, and you may blow up much further down the line (or not at all)
In the rare instances where dynamic types cause problems, they're virtually always something convoluted like that. The protocol design pattern describes the interface and protects you from hard to debug situations
One thing I grew to really love is how small my changes were when I’m just adjusting a decidedly brownfield chain of functions that operate on data. With go in place at work, I added a couple fields to a core data type in my business and I ended up with thousands of lines of changes to pipe them everywhere. Doing the corresponding change in clojure would be <100 lines. I do miss the feeling I get with Haskell that if it type checks, I’m (maybe) good, but like Rich says “List[A] -> List[A] tells me almost nothing about the reverse function.”
Don't underestimate the amount of information even simple type signatures contain!
f :: [a] -> [a]
f [] = []
f (x:xs) = x: x: f xsHickey: I value X, Y, Z
Me: Yeah man!
Hickey: We get great consequences A, B, C
Me: Ah yeah, I love programming like that. That's why I love Haskell!
Hickey: That's why Haskell is bad.
Me: err, what!?
> It tells you that the function must calculate a subset of a permutation of the input list
As tromp pointed out, "permutation" is technically incorrect. You mean something like "a list formed only from elements of the elements of the input list, and the particular arrangement is independent of the values of the input list"!
Not sure why you were downvoted though.
I didn’t say Haskell was bad though. I love Haskell in a different way from clojure.
Here is Rich’s work on the subject: https://youtu.be/YR5WdGrpoug?si=7C8EjQ7TVo2Ua8w7
I’m biased, but I think he’s got a point.