[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: in defense of types
This is a brilliant and non-obvious demonstration; thanks a lot! You saved
me hours of scratching my head ;-)
BTW I'm not sure what you mean when you say that Y is not usable in eager
languages. You can define Y in scheme, which is eager. Do you mean in
eager statically-typed languages?
<note for people who've zoned out>
The Y combinator is a way of creating recursive functions in a language
which doesn't necessarily support them directly. So instead of defining a
function to find the length of a list as:
;; requires recursion:
(define (length lst)
(if (null? lst)
0
(+ 1 (length (cdr lst)))))
You do this:
;; doesn't require recursion:
(define length
(Y (lambda (len)
(lambda (lst)
(if (null? lst)
0
(+ 1 (len (cdr lst))))))))
See "The Little Schemer", chapter 9, for more on this topic.
</note for people who've zoned out>
Mike
> From: Jaeyoun Chung <jay@kldp.org>
> Date: Thu, 30 May 2002 13:00:39 +0900
>
> * Michael Vanier <mvanier@cs.caltech.edu> at 2002-05-29 16:27-0700
> | There is a cost in flexibility (I don't think you can write the Y
> | combinator in ocaml, for instance ;-)), but it's much less than most
> | people assume.
>
> Actually, yes! You can make Z (equiv with Y with one step eta
> conversion)combinator typeable in ML family language. Note that Y is not
> usable in eage language in which the fixpoint function will simply loop
> forever!
>
> let z f = (fun x -> f (fun z -> x x z)) (fun x -> f (fun z -> x x z));;
>
> is not typable. since two 'x' in 'x x z' cannot have the same type.
> The key point is distinguish the type of these instances of 'x'.
>
>
> # type 'a t = I of ('a t -> 'a);;
> type 'a t = I of ('a t -> 'a)
> # let z f = (function I x -> f (fun z -> x (I x) z))
> (I (function I x -> f (fun z -> x (I x) z)));;
> val z : (('a -> 'b) -> 'a -> 'b) -> 'a -> 'b = <fun>
>
> voila! you can type it. Now, let's try simple example.
>
> # let f = fun f -> fun n -> if n = 1 then 1 else n * (f (n - 1));;
> val f : (int -> int) -> int -> int = <fun>
>
> # z f ;;
> - : int -> int = <fun>
>
> as we expected. and
>
> # z f 5;;
> - : int = 120
>
>
> The true value of static typing of ML style type system is that it makes
> sure the invariant at compile time based on the rigid theory. You
> can encode the invariants of your program into to type.
>
> --
> jay@_kldp_._org_ sans '_'
>
>