0

I want the following code to work:

(define fn.str "(lambda (x) (displayln x)")
(define fn.callable (string->lambda fn.str))
; and then 2 next lines should be valid
(fn.callable 123)
(apply fn.callable '(321))

But best I can get is to eval string and get output, instead my target is to get the actual holding value (λ in this case).

In general, this is also desired effect:

(define val.num "500")
(define val.li "'(1 2 3)")
(define val.fn "(λ (a) a)")
(define num (string->value val.num)) ; => num is now holding 500
(define li (string->value val.li)) ; => list '(1 2 3)
(define fn (string->value val.fn)) ; => callable lambda

Maybe I came close enough to solution, but it's got bad smell.

More info:

  • Those strings came into program from outside (file/user input).
  • Extracted/parsed values should be binded to something (hash table, for example) for further access.
1
  • Maybe related: stackoverflow.com/questions/20349543/…. Although, if you really want to take arbitrary user strings and eval them, you might need eval. When possible it's preferable to make your own #lang in Racket. Commented Mar 9, 2015 at 3:55

1 Answer 1

2

You're right about something - evaluating code from a string is a bad code smell… maybe there's a better way to do what you want to accomplish. Anyway, here's a possible solution:

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

(define (eval-string str)
  (eval (call-with-input-string str read) ns))

It works as requested for the sample inputs:

(define fn.str "(lambda (x) (displayln x))")
(define fn.callable (eval-string fn.str))
(fn.callable 123)
=> 123

(apply fn.callable '(321))
=> 321

(define val.num "500")
(eval-string val.num)
=> 500

(define val.li "'(1 2 3)")
(eval-string val.li)
=> '(1 2 3)

(define val.fn "(λ (a) a)")
(eval-string val.fn)
=> #<procedure>
Sign up to request clarification or add additional context in comments.

2 Comments

Using this solution this way: (hash-ref! h key (eval-str "(λ (x y) '(y x))")) causes arity mismatch. Manual check and hash-set! is better choice here (maybe it is obvious, but not for me), at least with this approach.
@IskanderSharipov that sounds more like a problem with the way you're actually using the function when you get it from the hash table, not with the approach itself.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.