Re: [racket-dev] cross-phase syntax constants
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
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
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
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
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
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?
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
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
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
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?
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
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
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
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
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
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