default   Racket Bugs
Main PageQuick QueryStandard QueryAdvanced QueryHelp
Log in

View Problem Report: 11458

send email to interested parties or send email followup to audit-trail
Reporter's email: matthias at ccs dot neu dot edu
Number: 11458
Category: all
Synopsis: lazy take fails to raise exceptions; lazy is NOT Haskell!
Class: sw-bug
Responsible: eli
Notify-List:
Severity: serious
Priority: medium
State: closed
Confidential: no
Arrival-Date: Mon Nov 22 16:20:01 -0500 2010
Closed-Date: Tue Nov 23 10:36:44 -0500 2010
Last-Modified: Tue Nov 23 20:16:01 -0500 2010
Originator: matthias
Organization: plt
Submitter-Id: unknown
Release: 5.0.99.2--2010-11-18(14bdcda/g)
Environment: macosx "Darwin antarctica.ccs.neu.edu 10.5.0 Darwin Kernel Version 10.5.0: Fri Nov  5 23:20:39 PDT 2010; root:xnu-1504.9.17~1/RELEASE_I386 i386" (i386-macosx/3m) (get-display-depth) = 32
Human Language: english
(current-memory-use) 157267160

Collections:
(("/Users/matthias/0Unison/collects/" ".DS_Store" "compiled" "date" "finance" "info-domain" "info.ss" "pdf.ss~" "session" "short" "testing" "tll-collects" "utils" "web") ("/Users/matthias/Library/Racket/5.0.99.2/collects" non-existent-path) ("/Users/matthias/plt/collects" ".gitignore" "2htdp" "afm" "algol60" "at-exp" "browser" "combinator-parser" "compiler" "config" "data" "datalog" "defaults" "deinprogramm" "drracket" "drscheme" "dynext" "embedded-gui" "eopl" "errortrace" "ffi" "file" "framework" "frtime" "games" "graphics" "gui-debugger" "guibuilder" "handin-client" "handin-server" "help" "hierlist" "honu" "htdp" "html" "icons" "info-domain" "lang" "launcher" "lazy" "macro-debugger" "make" "meta" "mred" "mrlib" "mysterx" "mz" "mzcom" "mzlib" "mzscheme" "net" "openssl" "parser-tools" "plai" "planet" "plot" "preprocessor" "profile" "r5rs" "r6rs" "racket" "racklog" "rackunit" "raclog" "raco" "racunit" "reader" "readline" "redex" "repo-time-stamp" "repos-time-stamp" "rnrs" "s-!
exp" "schelog" "scheme" "schemeunit" "scribble" "scribblings" "scriblib" "setup" "sgl" "sirmail" "slatex" "slideshow" "srfi" "srpersist" "stepper" "string-constants" "swindle" "syntax" "syntax-color" "teachpack" "test-box-recovery" "test-engine" "tests" "tex2page" "texpict" "tool" "trace" "typed" "typed-scheme" "unstable" "version" "waterworld" "web-server" "wxme" "xml"))
Computer Language: (("Determine language from source") (#(#t print mixed-fraction-e #f #t debug) (default) #() "#lang racket\n" #t))
Description: 1. run

#lang lazy
(take -1 '(1 2 3))

and see nothing printed. Why?

2. This should also be an exception in a real language.
Only toys like Haskell can afford not to raise an error
here.
File Attachments:
How-To-Repeat:
Fix:
Release-Note:
Unformatted:

send email to interested parties or send email followup to audit-trail

Audit Trail:

From: Robby Findler <robby at eecs.northwestern.edu>
To: matthias at ccs.neu.edu, bugs at racket-lang.org
Cc: nobody at racket-lang.org, bug-notification at racket-lang.org
Subject: Re: [racket-bug] all/11458: lazy take fails to raise exceptions; lazy
 is NOT Haskell!
Date: Mon, 22 Nov 2010 15:30:16 -0600

 "toy" seems misplaced here.
 
 And, in any case, ghc does a little bit better by at least printing
 something. (In some cases a type error, but still something).
 
 Prelude> take 0 ["a"]
 []
 Prelude> 1-23
 -22
 Prelude> take (1-23) ["a"]
 []
 Prelude> take -1 ["a"]
 
 <interactive>:1:0:
     No instance for (Num (Int -> [a] -> [a]))
       arising from a use of `-' at <interactive>:1:0-12
     Possible fix:
       add an instance declaration for (Num (Int -> [a] -> [a]))
     In the expression: take - 1 ["a"]
     In the definition of `it': it =3D take - 1 ["a"]
 
 <interactive>:1:6:
     No instance for (Num ([[Char]] -> Int -> [a] -> [a]))
       arising from the literal `1' at <interactive>:1:6-12
     Possible fix:
       add an instance declaration for
       (Num ([[Char]] -> Int -> [a] -> [a]))
     In the second argument of `(-)', namely `1 ["a"]'
     In the expression: take - 1 ["a"]
     In the definition of `it': it =3D take - 1 ["a"]
 Prelude>
 
 
 On Mon, Nov 22, 2010 at 3:20 PM,  <matthias at ccs.neu.edu> wrote:
 > A new problem report is waiting at
 > =C2=A0http://bugs.racket-lang.org/query/?cmd=3Dview&pr=3D11458
 >
 > Reported by matthias for release: 5.0.99.2--2010-11-18(14bdcda/g)
 >
 > *** Description:
 > 1. run
 >
 > #lang lazy
 > (take -1 '(1 2 3))
 >
 > and see nothing printed. Why?
 >
 > 2. This should also be an exception in a real language.
 > Only toys like Haskell can afford not to raise an error
 > here.
 >
 > *** How to repeat:
 >
 >
 > *** Environment:
 > macosx "Darwin antarctica.ccs.neu.edu 10.5.0 Darwin Kernel Version 10.5.0=
 : Fri Nov =C2=A05 23:20:39 PDT 2010; root:xnu-1504.9.17~1/RELEASE_I386 i386=
 " (i386-macosx/3m) (get-display-depth) =3D 32
 > Human Language: english
 > (current-memory-use) 157267160
 >
 > Collections:
 > (("/Users/matthias/0Unison/collects/" ".DS_Store" "compiled" "date" "fina=
 nce" "info-domain" "info.ss" "pdf.ss~" "session" "short" "testing" "tll-col=
 lects" "utils" "web") ("/Users/matthias/Library/Racket/5.0.99.2/collects" n=
 on-existent-path) ("/Users/matthias/plt/collects" ".gitignore" "2htdp" "afm=
 " "algol60" "at-exp" "browser" "combinator-parser" "compiler" "config" "dat=
 a" "datalog" "defaults" "deinprogramm" "drracket" "drscheme" "dynext" "embe=
 dded-gui" "eopl" "errortrace" "ffi" "file" "framework" "frtime" "games" "gr=
 aphics" "gui-debugger" "guibuilder" "handin-client" "handin-server" "help" =
 "hierlist" "honu" "htdp" "html" "icons" "info-domain" "lang" "launcher" "la=
 zy" "macro-debugger" "make" "meta" "mred" "mrlib" "mysterx" "mz" "mzcom" "m=
 zlib" "mzscheme" "net" "openssl" "parser-tools" "plai" "planet" "plot" "pre=
 processor" "profile" "r5rs" "r6rs" "racket" "racklog" "rackunit" "raclog" "=
 raco" "racunit" "reader" "readline" "redex" "repo-time-stamp" "repos-time-s=
 tamp" "rnrs" "s-!
 > =C2=A0exp" "schelog" "scheme" "schemeunit" "scribble" "scribblings" "scri=
 blib" "setup" "sgl" "sirmail" "slatex" "slideshow" "srfi" "srpersist" "step=
 per" "string-constants" "swindle" "syntax" "syntax-color" "teachpack" "test=
 -box-recovery" "test-engine" "tests" "tex2page" "texpict" "tool" "trace" "t=
 yped" "typed-scheme" "unstable" "version" "waterworld" "web-server" "wxme" =
 "xml"))
 > Computer Language: (("Determine language from source") (#(#t print mixed-=
 fraction-e #f #t debug) (default) #() "#lang racket\n" #t))
 >
 >
Responsible changed from "nobody" to "eli" by eli at racket-lang.org at Tue, 23 Nov 2010 10:36:44 -0500
Reason>>> A commit by eli at racket-lang.org has resolved this report
  http://git.racket-lang.org/plt/commit/f3c62a0efd
State changed from "open" to "closed" by eli at racket-lang.org at Tue, 23 Nov 2010 10:36:44 -0500
Reason>>> A commit by eli at racket-lang.org has resolved this report
  http://git.racket-lang.org/plt/commit/f3c62a0efd
From: Eli Barzilay <eli at barzilay.org>
To: matthias at ccs.neu.edu, bugs at racket-lang.org
Cc: bug-notification at racket-lang.org
Subject: Re: [racket-bug] all/11458: lazy take fails to raise exceptions; lazy is NOT Haskell!
Date: Tue, 23 Nov 2010 10:36:34 -0500

 Yesterday, matthias at ccs.neu.edu wrote:
 > 1. run 
 > 
 > #lang lazy
 > (take -1 '(1 2 3))
 > 
 > and see nothing printed. Why? 
 
 It was a bug.  See also the bad error message for (take 'x '(1 2 3)).
 
 
 > 2. This should also be an exception in a real language. 
 > Only toys like Haskell can afford not to raise an error
 > here. 
 
 +1 to what Robby said -- I can't make sense of this, it's a bug in
 lazy since it's trying to stay close to the plain language, but in
 haskell there's more freedom to not throw an error because:
 
 * Throwing an error when the number is too big is questionable, and my
   `take' (the fixed one wrt the above) doesn't do that.  The reason is
   that you'd get an error later which is much less useful.  (I don't
   have any strong opinion on avoiding this -- if you think it's
   necessary I'll add it.)
 
 * Once they don't do that, it seems more natural to also not throw an
   error in case of an index that is too small.  Perhaps the bolted on
   the negative case later, as a kind of an obvious easy-to-fix error.
 
 -- 
           ((lambda (x) (x x)) (lambda (x) (x x)))          Eli Barzilay:
                     http://barzilay.org/                   Maze is Life!
From: Robby Findler <robby at eecs.northwestern.edu>
To: Eli Barzilay <eli at barzilay.org>
Cc: matthias at ccs.neu.edu, bugs at racket-lang.org,
        bug-notification at racket-lang.org
Subject: Re: [racket-bug] all/11458: lazy take fails to raise exceptions; lazy
 is NOT Haskell!
Date: Tue, 23 Nov 2010 09:59:27 -0600

 FWIW, I like the version with the more errors. :)
 
 Robby
 
 On Tue, Nov 23, 2010 at 9:36 AM, Eli Barzilay <eli at barzilay.org> wrote:
 > Yesterday, matthias at ccs.neu.edu wrote:
 >> 1. run
 >>
 >> #lang lazy
 >> (take -1 '(1 2 3))
 >>
 >> and see nothing printed. Why?
 >
 > It was a bug. =C2=A0See also the bad error message for (take 'x '(1 2 3))=
 .
 >
 >
 >> 2. This should also be an exception in a real language.
 >> Only toys like Haskell can afford not to raise an error
 >> here.
 >
 > +1 to what Robby said -- I can't make sense of this, it's a bug in
 > lazy since it's trying to stay close to the plain language, but in
 > haskell there's more freedom to not throw an error because:
 >
 > * Throwing an error when the number is too big is questionable, and my
 > =C2=A0`take' (the fixed one wrt the above) doesn't do that. =C2=A0The rea=
 son is
 > =C2=A0that you'd get an error later which is much less useful. =C2=A0(I d=
 on't
 > =C2=A0have any strong opinion on avoiding this -- if you think it's
 > =C2=A0necessary I'll add it.)
 >
 > * Once they don't do that, it seems more natural to also not throw an
 > =C2=A0error in case of an index that is too small. =C2=A0Perhaps the bolt=
 ed on
 > =C2=A0the negative case later, as a kind of an obvious easy-to-fix error.
 >
 > --
 > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0((lambda (x) (x x)) (lambda (x) (x x)))=
  =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0Eli Barzilay:
 > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0http=
 ://barzilay.org/ =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
 =C2=A0 Maze is Life!
 >
From: Matthias Felleisen <matthias at ccs.neu.edu>
To: Robby Findler <robby at eecs.northwestern.edu>
Cc: Eli Barzilay <eli at barzilay.org>, bugs at racket-lang.org,
        bug-notification at racket-lang.org
Subject: Re: [racket-bug] all/11458: lazy take fails to raise exceptions; lazy is NOT Haskell!
Date: Tue, 23 Nov 2010 12:04:29 -0500

 So we're in agreement: +1 to what Robby says. 
 
 Throw an exception for heavens sake. We are not purists. 
 
 
 On Nov 23, 2010, at 10:59 AM, Robby Findler wrote:
 
 > FWIW, I like the version with the more errors. :)
 > 
 > Robby
 > 
 > On Tue, Nov 23, 2010 at 9:36 AM, Eli Barzilay <eli at barzilay.org> wrote:
 >> Yesterday, matthias at ccs.neu.edu wrote:
 >>> 1. run
 >>> 
 >>> #lang lazy
 >>> (take -1 '(1 2 3))
 >>> 
 >>> and see nothing printed. Why?
 >> 
 >> It was a bug.  See also the bad error message for (take 'x '(1 2 3)).
 >> 
 >> 
 >>> 2. This should also be an exception in a real language.
 >>> Only toys like Haskell can afford not to raise an error
 >>> here.
 >> 
 >> +1 to what Robby said -- I can't make sense of this, it's a bug in
 >> lazy since it's trying to stay close to the plain language, but in
 >> haskell there's more freedom to not throw an error because:
 >> 
 >> * Throwing an error when the number is too big is questionable, and my
 >>  `take' (the fixed one wrt the above) doesn't do that.  The reason is
 >>  that you'd get an error later which is much less useful.  (I don't
 >>  have any strong opinion on avoiding this -- if you think it's
 >>  necessary I'll add it.)
 >> 
 >> * Once they don't do that, it seems more natural to also not throw an
 >>  error in case of an index that is too small.  Perhaps the bolted on
 >>  the negative case later, as a kind of an obvious easy-to-fix error.
 >> 
 >> --
 >>          ((lambda (x) (x x)) (lambda (x) (x x)))          Eli Barzilay:
 >>                    http://barzilay.org/                   Maze is Life!
 >> 
 

----------
A commit by eli at racket-lang.org was marked as relevant
  http://git.racket-lang.org/plt/commit/698b3a6c90
From: Eli Barzilay <eli at barzilay.org>
To: Matthias Felleisen <matthias at ccs.neu.edu>
Cc: Robby Findler <robby at eecs.northwestern.edu>, bugs at racket-lang.org,
        bug-notification at racket-lang.org
Subject: Re: [racket-bug] all/11458: lazy take fails to raise exceptions; lazy is NOT Haskell!
Date: Tue, 23 Nov 2010 14:16:28 -0500

 Done.  Note some things that are likely to be disturbing:
 
   > (car (take 30 '(1 2 3)))
   1
 
 That one is obvious.  But in this one:
 
   > (!! (take 30 '(1 2 3)))
   take: index 30 too large for input list
 
 there's no information about the list that was too short.  The code
 *could* hold on to the original list and report it at this point --
 since it knows that the list is finite when it reaches the '(), but
 doing so means that it holds a reference to the beginning of the list
 and prevents racket from marking the input as no-longer-needed, which
 means that doing that will lead to a memory leak.  There's not much to
 do about this.
 
 
 
 Two hours ago, Matthias Felleisen wrote:
 > 
 > So we're in agreement: +1 to what Robby says. 
 > 
 > Throw an exception for heavens sake. We are not purists. 
 > 
 > 
 > On Nov 23, 2010, at 10:59 AM, Robby Findler wrote:
 > 
 > > FWIW, I like the version with the more errors. :)
 
 -- 
           ((lambda (x) (x x)) (lambda (x) (x x)))          Eli Barzilay:
                     http://barzilay.org/                   Maze is Life!
From: Matthias Felleisen <matthias at ccs.neu.edu>
To: Eli Barzilay <eli at barzilay.org>, stephen chang <stchang at ccs.neu.edu>,
        Christos Dimoulas <chrdimo at ccs.neu.edu>
Cc: Robby Findler <robby at eecs.northwestern.edu>, bugs at racket-lang.org,
        bug-notification at racket-lang.org
Subject: Re: [racket-bug] all/11458: lazy take fails to raise exceptions; lazy is NOT Haskell!
Date: Tue, 23 Nov 2010 14:35:39 -0500

 (take 30 '(1 2 3)) should not succeed.=20
 
 Yes, I can see how someone could say=20
 
  (first (take 30 '(1 2 3)))
 
 doesn't need to be as strict as finding 30 cons cells in a stream. But I =
 think that this is taking laziness a bit too seriously.=20
 
 The take function could have two different meanings:=20
 
  -- force the first N cons cells & fail if there aren't that many=20
  -- start forcing the first N cons cell but only complete the job if the =
 context demands it=20
 
 Both are lazy functions. I understand that the second one is the meaning =
 derived from the natural re-interpretation of the program text of take =
 in a lazy context but who says this is good for the programmer.=20
 
 [I cced Stephen because of lazy and Christos because of contract.]
 
 
 
 
 
 
 On Nov 23, 2010, at 2:16 PM, Eli Barzilay wrote:
 
 > Done.  Note some things that are likely to be disturbing:
 >=20
 >> (car (take 30 '(1 2 3)))
 >  1
 >=20
 > That one is obvious.  But in this one:
 >=20
 >> (!! (take 30 '(1 2 3)))
 >  take: index 30 too large for input list
 >=20
 > there's no information about the list that was too short.  The code
 > *could* hold on to the original list and report it at this point --
 > since it knows that the list is finite when it reaches the '(), but
 > doing so means that it holds a reference to the beginning of the list
 > and prevents racket from marking the input as no-longer-needed, which
 > means that doing that will lead to a memory leak.  There's not much to
 > do about this.
 >=20
 >=20
 >=20
 > Two hours ago, Matthias Felleisen wrote:
 >>=20
 >> So we're in agreement: +1 to what Robby says.=20
 >>=20
 >> Throw an exception for heavens sake. We are not purists.=20
 >>=20
 >>=20
 >> On Nov 23, 2010, at 10:59 AM, Robby Findler wrote:
 >>=20
 >>> FWIW, I like the version with the more errors. :)
 >=20
 > --=20
 >          ((lambda (x) (x x)) (lambda (x) (x x)))          Eli =
 Barzilay:
 >                    http://barzilay.org/                   Maze is =
 Life!
 
From: Eli Barzilay <eli at barzilay.org>
To: Matthias Felleisen <matthias at ccs.neu.edu>
Cc: stephen chang <stchang at ccs.neu.edu>,
        Christos Dimoulas <chrdimo at ccs.neu.edu>,
        Robby Findler <robby at eecs.northwestern.edu>, bugs at racket-lang.org,
        bug-notification at racket-lang.org
Subject: Re: [racket-bug] all/11458: lazy take fails to raise exceptions; lazy is NOT Haskell!
Date: Tue, 23 Nov 2010 14:44:03 -0500

 Two minutes ago, Matthias Felleisen wrote:
 > 
 > (take 30 '(1 2 3)) should not succeed. 
 > 
 > Yes, I can see how someone could say 
 > 
 >  (first (take 30 '(1 2 3)))
 > 
 > doesn't need to be as strict as finding 30 cons cells in a stream.
 > But I think that this is taking laziness a bit too seriously.
 > 
 > The take function could have two different meanings:
 > 
 >  -- force the first N cons cells & fail if there aren't that many
 >  -- start forcing the first N cons cell but only complete the job if
 >     the context demands it
 > 
 > Both are lazy functions. I understand that the second one is the
 > meaning derived from the natural re-interpretation of the program
 > text of take in a lazy context but who says this is good for the
 > programmer.
 
 I think that the main surprise in the first version (which is really
 very different from the second one (which is what's currently
 implemented)) is that as a user of a lazy language you expect things
 to always be lazy enough that (second (take 99999999 foo)) should not
 explode your memory.  IMO the current version chooses the least
 surprising behavior.  If not, then I'd also suspect (build-list
 9999999 foo) to not build the list lazily, and maybe also things like
 (map foo l1 l2) with lists of different lengths.
 
 An alternative way to look at this is that what you really want (or my
 guess of what you really want) is a proper way to distinguish infinite
 lists from finite ones -- which is (IMO) much better to do as an
 addition of lazy streams in plain racket than eager ones in lazy.
 
 -- 
           ((lambda (x) (x x)) (lambda (x) (x x)))          Eli Barzilay:
                     http://barzilay.org/                   Maze is Life!
From: Matthias Felleisen <matthias at ccs.neu.edu>
To: Eli Barzilay <eli at barzilay.org>
Cc: stephen chang <stchang at ccs.neu.edu>,
        Christos Dimoulas <chrdimo at ccs.neu.edu>,
        Robby Findler <robby at eecs.northwestern.edu>, bugs at racket-lang.org,
        bug-notification at racket-lang.org
Subject: Re: [racket-bug] all/11458: lazy take fails to raise exceptions; lazy is NOT Haskell!
Date: Tue, 23 Nov 2010 18:03:31 -0500

 You have convinced me. Leave take's n > length l behavior alone for now.=20=
 
 
 (Christos: this is a good example to keep in mind about 'lazy' contracts =
 because=20
 
    (and (<=3D 0 n) (< n (length l)))
 
 is the contract statement for take and length would clearly access too =
 many items in the regular case.)=20
 
 
 
 On Nov 23, 2010, at 2:44 PM, Eli Barzilay wrote:
 
 > Two minutes ago, Matthias Felleisen wrote:
 >>=20
 >> (take 30 '(1 2 3)) should not succeed.=20
 >>=20
 >> Yes, I can see how someone could say=20
 >>=20
 >> (first (take 30 '(1 2 3)))
 >>=20
 >> doesn't need to be as strict as finding 30 cons cells in a stream.
 >> But I think that this is taking laziness a bit too seriously.
 >>=20
 >> The take function could have two different meanings:
 >>=20
 >> -- force the first N cons cells & fail if there aren't that many
 >> -- start forcing the first N cons cell but only complete the job if
 >>    the context demands it
 >>=20
 >> Both are lazy functions. I understand that the second one is the
 >> meaning derived from the natural re-interpretation of the program
 >> text of take in a lazy context but who says this is good for the
 >> programmer.
 >=20
 > I think that the main surprise in the first version (which is really
 > very different from the second one (which is what's currently
 > implemented)) is that as a user of a lazy language you expect things
 > to always be lazy enough that (second (take 99999999 foo)) should not
 > explode your memory.  IMO the current version chooses the least
 > surprising behavior.  If not, then I'd also suspect (build-list
 > 9999999 foo) to not build the list lazily, and maybe also things like
 > (map foo l1 l2) with lists of different lengths.
 >=20
 > An alternative way to look at this is that what you really want (or my
 > guess of what you really want) is a proper way to distinguish infinite
 > lists from finite ones -- which is (IMO) much better to do as an
 > addition of lazy streams in plain racket than eager ones in lazy.
 >=20
 > --=20
 >          ((lambda (x) (x x)) (lambda (x) (x x)))          Eli =
 Barzilay:
 >                    http://barzilay.org/                   Maze is =
 Life!
 
From: Robby Findler <robby at eecs.northwestern.edu>
To: Matthias Felleisen <matthias at ccs.neu.edu>
Cc: Eli Barzilay <eli at barzilay.org>, stephen chang <stchang at ccs.neu.edu>,
        Christos Dimoulas <chrdimo at ccs.neu.edu>, bugs at racket-lang.org,
        bug-notification at racket-lang.org
Subject: Re: [racket-bug] all/11458: lazy take fails to raise exceptions; lazy
 is NOT Haskell!
Date: Tue, 23 Nov 2010 19:01:38 -0600

 FWIW, this example is exactly the kind of thing that the haskell
 contract guys worry about. It is what motivated Chitil's three or so
 papers on the subject and that's what Simon PJ likes to talk about too
 so you will probably see it in his student's work somewhere.
 
 Robby
 
 On Tue, Nov 23, 2010 at 5:03 PM, Matthias Felleisen
 <matthias at ccs.neu.edu> wrote:
 >
 > You have convinced me. Leave take's n > length l behavior alone for now.
 >
 > (Christos: this is a good example to keep in mind about 'lazy' contracts =
 because
 >
 > =C2=A0 (and (<=3D 0 n) (< n (length l)))
 >
 > is the contract statement for take and length would clearly access too ma=
 ny items in the regular case.)
 >
 >
 >
 > On Nov 23, 2010, at 2:44 PM, Eli Barzilay wrote:
 >
 >> Two minutes ago, Matthias Felleisen wrote:
 >>>
 >>> (take 30 '(1 2 3)) should not succeed.
 >>>
 >>> Yes, I can see how someone could say
 >>>
 >>> (first (take 30 '(1 2 3)))
 >>>
 >>> doesn't need to be as strict as finding 30 cons cells in a stream.
 >>> But I think that this is taking laziness a bit too seriously.
 >>>
 >>> The take function could have two different meanings:
 >>>
 >>> -- force the first N cons cells & fail if there aren't that many
 >>> -- start forcing the first N cons cell but only complete the job if
 >>> =C2=A0 =C2=A0the context demands it
 >>>
 >>> Both are lazy functions. I understand that the second one is the
 >>> meaning derived from the natural re-interpretation of the program
 >>> text of take in a lazy context but who says this is good for the
 >>> programmer.
 >>
 >> I think that the main surprise in the first version (which is really
 >> very different from the second one (which is what's currently
 >> implemented)) is that as a user of a lazy language you expect things
 >> to always be lazy enough that (second (take 99999999 foo)) should not
 >> explode your memory. =C2=A0IMO the current version chooses the least
 >> surprising behavior. =C2=A0If not, then I'd also suspect (build-list
 >> 9999999 foo) to not build the list lazily, and maybe also things like
 >> (map foo l1 l2) with lists of different lengths.
 >>
 >> An alternative way to look at this is that what you really want (or my
 >> guess of what you really want) is a proper way to distinguish infinite
 >> lists from finite ones -- which is (IMO) much better to do as an
 >> addition of lazy streams in plain racket than eager ones in lazy.
 >>
 >> --
 >> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0((lambda (x) (x x)) (lambda (x) (x x))=
 ) =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0Eli Barzilay:
 >> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0htt=
 p://barzilay.org/ =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
 =C2=A0 Maze is Life!
 >
 >
From: Matthias Felleisen <matthias at ccs.neu.edu>
To: Robby Findler <robby at eecs.northwestern.edu>
Cc: Eli Barzilay <eli at barzilay.org>, stephen chang <stchang at ccs.neu.edu>,
        Christos Dimoulas <chrdimo at ccs.neu.edu>, bugs at racket-lang.org,
        bug-notification at racket-lang.org
Subject: Re: [racket-bug] all/11458: lazy take fails to raise exceptions; lazy is NOT Haskell!
Date: Tue, 23 Nov 2010 20:04:05 -0500

 Thanks we're aware of the papers.=20
 
 Simon et al's work, however, is NOT motivated by this problem as far as =
 we can tell.=20
 
 
 On Nov 23, 2010, at 8:01 PM, Robby Findler wrote:
 
 > FWIW, this example is exactly the kind of thing that the haskell
 > contract guys worry about. It is what motivated Chitil's three or so
 > papers on the subject and that's what Simon PJ likes to talk about too
 > so you will probably see it in his student's work somewhere.
 >=20
 > Robby
 >=20
 > On Tue, Nov 23, 2010 at 5:03 PM, Matthias Felleisen
 > <matthias at ccs.neu.edu> wrote:
 >>=20
 >> You have convinced me. Leave take's n > length l behavior alone for =
 now.
 >>=20
 >> (Christos: this is a good example to keep in mind about 'lazy' =
 contracts because
 >>=20
 >>   (and (<=3D 0 n) (< n (length l)))
 >>=20
 >> is the contract statement for take and length would clearly access =
 too many items in the regular case.)
 >>=20
 >>=20
 >>=20
 >> On Nov 23, 2010, at 2:44 PM, Eli Barzilay wrote:
 >>=20
 >>> Two minutes ago, Matthias Felleisen wrote:
 >>>>=20
 >>>> (take 30 '(1 2 3)) should not succeed.
 >>>>=20
 >>>> Yes, I can see how someone could say
 >>>>=20
 >>>> (first (take 30 '(1 2 3)))
 >>>>=20
 >>>> doesn't need to be as strict as finding 30 cons cells in a stream.
 >>>> But I think that this is taking laziness a bit too seriously.
 >>>>=20
 >>>> The take function could have two different meanings:
 >>>>=20
 >>>> -- force the first N cons cells & fail if there aren't that many
 >>>> -- start forcing the first N cons cell but only complete the job if
 >>>>    the context demands it
 >>>>=20
 >>>> Both are lazy functions. I understand that the second one is the
 >>>> meaning derived from the natural re-interpretation of the program
 >>>> text of take in a lazy context but who says this is good for the
 >>>> programmer.
 >>>=20
 >>> I think that the main surprise in the first version (which is really
 >>> very different from the second one (which is what's currently
 >>> implemented)) is that as a user of a lazy language you expect things
 >>> to always be lazy enough that (second (take 99999999 foo)) should =
 not
 >>> explode your memory.  IMO the current version chooses the least
 >>> surprising behavior.  If not, then I'd also suspect (build-list
 >>> 9999999 foo) to not build the list lazily, and maybe also things =
 like
 >>> (map foo l1 l2) with lists of different lengths.
 >>>=20
 >>> An alternative way to look at this is that what you really want (or =
 my
 >>> guess of what you really want) is a proper way to distinguish =
 infinite
 >>> lists from finite ones -- which is (IMO) much better to do as an
 >>> addition of lazy streams in plain racket than eager ones in lazy.
 >>>=20
 >>> --
 >>>          ((lambda (x) (x x)) (lambda (x) (x x)))          Eli =
 Barzilay:
 >>>                    http://barzilay.org/                   Maze is =
 Life!
 >>=20
 >>=20
 
From: Robby Findler <robby at eecs.northwestern.edu>
To: Matthias Felleisen <matthias at ccs.neu.edu>
Cc: Eli Barzilay <eli at barzilay.org>, stephen chang <stchang at ccs.neu.edu>,
        Christos Dimoulas <chrdimo at ccs.neu.edu>, bugs at racket-lang.org,
        bug-notification at racket-lang.org
Subject: Re: [racket-bug] all/11458: lazy take fails to raise exceptions; lazy
 is NOT Haskell!
Date: Tue, 23 Nov 2010 19:14:07 -0600

 The papers I saw of hers were motivated by some kind of static dynamic
 hybrid (trying to leverage the fact that ghc can prove lots of simple
 theorems already iiuc).
 
 Robby
 
 On Tue, Nov 23, 2010 at 7:04 PM, Matthias Felleisen
 <matthias at ccs.neu.edu> wrote:
 >
 > Thanks we're aware of the papers.
 >
 > Simon et al's work, however, is NOT motivated by this problem as far as w=
 e can tell.
 >
 >
 > On Nov 23, 2010, at 8:01 PM, Robby Findler wrote:
 >
 >> FWIW, this example is exactly the kind of thing that the haskell
 >> contract guys worry about. It is what motivated Chitil's three or so
 >> papers on the subject and that's what Simon PJ likes to talk about too
 >> so you will probably see it in his student's work somewhere.
 >>
 >> Robby
 >>
 >> On Tue, Nov 23, 2010 at 5:03 PM, Matthias Felleisen
 >> <matthias at ccs.neu.edu> wrote:
 >>>
 >>> You have convinced me. Leave take's n > length l behavior alone for now=
 .
 >>>
 >>> (Christos: this is a good example to keep in mind about 'lazy' contract=
 s because
 >>>
 >>> =C2=A0 (and (<=3D 0 n) (< n (length l)))
 >>>
 >>> is the contract statement for take and length would clearly access too =
 many items in the regular case.)
 >>>
 >>>
 >>>
 >>> On Nov 23, 2010, at 2:44 PM, Eli Barzilay wrote:
 >>>
 >>>> Two minutes ago, Matthias Felleisen wrote:
 >>>>>
 >>>>> (take 30 '(1 2 3)) should not succeed.
 >>>>>
 >>>>> Yes, I can see how someone could say
 >>>>>
 >>>>> (first (take 30 '(1 2 3)))
 >>>>>
 >>>>> doesn't need to be as strict as finding 30 cons cells in a stream.
 >>>>> But I think that this is taking laziness a bit too seriously.
 >>>>>
 >>>>> The take function could have two different meanings:
 >>>>>
 >>>>> -- force the first N cons cells & fail if there aren't that many
 >>>>> -- start forcing the first N cons cell but only complete the job if
 >>>>> =C2=A0 =C2=A0the context demands it
 >>>>>
 >>>>> Both are lazy functions. I understand that the second one is the
 >>>>> meaning derived from the natural re-interpretation of the program
 >>>>> text of take in a lazy context but who says this is good for the
 >>>>> programmer.
 >>>>
 >>>> I think that the main surprise in the first version (which is really
 >>>> very different from the second one (which is what's currently
 >>>> implemented)) is that as a user of a lazy language you expect things
 >>>> to always be lazy enough that (second (take 99999999 foo)) should not
 >>>> explode your memory. =C2=A0IMO the current version chooses the least
 >>>> surprising behavior. =C2=A0If not, then I'd also suspect (build-list
 >>>> 9999999 foo) to not build the list lazily, and maybe also things like
 >>>> (map foo l1 l2) with lists of different lengths.
 >>>>
 >>>> An alternative way to look at this is that what you really want (or my
 >>>> guess of what you really want) is a proper way to distinguish infinite
 >>>> lists from finite ones -- which is (IMO) much better to do as an
 >>>> addition of lazy streams in plain racket than eager ones in lazy.
 >>>>
 >>>> --
 >>>> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0((lambda (x) (x x)) (lambda (x) (x x=
 ))) =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0Eli Barzilay:
 >>>> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0h=
 ttp://barzilay.org/ =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0=
  =C2=A0 Maze is Life!
 >>>
 >>>
 >
 >