Re: [racket-dev] Full transparency (was: dev Digest, Vol 72, Issue 31)

2015-01-29 Thread Byron Davies
Super!  Thank you.


On Thu, Jan 29, 2015 at 7:51 AM, Matthew Flatt mfl...@cs.utah.edu wrote:

 At Wed, 28 Jan 2015 16:21:51 -0700, Byron Davies wrote:
  Your code, commented:
 
  (define orig-i (current-inspector))  ; saves the original inspector
  (define sub-i (make-inspector orig-i))  ;make a new inspector whose
 parent
  is the original inspector
 
  (current-inspector sub-i)  ;makes the new inspector the current inspector
  (struct a (x))  ; creates a structure using the new inspector as the
  default inspector
  (define v (a 1))  ; creates an instance of the new structure
  (current-inspector orig-i) ;reverts the inspector to the original (the
  parent of the new inspector)
 
  I see how this works, but I'm a little confused about why it works.  I
 see
  that the new inspector is a child of the old one, and I read in the
  reference chapter that access is determined not by the inspector in force
  at creation time, but by the parent of that inspector, i.e., the old
  inspector. I can't find any description of the power of an inspector,
  except that the parent is more powerful.
 
  Are there degrees of power? Or if you have access to the parent do you
 have
  all the power you can have?

 There are degrees only in that you can have a hierarchy of inspectors.
 Inspector I is more powerful than inspector J if I is an ancestor of J.

 I'll try to improve the docs, such as replacing more powerful than
 with an ancestor of.

  I see that the inspector gives you access to
  the data in a structure instance, but does it also give you access to
  meta-data, so that I know that the name of the first field in struct a
 is x?

 You get access to all the metadata.

 It turns out that fields currently have only positions, not names, but
 that choice was not a good one. We plan to add support for field names
 in the near future, in which case the information will be accessible
 through an inspector.

  I also don't understand how the root inspector works.  I have found that
  setting (current-inspector root-inspector) delivers endless left parens
 for
  the (a 1) example, presumably because the display function recursively
  tries to inspect the components of the struct, all the way down.

 That's a problem in the pretty printer. The pretty printer's
 implementation includes

  (cond

[(struct? v) ]

[(unquoted? v) ]
)

 where `unquoted` is an internal structure. By setting the inspector to
 the root inspector, a value that satisfies `unquoted?` also satisfies
 `struct?`, and so printing doesn't reach the intended case. I'll push a
 repair.


  Finally, does this also work for classes?

 Yes. Reflective access to information via `object-info` and
 `class-info` is controlled by inspectors.


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


Re: [racket-dev] Full transparency (was: dev Digest, Vol 72, Issue 31)

2015-01-29 Thread Matthew Flatt
At Wed, 28 Jan 2015 16:21:51 -0700, Byron Davies wrote:
 Your code, commented:
 
 (define orig-i (current-inspector))  ; saves the original inspector
 (define sub-i (make-inspector orig-i))  ;make a new inspector whose parent
 is the original inspector
 
 (current-inspector sub-i)  ;makes the new inspector the current inspector
 (struct a (x))  ; creates a structure using the new inspector as the
 default inspector
 (define v (a 1))  ; creates an instance of the new structure
 (current-inspector orig-i) ;reverts the inspector to the original (the
 parent of the new inspector)
 
 I see how this works, but I'm a little confused about why it works.  I see
 that the new inspector is a child of the old one, and I read in the
 reference chapter that access is determined not by the inspector in force
 at creation time, but by the parent of that inspector, i.e., the old
 inspector. I can't find any description of the power of an inspector,
 except that the parent is more powerful.

 Are there degrees of power? Or if you have access to the parent do you have
 all the power you can have? 

There are degrees only in that you can have a hierarchy of inspectors.
Inspector I is more powerful than inspector J if I is an ancestor of J.

I'll try to improve the docs, such as replacing more powerful than
with an ancestor of.

 I see that the inspector gives you access to
 the data in a structure instance, but does it also give you access to
 meta-data, so that I know that the name of the first field in struct a is x?

You get access to all the metadata.

It turns out that fields currently have only positions, not names, but
that choice was not a good one. We plan to add support for field names
in the near future, in which case the information will be accessible
through an inspector.

 I also don't understand how the root inspector works.  I have found that
 setting (current-inspector root-inspector) delivers endless left parens for
 the (a 1) example, presumably because the display function recursively
 tries to inspect the components of the struct, all the way down.

That's a problem in the pretty printer. The pretty printer's
implementation includes

 (cond
   
   [(struct? v) ]
   
   [(unquoted? v) ]
   )

where `unquoted` is an internal structure. By setting the inspector to
the root inspector, a value that satisfies `unquoted?` also satisfies
`struct?`, and so printing doesn't reach the intended case. I'll push a
repair.


 Finally, does this also work for classes?

Yes. Reflective access to information via `object-info` and
`class-info` is controlled by inspectors.

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


Re: [racket-dev] build memory use (was: internal error during gc)

2015-01-29 Thread Matthew Flatt
At Thu, 29 Jan 2015 15:34:37 -0300, Gustavo Massaccesi wrote:
 If there are some easy technical details and advice, you can write a
 nice blog post about this.

Good idea. I have some advice on finalization (don't do it), and I
could write about how Racket tries to help when you can't follow that
advice.

 At line 109:
 +  (define max-val (apply max (map car measurements)))
 +  (define max-time (caddr (last measurements)))
 If you make multiple png at the same time, all of them get the same
 Peak and Duration.

Thanks! I had fixed that in http://github.com/racket/plt-build-plot,
but I forgot to update the service that uploads plot.rkt to the web
site. It will be fixed after the next run.

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


Re: [racket-dev] feature request: thread-safe memoize-evt

2015-01-29 Thread Matthew Flatt
Hi Jan,

Interesting problem!

I think I see what you mean: There's no way to combine the completion
of an event plus saving its value as an atomic operation, except by
putting the synchronization in its own thread. But if you put the
synchronization in its own thread, then there's no way to prevent that
thread's synchronization when a consumer synchronization (i.e., one
that is waiting for the thread's result) picks a different event than
the one represented by the thread.

It's easy to make a complete+save combination atomic if it's built into
the scheduler. So, I can easily imagine adding a simpler primitive,
`once-evt`. The event OE created by `(once-evt E)` could save the first
result produced by E, but not attempt to have only a single wait on E.
That is, if OE1 is synchronized in multiple threads, then it would be
like synchronizing E in multiple threads, but only the first result
from E will be saved.

Unfortunately, `once-evt` isn't enough to implement `memoize-evt`. The
troublesome case is then thread T1 is synchronizing on OE1, T1 gets
suspended, and T2 starts waiting on OE1. In that case, you'd like T2 to
take over the wait, even if it means restarting E. You can detect that
T1 is suspended and have T2 start waiting on E, but there's no way to
cancel the wait of E in T1.

Building `memoize-evt` into the core doesn't the avoid the need to, at
some level, cancel T1's wait on E. I'll keep thinking about it, but it
looks like that would require deep changes to the scheduler.

Would the simpler `once-evt` work in your situation, or do you need the
guarantee that only one wait of E happens at a time?

Matthew

At Wed, 28 Jan 2015 13:49:51 +0100, Jan Dvořák wrote:
 Hi,
 
 I would like to ask for another extension of the Racket's event handling
 system. A `memoize-evt` constructor with following semantics:
 
 Given a base event E_b, memoize-evt will produce a memoizing event E_m.
 Synchronizing on E_m from any number of threads will block until a
 single value is produced by E_b. This value is then stored inside the
 E_m. From that moment on, E_m will always be immediately ready for
 synchronization and produce the stored value in all waiting threads.
 
 The single-threaded implementation is a trivial guard-evt + replace-evt
 + (wrap-evt always-evt) combo, but for thread-safety a temporary thread
 would be needed to wait for the base event and the solution would have
 different semantics then rest of the event system.
 
 A lower-level approach would also be possible; create something along
 the lines of a dynamic-wind-evt that would, with some cleverness, allow
 for generic thread-safe events via locking. Or create a locked-wrap-evt
 constructor that will not be ready until it's handler finishes.
 
 Hoping that I am not being too bothersome,
 from Prague with thanks,
 Jan Dvorak


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


Re: [racket-dev] feature request: thread-safe memoize-evt

2015-01-29 Thread Robby Findler
Is the issue that the E_b from Jan's original message might produce
multiple values and you are supposed to take the value that's
available only after something syncs on the E_m?

That is, I thought you could just create a separate thread that sync's
on E_b and then whenever you get a value from it, then the E_m would
just continue to produce that all the time. But I think you're saying
that wouldn't work?

I guess I'm not getting it. Thanks for more explanation.

Robby


On Thu, Jan 29, 2015 at 1:55 PM, Matthew Flatt mfl...@cs.utah.edu wrote:
 Hi Jan,

 Interesting problem!

 I think I see what you mean: There's no way to combine the completion
 of an event plus saving its value as an atomic operation, except by
 putting the synchronization in its own thread. But if you put the
 synchronization in its own thread, then there's no way to prevent that
 thread's synchronization when a consumer synchronization (i.e., one
 that is waiting for the thread's result) picks a different event than
 the one represented by the thread.

 It's easy to make a complete+save combination atomic if it's built into
 the scheduler. So, I can easily imagine adding a simpler primitive,
 `once-evt`. The event OE created by `(once-evt E)` could save the first
 result produced by E, but not attempt to have only a single wait on E.
 That is, if OE1 is synchronized in multiple threads, then it would be
 like synchronizing E in multiple threads, but only the first result
 from E will be saved.

 Unfortunately, `once-evt` isn't enough to implement `memoize-evt`. The
 troublesome case is then thread T1 is synchronizing on OE1, T1 gets
 suspended, and T2 starts waiting on OE1. In that case, you'd like T2 to
 take over the wait, even if it means restarting E. You can detect that
 T1 is suspended and have T2 start waiting on E, but there's no way to
 cancel the wait of E in T1.

 Building `memoize-evt` into the core doesn't the avoid the need to, at
 some level, cancel T1's wait on E. I'll keep thinking about it, but it
 looks like that would require deep changes to the scheduler.

 Would the simpler `once-evt` work in your situation, or do you need the
 guarantee that only one wait of E happens at a time?

 Matthew

 At Wed, 28 Jan 2015 13:49:51 +0100, Jan Dvořák wrote:
 Hi,

 I would like to ask for another extension of the Racket's event handling
 system. A `memoize-evt` constructor with following semantics:

 Given a base event E_b, memoize-evt will produce a memoizing event E_m.
 Synchronizing on E_m from any number of threads will block until a
 single value is produced by E_b. This value is then stored inside the
 E_m. From that moment on, E_m will always be immediately ready for
 synchronization and produce the stored value in all waiting threads.

 The single-threaded implementation is a trivial guard-evt + replace-evt
 + (wrap-evt always-evt) combo, but for thread-safety a temporary thread
 would be needed to wait for the base event and the solution would have
 different semantics then rest of the event system.

 A lower-level approach would also be possible; create something along
 the lines of a dynamic-wind-evt that would, with some cleverness, allow
 for generic thread-safe events via locking. Or create a locked-wrap-evt
 constructor that will not be ready until it's handler finishes.

 Hoping that I am not being too bothersome,
 from Prague with thanks,
 Jan Dvorak


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

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


[racket-dev] A proposal for parametric opaque types in Typed Racket

2015-01-29 Thread Alexis King
I recently ran into a problem in which opaque types (types imported from 
untyped code) cannot by parameterized by Typed Racket. I initially encountered 
this problem in my attempt to port 2htdp/image to TR 
https://github.com/lexi-lambda/racket-2htdp-typed/issues/1.

After some further consideration, I’m interested in adding support to make 
something like this possible, which would certainly have additional benefits 
beyond this specific use-case. I’ve outlined my proposal here:
http://lexi-lambda.github.io/racket-parametric-opaque-types/ 
http://lexi-lambda.github.io/racket-parametric-opaque-types/

Any feedback, suggestions, or advice would be appreciated, especially from 
those who are familiar with Typed Racket’s internals.

Thank you,
Alexis_
  Racket Developers list:
  http://lists.racket-lang.org/dev


Re: [racket-dev] A proposal for parametric opaque types in Typed Racket

2015-01-29 Thread Alexis King
I think you’re reading too far into what I’m proposing, though I admit I 
probably didn’t give enough context. I’ve been talking with Sam about this 
issue on IRC, so he knows what I’m talking about, but I’ll try and clarify here.

This entire thing is just a fix for the problem described in Section 2 
http://lexi-lambda.github.io/racket-parametric-opaque-types/#(part._.Extending_parametricity_to_opaque_types).
 When using require/typed to import “opaque” types from untyped code, the 
imported types cannot be polymorphic. This entire proposal is simply a way to 
make that possible.

In Section 2.1, A is used in a number of places, but it is just a type 
parameter. See the typed struct definition in Section 1. A does not refer to a 
specific type but any type. Posn essentially becomes a new type combinator than 
can make new types by supplying it with any other type.

The other functions imported in Section 2.1 simply make use of Typed Racket’s 
polymorphic type utilities to make use of the fact that Posn is now a 
polymorphic type. The concepts here are simple. No semantics are being changed, 
it’s just extending parameterization to opaque types.

Sections 2.3 and 2.2, in contrast, are simply describing mechanisms for 
implementing the functionality outlined in 2.1.

Now to answer your points.

 - Should an A only be a base type like String or Symbol

A can by any type. It’s a type parameter. (Posn A) is like (Boxof A).

 - Do you mean to infer the type of the first thing put into the struct as the 
 exact type for everything else?

No, not really. Remember that Posn is an opaque type. TR has no idea it’s 
actually implemented as a struct. Perhaps the JSExpr example given in Section 3 
will help to illustrate that generality. This will just leverage the existing 
polymorphic type inference mechanisms TR already provides.

 - Would first class members prevent me from filling a struct with members 
 of (define-type (Option A) (U 'None (Some A))), where Some is a struct with 
 one field?

No, as I said, you can supply any type for A. By “first class member” of the 
type system, I simply meant that these types would have to be built-in to TR as 
a special case—they cannot be derived from the existing type constructs 
provided by TR. This is similar to how structure types are “first class” in 
TR—the struct form is “magical” and cannot be reimplemented in terms of other 
TR primitives.

I hope that helps to make things a little more clear.

 On Jan 29, 2015, at 19:44, Benjamin Greenman bl...@cornell.edu wrote:
 
 This has bothered me too, but I've realized that I was on the wrong track.
 
 The string a and symbol 'b are not different types. A struct (Foo a 'b), 
 or (list a 'b), is a homogeneous data structure of type (U String Symbol) 
 just like Alexander said. This really upsets me -- I like the Hindley Milner 
 world where the compiler warns me if I make a list [1, two] and forces me 
 to wrap the int and string into a new datatype. But Typed Racket is not HM.
 
 About the proposal, I'm confused about what the syntax in Section 2.1 should 
 do -- what is a first class member of Typed Racket's type system?
 - Should an A only be a base type like String or Symbol
 - Do you mean to infer the type of the first thing put into the struct as the 
 exact type for everything else?
 - Would first class members prevent me from filling a struct with members 
 of (define-type (Option A) (U 'None (Some A))), where Some is a struct with 
 one field?
 
 I totally agree that something needs fixing, but I'm not sure what.
 
 
 
 On Thu, Jan 29, 2015 at 10:13 PM, Alexis King lexi.lam...@gmail.com 
 mailto:lexi.lam...@gmail.com wrote:
 Or Any for that matter. I know. The fact that it could be literally anything 
 was sort of the point.
 
 On Jan 29, 2015, at 19:10, Alexander D. Knauth alexan...@knauth.org 
 mailto:alexan...@knauth.org wrote:
 
 Um, for this:
 (module 
 http://docs.racket-lang.org/reference/module.html#%28form._%28%28quote._~23~25kernel%29._module%29%29
  typed typed/racket/base
 (provide 
 http://docs.racket-lang.org/reference/require.html#%28form._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._provide%29%29
  (struct-out 
 http://docs.racket-lang.org/reference/require.html#%28form._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._struct-out%29%29
  Foo))
 (struct 
 http://docs.racket-lang.org/ts-reference/special-forms.html#%28form._%28%28lib._typed-racket%2Fbase-env%2Fprims..rkt%29._struct%29%29
  [A] Foo ([x : 
 http://docs.racket-lang.org/ts-reference/special-forms.html#%28form._%28%28lib._typed-racket%2Fbase-env%2Fprims..rkt%29._~3a%29%29
  A] [y : 
 http://docs.racket-lang.org/ts-reference/special-forms.html#%28form._%28%28lib._typed-racket%2Fbase-env%2Fprims..rkt%29._~3a%29%29
  A]) #:transparent))
 
 (Foo a 'b)
 Should be fine because Foo could be instantiated at the type (U String 
 Symbol).
 
 On Jan 29, 2015, at 9:25 PM, Alexis King lexi.lam...@gmail.com 
 mailto:lexi.lam...@gmail.com wrote:
 
 I 

Re: [racket-dev] A proposal for parametric opaque types in Typed Racket

2015-01-29 Thread Alexander D. Knauth

On Jan 29, 2015, at 11:34 PM, Alexis King lexi.lam...@gmail.com wrote:

 But the problem is that if it’s an opaque type then it can’t unwrap it once 
 the value is returned from make-posn.
 
 Yes, that’s precisely the problem. Your point about implementing everything 
 as single-valued structs on the typed side is an interesting one, though I 
 don’t think it ultimately solves any problems. The fact that the typed side 
 knows nothing about the contents of the value is what makes this such a 
 tricky problem.
 
 As for this:
 
 But then you couldn’t do any operations on it except those that you use 
 import with require/typed, right?
 
 That’s completely correct. That’s why it’s “opaque.”
 
 And what happens if you use cast on one of these things?
 
 That’s a little more interesting. Using cast on an object of this type would 
 never fail (unless, of course, it didn’t actually satisfy the basic posn? 
 predicate), but it would possibly introduce failures in the future since it 
 would affect the contracts generated for posn-x and posn-y, for example.
 
 To make that more clear, casting a (Posn Real) to a (Posn String) would work 
 fine until you tried to call posn-x on the instance, in which case it would 
 raise a contract error. Note that this isn’t really any different from 
 casting mutable data types.

But if it were wrapped in an opaque structure, then that structure wouldn’t 
satisfy the posn? predicate, unless of course the posn? predicate has a 
contract that unwraps it.  So all of the operations on it would have to have 
contracts that would unwrap it.  This might actually make sense if the type is 
meant to be actually opaque, but if it’s an opaque type that represents a 
normal non-opaque value, then it will still work as an opaque type, but it 
won’t be a normal non-opaque value anymore on the typed side.  

But the reason I asked about cast was because normally I can use cast with a 
value that has an opaque type, but it’s wrapped on the typed side in this 
opaque structure, then the contracts on the cast would see this opaque 
structure instead of the actual value.  

I’m thinking of an opaque typed representing a string with length 1, which I 
can use as long as I use either (cast x String) or (assert x string?) whenever 
I pass it to a string operation.  But if it were an opaque type, I don’t think 
I could do that.  There could be a 1string-string function that could take one 
of these 1strings and convert it to a string, but that seems like it should be 
unnecessary, but made necessary by this opaque structure thing.  

And for “this isn’t really any different from casting mutable data types,” look 
at this:
#lang typed/racket
(: b : (Boxof Number))
(define b (box 1))
(set-box! (cast b (Boxof (U Number String))) I am a string)
(ann (unbox b) Number) ;I am a string” ; not a contract error


 
 On Jan 29, 2015, at 20:20, Alexander D. Knauth alexan...@knauth.org wrote:
 
 Furthermore, even if the wrappers were shared between functions, untyped 
 code would recieved wrapped values, which would render them quite useless.
 
 If it’s not an opaque type, but something like a list, then this works, and 
 the untyped code receiving wrapped values isn’t a problem here:
 #lang typed/racket
 ; make Posn parametric
 (define-type (Posn A) (List A A))
 (provide Posn)
 (require/typed/provide
  untyped.rkt
  [make-posn (All (A) A A - (Posn A))]
  [posn-x (All (A) (Posn A) - A)]
  [posn-y (All (A) (Posn A) - A)]
  [real-posn? [(Posn Any) - Boolean]])
  (define p (make-posn 1 2))
 (make-posn #A6 #A6) ; a printf that I put in make-posn from “untyped.rkt
  p
 - : (Listof Positive-Byte) [more precisely: (List Positive-Byte 
 Positive-Byte)]
 '(1 2) ; unwrapped
  (posn-x p)
 - : Integer [more precisely: Positive-Byte]
 1
  (posn-y p)
 - : Integer [more precisely: Positive-Byte]
 2
  (real-posn? p)
 - : Boolean
 #t
 
 Even though for a short time it's wrapped, it’s unwrapped as soon as 
 make-posn returns, and then after that if it flows into untyped code again 
 it’s not wrapped and functions like real-posn? work fine.  
 
 But the problem is that if it’s an opaque type then it can’t unwrap it once 
 the value is returned from make-posn.
 
 And I don’t think parametric opaque types could solve this unless all posns 
 themselves were wrapped with an opaque struct on the typed side, which I 
 guess does make sense now that I think about it.  But then you couldn’t do 
 any operations on it except those that you use import with require/typed, 
 right?  Or not?  And what happens if you use cast on one of these things?
 
 
 On Jan 29, 2015, at 9:25 PM, Alexis King lexi.lam...@gmail.com wrote:
 
 I recently ran into a problem in which opaque types (types imported from 
 untyped code) cannot by parameterized by Typed Racket. I initially 
 encountered this problem in my attempt to port 2htdp/image to TR.
 
 After some further consideration, I’m interested in adding support to make 
 something like this possible, which 

Re: [racket-dev] A proposal for parametric opaque types in Typed Racket

2015-01-29 Thread Alexander D. Knauth
Um, for this:
(module typed typed/racket/base
(provide (struct-out Foo))
(struct [A] Foo ([x : A] [y : A]) #:transparent))

(Foo a 'b)
Should be fine because Foo could be instantiated at the type (U String Symbol).

On Jan 29, 2015, at 9:25 PM, Alexis King lexi.lam...@gmail.com wrote:

 I recently ran into a problem in which opaque types (types imported from 
 untyped code) cannot by parameterized by Typed Racket. I initially 
 encountered this problem in my attempt to port 2htdp/image to TR.
 
 After some further consideration, I’m interested in adding support to make 
 something like this possible, which would certainly have additional benefits 
 beyond this specific use-case. I’ve outlined my proposal here:
 http://lexi-lambda.github.io/racket-parametric-opaque-types/
 
 Any feedback, suggestions, or advice would be appreciated, especially from 
 those who are familiar with Typed Racket’s internals.
 
 Thank you,
 Alexis
 _
  Racket Developers list:
  http://lists.racket-lang.org/dev

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


Re: [racket-dev] build memory use (was: internal error during gc)

2015-01-29 Thread Philippe Meunier
Matthew Flatt wrote:
We've so far cut the peak memory use of a build by about 1/4 compared
to a v6.1.1 build.

Yes, peak memory use for me has now dropped from about 900MB to just
below 700MB.  Veeery nice :-)

Philippe


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


Re: [racket-dev] A proposal for parametric opaque types in Typed Racket

2015-01-29 Thread Alexis King
 But the problem is that if it’s an opaque type then it can’t unwrap it once 
 the value is returned from make-posn.

Yes, that’s precisely the problem. Your point about implementing everything as 
single-valued structs on the typed side is an interesting one, though I don’t 
think it ultimately solves any problems. The fact that the typed side knows 
nothing about the contents of the value is what makes this such a tricky 
problem.

As for this:

 But then you couldn’t do any operations on it except those that you use 
 import with require/typed, right?

That’s completely correct. That’s why it’s “opaque.”

 And what happens if you use cast on one of these things?

That’s a little more interesting. Using cast on an object of this type would 
never fail (unless, of course, it didn’t actually satisfy the basic posn? 
predicate), but it would possibly introduce failures in the future since it 
would affect the contracts generated for posn-x and posn-y, for example.

To make that more clear, casting a (Posn Real) to a (Posn String) would work 
fine until you tried to call posn-x on the instance, in which case it would 
raise a contract error. Note that this isn’t really any different from casting 
mutable data types.

 On Jan 29, 2015, at 20:20, Alexander D. Knauth alexan...@knauth.org wrote:
 
 Furthermore, even if the wrappers were shared between functions, untyped code 
 would recieved wrapped values, which would render them quite useless.
 
 If it’s not an opaque type, but something like a list, then this works, and 
 the untyped code receiving wrapped values isn’t a problem here:
 #lang typed/racket
 ; make Posn parametric
 (define-type (Posn A) (List A A))
 (provide Posn)
 (require/typed/provide
  untyped.rkt
  [make-posn (All (A) A A - (Posn A))]
  [posn-x (All (A) (Posn A) - A)]
  [posn-y (All (A) (Posn A) - A)]
  [real-posn? [(Posn Any) - Boolean]])
  (define p (make-posn 1 2))
 (make-posn #A6 #A6) ; a printf that I put in make-posn from “untyped.rkt
  p
 - : (Listof Positive-Byte) [more precisely: (List Positive-Byte 
 Positive-Byte)]
 '(1 2) ; unwrapped
  (posn-x p)
 - : Integer [more precisely: Positive-Byte]
 1
  (posn-y p)
 - : Integer [more precisely: Positive-Byte]
 2
  (real-posn? p)
 - : Boolean
 #t
 
 Even though for a short time it's wrapped, it’s unwrapped as soon as 
 make-posn returns, and then after that if it flows into untyped code again 
 it’s not wrapped and functions like real-posn? work fine.  
 
 But the problem is that if it’s an opaque type then it can’t unwrap it once 
 the value is returned from make-posn.
 
 And I don’t think parametric opaque types could solve this unless all posns 
 themselves were wrapped with an opaque struct on the typed side, which I 
 guess does make sense now that I think about it.  But then you couldn’t do 
 any operations on it except those that you use import with require/typed, 
 right?  Or not?  And what happens if you use cast on one of these things?
 
 
 On Jan 29, 2015, at 9:25 PM, Alexis King lexi.lam...@gmail.com 
 mailto:lexi.lam...@gmail.com wrote:
 
 I recently ran into a problem in which opaque types (types imported from 
 untyped code) cannot by parameterized by Typed Racket. I initially 
 encountered this problem in my attempt to port 2htdp/image to TR 
 https://github.com/lexi-lambda/racket-2htdp-typed/issues/1.
 
 After some further consideration, I’m interested in adding support to make 
 something like this possible, which would certainly have additional benefits 
 beyond this specific use-case. I’ve outlined my proposal here:
 http://lexi-lambda.github.io/racket-parametric-opaque-types/ 
 http://lexi-lambda.github.io/racket-parametric-opaque-types/
 
 Any feedback, suggestions, or advice would be appreciated, especially from 
 those who are familiar with Typed Racket’s internals.
 
 Thank you,
 Alexis
 _
  Racket Developers list:
  http://lists.racket-lang.org/dev http://lists.racket-lang.org/dev
 

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


Re: [racket-dev] A proposal for parametric opaque types in Typed Racket

2015-01-29 Thread Benjamin Greenman
This has bothered me too, but I've realized that I was on the wrong track.

The string a and symbol 'b are not different types. A struct (Foo a
'b), or (list a 'b), is a homogeneous data structure of type (U String
Symbol) just like Alexander said. This really upsets me -- I like the
Hindley Milner world where the compiler warns me if I make a list [1,
two] and forces me to wrap the int and string into a new datatype. But
Typed Racket is not HM.

About the proposal, I'm confused about what the syntax in Section 2.1
should do -- what is a first class member of Typed Racket's type system?
- Should an A only be a base type like String or Symbol
- Do you mean to infer the type of the first thing put into the struct as
the exact type for everything else?
- Would first class members prevent me from filling a struct with members
of (define-type (Option A) (U 'None (Some A))), where Some is a struct
with one field?

I totally agree that something needs fixing, but I'm not sure what.



On Thu, Jan 29, 2015 at 10:13 PM, Alexis King lexi.lam...@gmail.com wrote:

 Or Any for that matter. I know. The fact that it could be literally
 anything was sort of the point.

 On Jan 29, 2015, at 19:10, Alexander D. Knauth alexan...@knauth.org
 wrote:

 Um, for this:
 (module
 http://docs.racket-lang.org/reference/module.html#%28form._%28%28quote._~23~25kernel%29._module%29%29
  typed typed/racket/base(provide
 http://docs.racket-lang.org/reference/require.html#%28form._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._provide%29%29
  (struct-out
 http://docs.racket-lang.org/reference/require.html#%28form._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._struct-out%29%29
  Foo))(struct
 http://docs.racket-lang.org/ts-reference/special-forms.html#%28form._%28%28lib._typed-racket%2Fbase-env%2Fprims..rkt%29._struct%29%29
  [A] Foo ([x :
 http://docs.racket-lang.org/ts-reference/special-forms.html#%28form._%28%28lib._typed-racket%2Fbase-env%2Fprims..rkt%29._~3a%29%29
  A] [y :
 http://docs.racket-lang.org/ts-reference/special-forms.html#%28form._%28%28lib._typed-racket%2Fbase-env%2Fprims..rkt%29._~3a%29%29
  A]) #:transparent))

 (Foo a 'b)
 Should be fine because Foo could be instantiated at the type (U String
 Symbol).

 On Jan 29, 2015, at 9:25 PM, Alexis King lexi.lam...@gmail.com wrote:

 I recently ran into a problem in which opaque types (types imported from
 untyped code) cannot by parameterized by Typed Racket. I initially
 encountered this problem in my attempt to port 2htdp/image to TR
 https://github.com/lexi-lambda/racket-2htdp-typed/issues/1.

 After some further consideration, I’m interested in adding support to make
 something like this possible, which would certainly have additional
 benefits beyond this specific use-case. I’ve outlined my proposal here:
 http://lexi-lambda.github.io/racket-parametric-opaque-types/

 Any feedback, suggestions, or advice would be appreciated, especially from
 those who are familiar with Typed Racket’s internals.

 Thank you,
 Alexis
 _
  Racket Developers list:
  http://lists.racket-lang.org/dev




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


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


Re: [racket-dev] A proposal for parametric opaque types in Typed Racket

2015-01-29 Thread Alexander D. Knauth
Furthermore, even if the wrappers were shared between functions, untyped code 
would recieved wrapped values, which would render them quite useless.

If it’s not an opaque type, but something like a list, then this works, and the 
untyped code receiving wrapped values isn’t a problem here:
#lang typed/racket
; make Posn parametric
(define-type (Posn A) (List A A))
(provide Posn)
(require/typed/provide
 untyped.rkt
 [make-posn (All (A) A A - (Posn A))]
 [posn-x (All (A) (Posn A) - A)]
 [posn-y (All (A) (Posn A) - A)]
 [real-posn? [(Posn Any) - Boolean]])
 (define p (make-posn 1 2))
(make-posn #A6 #A6) ; a printf that I put in make-posn from “untyped.rkt
 p
- : (Listof Positive-Byte) [more precisely: (List Positive-Byte Positive-Byte)]
'(1 2) ; unwrapped
 (posn-x p)
- : Integer [more precisely: Positive-Byte]
1
 (posn-y p)
- : Integer [more precisely: Positive-Byte]
2
 (real-posn? p)
- : Boolean
#t

Even though for a short time it's wrapped, it’s unwrapped as soon as make-posn 
returns, and then after that if it flows into untyped code again it’s not 
wrapped and functions like real-posn? work fine.  

But the problem is that if it’s an opaque type then it can’t unwrap it once the 
value is returned from make-posn.

And I don’t think parametric opaque types could solve this unless all posns 
themselves were wrapped with an opaque struct on the typed side, which I guess 
does make sense now that I think about it.  But then you couldn’t do any 
operations on it except those that you use import with require/typed, right?  
Or not?  And what happens if you use cast on one of these things?


On Jan 29, 2015, at 9:25 PM, Alexis King lexi.lam...@gmail.com wrote:

 I recently ran into a problem in which opaque types (types imported from 
 untyped code) cannot by parameterized by Typed Racket. I initially 
 encountered this problem in my attempt to port 2htdp/image to TR.
 
 After some further consideration, I’m interested in adding support to make 
 something like this possible, which would certainly have additional benefits 
 beyond this specific use-case. I’ve outlined my proposal here:
 http://lexi-lambda.github.io/racket-parametric-opaque-types/
 
 Any feedback, suggestions, or advice would be appreciated, especially from 
 those who are familiar with Typed Racket’s internals.
 
 Thank you,
 Alexis
 _
  Racket Developers list:
  http://lists.racket-lang.org/dev

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


Re: [racket-dev] A proposal for parametric opaque types in Typed Racket

2015-01-29 Thread Alexis King
Or Any for that matter. I know. The fact that it could be literally anything 
was sort of the point.

 On Jan 29, 2015, at 19:10, Alexander D. Knauth alexan...@knauth.org wrote:
 
 Um, for this:
 (module 
 http://docs.racket-lang.org/reference/module.html#%28form._%28%28quote._~23~25kernel%29._module%29%29
  typed typed/racket/base
 (provide 
 http://docs.racket-lang.org/reference/require.html#%28form._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._provide%29%29
  (struct-out 
 http://docs.racket-lang.org/reference/require.html#%28form._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._struct-out%29%29
  Foo))
 (struct 
 http://docs.racket-lang.org/ts-reference/special-forms.html#%28form._%28%28lib._typed-racket%2Fbase-env%2Fprims..rkt%29._struct%29%29
  [A] Foo ([x : 
 http://docs.racket-lang.org/ts-reference/special-forms.html#%28form._%28%28lib._typed-racket%2Fbase-env%2Fprims..rkt%29._~3a%29%29
  A] [y : 
 http://docs.racket-lang.org/ts-reference/special-forms.html#%28form._%28%28lib._typed-racket%2Fbase-env%2Fprims..rkt%29._~3a%29%29
  A]) #:transparent))
 
 (Foo a 'b)
 Should be fine because Foo could be instantiated at the type (U String 
 Symbol).
 
 On Jan 29, 2015, at 9:25 PM, Alexis King lexi.lam...@gmail.com 
 mailto:lexi.lam...@gmail.com wrote:
 
 I recently ran into a problem in which opaque types (types imported from 
 untyped code) cannot by parameterized by Typed Racket. I initially 
 encountered this problem in my attempt to port 2htdp/image to TR 
 https://github.com/lexi-lambda/racket-2htdp-typed/issues/1.
 
 After some further consideration, I’m interested in adding support to make 
 something like this possible, which would certainly have additional benefits 
 beyond this specific use-case. I’ve outlined my proposal here:
 http://lexi-lambda.github.io/racket-parametric-opaque-types/ 
 http://lexi-lambda.github.io/racket-parametric-opaque-types/
 
 Any feedback, suggestions, or advice would be appreciated, especially from 
 those who are familiar with Typed Racket’s internals.
 
 Thank you,
 Alexis
 _
  Racket Developers list:
  http://lists.racket-lang.org/dev http://lists.racket-lang.org/dev
 

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


Re: [racket-dev] A proposal for parametric opaque types in Typed Racket

2015-01-29 Thread Alexis King
It isn’t wrapped in an opaque structure. That wasn’t a part of my proposal, and 
while I didn’t think of it until you brought it up, I still think it’s 
unnecessary and doesn’t add any convenience.

Perhaps I’m not understanding you properly, but your “one-length string” idea 
sounds like it has little to do with this opaque type problem and more to do 
with the fact that you want refinement types in Typed Racket. I do, too! But I 
don’t think hacking the opaque type system is going to help you with that.

(Also, as for the box example, I’m actually a little surprised that doesn’t 
contract error. Seems like a bug to me, but perhaps I’m missing some 
idiosyncrasies of the type system. Either way, it’s precisely that kind of 
craziness I was referring to when I compared casting parametric opaque types to 
casting mutable types.)

 On Jan 29, 2015, at 20:50, Alexander D. Knauth alexan...@knauth.org wrote:
 
 
 On Jan 29, 2015, at 11:34 PM, Alexis King lexi.lam...@gmail.com 
 mailto:lexi.lam...@gmail.com wrote:
 
 But the problem is that if it’s an opaque type then it can’t unwrap it once 
 the value is returned from make-posn.
 
 Yes, that’s precisely the problem. Your point about implementing everything 
 as single-valued structs on the typed side is an interesting one, though I 
 don’t think it ultimately solves any problems. The fact that the typed side 
 knows nothing about the contents of the value is what makes this such a 
 tricky problem.
 
 As for this:
 
 But then you couldn’t do any operations on it except those that you use 
 import with require/typed, right?
 
 That’s completely correct. That’s why it’s “opaque.”
 
 And what happens if you use cast on one of these things?
 
 That’s a little more interesting. Using cast on an object of this type would 
 never fail (unless, of course, it didn’t actually satisfy the basic posn? 
 predicate), but it would possibly introduce failures in the future since it 
 would affect the contracts generated for posn-x and posn-y, for example.
 
 To make that more clear, casting a (Posn Real) to a (Posn String) would work 
 fine until you tried to call posn-x on the instance, in which case it would 
 raise a contract error. Note that this isn’t really any different from 
 casting mutable data types.
 
 But if it were wrapped in an opaque structure, then that structure wouldn’t 
 satisfy the posn? predicate, unless of course the posn? predicate has a 
 contract that unwraps it.  So all of the operations on it would have to have 
 contracts that would unwrap it.  This might actually make sense if the type 
 is meant to be actually opaque, but if it’s an opaque type that represents a 
 normal non-opaque value, then it will still work as an opaque type, but it 
 won’t be a normal non-opaque value anymore on the typed side.  
 
 But the reason I asked about cast was because normally I can use cast with a 
 value that has an opaque type, but it’s wrapped on the typed side in this 
 opaque structure, then the contracts on the cast would see this opaque 
 structure instead of the actual value.  
 
 I’m thinking of an opaque typed representing a string with length 1, which I 
 can use as long as I use either (cast x String) or (assert x string?) 
 whenever I pass it to a string operation.  But if it were an opaque type, I 
 don’t think I could do that.  There could be a 1string-string function that 
 could take one of these 1strings and convert it to a string, but that seems 
 like it should be unnecessary, but made necessary by this opaque structure 
 thing.  
 
 And for “this isn’t really any different from casting mutable data types,” 
 look at this:
 #lang typed/racket
 (: b : (Boxof Number))
 (define b (box 1))
 (set-box! (cast b (Boxof (U Number String))) I am a string)
 (ann (unbox b) Number) ;I am a string” ; not a contract error
 
 
 
 On Jan 29, 2015, at 20:20, Alexander D. Knauth alexan...@knauth.org 
 mailto:alexan...@knauth.org wrote:
 
 Furthermore, even if the wrappers were shared between functions, untyped 
 code would recieved wrapped values, which would render them quite useless.
 
 If it’s not an opaque type, but something like a list, then this works, and 
 the untyped code receiving wrapped values isn’t a problem here:
 #lang typed/racket
 ; make Posn parametric
 (define-type (Posn A) (List A A))
 (provide Posn)
 (require/typed/provide
  untyped.rkt
  [make-posn (All (A) A A - (Posn A))]
  [posn-x (All (A) (Posn A) - A)]
  [posn-y (All (A) (Posn A) - A)]
  [real-posn? [(Posn Any) - Boolean]])
  (define p (make-posn 1 2))
 (make-posn #A6 #A6) ; a printf that I put in make-posn from 
 “untyped.rkt
  p
 - : (Listof Positive-Byte) [more precisely: (List Positive-Byte 
 Positive-Byte)]
 '(1 2) ; unwrapped
  (posn-x p)
 - : Integer [more precisely: Positive-Byte]
 1
  (posn-y p)
 - : Integer [more precisely: Positive-Byte]
 2
  (real-posn? p)
 - : Boolean
 #t
 
 Even though for a short time it's wrapped, it’s unwrapped as soon as 
 make-posn returns, and 

Re: [racket-dev] feature request: thread-safe memoize-evt

2015-01-29 Thread Jan Dvořák
On Thu, 2015-01-29 at 16:41 -0600, Robby Findler wrote:
 That is, I thought you could just create a separate thread that sync's
 on E_b and then whenever you get a value from it, then the E_m would
 just continue to produce that all the time. But I think you're saying
 that wouldn't work?

The problem is that the auxiliary thread would always wait for the E_b,
even when nobody is interested in the result anymore. Moreover, putting
the wait in another thread would require the E_b to be thread safe.

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