Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Call function based on a string

I am passing in command line arguments to my Lisp program and they are formatted like this when they hit my main function:

("1 1 1" "dot" "2 2 2") 

I have a dot function (which takes two vectors as arguments) and would like to call it directly from the argument, but this isn't possible because something like (funcall (second args)...) receives "dot" and not dot as the function name.

I tried variations of this function:
(defun remove-quotes (s)
(setf (aref s 0) '""))

to no avail, before realizing that the quotes were not really a part of the string. Is there a simple way to do this, or should I just check each string and then call the appropriate function?

like image 570
powerj1984 Avatar asked May 30 '10 20:05

powerj1984


2 Answers

"1 1 1" is a string of five characters: 1, space, 1, space and 1. The double quotes are not part of the string.

("1 1 1" "dot" "2 2 2") is a list of three strings.

There are no " characters above. The " are used to delimit strings in s-expressions.

If you have a dot function you need to tell us what kind of input data it expects. Does it expect two lists of numbers? Then you have to convert the string "1 1 1" into a list of numbers.

(with-input-from-string (in "1 1 1")
  (loop for data = (read in nil in)
   until (eq data in)
   collect data)))

To get the function DOT from the string "dot" first find the symbol DOT and then get its symbol function.

(symbol-function (find-symbol (string-upcase "dot")))

For find-symbol one might need to specify also the package, if there is a special package where the symbol is in.

Converting a list to a vector then is the next building block.

So you need to convert the arguments for your function to vectors (probably first converting them to lists as I showed above). Then you need to find the function (see above). If you have then the function and the arguments, then you can call the function using FUNCALL or APPLY (whatever is more convenient).

like image 68
Rainer Joswig Avatar answered Oct 06 '22 11:10

Rainer Joswig


The question is a bit unclear, but as far as I understand it you want, when given the list ("1 1 1" "dot" "2 2 2") as input to evaluate the expression (dot "1 1 1" "2 2 2"). In that case you can do this:

(defun apply-infix (arg1 f arg2)
  (apply (intern (string-upcase f)) (list arg1 arg2)))
(defun apply-list-infix (lst)
  (apply 'apply-infix lst))

(apply-list-infix '("1 1 1" "dot" "2 2 2"))
like image 31
sepp2k Avatar answered Oct 06 '22 11:10

sepp2k