[racket] How to tell if identifier is bound in racket/load?
> I can't tell how the behavior you described differs from just providing the
> variable from ark.rkt and requiring ark.rkt normally. Can you elaborate?
Wow. I'm not sure what misconceptions I was working under, but that
works completely fine. And it looks like I can use something like
defm from http://permalink.gmane.org/gmane.comp.lang.racket.user/13119
to hide the getters and setters.
Thanks!
That said, I'd still like to be able to enable the equivalent of the
following in arc:
#lang racket/load
(define (test1)
(displayln "a"))
(define (test2)
(test1))
(test2)
(define (test1)
(displayln "b"))
(test2)
Welcome to DrRacket, version 5.2.1 [3m].
Language: racket/load [custom]; memory limit: 128 MB.
a
b
My current macro to handle top level assignment doesn't work in racket/load:
#lang racket/load
(require (for-syntax syntax/parse))
; From Danny Yoo's arctangent
; https://github.com/dyoo/arctangent/blob/master/language.rkt
; Returns true if stx is an identifier that is lexically bound.
(define-for-syntax (lexically-bound? stx)
(let ([expanded (local-expand stx (syntax-local-context) #f)])
(cond
[(and (identifier? expanded)
(eq? #f (identifier-binding expanded)))
#f]
[else #t])))
(define-syntax (assign1 stx)
(define-splicing-syntax-class binding-pair
#:description "binding pair"
(pattern (~seq var:id rhs:expr)))
(syntax-parse
stx
[(_ p:binding-pair)
(if (lexically-bound? #'p.var)
#'(begin (set! p.var p.rhs)
p.var)
#'(begin (define p.var #f)
(assign1 p.var p.rhs)))]))
(assign1 a 5)
When run, it never completes because lexically-bound? always returns
false and recursion never terminates.
If instead the assignment is in the body of a function, or in a
module, it all works fine:
(define (test)
(assign a 5)
a)
Do these examples make my intent more clear? I'm not sure how to
describe what I want correctly.
-Nick
On Mon, Jul 16, 2012 at 10:43 AM, Ryan Culpepper <ryan at cs.utah.edu> wrote:
> On 07/16/2012 03:35 AM, Nick Sivo wrote:
>>
>> Hi,
>>
>> I've been using the following awesome snippet to detect when
>> identifiers are already bound:
>>
>> ; From Danny Yoo's arctangent
>> ; https://github.com/dyoo/arctangent/blob/master/language.rkt
>> ; Returns true if stx is an identifier that is lexically bound.
>> (define-for-syntax (lexically-bound? stx)
>> (let ([expanded (local-expand stx (syntax-local-context) #f)])
>> (cond
>> [(and (identifier? expanded)
>> (eq? #f (identifier-binding expanded)))
>> #f]
>> [else
>> #t])))
>>
>> Then I created a helper so I could call it at runtime:
>>
>> (define-syntax (arc-bound stx)
>> (syntax-parse
>> stx
>> [(_ var:id)
>> (if (lexically-bound? #'var) #'#t #'#f)]))
>>
>> That still worked great. Then I tried using racket/load:
>>
>> Welcome to DrRacket, version 5.2.1 [3m].
>> Language: racket/load; memory limit: 128 MB.
>>>
>>> (arc-bound a)
>>
>> #f
>>>
>>> (define a 5)
>>> (arc-bound a)
>>
>> #f
>>>
>>>
>>
>> :( I've read through the docs on namespaces and the racket/load
>> language source in an attempt to fully understand why racket/load is
>> different, but I'm missing something. I've noticed that I can see 'a
>> in (namespace-mapped-symbols), and have tried using that, but ran into
>> (I think) phase issues. If there's a quick solution to this that I've
>> missed, that's brilliant.
>
>
> It works in DrRacket using #lang racket because the interactions occur in a
> module namespace, but with #lang racket/load all interactions happen in an
> ordinary namespace. That accounts for the differences in the results of
> identifier-binding.
>
>
>> Otherwise, my motivation to start making use of racket/load (really
>> arc/load in my case), is to get access to global variables. If
>> ark.rkt declares something at the module level, I need to be able to
>> see it - the same copy of it - from other modules that require
>> ark.rkt. What I'm trying now is to have ark.rkt be a real module
>> written in arc, and then require it and load the rest of the arc files
>> using the arc/load language so they all share the same module registry
>> and the same ark.rkt. If there's some other, better way to do this,
>> pointers will be quite warmly received.
>
>
> I can't tell how the behavior you described differs from just providing the
> variable from ark.rkt and requiring ark.rkt normally. Can you elaborate?
>
> Ryan