Re: [racket-users] whither `splicing-parameterize`? or am I doing it wrong?

2018-01-25 Thread Alexis King
> On Jan 25, 2018, at 16:45, Robby Findler 
> wrote:
> 
> Isn't the last form already required to not be a definition?

In that example, yes, but not always, and splicing-parameterize can’t
be sure one way or the other. In this example, containing exclusively
definitions is completely legal:

(let ()
  (splicing-parameterize ([my-param #t])
(define x (my-param)))
  x)

I suppose it would be possible to force users of splicing-parameterize
to make the final body form an expression, but the other forms from
racket/splicing don’t have that restriction, so it would be a bit odd
to have different behavior here.

Alexis

-- 
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] whither `splicing-parameterize`? or am I doing it wrong?

2018-01-25 Thread Robby Findler
Isn't the last form already required to not be a definition?

Robby

On Thu, Jan 25, 2018 at 5:59 PM Alexis King  wrote:

> > On Jan 24, 2018, at 12:57 AM, Ryan Culpepper 
> > wrote:
> >
> > It might make sense to `(set! new-parameterization #f)` at the end so
> > that the parameterization (and the values it holds) can be GC'd sooner
> > when splicing-parameterize is used at top level or module level.
>
> The tricky thing about doing this is maintaining the evaluation result.
> If I add a (set! new-parameterization #f) to the end of
> splicing-parameterize, then this:
>
> (let ()
>   (splicing-parameterize ([my-param #t])
> 42))
>
> ...evaluates to # instead of 42. It’s theoretically possible to
> figure out if the last form is a definition or an expression, and if
> it’s the latter, insert a use of begin0, but this means the final
> expression is not called in tail position. This probably isn’t a
> problem, though, so maybe it’s still worth it?
>
> Alexis
>
> --
> 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] whither `splicing-parameterize`? or am I doing it wrong?

2018-01-25 Thread Alexis King
> On Jan 24, 2018, at 12:57 AM, Ryan Culpepper 
> wrote:
> 
> It might make sense to `(set! new-parameterization #f)` at the end so
> that the parameterization (and the values it holds) can be GC'd sooner
> when splicing-parameterize is used at top level or module level.

The tricky thing about doing this is maintaining the evaluation result.
If I add a (set! new-parameterization #f) to the end of
splicing-parameterize, then this:

(let ()
  (splicing-parameterize ([my-param #t])
42))

...evaluates to # instead of 42. It’s theoretically possible to
figure out if the last form is a definition or an expression, and if
it’s the latter, insert a use of begin0, but this means the final
expression is not called in tail position. This probably isn’t a
problem, though, so maybe it’s still worth it?

Alexis

-- 
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] whither `splicing-parameterize`? or am I doing it wrong?

2018-01-24 Thread Ryan Culpepper
It might make sense to `(set! new-parameterization #f)` at the end so 
that the parameterization (and the values it holds) can be GC'd sooner 
when splicing-parameterize is used at top level or module level.


Ryan


On 1/24/18 6:00 AM, Alexis King wrote:

Here is an implementation of a version of splicing-parameterize that
uses local-expand, a la other forms in racket/splicing:

#lang racket

(require (for-syntax syntax/kerncase)
 (for-meta 2 racket/base)
 syntax/parse/define)

(begin-for-syntax
  (define-syntax (syntax/loc/props stx)
(syntax-case stx ()
  [(_ src-expr template)
   #`(let ([src src-expr])
   (datum->syntax (quote-syntax #,stx)
  (syntax-e (syntax template))
  src
  src))])))

(define-syntax-parser splicing-parameterize
  [(_ ([{~var param (expr/c #'parameter?)} value:expr] ...)
  body ...)
   (if (eq? (syntax-local-context) 'expression)
   #'(parameterize ([param.c value] ...)
   body ...)
   #'(begin
   (define new-parameterization
 (parameterize ([param.c value] ...)
   (current-parameterization)))
   (do-splicing-parameterize new-parameterization body)
   ...))])

(define-syntax-parser do-splicing-parameterize
  [(_ parameterization:expr body:expr)
   (syntax-parse (local-expand #'body (syntax-local-context)
   (kernel-form-identifier-list))
 #:literal-sets [kernel-literals]
 [(begin new-body ...)
  (syntax/loc/props this-syntax
(begin
  (do-splicing-parameterize parameterization new-body)
  ...))]
 [(define-values ids rhs)
  (syntax/loc/props this-syntax
(define-values ids
  (call-with-parameterization parameterization
  (thunk rhs]
 [({~or begin-for-syntax define-syntaxes module module*
#%require #%provide #%declare}
   . _)
  this-syntax]
 [expr
  (syntax/loc/props this-syntax
(call-with-parameterization parameterization
(thunk expr)))])])

I have not extensively tested it, but it seems to work okay for simple
programs. For example, given the following program:

(define my-param (make-parameter #f))

(splicing-parameterize ([my-param #t])
  (my-param)
  (define x (my-param))
  (define (f) (my-param)))

x
(f)

...the output is:

#t
#t
#f

...which I believe makes sense, since the dynamic adjustment of my-param
does not affect its use within the internal definition of a procedure.

Additionally, mutating a parameter does the right thing, so this
program:

(splicing-parameterize ([my-param #t])
  (my-param 42)
  (my-param))

(my-param)

...produces:

42
#f

This seems like something that would make sense in racket/splicing,
though it’s different from the other forms, since they are all lexical
binding forms (even splicing-syntax-parameterize), whereas parameterize
is not.

Alexis



--
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] whither `splicing-parameterize`? or am I doing it wrong?

2018-01-23 Thread Alexis King
Here is an implementation of a version of splicing-parameterize that
uses local-expand, a la other forms in racket/splicing:

#lang racket

(require (for-syntax syntax/kerncase)
 (for-meta 2 racket/base)
 syntax/parse/define)

(begin-for-syntax
  (define-syntax (syntax/loc/props stx)
(syntax-case stx ()
  [(_ src-expr template)
   #`(let ([src src-expr])
   (datum->syntax (quote-syntax #,stx)
  (syntax-e (syntax template))
  src
  src))])))

(define-syntax-parser splicing-parameterize
  [(_ ([{~var param (expr/c #'parameter?)} value:expr] ...)
  body ...)
   (if (eq? (syntax-local-context) 'expression)
   #'(parameterize ([param.c value] ...)
   body ...)
   #'(begin
   (define new-parameterization
 (parameterize ([param.c value] ...)
   (current-parameterization)))
   (do-splicing-parameterize new-parameterization body)
   ...))])

(define-syntax-parser do-splicing-parameterize
  [(_ parameterization:expr body:expr)
   (syntax-parse (local-expand #'body (syntax-local-context)
   (kernel-form-identifier-list))
 #:literal-sets [kernel-literals]
 [(begin new-body ...)
  (syntax/loc/props this-syntax
(begin
  (do-splicing-parameterize parameterization new-body)
  ...))]
 [(define-values ids rhs)
  (syntax/loc/props this-syntax
(define-values ids
  (call-with-parameterization parameterization
  (thunk rhs]
 [({~or begin-for-syntax define-syntaxes module module*
#%require #%provide #%declare}
   . _)
  this-syntax]
 [expr
  (syntax/loc/props this-syntax
(call-with-parameterization parameterization
(thunk expr)))])])

I have not extensively tested it, but it seems to work okay for simple
programs. For example, given the following program:

(define my-param (make-parameter #f))

(splicing-parameterize ([my-param #t])
  (my-param)
  (define x (my-param))
  (define (f) (my-param)))

x
(f)

...the output is:

#t
#t
#f

...which I believe makes sense, since the dynamic adjustment of my-param
does not affect its use within the internal definition of a procedure.

Additionally, mutating a parameter does the right thing, so this
program:

(splicing-parameterize ([my-param #t])
  (my-param 42)
  (my-param))

(my-param)

...produces:

42
#f

This seems like something that would make sense in racket/splicing,
though it’s different from the other forms, since they are all lexical
binding forms (even splicing-syntax-parameterize), whereas parameterize
is not.

Alexis

-- 
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] whither `splicing-parameterize`? or am I doing it wrong?

2018-01-23 Thread Matthias Felleisen

You want to head expand not just look at the raw words, because an expression 
can expand to (define-values (x …) …). You may wish to look at how modules, 
units, and classes are expanded — Matthias




> On Jan 23, 2018, at 8:15 PM, Matthew Butterick  wrote:
> 
> 
>> On Jan 22, 2018, at 7:22 PM, Matthew Flatt > > wrote:
>> 
>> I think I've never considered `splicing-parameterize` because
>> parameters can be mutated, but a `splicing-parameterize` form does make
>> sense. I imagine that it would be implemented by creating a
>> parameterization once, then pushing the parameterization over multiple
>> expressions using `call-with-parameterization`.
> 
> IIUC, to use `call-with-parameterization`, each expression needs to become 
> the body of a thunk. This works for expressions that return a value. But 
> forms like `define` and `require` can't be used as the body of a thunk. So 
> one has to specially pluck them out. The example below works, albeit 
> brutally. Is there a more elegant pattern for picking out identifiers that 
> cannot appear as the body of a thunk?
> 
>  
> ;;;
> 
> #lang racket/base
> (require racket/splicing
>  (for-syntax racket/base racket/syntax))
> 
> (define-syntax (splicing-parameterize stx)
>   (syntax-case stx ()
> [(_ ([PARAM VAL] ...) . BODY)
>  (with-syntax* ([PZATION (generate-temporary)]
> [NEW-BODY (map (λ (stx)
>  (syntax-case stx ()
>[(ID ARG0 . ARGS)
> (memq (syntax->datum #'ID) '(define 
> define-values)) ; ... and others
> #'(ID ARG0 
> (call-with-parameterization PZATION (λ () (begin . ARGS]
>[(ID . ARGS)
> (memq (syntax->datum #'ID) '(require 
> provide splicing-let)) ; ... and others
> #'(ID . ARGS)]
>[OTHER #'(call-with-parameterization 
> PZATION (λ () OTHER))])) (syntax->list #'BODY))])
>#'(splicing-let ([PZATION (parameterize ([PARAM VAL] ...) 
> (current-parameterization))]) . NEW-BODY))]))
> 
> (define my-param (make-parameter 0))
> 
> (splicing-parameterize ([my-param 42])
>(add1 (my-param))
>(sub1 (my-param))) ; prints 43 and 41 to repl
> 
> (splicing-parameterize ([my-param 42])
>(define x (my-param))
>(check-equal? x 42)
>(define-values (y z) (values (add1 (my-param)) (sub1 
> (my-param)
> 
> (splicing-parameterize ([my-param 42])
>(require rackunit))
> 
> (check-equal? x 42)
> (check-equal? y 43)
> (check-equal? z 41)
> 
> 
> 
> 
> 
> 
> -- 
> 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] whither `splicing-parameterize`? or am I doing it wrong?

2018-01-23 Thread Matthew Flatt
If you want `splicing-parameterize` to compose with other macros that
might implement definition forms, there's no fixed set of definition
forms.

The other splicing forms use `local-expand` to detect definition forms,
since the small set of core definition forms can be reliably detected
in expanded code. See `splicing-let-body` within the implementation of
`racket/splicing`.

At Tue, 23 Jan 2018 17:15:10 -0800, Matthew Butterick wrote:
> 
> > On Jan 22, 2018, at 7:22 PM, Matthew Flatt  wrote:
> > 
> > I think I've never considered `splicing-parameterize` because
> > parameters can be mutated, but a `splicing-parameterize` form does make
> > sense. I imagine that it would be implemented by creating a
> > parameterization once, then pushing the parameterization over multiple
> > expressions using `call-with-parameterization`.
> 
> IIUC, to use `call-with-parameterization`, each expression needs to become 
> the 
> body of a thunk. This works for expressions that return a value. But forms 
> like `define` and `require` can't be used as the body of a thunk. So one has 
> to specially pluck them out. The example below works, albeit brutally. Is 
> there a more elegant pattern for picking out identifiers that cannot appear 
> as 
> the body of a thunk?
> 
>  
> ;;;
> 
> #lang racket/base
> (require racket/splicing
>  (for-syntax racket/base racket/syntax))
> 
> (define-syntax (splicing-parameterize stx)
>   (syntax-case stx ()
> [(_ ([PARAM VAL] ...) . BODY)
>  (with-syntax* ([PZATION (generate-temporary)]
> [NEW-BODY (map (λ (stx)
>  (syntax-case stx ()
>[(ID ARG0 . ARGS)
> (memq (syntax->datum #'ID) '(define 
> define-values)) ; ... and others
> #'(ID ARG0 
> (call-with-parameterization 
> PZATION (λ () (begin . ARGS]
>[(ID . ARGS)
> (memq (syntax->datum #'ID) '(require 
> provide splicing-let)) ; ... and others
> #'(ID . ARGS)]
>[OTHER #'(call-with-parameterization 
> PZATION (λ () OTHER))])) (syntax->list #'BODY))])
>#'(splicing-let ([PZATION (parameterize ([PARAM VAL] ...) 
> (current-parameterization))]) . NEW-BODY))]))
> 
> (define my-param (make-parameter 0))
> 
> (splicing-parameterize ([my-param 42])
>(add1 (my-param))
>(sub1 (my-param))) ; prints 43 and 41 to repl
> 
> (splicing-parameterize ([my-param 42])
>(define x (my-param))
>(check-equal? x 42)
>(define-values (y z) (values (add1 (my-param)) (sub1 
> (my-param)
> 
> (splicing-parameterize ([my-param 42])
>(require rackunit))
> 
> (check-equal? x 42)
> (check-equal? y 43)
> (check-equal? z 41)

-- 
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] whither `splicing-parameterize`? or am I doing it wrong?

2018-01-23 Thread Matthew Butterick

> On Jan 22, 2018, at 7:22 PM, Matthew Flatt  wrote:
> 
> I think I've never considered `splicing-parameterize` because
> parameters can be mutated, but a `splicing-parameterize` form does make
> sense. I imagine that it would be implemented by creating a
> parameterization once, then pushing the parameterization over multiple
> expressions using `call-with-parameterization`.

IIUC, to use `call-with-parameterization`, each expression needs to become the 
body of a thunk. This works for expressions that return a value. But forms like 
`define` and `require` can't be used as the body of a thunk. So one has to 
specially pluck them out. The example below works, albeit brutally. Is there a 
more elegant pattern for picking out identifiers that cannot appear as the body 
of a thunk?

 
;;;

#lang racket/base
(require racket/splicing
 (for-syntax racket/base racket/syntax))

(define-syntax (splicing-parameterize stx)
  (syntax-case stx ()
[(_ ([PARAM VAL] ...) . BODY)
 (with-syntax* ([PZATION (generate-temporary)]
[NEW-BODY (map (λ (stx)
 (syntax-case stx ()
   [(ID ARG0 . ARGS)
(memq (syntax->datum #'ID) '(define 
define-values)) ; ... and others
#'(ID ARG0 (call-with-parameterization 
PZATION (λ () (begin . ARGS]
   [(ID . ARGS)
(memq (syntax->datum #'ID) '(require 
provide splicing-let)) ; ... and others
#'(ID . ARGS)]
   [OTHER #'(call-with-parameterization 
PZATION (λ () OTHER))])) (syntax->list #'BODY))])
   #'(splicing-let ([PZATION (parameterize ([PARAM VAL] ...) 
(current-parameterization))]) . NEW-BODY))]))

(define my-param (make-parameter 0))

(splicing-parameterize ([my-param 42])
   (add1 (my-param))
   (sub1 (my-param))) ; prints 43 and 41 to repl

(splicing-parameterize ([my-param 42])
   (define x (my-param))
   (check-equal? x 42)
   (define-values (y z) (values (add1 (my-param)) (sub1 
(my-param)

(splicing-parameterize ([my-param 42])
   (require rackunit))

(check-equal? x 42)
(check-equal? y 43)
(check-equal? z 41)





-- 
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] whither `splicing-parameterize`? or am I doing it wrong?

2018-01-22 Thread Matthew Flatt
At Sun, 21 Jan 2018 17:43:04 -0500, Matthew Butterick wrote:
> I have a macro that produces code for a module expression, roughly like so:
> 
> #'(module mod racket/base
> . BODY-EXPRS)
> 
> I'd like to `parameterize` the BODY-EXPRS as a group, roughly like so: 
> 
> #'(module mod racket/base
> (parameterize ([param val])
>   . BODY-EXPRS))
> 
> But — my BODY-EXPRS might contain things like `require` and `provide`. They 
> need to be at the top level. So I want the body of the `parameterize` to be 
> spliced into the surrounding context.
> 
> I assume this is a job for `racket/splicing`. But even though it contains a 
> whole range of `splicing-let···` forms and a `splicing-syntax-parameterize`, 
> there is no `splicing-parameterize`.
> 
> Is there a different way to get this done? (Short of imperatively setting the 
> parameter, which is my current workaround) Or is there some formidable reason 
> that `splicing-parameterize` doesn't exist?

I think I've never considered `splicing-parameterize` because
parameters can be mutated, but a `splicing-parameterize` form does make
sense. I imagine that it would be implemented by creating a
parameterization once, then pushing the parameterization over multiple
expressions using `call-with-parameterization`.

Beware that a `splicing-parameterize` around a `require` could be
misleading. The `require` form just declares a dependency, but a
programmer who sees `splicing-parameterize` around `require` might
expect the parameterize to somehow wrap the dynamic loading of the
required module (and there's no way to do that, partly because the
required module might already be loaded). Then again, the same
confusion is possible with an imperative parameter assignment written
before a `require` in a module body.

-- 
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.


[racket-users] whither `splicing-parameterize`? or am I doing it wrong?

2018-01-21 Thread Matthew Butterick
I have a macro that produces code for a module expression, roughly like so:

#'(module mod racket/base
. BODY-EXPRS)

I'd like to `parameterize` the BODY-EXPRS as a group, roughly like so: 

#'(module mod racket/base
(parameterize ([param val])
  . BODY-EXPRS))

But — my BODY-EXPRS might contain things like `require` and `provide`. They 
need to be at the top level. So I want the body of the `parameterize` to be 
spliced into the surrounding context.

I assume this is a job for `racket/splicing`. But even though it contains a 
whole range of `splicing-let···` forms and a `splicing-syntax-parameterize`, 
there is no `splicing-parameterize`.

Is there a different way to get this done? (Short of imperatively setting the 
parameter, which is my current workaround) Or is there some formidable reason 
that `splicing-parameterize` doesn't exist?



-- 
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.