Re: [racket-dev] Uninterned symbols in compiled code
At Fri, 6 Jul 2012 15:19:25 -0400, Carl Eastlund wrote: 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? I think this could be made to work in the case of use a gensym for an identifier. Different bytecode loads would still produce different gensyms, but an identifier based on a gensym could still get its binding from the originating module in the same way as an identifier from `generate-temporaries'. I'll try that out sometime. _ Racket Developers list: http://lists.racket-lang.org/dev
Re: [racket-dev] Uninterned symbols in compiled code
On Sat, Jul 7, 2012 at 8:38 AM, Matthew Flatt mfl...@cs.utah.edu wrote: At Fri, 6 Jul 2012 15:19:25 -0400, Carl Eastlund wrote: 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? I think this could be made to work in the case of use a gensym for an identifier. Different bytecode loads would still produce different gensyms, but an identifier based on a gensym could still get its binding from the originating module in the same way as an identifier from `generate-temporaries'. I'll try that out sometime. Okay -- to be clear, gensym in identifiers might work, but gensym in quoted literals would not? --Carl _ Racket Developers list: http://lists.racket-lang.org/dev
Re: [racket-dev] promise vs polym contracts
As Carl pointed out, I should explain more background. Stephen and I are exploring how to get laziness in Racket w/o going to Lazy Racket (in a sense). As I wrote the idea is to introduce laziness in a somewhat transparent manner, the way Sam introduces types in a mostly transparent manner (minus polymorphic exports and bugs). What this particularly means is that I do not want programs to change behavior silently. So yes you get promise? and you get force so that you can retrieve computations as needed. BUT it becomes your responsibility to force things for all strict functions/points in your language (e.g., add1, function application, if). If you forget to force there or insert a promise?, the language traps the value. ;; --- The more general idea is that there is an alternative design space out there where you want 'boxes' that signal errors when touched by strict functions. You need these every time you want transparent transitions from one point in the computational spectrum to another. ;; --- And one more level up, I am thinking of selling Racket as a wide-spectrum programming language, the first one that introduces safe or transparent transitions properly. -- Matthias, CPS p.s. Sam's version forces too early because strict functions should force not variable lookups. This is a common misconception among programmers. I suspect it goes back to Abelson and Sussman getting it wrong (see what happens if you don't understand the foundations). Then again, Racket is PITCO so in a sense the force is executed at the right place in this particular example, even though it was inserted in the wrong place. On Jul 6, 2012, at 8:19 PM, Robby Findler wrote: 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
Re: [racket-dev] promise vs polym contracts
I may have made a mistake under time pressure: [else (+ (force (sum (car x))) (force (sum (cdr x] On Jul 7, 2012, at 10:19 AM, Sam Tobin-Hochstadt wrote: On Sat, Jul 7, 2012 at 10:14 AM, Matthias Felleisen matth...@ccs.neu.edu wrote: p.s. Sam's version forces too early because strict functions should force not variable lookups. This is a common misconception among programmers. I suspect it goes back to Abelson and Sussman getting it wrong (see what happens if you don't understand the foundations). I still don't think my version forces too early -- your alternative contains no calls to `force` at all. Are you suggesting that I should `force` around the recursive calls to `sum`? In that case, clients are exposed to promises, and the result type is (U Integer (Promise Integer)). I can't tell from your description if you think that's an acceptable result. -- sam th sa...@ccs.neu.edu _ Racket Developers list: http://lists.racket-lang.org/dev
Re: [racket-dev] promise vs polym contracts
On Jul 7, 2012, at 10:27 AM, Sam Tobin-Hochstadt wrote: Right, that's what I thought. This is only different in that: (define v (delay (+ 1 2))) (sum v) ; = v Which means clients of `sum` now have to handle either Integers or Promises. Is that intentional? Yes. ;; --- Overall I feel like Bob Harper when he called me to say that he had figured out ML got it all wrong with let after he had read and understood the draft of Andrew's value restriction paper I had mailed him. Here is how he put it -- Omega has the wrong type on the right side of the let, you just don't notice. The real idea, which he developed a year later or so, was to map ML to a language with Lambda and then you see that let should be translated like this [[ let x = e in e' ]] . = let x = Lambda it. [[e]]. in [[e']]. where it is the inferred possibly forall-quantified type. Now you see that old ML shifted the semantics for Omega (and ref and callcc etc) w/o knowing it. In the purely functional case -- which everyone uses for papers and stuff -- you don't notice the shift from bottom to functional bottom or (which is what I conjectured) there are errors in old proofs. -- Matthias, CPS On Sat, Jul 7, 2012 at 10:23 AM, Matthias Felleisen matth...@ccs.neu.edu wrote: I may have made a mistake under time pressure: [else (+ (force (sum (car x))) (force (sum (cdr x] On Jul 7, 2012, at 10:19 AM, Sam Tobin-Hochstadt wrote: On Sat, Jul 7, 2012 at 10:14 AM, Matthias Felleisen matth...@ccs.neu.edu wrote: p.s. Sam's version forces too early because strict functions should force not variable lookups. This is a common misconception among programmers. I suspect it goes back to Abelson and Sussman getting it wrong (see what happens if you don't understand the foundations). I still don't think my version forces too early -- your alternative contains no calls to `force` at all. Are you suggesting that I should `force` around the recursive calls to `sum`? In that case, clients are exposed to promises, and the result type is (U Integer (Promise Integer)). I can't tell from your description if you think that's an acceptable result. -- sam th sa...@ccs.neu.edu -- sam th sa...@ccs.neu.edu _ Racket Developers list: http://lists.racket-lang.org/dev
[racket-dev] Custom write that pretty-prints and works well with quote?
I've got an array structure like so: (struct: (A) strict-array ([shape : (Listof Index)] [data : (Vectorof A)]) Say I have this value: (strict-array '(2 2) #(1 2 3 4)) I want it to print like this at the REPL: #strict-array '(2 2) '[[1 2] [3 4]] If there's not enough room, I want this: #strict-array '(2 2) '((1 2) (3 4)) If it happens to be in a list, I want this: (list #strict-array '(2 2) '[[1 2] [3 4]]) and definitely NOT '(#strict-array '(2 2) '[[1 2] [3 4]]) because the inner quotes are confusing. How do I do that with prop:custom-write? The only way I've found so far to get nicely formatted output is to write/display/print a list, but then the quotes get messed up. I haven't found a way to keep the REPL from quoting lists of structs, except to go with the default printer, which flattens arrays, which makes them hard to read. This is frustrating. Neil ⊥ _ Racket Developers list: http://lists.racket-lang.org/dev
[racket-dev] math
Neil, do you intend to provide differentiat and integrate and possibly adjoin operations on operators from your math collection? -- Matthias _ Racket Developers list: http://lists.racket-lang.org/dev
Re: [racket-dev] math
On 07/07/2012 01:39 PM, Matthias Felleisen wrote: Neil, do you intend to provide differentiat and integrate and possibly adjoin operations on operators from your math collection? I've considered numerical differentiation and integration. If you want them, I'll make sure they (eventually) get in. Can you explain adjoin operators on operators? Neil ⊥ _ Racket Developers list: http://lists.racket-lang.org/dev
[racket-dev] Overly general types for mutable containers
#lang typed/racket (define: x : Index 1) (: bar ((Vectorof Index) - (Vectorof Index))) (define (bar xs) xs) (: foo (All (A) ((Vectorof Index) - (Vectorof Index (define (foo xs) xs) So we have an Index `x' and a couple of identity functions `bar' and `foo' that only differ by the fact that `foo' is polymorphic. In the REPL: (vector x) - : (Vector Integer) '#(1) So we get a general type. I guess it's so literals like `(vector 0 1 0 1)' don't get overly-specific types like `(Vector Zero One Zero One)', for which non-trivial mutation would fail to typecheck. I respect that, but I have a problem with it: it's been surprising me too much. Here's a surprise that took 20 minutes to figure out: (bar (vector x)) - : (Vectorof Index) '#(1) (define xs (vector x)) (bar xs) Type Checker: Expected (Vectorof Index), but got (Vector Integer) in: xs I finally decided that there must be a special rule for applying functions like `bar' directly to `(vector x ...)', since the vector is never referred to except as a (Vectorof Index). Okay, that's one fewer circumstance in which `(vector x)' won't get an overly general type. One reason it took so long to figure out that special rule was this surprise, and the fact that I was working on a non-toy program and had to reduce the problem to this: (foo (vector x)) Type Checker: Polymorphic function foo could not be applied to arguments: Argument 1: Expected: (Vectorof Index) Given:(Vector Integer) in: (foo (vector x)) Remember that `foo' only differs from `bar' in that it's polymorphic, parameterized on a type `A' that it doesn't use. So that's one circumstance in which `(vector x)' gets an overly general type. Here's another reason it took a while to figure all this out: ((inst vector Index) x) - : (Vector Integer) '#(1) I expect Sam to declare that that's the bug, and possibly also the fact that `(foo (vector x))' doesn't type. But really, I think generalizing the container's types is the bug. It runs directly counter to what I expect from immutable containers, which I use most of the time: (list x) - : (Listof Index) [generalized from (List Index)] '(1) (list 0 1) - : (Listof (U Zero One)) [generalized from (List Zero One)] '(0 1) Honestly, I'd rather have to write `((inst vector Integer) 0 1 0 1)' or `(ann #(0 1 0 1) (Vectorof Index))' when I create literal vectors. Neil ⊥ _ Racket Developers list: http://lists.racket-lang.org/dev
Re: [racket-dev] Overly general types for mutable containers
On Sun, Jul 8, 2012 at 12:58 AM, Neil Toronto neil.toro...@gmail.com wrote: It runs directly counter to what I expect from immutable containers, which I use most of the time: This is the problem. Immutable containers are very different from mutable ones, and your expectations shouldn't be expected to carry over. Mutability is a communications channel, not just a data storage mechanism, and you should expect it to be different. -- sam th sa...@ccs.neu.edu _ Racket Developers list: http://lists.racket-lang.org/dev