[racket-users] Syntax-highlighting colors in slideshow/repl ?

2020-05-11 Thread Scott Moore
Hi all,

Does anyone know of a way to set the colors for syntax highlighting in a 
slideshow/repl area? I tried using the `slideshow/code` / `pict/code` 
parameters but they don't effect slideshow/repl. I suspect I need to do 
whatever DrRacket does to the editor when you switch themes, but I can't 
seem to find out how in the docs...

Thanks,
Scott

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/4f650e4e-2f5d-4c5d-8a67-03056355d770%40googlegroups.com.


Re: [racket-users] Self evaluating Racket Interpreter

2017-05-01 Thread Scott Moore
Matthias helpfully pointed me at this 
http://www.ccs.neu.edu/home/matthias/HtDP2e/part_two.html#%28part._i2-3%29, 
which made me reflect a bit more and I agree now it is fair to say that `(1 2 
3) is short for (list 1 2 3). Perhaps a reflexive reaction from letting myself 
get confused about quotation once too many times. ;)

On May 1, 2017, 2:04 PM -0400, Scott Moore <sdmo...@fas.harvard.edu>, wrote:
> Hijacking this thread a little, but a pet peeve: ‘(1 2 3) is not short for 
> (list 1 2 3), it just happens to evaluate to that…
>
> (let ([x 0]) (list x x)) -> (list 0 0)
> (let ([x 0]) ‘(x x)) -> (list ‘x ‘x)
>
> Perhaps the reader should implement #l(, which inserts an explicit `list` at 
> the beginning of the list.
> Then there would still be a short way to write (list 1 2 3): #l(1 2 3), 
> without all the hiccups involved when using ‘ as an abbreviation for list...
>
> On May 1, 2017, 1:08 PM -0400, Ben Greenman <benjaminlgreen...@gmail.com>, 
> wrote:
> > '(1 2 3) is short for (list 1 2 3)
> > which is short for (cons 1 (cons 2 (cons 3 null))
> > which is different from (mcons 1 (mcons 2 (mcons 3 null)))
> >
> > I hope this helps
> >
> >
> > > On Mon, May 1, 2017 at 1:03 PM, <circularba...@gmail.com> wrote:
> > > > I posted this question on stackoverflow but have not found an answer 
> > > > yet. 
> > > > https://stackoverflow.com/questions/43476080/self-evaluting-racket-interpreter
> > > >
> > > > I've been trying to write a Racket interpreter that can interpret 
> > > > itself.
> > > >
> > > > interpreter.rkt contains the code for the interpreter. It is pretty 
> > > > standard. Then, in interpreter-self-evaluate.rkt, I
> > > >     1. import interpreter.rkt,
> > > >     2. copy paste the code from interpreter.rkt and
> > > >     3. evaluate the code using the eeval function defined in 
> > > > interpreter.rkt.
> > > >
> > > > However, this returns an error "; mcdr: contract violation". I suspect 
> > > > that the problem is in interpreter-self-evaluate.rkt and that it might 
> > > > have something to do with how quote works. I might be completely off 
> > > > base though. Any ideas?
> > > >
> > > > --
> > > > 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.

-- 
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] Self evaluating Racket Interpreter

2017-05-01 Thread Scott Moore
Hijacking this thread a little, but a pet peeve: ‘(1 2 3) is not short for 
(list 1 2 3), it just happens to evaluate to that…

(let ([x 0]) (list x x)) -> (list 0 0)
(let ([x 0]) ‘(x x)) -> (list ‘x ‘x)

Perhaps the reader should implement #l(, which inserts an explicit `list` at 
the beginning of the list.
Then there would still be a short way to write (list 1 2 3): #l(1 2 3), without 
all the hiccups involved when using ‘ as an abbreviation for list...

On May 1, 2017, 1:08 PM -0400, Ben Greenman , 
wrote:
> '(1 2 3) is short for (list 1 2 3)
> which is short for (cons 1 (cons 2 (cons 3 null))
> which is different from (mcons 1 (mcons 2 (mcons 3 null)))
>
> I hope this helps
>
>
> > On Mon, May 1, 2017 at 1:03 PM,  wrote:
> > > I posted this question on stackoverflow but have not found an answer yet. 
> > > https://stackoverflow.com/questions/43476080/self-evaluting-racket-interpreter
> > >
> > > I've been trying to write a Racket interpreter that can interpret itself.
> > >
> > > interpreter.rkt contains the code for the interpreter. It is pretty 
> > > standard. Then, in interpreter-self-evaluate.rkt, I
> > >     1. import interpreter.rkt,
> > >     2. copy paste the code from interpreter.rkt and
> > >     3. evaluate the code using the eeval function defined in 
> > > interpreter.rkt.
> > >
> > > However, this returns an error "; mcdr: contract violation". I suspect 
> > > that the problem is in interpreter-self-evaluate.rkt and that it might 
> > > have something to do with how quote works. I might be completely off base 
> > > though. Any ideas?
> > >
> > > --
> > > 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.

-- 
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] Re: Proper non-tail recursion?

2017-04-27 Thread Scott Moore
On the other hand, if I recall correctly SML has the same behavior as racket. I 
think the implementation uses a chain of "stacklets" that are heap allocated.

On Apr 27, 2017, 8:07 PM -0400, Jon Zeppieri , wrote:
> On Thu, Apr 27, 2017 at 8:05 PM, Hendrik Boom  wrote:
> > On Thu, Apr 27, 2017 at 07:14:15PM -0400, Jon Zeppieri wrote:
> > > On Thu, Apr 27, 2017 at 7:10 PM, Raoul Duke  wrote:
> > > > i should think any "real" fp would support it. where real is a bijection
> > > > with having such support. well, at least necessary if not sufficient.
> > >
> > > That would be a rather contentious claim, as it rules out OCaml, for 
> > > example.
> >
> > I really thought OCaml did tail-recursion properly. Its tutorial
> > literature goes th some trouble to explain that it's OK to recurse
> > tailfully. What is the truth here?
> >
>
> OCaml does handle tail calls properly. But proper tails calls are not
> the subject of this discussion. The original post was explicitly about
> non-tail calls and how, in Racket, you cannot exhaust the stack
> without exhausting all of the memory available to the program.
> (Whereas in OCaml you can, because it uses a fixed-size stack.)
>
> --
> 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] Setting parameters between files does not work as expected

2017-04-24 Thread Scott Moore
Parameters are thread local, and from reading the docs of virtual-connection 
and connection-pool, I think they create new threads to handle the connections. 
These threads are probably created before you parameterize, and thus see the 
original values.

Try replacing the virtual-connection stuff with a single call to do-connect, 
and see if that works. (Obviously not the real fix, but may help identify the 
error).

On Apr 24, 2017, 4:35 PM -0400, David Storrs , wrote:
> I'm finding parameters confusing and was hoping someone could explain them 
> for me.  The following is a simplified version of our production code; I'm 
> expecting it to fail but it does not.  What am I not understanding?
>
> The sequence goes:
>
> *) db.conf creates and provides some parameters (db username, db password, db 
> name, db port) and a function for creating database connections using those 
> parameters
>
> *) dbstuff.rkt requires db.conf, re-provides the parameters from db.conf, and 
> also provides a wrapper around the db connector from db.conf
>
> *) bar.rkt parses the command line, uses that command line data to set the 
> parameters that were imported from db.conf by way of dbstuff.rkt and makes a 
> DB call
>
> *) I run bar.rkt from the command line with an invalid username for the 
> database, expecting it to fail to connect, but it works fine???
>
>
>
> My first guess was that since I was using the parameters as default values 
> perhaps they were being evaluated at compile time instead of runtime.  I 
> tried changing the default value to #f and then doing (or u (db-user)) in the 
> body of the function, but that had no effect.
>
> I am utterly baffled at this point.  Any help would be much appreciated.
>
>
>
> # file: "db.conf"
> #lang racket
>
> (require db)
>
> (define db-user (make-parameter "postgres"))
> (define db-name (make-parameter "test-db"))
> (define db-password (make-parameter "mellon"))
> (define db-port-num (make-parameter 5433))
>
> (define (do-connect #:u [u (db-user)]
>     #:d [d (db-name)]
>     #:p [p (db-password)]
>     #:prt [prt (db-port-num)])
>   (println (~a "In db.conf db-user: " (db-user)))
>   (println (~a "db-name: " (db-name)))
>   (println (~a "db-password: " (db-password)))
>   (println (~a "db-port: " (db-port-num)))
>
>   (postgresql-connect #:user u
>   #:database d
>   #:password p
>   #:port prt
>   ))
>
> (define dbh (virtual-connection
>  (connection-pool
>   do-connect)))
>
> (define (make-connect)
>   dbh)
>
> (provide (all-defined-out))
>
>
> # file: "dbstuff.rkt"
> #lang racket
>
> (require db)
> (require "db.conf")
>
> (define/contract (dbh)
>   (-> connection?)
>   (make-connect))
>
> (provide (all-defined-out)
>  (all-from-out db)
>  (all-from-out "db.conf"))
>
>
> # file: "bar.rkt"
> #lang racket
>
> (require "dbstuff.rkt")
>
> (command-line
>  #:program "db demo"
>  #:once-each
>  [("--db-user") dbu "Username for database handles"
>   (db-user dbu)]
>  )
>
> (println (~a "In bar: db user: " (db-user)))
> (query-value (dbh) "select 'this should not have worked'")
>
>
> # command line:
>
> $ racket bar.rkt --db-user invalid_user
> "In bar: db user: invalid_user"
> "In db.conf db-user: postgres"
> "db-name: test-db"
> "db-password: mellon"
> "db-port: 5433"
> "this should not have worked"
>
>
>
>
> --
> 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] ->i applies contract projections multiple times?

2016-12-14 Thread Scott Moore
Robby beat me to it. For a longer discussion, see Christos, Robby, Cormac and 
Matthias’ paper: http://www.ccs.neu.edu/racket/pubs/popl11-dfff.pdf on the 
difference between dependent (->d) and indy-dependent contracts (->i).

A contrived example of why this is better is:
(define/contract (foo x y)
  (->d ([x (λ (x) (y ‘evil) #t)]
        [y (-> integer? integer?)])
       [result any/c])
  void)

(foo 0 (λ (x) (+ x 1)))

> +: contract violation   !!! Whoops, but I promised to only call y with 
>integers!
  expected: number?
  given: 'evil
  argument position: 1st
  other arguments…:
vs:

(define/contract (foo x y)
  (->i ([x (y) (λ (x) (y 'evil) #t)]
        [y (-> integer? integer?)])
       [result any/c])
  void)

(foo 0 (λ (x) (+ x 1)))

foo: broke its own contract  !!! Much better :)
  promised: integer?
  produced: 'evil
  in: the 1st argument of
      the y argument of
      (->i
       ((x (y) (λ (x) (y 'evil) #t))
        (y (-> integer? integer?)))
       (result any/c))
  contract from: anonymous-module
  blaming: anonymous-module
   (assuming the contract is correct)
  at: unsaved-editor:3.18

On December 14, 2016 at 3:44:56 PM, Robby Findler (ro...@eecs.northwestern.edu) 
wrote:

I think it could be possible to avoid those printfs but only because  
the contracts used here are flat, but the implementation of ->i  
doesn't do that specialization. In the general case, the contract on  
each of the depended on arguments (x and y in this case) have to be  
applied twice, once to catch errors in the contract itself and once to  
catch errors in the body of the function. (So if you'd used  
impersonator contracts, we'd have to see multiple printouts.)  

The fact that this code prints "y" twice is related, but more  
obviously a bug to be fixed.  

#lang racket  
(define/contract f  
(->i ([x any/c]  
[y (x) (begin (printf "y\n") any/c)]  
[z (x y) (begin (printf "z\n") any/c)])  
any)  
(λ args 0))  
(f 1 2 3)  

Robby  


On Wed, Dec 14, 2016 at 5:33 PM, Alexis King  wrote:  
> This question comes from someone else on Stack Overflow, which they  
> asked here: http://stackoverflow.com/q/41144374/465378  
>  
> I think it’s likely that the people who can answer this are probably  
> only on the mailing list, though, so I figured I’d ask it here.  
>  
> Basically, the ->i contract applies contract projections more than  
> once, despite the fact that it seems unnecessary. Here’s the example  
> provided in the question:  
>  
> (define/contract (foo x y z)  
> (->i ([x (λ (x) (begin (displayln 0) #t))]  
> [y (x) (λ (y) (begin (displayln 1) #t))]  
> [z (x y) (λ (z) (begin (displayln 2) #t))])  
> any)  
> #t)  
>  
> (foo 1 2 3)  
>  
> The above example prints the following when run:  
>  
> 0  
> 0  
> 1  
> 1  
> 2  
> #t  
>  
> This indicates that values used dependently for determining other  
> contracts cause their contracts to be applied more than once. The  
> above example only uses flat contracts, but I tested with a  
> side-effectful impersonator contract and got the same result.  
>  
> After some very simple pondering, I couldn’t come up with a situation  
> in which applying the contracts more than once would be necessary,  
> and this could obviously have a performance penalty given that ->i  
> is already a fairly slow contract. Is this a bug in ->i, or is it  
> necessary or intentional behavior? If the latter, why is it necessary?  
>  
> 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.  

-- 
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] Contract on a parameter’s value as a function precondition?

2016-11-28 Thread Scott Moore
It turns out that the continuation mark keys and procedures for parameters 
aren’t really hidden away, so it ended up being pretty straight forward. Below 
is a minimal implementation of parameterization->. I’m happy to help integrate 
this into the racket/contract family once we figure out what’s the nicest 
interface.

#lang racket

(require '#%paramz)

(define (parameterization-> param-name param val/c)
  (make-chaperone-contract
   #:name
   `(parameterization-> ,param-name 
                        ,(contract-name val/c))
   #:first-order
   procedure?
   #:late-neg-projection
   (λ (blame)
     (λ (value party)
       (let* ([positive (blame-replace-negative blame party)]
              [negative (blame-swap positive)])
         (unless (procedure? value)
           (raise-blame-error positive value
                              '(expected: "procedure?" given: "~e")
                              value))
         (chaperone-procedure
          value
          (λ args
            (let ([new-parameterization (extend-parameterization
                                         (continuation-mark-set-first #f 
parameterization-key)
                                         param
                                         (((contract-projection val/c) 
negative) (param)))])
              (apply values 'mark parameterization-key new-parameterization 
args)

(require rackunit)

(define p (make-parameter #f))

(define/contract (foo)
  (parameterization-> 'p p integer?)
  (p))

(define/contract (bar)
  (parameterization-> 'p p (-> integer? integer?))
  ((p) 4))

(define/contract (baz)
  (parameterization-> 'p p (-> symbol? symbol?))
  ((p) 4))

(check-exn
 exn:fail:contract?
 (thunk (foo)))

(check-not-exn
 (thunk
  (parameterize ([p 2])
    (foo

(check-not-exn
 (thunk
  (parameterize ([p (λ (x) x)])
    (bar

(check-exn
 exn:fail:contract?
 (thunk
  (parameterize ([p (λ (x) x)])
    (baz
On November 28, 2016 at 11:24:29 AM, Alexis King (lexi.lam...@gmail.com) wrote:

That sounds promising, yes. Not being familiar with the guts of  
parameters, is there any way to implement this as a derived concept  
using the existing support in chaperone-procedure? As far as I can  
tell, parameters do not expose the continuation marks they use, and  
they also create thread cells, which I’m not sure that  
chaperone-procedure’s existing API would support. Would this require  
modification of procedure chaperones to support parameters directly,  
or is there some way to implement it separately?  

> On Nov 23, 2016, at 10:51 AM, Scott Moore <sdmo...@fas.harvard.edu> wrote:  
>  
> Yes, we worked with Matthew to implement the necessary hooks in procedure 
> chaperones (see the 'mark options that were added to the return value of 
> wrapper-proc). For the contracts we were writing, we ended up using these 
> continuation marks directly.  
>  
> To implement what you're looking for, a little extra work is required to link 
> up the implementation of parameters with this mechanism to get at the 
> appropriate continuation marks. One question there will be whether to 
> integrate it with either the existing  
> arrow contracts (carefully protecting access to the internals of the 
> parameter implementation), or to just provide a standalone combinator. I 
> would need to refresh my memory to see what exactly would need to be done for 
> either.  
>  
> Cheers,  
> Scott  

-- 
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] Contract on a parameter’s value as a function precondition?

2016-11-23 Thread Scott Moore
Yes, we worked with Matthew to implement the necessary hooks in procedure 
chaperones (see the 'mark options that were added to the return value of 
wrapper-proc). For the contracts we were writing, we ended up using these 
continuation marks directly.  

To implement what you're looking for, a little extra work is required to link 
up the implementation of parameters with this mechanism to get at the 
appropriate continuation marks. One question there will be whether to integrate 
it with either the existing  
arrow contracts (carefully protecting access to the internals of the parameter 
implementation), or to just provide a standalone combinator. I would need to 
refresh my memory to see what exactly would need to be done for either.  

Cheers,  
Scott

On November 23, 2016 at 7:35:32 AM, Robby Findler 
(ro...@eecs.northwestern.edu(mailto:ro...@eecs.northwestern.edu)) wrote:

>  
> I think that Scott investigated adding support to chaperones that
> would make something like this work.
>  
> Robby
>  
>  
> On Tue, Nov 22, 2016 at 10:16 PM, Alexis King  wrote:
> > I have a function that requires a parameter be set to a value satisfying
> > a particular contract, but I don’t see any direct way to specify that
> > constraint using the contract system. It seems possible to emulate using
> > #:pre from ->* and ->i, but this has two problems: it doesn’t produce
> > very good error messages, and it doesn’t let me provide an arbitrary
> > contract.
> >  
> > The latter issue seems a little trickier to implement, since I don’t
> > think there’s any specific support in Racket’s existing interposition
> > layer. Neither impersonate-procedure nor impersonate-procedure* provide
> > any control over the dynamic extent of the call, so it isn’t possible to
> > adjust the parameterization. It’s possible to create an extremely simple
> > contract that creates an entirely new procedure instead of a chaperone
> > or impersonator:
> >  
> > (define (parameterization-> param-name param val/c)
> > (make-contract
> > #:name `(parameterization-> ,param-name
> > ,(contract-name val/c))
> > #:projection
> > (λ (blame)
> > (let ([blame* (blame-add-context
> > blame #:swap? #t
> > (format "the value of (~a)" param-name))])
> > (λ (val)
> > (λ args
> > (parameterize ([param (((contract-projection val/c) blame*)
> > (param))])
> > (apply val args
> >  
> > …but this seems like it probably has some drawbacks. Is there a better
> > way to do this? And in any case, would this be something useful to add
> > to ->* or ->i?
> >  
> > 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.

-- 
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] Re: FUSE filesystem package

2016-10-12 Thread Scott Moore
Good catch! Thanks Robby.
On October 12, 2016 at 4:03:36 PM, Robby Findler (ro...@eecs.northwestern.edu) 
wrote:

Looks like the code has a race-condition. You could either define it  
away (using thread-cells (ie once per thread)) or add some  
syncronization.  

Robby  


On Wed, Oct 12, 2016 at 4:53 PM, Scott Moore <sdmo...@fas.harvard.edu> wrote:  
> On October 12, 2016 at 2:35:37 PM, Vincent St-Amour  
> (stamo...@eecs.northwestern.edu) wrote:  
>  
> On Wed, 12 Oct 2016 16:31:46 -0500,  
> Scott Moore wrote:  
>>  
>> PS: is the documentation for use-once/c somewhere?  
>>  
>> I’ll add it to the docs when I get a chance. You can see the definition  
>> here:  
>>  
>> https://github.com/thinkmoore/racket-fuse/blob/master/private/filesystem.rkt#L132
>>   
>>  
>> use-once/c is a combinator that takes a procedure contract and makes it  
>> so that the contracted procedure can only be applied once. Ideally, I’d  
>> enforce the stronger property that you can use only one of the response  
>> or error callback for each procedure, but that would have been a bit  
>> trickier due to the need to attach the contract to two values at once.  
>> use-once/c is a nod to at least making sure you didn’t reuse them  
>> between operations...  
>  
> Any connection to Jesse's affine contracts?  
>  
> http://planet.racket-lang.org/package-source/tov/affine-contracts.plt/2/2/planet-docs/manual/index.html
>   
>  
> Vincent  
>  
> Neat! Hadn’t seen those before. My implementation is basically exactly  
> makeAffineFunContract from the paper but as a combinator instead of a new ->  
> contract.  
>  
> --  
> 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] Re: FUSE filesystem package

2016-10-12 Thread Scott Moore
On October 12, 2016 at 2:35:37 PM, Vincent St-Amour 
(stamo...@eecs.northwestern.edu) wrote:
On Wed, 12 Oct 2016 16:31:46 -0500, 
Scott Moore wrote: 
> 
> PS: is the documentation for use-once/c somewhere? 
> 
> I’ll add it to the docs when I get a chance. You can see the definition 
> here: 
> https://github.com/thinkmoore/racket-fuse/blob/master/private/filesystem.rkt#L132
>  
> 
> use-once/c is a combinator that takes a procedure contract and makes it 
> so that the contracted procedure can only be applied once. Ideally, I’d 
> enforce the stronger property that you can use only one of the response 
> or error callback for each procedure, but that would have been a bit 
> trickier due to the need to attach the contract to two values at once. 
> use-once/c is a nod to at least making sure you didn’t reuse them 
> between operations... 

Any connection to Jesse's affine contracts? 

http://planet.racket-lang.org/package-source/tov/affine-contracts.plt/2/2/planet-docs/manual/index.html
 

Vincent 
Neat! Hadn’t seen those before. My implementation is basically exactly 
makeAffineFunContract from the paper but as a combinator instead of a new -> 
contract.

-- 
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] Re: FUSE filesystem package

2016-10-12 Thread Scott Moore
On October 12, 2016 at 12:15:38 PM, Dupéron Georges 
(jahvascriptman...@gmail.com) wrote:
This is great! Thumbs up, and thanks for writing this library. I have a couple 
of filesystems in my "TODO" list, hopefully this package will motivate me to 
actually write them one of these days :) . 
Awesome!

A nice feature would be some simpler API for creating filesystems which work by 
virtually moving or changing the attributes of (or concatenating + splitting, 
or otherwise transforming) files stored in an existing directory. This is a 
common use case in FUSE, I believe. 

PS: is the documentation for use-once/c somewhere?
I’ll add it to the docs when I get a chance. You can see the definition here: 
https://github.com/thinkmoore/racket-fuse/blob/master/private/filesystem.rkt#L132

use-once/c is a combinator that takes a procedure contract and makes it so that 
the contracted procedure can only be applied once. Ideally, I’d enforce the 
stronger property that you can use only one of the response or error callback 
for each procedure, but that would have been a bit trickier due to the need to 
attach the contract to two values at once. use-once/c is a nod to at least 
making sure you didn’t reuse them between operations...

-- 
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] FUSE filesystem package

2016-10-11 Thread Scott Moore
Hi all,

I'm announcing a new package: fuse (
https://github.com/thinkmoore/racket-fuse).

fuse is a racket library for implementing filesystems in userspace using
the FUSE API available on many *nix platforms and OS X (currently, I've
only tested using recent releases of FUSE on Linux).

People have used FUSE to implement a wide variety of neat stuff, like
distributed filesystems, providing a filesystem API for accessing a music
library by various search criteria, or mounting gmail as a storage system.
Now you can write your own filesystem in Racket!

The package implements communication routines for interfacing with the FUSE
kernel driver. Client programs can implement a userspace filesystem by
providing a collection of functions that implement filesystem
operations. Currently,
the package depends on the libfuse C library to mount a FUSE filesystem.
However, the communication protocol with the kernel and filesystem API does
not reuse libfuse functionality, and this dependency will be removed in a
future release.

The FUSE API is huge and I've only done very limited testing, so there are
likely bugs. If you encounter some, please file an issue!

Cheers,
Scott

-- 
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] dynamic-require

2016-03-20 Thread Scott Moore
If the definitions are saved as “test.rkt”, the following works: 

#lang racket 

(module a racket/base (displayln "hello")) 
(dynamic-require '(submod "test.rkt" a) #f) 

On March 16, 2016 at 12:13:46 PM, Jos Koot (jos.k...@gmail.com) wrote:

Hi,
 
The following example of dynamic-require in the reference manual works in the 
interactions window of DrRacket, but not in its definitions window:
 
(module a racket/base (displayln "hello"))
(dynamic-require ''a #f)
 
How do I do this in the definitions window?
 
The reason I use dynamic-require is that I want to set some parameters before 
submod a is executed.
 
I found out I can do the following:
 
#lang racket
(module a racket/base (displayln "hello"))
(module b racket/base (current-output-port (open-output-file ...)))
(require 'b)
(require 'a)
 
To me this seems an ugly trick.
In addition I am not sure this is guaranteed to work consistently.
How can I dynamically require a submod in the same source as it is defined?
 
Jos
--
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] Unicode subscripts in code and scribble

2016-03-10 Thread Scott Moore
Whoops left off the mailing list...
On March 10, 2016 at 2:48:49 PM, Scott Moore (sdmo...@fas.harvard.edu) wrote:

On March 10, 2016 at 2:41:53 PM, Leif Andersen (l...@leifandersen.net) wrote:
On the other hand, I'm all down for making a `literal` or `exact` 
scribble form that spits out the literal text into the target latex or 
html. (Like what Vincent seems to use in his papers, or is in my 
`doodle` package.) 
This isn’t defined in the library but the functionality is there:

(define (exact txt) (make-element (make-style #f '(exact-chars)) txt))

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

2016-02-11 Thread Scott Moore
Yes, around 80% of the time if I disable macro hiding, and sometimes even with 
macro hiding if I’m moving back and forth through a long sequence of steps.

I had been meaning to file a report...
On February 11, 2016 at 11:27:21 AM, Matthias Felleisen (matth...@ccs.neu.edu) 
wrote:


... has anyone seen this error message from stepping thru macros:  

[:~/svn/2HtDP] matthias% sequence-contract-violation: negative: method 
set-max-width cannot be called, except in states (unlocked write-lock), args 
834  
context...:  
/Users/matthias/plt/racket/collects/racket/private/more-scheme.rkt:148:2: 
call-with-break-parameterization  
/Users/matthias/plt/racket/share/pkgs/gui-lib/mred/private/lock.rkt:43:38  
/Users/matthias/plt/racket/collects/racket/private/more-scheme.rkt:265:2: 
call-with-exception-handler  
/Users/matthias/plt/racket/share/pkgs/gui-lib/mred/private/wxme/text.rkt:766:2: 
end-edit-sequence method in text%  
/Users/matthias/plt/racket/share/pkgs/macro-debugger/macro-debugger/view/stepper.rkt:438:4:
 update* method in macro-stepper-widget%  
/Users/matthias/plt/racket/share/pkgs/macro-debugger/macro-debugger/view/stepper.rkt:400:31
  
.../more-scheme.rkt:261:28  
/Users/matthias/plt/racket/share/pkgs/macro-debugger/macro-debugger/view/stepper.rkt:369:24
  

--  
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] Reliable equality testing of procedures

2015-11-04 Thread Scott Moore
One place where this can go wrong is with contracts.

Contracts are implemented using chaperones and impersonators (depending on the 
particular contract) 
http://docs.racket-lang.org/reference/chaperones.html?q=chaperone#%28tech._chaperone%29.
 Because of how chaperones and impersonators work, a procedure with a contract 
may be equal? to the original procedure, but is not eq? to it.

I would suggest using equal? in your implementation instead of eq? That way if 
someone receives one of your measures with a contract around it, the 
get-maximum procedure will still work.

I’m not sure if there are other pitfalls to look out for. I’m sure others will 
chime in.
On November 4, 2015 at 11:14:47 AM, Erich Rast (er...@snafu.de) wrote:

Hi,  

I have a number of functions for computing raw distance measures and  
functions to compute their maxima for a given number of items, so to  
normalize them to [0,1] I provide this:  

(define (normalize/distance measure maximum)  
(lambda (p q)  
(/ (measure p q) (maximum (full-domain-size p q)  

However, the maximum procedure seems unnecessary, because every measure  
has its own maximum. So I was wondering whether I could leave it out  
and instead use something like this:  

(define (get-maximum measure)  
(cond  
((eq? measure footrule) footrule-maximum)  
((eq? measure bogart) bogart-maximum)  
.  
.  
.  
(else (error 'get-maximum "unknown measure ~s" measure  

both internally and for export. But if I also export it, because  
sometimes people might want to use the respective procedure directly,  
is this really safe? Will this always work, or can this somehow  
interfere with macros, modules, etc.?  

Best,  

Erich  

--  
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] let/define

2015-11-03 Thread Scott Moore
I think its more a complexity of “define” than of “begin” (though begin is 
certainly tricky be because it can introduce and internal definition context).

Your student’s program has the same behavior as this program without the begin, 
since the let also introduces a definition context:

(let ([y 5])
  (display y)
  (define y 10)
  y)
On November 3, 2015 at 8:51:38 AM, Éric Tanter (etan...@dcc.uchile.cl) wrote:

Thanks all! This is helpful — the mental model of begin that I presented to my 
students was too simple to account for defines.

-- Éric


On Nov 2, 2015, at 10:00 PM, Scott Moore <sdmo...@fas.harvard.edu> wrote:

The relevant part of the reference for these “internal definition contexts” is 
here: 
http://docs.racket-lang.org/reference/syntax-model.html#%28part._intdef-body%29

That’s a very operational description, but amounts to saying “the bindings from 
a define in an internal definition context are visible to all other 
definitions/expressions in the same internal definition context."
On November 2, 2015 at 7:52:43 PM, Scott Moore (sdmo...@fas.harvard.edu) wrote:

Does it help to think of let and begin as introducing a new scope, and define 
as having “block scope” (or whatever they call this sort of thing in trendy 
languages like javascript)?

I’m guessing the reason you found this to be unintuitive is that the ‘y’ in 
(display y) refers to something that comes after it in the source, which would 
not be the case if the semantics of define were more like a let:

(let ([y 5])
  (begin
     (display y)
     (define y 10)
     y

=>

(let ([y 5])
  (begin
     (display y)
     (let ([y 10])
        y

But that ‘y’ appears in the scope of the begin, which is the scope in which the 
define inserts it’s bindings.

Not sure if this was helpful…
On November 2, 2015 at 7:39:16 PM, Robby Findler (ro...@eecs.northwestern.edu) 
wrote:

Yeah, perhaps I've drunk too much of the koolaid, but I'm not even
seeing an alternative interpretation that makes any sense!

Does it help to see the arrows in DrRacket? In particular the upward
pointing one that points at the 'y' in display's argument?

Robby


On Mon, Nov 2, 2015 at 6:32 PM, Alex Knauth <alexan...@knauth.org> wrote:
> This is because begin can have potentially recursive and mutually recursive
> definitions in it.
>
> This does the same thing:
> (let ([y 5])
> (local [(define x y) ; this y should be bound to
> (define y 10)] ; <- this y, but it is used too early
> y))
>
> While this slightly different case works fine:
> (let ([y 5])
> (local [(define (x) y) ; this y is bound to
> (define y 10)] ; <- this y, but it is within a function
> y))
>
> When the first y in the local is within a function, it isn't evaluated until
> the function is called, so that's fine.
>
> But when the first y in the local is evaluated right away, before it is
> defined, it raises an error.
>
> It doesn't make sense for it to be bound to the outer y, because then it
> would be inconsistent with the version where it is within a function.
>
>
> On Nov 2, 2015, at 7:13 PM, Éric Tanter <etan...@dcc.uchile.cl> wrote:
>
> Hi all,
>
> Some of my creative students came up with the following:
>
> (let ([y 5])
> (begin
> (display y)
> (define y 10)
> y)))
>
> which raises a mysterious
> y: undefined;
> cannot use before initialization
>
> I remember earlier discussion on this list about the fact that `define' was
> somehow “broken” for various cases of nesting, and that it was part of the
> motivation for coming up with `local’. Sure enough, the following works as
> expected:
>
> (let ([y 5])
> (begin
> (display y)
> (local [(define y 10)]
> y)))
>
> While I don’t intend to motivate my students to do funky let/define nesting,
> I would like to be able to explain why the error is raised. Any (sensible)
> explanation?
>
> Thanks!
>
> -- Éric
>
> --
> 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.

--
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://gr

[racket-users] Strange garbage collection behavior with closures

2015-10-21 Thread Scott Moore
I’m trying to do something a bit fancy that makes use of weak-hashes, but I’ve 
run into strange behavior (things not being removed that I believe should be) 
when I use keys that are closures. Doing some of my own debugging, this doesn’t 
appear specific to weak hashes, but also to weak boxes. Here is a short example 
(based on the example programs in section 19.11 of 
http://docs.racket-lang.org/guide/performance.html):

#lang racket

(struct foo ())

(define box #f)

(let ([f (foo)])
  (set! box (make-weak-box f))
  (weak-box-value box))
(weak-box-value box)
(collect-garbage)
(weak-box-value box)

(let ([f (λ () 0)])
  (set! box (make-weak-box f))
  (weak-box-value box))
(weak-box-value box)
(collect-garbage)
(weak-box-value box)

I expect the output of this program to be:

#
#
#f
#
#
#f

Curiously, I do get this answer if I paste the program to pasterack.org. If 
instead I run the program in DrRacket, or at the command line (both compiled 
and not compiled), I get this output:

#
#
#f
#
#
#

Any idea what is happening here? As far as I can tell, the reachability of “f” 
in both code blocks should be identical, despite the difference in the type of 
value. Maybe some sort of compiler transformation or a subtlety in the 
reachability analysis? Or a bug?

Thanks,
Scott

-- 
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] Capability security in Racket?

2015-08-19 Thread Scott Moore
Hi Sean,

An alternative approach you might consider instead of relying heavily on
sandboxes and namespaces is to define your own #lang where you can
carefully control how different objects are allowed to communicate with
each other. This approach could have two advantages:
1) you can use lighter-weight mechanisms to represent objects, and
2) you can restrict things to make it much less likely that you would get
bitten by a misunderstanding how namespaces and require, etc, work.

We used a similar approach when writing Shill, our capability-based shell
scripting language based on Racket (shill-lang.org). You can find a short
description of how we did this in section 3.1 of the paper (
http://shill.seas.harvard.edu/shill-osdi-2014.pdf).

Cheers,
Scott

On Tue, Aug 18, 2015 at 12:48 AM, Sean Lynch se...@literati.org wrote:

 Hi, folks. I'd like to implement an LPMUD-like multi-user programmable
 environment in Racket. The idea is that an object would be a module plus
 some state, similar to a gen_server in Erlang. Objects would each live in
 their own sandbox and communicate with one another via message passing,
 probably via channels.

 So far so good; despite my inexperience with Racket, I am fairly certain
 this should be straightforward to implement. And a sandbox per persistent
 object and message passing between them doesn't seem like it would be too
 high a price to pay, since this is what Erlang does, and it's similar to
 what LPMUD and MOO and Genesis do.

 However, users nee to be able to extend and reuse one another's code, and
 I'd like them to be able to do that without having to trust the code not to
 leak private state or affect their own code's behavior in unexpected ways.
 It seems like I can use contracts to some extent to help users from
 accidentally passing or returning excessively powerful capabilities
 (however I implement those: proxies, closures, etc); But at the very least
 I know that any function called in a required module can inspect and
 modify the current namespace, which will affect dynamic code even if it
 doesn't affect module code. And I imagine there are probably other
 introspection functions that could enable access at least to any state
 stored in top-level variables.

 So my question is: assuming it is even practical to protect state from
 code in required modules running in the same sandbox, what would be the
 best way to go about this? Or are sandboxes and channels (or some other way
 to pass messages between sandboxes) cheap enough that that's the best way?

 --
 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
 https://urldefense.proofpoint.com/v2/url?u=https-3A__groups.google.com_d_optoutd=BQMFaQc=WO-RGvefibhHBZq3fL85hQr=OPR-Xys5wfSBIeTkWaH0D_htBR-X7qY24pTHU6ib2iMm=vNTo0BhTaa0rf5fiErRpax-tpq3uFcfyQMrQ0pZ_dccs=xIiHlc9nqPBTsx6n-KUJPsWMGd6iTGjpZyp6arDHCJoe=
 .


-- 
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-introducing macros with inter-macro communication channel

2015-06-23 Thread Scott Moore
I ran into this issue recently. The right answer for me was to write a
trampolining macro. define-values is treated specially by the macro
expander and thus can't be handled easily in a local expand. The pattern I
ended up using (adapted from an old mailing list post by Ryan and a
discussion with Matthew and Robby) is the following:

1) expand in whatever the current syntax context is and add define-values
to the stop list (to prevent attempting to expand it outside of a
definition context)

(local-expand my-stx (syntax-local-context) (list #'define-values))

2) Use syntax-case on the resulting syntax to find any occurrences of
define-values, then replace the body of each define-values with a new call
to your macro:

(define-syntax (my-syntax stx)
  (syntax-case stx ()
[(my-syntax expr)
 (syntax-case (local-expand stx (syntax-local-context) (list
#'define-values)) ()
   [(define-values (id) expr) (define-values (id) (my-syntax expr))]
   [other other])]))

Note this code might not work verbatim... I abstracted it from my example
as I pasted it in...

This pattern seems fairly robust for getting your macro to run on all of
the expanded code in a local context. The downside is that your macro will
need to work correctly in this staged fashion where things run as the
expander gets to them.

Hope this helps.

Cheers,
Scott

On Tue, Jun 23, 2015 at 2:23 PM, Sam Tobin-Hochstadt sa...@cs.indiana.edu
wrote:

 Based on the documentation, I thought that the right answer would be
 `(list (gensym))` but that didn't work -- hopefully someone else
 knows.

 Sam

 On Tue, Jun 23, 2015 at 4:43 PM, Thomas Dickerson
 thomas_dicker...@brown.edu wrote:
  I thought that might be the case, but the documentation is pretty dense
 (and
  self-referential), so it's not clear what the correct value for that
  argument is.
 
  Thomas Dickerson
 
  Brown University
  Department of Computer Science
  115 Waterman St, 4th Floor
  Providence, RI 02912
 
  802-458-0637
 
  On Tue, Jun 23, 2015 at 3:57 PM, Sam Tobin-Hochstadt 
 sa...@cs.indiana.edu
  wrote:
 
  To fix your last issue, you probably want to provide a different value
 as
  the `context-v` argument (the 2nd one) to `local-expand`.
 
  Sam
 
  On Tue, Jun 23, 2015 at 3:46 PM Thomas Dickerson
  thomas_dicker...@brown.edu wrote:
 
  Okay - for posterity's sake, here's an updated version of Alex's code
  that supports nested Loop/Accum, and doesn't leave any syntactic
 residue
  after expansion. This is now what I set out to accomplish with my
 original
  set of questions:
 
  #lang racket/base
 
  (require racket/stxparam
   (for-syntax racket/base
 
   racket/set
   racket/syntax
   syntax/parse
   syntax/stx
   syntax/context))
 
  (define-syntax Loop
(lambda (stx)
  (syntax-parse stx
[(Loop accum-id:id up-to-expr:expr body:expr ...+)
 (let* ([defs (syntax-local-make-definition-context)]
[ctx (generate-expand-context)])
   (syntax-local-bind-syntaxes
(list #'accum-id)
(local-transformer-expand
 #'(let ([vars (mutable-set)])
 (lambda ([stx #f])
   (if (syntax? stx)
   (syntax-parse stx
 [(accum-id x:id dx:expr)
  (set-add! vars (syntax-local-introduce #'x))
 
 
  #'(set! x (+ x dx))])
 
   vars))) 'expression null) defs)
   (internal-definition-context-seal defs)
   (with-syntax* ([(body ...)
   (stx-map
(lambda (body)
  (with-syntax ([body body])
(local-expand #'body ctx null defs)))
#'(body ...))]
  [(init ...)
   (map
(lambda (var)
  (with-syntax ([var (syntax-local-introduce
  var)]) #'(set! var 0)))
(set-list
 ((syntax-local-value
   (internal-definition-context-apply defs
  #'accum-id)
   #f defs])
 #'(let ([up-to up-to-expr])
 
 
 (letrec
 ([loop
   (lambda (n)
 body ...
 
 (let ([n (add1 n)])
   (if ( n up-to)
   (loop n)
   (void])
   init ...
   (loop 0)]
 
 
[(Loop up-to-expr:expr body:expr ...+)
 
 (with-syntax
 ([Accum (datum-syntax stx 'Accum)])
   #'(Loop Accum up-to-expr body ...))])))
 
  (let ([x (void)] [y (void)] [z (void)])
(Loop 2
  (let ([dx 1] [dy 2] [dz 3])

[racket-users] Fully-expanding a define form in its definition context

2015-05-04 Thread Scott Moore
Hi,

I'm trying to write a macro that fully-expands define forms with the goal
of doing some static checking (and thus want the code in racket core so
that I know what I'm looking at). Ideally, this macro would work in any
context where a define form works. Unfortunately, I'm having a great deal
of difficulty using local-expand to get what I want. I've tried a few
approaches---the code and simple examples are below.

Local expanding as a 'top-level' definition was closest to working because
it both fully-expands the definition and inserts binding into the enclosing
definition context. Unfortunately, it seems to fail to bind the identifier
correctly in the body of its own define.

I tried expanding in the 'syntax-local-context', but this causes
define-values to complain that it isn't in a definition context (even
though syntax-local-context is a module context, which I thought was a
definition context).

Creating a new definition context makes the expansion work, but the binding
goes into the newly created context, which isn't what I want. It also
doesn't fully expand the definition. (If I remove define-values from the
stop list, it tries to fully-expand but dies complaining that define-values
is not in a definition context).

I think I'm probably misreading the documentation. Can anyone suggest a
correct solution?

Thanks,
Scott

#lang racket

(require (for-syntax syntax/parse
 syntax/parse/lib/function-header))

(define-for-syntax (definition-local-context-expand stx)
  (local-expand stx (syntax-local-context) '()))

(define-syntax (define-expand-top-level stx)
  (syntax-parse stx
#:literals (define-expand-top-level)
[(define-expand-top-level header:function-header body ...+)
 (local-expand #'(define header body ...) 'top-level '())]))

(define-syntax (define-expand-local-context stx)
  (syntax-parse stx
#:literals (define-expand-local-context)
[(define-expand-local-context header:function-header body ...+)
 (local-expand #'(define header body ...) (syntax-local-context) '())]))

(define-syntax (define-expand-new-context stx)
  (syntax-parse stx
#:literals (define-expand-new-context)
[(define-expand-new-context header:function-header body ...+)
 (let* ([def-ctx (syntax-local-make-definition-context)]
[ctx (if (list? (syntax-local-context))
 (cons (gensym) (syntax-local-context))
 (list (gensym)))]
[expd (local-expand #'(define header body ...) ctx (list
#'define-values) def-ctx)])
   (define ids (syntax-parse expd [(def (id) _) (list #'id)]))
   (syntax-local-bind-syntaxes ids #f def-ctx)
   (internal-definition-context-seal def-ctx)
   expd)]))

; Works as expected
(define-expand-top-level (foo n)
  (+ n 1))

(foo 5)

; Fails to bind fib in the body of the define
#;(define-expand-top-level (fib n)
  (if (= n 1)
  1
  (+ (fib (- n 1)) (fib (- n 2)
; fib: unbound identifier in module in: fib

; Attempt to use the local-context (which should be a definition context?)
#;(define-expand-local-context (fib n)
  (if (= n 1)
  1
  (+ (fib (- n 1)) (fib (- n 2)
; define-values: not in a definition context in:
; (define-values (fib) (lambda (n) (if (= n 1) 1 (+ (fib (- n 1)) (fib (-
n 2))

; Creating new definition context makes the expand work but doesn't expose
; the identifiers to the definition context I really want
(define-expand-new-context (fib n)
  (if (= n 1)
  1
  (+ (fib (- n 1)) (fib (- n 2)

#;(fib 3)
; fib: unbound identifier in module in: fib

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