Re: [racket-users] Re: How to make DrRacket interactions window use the same reader as the definitions window?

2020-05-29 Thread Thomas Dickerson
Jens -

Interesting - does the default #%top-interaction behave differently from
#%module-begin w.r.t. to a #lang's read?
Right now my main.rkt is providing the standard #%module-begin,
#%top-interaction, #%app, #%datum, and #%top, in addition to my language's
functions + macros.

Thanks!

On Fri, May 29, 2020 at 4:51 PM Jens Axel Søgaard 
wrote:

> There may be other solutions, but one way to control the evaluation of
> expressions entered in the REPL
> is to provide an   #%top-interaction, which sets the appropriate
> parameters.
>
> /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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/CA%2BHWosWC9yWUAjG-bNB8tVbygOV%2BXcfmsF0Z1p6vF7Jja81GCg%40mail.gmail.com.


Re: [racket-users] Re: How to make DrRacket interactions window use the same reader as the definitions window?

2020-05-29 Thread Thomas Dickerson
f the relevant code is supposed to 
go.


Any guidance from someone who knows their way around these systems (as they 
relate to my queries above) would be immensely helpful (and should probably 
also just be added to the documentation pages).

On Friday, May 29, 2020 at 12:25:58 PM UTC-4, Thomas Dickerson wrote:
>
>
>
> On Friday, May 29, 2020 at 11:29:38 AM UTC-4, Matthew Flatt wrote:
>>
>> DrRacket uses `pretty-print`, which will print numbers using 
>> `number->string`, and so (I think) won't go through your parameter. 
>>
>
> This sounds like a good lead - curious if this also applies to `write` and 
> `display` as well? 
> I was having trouble with all three.
>  
>
>> I think there may be problems with parametering the core printer, 
>> partly because printing is is sometimes used where `read` is supposed 
>> to work on the result, but I think there may be other issues and I 
>> haven't thought through them enough. 
>>
>
> The intended use is in a setting where `read` has already been extended 
> (cf. my original question in this thread, which is that the DrRacket 
> interactions window appears to ignore any `read` extensions provided by a 
> #lang)
>  
>
>> Just to make sure, does using the pretty printer and its hooks 
>> (especially `pretty-print-print-hook`) work for your goals? 
>>
>
> It sounds like that may be useful for fixing this particular issue with 
> DrRacket, but I don't think it will meet my goals for the overall project.
> One question - to what extent are pretty-print-print-hooks expected to 
> cooperate with the current value of that parameter when printing compound 
> or recursive values?
> It would be great to install a hook that delegates to the existing hook 
> for everything but numbers, but that approach not working with 
> port-print-handler et al. is what led me to parameterizing over all of 
> print et al.
>
> For example, if for some reason I want numbers to be printed as Roman 
> numerals, I don't want to reimplement printing lists for `(print '(7))` to 
> result in `'(VII)`
>
>

-- 
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/b5cad591-6eba-4900-9286-89db73b652b0%40googlegroups.com.


Re: [racket-users] Re: How to make DrRacket interactions window use the same reader as the definitions window?

2020-05-29 Thread Thomas Dickerson


On Friday, May 29, 2020 at 11:29:38 AM UTC-4, Matthew Flatt wrote:
>
> DrRacket uses `pretty-print`, which will print numbers using 
> `number->string`, and so (I think) won't go through your parameter. 
>

This sounds like a good lead - curious if this also applies to `write` and 
`display` as well? 
I was having trouble with all three.
 

> I think there may be problems with parametering the core printer, 
> partly because printing is is sometimes used where `read` is supposed 
> to work on the result, but I think there may be other issues and I 
> haven't thought through them enough. 
>

The intended use is in a setting where `read` has already been extended 
(cf. my original question in this thread, which is that the DrRacket 
interactions window appears to ignore any `read` extensions provided by a 
#lang)
 

> Just to make sure, does using the pretty printer and its hooks 
> (especially `pretty-print-print-hook`) work for your goals? 
>

It sounds like that may be useful for fixing this particular issue with 
DrRacket, but I don't think it will meet my goals for the overall project.
One question - to what extent are pretty-print-print-hooks expected to 
cooperate with the current value of that parameter when printing compound 
or recursive values?
It would be great to install a hook that delegates to the existing hook for 
everything but numbers, but that approach not working with 
port-print-handler et al. is what led me to parameterizing over all of 
print et al.

For example, if for some reason I want numbers to be printed as Roman 
numerals, I don't want to reimplement printing lists for `(print '(7))` to 
result in `'(VII)`

-- 
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/593eccc6-6bbf-4604-85b8-ac5f9d4ba89f%40googlegroups.com.


[racket-users] Re: How to make DrRacket interactions window use the same reader as the definitions window?

2020-05-29 Thread Thomas Dickerson
On an apparently related note:

I have modified Racket to allow parameterized control over how numbers are 
written/printed/displayed ( cf. https://github.com/racket/racket/pull/3222 
).
This works fine from command-line racket, but DrRacket (installed using 
`raco pkg install -i drracket` of my modified racket) is merrily doing its 
own thing and printing numbers without invoking my parameterized routine. 

It doesn't appear to be a case of DrRacket using a separate binary, because 
I can still read and set the parameter, it just has no effect.

Thoughts?

-- 
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/6f260d7e-68e0-454c-9d81-04d74cb78b9a%40googlegroups.com.


Re: [racket-users] What is the purpose of "compact" code paths in print.c?

2020-05-28 Thread Thomas Dickerson
Perfect, thanks for insight =)

-- 
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/CA%2BHWosVZGa1aOEbznUnAi535a%2BcqrX_zDGfZNejaiOeCnTgCyQ%40mail.gmail.com.


[racket-users] What is the purpose of "compact" code paths in print.c?

2020-05-28 Thread Thomas Dickerson
I'm working on an enhancement for write/print/display, and thought I had it 
all implemented in io/print/main.rkt before realizing that code is only 
used for Racket-CS.

Now I'm working on making equivalent changes in print.c for the traditional 
implementation, and that code is substantially more complex.
Among other things, print has a bunch of checks against a variable called 
"compact", but I can't find any comments (either in the source or in the 
git log) as to what its for / when its used.
Can anyone comment?

-- 
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/1a2b4d7d-bdf7-4cbb-bf9e-6565c7bfec28%40googlegroups.com.


[racket-users] How to make DrRacket interactions window use the same reader as the definitions window?

2020-05-27 Thread Thomas Dickerson
I'm working on #lang with a custom reader (via read-table extension), that 
among other things, defines custom syntax for duodecimal numbers. 

My reader is working great in the definitions window / when I hut "Run" in 
DrRacket, and the top of the interaction window shows the name of my #lang, 
but my custom literal syntax is being read as an (undefined) identifier.

Any thoughts on what I'm missing?

Thanks!

-- 
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/483bb175-67c7-45c4-9a77-49a0347e10aa%40googlegroups.com.


Re: [racket-users] Re: C++ and pointer registration with 3M?

2019-11-01 Thread Thomas Dickerson
On Fri, Nov 1, 2019 at 6:04 PM Matthew Flatt  wrote:

> Just unnecessary.


Great :)

>
It's not common, but that can happen. The GC can recognize and ignore
> pointers that are not to its own space.


This also fits my mental model, but I wanted to make sure I understood the
corner cases.

>

Thanks!
-- 
Thomas Dickerson
Founder // Chief Science Officer
Geopipe, Inc.

802-458-0637

-- 
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/CA%2BHWosW4Zuc33A6%2BHpwyVr%2BSXOHyEEKd7w5D-EmkHQkm6bkvsQ%40mail.gmail.com.


Re: [racket-users] Re: C++ and pointer registration with 3M?

2019-11-01 Thread Thomas Dickerson
Great, this is very helpful.

On Fri, Nov 1, 2019 at 4:53 PM Matthew Flatt  wrote:

> At Fri, 1 Nov 2019 10:34:50 -0700 (PDT), Thomas Dickerson wrote:
> Only pointers to GCable memory --- which tends to be the things passed
> to a Racket function, but more generally corresponds to things that
> come from Racket .
>

Is it an error to register things which are not GCable, or just unnecessary?
Also - are there ever likely to be pointers which could hold memory which
may or may not be GCable depending on the code path?
(e.g. a `const char*` that is sometimes converted from a Racket string, and
sometimes provided by a C string)

> - Do I need to register the data pointer passed to
> > `scheme_main_stack_setup`, even though this is above the GC's stack base?
>
> No. As you say, that's before the GC is ready.
>
> > - In an instance method, does `this` need to be registered? What about
> > reference types?
>
> A `this` pointer does not point to GCable memory, unless you do well
> out of your way to allocate an object with Racket's allocator.
>
> The value of a variable with a reference type would normally correspond
> to an address on the C stack, so it would not need to be registered.
>

Great, this matches my mental model of what should be happening, but I've
been seeing very strange behavior, so I was getting paranoid.

-- 
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/CA%2BHWosXA2oFQT0igYpGrKY%3DJLAV5dc2cU9rY1frhU5ig34a2PQ%40mail.gmail.com.


[racket-users] Re: C++ and pointer registration with 3M?

2019-11-01 Thread Thomas Dickerson
Sorry for the double-post, one more question.

The output of `raco ctool --c-mods` has the form:

#ifdef MZ_XFORM
> XFORM_START_SKIP;
> #endif
> static void declare_modules(Scheme_Env *env) {
>   static unsigned char data[] = { /* bytes go here */ };
>   scheme_register_embedded_load(NUM_BYTES, (const char *)data);
>   scheme_embedded_load(NUM_BYTES, (const char *)data, 1);
> }
> #ifdef MZ_XFORM
> XFORM_END_SKIP;
> #endif
>

As I understand it, this means there's no reason to pass it through `raco 
ctool --xform`, which presumably means we don't need need to register `env` 
or `data`, but we are seeing `scheme_embedded_load` in the stack trace of 
some Racket routines that triggered a watchpoint on memory that it 
shouldn't be touching, so I just wanted to double check that's indicative 
of a problem upstream.

On Friday, November 1, 2019 at 1:34:50 PM UTC-4, Thomas Dickerson wrote:
>
> The documentation says:
> "The 3m collector needs to know the address of every local or temporary 
> pointer within a function call at any point when a collection can be 
> triggered."
>
> A couple questions:
> - Is this "every pointer which might be passed to a Racket function, or 
> contain the result of a Racket function"? Or is it truly *every pointer*?
> - Do I need to register the data pointer passed to 
> `scheme_main_stack_setup`, even though this is above the GC's stack base?
> - In an instance method, does `this` need to be registered? What about 
> reference types?
>

-- 
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/91dbac56-97da-4446-ab49-d061dc36f8f6%40googlegroups.com.


[racket-users] C++ and pointer registration with 3M?

2019-11-01 Thread Thomas Dickerson
The documentation says:
"The 3m collector needs to know the address of every local or temporary 
pointer within a function call at any point when a collection can be 
triggered."

A couple questions:
- Is this "every pointer which might be passed to a Racket function, or 
contain the result of a Racket function"? Or is it truly *every pointer*?
- Do I need to register the data pointer passed to 
`scheme_main_stack_setup`, even though this is above the GC's stack base?
- In an instance method, does `this` need to be registered? What about 
reference types?

-- 
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/7f3c6482-f24f-4bd5-8590-5feca4145317%40googlegroups.com.


Re: [racket-users] Help me understand FFI callouts in this context?

2019-10-31 Thread Thomas Dickerson
Hi Sage - 

Does your SIGSEGV MAPERR show up only while attached to a debugger?
If so I noticed similar behavior while debugging my own project this week, 
and opened #2882 .
It took me quite a bit of head scratching before I realized that (a) it 
only manifests as an immediate crash when the process is attached to a 
debugging tool, and (b) it happens even if I don't try to run any of my own 
code.

Let me know if this is helpful.

On Wednesday, October 30, 2019 at 4:57:08 PM UTC-4, Sage Gerard wrote:
>
> Hi Matthew, 
>
> I reproduced "SIGSEGV MAPERR si_code 1 fault on addr (nil)" after 
> specifying '#:atomic? #t', so not out of the woods yet. 
>
> If you wish I can help you set up Vulkan off-list. 
>
> > Will the callback definitely be invoked in the same OS-level thread as 
> calls to Vulkan functions? 
>
> Yes. [1] 
>
> Even so, I specified #:async-apply for grins. No change in behavior. 
>
> The only new development I can share is that the program now functions 
> correctly, provided that if I comment out the expression that tries to 
> register the callback. Previously the program was not even finished, so I 
> can at least say the problem is isolated. 
>
> I tried setting PLTSTDOUT to "debug" and prepared a diff between the 
> output when I try to use the callback, and the output when I don't try at 
> all. Sadly, when the program breaks the last line from STDOUT is 'ffi-lib: 
> loaded "libvulkan.so"'. 
>
> I'll wait for one more round of advice on troubleshooting before writing a 
> repository that reproduces the problem with added logging in a C shim. 
>
> [1]: 
> https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html#VkDebugReportCallbackCreateInfoEXT,
>  
> "A callback will always be executed in the same thread as the originating 
> Vulkan call." 
>
>
> ~slg 
>
> ‐‐‐ Original Message ‐‐‐ 
> On Tuesday, October 29, 2019 9:35 AM, Matthew Flatt  > wrote: 
>
> > I haven't been able to get Vulkan going on my machines, so I can't run 
> > your code enough to offer reliable advice. 
> > 
> > Still, I wonder whether making the callback atomic has any effect. 
> > To make the callback atomic: 
> > 
> > -   Change the definition of `_PFN_vkDebugReportCallbackEXT` to add 
> > `#:atomic? #t` after `_fun`. 
> > 
> > -   Don't use `printf` in the callback, because that's not safe from 
> > atomic code. Instead, use logging, which is ok to use from atomic 
> > code. 
> > 
> > "Atomic" means atomic with respect to the Racket runtime system, so 
> > Racket won't try to swap its threads while running the callback. 
> > Swapping threads involves coping the C stack, which often annoys 
> C/C++ 
> > libraries. 
> > 
> > Will the callback definitely be invoked in the same OS-level thread 
> as 
> > calls to Vulkan functions? If not, then specify `#:async-apply 
> (lambda (thunk) (thunk))` alongside `#:atomic? #t` to make sure the 
> callback is 
> > run in Racket's thread. 
> > 
> > At Sun, 27 Oct 2019 19:57:52 +, Sage Gerard wrote: 
> > 
> > 
> > > I was still stumped on this one due to the opaque error message and 
> repeated 
> > > comparisons to the original source appearing correct. I stepped away 
> for a 
> > > while to think about it, and the only option I see to help me along is 
> to 
> > > write a shared library in C that behaves similarly, and have it log 
> noisily to 
> > > STDOUT whatever it gets from a Racket program. 
> > > Since writing this shim would be tedious, are there any additional 
> > > troubleshooting techniques or tools unique to Racket that can help me 
> narrow 
> > > down the root cause of a crash in foreign code? 
> > >  Original Message  
> > > On Oct 25, 2019, 1:56 AM, Sage Gerard wrote: 
> > > 
> > > > Hi Ryan, and thank you for the detailed and informative reply! 
> > > > I gathered that I should trust Racket's handling of values across 
> the 
> > > > foreign boundary more, 
> > > > and used what I learned from your email to get past one error. 
> Sadly, I 
> > > > landed on 
> > > > "SIGSEGV MAPERR si_code 1 fault on addr (nil)" right after, and 
> under a 
> > > > different context. 
> > > > The affected expression can be found at 1, and I verified that I do 
> not 
> > > > try to use a NULL pointer. 
> > > > This is a case where foreign function returns a "dummy" pointer to 
> another 
> > > > function whose 
> > > > signature the client is expected to know in advance, but the address 
> of the 
> > > > foreign 
> > > > function would NOT be known to get-ffi-obj since the procedure is 
> loaded 
> > > > dynamically 
> > > > by the library itself 2. 
> > > > The Vulkan docs call for casting this pointer to the function I 
> need. So if 
> > > > I'm understanding your email 
> > > > correctly, I need to prepare a value such that I produce a callout 
> object 
> > > > that knows the right signature. 
> > > > I tried using (cast) and 

Re: [racket-users] Efficient idiom for converting key-set of a hash-map into a hash-set

2019-10-30 Thread Thomas Dickerson
Hi Simon -

Thanks for the detailed reply, my responses are in-line below.

~Thomas

On Wed, Oct 30, 2019 at 7:52 AM Simon Schlee  wrote:

> Racket has mutable and immutable hash tables these are implemented
> differently.
> Because as a user of hash tables you have to differentiate between mutable
> and immutable,
>
I dug into the source a little bit here: for posterity, the immutable hash
"tables" are actually HAMTs.
There's no particular reason why the mutable hash tables couldn't also be
HAMTs, but the fact that they're not suggests a good reason at least for
why there wouldn't be an efficient direct conversion from mutable maps and
sets to immutable maps and sets.


> Immutable hash tables are excellent for your use case, because you can
> easily keep around the original version just by keeping a
> variable/reference to it.
> As its name implies it is immutable/not changed, so when you "update" the
> hash that you are using as a set you aren't really updating it, instead you
> create a new updated hash from it, while the original version remains as it
> was. Because the immutable hash is implemented as a persistent
> data-structure with structural sharing, this is efficient,
>
I'm reasonably familiar
 with the
semantics of persistent data structures =)


> because it doesn't copy everything but instead only copies a few small
> internal nodes, those which need to be changed, the rest refers to the
> old/original version.
> Depending on the racket version there are different internal
> implementations of immutable hashes,
> but you can expect operations like hash-set to create a small extended
> version of your hash (if you are using racket's immutable hashes) that
> doesn't copy the complete hash.
>
In my use case, persistence will result in *O(N log N)* unnecessary
allocations, since the root-to-leaf path will be rewritten *N* times as I
drain the set.
Threading the state in and out of the function calls implementing my loop
will also make my code a lot more verbose for no particular gain, as
opposed to just wrapping a mutable set in a closure.


> Immutable hash tables actually provide O(log N) access and update. Since N
>> is limited by the address space so that log N is limited to less than 30
>> or 62 (depending on the platform), log N can be treated reasonably as a
>> constant.
>>
> from https://docs.racket-lang.org/reference/hashtables.html
>
This is actually six years out of date and should be updated: a HAMT is
typically bounded to depth 6 or 7.


> Another possibility is to create a custom-set implementation which wraps
> the hash to appear like a set, here is an example implementation:
>
> #lang racket
>
> (provide (contract-out
>   [proxy-set (-> (and/c hash? immutable?) generic-set?)])
>  proxy-set->set
>  proxy-set->seteq
>  proxy-set->seteqv)
>
> (require racket/struct)
>
> (struct proxy-set [hash]
>   ;; #:transparent
>   #:methods gen:set
>   [(define (set-member? s k)
>  (hash-has-key? (proxy-set-hash s) k))
>(define (set-add s v)
>  (proxy-set (hash-set (proxy-set-hash s) v #f)))
>(define (set-remove s v)
>  (proxy-set (hash-remove (proxy-set-hash s) v)))
>(define (set-empty? s)
>  (hash-empty? (proxy-set-hash s)))
>(define (set-count s)
>  (hash-count (proxy-set-hash s)))
>(define (set->stream s)
>  (sequence->stream (in-immutable-hash-keys (proxy-set-hash s]
>
>   #:methods gen:custom-write
>   [(define write-proc
>  (make-constructor-style-printer
>   (lambda (s) 'proxy-set)
>   (lambda (s) (in-immutable-hash-keys (proxy-set-hash s)])
>
> ;; these functions are in case you eventually don't need the proxy anymore
> ;; and want to convert to a plain racket set
> (define/contract (proxy-set->set s)
>   (-> proxy-set? (and/c generic-set? set-equal? set?))
>   (for/set ([k (in-immutable-hash-keys (proxy-set-hash s))])
> k))
>
> (define/contract (proxy-set->seteq s)
>   (-> proxy-set? (and/c generic-set? set-eq? set?))
>   (for/seteq ([k (in-immutable-hash-keys (proxy-set-hash s))])
> k))
>
> (define/contract (proxy-set->seteqv s)
>   (-> proxy-set? (and/c generic-set? set-eqv? set?))
>   (for/seteqv ([k (in-immutable-hash-keys (proxy-set-hash s))])
> k))
>
> (define-syntax-rule (show x)
>   (displayln (format "~a: ~a" (quote x) x)))
>
> (define (example)
>   (define original-map (hasheq 'a 4 'b 7 'c 1))
>   (show original-map)
>
>   (define extended-map (hash-set original-map 'another 42))
>   (show extended-map)
>
>   (define derived-set (proxy-set original-map))
>   (show derived-set)
>
>   (define extended-set (set-union derived-set (seteq 'd 'e)))
>   (show extended-set)
>
>   (displayln "after all that the original map remains unchanged")
>   (show original-map)
>   (displayln "and the extended set does not modify the derived set")
>   (show derived-set)
>
>   (displayln "you also can merge the new keys from the 

Re: [racket-users] Efficient idiom for converting key-set of a hash-map into a hash-set

2019-10-29 Thread Thomas Dickerson
Hi All,

Thanks for the information + various ideas.
The various suggest constructs provide a helpful view on different corners
of the language, but all appear to have the characteristic of throwing out
the existing hashtable structure from the map and then reconstructing it
from scratch for the new set (which is fine in a big-O sense, but feels
like it can be improved upon in principle).

Responding specifically to Stephen:

> I don't know of a more efficient way to convert, but depending on what
> operations you want, you might be able to compute it directly on the
> hash, e.g., see hash-has-key?, hash-keys-subset?, hash-union, etc. (I
> didnt know about some of the functions until recently.)
>

I agree that if I just needed to query an existing notional set, this would
be a good approach without having to copy at all.
Unfortunately, I need to be able to update the set over time without
modifying the original map, and maintaining a second map when I only need
the keys seems even more wasteful than the intermediate conversion to list.

Best,
~Thomas

-- 
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/CA%2BHWosUDPW4bfWCH84zC-%2B_YtX67eJ%3DO1Th57qUFqTN0afPvkQ%40mail.gmail.com.


[racket-users] Efficient idiom for converting key-set of a hash-map into a hash-set

2019-10-25 Thread Thomas Dickerson
For reasons that are unclear to me, hash-keys and dict-keys both return a 
list? instead of a set? (frankly, this seems like a bug in the API...).

Is there a something I can do that's more efficient than just calling 
list->set?

-- 
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/36eb8bd7-45eb-4ebb-be30-ebdfd89023fe%40googlegroups.com.


Re: [racket-users] Re: Retina display for OpenGL

2019-08-14 Thread Thomas Dickerson
It seems like the issue here is not with the OpenGL setup, but with 
figuring out whether or not the draw context passed to a snip supports 
high-resolution drawing.
Presumably the answer is "yes" somewhere in the pipeline, since the font 
rendering in the REPL doesn't look noticeably worse than the font rendering 
in my menu bar.
The question is what plumbing needs to be established in between to make 
use of it (or whether or not the plumbing is there to begin with).

-- 
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/713574fc-6572-47cf-87a1-fd28135295e4%40googlegroups.com.


Re: [racket-users] Language-Specific Plugins: Toolbar button functionality to call drracket:eval:expand-program

2019-07-23 Thread Thomas Dickerson

On Tuesday, July 23, 2019 at 12:35:27 PM UTC-4, Thomas Dickerson wrote:
>
>
> Yes - the architecture we eventually settled on is a main submodule that 
> does roughly this to get a black-box value which we can pass back to a 
> rendering function to produce a gl-bitmap, and stick it in a snip.
>

Sorry for the double email, but for posterity I want to be slightly more 
specific here: our main submodule uses dynamic-require for all of the 
graphics/rendering functionality, to avoid saddling our embedded Racket 
used by C++ applications with extra dependencies.

-- 
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/a9a2868d-a3c8-475e-9968-1a6c57db0e5b%40googlegroups.com.


Re: [racket-users] Language-Specific Plugins: Toolbar button functionality to call drracket:eval:expand-program

2019-07-23 Thread Thomas Dickerson


On Tuesday, July 23, 2019 at 2:34:47 AM UTC-4, Robby Findler wrote:
>
> Sorry for letting this thread lapse. Wrt to your third option 
> mentioned below, would it work to make that option accessible via the 
> FFI? If so, then maybe you could make the "essentially phase shifted 
> everything" into "actually phase shifted everything" and then when you 
> get the result program have your #%module-begin call into the FFI to 
> actually run the program. Does that seem like a viable option? 
>

Yes - the architecture we eventually settled on is a main submodule that 
does roughly this to get a black-box value which we can pass back to a 
rendering function to produce a gl-bitmap, and stick it in a snip.

By the way - it seems you weren't the only person who doesn't use OpenGL 
very often from Racket, because gl-bitmap had bit-rotted somewhat, compared 
to a 'gl-styled canvas, but my PR got merged, and gl-bitmaps now support 
core contexts.

-- 
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/48abec2f-ff48-4360-ab8d-7115056d349e%40googlegroups.com.


Re: [racket-users] Re: Racket2 possibilities

2019-07-23 Thread Thomas Dickerson
A couple thoughts, not particularly well-organized, but in a more 
accessible form here than just tweeting at Alexis.

In all this discussion of "parens-less LISP", I find it slightly odd that 
nobody has mentioned Logo yet. I'm ambivalent about surface syntax, but 
it's not like this is a revolutionary idea.

Since people are talking about running on different "VM" architectures, an 
LLVM backend would be lovely and gives WebAssembly for free.
JVM support, on the other hand, seems like a particularly poor time 
investment, since (1) there is no shortage of options for functional 
programmers, and (2) the only real advantage of running on JVM is if you 
can provide interoperability with the massive Java ecosystem, but that's 
essentially incompatible with working around the JVM's bad architectural 
decisions.
The elephant in the room for any Scheme running on the JVM is that (a) 
cross-function tail call elimination is incompatible with the security 
model; (b) trampolining everything is bad for performance and, more 
importantly, makes interoperability miserable (have fun writing all your 
Java code that calls Racket code in manual CPS-style); and (c) throwing 
everything into a massive state machine while-loop with gotos is both a 
static analysis nightmare and breaks the JIT optimizer due to single-method 
bytecode size restrictions.

As someone who loves the Racket philosophy and 
language-oriented-programming, but who is also very interested in building 
large-scale practical systems, the single biggest obstacle to me using 
Racket over other functional languages (mostly Scala/Dotty) for personal 
projects is the lack of static typing (Typed Racket feels very much like a 
second-class citizen in the ecosystem).
My deepest dream would be for Racket2 to have static type-checking as the 
default, with opt-in Rust-like affine types for programs that need precise 
resource management.
Essentially any other outcome is "fine, I guess".

-- 
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/0e71f4c5-da98-4fcc-aed9-03a2bd547994%40googlegroups.com.


Re: [racket-users] Language-Specific Plugins: Toolbar button functionality to call drracket:eval:expand-program

2019-07-01 Thread Thomas Dickerson
On Mon, Jul 1, 2019 at 2:23 PM Philip McGrath 
wrote:

>
> I believe the main submodule will still be compiled the enclosing module
> is loaded from source, but that should be trivial: it really only needs a
> `require` and a function call. If the file has already been compiled to
> bytecode, the bytecode for the main submodule won't be loaded, nor for any
> of its transitive dependencies.
>
> Depending on how you are distributing your code, you may or may not want
> to add an indirection via `dynamic-require` to prevent the distribution
> building tools from shipping graphics libraries that you only need for the
> main submodule. (Basically this would be the reverse of what
> `racket/runtime-path` does.) I haven't done much with the tools for
> distributing built artifacts beyond toy experiments, but I think some of
> them may be able to do that stripping automatically or with e.g. a
> command-line flag, without needing a `dynamic-require`. At the maximum, you
> could put the graphics modules in their own package, analogous to the
> `foo`+`foo-lib`+`foo-doc`+`foo-test` convention: in that case, the support
> library for your main submodule (what I called
> `hypothetical-lanugage/private/render`) would just be a stub to
> `dynamic-require` the `render` function or do something useful if the
> graphics package isn't installed, like print a message to standard error.
>

I'll chew on this, but if the dependencies for the main submodule need to
be available at the time that it is compiled, then the easiest thing may
just be doing a dynamic-require.


>  I haven't used OpenGL, from Racket or otherwise, but it might be possible
> to use a bitmap from `make-gl-bitmap` as a buffer for your OpenGL drawing
> and copy it to the canvas via `draw-bitmap`. If you have an existing
> foreign library that does the actual drawing, you can get a
> platform-specific pointer via `gl-context<%>
> `.
>

That's an interesting possibility, and I shouldn't actually need the
gl-context pointer, just to make it current before calling the foreign
rendering code.


>  I suspect, though, that a solution would involve your support library
> cooperating with an extension set up by your #lang.
>
Right, this is what we originally hand in mind.


> On the whole, though, either returning a snip or creating a new `frame%`
> would probably be easier. Using a new `frame%` would also be entirely
> independent of DrRacket: I expect it would work with racket-mode for Emacs,
> for example.
>
frame% is portable, but also not a very nice UI. I'll see what can be done
with a snip.

On Mon, Jul 1, 2019 at 2:56 PM Robby Findler 
wrote:

> I think I'm missing a bit more context so I'll continue this line of
> questions. The path that you seem to be heading down seems to be one
> where you'll duplicate a lot of work that's already gone into
> DrRacket, and it seems unlikely to me that it is the most productive


Perhaps you could elaborate on the mechanisms you think we would be
duplicating, because those may provide either the entry points we're
looking for, or clarify a potential miscommunication on our end.


> Can you say a little more about what you want to do with DrRacket?


Currently, most of our DSL programs are constructed automatically from
inferred geometry, and it's fine, because an artist/programmer doesn't need
to do any design work.
Going forward, we would like to also be able to model reusable parametric
object classes that we can plug in to our scenes, and here it would be very
helpful to be able to visualize the geometry generated by our DSL programs
interactively.
Rather than reinventing the wheel, and writing our own editor, we would
like to bend DrRacket to our will for that purpose; however, the current
"Run" button doesn't seem like quite the right UI for that.

Do you expect to be able to run these programs? If so, does it
> make sense to run them when you aren't in the
> embedded-in-the-huge-C++-code-base mode? How about compilation of the
> programs (i.e. macro expansion)?


We've essentially phase shifted everything, so that Racket's Phase 0 is
really Phase 1 in a DSL library implemented with C++, which provides our
"core language", so the result of "running" the Racket program is a pointer
to an opaque C++ type which represents the fully expanded syntax for our
program, ready to be evaluated by the C++ geometry library.
Racket's Phase 1 handles type checking + inference of the surface language,
converting pretty surface syntax into a lot of horrific FFI code, and
providing a consistent API to the resulting modules to make it easy to grab
the C++ representation of the DSL program.

We currently can then either just run this as a Racket program, which
works, but is basically useless, *or* further stuff the Racket interpreter
into a C++ library for reading, writing, and executing our DSL programs
from elsewhere in the C++ code base. We would like to have a third option
which 

Re: [racket-users] Language-Specific Plugins: Toolbar button functionality to call drracket:eval:expand-program

2019-07-01 Thread Thomas Dickerson
Thanks for the responses.

On Fri, Jun 28, 2019 at 5:50 PM Philip McGrath 
wrote:

> If you're sure you want to get the raw program source and deal with it
> manually, you can use the method `get-definitions-text
> `
> on the DrRacket frame given as an argument to your button's callback
> function. This will give you the editor object for the definitions window.
> You can then use a method like `get-flattened-text
> `
> to get the source as a sting or (probably better) the function `
> open-input-test-editor
> `
> to get an input port directly.
>

This is very helpful, thanks.


> Again, this part works just fine. In particular, because of the way Racket's
> submodules
> 
> work, the code in the "main" submodule *does not* run when you
> instantiate the parent module, whether via `scheme_dynamic_require`,
> `dynamic-require`, `require`, or some other way: the compiled form of the
> submodule need not even be loaded into memory. So you can use rendering
> code in the main submodule without creating a dependency for your main
> application.
>

Specifically, this means we can avoid byte-compiling and loading any
graphics modules the main submodule depends on, yes?


> It could certainly open a new GUI window, and it could also return a value
> that renders as an embedded widget (snip) in the interactions pane. (See
> the plot library for an example.)
>

Snips seem nice, but even browsing through the source for the 3d renderers
for plot, I don't see any way to get an OpenGL context for a snip, since
they appear to work on predefined DCs, rather than allowing you to
construct a canvas.


> I haven't looked at the DrRacket extension APIs enough to be sure whether
> you could open a new pane in the DrRacket window, but it certainly seems
> possible.
>

Are you aware of any projects that usefully manipulate the interactions
pane that I could turn to for example code? It looks like it's possible to
extend that class.


On Sun, Jun 30, 2019 at 11:44 AM Robby Findler 
wrote:

> May I ask why you need to have the C++ code embed Racket instead of
> the other way around (ie using the FFI)?


The short answer is this project is a very small part of a very large
enterprise C++ code base, and it's not reasonable to rewrite every single
program in our toolkit that needs to interact with our DSL to be a dynamic
library with a Racket front-end.


> Generally speaking, DrRacket (and other Racket tools) are going to work
> better if they get to
> "drive", I expect.


Thankfully we're not trying to embed DrRacket - our applications are
primarily command-line driven, so the editor enhancements are just for
artist convenience.

The rest of the time, Racket happily sits in its own stack
,
and has no idea we've embedded in it (although since the time that was
written, the Boost Coroutines library was deprecated, so we built our own
).

-- 
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/CA%2BHWosX%2BcPFjOTuKT6iWHoJh3M93fdOfYBijQedfkBkJszRxGw%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] Jupyter Racket Kernel - iracket

2019-06-26 Thread Thomas Dickerson
Sorry - typo. that should be "Racket v7.3"

On Wednesday, June 26, 2019 at 2:05:20 PM UTC-4, Thomas Dickerson wrote:
>
> Let's say you have DrRacket 7.3 installed. Then your raco and racket 
> executables are in "/Applications/Racket 7.3/bin". You can either specify 
> the full path manually, or add that to your PATH by editing your .bashrc.
>
>
> On Wednesday, June 26, 2019 at 1:39:10 PM UTC-4, Arie Schlesinger wrote:
>>
>> Hi,
>> I installed iracket on Dr Racket, but still can not run raco pkg install 
>> iracket and not racket -l iracket/install to enable racket on jupyter .
>>
>> thanks
>>
>> On Wed, Jun 26, 2019 at 11:09 AM John Clements  
>> wrote:
>>
>>> It may be that ‘raco’ is not in your path. An alternative is to use the 
>>> “Package Manager” that’s built into DrRacket, under “File>Package Manager…” 
>>> to install libraries such as iracket.
>>>
>>> > On Jun 23, 2019, at 09:10, Arie Schlesinger  
>>> wrote:
>>> > 
>>> > Hi,
>>> > I am trying to install racket for jupyter on a mac, and from the 
>>> github it is not clear for me how to do it.  
>>> > I use Dr Racket,  still running "raco pkg install iracket" is not 
>>> recognized in the mac shell.
>>> > 
>>> > Thanks,
>>> > Ari
>>> > 
>>> > On Friday, May 4, 2018 at 9:57:42 AM UTC+3, Graham Dean wrote:
>>> > Pleasure Ryan. Thanks for developing iracket, it's really useful for 
>>> me to demonstrate on-going work using Racket.
>>> > Graham
>>> > 
>>> > 
>>> > -- 
>>> > 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...@googlegroups.com.
>>> > To view this discussion on the web visit 
>>> https://groups.google.com/d/msgid/racket-users/e58716f9-f60f-48a7-a2bf-d79d477880a0%40googlegroups.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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/38defbd0-3107-4a5a-be3f-fc43960494d0%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] Jupyter Racket Kernel - iracket

2019-06-26 Thread Thomas Dickerson
Let's say you have DrRacket 7.3 installed. Then your raco and racket 
executables are in "/Applications/Racket 7.3/bin". You can either specify 
the full path manually, or add that to your PATH by editing your .bashrc.


On Wednesday, June 26, 2019 at 1:39:10 PM UTC-4, Arie Schlesinger wrote:
>
> Hi,
> I installed iracket on Dr Racket, but still can not run raco pkg install 
> iracket and not racket -l iracket/install to enable racket on jupyter .
>
> thanks
>
> On Wed, Jun 26, 2019 at 11:09 AM John Clements  > wrote:
>
>> It may be that ‘raco’ is not in your path. An alternative is to use the 
>> “Package Manager” that’s built into DrRacket, under “File>Package Manager…” 
>> to install libraries such as iracket.
>>
>> > On Jun 23, 2019, at 09:10, Arie Schlesinger > > wrote:
>> > 
>> > Hi,
>> > I am trying to install racket for jupyter on a mac, and from the github 
>> it is not clear for me how to do it.  
>> > I use Dr Racket,  still running "raco pkg install iracket" is not 
>> recognized in the mac shell.
>> > 
>> > Thanks,
>> > Ari
>> > 
>> > On Friday, May 4, 2018 at 9:57:42 AM UTC+3, Graham Dean wrote:
>> > Pleasure Ryan. Thanks for developing iracket, it's really useful for me 
>> to demonstrate on-going work using Racket.
>> > Graham
>> > 
>> > 
>> > -- 
>> > 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...@googlegroups.com .
>> > To view this discussion on the web visit 
>> https://groups.google.com/d/msgid/racket-users/e58716f9-f60f-48a7-a2bf-d79d477880a0%40googlegroups.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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/421ef4a2-bba9-4f4b-970b-88b7653b33d3%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] Language-Specific Plugins: Toolbar button functionality to call drracket:eval:expand-program

2019-06-26 Thread Thomas Dickerson
Hi,

Chiming in here, because Kshitij is working on this project for me.
It sounds like Philip has answered (3) and most of (2).

On Tuesday, June 25, 2019 at 10:06:07 PM UTC-4, Philip McGrath wrote:
>
> The functionality you describe—in particular, setting up clean evaluation 
> contexts—sounds a lot like what the "Run" button already does. Unless you 
> have some other notion of "running" in mind for programs in your DSL, I 
> think what you describe could be accomplished nicely with a "main" 
> submodule, which (as you may know) is run only when its enclosing module is 
> invoked as a main program, not when it is required as a library. One 
> benefit is that this would make this functionality independent of DrRacket.
>

A couple additional bits of context:

   - The DSL he is working on is embedded in a C++ application and strongly 
   typed, so we have several different notions of "running", which are 
   orthogonal to DrRacket's run button:
  1. The language is a language for describing parametric 3D models, 
  not for rendering, and the final result of being evaluated by Racket is a 
  module containing a provided result value, which is a pointer to a 
  C++ object which represents some a low level program evaluated by our C++ 
  runtime to produce a triangle mesh.
  2. Our C++ applications obtain the result value from a DSL program by 
  calling scheme_dynamic_require in the inner loop of a Racket 
  interpreter we've stuffed into a coroutine 
  .
  3. When the toolbar button is pushed in DrRacket we want to evaluate 
  the program in a fresh namespace, (dynamic-require ''module-name 
  'result), and then pass that result value into a C++ FFI function 
  that will handle the C++ side of evaluation and doing the actual OpenGL 
  calls to visualize it in the editor. This should have similar behavior to 
  the run button from an evaluation standpoint, but after evaluating the 
  program, enter a render loop until, e.g. the button is pushed again to 
stop 
  rendering. Here, the DrRacket plugin is responsible for creating the 
OpenGL 
  context, which could be in a separate window, but as Kshitij said it 
would 
  be ideal if we could figure out how to add a pane below the REPL.
  
 

>
> To illustrate what I mean, your source program:
> #lang hypothetical-lanugage
> (hypothetical-code)
> would be transformed by the reader into:
> (module example hypothetical-lanugage
>   (#%module-begin
> (hypothetical-code)))
> Then, your `#%module-begin` macro might expand to something like:
> (module example hypothetical-lanugage
>   (#%plain-module-begin
> (provide shape)
> (define shape (hypothetical-code))
> (module* main racket/base
>   (require (submod "..")
>hypothetical-lanugage/private/render)
>   (render shape
>
> What I'm most unsure of about your question is that you say you want to 
> use a "C++ library that contains a function that takes in a module object 
> as input." Do you mean that you want to use the Racket C API 
> 
>  
> to create a new primitive module or something? That is not a very common 
> thing to do. Racket modules are not first-class values. While you can 
> produce a value representing the compiled form of a module (`
> compiled-module-expression? 
> `)
>  
> by doing something like:
> (compile '(module foo racket/base))
> that is rarely what you want to do. In particular, the result of calling 
> `eval` is not a module (unless of course you do something like `(eval 
> '(compile '(module foo racket/base)) (make-base-namespace))`. 
>
> Calling `eval` on a module form, compiled or otherwise, merely declares 
> the module: it doesn't immediately do anything. For example, this 
> expression:
> (let ([ns (make-base-namespace)])
>   (eval '(module effects racket/base
>(println "running"))
> ns)
>   (println "module evaluated")
>   (eval '(require 'effects) ns))
> prints:
> "module evaluated"
> "running"
> because the module isn't run until the `require` form is evaluated. Also, 
> `eval` handles expanding the program already: manual expansion is only 
> needed if you want to do some kind of static analysis.
>

What is the "correct" way to get the current program source code from the 
DrRacket editor to pass into eval?
drracket:eval:expand-program seemed closest, given the type of the first 
argument, but the plugin documentation is not clear and we don't actually 
know how to get the relevant input port or text-pos.




On Wednesday, June 26, 2019 at 12:06:36 AM UTC-4, Jack Firth wrote:
>
> This sounds very similar to 

Re: [racket-users] Correctly executing a source file from embedded Racket

2017-08-09 Thread Thomas Dickerson
On Thursday, July 27, 2017 at 9:01:11 AM UTC-4, Matthew Flatt wrote: 
> Declaring (as opposed to instantiating) a compiled module will normally
> not raise an exception. Probably it's possible to construct a set of
> embedded modules where there will be a declare-time error due to
> conflicting or missing declarations, but I don't see how to make that
> happen only sometimes.

Good to know.

> The escape-catching pattern is needed anywhere that you don't want to
> just exit/crash.
> 
> You can certainly call multiple `scheme_...` functions within a single
> escape-handling block, including multiple calls to `scheme_eval_string`.

Also good to know, thanks.

On Wednesday, July 26, 2017 at 11:09:48 AM UTC-4, Matthew Flatt wrote:
> At Wed, 26 Jul 2017 07:54:32 -0700 (PDT), Thomas Dickerson wrote:
> > One more thing: in terms of repeatedly executing scripts, does it make 
> > sense 
> > to set up and tear down the interpreter every time? Or just swap in a fresh 
> > namespace?
> 
> Between those two options, a fresh namespace is almost certainly
> better.

For posterity, it's worth noting that you can use the Boost Coroutine library 
to implement this in C++ in a nice object-oriented fashion to make a loop that 
executes Racket tasks in a way that doesn't require bouncing your `main` 
through `scheme_main_setup` or equivalent, which is great if you're embedding a 
racket interpreter to be reused as an API rather than a one-off program.

-- 
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] Correctly executing a source file from embedded Racket

2017-07-26 Thread Thomas Dickerson
On Wednesday, July 26, 2017 at 11:09:48 AM UTC-4, Matthew Flatt wrote:
> At Wed, 26 Jul 2017 07:54:32 -0700 (PDT), Thomas Dickerson wrote:
> > One more thing: in terms of repeatedly executing scripts, does it make 
> > sense 
> > to set up and tear down the interpreter every time? Or just swap in a fresh 
> > namespace?
> 
> Between those two options, a fresh namespace is almost certainly
> better.

Thanks. 

> Depending on how much you need to reset, you might be even better off
> with `dynamic-rerequire` from `racket/rerequire`.

Interesting. When would a rerequire be necessary, over a require? 
`dynamic-require` documentation says "Dynamically instantiates the module 
specified by mod in the current namespace’s registry at the namespace’s base 
phase, if it is not yet instantiated."
Is a module instantiation local to the current namespace? If so, it sounds like 
wiping the namespace is sufficient.

On Wednesday, July 26, 2017 at 12:27:09 PM UTC-4, Shu-Hung You wrote:
> Hi Thomas,
> 
> I tried following Matthew's suggestions to attach my-lang and use
> dynamic-require. Turns out that works pretty well! And then there's
> even no need to setup collection path since everything loads from
> compiled byte-code.
> https://gist.github.com/shhyou/aa2adaf7e1b7d548783cee352c3230a9
> 
> The code is basically calling (dynamic-require `(file ,argv-1) #f) to
> run the external script. At line 35, the code builds (list 'file
> argv-1) and at line 41 the code dynamic-requires the script.
> 
> /* custom_dsl.cpp
> 
> $ raco ctool --cgc --c-mods base.c ++lib racket/base ++lib
> racket/base/lang/reader ++lib racket/runtime-config ++lib my-lang
> ++lib my-lang/lang/reader
> 
> $ g++ -framework Foundation -I/racket/include
> -L/racket/src/build/racket
> -L/racket/src/build/rktio custom_dsl.cpp -o
> custom_dsl -lracket -lmzgc -lrktio -liconv
> 
> $ ./custom_dsl ./a-module.rkt
> 
>  */
> #include 
> #include 
> 
> #include "base.c"
> 
> static int run(Scheme_Env *e, int argc, char *argv[])
> {
>   Scheme_Object *curout;
>   int i;
>   Scheme_Thread *th;
>   mz_jmp_buf * volatile save, fresh;
> 
>   /* Declare embedded modules in "base.c": */
>   declare_modules(e);
>   scheme_namespace_require(scheme_intern_symbol("my-lang"));
> 
>   curout = scheme_get_param(scheme_current_config(),
>   MZCONFIG_OUTPUT_PORT);
> 
>   th = scheme_get_current_thread();
> 
>   save = th->error_buf;
>   th->error_buf = 
>   if (scheme_setjmp(*th->error_buf)) {
> th->error_buf = save;
> return -1; /* There was an error */
>   } else {
> std::cout << "Trying to load file from \"" << argv[1] << "\"\n";
> Scheme_Object *custom_dsl_path[2];
> custom_dsl_path[0] = scheme_make_pair(
>scheme_intern_symbol("file"),
>scheme_make_pair(
>  scheme_make_utf8_string(argv[1]),
>  scheme_make_null()));
> custom_dsl_path[1] = scheme_make_false();
> Scheme_Object *custom_dsl = scheme_dynamic_require(2, custom_dsl_path);
> th->error_buf = save;
>   }
>   return 0;
> }

Thanks for the continued help with this! I found that once I switched to using 
`dynamic-require` I didn't even need the initial `scheme_namespace_require`

The core of my script execution code now looks like this:

|   ret = boost::none;
|   Scheme_Object *drArgs[2] = {scheme_make_path(filename), 
resultSym_};
|   Scheme_Object *loadResult = scheme_dynamic_require(2, drArgs);
|   if(SCHEME_CPTRP(loadResult)){
|   Scheme_Object *resT = SCHEME_CPTR_TYPE(loadResult);
|   if(acceptedTypeTag_ == resT){
|   ret = 
(AcceptedType*)SCHEME_CPTR_VAL(loadResult);
|   } else {
|   std::cerr << "Wrong type-tag received" << 
std::endl;
|   Scheme_Object *curout = 
scheme_get_param(scheme_current_config(), MZCONFIG_ERROR_PORT);
|   std::cerr << "Got: ";
|   scheme_display(resT, curout);
|   scheme_display(scheme_make_char('\n'), curout);
|   std::cerr << "Wanted: ";
|   scheme_display(acceptedTypeTag_, curout);
|   scheme_display(scheme_make_char('\n'), curout);
|   }
|   } else {
|   std::cerr << "Result was not a cptr" << std::end

Re: [racket-users] Correctly executing a source file from embedded Racket

2017-07-26 Thread Thomas Dickerson
Thanks for the help, a couple more quick questions:

On Wednesday, July 26, 2017 at 9:15:12 AM UTC-4, Matthew Flatt wrote: 
> You don't have to populate the top-level environment with
> `racket/base`. You could instead use
> 
>   scheme_namespace_require(scheme_intern_symbol("my-lang"))
> 
> where "my-lang" is your language's main module to populate the
> environment from there. Still, this isn't really the right direction.

I actually tried this without much success, but I might still have been missing 
something.

> Overall, I think you want to `scheme_dynamic_require` instead of
> `scheme_load`, just as Shu-Hung suggests. Using
> `scheme_dynamic_require` corresponds to what `racket` does where you
> provide it a file on the command line, and it avoids the top-level
> environment and `load`.

Just tried this, and it worked great, thanks! I was having a little trouble 
getting the `scheme_eval` variant that constructed a `dynamic-require` form 
manually to work correctly, so knowing about `scheme_dynamic_require` is 
helpful.

> I can see how the "Inside Racket" example lead you astray by showing a
> traditional REPL, where `eval` and `load` come into play, and I'll look
> at ways to improve the docs. But if your goal is to run modules, then
> you can avoid all that trouble.
Thanks!


One more thing: in terms of repeatedly executing scripts, does it make sense to 
set up and tear down the interpreter every time? Or just swap in a fresh 
namespace?

-- 
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] Correctly executing a source file from embedded Racket

2017-07-25 Thread Thomas Dickerson
On Tuesday, July 25, 2017 at 5:52:45 PM UTC-4, Shu-Hung You wrote:> 
> As we can see, 
> `scheme_namespace_require(scheme_intern_symbol("racket/base"));`
> is actually missing from your setup program. This line requires racket
> base and the usual #%app bindings. It's probably needed even if you're
> loading your own DSL -- I suspect at some point racket/base will
> install the right `load` function to make things work, and that this
> will also affect loading custom #langs.

You appear to be correct, but it strikes me as really odd that 
(a) In a language which prides itself on metaprogramming, the interpreter 
namespace needs to be manually bootstrapped with a specific module.
(b) That the form the error takes is not an error with the requires/provides in 
the `main.rkt` for my #lang, but as an error in a module which is using it.
This code:
|#lang racket
|(require "Value-Forms.rkt"
| "Operator-Forms.rkt"
| "Variable-Forms.rkt")
|
|(provide
| #%module-begin
| #%top-interaction
| #%datum
| #%app
| (all-from-out "Value-Forms.rkt"
|   "Operator-Forms.rkt"
|   "Variable-Forms.rkt"))
Should definitely complain if its imports aren't available.


> * Dependencies for main.rkt and lang/reader.rkt: I don't think there's
> a conflict. The dependencies seem to refer to `require`s, like
> racket/base -> racket/list, racket/...

Relatedly, even if `main.rkt` and `lang/reader.rkt` are independent, it's 
really odd that my module beginning with `#lang racket` is insufficient for 
raco to pick up the racket dependencies.

> * load: instead of using load, I would probably try to implement a
> function in Racket that use `dynamic-require` to load other DSL
> scripts. Then in the C part, we can `dynamic-require` that function to
> load argv[1]. Of course, remember to add that module in raco ctool. An
> example is given in load-file.rkt and call_racket_from_load.cpp in the
> link.
> 
> I am not familiar with this; there could be a better way to
> dynamically load a file.
> 

Thanks, I'll think some more about this.

> # Commands:
> $ raco ctool --c-mods base.c ++lib racket/base ++lib
> racket/base/lang/reader ++lib racket/runtime-config

This appears to be precisely the necessary set of minimum ++libs. It *really* 
ought to be documented somewhere, in big bold letters.


Thanks for the help!

~Thomas

-- 
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] Correctly executing a source file from embedded Racket

2017-07-25 Thread Thomas Dickerson
I've been working on building a DSL in Racket (as a #lang collection), and have 
reached the stage where it's functioning as expected and ready to be embedded 
in my application (which is written in C++).

I have modified the `run` function from the embedding example here 
(https://docs.racket-lang.org/inside/embedding.html) as follows:

|static int run(Scheme_Env *e, int argc, char *argv[]) {
|   Scheme_Object *curout;
|   int i;
|   Scheme_Thread *th;
|   
|   mz_jmp_buf * volatile save, fresh;
|   
|   /* Declare embedded modules in "base.hpp": */
|   declare_modules(e);
|   /*** Alternatively (see email commentary below):
|   scheme_set_collects_path(scheme_make_path(argv[1]));
|   scheme_init_collection_paths(e, scheme_null);
|*/
|   curout = scheme_get_param(scheme_current_config(),
| MZCONFIG_OUTPUT_PORT);
|   
|   th = scheme_get_current_thread();
|   for (i = 2; i < argc; i++) {
|   save = th->error_buf;
|   th->error_buf = 
|   
|   if (scheme_setjmp(*th->error_buf)) {
|   th->error_buf = save;
|   return -1; /* There was an error */
|   } else {
|   Scheme_Object *v, *a[2];
|   v = scheme_load(argv[i]);
|   scheme_display(v, curout);
|   scheme_display(scheme_make_char('\n'), curout);
|   th->error_buf = save;
|   }
|   }
|   
|   return 0;
|}


When I run my program, so that the file to be executed is in `argv[2]`, I get 
an error message that begins as follows:

|../libraries/dsl-exec/racket-src/gpsm-test.gpsm:1:0: #%top-interaction: 
unbound identifier;
| also, no #%app syntax transformer is bound
|  at: #%top-interaction

Note that when I run programs written in my DSL with a standalone interpreter, 
this error does not appear, and I *explicitly* export `#%top-interaction`, 
`#%app`, `#%module-begin`, and `#%datum`.

I noticed some oddities when using `raco ctool`. For example, the documentation 
claims that a module specified for embedding with ++lib will embed all of its 
dependencies, but my #lang's reader submodule needed to be explicitly specified 
with its own ++lib argument. To see if this was a contributing factor, I also 
tried using a manual `scheme_set_collects_path` and 
`scheme_init_collections_paths` combo (with `argv[1]` pointing to the location 
of my collects dir on disk), but got the same error as with the embedded 
versions of the modules.

As a follow-up, using the manually-specified collections path variant of the 
code above, I also tried to execute the following simple Racket program (to 
isolate if the use of my #lang specifically was a contributing factor):
|#lang racket
|
|(display (+ 5 6))
|(newline)

The same error as before was immediately raised:
|racket-test.rkt:1:0: #%top-interaction: unbound identifier;
| also, no #%app syntax transformer is bound
|  at: #%top-interaction


I assume I'm missing some crucial piece of the embedded Racket puzzle, but I 
have no idea what it is.

(I might also recommend that whatever this missing piece is be *clearly* 
documented in future editions of the documentation, since it seems like a 
fairly basic use-case).

Thanks,
~Thomas

-- 
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] (syntax-local-make-definition-context intdef-ctx) inexplicably sheds bindings

2015-11-20 Thread Thomas Dickerson
I have a code that looks like this:

(emit-local-step #'func.name 
 (internal-definition-context-apply/loc defs #'func.name) #:id 
#'defun)
(let ([defs (syntax-local-make-definition-context defs)]
  [ctx (build-expand-context ctx)]
  [args (parse-arg-names #'func.args)])
  (syntax-local-bind-syntaxes args #f defs)
  (internal-definition-context-seal defs)
  (with-syntax*
  ([f-name (internal-definition-context-apply/loc defs #'func.name)])
(emit-local-step #'func.name #'f-name #:id #'defun2)))


Contrary to 
http://docs.racket-lang.org/reference/stxtrans.html#%28def._%28%28quote._~23~25kernel%29._syntax-local-make-definition-context%29%29
 "the new internal-definition context can use bindings previously introduced 
into intdef-ctx."

The first emit-local-step shows a properly introduced binding, the second does 
not.

-- 
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] syntax-original? always returns #f within syntax transformers?

2015-11-12 Thread Thomas Dickerson
On Thursday, November 12, 2015 at 12:26:23 PM UTC-5, Matthew Flatt wrote: 
> The macro stepper shows a form after expansion, while Alexis's example
> was looking at it during expansion (i.e., in the dynamic extent of a
> syntax transformer). Those different times have different syntax
> objects --- although one is derived from the other --- and they have
> different properties. In particular, the syntax object during the
> transformer call has an extra scope that will be canceled when it is
> returned back from the transformer.
> 
> Inspecting syntax objects during a transformer call would be useful,
> but the current macro stepper doesn't do that.

In my case, I was using emit-local-step, and was under the impression that 
emit-local-step allowed the inspection of syntax objects as they might appear 
to the transformer, as unlike emit-remark it makes no note about marks.

-- 
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] syntax-original? always returns #f within syntax transformers?

2015-11-11 Thread Thomas Dickerson
On Tuesday, October 27, 2015 at 7:24:55 AM UTC-4, Matthew Flatt wrote:
> This role of marks has been taken over by macro-introduction scopes, so
> that's still the explanation. A macro-introduction scope is added to
> the right places by first adding it everywhere to the argument to a
> macro transformer, then flipping it everywhere in the transformer's
> result.
> 
> (The documentation of `syntax-original?` includes an attempt to specify
> that, but none of the documentation is clear enough yet about scopes.)

I'm looking at this documentation now ( 
http://docs.racket-lang.org/reference/stxops.html#%28def._%28%28quote._~23~25kernel%29._syntax-original~3f%29%29
 ) and see nothing of the sort. Can you specify where this is hypothetically 
being communicated?



That the macro stepper simultaneously allows you to click on the syntax in a 
remark or local step and see #t for original?, while simultaneously returning 
false for syntax-original? is incredibly user hostile.

-- 
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] Correct use of pattern-expander (example in docs is broken)

2015-11-11 Thread Thomas Dickerson
On Tuesday, November 10, 2015 at 10:38:35 PM UTC-5, Alex Knauth wrote:
> Ok, I just opened https://github.com/racket/racket/pull/1133, which fixes 
> this so that syntax-rules still works.

Awesome!

 
> > On Nov 10, 2015, at 6:19 PM, Alex Knauth  wrote:
> > This works though:
> > (define-syntax ~maybe
> >  (pattern-expander
> >   (lambda (stx)
> > (syntax-case stx ()
> >   [(~maybe pat ...)
> >#'(~optional (~seq pat ...))]

Oh yeah, I guess I should have tried that out of the gate.

-- 
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] Correct use of pattern-expander (example in docs is broken)

2015-11-10 Thread Thomas Dickerson
The docs 
(http://docs.racket-lang.org/syntax/stxparse-patterns.html#%28def._%28%28lib._syntax%2Fparse..rkt%29._pattern-expander%29%29)
 give an example, ~maybe, that doesn't actually work:

> (define-syntax ~maybe
(pattern-expander
 (syntax-rules ()
  [(~maybe pat ...)
   (~optional (~seq pat ...))])))
> (define-syntax-class blah
  (pattern (hi (~maybe two three) ...)))
. ~optional: cannot use identifier tainted by macro transformation in: ~optional

I noticed this because I wanted to do something analogous, which fails with the 
same error (identifier tainted by macro transformation):

(define-syntax ~bdatum
  (pattern-expander
   (syntax-rules ()
 [(~bdatum id)
(~and id (~datum id))]
   [(~bdatum bid id)
(~and bid (~datum id))])))


Any insight into either correct usage of pattern-expander, or a more efficient 
shorthand to achieve the same result I was aiming for with ~bdatum (being able 
to match with ~datum while still having a pattern variable that preserves 
source information).

Thanks!

-- 
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 Thomas Dickerson
On Tuesday, June 23, 2015 at 8:30:32 AM UTC-4, Matthew Flatt wrote:
 Providing #f as the third argument to `local-expand` means that
 
  (+ i j)
 
 is expanded only as far as exposing the primitive function-call form, also 
 known as `#%plain-app`:
 
  (#%plain-app + i j)
 
 When `i` is encountered later, there's no binding in the compile-time
 environment, because the internal-definition context has been
 discarded as the `my-def-stx` macro returned.
 
 Probably you want to replace the `#f` with `null` (which means expand
 without stopping).
Got it - this makes sense, thanks.

 Another possibility is to expand to a
 `letrec-syntaxes+values` form to bind `i` and `j`.

This is actually what I'm trying to avoid - see the earlier note on why I need 
a solution that won't leave behind empty (let-values () ...) forms (or any 
other Racket-specific forms) in the output syntax.
 
 At Tue, 23 Jun 2015 02:13:19 -0400, Thomas Dickerson wrote:
  I seem to be missing some key ingredient here. The following really simply
  test-case, using let-syntaxes, works as expected:
  
   (define-syntax my-def-stx
 (lambda (stx)
   (syntax-case stx (my-def-stx)
 [(my-def-stx (id ...) rhs expr)
  #'(let-syntaxes ([(id ...) rhs]) expr)])))
  
   (my-def-stx
(i j) (values (lambda (stx) #'3) (lambda (stx) #'4))
(+ i j))
  
  Trying the same thing, but with this:
  
   (require (for-syntax syntax/context))
   (define-syntax my-def-stx
 (lambda (stx)
   (syntax-case stx (my-def-stx)
 [(my-def-stx (id ...) rhs expr)
  (let* ([intdef (syntax-local-make-definition-context)]
[ctx (generate-expand-context)])
  (syntax-local-bind-syntaxes (syntax-list #'(id ...))
   (local-transformer-expand #'rhs 'expression null) intdef)
  (internal-definition-context-seal intdef)
  (local-expand #'expr ctx #f intdef))])))
  
   (my-def-stx
(i j) (values (lambda (stx) #'3) (lambda (stx) #'4))
(+ i j))
  
  instead, gives me i: undefined; cannot reference an identifier before its
  definition.
  
  Thomas Dickerson
  
  Brown University
  Department of Computer Science
  115 Waterman St, 4th Floor
  Providence, RI 02912
  
  802-458-0637
  
  On Mon, Jun 22, 2015 at 11:39 PM, Matthew Flatt mfl...@cs.utah.edu wrote:
  
   Probably you don't want to work with namespaces, which are intended more
   for run-time reflection.
  
   For an example of turning internal definitions into
   'letrec-syntaxes+values', try the implementation of 'racket/block'.
  
On Jun 23, 2015, at 10:06 AM, Thomas Dickerson 
   thomas_dicker...@brown.edu wrote:
   
Update / addendum: I was also able to fairly trivially extend Alex's
   code using let-syntax to have the more hygienic behavior for where Accum
   is/is-not visible, but let-syntax ends up leaving an additional layer of
   empty (let-values() ...) behind.
   
The documentation for let-syntax makes the following claim - The
   evaluation of each trans-expr is parameterized to set current-namespace to
   a namespace that shares bindings and variables with the namespace being
   used to expand the let-syntax form, except that its base phase is one
   greater. which seems very much related to what I'd like to accomplish 
   (and
   Shriram's suggestion that I mentioned in the original post); however, I 
   see
   no evidence of this actually taking place in the Racket source-code, it
   just appears to desugar, with very few bells and whistles, to
   letrec-syntaxes+values which evidently is implemented in the C code.
   Digging into syntax-parameterize shows that, unsurprisingly, this is also
   how syntax-parameterize gets desugared, with a few more bells and 
   whistles.
   
So I guess at this point the remainder of my question boils down to
   this: can someone offer any insight into the process of turning macros
   which are introduced by let-syntax or equivalent into macros which are
   introduced implicitly by an internal-definition-context argument to
   local-expand, or by explicit namespace manipulation as hinted at in the
   let-syntax documentation (but which I can't turn up anywhere).
   
On Monday, June 22, 2015 at 5:35:50 PM UTC-4, Thomas Dickerson wrote:
Thanks for the effort that went into figuring that out! A couple first
   thoughts on the implementation:
To first order, this is exactly what I want to be able to do (and it
   elegantly avoids local-expand by reasoning about expansion order); 
   however,
   as a general pattern, it's a bit unhygienic in that Accum is now in the
   global namespace, which precludes using it as a child macro for other
   constructs, and prevents specific instantiations of Loop from requesting a
   different name for Accum to cooperate in nested loops.
   
I also noticed that (syntax-parameterize) isn't totally transparent in
   the expanded syntax - it leaves a bunch of empty (let-values () ...)
   behind, which is fine for Racket

Re: [racket-users] Macro-introducing macros with inter-macro communication channel

2015-06-23 Thread Thomas Dickerson
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])
   (Accum x dx)
   (Loop AccumInner 2
 (printf x = ~v, y = ~v, z = ~v\n x y z)
 (Accum y dy)
 (AccumInner z dz)


One last question - the change to using local-expand meant that the loop
body was no longer happy accepting define-values forms and raised Not in a
definition context errors. I can use let to accomplish the same thing
without any problems, but if someone could explain what changes would need
to be made to the local-expand call for that to work, I'd be grateful (for
my own understanding).


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 11:17 AM, Thomas Dickerson 
thomas_dicker...@brown.edu wrote:

 On Tuesday, June 23, 2015 at 8:30:32 AM UTC-4, Matthew Flatt wrote:
  Providing #f as the third argument to `local-expand` means that
 
   (+ i j)
 
  is expanded only as far as exposing the primitive function-call form,
 also known as `#%plain-app`:
 
   (#%plain-app + i j)
 
  When `i` is encountered later, there's no binding in the compile-time
  environment, because the internal-definition context has been
  discarded as the `my-def-stx` macro returned.
 
  Probably you want to replace the `#f` with `null` (which means expand
  without stopping).
 Got it - this makes sense, thanks.

  Another possibility is to expand to a
  `letrec-syntaxes+values` form to bind `i` and `j`.

 This is actually what I'm trying to avoid - see the earlier note on why I
 need a solution that won't leave behind empty (let-values () ...) forms (or
 any other Racket-specific forms) in the output syntax.

  At Tue, 23 Jun 2015 02:13:19 -0400, Thomas Dickerson wrote:
   I seem to be missing some key ingredient here. The following really
 simply
   test-case, using let-syntaxes, works as expected:
  
(define-syntax my-def-stx
  (lambda (stx)
(syntax-case stx (my-def-stx)
  [(my-def-stx (id ...) rhs expr)
   #'(let-syntaxes ([(id ...) rhs]) expr)])))
   
(my-def-stx
 (i j) (values (lambda (stx) #'3) (lambda (stx) #'4))
 (+ i j))
   
   Trying the same thing, but with this:
  
(require (for-syntax syntax/context))
(define-syntax my-def-stx
  (lambda (stx)
(syntax-case stx (my-def-stx)
  [(my-def-stx (id ...) rhs expr)
   (let* ([intdef

Re: [racket-users] Macro-introducing macros with inter-macro communication channel

2015-06-23 Thread Thomas Dickerson
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])
   (Accum x dx)
   (Loop AccumInner 2


 (printf x = ~v, y = ~v, z = ~v\n x y z)

 (Accum y dy)
 (AccumInner z dz)


 One last question - the change to using local-expand meant that the loop
 body was no longer happy accepting define-values forms and raised Not in a
 definition context errors. I can use let to accomplish the same thing
 without any problems, but if someone could explain what changes would need
 to be made to the local-expand call for that to work, I'd be grateful (for
 my own understanding).


 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 11:17 AM, Thomas Dickerson 
 thomas_dicker...@brown.edu wrote:

 On Tuesday, June 23, 2015 at 8:30:32 AM UTC-4, Matthew Flatt wrote:
  Providing #f as the third argument to `local-expand` means that
 
   (+ i j)
 
  is expanded only as far as exposing the primitive function-call form,
 also known as `#%plain-app`:
 
   (#%plain-app + i j)
 
  When `i` is encountered later, there's no binding in the compile-time
  environment, because the internal-definition context has been
  discarded as the `my-def-stx` macro returned.
 
  Probably you want to replace the `#f` with `null` (which means expand
  without stopping).
 Got it - this makes sense, thanks.

  Another possibility is to expand to a
  `letrec-syntaxes+values` form to bind `i` and `j`.

 This is actually what I'm trying to avoid - see the earlier note on why
 I need a solution that won't leave behind empty (let-values () ...) forms
 (or any other Racket-specific forms) in the output syntax.

  At Tue, 23 Jun 2015 02:13:19 -0400, Thomas Dickerson wrote:
   I seem to be missing some

Re: [racket-users] Macro-introducing macros with inter-macro communication channel

2015-06-23 Thread Thomas Dickerson
I seem to be missing some key ingredient here. The following really simply
test-case, using let-syntaxes, works as expected:

 (define-syntax my-def-stx
   (lambda (stx)
 (syntax-case stx (my-def-stx)
   [(my-def-stx (id ...) rhs expr)
#'(let-syntaxes ([(id ...) rhs]) expr)])))

 (my-def-stx
  (i j) (values (lambda (stx) #'3) (lambda (stx) #'4))
  (+ i j))

Trying the same thing, but with this:

 (require (for-syntax syntax/context))
 (define-syntax my-def-stx
   (lambda (stx)
 (syntax-case stx (my-def-stx)
   [(my-def-stx (id ...) rhs expr)
(let* ([intdef (syntax-local-make-definition-context)]
  [ctx (generate-expand-context)])
(syntax-local-bind-syntaxes (syntax-list #'(id ...))
 (local-transformer-expand #'rhs 'expression null) intdef)
(internal-definition-context-seal intdef)
(local-expand #'expr ctx #f intdef))])))

 (my-def-stx
  (i j) (values (lambda (stx) #'3) (lambda (stx) #'4))
  (+ i j))

instead, gives me i: undefined; cannot reference an identifier before its
definition.

Thomas Dickerson

Brown University
Department of Computer Science
115 Waterman St, 4th Floor
Providence, RI 02912

802-458-0637

On Mon, Jun 22, 2015 at 11:39 PM, Matthew Flatt mfl...@cs.utah.edu wrote:

 Probably you don't want to work with namespaces, which are intended more
 for run-time reflection.

 For an example of turning internal definitions into
 'letrec-syntaxes+values', try the implementation of 'racket/block'.

  On Jun 23, 2015, at 10:06 AM, Thomas Dickerson 
 thomas_dicker...@brown.edu wrote:
 
  Update / addendum: I was also able to fairly trivially extend Alex's
 code using let-syntax to have the more hygienic behavior for where Accum
 is/is-not visible, but let-syntax ends up leaving an additional layer of
 empty (let-values() ...) behind.
 
  The documentation for let-syntax makes the following claim - The
 evaluation of each trans-expr is parameterized to set current-namespace to
 a namespace that shares bindings and variables with the namespace being
 used to expand the let-syntax form, except that its base phase is one
 greater. which seems very much related to what I'd like to accomplish (and
 Shriram's suggestion that I mentioned in the original post); however, I see
 no evidence of this actually taking place in the Racket source-code, it
 just appears to desugar, with very few bells and whistles, to
 letrec-syntaxes+values which evidently is implemented in the C code.
 Digging into syntax-parameterize shows that, unsurprisingly, this is also
 how syntax-parameterize gets desugared, with a few more bells and whistles.
 
  So I guess at this point the remainder of my question boils down to
 this: can someone offer any insight into the process of turning macros
 which are introduced by let-syntax or equivalent into macros which are
 introduced implicitly by an internal-definition-context argument to
 local-expand, or by explicit namespace manipulation as hinted at in the
 let-syntax documentation (but which I can't turn up anywhere).
 
  On Monday, June 22, 2015 at 5:35:50 PM UTC-4, Thomas Dickerson wrote:
  Thanks for the effort that went into figuring that out! A couple first
 thoughts on the implementation:
  To first order, this is exactly what I want to be able to do (and it
 elegantly avoids local-expand by reasoning about expansion order); however,
 as a general pattern, it's a bit unhygienic in that Accum is now in the
 global namespace, which precludes using it as a child macro for other
 constructs, and prevents specific instantiations of Loop from requesting a
 different name for Accum to cooperate in nested loops.
 
  I also noticed that (syntax-parameterize) isn't totally transparent in
 the expanded syntax - it leaves a bunch of empty (let-values () ...)
 behind, which is fine for Racket, but problematic in my target use-case of
 emitting something which ultimately needs to be an entirely different
 language. This is why my experiments have all involved local-expand - I
 want to introduce expand-time names without introducing wrapping
 let-syntaxes (or similar) forms around my body code.
 
 
  On Saturday, June 20, 2015 at 2:24:40 PM UTC-4, Alex Knauth wrote:
  On Jun 19, 2015, at 7:44 PM, Thomas Dickerson 
 thomas_dicker...@brown.edu wrote:
 
  I was intending for that example to have the variables be defined
 outside the macro, but being able to create the (set! ...) forms outside
 should mean I could also hypothetically create let/define-values forms.
 This is why I originally specified being able to effect generation of both
 prologue + epilogue code.
 
  I figured this out for code that will be expanded after the body:
 
  #lang racket/base
 
  (require racket/stxparam
  (for-syntax racket/base
  syntax/parse
  racket/set
  ))
 
  ;; (syntax-parameter-value vars) : (U #f (MutableSetof Identifier))
  (define-syntax-parameter vars #f

Re: [racket-users] Macro-introducing macros with inter-macro communication channel

2015-06-22 Thread Thomas Dickerson
Thanks for the effort that went into figuring that out! A couple first thoughts 
on the implementation:
To first order, this is exactly what I want to be able to do (and it elegantly 
avoids local-expand by reasoning about expansion order); however, as a general 
pattern, it's a bit unhygienic in that Accum is now in the global namespace, 
which precludes using it as a child macro for other constructs, and prevents 
specific instantiations of Loop from requesting a different name for Accum to 
cooperate in nested loops.

I also noticed that (syntax-parameterize) isn't totally transparent in the 
expanded syntax - it leaves a bunch of empty (let-values () ...) behind, which 
is fine for Racket, but problematic in my target use-case of emitting something 
which ultimately needs to be an entirely different language. This is why my 
experiments have all involved local-expand - I want to introduce expand-time 
names without introducing wrapping let-syntaxes (or similar) forms around my 
body code.


On Saturday, June 20, 2015 at 2:24:40 PM UTC-4, Alex Knauth wrote:
 On Jun 19, 2015, at 7:44 PM, Thomas Dickerson thomas_dicker...@brown.edu 
 wrote:
 
  I was intending for that example to have the variables be defined outside 
  the macro, but being able to create the (set! ...) forms outside should 
  mean I could also hypothetically create let/define-values forms. This is 
  why I originally specified being able to effect generation of both prologue 
  + epilogue code.
 
 I figured this out for code that will be expanded after the body:
 
 #lang racket/base
 
 (require racket/stxparam
  (for-syntax racket/base
  syntax/parse
  racket/set
  ))
 
 ;; (syntax-parameter-value vars) : (U #f (MutableSetof Identifier))
 (define-syntax-parameter vars #f)
 
 (define-syntax Accum
   (lambda (stx)
 (syntax-parse stx
   [(Accum x:id dx:expr)
(define vs (syntax-parameter-value #'vars))
(unless (set-mutable? vs)
  (raise-syntax-error #f cannot be used outside Loop stx))
(set-add! vs (syntax-local-introduce #'x))
#'(set! x (+ x dx))])))
 
 (define-syntax set-accums-zero!
   (syntax-parser
 [(set-accums-zero!)
  #:with [x ...]
  (map syntax-local-introduce (set-list (syntax-parameter-value #'vars)))
  #'(begin (set! x 0) ...)]))
 
 (define-syntax Loop
   (syntax-parser
 [(Loop up-to-expr:expr body:expr ...+)
  #'(syntax-parameterize ([vars (mutable-set)])
  (let ([up-to up-to-expr])
(letrec
([loop
  (lambda (n)
body
...
(if ( n up-to)
(loop (add1 n))
(void)))])
  (set-accums-zero!)
  (loop 0]))
 
 (let ([x x] [y y] [z z])
   (Loop 10
 (begin
   (define-values 
 [dx dy dz] 
 (values 1 2 3))
   (printf x = ~v, y = ~v, z = ~v\n x y z)
   (Accum x dx)
   (Accum y dy)
   (Accum z dz
 
 To generate a let outside of that you’d probably need to do some kind of 
 local-expand, but I’m not sure.

-- 
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-22 Thread Thomas Dickerson
Update / addendum: I was also able to fairly trivially extend Alex's code using 
let-syntax to have the more hygienic behavior for where Accum is/is-not 
visible, but let-syntax ends up leaving an additional layer of empty 
(let-values() ...) behind.

The documentation for let-syntax makes the following claim - The evaluation of 
each trans-expr is parameterized to set current-namespace to a namespace that 
shares bindings and variables with the namespace being used to expand the 
let-syntax form, except that its base phase is one greater. which seems very 
much related to what I'd like to accomplish (and Shriram's suggestion that I 
mentioned in the original post); however, I see no evidence of this actually 
taking place in the Racket source-code, it just appears to desugar, with very 
few bells and whistles, to letrec-syntaxes+values which evidently is 
implemented in the C code. Digging into syntax-parameterize shows that, 
unsurprisingly, this is also how syntax-parameterize gets desugared, with a few 
more bells and whistles.

So I guess at this point the remainder of my question boils down to this: can 
someone offer any insight into the process of turning macros which are 
introduced by let-syntax or equivalent into macros which are introduced 
implicitly by an internal-definition-context argument to local-expand, or by 
explicit namespace manipulation as hinted at in the let-syntax documentation 
(but which I can't turn up anywhere).

On Monday, June 22, 2015 at 5:35:50 PM UTC-4, Thomas Dickerson wrote:
 Thanks for the effort that went into figuring that out! A couple first 
 thoughts on the implementation:
 To first order, this is exactly what I want to be able to do (and it 
 elegantly avoids local-expand by reasoning about expansion order); however, 
 as a general pattern, it's a bit unhygienic in that Accum is now in the 
 global namespace, which precludes using it as a child macro for other 
 constructs, and prevents specific instantiations of Loop from requesting a 
 different name for Accum to cooperate in nested loops.
 
 I also noticed that (syntax-parameterize) isn't totally transparent in the 
 expanded syntax - it leaves a bunch of empty (let-values () ...) behind, 
 which is fine for Racket, but problematic in my target use-case of emitting 
 something which ultimately needs to be an entirely different language. This 
 is why my experiments have all involved local-expand - I want to introduce 
 expand-time names without introducing wrapping let-syntaxes (or similar) 
 forms around my body code.
 
 
 On Saturday, June 20, 2015 at 2:24:40 PM UTC-4, Alex Knauth wrote:
  On Jun 19, 2015, at 7:44 PM, Thomas Dickerson thomas_dicker...@brown.edu 
  wrote:
  
   I was intending for that example to have the variables be defined outside 
   the macro, but being able to create the (set! ...) forms outside should 
   mean I could also hypothetically create let/define-values forms. This is 
   why I originally specified being able to effect generation of both 
   prologue + epilogue code.
  
  I figured this out for code that will be expanded after the body:
  
  #lang racket/base
  
  (require racket/stxparam
   (for-syntax racket/base
   syntax/parse
   racket/set
   ))
  
  ;; (syntax-parameter-value vars) : (U #f (MutableSetof Identifier))
  (define-syntax-parameter vars #f)
  
  (define-syntax Accum
(lambda (stx)
  (syntax-parse stx
[(Accum x:id dx:expr)
 (define vs (syntax-parameter-value #'vars))
 (unless (set-mutable? vs)
   (raise-syntax-error #f cannot be used outside Loop stx))
 (set-add! vs (syntax-local-introduce #'x))
 #'(set! x (+ x dx))])))
  
  (define-syntax set-accums-zero!
(syntax-parser
  [(set-accums-zero!)
   #:with [x ...]
   (map syntax-local-introduce (set-list (syntax-parameter-value 
  #'vars)))
   #'(begin (set! x 0) ...)]))
  
  (define-syntax Loop
(syntax-parser
  [(Loop up-to-expr:expr body:expr ...+)
   #'(syntax-parameterize ([vars (mutable-set)])
   (let ([up-to up-to-expr])
 (letrec
 ([loop
   (lambda (n)
 body
 ...
 (if ( n up-to)
 (loop (add1 n))
 (void)))])
   (set-accums-zero!)
   (loop 0]))
  
  (let ([x x] [y y] [z z])
(Loop 10
  (begin
(define-values 
  [dx dy dz] 
  (values 1 2 3))
(printf x = ~v, y = ~v, z = ~v\n x y z)
(Accum x dx)
(Accum y dy)
(Accum z dz
  
  To generate a let outside of that you’d probably need to do some kind of 
  local-expand, but I’m not sure.

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

Re: [racket-users] Macro-introducing macros with inter-macro communication channel

2015-06-19 Thread Thomas Dickerson
I was intending for that example to have the variables be defined outside the 
macro, but being able to create the (set! ...) forms outside should mean I 
could also hypothetically create let/define-values forms. This is why I 
originally specified being able to effect generation of both prologue + 
epilogue code.

On Friday, June 19, 2015 at 6:47:15 PM UTC-4, Alex Knauth wrote:
 Are the x, y, and z variables meant to be defined outside the macro by the 
 user as in:
 (let ([x “something”] [y “something else”] [z “and something else”])
   (Loop ….))
 ?
 
 
 Or should the Loop macro create a (let ([x 0] [y 0] [z 0]) ….) for you 
 instead?
 
 
 On Jun 19, 2015, at 5:58 PM, Thomas Dickerson thomas_d...@brown.edu wrote:
 
 
 Sure, here's a toy example.
 
 This code:
 
 
 (Loop 10
   (begin
     (define-values 
   [dx dy dz] 
   (values 0 0 0))
     ; Some calculation here
     (Accum x dx)
     (Accum y dy)
     (Accum z dz)))
 
 Should desugar into this code:
 (letrec 
     ([loop 
   (lambda (n) 
     (begin
   (define-values 
     [dx dy dz] 
     (values 0 0 0))
   ; Some calculation here
   (set! x (+ x dx))
   (set! y (+ y dy))
   (set! z (+ z dz)))
     (if ( n 10)
     (loop (+ 1 n))
     (void)))])
   (set! x 0)
   (set! y 0)
   (set! z 0)
   (loop 0))
 
 
 And in general, every unique id occuring in an (Accum id delta) in the loop 
 body should result in (set! id 0) in the prologue.
 
 
 Also, some context to avoid unproductive side-conversation: I'm using 
 Racket's macro facility to do pre-compilation of a totally different 
 language. The fully-expanded program in this case is going to be a call to a 
 function that rewrites Racket syntax objects into strings in the syntax of 
 something which isn't Racket. This means that I really want my original 
 question answered, rather than suggestions to solve a different problem that 
 happens to accomplish the same thing for this toy example. The critical 
 pieces here are that Accum only be defined within the body of a Loop, and 
 that it be able to communicate outwards to effect the code generation of the 
 specific instantiation of Loop in which it appears.
 
 
 
 
 
 
 
 
 
 
 Thomas Dickerson
 
 Brown University
 Department of Computer Science
 
 115 Waterman St, 4th Floor
 
 Providence, RI 02912
 
 802-458-0637
 
 
 
 On Fri, Jun 19, 2015 at 3:22 PM, Ryan Culpepper ry...@ccs.neu.edu wrote:
 On 06/19/2015 03:07 PM, Thomas Dickerson wrote:
 
 
 Hi All,
 
 
 
 I'm trying to figure out how best to implement the following pattern of macro 
 behavior:
 
 
 
 Let's say we are writing Loop macro that implements a looped computation over 
 a specified body. I would like to then be able to
 
 (a) introduce additional Loop-specific macros that are defined only within 
 the scope of the body
 
 (b) are able to coordinate with the outer macro so as to alter its generation 
 of prologue and epilogue code.
 
 
 
 My best guess here is some use of local-expand with 
 syntax-local-bind-syntaxes, or perhaps syntax-parameterize, but I can't quite 
 work out the appropriate constructions.
 
 
 
 I've been able to implement something similar using syntax-case functions on 
 syntax objects at phase-0, by essentially implementing my own namespace for 
 macros and passing it as an explicit argument, but this loses the hygiene 
 benefits of coordinating with expand.  I had an offline discussion with 
 Shriram yesterday in which he suggested looking into ways to reify the 
 expansion-time namespace, but obviously current-namespace does the wrong 
 thing here.
 
 
 
 
 Can you provide a small example program and describe how you want it to 
 behave?
 
 
 
 Ryan
 
 
 
 
 
 
 
 
 -- 
 
 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...@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-introducing macros with inter-macro communication channel

2015-06-19 Thread Thomas Dickerson
Sure, here's a toy example.

This code:

 (Loop 10
   (begin
 (define-values
   [dx dy dz]
   (values 0 0 0))
 ; Some calculation here
 (Accum x dx)
 (Accum y dy)
 (Accum z dz)))


Should desugar into this code:

 (letrec
 ([loop
   (lambda (n)
 (begin
   (define-values
 [dx dy dz]
 (values 0 0 0))
   ; Some calculation here
   (set! x (+ x dx))
   (set! y (+ y dy))
   (set! z (+ z dz)))
 (if ( n 10)
 (loop (+ 1 n))
 (void)))])
   (set! x 0)
   (set! y 0)
   (set! z 0)
   (loop 0))


And in general, every unique id occuring in an (Accum id delta) in the loop
body should result in (set! id 0) in the prologue.

Also, some context to avoid unproductive side-conversation: I'm using
Racket's macro facility to do pre-compilation of a totally different
language. The fully-expanded program in this case is going to be a call to
a function that rewrites Racket syntax objects into strings in the syntax
of something which isn't Racket. This means that I really want my original
question answered, rather than suggestions to solve a different problem
that happens to accomplish the same thing for this toy example. The
critical pieces here are that Accum only be defined within the body of a
Loop, and that it be able to communicate outwards to effect the code
generation of the specific instantiation of Loop in which it appears.


Thomas Dickerson

Brown University
Department of Computer Science
115 Waterman St, 4th Floor
Providence, RI 02912

802-458-0637

On Fri, Jun 19, 2015 at 3:22 PM, Ryan Culpepper ry...@ccs.neu.edu wrote:

 On 06/19/2015 03:07 PM, Thomas Dickerson wrote:

 Hi All,

 I'm trying to figure out how best to implement the following pattern of
 macro behavior:

 Let's say we are writing Loop macro that implements a looped computation
 over a specified body. I would like to then be able to
 (a) introduce additional Loop-specific macros that are defined only
 within the scope of the body
 (b) are able to coordinate with the outer macro so as to alter its
 generation of prologue and epilogue code.

 My best guess here is some use of local-expand with
 syntax-local-bind-syntaxes, or perhaps syntax-parameterize, but I can't
 quite work out the appropriate constructions.

 I've been able to implement something similar using syntax-case functions
 on syntax objects at phase-0, by essentially implementing my own namespace
 for macros and passing it as an explicit argument, but this loses the
 hygiene benefits of coordinating with expand.  I had an offline discussion
 with Shriram yesterday in which he suggested looking into ways to reify the
 expansion-time namespace, but obviously current-namespace does the wrong
 thing here.


 Can you provide a small example program and describe how you want it to
 behave?

 Ryan



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

2015-06-19 Thread Thomas Dickerson
Hi All,

I'm trying to figure out how best to implement the following pattern of macro 
behavior:

Let's say we are writing Loop macro that implements a looped computation over a 
specified body. I would like to then be able to
(a) introduce additional Loop-specific macros that are defined only within the 
scope of the body
(b) are able to coordinate with the outer macro so as to alter its generation 
of prologue and epilogue code.

My best guess here is some use of local-expand with syntax-local-bind-syntaxes, 
or perhaps syntax-parameterize, but I can't quite work out the appropriate 
constructions.

I've been able to implement something similar using syntax-case functions on 
syntax objects at phase-0, by essentially implementing my own namespace for 
macros and passing it as an explicit argument, but this loses the hygiene 
benefits of coordinating with expand.  I had an offline discussion with Shriram 
yesterday in which he suggested looking into ways to reify the expansion-time 
namespace, but obviously current-namespace does the wrong thing here.


Thanks in advance for any help =)

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