5 ms·
> Once you really understand the typesystem, most of the time, types really are the best documentation --- they often tell you exactly what the function does, i
by wellpast 7y ago
> Once you really understand the typesystem, most of the time, types really are the best documentation --- they often tell you exactly what the function does, in a way that English comments never will.
Snake Oil.
Apply this claim to any set of real world functions, however well designed they are.
This is classic Haskellism. Obsessed with the lattice of types in the room. Door closed. Real world outside.
- quickthrower2 7y agoNot completely. Types are documentation. When going from JS -> TS you suddenly have the ability to create types that allow you to easily discover what is in an object. You can now confidently say foo.bar.replace(...) and know it'll work at runtime. Otherwise you hope that someone has written in a doc somewhere that bar is a string. And judging by npm docs I've seen - that is very unlikely. So you debug at runtime, head over to the github repo, or do an console.log(typeof(... hmm!
- wellpast 7y agoTypes alone are severely insufficient documentation. That’s the refutation of the original poster’s claim.
- perfmode 7y agoWhat are all of the things this function could possibly do to its arguments? (a -> b -> c) -> b -> a -> c
- deleted 7y ago[deleted]
- wellpast 7y agoInfinite.
- quickthrower2 7y ago3 things: 1. Call the function 2. error 3. infinite recursion Technically correct - there are infinite possible error messages.
- im3w1l 7y agoIt's my understanding that we have to involve a function call as a fallback, as a function call is the only way we have of producing a value of type c in the general case. But we could potentially have some list of exceptions. So one valid implementation would be: If c is string we always return hello world elseif a, b and c are integers we add the two ints. Elseif a and b are the same type we call the function with the argument order swapped. And finally, if none of these are the case, we call call the function with the arguments.
- danharaj 7y agoIn a type system like Haskell's, a function with that signature has to be unconditionally polymorphic in its variable types, so you can't have a list of exceptions.
- dllthomas 7y agoIf you do want to be able to list exceptions in Haskell, that's what Typeable gets you. But then the type signature is different.
- Twisol 7y agoTypes don’t exist at runtime in the way you’re describing. It isn’t possible to express a program that asks what type a value has. Dynamic types are sometimes called “tags” to distinguish the case in which this information _does_ exist at runtime.
- wellpast 7y agoYou need to rethink your #1. How about calling the function derivative? Sounds like you could have used real documentation.
- quickthrower2 7y agoWhat about String -> String-> String ?
- dodobirdlord 7y agoUnless what you're doing is content-agnostic String manipulation (i.e. a function to concatenate arbitrary Strings), this type signature wouldn't make sense. And since there are only a small number of meaningful content-agnostic string manipulations, I've already got a solid guess that this is probably doing concatenation! It could also possibly be doing substitution, or a few other things, but not much before it becomes a gaping code flaw that the types in use are still 'String'. Concatenating a person's name with a country name doesn't make sense. Nor does searching for a street address in a month. A type signature like String -> String-> String should only show up down in the implementation details of helper functions, or on the signatures of content-agnostic library functions.
- mpcjanssen 7y agoThis could equally well be a function which takes a string and a seed and returns the hash. The more concrete the type signatures become the less they become documenting. A signature of a -> a defines the id function because the type is so generic. A function of String->String can do pretty much anything.
- dodobirdlord 7y agoBut that's exactly my point. Why would something that is a randomization seed have type "String"? Why would a hash have type "String"? Why not type Seed and type Hash? A type signature of Seed -> String -> Hash is pretty enlightening!
- wellpast 7y agof(+’,1,2) = “cookie” For one. Now tell me: are types the best documentation?
- TheAsprngHacker 7y agoMaybe I'm misunderstanding what you're saying, but how on Earth would a function f :: (a -> b -> c) -> b -> a -> c result in f (+) 1 2 evaluating to "cookie" ? For one, the types (obviously, to me at least) don't work out.
- wellpast 7y agoSounds like you could use some real documentation.
- deleted 7y ago[deleted]
- dllthomas 7y agoThe types tell me that that's not the function in question. Type variables in Haskell mean the caller of the function gets to pick the types. That means the implementation doesn't get to - and the compiler makes sure of it. You're pattern matching on a number and returning a string. The function might be handed a function and expected to return a file handle for all you know from inside the function.
- nilkn 7y agoa, b, and c are generic types. You need to supply an implementation of f that doesn't know anything about a, b, or c. How many such implementations are there? Can you supply at least two, both of which finish running in a finite amount of time and neither of which produces any error?
- dllthomas 7y agoTypes are incomplete documentation. They may or may not be sufficient depending on the context. There are some really great things about types as documentation, though: 1) It's machine-checked, so it's probably not out of date or mistaken, which can be worse than no documentation. 2) The interaction with my code is checked, so if I misunderstood the compiler often has my back. 3) With inference, I can often ask for docs for code I just wrote. None of this is to say that there aren't usually other forms of documentation that should be produced.
- Scooty 7y agoMy biggest problem with this claim is typescript doesn't include any support for runtime type checking. My experience with TS has been great until I need to deal with data that comes from an external system (API, client, database). Then I either have to cast the type (which can lead to bugs where compile and run time types don't match and IMO isn't an option server-side) or I have to effectively duplicate my types by writing type guard functions.
- munchbunny 7y agoIt would be really nice to be able to coerce/validate incoming data (JSON I assume) at runtime against an interface definition. However, I feel like something like this goes against most of TypeScript's other stuff that aims for low cost abstractions on top of JS. That said, even if I have to write type guards at the edges (which I'd do in JS anyway, just because you aren't using types doesn't mean you don't need to enforce schemas), I think being able to rely on compiler typechecking inside the codebase boundary is really nice for making module interactions more predictable.
- kyllo 7y agoSpeaking of TS, here is a good argument for static typing: >Change a front-end React prop, then follow static type errors through the statically typed API, into the backend, all the way down into the database where they force a change in the Postgres schema. The system won't even compile unless React can talk all the way down to Postgres. https://twitter.com/garybernhardt/status/1140695491685933060 https://twitter.com/garybernhardt/status/1140695491685933060
- wellpast 7y agoYou’ve just described hell.
- taneq 7y agoYeah, it's much better when you have to change something, and you miss an important step in the guts of the code somewhere, and the compiler DOESN'T warn you, and you continue merrily on your way, unaware that six months from now when that code path executes in the wild, it'll take your company offline for six hours while someone (probably you) sweats their box off trying to figure out what the hell just happened.