begin quoting David Brown as of Mon, Jan 07, 2008 at 12:07:52AM -0800: > On Sun, Jan 06, 2008 at 11:15:12PM -0800, SJS wrote: > > >But it also seems to open the door for auto-return-types. > > This is what you get with full Hindley-Milner type-inference. It is > possible to write large, complex programs, without ever declaring what > types things are, and yet the language is fully statically typed. > > Inferring variable types isn't that hard. Inferring return types isn't > that hard. Inferring both is quite complicated. It defines a dependency > graph that has to propagate knowledge until the graph is either complete, > or there is a conflict.
Which is where some of my problem comes in. *I* have to be able to do some of that in my head, at least some of the time. > It also requires type variables, since there might be parts of a type that > just aren't known. E.g. (in something resembling Haskell) > > map f [] = [] > map f (x:r) = (f x) : (map f r) > > It allows patterns at the top level as basically a case statement. The Looks like a loop to me, not a case statement. > first line says that map (with two arguments) if the second argument is an > empty list, return an empty list. So, "map" is an operator, and "f" is the name of a function? > The second line says to split apart the first item from the rest of the > list, call f with that argument, and stick that on the beginning of a new > list which recursively invokes map on the rest of the list. I actually preferred lisp's CDR and CAR to this implicit breaking of lists. > The complier figures out it's type as: s/'// > > map :: (a -> b) -> [a] -> [b] All from just those two lines? Doesn't it need to know about the definition of 'f' first? > which basically means the first argument is a function taking some type > 'a', and returning some type 'b'. The second argument is a list of type > 'a', and the function returns a list of type 'b'. Map doesn't care what > 'a' and 'b' are, but for a given inference, all of the 'a's must map to the > same type, and all of the 'b's to the same type. ...yup, okay. Because f is invoked on the head of the list every time, it has a consistent input. And because the new list is made up of invoking f each time, you get the same output type from f, so it's all the same type. What if you had (guessing wildly at syntax): map f g [] = [] map f g (x:r) = ((x even ? f x) (x even not ? g x)) : (map f g r) Hmm.... maybe dispose of the conditional? map (f,g) [] = [] map (f,g) (x:r) = (f x) : (map (g,x) r ) Anyway... I suspect you'd either have to coerce f and g to have the same return types (walk your graph), or you'd get a potential conflict here. Yes? No? Almost? Off in left field? -- Tersness is a virtue, up to a particular point, Then you end up with your nose out of joint. Stewart Stremler -- KPLUG-LPSG@kernel-panic.org http://www.kernel-panic.org/cgi-bin/mailman/listinfo/kplug-lpsg