5 ms·
You do this because that's how you have trained yourself to think about code. It's a little self centered too assume this for everyone else.
by Guthur 8y ago
You do this because that's how you have trained yourself to think about code. It's a little self centered too assume this for everyone else.
- int_19h 8y agoThinking about data contracts for inputs and outputs is pretty basic stuff. If you don't do that, how do you know what your code actually does?
- carlmr 8y agoThey don't, but they're fast and fail often.
- regularfry 8y agoThere's a gap between things it might make sense to consider as data contracts, and things that can be expressed in practical type systems in common use. One example: a function which, when given a single element, returns a single transform of that element. When passed a list of elements, returns a map of that transform over the list. You can argue as to whether that's a good idea or not, but I've seen JS functions that make sense in context which do that. This might just be my lack of type system expressivity knowledge, but how would one annotate the type of that function? I get that you could use a union type on the param and the return value, but not how you link the two.
- hombre_fatal 8y ago> how would one annotate the type of that function Some languages support function overloads like Swift and Kotlin. fn foo(input: A, xform: A -> B) -> B fn foo(input: [A], xform: A -> B) -> [B] Hmm, maybe we can generalize that into a Functor.
- int_19h 8y agoYes, this is very common in JS, and somewhat common in other popular dynamic languages. In TypeScript, for example, you'd implement this by defining several overloaded signatures. Note that this isn't C++ or Java, so you still have a single function implementing all of them - the various overloads just specify what happens depending on the arguments you pass. https://www.typescriptlang.org/docs/handbook/functions.html#overloads https://www.typescriptlang.org/docs/handbook/functions.html#... This is a limited approach, because the overloads aren't a part of a function type - i.e. you can't have an anonymous function value that is overload-typed, it must be a named function. In principle, a similar mechanism could be used for types as well, it just doesn't usually come up in that context (e.g. callbacks typically don't return different things), which is probably why they didn't do it.
- cjs_2 8y agoHow could one think about functions differently than about what their input and output is?
- zimablue 8y agoYour statement is just a tiny bit too general and that's where you're missing. "What about their input and output is" => "what type their input/output is" The next question is what does the type of the input/output actually tell you about the input/output? In the most popular languages (using interfaces), it basically tells you that the input/output might have a, b and c set (or they might be null), and it could also have anything else set. So the actual information you have is that you might or might not have (a,b,c) and also might or might not have (anything). Not as foolproof as you think. The natural objection is that aha! I defined this class to require (a,b,c) in the constructor and do a nullity check, so I know much more than this! But this is back to having "types in your head", that constructor signature and nullity check isn't compiler enforced (as in if you change it, nothing will fail in the typesystem at the point of the function that we're checking, as long as those fields remain on the class). So the useful part of the static typing is actually living in your head either way.