3 ms·
I like the Nix example - accidentally constructing a `List<String|Function>` and passing it into a function expecting a `List<String|...>` (where `...` does not
by pansa2 6y ago
I like the Nix example - accidentally constructing a `List<String|Function>` and passing it into a function expecting a `List<String|...>` (where `...` does not include Function). The dynamically-typed version can't do anything to prevent this.
However, I'm not convinced that a theoretical statically-typed version would be so much better. To get the error message given in the article, the compiler would have to consider the list of the form `['a', 'b', function(){...}, 'c']` to be an erroneous attempt to construct a `List<String>` - is that desirable? Or would it be better to consider it to be a `List<String|Function>` or `List<Any>`?
Even using `List<String|Function>`, the statically typed version could still give a reasonable error message on passing it into a function expecting a `List<String|...>` - as long as `...` is an accurate list of exactly what the function is and isn't willing to accept. If it's necessary to write out that list, correctly and completely every time, that's where static types can sometimes become more trouble than they're worth.
- TheDong 6y agoIs a correct summary of what you're saying "static type systems may also give poor messages when types are inferred, not explicit"? If someone wrote "let x: List<String> = [ 'foo', 'bar', func ]", it could certainly figure out the type. In practice, it seems like what people in statically typed languages have settled on is "always write the types for function signatures", and that does seem to give a happy compromise. In this case, the "toGNUCommandLine" function would specify that it takes in a list of strings, and from there the type-errors would be fine I think.
- pansa2 6y ago> the "toGNUCommandLine" function would specify that it takes in a list of strings The problem is that `List<String>` isn't the correct type for that function's parameter. It converts each item in the list to a string by calling `mkValueStringDefault` [0], which takes an argument that's of any type except list, attrset or function. So, the correct type for `toGNUCommandLine`'s parameter is something like `List<Any - {list, attrset, function}>`. Are there static type systems that make it easy to work with types like that? [0] https://github.com/NixOS/nixpkgs/blob/9b935b02e3775d95490f6586b88857a006e05fe5/lib/generators.nix#L33 https://github.com/NixOS/nixpkgs/blob/9b935b02e3775d95490f65...
- Measter 6y ago> Are there static type systems that make it easy to work with types like that? In Rust things that can be rendered to a string (in a user-friendly manner) implement the Display trait. A slice of things that can be rendered would have this type: `&[&dyn Display]`.