Re: [racket-users] Injecting local contracts for prefab constructors

2021-05-09 Thread Sage Gerard
Almost forgot, just in case someone asks: I want to avoid checking for 
invariant violations when I print. That would entail checking a bunch of values 
in accumulated program output, where it would be awkward to do something 
non-printing related, let alone raise an error. When I am printing logs, all 
invariant violations come down to what went a constructor, because all program 
output is encoded as prefab structures. That's why I want to raise any errors 
on instantiation.

On 5/9/21 8:55 PM, Sage Gerard wrote:

> Of course, if you're okay with a longer email. Before that, thank you both 
> for volunteering your time to code something out. I enjoyed running into a 
> `define-module-boundary-contract` in the wild for the first time.
>
> I sometimes print output in a (read)able form because I like analyzing my 
> logs. The data I print includes prefab structures, with type ids matching the 
> topic they cover or the statements they make. You can see that I declare 
> prefab structure (sub)types cutely labeled "messages" here. [1]
>
> The idea is that I can either print (for example) a $package:output:built 
> instance as a localized string, or just toss the instance itself into 
> writeln. When I read instances back from a port, the struct accessors will 
> help me filter and match. Hopefully all this shows where my head is.
>
> Now for the problem. Look at [2], but don't worry about what it means. I just 
> wanted you to see the constructor call in the exception handler. If I made a 
> mistake and wrote that line such the exception was placed directly in the 
> instance, then I wouldn't be able to (read) that instance back later! I 
> cannot allow #<...> forms in my output, or some symbol soup that happens to 
> be readable, but doesn't constitute the value it used to be.
>
> TL;DR I want to protect the invariant `(equal? V (read (open-input-string (~s 
> V` for each V I print to an output port.
>
> Finally, as to why I didn't want the module boundary contract. The module 
> that declares prefab structure types is also primarily responsible for 
> creating all instances of those types. I rarely cross module boundaries when 
> applying the constructors.
>
> [1]: https://github.com/zyrolasting/xiden/blob/master/package.rkt#L49
> [2]: https://github.com/zyrolasting/xiden/blob/master/security.rkt#L100
>
> On 5/9/21 8:02 PM, Philip McGrath wrote:
>
>> Here's another minimally-tested sample implementation. A more robust 
>> solution might try to chaperone the struct type, as well, to protect 
>> reflective access to the constructor—but I wonder if that really makes sense 
>> when you are working with prefab structs. If you can explain more about your 
>> requirements, it might be possible to suggest better approaches.
>>
>> On Sun, May 9, 2021 at 7:57 PM Ryan Culpepper  wrote:
>>
>>> I'm not clear on what constraints you're working under with respect to 
>>> modules, but hopefully you can adapt this to your needs.
>>>
>>> One option is to use a combination of `define-module-boundary-contract` (or 
>>> `define/contract`) and `define-match-expander` to bind a name that can be 
>>> used as a contracted constructor and as a match pattern. (If you want to 
>>> extend the struct type, though, you still need to use the real one.)
>>>
>>> Another option would be to "forge" a new compile-time struct-info based on 
>>> the original struct-info but replacing the constructor.
>>>
>>> Minimally tested sample implementations attached.
>>>
>>> Ryan
>>>
>>> On Mon, May 10, 2021 at 12:23 AM Sage Gerard  wrote:
>>>
 I have a project with 57 prefab structure types. I need to construct 
 instances using a local contract (module level contracts do not fit my 
 needs here). Since I cannot define guards, the solution is easy enough.

 (struct foo (num) #:prefab)
 (define/contract make-foo (-> real? foo?) foo)

 Problem: I already have a few hundred constructor calls without contracts. 
 I could either A) rewrite them all to use contracted constructors, or B) 
 attach local contracts in a sweet spot so that I don't have to rewrite 
 anything else.

 I prefer option B, but it doesn't look like I can attach a local contract 
 to a constructor with `struct` alone, or even with an impersonator. When I 
 hack around to rebind or hide the constructor's identifier, I break 
 compatibility with `match` and `defstruct*`.

 If you were in my position, what would you do?

 --

 ~slg

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

Re: [racket-users] Injecting local contracts for prefab constructors

2021-05-09 Thread Sage Gerard
Of course, if you're okay with a longer email. Before that, thank you both for 
volunteering your time to code something out. I enjoyed running into a 
`define-module-boundary-contract` in the wild for the first time.

I sometimes print output in a (read)able form because I like analyzing my logs. 
The data I print includes prefab structures, with type ids matching the topic 
they cover or the statements they make. You can see that I declare prefab 
structure (sub)types cutely labeled "messages" here. [1]

The idea is that I can either print (for example) a $package:output:built 
instance as a localized string, or just toss the instance itself into writeln. 
When I read instances back from a port, the struct accessors will help me 
filter and match. Hopefully all this shows where my head is.

Now for the problem. Look at [2], but don't worry about what it means. I just 
wanted you to see the constructor call in the exception handler. If I made a 
mistake and wrote that line such the exception was placed directly in the 
instance, then I wouldn't be able to (read) that instance back later! I cannot 
allow #<...> forms in my output, or some symbol soup that happens to be 
readable, but doesn't constitute the value it used to be.

TL;DR I want to protect the invariant `(equal? V (read (open-input-string (~s 
V` for each V I print to an output port.

Finally, as to why I didn't want the module boundary contract. The module that 
declares prefab structure types is also primarily responsible for creating all 
instances of those types. I rarely cross module boundaries when applying the 
constructors.

[1]: https://github.com/zyrolasting/xiden/blob/master/package.rkt#L49
[2]: https://github.com/zyrolasting/xiden/blob/master/security.rkt#L100

On 5/9/21 8:02 PM, Philip McGrath wrote:

> Here's another minimally-tested sample implementation. A more robust solution 
> might try to chaperone the struct type, as well, to protect reflective access 
> to the constructor—but I wonder if that really makes sense when you are 
> working with prefab structs. If you can explain more about your requirements, 
> it might be possible to suggest better approaches.
>
> On Sun, May 9, 2021 at 7:57 PM Ryan Culpepper  wrote:
>
>> I'm not clear on what constraints you're working under with respect to 
>> modules, but hopefully you can adapt this to your needs.
>>
>> One option is to use a combination of `define-module-boundary-contract` (or 
>> `define/contract`) and `define-match-expander` to bind a name that can be 
>> used as a contracted constructor and as a match pattern. (If you want to 
>> extend the struct type, though, you still need to use the real one.)
>>
>> Another option would be to "forge" a new compile-time struct-info based on 
>> the original struct-info but replacing the constructor.
>>
>> Minimally tested sample implementations attached.
>>
>> Ryan
>>
>> On Mon, May 10, 2021 at 12:23 AM Sage Gerard  wrote:
>>
>>> I have a project with 57 prefab structure types. I need to construct 
>>> instances using a local contract (module level contracts do not fit my 
>>> needs here). Since I cannot define guards, the solution is easy enough.
>>>
>>> (struct foo (num) #:prefab)
>>> (define/contract make-foo (-> real? foo?) foo)
>>>
>>> Problem: I already have a few hundred constructor calls without contracts. 
>>> I could either A) rewrite them all to use contracted constructors, or B) 
>>> attach local contracts in a sweet spot so that I don't have to rewrite 
>>> anything else.
>>>
>>> I prefer option B, but it doesn't look like I can attach a local contract 
>>> to a constructor with `struct` alone, or even with an impersonator. When I 
>>> hack around to rebind or hide the constructor's identifier, I break 
>>> compatibility with `match` and `defstruct*`.
>>>
>>> If you were in my position, what would you do?
>>>
>>> --
>>>
>>> ~slg
>>>
>>> --
>>> 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/0a16cfbe-4789-a939-796e-5f6f9da21626%40sagegerard.com](https://groups.google.com/d/msgid/racket-users/0a16cfbe-4789-a939-796e-5f6f9da21626%40sagegerard.com?utm_medium=email_source=footer).
>>
>> --
>> 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/CANy33qmngGoVoAok6%2BR885jkh8MroMqYHpOd6XtjCSH7iiESQA%40mail.gmail.com](https://groups.google.com/d/msgid/racket-users/CANy33qmngGoVoAok6%2BR885jkh8MroMqYHpOd6XtjCSH7iiESQA%40mail.gmail.com?utm_medium=email_source=footer).

--

Re: [racket-users] Racket v8.1

2021-05-09 Thread 'John Clements' via Racket Users
Ah! My apologies. I’ve added your name to our “preferred names” file, and I 
hope not to make this mistake again.

Thank you!

John

> On May 8, 2021, at 13:38, Dexter Lagan  wrote:
> 
> Hello sir,
> 
>  Thank you ! My name is actually Dexter Santucci. Apologies for the 
> confusion. My email address isn't telling.
> 
> Cheers!
> 
> Dexter
> 
> On Wednesday, May 5, 2021 at 6:39:22 PM UTC+2 johnbclements wrote:
> -- 
> Racket version 8.1 is now available from 
> 
> https://racket-lang.org/ 
> 
> 
> - DrRacket tabs can be dragged, and have new close buttons. 
> 
> - Racket CS supports cross-compilation using `raco exe`. 
> 
> - Racket CS supports Android on 32-bit and 64-bit ARM processors. 
> 
> - The database library supports running queries in OS threads. 
> 
> - Check-Syntax arrows correctly identify the definition site of 
> identifiers with contracts. 
> 
> - Racket CS performance has improved for structure predicates and 
> accessors 
> 
> - Racket CS is faster at multiplying extremely large numbers and 
> dividing large integers. 
> 
> - Racket CS allows callbacks to raise exceptions if they are annotated 
> with `#:callback-exns?`. 
> 
> - New ephemeron hash tables simplify the implementation of tables where 
> keys can refer to values. 
> 
> - Typed Racket supports for/foldr. 
> 
> - The stepper works for #lang htdp/*sl. 
> 
> - Struct signatures work for the ASL teaching language. 
> 
> The following people contributed to this release: 
> 
> Alex Harsányi, Alex Knauth, Alexander Shopov, Alexis King, Andrew 
> Mauer-Oats, Anish Athalye, Ben Greenman, Bert De Ketelaere, Bob Burger, 
> Bogdan Popa, Brian Adkins, Cameron Moy, David Van Horn, Dexter Lagan, 
> Dominik Pantůček, Fred Fu, Greg Hendershott, Gustavo Massaccesi, Hazel 
> Levine, Ismael Luceno, Jack Firth, Jarhmander, John Clements, Jörgen 
> Brandt, Laurent Orseau, Lazerbeak12345, Matthew Flatt, Matthias 
> Felleisen, Micah Cantor, Mike Sperber, Noah Ma, Patrick McCarty, Paulo 
> Matos, Pavel Panchekha, Philip McGrath, Philippe Meunier, R. Kent 
> Dybvig, Robby Findler, Ryan Culpepper, Ryan Kramer, Sam Tobin-Hochstadt, 
> Sergiu Ivanov, Shu-Hung You, Sorawee Porncharoenwase, Stephen De 
> Gabrielle, William J. Bowman, bmitc, xxyzz, yjqww6, and ymdarake 
> 
> Feedback Welcome 
> -- 
> 
> 
> -- 
> 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/e8e8ecff-79ad-4c33-ab37-6d98ca18baa7n%40googlegroups.com.

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/3aa00891-bcde-4cbd-879f-1da1781210e1%40mtasv.net.


Re: [racket-users] Injecting local contracts for prefab constructors

2021-05-09 Thread Philip McGrath
Here's another minimally-tested sample implementation. A more robust
solution might try to chaperone the struct type, as well, to protect
reflective access to the constructor—but I wonder if that really makes
sense when you are working with prefab structs. If you can explain more
about your requirements, it might be possible to suggest better approaches.


On Sun, May 9, 2021 at 7:57 PM Ryan Culpepper 
wrote:

> I'm not clear on what constraints you're working under with respect to
> modules, but hopefully you can adapt this to your needs.
>
> One option is to use a combination of `define-module-boundary-contract`
> (or `define/contract`) and `define-match-expander` to bind a name that can
> be used as a contracted constructor and as a match pattern. (If you want to
> extend the struct type, though, you still need to use the real one.)
>
> Another option would be to "forge" a new compile-time struct-info based on
> the original struct-info but replacing the constructor.
>
> Minimally tested sample implementations attached.
>
> Ryan
>
>
> On Mon, May 10, 2021 at 12:23 AM Sage Gerard  wrote:
>
>> I have a project with 57 prefab structure types. I need to construct
>> instances using a *local* contract (module level contracts do not fit my
>> needs here). Since I cannot define guards, the solution is easy enough.
>> (struct foo (num) #:prefab)
>> (define/contract make-foo (-> real? foo?) foo)
>>
>> Problem: I already have a few hundred constructor calls without
>> contracts. I could either A) rewrite them all to use contracted
>> constructors, or B) attach local contracts in a sweet spot so that I don't
>> have to rewrite anything else.
>>
>> I prefer option B, but it doesn't look like I can attach a local contract
>> to a constructor with `struct` alone, or even with an impersonator. When I
>> hack around to rebind or hide the constructor's identifier, I break
>> compatibility with `match` and `defstruct*`.
>>
>> If you were in my position, what would you do?
>> --
>>
>> ~slg
>>
>> --
>> 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/0a16cfbe-4789-a939-796e-5f6f9da21626%40sagegerard.com
>> 
>> .
>>
> --
> You received this message because you are subscribed to the Google Groups
> "Racket Users" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to racket-users+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/racket-users/CANy33qmngGoVoAok6%2BR885jkh8MroMqYHpOd6XtjCSH7iiESQA%40mail.gmail.com
> 
> .
>

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/01000179539521f3-7e3fc7cf-409e-4574-8917-5d2ef798fa1c-00%40email.amazonses.com.


prefab-transformer.rkt
Description: Binary data


Re: [racket-users] Injecting local contracts for prefab constructors

2021-05-09 Thread Ryan Culpepper
I'm not clear on what constraints you're working under with respect to
modules, but hopefully you can adapt this to your needs.

One option is to use a combination of `define-module-boundary-contract` (or
`define/contract`) and `define-match-expander` to bind a name that can be
used as a contracted constructor and as a match pattern. (If you want to
extend the struct type, though, you still need to use the real one.)

Another option would be to "forge" a new compile-time struct-info based on
the original struct-info but replacing the constructor.

Minimally tested sample implementations attached.

Ryan


On Mon, May 10, 2021 at 12:23 AM Sage Gerard  wrote:

> I have a project with 57 prefab structure types. I need to construct
> instances using a *local* contract (module level contracts do not fit my
> needs here). Since I cannot define guards, the solution is easy enough.
> (struct foo (num) #:prefab)
> (define/contract make-foo (-> real? foo?) foo)
>
> Problem: I already have a few hundred constructor calls without contracts.
> I could either A) rewrite them all to use contracted constructors, or B)
> attach local contracts in a sweet spot so that I don't have to rewrite
> anything else.
>
> I prefer option B, but it doesn't look like I can attach a local contract
> to a constructor with `struct` alone, or even with an impersonator. When I
> hack around to rebind or hide the constructor's identifier, I break
> compatibility with `match` and `defstruct*`.
>
> If you were in my position, what would you do?
> --
>
> ~slg
>
> --
> 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/0a16cfbe-4789-a939-796e-5f6f9da21626%40sagegerard.com
> 
> .
>

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/CANy33qmngGoVoAok6%2BR885jkh8MroMqYHpOd6XtjCSH7iiESQA%40mail.gmail.com.


prefab-contract.rkt
Description: Binary data


[racket-users] Injecting local contracts for prefab constructors

2021-05-09 Thread Sage Gerard
I have a project with 57 prefab structure types. I need to construct instances 
using a local contract (module level contracts do not fit my needs here). Since 
I cannot define guards, the solution is easy enough.

(struct foo (num) #:prefab)
(define/contract make-foo (-> real? foo?) foo)

Problem: I already have a few hundred constructor calls without contracts. I 
could either A) rewrite them all to use contracted constructors, or B) attach 
local contracts in a sweet spot so that I don't have to rewrite anything else.

I prefer option B, but it doesn't look like I can attach a local contract to a 
constructor with `struct` alone, or even with an impersonator. When I hack 
around to rebind or hide the constructor's identifier, I break compatibility 
with `match` and `defstruct*`.

If you were in my position, what would you do?

--

~slg

-- 
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/0a16cfbe-4789-a939-796e-5f6f9da21626%40sagegerard.com.


Re: [racket-users] Racket - How to define a function that can be used both in syntax transformers and ordinary code?

2021-05-09 Thread Sage Gerard
Wow, I really butchered a sentence. Let me try it again.

Old: "That is, there's a compile-time "pass" where Racket is focuses on the 
code you write and what they can see"

New: "That is, there's a compile-time "pass" where Racket focuses on replacing 
used macros with new code, and that pass has its own set of bindings that only 
that pass can see."

~slg

 Original Message 
On May 9, 2021, 3:14 PM, Sage Gerard wrote:

> I'm stretching details a bit, but maybe it would help to think of phases as 
> "passes." That is, there's a compile-time "pass" where Racket is focuses on 
> the code you write and what they can see. These passes continue until the 
> Racket program is fully expanded.
>
> Where things get tricky is remembering that when you create a binding at one 
> phase, it is available for that phase. It's a little easier to tell the 
> difference across module boundaries.
>
> Let's say you have a library that defines your functions at phase 0, or 
> runtime.
>
> ; lib.rkt
> #lang racket/base
> (provide (all-defined-out))
> (define (my-function x) (+ x 1))  (define (my-macro stx)
> (datum->syntax stx (my-function (cadr (syntax->datum stx)
>
> Now let's have another module use the syntax transformer. I'm handwaving 
> around some details because `define-syntax` and `define-for-syntax` are not 
> the same, but I'd like to focus on illustrating how phases operate.
>
> #lang racket/base
> (require "lib.rkt")
> (my-macro #'(x 1))
>
> The reason this works is because all the bindings are in the same phase. That 
> is, everything was defined in the same pass. Now let's shift it all one phase 
> up, which will break the program because it no longer sees my-macro, or even 
> enough of racket/base to apply functions.
>
> #lang racket/base
> (require (for-syntax "lib.rkt"))
> (my-macro #'(x 1))
>
> Right now `my-macro` is in phase 1 relative to this module. So we have to 
> "lift" the rest of the code to match.
>
> #lang racket/base
> (require (for-syntax racket/base "lib.rkt"))
> (begin-for-syntax (my-macro #'(x 1)))
>
> This still isn't particularly useful because most of the time, a module 
> manages multiple phases at once. It can be harder to visualize, but the 
> principle is the same: When code runs at a certain phase, is everything that 
> code needs to run also available at that phase? It's still just Racket. I 
> like to visualize it as running at a different "layer" on top of the code 
> that I know will eventually execute at runtime. Here's another example that 
> can help drive the point home. Run it using the `racket` command.
>
> #lang racket/base
> (require (for-syntax racket/base))
>
> (define a "foo")
> (define-for-syntax a 1)
>
> (displayln a)
> (begin-for-syntax (displayln a))
>
> Notice that you see "1" first, before "foo", even though the displayln for 
> the "1" is after the displayln for "foo".
>
> So to answer your question, if you have something you want available across 
> phases, you need to bind that same value across phases. Here's a simplified 
> example.
>
> #lang racket/base
> (require (for-syntax racket/base))
>
> (define-syntax-rule (define-across-phases id v)
> (begin (define id v)
> (define-for-syntax id v)))
>
> (define-across-phases a 1)
>
> (displayln a)
>
> (begin-for-syntax (displayln a))
>
> Notice that I leverage a phase to define an identifier twice: Once for the 
> current phase, and once for the phase +1 "layer" up.
>
> But... I normally do bind across phases using (require) with both for-syntax 
> and without a phase shift. e.g. (require "lib.rkt" (for-syntax "lib.rkt")). 
> There are times I'll need cross-phase definitions only within one module, but 
> it doesn't come up much for me.
>
> Hope this helps.
>
> On 5/9/21 3:53 AM, Yushuo Xiao wrote:
>
>> I am using syntax transformers to define macros in Racket. I want to create 
>> some helper functions to help me manipulate the syntax. However, the 
>> functions I defined outside the syntax transformer are not available inside 
>> the syntax transformer. For example, in the following code
>>
>> (define (my-function x) (+ x 1))
>>
>> (define-syntax my-macro
>> (lambda (stx)
>> (datum->syntax stx (my-function (cadr (syntax->datum stx))
>>
>> I got the error "my-function: reference to an unbound identifier at phase: 
>> 1; the transformer environment".
>>
>> After some searching, I am able to write the following code so that 
>> `my-function` is available inside the syntax transformer.
>>
>> (begin-for-syntax
>> (define (my-function x) (+ x 1)))
>> (provide (for-syntax my-function))
>>
>> (define-syntax my-macro
>> (lambda (stx)
>> (datum->syntax stx (my-function (cadr (syntax->datum stx))
>>
>> But the problem is, `my-function` is not available outside the syntax 
>> transformer this time. Sometimes I want to check those helper functions in 
>> ordinary code, so I need to be able to call it from both inside and outside 
>> the syntax transformer, just like the function `cadr`. How can I 

Re: [racket-users] Racket - How to define a function that can be used both in syntax transformers and ordinary code?

2021-05-09 Thread Sage Gerard
I'm stretching details a bit, but maybe it would help to think of phases as 
"passes." That is, there's a compile-time "pass" where Racket is focuses on the 
code you write and what they can see. These passes continue until the Racket 
program is fully expanded.

Where things get tricky is remembering that when you create a binding at one 
phase, it is available for that phase. It's a little easier to tell the 
difference across module boundaries.

Let's say you have a library that defines your functions at phase 0, or runtime.

; lib.rkt
#lang racket/base
(provide (all-defined-out))
(define (my-function x) (+ x 1))  (define (my-macro stx)
(datum->syntax stx (my-function (cadr (syntax->datum stx)

Now let's have another module use the syntax transformer. I'm handwaving around 
some details because `define-syntax` and `define-for-syntax` are not the same, 
but I'd like to focus on illustrating how phases operate.

#lang racket/base
(require "lib.rkt")
(my-macro #'(x 1))

The reason this works is because all the bindings are in the same phase. That 
is, everything was defined in the same pass. Now let's shift it all one phase 
up, which will break the program because it no longer sees my-macro, or even 
enough of racket/base to apply functions.

#lang racket/base
(require (for-syntax "lib.rkt"))
(my-macro #'(x 1))

Right now `my-macro` is in phase 1 relative to this module. So we have to 
"lift" the rest of the code to match.

#lang racket/base
(require (for-syntax racket/base "lib.rkt"))
(begin-for-syntax (my-macro #'(x 1)))

This still isn't particularly useful because most of the time, a module manages 
multiple phases at once. It can be harder to visualize, but the principle is 
the same: When code runs at a certain phase, is everything that code needs to 
run also available at that phase? It's still just Racket. I like to visualize 
it as running at a different "layer" on top of the code that I know will 
eventually execute at runtime. Here's another example that can help drive the 
point home. Run it using the `racket` command.

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

(define a "foo")
(define-for-syntax a 1)

(displayln a)
(begin-for-syntax (displayln a))

Notice that you see "1" first, before "foo", even though the displayln for the 
"1" is after the displayln for "foo".

So to answer your question, if you have something you want available across 
phases, you need to bind that same value across phases. Here's a simplified 
example.

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

(define-syntax-rule (define-across-phases id v)
(begin (define id v)
(define-for-syntax id v)))

(define-across-phases a 1)

(displayln a)

(begin-for-syntax (displayln a))

Notice that I leverage a phase to define an identifier twice: Once for the 
current phase, and once for the phase +1 "layer" up.

But... I normally do bind across phases using (require) with both for-syntax 
and without a phase shift. e.g. (require "lib.rkt" (for-syntax "lib.rkt")). 
There are times I'll need cross-phase definitions only within one module, but 
it doesn't come up much for me.

Hope this helps.

On 5/9/21 3:53 AM, Yushuo Xiao wrote:

> I am using syntax transformers to define macros in Racket. I want to create 
> some helper functions to help me manipulate the syntax. However, the 
> functions I defined outside the syntax transformer are not available inside 
> the syntax transformer. For example, in the following code
>
> (define (my-function x) (+ x 1))
>
> (define-syntax my-macro
> (lambda (stx)
> (datum->syntax stx (my-function (cadr (syntax->datum stx))
>
> I got the error "my-function: reference to an unbound identifier at phase: 1; 
> the transformer environment".
>
> After some searching, I am able to write the following code so that 
> `my-function` is available inside the syntax transformer.
>
> (begin-for-syntax
> (define (my-function x) (+ x 1)))
> (provide (for-syntax my-function))
>
> (define-syntax my-macro
> (lambda (stx)
> (datum->syntax stx (my-function (cadr (syntax->datum stx))
>
> But the problem is, `my-function` is not available outside the syntax 
> transformer this time. Sometimes I want to check those helper functions in 
> ordinary code, so I need to be able to call it from both inside and outside 
> the syntax transformer, just like the function `cadr`. How can I achieve that?
>
> I know my question has something to do with Racket's syntax model, in 
> particular the concept of "phase level", but I never really understand it. If 
> you could provide some easy-to-follow tutorials explaining it I would even be 
> more grateful.
> --
> 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 
> 

Re: [racket-users] macros in Racket repository

2021-05-09 Thread Tim Meehan
Thanks folks!


> On May 9, 2021, at 09:38, Robby Findler  wrote:
> 
> 
> Here's one way to write it in modern Racket:
> 
> #lang racket
> (require (for-syntax syntax/parse))
> 
> (module+ test (require rackunit))
> 
> (define-syntax (my-and stx)
>   (syntax-parse stx
> [(_) #'#f]
> [(_ e:expr) #'e]
> [(_ e1:expr e2:expr ...)
>  #'(if e1 (my-and e2 ...) #f)]))
> 
> (module+ test
>   (check-equal? (my-and) #f)
>   (check-equal? (my-and 1) 1)
>   (check-equal? (my-and 1 2) 2)
>   (check-equal? (my-and 1 #f 2) #f))
> 
> 
> 
>> On Sun, May 9, 2021 at 9:30 AM Jens Axel Søgaard  
>> wrote:
>> Hi Tim,
>> 
>> In this case Ryan's method leads to:
>> 
>> https://github.com/racket/racket/blob/master/racket/collects/racket/private/qq-and-or.rkt#L440
>> 
>> But in case you are wondering about the style used in that file:
>> at the point where "qq-and-or.rkt" is used, none of the usual 
>> syntax tools (such as syntax-case and syntax-parse) are available,
>> so it is written using only primitive constructs.
>> 
>> That is, that particular file does not represent the usual style of macro 
>> writing.
>> 
>> /Jens Axel
>> 
>> 
>>> Den søn. 9. maj 2021 kl. 16.13 skrev Ryan Culpepper 
>>> :
>>> Here are the three most convenient ways I know of to find that information 
>>> (which is "$RACKET/collects/racket/private/qq-and-or.rkt" in this specific 
>>> case):
>>> 
>>> If you use DrRacket, then open a file that uses `and`, right-click on an 
>>> occurrence of `and`, and choose "Open Defining File" (which changes to 
>>> "Jump to Definition (in Other File)" once DrRacket opens the file.
>>> 
>>> If you use Emacs with racket-mode, go to an occurrence of `and` and hit 
>>> "M-." (that is, hold down Meta/Alt and press the period key). You can also 
>>> use "M-x racket-visit-definition". That opens the defining module and jumps 
>>> to the definition.
>>> 
>>> If you have the `whereis` package installed, run the command `raco whereis 
>>> -b racket/base and` and it will print the path of the defining file.
>>> 
>>> Ryan
>>> 
>>> 
 On Sun, May 9, 2021 at 3:26 PM Tim Meehan  wrote:
 Where in the repository are macros like "and" and "or" defined?
 I tried searching for "and" and "or" ... but you probably know how that 
 worked out.
 
 Thanks folks!
 -- 
 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/CACgrOxK6S8EOAGk_rPbE%2B_wMLJiSbpwMhVd4AeRL8C9%2BDW3mgg%40mail.gmail.com.
>>> 
>>> -- 
>>> You received this message because you are subscribed to the Google Groups 
>>> "Racket Users" group.
>>> To unsubscribe from this group and stop receiving emails from it, send an 
>>> email to racket-users+unsubscr...@googlegroups.com.
>>> To view this discussion on the web visit 
>>> https://groups.google.com/d/msgid/racket-users/CANy33q%3DsLEH-ooUJxTay6pG1GNcRLZDUotNJ23L1HRTC1XqHwA%40mail.gmail.com.
>> 
>> 
>> -- 
>> -- 
>> Jens Axel Søgaard
>> 
>> -- 
>> You received this message because you are subscribed to the Google Groups 
>> "Racket Users" group.
>> To unsubscribe from this group and stop receiving emails from it, send an 
>> email to racket-users+unsubscr...@googlegroups.com.
>> To view this discussion on the web visit 
>> https://groups.google.com/d/msgid/racket-users/CABefVgzgqRPzx6ct6LrN-TAfE18vsdqnopun0B63LmqqKxerAQ%40mail.gmail.com.

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/5FA065BA-EFB1-424A-BDCE-7C865613EDEB%40gmail.com.


Re: [racket-users] macros in Racket repository

2021-05-09 Thread Robby Findler
Here's one way to write it in modern Racket:

#lang racket
(require (for-syntax syntax/parse))

(module+ test (require rackunit))

(define-syntax (my-and stx)
  (syntax-parse stx
[(_) #'#f]
[(_ e:expr) #'e]
[(_ e1:expr e2:expr ...)
 #'(if e1 (my-and e2 ...) #f)]))

(module+ test
  (check-equal? (my-and) #f)
  (check-equal? (my-and 1) 1)
  (check-equal? (my-and 1 2) 2)
  (check-equal? (my-and 1 #f 2) #f))



On Sun, May 9, 2021 at 9:30 AM Jens Axel Søgaard 
wrote:

> Hi Tim,
>
> In this case Ryan's method leads to:
>
>
> https://github.com/racket/racket/blob/master/racket/collects/racket/private/qq-and-or.rkt#L440
>
> But in case you are wondering about the style used in that file:
> at the point where "qq-and-or.rkt" is used, none of the usual
> syntax tools (such as syntax-case and syntax-parse) are available,
> so it is written using only primitive constructs.
>
> That is, that particular file does not represent the usual style of macro
> writing.
>
> /Jens Axel
>
>
> Den søn. 9. maj 2021 kl. 16.13 skrev Ryan Culpepper <
> rmculpepp...@gmail.com>:
>
>> Here are the three most convenient ways I know of to find that
>> information (which is "$RACKET/collects/racket/private/qq-and-or.rkt" in
>> this specific case):
>>
>> If you use DrRacket, then open a file that uses `and`, right-click on an
>> occurrence of `and`, and choose "Open Defining File" (which changes to
>> "Jump to Definition (in Other File)" once DrRacket opens the file.
>>
>> If you use Emacs with racket-mode, go to an occurrence of `and` and hit
>> "M-." (that is, hold down Meta/Alt and press the period key). You can also
>> use "M-x racket-visit-definition". That opens the defining module and jumps
>> to the definition.
>>
>> If you have the `whereis` package installed, run the command `raco
>> whereis -b racket/base and` and it will print the path of the defining file.
>>
>> Ryan
>>
>>
>> On Sun, May 9, 2021 at 3:26 PM Tim Meehan  wrote:
>>
>>> Where in the repository are macros like "and" and "or" defined?
>>> I tried searching for "and" and "or" ... but you probably know how that
>>> worked out.
>>>
>>> Thanks folks!
>>>
>>> --
>>> 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/CACgrOxK6S8EOAGk_rPbE%2B_wMLJiSbpwMhVd4AeRL8C9%2BDW3mgg%40mail.gmail.com
>>> 
>>> .
>>>
>> --
>> You received this message because you are subscribed to the Google Groups
>> "Racket Users" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to racket-users+unsubscr...@googlegroups.com.
>> To view this discussion on the web visit
>> https://groups.google.com/d/msgid/racket-users/CANy33q%3DsLEH-ooUJxTay6pG1GNcRLZDUotNJ23L1HRTC1XqHwA%40mail.gmail.com
>> 
>> .
>>
>
>
> --
> --
> Jens Axel Søgaard
>
> --
> You received this message because you are subscribed to the Google Groups
> "Racket Users" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to racket-users+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/racket-users/CABefVgzgqRPzx6ct6LrN-TAfE18vsdqnopun0B63LmqqKxerAQ%40mail.gmail.com
> 
> .
>

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/CAL3TdOOSKK_ae-JiObMc%2B7SJDYWZg%3Depw43HiD9oa%2B2kLTro7g%40mail.gmail.com.


Re: [racket-users] macros in Racket repository

2021-05-09 Thread Jens Axel Søgaard
Hi Tim,

In this case Ryan's method leads to:

https://github.com/racket/racket/blob/master/racket/collects/racket/private/qq-and-or.rkt#L440

But in case you are wondering about the style used in that file:
at the point where "qq-and-or.rkt" is used, none of the usual
syntax tools (such as syntax-case and syntax-parse) are available,
so it is written using only primitive constructs.

That is, that particular file does not represent the usual style of macro
writing.

/Jens Axel


Den søn. 9. maj 2021 kl. 16.13 skrev Ryan Culpepper :

> Here are the three most convenient ways I know of to find that information
> (which is "$RACKET/collects/racket/private/qq-and-or.rkt" in this specific
> case):
>
> If you use DrRacket, then open a file that uses `and`, right-click on an
> occurrence of `and`, and choose "Open Defining File" (which changes to
> "Jump to Definition (in Other File)" once DrRacket opens the file.
>
> If you use Emacs with racket-mode, go to an occurrence of `and` and hit
> "M-." (that is, hold down Meta/Alt and press the period key). You can also
> use "M-x racket-visit-definition". That opens the defining module and jumps
> to the definition.
>
> If you have the `whereis` package installed, run the command `raco whereis
> -b racket/base and` and it will print the path of the defining file.
>
> Ryan
>
>
> On Sun, May 9, 2021 at 3:26 PM Tim Meehan  wrote:
>
>> Where in the repository are macros like "and" and "or" defined?
>> I tried searching for "and" and "or" ... but you probably know how that
>> worked out.
>>
>> Thanks folks!
>>
>> --
>> 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/CACgrOxK6S8EOAGk_rPbE%2B_wMLJiSbpwMhVd4AeRL8C9%2BDW3mgg%40mail.gmail.com
>> 
>> .
>>
> --
> You received this message because you are subscribed to the Google Groups
> "Racket Users" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to racket-users+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/racket-users/CANy33q%3DsLEH-ooUJxTay6pG1GNcRLZDUotNJ23L1HRTC1XqHwA%40mail.gmail.com
> 
> .
>


-- 
-- 
Jens Axel Søgaard

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/CABefVgzgqRPzx6ct6LrN-TAfE18vsdqnopun0B63LmqqKxerAQ%40mail.gmail.com.


Re: [racket-users] macros in Racket repository

2021-05-09 Thread Ryan Culpepper
Here are the three most convenient ways I know of to find that information
(which is "$RACKET/collects/racket/private/qq-and-or.rkt" in this specific
case):

If you use DrRacket, then open a file that uses `and`, right-click on an
occurrence of `and`, and choose "Open Defining File" (which changes to
"Jump to Definition (in Other File)" once DrRacket opens the file.

If you use Emacs with racket-mode, go to an occurrence of `and` and hit
"M-." (that is, hold down Meta/Alt and press the period key). You can also
use "M-x racket-visit-definition". That opens the defining module and jumps
to the definition.

If you have the `whereis` package installed, run the command `raco whereis
-b racket/base and` and it will print the path of the defining file.

Ryan


On Sun, May 9, 2021 at 3:26 PM Tim Meehan  wrote:

> Where in the repository are macros like "and" and "or" defined?
> I tried searching for "and" and "or" ... but you probably know how that
> worked out.
>
> Thanks folks!
>
> --
> 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/CACgrOxK6S8EOAGk_rPbE%2B_wMLJiSbpwMhVd4AeRL8C9%2BDW3mgg%40mail.gmail.com
> 
> .
>

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/CANy33q%3DsLEH-ooUJxTay6pG1GNcRLZDUotNJ23L1HRTC1XqHwA%40mail.gmail.com.


[racket-users] macros in Racket repository

2021-05-09 Thread Tim Meehan
Where in the repository are macros like "and" and "or" defined?
I tried searching for "and" and "or" ... but you probably know how that
worked out.

Thanks folks!

-- 
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/CACgrOxK6S8EOAGk_rPbE%2B_wMLJiSbpwMhVd4AeRL8C9%2BDW3mgg%40mail.gmail.com.


[racket-users] Re: Help in understanding 'letrec' example

2021-05-09 Thread Utkarsh Singh
Hi,

> We are finding a file (or directory) with name "tarzan" inside all
> directories inside given path upto given depth.
>
> Recursion is needed here, because  tarzan-near-top-of-tree? calls 
> tarzan-in-directory? and  tarzan-in-directory? calls 
> tarzan-near-top-of-tree? for each file in given directory.

Thanks! I finally understood it.

Here is the explanation (for reference):

Consider a sample directory called test with following structure (ASCII
art using 'tree' command):

test
├── dir1
│   └── subdir1
│   └── file1
└── dir2

Our code will first recursively search for all file in dir1 upto depth 4
and then move to dir2.  Using ormap insures that search for 'tarzan'
will stop at first match (or first true result).
-- 
Utkarsh Singh
http://utkarshsingh.xyz

-- 
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/87h7jcp6fm.fsf%40gmail.com.


RE: [racket-users] How to define a function that can be used both in syntax transformers and ordinary code?

2021-05-09 Thread Jacob Jozef
Another solution: #lang racket (define-syntax (def-both-phases stx) (syntax-case stx ()  ((_ rest ...) #'(begin (define rest ...)     (define-for-syntax rest ...) (def-both-phases (my-function x) (+ x 1)) (define-syntax my-macro  (lambda (stx)    (datum->syntax stx (my-function (cadr (syntax->datum stx)) (my-macro 5)(my-function 7) Jos From: Yushuo XiaoSent: domingo, 9 de mayo de 2021 10:00To: Racket UsersSubject: [racket-users] How to define a function that can be used both in syntax transformers and ordinary code? I am using syntax transformers to define macros in Racket. I want to create some helper functions to help me manipulate the syntax. However, the functions I defined outside the syntax transformer are not available inside the syntax transformer. For example, in the following code (define (my-function x) (+ x 1)) (define-syntax my-macro  (lambda (stx)    (datum->syntax stx (my-function (cadr (syntax->datum stx)) I got the error "my-function: reference to an unbound identifier at phase: 1; the transformer environment". After some searching, I am able to write the following code so that `my-function` is available inside the syntax transformer. (begin-for-syntax  (define (my-function x) (+ x 1)))(provide (for-syntax my-function)) (define-syntax my-macro  (lambda (stx)    (datum->syntax stx (my-function (cadr (syntax->datum stx)) But the problem is, `my-function` is not available outside the syntax transformer this time. Sometimes I want to check those helper functions in ordinary code, so I need to be able to call it from both inside and outside the syntax transformer, just like the function `cadr`. How can I achieve that? I know my question has something to do with Racket's syntax model, in particular the concept of "phase level", but I never really understand it. If you could provide some easy-to-follow tutorials explaining it I would even be more grateful. (Also, I have asked the same question on StackOverflow before I am aware of this Google group. Is this place more suitable for asking Racket questions like this than StackOverflow? Should I delete the question on StackOverflow?)-- 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/244a3fc8-e24f-4121-a09f-3bd6d2c6b140n%40googlegroups.com. 



-- 
You received this message because you are subscribed to the Google Groups "Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to racket-users+unsubscr...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/racket-users/ADFCA8F8-72A0-4F1F-89B1-CE28BBEF4017%40hxcore.ol.


RE: [racket-users] How to define a function that can be used both in syntax transformers and ordinary code?

2021-05-09 Thread Jacob Jozef
You can put your function in a module and require it both normally and for syntax.#lang racket (module my-function racket (provide my-function) (define (my-function x) (+ x 1))) (require 'my-function (for-syntax 'my-function)) (define-syntax my-macro  (lambda (stx)    (datum->syntax stx (my-function (cadr (syntax->datum stx)) (my-macro 5)(my-function 7) See also cross phase persistent if you want one instantiation only.Jos   From: Yushuo XiaoSent: domingo, 9 de mayo de 2021 10:00To: Racket UsersSubject: [racket-users] How to define a function that can be used both in syntax transformers and ordinary code? I am using syntax transformers to define macros in Racket. I want to create some helper functions to help me manipulate the syntax. However, the functions I defined outside the syntax transformer are not available inside the syntax transformer. For example, in the following code (define (my-function x) (+ x 1)) (define-syntax my-macro  (lambda (stx)    (datum->syntax stx (my-function (cadr (syntax->datum stx)) I got the error "my-function: reference to an unbound identifier at phase: 1; the transformer environment". After some searching, I am able to write the following code so that `my-function` is available inside the syntax transformer. (begin-for-syntax  (define (my-function x) (+ x 1)))(provide (for-syntax my-function)) (define-syntax my-macro  (lambda (stx)    (datum->syntax stx (my-function (cadr (syntax->datum stx)) But the problem is, `my-function` is not available outside the syntax transformer this time. Sometimes I want to check those helper functions in ordinary code, so I need to be able to call it from both inside and outside the syntax transformer, just like the function `cadr`. How can I achieve that? I know my question has something to do with Racket's syntax model, in particular the concept of "phase level", but I never really understand it. If you could provide some easy-to-follow tutorials explaining it I would even be more grateful. (Also, I have asked the same question on StackOverflow before I am aware of this Google group. Is this place more suitable for asking Racket questions like this than StackOverflow? Should I delete the question on StackOverflow?)-- 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/244a3fc8-e24f-4121-a09f-3bd6d2c6b140n%40googlegroups.com. 



-- 
You received this message because you are subscribed to the Google Groups "Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to racket-users+unsubscr...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/racket-users/874CCB4A-0952-4E7A-9DA5-279C4578B1DE%40hxcore.ol.


[racket-users] How to define a function that can be used both in syntax transformers and ordinary code?

2021-05-09 Thread Yushuo Xiao
I am using syntax transformers to define macros in Racket. I want to create 
some helper functions to help me manipulate the syntax. However, the 
functions I defined outside the syntax transformer are not available inside 
the syntax transformer. For example, in the following code

(define (my-function x) (+ x 1))

(define-syntax my-macro
  (lambda (stx)
(datum->syntax stx (my-function (cadr (syntax->datum stx))

I got the error "my-function: reference to an unbound identifier at phase: 
1; the transformer environment".

After some searching, I am able to write the following code so that 
`my-function` is available inside the syntax transformer.

(begin-for-syntax
  (define (my-function x) (+ x 1)))
(provide (for-syntax my-function))

(define-syntax my-macro
  (lambda (stx)
(datum->syntax stx (my-function (cadr (syntax->datum stx))

But the problem is, `my-function` is not available outside the syntax 
transformer this time. Sometimes I want to check those helper functions in 
ordinary code, so I need to be able to call it from both inside and outside 
the syntax transformer, just like the function `cadr`. How can I achieve 
that?

I know my question has something to do with Racket's syntax model, in 
particular the concept of "phase level", but I never really understand it. 
If you could provide some easy-to-follow tutorials explaining it I would 
even be more grateful.

(Also, I have asked the same question on StackOverflow before I am aware of 
this Google group. Is this place more suitable for asking Racket questions 
like this than StackOverflow? Should I delete the question on 
StackOverflow?)

-- 
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/244a3fc8-e24f-4121-a09f-3bd6d2c6b140n%40googlegroups.com.


[racket-users] Racket - How to define a function that can be used both in syntax transformers and ordinary code?

2021-05-09 Thread Yushuo Xiao
I am using syntax transformers to define macros in Racket. I want to create 
some helper functions to help me manipulate the syntax. However, the 
functions I defined outside the syntax transformer are not available inside 
the syntax transformer. For example, in the following code

(define (my-function x) (+ x 1))

(define-syntax my-macro
  (lambda (stx)
(datum->syntax stx (my-function (cadr (syntax->datum stx))

I got the error "my-function: reference to an unbound identifier at phase: 
1; the transformer environment".

After some searching, I am able to write the following code so that 
`my-function` is available inside the syntax transformer.

(begin-for-syntax
  (define (my-function x) (+ x 1)))
(provide (for-syntax my-function))

(define-syntax my-macro
  (lambda (stx)
(datum->syntax stx (my-function (cadr (syntax->datum stx))

But the problem is, `my-function` is not available outside the syntax 
transformer this time. Sometimes I want to check those helper functions in 
ordinary code, so I need to be able to call it from both inside and outside 
the syntax transformer, just like the function `cadr`. How can I achieve 
that?

I know my question has something to do with Racket's syntax model, in 
particular the concept of "phase level", but I never really understand it. 
If you could provide some easy-to-follow tutorials explaining it I would 
even be more grateful.

-- 
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/46cce5b2-251b-481c-afe2-28582e8c44f3n%40googlegroups.com.


[racket-users] Re: Help in understanding 'letrec' example

2021-05-09 Thread kalime...@gmail.com
We are finding a file (or directory) with name "tarzan" inside all 
directories inside given path upto given depth.
Recursion is needed here, because  tarzan-near-top-of-tree? calls  
tarzan-in-directory? and  tarzan-in-directory? calls  
tarzan-near-top-of-tree? for each file in given directory.

суббота, 8 мая 2021 г. в 12:50:09 UTC+5, Utkarsh Singh: 

> Hi,
>
> First of all I would like to thank Racket community for creating and
> maintaining top quality documentation at https://docs.racket-lang.org/
> and even providing a local copy for it.
>
> Currently I am having some difficulties in understanding this letrec
> example from Racket Guide docs
> (
> https://docs.racket-lang.org/guide/let.html#%28part._.Recursive_.Binding__letrec%29
> ):
>
> (letrec ([tarzan-near-top-of-tree?
> (lambda (name path depth)
> (or (equal? name "tarzan")
> (and (directory-exists? path)
> (tarzan-in-directory? path depth]
> [tarzan-in-directory?
> (lambda (dir depth)
> (cond
> [(zero? depth) #f]
> [else
> (ormap
> (λ (elem)
> (tarzan-near-top-of-tree? (path-element->string elem)
> (build-path dir elem)
> (- depth 1)))
> (directory-list dir))]))])
> (tarzan-near-top-of-tree? "tmp"
> (find-system-path 'temp-dir)
> 4))
>
> Problem:
> I having some problem on how recursion is working here and what is the
> problem we are solving here. Are we finding a file with (name?
> "tarzan") or something else?
>
> -- 
> Utkarsh Singh
> http://utkarshsingh.xyz
>

-- 
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/a3d31da0-c9b7-4aac-a541-15137197d941n%40googlegroups.com.