On Fri, Jul 6, 2012 at 6:53 PM, Matthias Felleisen <matth...@ccs.neu.edu> wrote: > > I don't care about typed definitions.
Sam didn't have a "typed" definition, just a "type" definition, note the significant "d" suffix. > And yes, in an untyped world, you'd write > > (define (sum lt) > (cond > [(promise? lt) lt] > [else (+ (sum (car lt)) (sum (cdr lt)))])) In an untyped world, you could write the same function that Sam did. > Note the mistake you made in forcing too early. Sam didn't force anything too early. He only forced anything in the branch that accepts promises. ----- >From in-person conversation, what's really going on here is that Matthias is talking about some other, imaginary language, not Racket, where _any_ primitive operation other than promise? forces any promises in its arguments. In this language, promises are more like an implicit monad than a data structure. I don't know why Matthias has not clarified this issue so far, but I'm doing so now to hopefully save some bandwidth. --Carl > On Jul 6, 2012, at 5:58 PM, Sam Tobin-Hochstadt wrote: > >> On Fri, Jul 6, 2012 at 5:53 PM, Matthias Felleisen <matth...@ccs.neu.edu> >> wrote: >>> >>> I can't think of such a primitive other than force, for which it is okay. >>> Can you be concrete? >> >> Here's a type definition; >> >> (define-type LTree >> (U (Promise Integer) (Cons LTree LTree))) >> >> This is just a tree of integer promises, but to traverse it, we need >> to write code like: >> >> (define (sum lt) >> (cond [(cons? lt) (+ (sum (car lt)) (sum (cdr lt)))] >> [else (force lt)])) >> >> If `cons?` raised an error when applied to promises, we'd be out of luck. >> >>> On Jul 6, 2012, at 5:16 PM, Robby Findler wrote: >>> >>>> What do you do if you have a function that accepts either promises or >>>> lists? Then, you might want total predicates. >>>> >>>> Robby >>>> >>>> On Fri, Jul 6, 2012 at 2:22 PM, Matthias Felleisen <matth...@ccs.neu.edu> >>>> wrote: >>>>> >>>>> I just realized that Racket already suffers from the problem that >>>>> polymorphic contracts introduce. >>>>> >>>>> As Stephen is working out right now, Racketeers want to introduce >>>>> laziness to speed up programs on occasion. We have been told for decades >>>>> that delay and force are our friends. In a sense, this >>>>> performance-refactoring problem is exactly the same problem as >>>>> incremental type refactoring aka gradual typing. You want to add laziness >>>>> in a transparent manner -- or if you make a mistake, it should blow up on >>>>> you. >>>>> >>>>> But it doesn't: >>>>> >>>>>> Welcome to DrRacket, version 5.3.0.13--2012-07-05(467bde3a/d) [3m]. >>>>>> Language: racket. >>>>>>> (null? (delay (/ 1 0))) >>>>>> #f >>>>>>> (zero? (delay (/ 1 0))) >>>>>> . . zero?: contract violation >>>>>> expected: number? >>>>>> given: #<promise:unsaved-editor12957:6:9> >>>>> >>>>> For some reasons I don't understand, our ancestors (let's not use their >>>>> name anymore) decided to make some primitives resistant to promises and >>>>> some aren't. Now imagine you accidentally package a null in a delay, >>>>> which may happen when you use lazy combinators: >>>>> >>>>>>> (null? (delay null)) >>>>>> #f >>>>> >>>>> Your program changes meaning and off it goes and signals an error. You >>>>> don't get a faster program, you get a program that raises the wrong kind >>>>> of error. >>>>> >>>>> What they should have done is signal an exception when strict primitives >>>>> receive a promise. >>>>> >>>>> I take it is too late to correct such a {\HUGE HUGE} historical blunder. >>>>> -- Matthias >>>>> >>>>> >>>>> _________________________ >>>>> Racket Developers list: >>>>> http://lists.racket-lang.org/dev >>> >>> >>> _________________________ >>> Racket Developers list: >>> http://lists.racket-lang.org/dev >> >> >> >> -- >> sam th >> sa...@ccs.neu.edu > > > _________________________ > Racket Developers list: > http://lists.racket-lang.org/dev _________________________ Racket Developers list: http://lists.racket-lang.org/dev