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

2012-07-07 Thread Matthew Flatt
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

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

2012-07-07 Thread Matthias Felleisen

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

2012-07-07 Thread Matthias Felleisen

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

2012-07-07 Thread Matthias Felleisen


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?

2012-07-07 Thread Neil Toronto

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

2012-07-07 Thread Matthias Felleisen

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

2012-07-07 Thread Neil Toronto

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

2012-07-07 Thread Neil Toronto

#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

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