I don't care about typed definitions. And yes, in an untyped world, you'd write
(define (sum lt) (cond [(promise? lt) lt] [else (+ (sum (car lt)) (sum (cdr lt)))])) Note the mistake you made in forcing too early. 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