skobls
skobls

Reputation: 182

printf symbol name and value

Suppose somewhere I have defined several symbols:

#lang racket
(define foo 123)
(define bar '("1" "2" "3"))

I need a way to produce a string like "foo = 123" or "bar = '("1" "2" "3")". I wrote a function for that:

(define (f2 sy)
  (format "~a = ~s" sy (eval sy)))

This function works in the interpretator window pretty well.

> (f2 'foo)
"foo = 123"
> (f2 'bar)
"bar = (\"1\" \"2\" \"3\")"

That is quite satisfactory for me. However, when I use it in the code, I get

foo: unbound identifier;
 also, no #%top syntax transformer is bound in: foo

I have a feeling that I am doing something wrong. Can you please suggest the right way to solve my problem?

P.S.: I am using DrRacket, version 5.3.1

Upvotes: 1

Views: 188

Answers (2)

skobls
skobls

Reputation: 182

Another solution, also inspired by Asumu Takikawa uses the trick described in the guide:

(define-namespace-anchor a)
(define ns (namespace-anchor->namespace a))

(define (f2 sy)
  (format "~a = ~s" sy (eval sy ns)))

On the contrast to the solution with macros, this function can be mapped.

Upvotes: 1

Asumu Takikawa
Asumu Takikawa

Reputation: 8523

First of all, eval should really only be used as a last resort in Racket. It makes your program less efficient and harder to understand. The right way to do this is probably to write a macro such as the following:

(define-syntax-rule (f2 sy)
  (format "~a = ~s" (quote sy) sy))

(define foo 2)
(f2 foo)

This macro just substitutes the name of the variable you want to lookup into the format expression in the body. The quote turns the variable name into a symbol you can print. This macro doesn't work as a procedure, because (f2 foo) would deference foo before you can quote and print its name.


Note: the reason why your eval doesn't work as expected is because eval always evaluates with respect to a namespace, which dictates what is in scope. The default namespace within a module has nothing in it, so eval can't see foo or anything else. You can read more about namespaces in the Guide.

Upvotes: 1

Related Questions