Re: [racket-dev] cross-phase syntax constants

2012-07-06 Thread Matthew Flatt
I find the example too abstract to understand why the computation
happens at the wrong phase when you adjust the code with
`begin-for-syntax'. Can you explain a little more, maybe with a more
concrete example?

Just in case, here's the code that I think you have in mind for wrong
phase:

 #lang racket/load

 (module m1 racket
   (define l (list #'l))
   (provide l))

 (module m2 racket
   (require (for-syntax 'm1))
   (define-syntax (mac stx)
 #`(begin-for-syntax
(module* sub #f
  (length (list #,(car l))
   (provide mac))

 (module m3 racket
   (require 'm2)
   (mac))

 (require (submod 'm3 sub))


At Thu, 5 Jul 2012 17:17:08 -0400, Sam Tobin-Hochstadt wrote:
 I'd like to write a program basically like this:
 
 #lang racket/load
 
 (module m1 racket
   (define l (list #'l))
   (provide l))
 
 (module m2 racket
   (require (for-syntax 'm1))
   (define-syntax (mac stx)
 #`(module* sub #f
 (length (list #,(car l)
   (provide mac))
 
 (module m3 racket
   (require 'm2)
   (mac))
 
 But I can't come up with any way to `require` m1 appropriately so that
 `l` is bound in the generated submodule.  If I wrap the body of the
 submodule in `begin-for-syntax`, then it works, but then loading the
 submodule does the computation at the wrong phase.  So another
 solution would be `dynamic-require-for-template`, if that's feasible.
 -- 
 sam th
 sa...@ccs.neu.edu
_
  Racket Developers list:
  http://lists.racket-lang.org/dev


Re: [racket-dev] cross-phase syntax constants

2012-07-06 Thread Sam Tobin-Hochstadt
On Fri, Jul 6, 2012 at 11:00 AM, Matthew Flatt mfl...@cs.utah.edu wrote:
 I find the example too abstract to understand why the computation
 happens at the wrong phase when you adjust the code with
 `begin-for-syntax'. Can you explain a little more, maybe with a more
 concrete example?

 Just in case, here's the code that I think you have in mind for wrong
 phase:

I had not realized that I could sensibly wrap a module in a
`begin-for-syntax`.  What is the semantic difference between that and
a plain submodule (other than my example working)?  I will try that,
and see if it works for my purposes.

 At Thu, 5 Jul 2012 17:17:08 -0400, Sam Tobin-Hochstadt wrote:
 I'd like to write a program basically like this:

 #lang racket/load

 (module m1 racket
   (define l (list #'l))
   (provide l))

 (module m2 racket
   (require (for-syntax 'm1))
   (define-syntax (mac stx)
 #`(module* sub #f
 (length (list #,(car l)
   (provide mac))

 (module m3 racket
   (require 'm2)
   (mac))

 But I can't come up with any way to `require` m1 appropriately so that
 `l` is bound in the generated submodule.  If I wrap the body of the
 submodule in `begin-for-syntax`, then it works, but then loading the
 submodule does the computation at the wrong phase.  So another
 solution would be `dynamic-require-for-template`, if that's feasible.
 --
 sam th
 sa...@ccs.neu.edu



-- 
sam th
sa...@ccs.neu.edu
_
  Racket Developers list:
  http://lists.racket-lang.org/dev


Re: [racket-dev] cross-phase syntax constants

2012-07-06 Thread Matthew Flatt
At Fri, 6 Jul 2012 11:13:44 -0400, Sam Tobin-Hochstadt wrote:
 I had not realized that I could sensibly wrap a module in a
 `begin-for-syntax`.  What is the semantic difference between that and
 a plain submodule (other than my example working)?

For `(module* _name #f )', `begin-for-syntax' shifts the phase
level of the enclosing module's bindings relative to the submodule. An
enclosing `begin-for-syntax' has no effect on a `module' submodule or
`module*' with a module path instead of `#f', though.

(This is documented with `module*'.)

_
  Racket Developers list:
  http://lists.racket-lang.org/dev


Re: [racket-dev] A very listy Typed Racket Integer

2012-07-06 Thread Sam Tobin-Hochstadt
On Fri, Jul 6, 2012 at 11:59 AM, Neil Toronto neil.toro...@gmail.com wrote:
 On 07/05/2012 05:54 PM, Sam Tobin-Hochstadt wrote:

 On Jul 5, 2012 8:50 PM, Neil Toronto neil.toro...@gmail.com
 mailto:neil.toro...@gmail.com wrote:
  
   (define-predicate boxof-integer? (Boxof Integer))

 This is the bug -- there's no way to write the boxof-integer? predicate,
 and define- predicate shouldn't think it can.


 Meaning no way that ensures preservation when some other piece of the
 program has a pointer to that box, right?

Right.

 Anticipating a bug fix, I've started converting my recent TR code so that it
 doesn't define predicates for mutable container types. Instead of using
 `define-predicate', I need to *copy* the mutable data structure, using
 occurrence typing on each immutable containee. It's kind of a pain, but I
 only have one type that needs this treatment.

Can you not do the checking *after* extracting the elements from the
container?  That may well be faster.

 It's actually a good thing to have to do this. Copying happens at the
 boundary between private code and user code, and ensures that user code
 can't violate the private code's invariants by mutating private data.

 If I had more to change, it'd be a major hassle. Would a `define-converter'
 be possible for mutable container types? Here's an example:

 (define-converter (make-vectorof T) (Vectorof T))

 #;(: make-vectorof (All (A B) ((A - Boolean : B)
(Vectorof A) - (U False (Vectorof B)
 ;; Receives a predicate that indicates `B' instances and a vector
 ;; Returns #f when every `A' in the vector isn't also a `B'

 (: ds (Vectorof Integer))
 (define ds (build-vector 10 identity))

 (: idx-ds (U False (Vectorof Index)))
 (define idx-ds (make-vectorof index? ds))  ; possibly makes a copy

 (cond [idx-ds  ...]  ; idx-ds is a (Vectorof Index)
   [else  ...])   ; it's not

I'm confused about what this does.  When does it copy, and when does
it produce `#false`?

 Of course, this wouldn't leverage the contract system nicely like
 define-predicate does.

And in general, implicitly copying mutable data seems like a bad idea
-- mutable data is for sharing.

 I could also maintain invariants easily if I had an Immutable-Vectorof type.
 But that doesn't help with the fact that subtyping and occurrence typing
 don't work nicely on parameterized mutable types.

Right.  Unfortunately, that's a pretty fundamental feature of
languages with mutation and aliasing.
-- 
sam th
sa...@ccs.neu.edu
_
  Racket Developers list:
  http://lists.racket-lang.org/dev


Re: [racket-dev] A very listy Typed Racket Integer

2012-07-06 Thread Neil Toronto

On 07/06/2012 09:11 AM, Sam Tobin-Hochstadt wrote:

On Fri, Jul 6, 2012 at 11:59 AM, Neil Toronto neil.toro...@gmail.com wrote:

Anticipating a bug fix, I've started converting my recent TR code so that it
doesn't define predicates for mutable container types. Instead of using
`define-predicate', I need to *copy* the mutable data structure, using
occurrence typing on each immutable containee. It's kind of a pain, but I
only have one type that needs this treatment.


Can you not do the checking *after* extracting the elements from the
container?  That may well be faster.


I can't maintain my invariants that way, because the same user code that 
sent the container might change the contained values.



(define-converter (make-vectorof T) (Vectorof T))

#;(: make-vectorof (All (A B) ((A - Boolean : B)
(Vectorof A) - (U False (Vectorof B)
;; Receives a predicate that indicates `B' instances and a vector
;; Returns #f when every `A' in the vector isn't also a `B'

[...]


I'm confused about what this does.  When does it copy, and when does
it produce `#false`?


Here's a case where `make-vectorof' copies:

(define ds (vector 0 1 2 3))
(make-vectorof index? ds)

Here's a case where `make-vectorof' returns #f:

;; (expt 2 60) is not an Index on any platform:
(define ds (vector (expt 2 60)))
(make-vectorof index? ds)


Of course, this wouldn't leverage the contract system nicely like
define-predicate does.


And in general, implicitly copying mutable data seems like a bad idea
-- mutable data is for sharing.


I don't read `(make-vectorof index? ds)' as implicit.

It's generally true that mutable data is for sharing. But sometimes I 
don't intend to share mutable data; for example, when using a mutable 
data structure is a lot faster than using its functional counterpart. In 
that case, there's no way to follow basic user-interface guidelines for 
typing functions; i.e. to have general argument types and precise return 
types.


It's kind of a moot point now, anyway. I've decided to receive (Listof 
Integer) and return (Listof Index), and convert them to and from 
vectors. Lists will subtype nicely for my library users.


Neil ⊥
_
 Racket Developers list:
 http://lists.racket-lang.org/dev


[racket-dev] Uninterned symbols in compiled code

2012-07-06 Thread Carl Eastlund
The documentation for generate-temporaries[1] ends with, The
generated identifiers are built with interned symbols (not gensyms),
so the limitations described with current-compile do not apply.
However, I cannot find any limitations described in the documentation
for current-compile[2].  If I follow a link there to documentation on
printing compiled code[3], I find the following paragraph:

A compiled-form object may contain uninterned symbols (see Symbols)
that were created by gensym or string-uninterned-symbol. When the
compiled object is read via #~, each uninterned symbol in the original
form is mapped to a new uninterned symbol, where multiple instances of
a single symbol are consistently mapped to the same new symbol. The
original and new symbols have the same printed representation.
Unreadable symbols, which are typically generated indirectly during
expansion and compilation, are saved and restored consistently through
#~.

I'm unsure whether this corresponds to the limitations that
generate-temporaries refers to.  This certainly looks to me like it
does the right thing with uninterned symbols in compiled code, but
I'm probably ignoring an important subtlety.  Can someone please
clarify this issue, here and/or in the documentation?  An example of
the kind of problem that arises when using gensym in compiled code
would be wonderful.

Carl Eastlund

[1] 
http://docs.racket-lang.org/reference/stxops.html#%28def._%28%28lib._racket/private/stxcase-scheme..rkt%29._generate-temporaries%29%29

[2] 
http://docs.racket-lang.org/reference/eval.html#%28def._%28%28quote._~23~25kernel%29._current-compile%29%29

[3] 
http://docs.racket-lang.org/reference/printing.html#%28part._print-compiled%29
_
  Racket Developers list:
  http://lists.racket-lang.org/dev


[racket-dev] Redex site down?

2012-07-06 Thread Jonathan Schuster
Has anyone noticed that the Redex website appears to be down? When I go to
http://redex.racket-lang.org/ , all I get is an index page listing a bunch
of Racket/Scheme source files.
_
  Racket Developers list:
  http://lists.racket-lang.org/dev


Re: [racket-dev] Uninterned symbols in compiled code

2012-07-06 Thread Carl Eastlund
On Fri, Jul 6, 2012 at 3:06 PM, Matthew Flatt mfl...@cs.utah.edu wrote:
 At Fri, 6 Jul 2012 12:59:34 -0600, Matthew Flatt wrote:
 As I try to make an example illustrating problems, I see that Racket is
 more resistant to problems created by `gensym' than I expected.

 Ah --- one more level of indirection demonstrates the sort of trouble
 that I expected. If you compile only a.rkt and b.rkt below with
 `raco make b.rkt', then `racket c.rkt' doesn't work.

Thanks, Matthew, having a setup that creates a predictable error is
illuminating.

--Carl
_
  Racket Developers list:
  http://lists.racket-lang.org/dev


Re: [racket-dev] Uninterned symbols in compiled code

2012-07-06 Thread Carl Eastlund
On Fri, Jul 6, 2012 at 3:11 PM, Carl Eastlund c...@ccs.neu.edu wrote:
 On Fri, Jul 6, 2012 at 3:06 PM, Matthew Flatt mfl...@cs.utah.edu wrote:
 At Fri, 6 Jul 2012 12:59:34 -0600, Matthew Flatt wrote:
 As I try to make an example illustrating problems, I see that Racket is
 more resistant to problems created by `gensym' than I expected.

 Ah --- one more level of indirection demonstrates the sort of trouble
 that I expected. If you compile only a.rkt and b.rkt below with
 `raco make b.rkt', then `racket c.rkt' doesn't work.

 Thanks, Matthew, having a setup that creates a predictable error is
 illuminating.

While I'm thinking about this -- since gensym in macros is a common
error, is it possible we could fix it so that it works?  The unique
marks on generate-temporaries's output are marshalled in a way that
ensures marks in one module are consistent with others, I believe by
tracking the originating module.  Would it be possible to do the same
thing with uninterned symbols in compiled code, keeping around a
reference to the originating module to preserve eq?-ness?

--Carl
_
  Racket Developers list:
  http://lists.racket-lang.org/dev


[racket-dev] promise vs polym contracts

2012-07-06 Thread Matthias Felleisen

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


Re: [racket-dev] Redex site down?

2012-07-06 Thread Eli Barzilay
50 minutes ago, Jonathan Schuster wrote:
 Has anyone noticed that the Redex website appears to be down? When I
 go to http://redex.racket-lang.org/ , all I get is an index page
 listing a bunch of Racket/Scheme source files.

Yeah, that was a server misconfiguration -- thanks for reporting it.
It's fixed now, and I've improved the code to avoid such problems in
the future.

-- 
  ((lambda (x) (x x)) (lambda (x) (x x)))  Eli Barzilay:
http://barzilay.org/   Maze is Life!
_
  Racket Developers list:
  http://lists.racket-lang.org/dev


Re: [racket-dev] promise vs polym contracts

2012-07-06 Thread Robby Findler
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


Re: [racket-dev] promise vs polym contracts

2012-07-06 Thread Matthias Felleisen

I can't think of such a primitive other than force, for which it is okay. Can 
you be concrete? 



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


Re: [racket-dev] promise vs polym contracts

2012-07-06 Thread Sam Tobin-Hochstadt
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


Re: [racket-dev] promise vs polym contracts

2012-07-06 Thread Carl Eastlund
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


Re: [racket-dev] promise vs polym contracts

2012-07-06 Thread Robby Findler
Lets say I have a function that gets a list of promises or lists. It
is going to print out the state of some ongoing computation (that is
producing these lists). It will print the list, if there's a list, and
it will print pending if it is a promise; it doesn't want to force
it, since it is just a view.

Somewhere else, something is building new lists-- when it decides to
force something, it replaces the promise in the list with the forced
value and then hands a new list off to the view.

(But in general, it just seems useful to be able to ask if something
is a promise without forcing it.)

Robby

On Fri, Jul 6, 2012 at 4: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?



 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