Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamic function call in Racket; or get a procedure from a string

I apologize in advance for this likely silly question :)

Suppose, I have a list of strings like

(define func-names '("add" "sub" "mul"))

And there are also functions defined like so

(define (add x y)
  (+ x y))

(define (sub x y)
  (- x y))

(define (mul x y)
  (* x y))

As you can see, values of the strings in the list correspond to the names of the functions. I need a way to iterate through the list and call the function that corresponds to a string value. Something like

(define (all-ops x y)                                        
  (map (lambda (name) (string->proc name x y)) func-names))

where string->proc is what I'm looking for. Something like Ruby's send/public_send method, if you're familiar with Ruby.

I'm mostly interested in answers applicable to Racket.

Thank you.

EDIT; And I've forgotten to mention that there may be a million of function names, so cond, match would be tedious to use here.

like image 805
Anton Harniakou Avatar asked Nov 15 '25 13:11

Anton Harniakou


1 Answers

Consider making a hash table that maps strings to function values.

That said, you can do as follows:

#lang racket
(define (add x y)
  (+ x y))

(define ns (variable-reference->namespace (#%variable-reference)))

(define (string->procedure s)
  (define sym (string->symbol s))
  (eval sym ns))

(string->procedure "add")

((string->procedure "add") 1 2)

See also http://blog.racket-lang.org/2011/10/on-eval-in-dynamic-languages-generally.html

like image 73
soegaard Avatar answered Nov 17 '25 08:11

soegaard



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!