
Why can’t I get the value of b
here?
> (define n (make-base-namespace))
> (eval-syntax (namespace-syntax-introduce #'(define b 2)) n)
> (eval-syntax (namespace-syntax-introduce #'(define b 2) n) n)
> (namespace-variable-value 'b #t (lambda _ #f) n)
#f
> (namespace-variable-value 'b #f (lambda _ #f) n)
#f
>

For comparison, this works fine, so I know the problem has to do with enriching the syntax object for eval-syntax
. The problem is that if I use expand
or namespace-syntax-introduce
, I still don’t get desired results. What specific information is still missing?
> (define n (make-base-namespace))
> (eval '(define b 2) n)
> (namespace-variable-value 'b #t (lambda _ #f) n)
2

I read through Racket’s source and mushed together all of the usage patterns into behemoth expressions like (eval-syntax (expand (namespace-syntax-introduce (datum->syntax #f '(define b 2)))) n)
just for grins. Still cannot see the expected value.

This works for me, but I have no idea why:
> (require syntax/strip-context)
> (define n (make-base-namespace))
> (parameterize ([current-namespace n]) ((current-eval) (namespace-syntax-introduce (strip-context #'(define b 2)))))
> (namespace-variable-value 'b #t (lambda _ #f) n)

And it’s really weird because:
> (require syntax/strip-context)
> (define n (make-base-namespace))
> (eval-syntax (namespace-syntax-introduce (strip-context #'(define b 2))) n)
> (namespace-variable-value 'b #t (lambda _ #f) n)
doesn’t work, even though it should be completely equivalent to the above

Ah

I understand now

I forgot to put n
in namespace-syntax-introduce
. This works:
> (require syntax/strip-context)
> (define n (make-base-namespace))
> (eval-syntax (namespace-syntax-introduce (strip-context #'(define b 2)) n) n)
> (namespace-variable-value 'b #t (lambda _ #f) n)

That makes sense given the docs for namespace-syntax-introduce
> The additional context is overridden by any existing <https://docs.racket-lang.org/reference/syntax-model.html?q=expand#%28tech._top._level._binding%29|top-level bindings> in the <https://docs.racket-lang.org/reference/syntax-model.html?q=expand#%28tech._syntax._object%29|syntax object>’s <https://docs.racket-lang.org/reference/syntax-model.html?q=expand#%28tech._lexical._information%29|lexical information>, or by any existing or future <https://docs.racket-lang.org/reference/syntax-model.html?q=expand#%28tech._module._binding%29|module bindings> in the <https://docs.racket-lang.org/reference/syntax-model.html?q=expand#%28tech._lexical._information%29|lexical information>. Since the docs do not call out strip-context
as possibly (frequently?) needed, I assumed I didn’t need it in the REPL.

Thanks much!!

Here’s a preview of the manual for a new package: tesurell
. It’s a markup language that uses the Scribble reader, and allows inline use of #lang
. What makes it different from multi-lang
and polyglot
is that it doesn’t write modules to disk, and can self-host.

PDF shows motivation. I didn’t see an identical project, but please let me know if one exists. Source: https://github.com/zyrolasting/tesurell

Is (eval-syntax (namespace-syntax-introduce (strip-context #'(define b 2)) ns) ns)
effectively just (eval '(define b 2) ns)
? I think so but I’m not sure.

Yes, I think so too.


Caveat: I mean in terms of lexical context. (Maybe the first way, you get source location attached to the syntax, which either you want, don’t want, or don’t care.)

Oh sorry, I misunderstood. I don’t think they are equivalent for my purposes, which is to keep the location info within a markup file.

Ah OK. So you may want to retain the syntax object, if only for the location. Even if you’re effectively just using it as a plain s-expression, in terms of lexical context. Seems like the situation.

Correct. Since “lexical context” seems to be an umbrella term it’s been tricky to find what info I’m missing and what info I want to keep before hitting eval-syntax
. Just a gap in my education.

I’m adding more tests for Racket Mode, including now for the macro stepper feature. It seems like I’ve discovered something broke or at least changed with macro-debugger/stepper-text
, in 7.6, both plain and CS, and persisting on HEAD. (I wish I’d already had these new tests in Racket Mode, some months ago, I could have known and reported before 7.6 released).
Given stepper.rkt #lang racket/base
(require macro-debugger/stepper-text)
(define step (stepper-text #'(module example racket/base (define x 42) x)))
(step 'next)
In Racket versions 6.0 through 7.5 you get e.g.: $ ~/racket/7.5/bin/racket stepper.rkt
Tag #%module-begin
(module example racket/base (define x 42) x)
==>
(module example racket/base (#%module-begin (define x 42) x))
and in this example you could call step
another dozen times before it returns #f
i.e. “done”.
But starting in 7.6 the first step
immediately returns #f
: $ ~/racket/7.6/bin/racket stepper.rkt
#f

@greg For 7.6, @ryanc entirely rewrote macro hiding, so probably that has something to do with it

I was wondering if I should dive in and try to figure out what changed and how to fix. What you say makes me think probably not. :simple_smile:

Well, maybe I could take a quick look at the “edge” and see if some “glue” code just needs to be tweaked.

Anything deeper sounds like something @ryanc would be able to figure out about a billion times faster than I could.

It’s possible that something about the default hiding policy broke, which might be easy to fix, but it’s definitely a bug relative to the documented behavior.

@greg I pushed a fix. I broke the “is this an interesting step?” predicate, so it was generating the steps and then throwing them all away. Unfortunately, I can’t think of a good workaround for 7.6 unless you want to use namespace magic to hot-patch the code.

@ryanc Thanks! I’ll take a look at the commit and consider a hot-patch. (Worst case, I’ll do a little runtime test for this behavior, advise the user to use a newer/older version of Racket. IIRC I had to do similar for a version of Racket where module->namespace
behaved differently in some respect. Rather than compare version numbers, I directly tested for the behavior.)

@ryanc Although, “use namespace magic to hot-patch the code” sounds naughty and something I’d like to know how to do. :simple_smile: Do you mean using namespace-set-variable-value!
to substitute my own values for the rename-step?
and rewrite-step?
functions? If so, wouldn’t the code inspector disallow that? Would I need my subs to know about the protostep
struct
, and, might that be tricky since struct
s are generative?

@greg I haven’t thought this all the way through, but I was thinking about something using module->namespace
and eval
. Earlier I had forgotten about the module restrictions on set!
(or other operations that have the same effect) — that’s related to the compile-enforce-module-constants
parameter, not the code inspector. It might be easiest set compile-enforce-module-constants
to false, load the macro-debugger/stepper-text
module from source, use module->namespace
to enter the module, and then use eval
to replace the definition of get-steps
(replacing rewrite-step?
with a fixed equivalent). That’s probably easier than fixing rewrite-step?
directly in macro-debugger/model/steps
, since that module gets required by multiple others, and (IIUC) you might have to load more things from source to get around the set!
restriction. Re: generative structs, the goal would be to reuse an existing instantiation of the steps module; a solution that involved re-running the struct declarations would cause problems.

Is there an easy way to “upgrade” installed packages in an old version of Racket when I install a new version of Racket? I understand that I can just copy directories/files at ~/Library/Racket/<version>
and remove compiled
directories as a way to “upgrade”, but it requires users to know where things are and basic shell scripting skill. The alternative choice that beginner programmers have is to reinstall everything again.

Ha, there’s “Copy from Version” in the package manager. This looks promising.

raco pkg migrate
is I think the command line version

Yep, thanks!