3 ms·
> The @spec line in Elixir is just not DRY and inconvenient. I disagree. The spec is part of the documentation of the function. I find code with specs is 10x e
by ashton314 4y ago
> The @spec line in Elixir is just not DRY and inconvenient.
I disagree. The spec is part of the documentation of the function. I find code with specs is 10x easier to read and safely modify/refactor when you better understand the function contract.
See also: Typed Racket, Haskell where the types are often specified just above the actual implementation. If you don’t like it, I doubt I’ll change your mind. :) I don’t think it’s that bad though.
There are plenty of times when you can make the specs really expressive, much more than just pattern matching (which is great, especially when combined with guards) eg: (on phone, might be a like off on syntax)
@spec find_if([t1()], (t1() -> boolean())) :: t1() | nil when t1: any()
Function types are opaque to pattern matching and you can’t express return types in patter matching either.
- pmontra 4y agoI had to look at that spec for a while but I got it. Of course I'm out of training. More than that, there is the self selection bias: the main reason for I'm using dynamically typed languages is that they don't have type declarations so I'm never happy to see static typing get close to them. BTW I definitely lean towards strong typing, so 1 + "1" is an error (Ruby) and not 11 or "11" (Perl and JS.)
- ashton314 4y agoWell, Perl actually would return 2 in that case because the + turns it’s arguments into numbers… ;-) Yeah, I’m all for strong typing too. Most specs aren’t as complex as the one I just threw up there. What I really like specs for is to tell me whether or not the function is meant to return a maybe tuple ({:ok, val} | {:error, “err”}) or if it will throw an error. Sometimes that’s not obvious from bigger functions, and it makes refactoring harder. My ideal would be something like Typed Racket’s gradual typing, which would let you get static types around eg core modules that see a lot of use and where you use the types to check your assumptions but non-core modules can be untyped.