Re: [racket-users] Sending Closures to Places

2015-08-03 Thread Michael Titke

On 03/08/2015 07:22, Neil Van Dyke wrote:

Michael Titke wrote on 08/03/2015 12:50 AM:


Perhaps /quote/ and /eval/ would do the job? That is the usual way to 
treat Scheme code as data and data as Scheme code.


Eval might indeed be the perfect solution this time, iff every other 
conceivable alternative has been rejected. :)


Shameless link to PSA on the topic of eval: 
http://lists.racket-lang.org/users/archive/2014-July/063597.html


Suggestions for other forms for PSA are welcome: 
http://lists.racket-lang.org/users/archive/2014-July/063618.html


Neil V.

On a second thought you would even need to serialize the data graph 
(let's just call it string) and unstring it on the other side with the 
infamous /read/. You could just send a dot rkt file there ...


--
You received this message because you are subscribed to the Google Groups Racket 
Users group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] Optimizing closures

2015-08-03 Thread Laurent
I see, thanks for the explanations, Matthew. So that's the kind of things
that are simple in principle, but more complicated than one would like in
practice then. Good luck with your experiments!

On Fri, Jul 31, 2015 at 10:02 PM, Matthew Flatt mfl...@cs.utah.edu wrote:

 At Fri, 31 Jul 2015 18:56:15 +0100, Laurent wrote:
  On Fri, Jul 31, 2015 at 5:40 PM, Matthew Flatt mfl...@cs.utah.edu
 wrote:
 
   At Fri, 31 Jul 2015 15:03:53 +0100, Laurent wrote:
I don't really understand why `in-range` makes such a difference. It
   looks
like the kind of sequence iterator is tested at each step, whereas I
 was
expecting it to be tested only at the beginning of the loop, since
 this
sequence iterator kind can't change from one iteration to the next,
   right?
   
Hence, I was expecting the `in-range` (and actually all other `in-*`)
   issue
to appear only inside nested loops, where some loops are started many
   times
(thus requiring many iterator kind tests).
  
   Right: The `in-*` functions tell `for` what kind of step operations to
   inline into the loop (after an initial guard that confirms that it has
   a number, list, etc., to iterate through). Otherwise, there's a
   run-time dispatch to take each step, which is usually more significant
   than a run-time dispatch to set up the loop.
  
 
  Apparently the optimizer is looking very specifically for `in-range`.
 This:
 
  (define my-in-range in-range)
  (time (for ([x (my-in-range 4000)])
  (+ x 3)))
 
  is as slow as not using `in-range` at all, which I find rather strange.

 It's really the `for` macro that recognizes `in-*`. The expansion of a
 `for` form is too complex for the optimizer to see through the levels
 of dispatching.

 Giving macros more power to interact with the optimizer is a long-term
 goal, but it's beyond the things that Racket macros can do right now.


  By run-time dispatch, do you mean that the check of which kind the
  argument is is done at each iteration?

 No...

  Isn't it possible to test this only on the very first iteration? Then the
  rest of the loop should be as fast as with `in-range`.

 The fact that `add1` should be used for stepping is determined once at
 the start of the loop. Since that determination is dynamic, however,
 the call to `add1` is not static in the bytecode, and so the JIT
 doesn't inline `add1`.

 Some JITs would detect that `add1` turns out to be the stepping
 function on the first iteration, when the loop is compiled. Then, the
 JIT would optimistically generate a faster path for future iterations
 where `add1` turns out to be the stepping function. It's possible that
 Racket's JIT could do that and achieve some intermediate performance
 --- not as fast as `in-range` but better than current performance
 without `in-range`. I'll have to try some experiments.




-- 
You received this message because you are subscribed to the Google Groups 
Racket Users group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] Sending Closures to Places

2015-08-03 Thread Jens Axel Søgaard
2015-08-02 19:12 GMT+02:00 Konstantin Weitz konstantin.we...@gmail.com:

 I'm trying to write a distributed racket program using [places][0]. From
 my current understanding, this means that I have to send data to each place
 over a channel using the `place-channel-put` function, which can send any
 value accepted by `place-message-allowed?`.

 I would like to send closures over a channel, unfortunately, closures are
 not accepted by `place-message-allowed?`. Is there any way to serialize a
 closure into a value accepted by a channel, and then deserialize it on the
 other side of the channel?


How many lambda expressions are we talking about?
If the number is limited you can defined custom closures.

Whether or not the following is practical I will leave up to you
to decide :-)


Consider this program.

(define x 3)
(define f (lambda (y) (+ x y)))
(f 4)

Annotate the free variables of the lambda-expression.

(define x 3)
(define f (lambda (y) (+ x y)))  ; x is free
(f 4)

Define an explicit closure struct and a helper to access free variables.

(struct closure (code free) #:prefab)

The code field will refer to a closed (no free variables) version of f and
free is a vector of the values of the free variables at the
time the closure was created.

The idea is that we want to replace (lambda (y) (+ x y)) with (closure
f_closed (vector x)).

A little helper to access the free variables:

(define (free-ref cl i)
  (vector-ref (closure-free cl) i))

Now define a closed (no free variables) version of f:

(define f_closed
  (lambda (cl y)
(let ((x (free-ref cl 0)))
  (+ x y

We can now rewrite the lambda expression into a closure allocation.

The full program is now:

(struct closure (code free) #:prefab)
(define (free-ref cl i)  (vector-ref (closure-free cl) i))

(define f_closed
  (lambda (cl y)
(let ((x (free-ref cl 0)))
  (+ x y

(define x 3)
(define f (closure f_closed (vector x)))
(f 4)

Note that the structure is a prefab structure in order to be a legal
message.

At this point there is a complication:

* f_closed is not an allowed message
* (f 4) fails since the closure structure is not applicable

The first point is solved by sending the name of f_closed as a symbol.
One could use eval to change it back to a function, but a hash table will
do:

(define closed-functions-ht
  (make-hasheq (list (cons 'f_closed f_closed

(define (get-closed-function name)
  (hash-ref closed-functions-ht name
(λ _ (error 'app no closed function of that name ~a
name

The other can unfortunately not be solved by turning the structure
into an applicable struct, since prefab structures can't have properties.
Therefore we need to introduce a construct app that knows how to invoke
closures.

(define-syntax-rule (app cl arg ...)
  ((get-closed-function (closure-code cl)) cl arg ...))

The entire program is now:

#lang racket
(struct closure (code free) #:prefab)
(define (free-ref cl i)  (vector-ref (closure-free cl) i))

(define f_closed
  (lambda (cl y)
(let ((x (free-ref cl 0)))
  (+ x y

(define closed-functions-ht
  (make-hasheq (list (cons 'f_closed f_closed

(define (get-closed-function name)
  (hash-ref closed-functions-ht name
(λ _ (error 'app no closed function of that name ~a
name

(define-syntax-rule (app cl arg ...)
  ((get-closed-function (closure-code cl)) cl arg ...))

(define x 3)
(define f (closure 'f_closed (vector x)))
(app f 4)

The value of f is:

 f
'#s(closure f_closed #(3))

and that value is an allowed message.

The standard higher operations such as map and apply do not know about the
special calling convention of f, so (map f '(1 2 3)) will not work.
It is no big deal though, since wrapping f in a lambda works:

 (map (λ (x) (app f x))
   '(1 2 3))
'(4 5 6)

To make this solution practical one could introduce a macro Lambda
that turns (Lambda (x) (y) (+ x y)) into (closure 'closed1 (vector x)))
and at the same time lifts

(define closed1
  (lambda (cl y)
(let ((x (free-ref cl 0)))
  (+ x y

to the top of the program.

An ambitious solution would also use free-vars from syntax/free-vars
to determine the free variables automatically.

/Jens Axel

-- 
You received this message because you are subscribed to the Google Groups 
Racket Users group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] Sending Closures to Places

2015-08-03 Thread Jens Axel Søgaard
Note that the web-server has support for serializable closures:

http://docs.racket-lang.org/web-server-internal/closure.html

I think they are the practical choice.

/Jens Axel


2015-08-03 12:29 GMT+02:00 Jens Axel Søgaard jensa...@soegaard.net:

 2015-08-02 19:12 GMT+02:00 Konstantin Weitz konstantin.we...@gmail.com:

 I'm trying to write a distributed racket program using [places][0]. From
 my current understanding, this means that I have to send data to each place
 over a channel using the `place-channel-put` function, which can send any
 value accepted by `place-message-allowed?`.

 I would like to send closures over a channel, unfortunately, closures are
 not accepted by `place-message-allowed?`. Is there any way to serialize a
 closure into a value accepted by a channel, and then deserialize it on the
 other side of the channel?


 How many lambda expressions are we talking about?
 If the number is limited you can defined custom closures.

 Whether or not the following is practical I will leave up to you
 to decide :-)


 Consider this program.

 (define x 3)
 (define f (lambda (y) (+ x y)))
 (f 4)

 Annotate the free variables of the lambda-expression.

 (define x 3)
 (define f (lambda (y) (+ x y)))  ; x is free
 (f 4)

 Define an explicit closure struct and a helper to access free variables.

 (struct closure (code free) #:prefab)

 The code field will refer to a closed (no free variables) version of f and
 free is a vector of the values of the free variables at the
 time the closure was created.

 The idea is that we want to replace (lambda (y) (+ x y)) with (closure
 f_closed (vector x)).

 A little helper to access the free variables:

 (define (free-ref cl i)
   (vector-ref (closure-free cl) i))

 Now define a closed (no free variables) version of f:

 (define f_closed
   (lambda (cl y)
 (let ((x (free-ref cl 0)))
   (+ x y

 We can now rewrite the lambda expression into a closure allocation.

 The full program is now:

 (struct closure (code free) #:prefab)
 (define (free-ref cl i)  (vector-ref (closure-free cl) i))

 (define f_closed
   (lambda (cl y)
 (let ((x (free-ref cl 0)))
   (+ x y

 (define x 3)
 (define f (closure f_closed (vector x)))
 (f 4)

 Note that the structure is a prefab structure in order to be a legal
 message.

 At this point there is a complication:

 * f_closed is not an allowed message
 * (f 4) fails since the closure structure is not applicable

 The first point is solved by sending the name of f_closed as a symbol.
 One could use eval to change it back to a function, but a hash table will
 do:

 (define closed-functions-ht
   (make-hasheq (list (cons 'f_closed f_closed

 (define (get-closed-function name)
   (hash-ref closed-functions-ht name
 (λ _ (error 'app no closed function of that name ~a
 name

 The other can unfortunately not be solved by turning the structure
 into an applicable struct, since prefab structures can't have properties.
 Therefore we need to introduce a construct app that knows how to invoke
 closures.

 (define-syntax-rule (app cl arg ...)
   ((get-closed-function (closure-code cl)) cl arg ...))

 The entire program is now:

 #lang racket
 (struct closure (code free) #:prefab)
 (define (free-ref cl i)  (vector-ref (closure-free cl) i))

 (define f_closed
   (lambda (cl y)
 (let ((x (free-ref cl 0)))
   (+ x y

 (define closed-functions-ht
   (make-hasheq (list (cons 'f_closed f_closed

 (define (get-closed-function name)
   (hash-ref closed-functions-ht name
 (λ _ (error 'app no closed function of that name ~a
 name

 (define-syntax-rule (app cl arg ...)
   ((get-closed-function (closure-code cl)) cl arg ...))

 (define x 3)
 (define f (closure 'f_closed (vector x)))
 (app f 4)

 The value of f is:

  f
 '#s(closure f_closed #(3))

 and that value is an allowed message.

 The standard higher operations such as map and apply do not know about the
 special calling convention of f, so (map f '(1 2 3)) will not work.
 It is no big deal though, since wrapping f in a lambda works:

  (map (λ (x) (app f x))
'(1 2 3))
 '(4 5 6)

 To make this solution practical one could introduce a macro Lambda
 that turns (Lambda (x) (y) (+ x y)) into (closure 'closed1 (vector x)))
 and at the same time lifts

 (define closed1
   (lambda (cl y)
 (let ((x (free-ref cl 0)))
   (+ x y

 to the top of the program.

 An ambitious solution would also use free-vars from syntax/free-vars
 to determine the free variables automatically.

 /Jens Axel




-- 
-- 
Jens Axel Søgaard

-- 
You received this message because you are subscribed to the Google Groups 
Racket Users group.
To unsubscribe from this group and stop receiving emails from it, send an 

Re: [racket-users] continuing after a user break

2015-08-03 Thread Robby Findler
It does seem useful. It would require some thought because the
exception handler cannot escape until there is no possibility of
resuming which seems like it would have UI implications. This would
also cause some REPL interactions to behave differently when they are
in the break-resumable context (notably those involving continuations
and related things). But I agree it seems worth thinking about.

Since it's been 7 days and I've not made any more progress than that,
I guess that the best I can offer is advice if someone else wants to
give it a try.

Robby


On Mon, Jul 27, 2015 at 5:48 PM, John Carmack jo...@oculus.com wrote:
 Any chance that could make it in as a DrRacket feature?  Seems likely to have 
 moderately broad utility.

 Out of curiosity, what programming environment do the core Racket devs use 
 when programming Racket?  I quite like DrRacket for my projects that are only 
 a few files, but it doesn't seem to be aimed at large scale work.

 -Original Message-
 From: Matthew Flatt [mailto:mfl...@cs.utah.edu]
 Sent: Monday, July 27, 2015 2:43 PM
 To: John Carmack
 Cc: Racket Users
 Subject: Re: [racket-users] continuing after a user break

 At Mon, 27 Jul 2015 19:32:32 +, John Carmack wrote:
 Is it possible to continue execution after a ^b user break in DrRacket
 (not debugging)?  It would often be useful to be able to ^b, print
 some global state, set some flags, and continue running.

 The `exn:break` exception record includes a `continuation` field. An 
 exception handler can apply that continuation to resume from the point of the 
 break.

 A significant limitation is that the handler has to be installed with 
 `call-with-continuation-handler` or `uncaught-exception-handler`. If any 
 `with-handlers` is in effect, it will catch any continuation and escape to 
 the `with-handlers` form, at which point the continuation in `exn:break` 
 cannot be applied (because it's an escape-only continuation).

 

 #lang racket

 (let ([orig (uncaught-exception-handler)])
   (uncaught-exception-handler
(lambda (exn)
  (if (exn:break? exn)
  (begin
(printf continuing...\n)
((exn:break-continuation exn)))
  (orig exn)

 (let loop () (loop))

 --
 You received this message because you are subscribed to the Google Groups 
 Racket Users group.
 To unsubscribe from this group and stop receiving emails from it, send an 
 email to racket-users+unsubscr...@googlegroups.com.
 For more options, visit https://groups.google.com/d/optout.

-- 
You received this message because you are subscribed to the Google Groups 
Racket Users group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] Macro that does substitution

2015-08-03 Thread Andrew Gwozdziewycz
On Wed, Jul 29, 2015 at 9:30 AM, Matthias Felleisen matth...@ccs.neu.edu
wrote:


 On Jul 29, 2015, at 7:50 AM, Klaus Ostermann wrote:

  Thanks, Matthew and Matthias. The service on this mailing list is
 incredible!
 
  I know it is not cbn because it is local, but a better name didn't come
 to my mind and it is what I need to solve my problem.


 It's not about locality, the problem is that it runs the thunks at the
 wrong time.

 Example:

   (let ((x (/ 1 0)))
 ((lambda (y) (displayln `(hello world)))
  x))

 in CBN would _first_ show hello-world and then raise the exception but
 your let-cbn will raise the exception first and never display anything on
 the output port.


I'm confused. Why would this raise an exception? x is never in strict
position, as `y` is unused in the lambda. But, I could simply be missing
something, and if so, please ignore. :)

-- 
http://www.apgwoz.com

-- 
You received this message because you are subscribed to the Google Groups 
Racket Users group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] Macro that does substitution

2015-08-03 Thread Matthias Felleisen


Correct. There should never be an exception because the value never ends up in 
a strict position. -- Matthias





On Aug 3, 2015, at 12:44 PM, Andrew Gwozdziewycz apg...@gmail.com wrote:

 On Wed, Jul 29, 2015 at 9:30 AM, Matthias Felleisen matth...@ccs.neu.edu 
 wrote:
 
 On Jul 29, 2015, at 7:50 AM, Klaus Ostermann wrote:
 
  Thanks, Matthew and Matthias. The service on this mailing list is 
  incredible!
 
  I know it is not cbn because it is local, but a better name didn't come to 
  my mind and it is what I need to solve my problem.
 
 
 It's not about locality, the problem is that it runs the thunks at the wrong 
 time.
 
 Example:
 
   (let ((x (/ 1 0)))
 ((lambda (y) (displayln `(hello world)))
  x))
 
 in CBN would _first_ show hello-world and then raise the exception but your 
 let-cbn will raise the exception first and never display anything on the 
 output port.
 
 I'm confused. Why would this raise an exception? x is never in strict 
 position, as `y` is unused in the lambda. But, I could simply be missing 
 something, and if so, please ignore. :)
 
 -- 
 http://www.apgwoz.com

-- 
You received this message because you are subscribed to the Google Groups 
Racket Users group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] eval PSA (was Sending Closures to Places)

2015-08-03 Thread Josh Grams
On 2015-08-03 01:22AM, Neil Van Dyke wrote:
 Eval might indeed be the perfect solution this time, iff every other  
 conceivable alternative has been rejected. :)

 Shameless link to PSA on the topic of eval:  
 http://lists.racket-lang.org/users/archive/2014-July/063597.html

 Suggestions for other forms for PSA are welcome:  

If people knew *why* and *how* to avoid eval, wouldn't they already be
doing it? To be useful to your target audience, I think you *need* to
back this up with a link to supporting documentation. I'd be looking
for:

- A *brief* high-level statement of why eval causes problems: maybe
  something like this? I'm sure there are better statements out there...

  eval takes code which was constructed in one context and assigns
  meaning to it in a different context. This can cause the code to have
  an unexpected meaning, or fail to work altogether. It can also cause
  security problems (if you pass it code from an untrusted source) or be
  unnecessarily slow (evaluating code at runtime which could have been
  fixed at compile time).

- Rules of thumb for how to decide what to use instead, and when eval
  might be ok. This answer (http://stackoverflow.com/a/2571549/2426692)
  suggests asking:
  
  - Do I really need eval or does the compiler/evaluator already do what
I want?
  - Does the code really need to be constructed at runtime or can it be
constructed earlier?
  - Will funcall, reduce, or apply work instead?

- Concrete examples of where beginners tend to use eval and how to code
  them without it. This is sort of the same as the previous one, but I
  like to see a short overview of the whole strategy by itself, so I
  would put the examples separately, e.g. HTDP has a *nice* clear
  overview of the design recipe, whereas HTDP 2e has no place where you
  can go for a quick refresher of what were the steps of the design
  recipe again?

-

That's my two cents. I always see these sorts of things getting brushed
off as unhelpful or even patronizing, so I think you want to go out of
your way to make it easy to dig into it and reach successively deeper
levels of understanding.

--Josh

-- 
You received this message because you are subscribed to the Google Groups 
Racket Users group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] eval PSA (was Sending Closures to Places)

2015-08-03 Thread Jens Axel Søgaard
On eval in dynamic languages generally and in Racket specifically
http://blog.racket-lang.org/2011/10/on-eval-in-dynamic-languages-generally.html
Posted by Matthew Flatt
http://blog.racket-lang.org/2011/10/on-eval-in-dynamic-languages-generally.html



2015-08-03 13:32 GMT+02:00 Josh Grams j...@qualdan.com:

 On 2015-08-03 01:22AM, Neil Van Dyke wrote:
  Eval might indeed be the perfect solution this time, iff every other
  conceivable alternative has been rejected. :)
 
  Shameless link to PSA on the topic of eval:
  http://lists.racket-lang.org/users/archive/2014-July/063597.html
 
  Suggestions for other forms for PSA are welcome:

 If people knew *why* and *how* to avoid eval, wouldn't they already be
 doing it? To be useful to your target audience, I think you *need* to
 back this up with a link to supporting documentation. I'd be looking
 for:

 - A *brief* high-level statement of why eval causes problems: maybe
   something like this? I'm sure there are better statements out there...

   eval takes code which was constructed in one context and assigns
   meaning to it in a different context. This can cause the code to have
   an unexpected meaning, or fail to work altogether. It can also cause
   security problems (if you pass it code from an untrusted source) or be
   unnecessarily slow (evaluating code at runtime which could have been
   fixed at compile time).

 - Rules of thumb for how to decide what to use instead, and when eval
   might be ok. This answer (http://stackoverflow.com/a/2571549/2426692)
   suggests asking:

   - Do I really need eval or does the compiler/evaluator already do what
 I want?
   - Does the code really need to be constructed at runtime or can it be
 constructed earlier?
   - Will funcall, reduce, or apply work instead?

 - Concrete examples of where beginners tend to use eval and how to code
   them without it. This is sort of the same as the previous one, but I
   like to see a short overview of the whole strategy by itself, so I
   would put the examples separately, e.g. HTDP has a *nice* clear
   overview of the design recipe, whereas HTDP 2e has no place where you
   can go for a quick refresher of what were the steps of the design
   recipe again?

 -

 That's my two cents. I always see these sorts of things getting brushed
 off as unhelpful or even patronizing, so I think you want to go out of
 your way to make it easy to dig into it and reach successively deeper
 levels of understanding.

 --Josh

 --
 You received this message because you are subscribed to the Google Groups
 Racket Users group.
 To unsubscribe from this group and stop receiving emails from it, send an
 email to racket-users+unsubscr...@googlegroups.com.
 For more options, visit https://groups.google.com/d/optout.




-- 
-- 
Jens Axel Søgaard

-- 
You received this message because you are subscribed to the Google Groups 
Racket Users group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] upcoming v6.2.1

2015-08-03 Thread Ryan Davis
 
 On Jul 29, 2015, at 08:16, Matthew Flatt mfl...@cs.utah.edu wrote:
 
 We're preparing a v6.2.1 release, which will go out before August 10.
 The v6.2.1 build will be a small set of patches to v6.2, i.e., not
 derived from the current development branch. 
 
 The patches are for the HtDP teaching languages. The main patch for
 v6.2.1 is to add an option to restore the old output format for
 booleans and the empty list in *SL --- to print as true, false, and
 empty, instead of the new style of #true, #false, and '() that was
 enabled in v6.2.
 
 Classes using DrRacket will not necessarily need v6.2.1. In particular,
 the latest version of HtDP2e uses the new v6.2 output format, while the
 names true, false, and empty can still be used in programs. The output
 change can be a problem, however, for teachers who have other material
 that depends on the old output format (and that is not easily updated).
 So, if your class does not need the old printing style, feel free to
 use the current v6.2 release.

Can the fix for the regression I reported (on 7/14) get backported to the 6.2 
branch?

This is the minimal repro:

#lang racket
(define dup (lambda (f) (f f)))
(lambda ()
 (let ([rep (lambda (f) (f f))])
   (dup rep)))

-- 
You received this message because you are subscribed to the Google Groups 
Racket Users group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.