Re:Function Strings
Posted: Thu Sep 02, 2004 8:09 pm
The reason that doesn't work, is that a function call like yours is evaluated so that each of the "subforms" are evaluated first, and then the function is called.Schol-R-LEA wrote:
Now, what's interesting is that I originally thought that I could just run it as
[tt]((string->symbol "sqrt") 2)[/tt]
Now, what happens is that if you type [tt](sqrt 2)[/tt] the symbol [tt]sqrt[/tt] gets evaluated into "the function stored in the variable [tt]sqrt[/tt]" and the 2 simply evaluates to itself. Then "the function stored in the variable [tt]sqrt[/tt]" is called with 2 as it's argument.
If you write [tt](string->symbol "sqrt")[/tt] it does not evaluate to "the function stored in the variable [tt]sqrt[/tt]" but simply the symbol [tt]sqrt[/tt]. Since a symbol is not a function, trying to call it with parameter 2 causes a runtime (or with good type inference, a compiler) error.
In a sense, what you wrote is the same as writing:
[tt]('sqrt 2)[/tt]
You could also use:
[tt](eval '(sqrt 2))[/tt]
or
[tt](eval (list 'sqrt 2))[/tt]
The good thing with Lisp is that in many cases, one can build such expressions on compilation time, using macros, so the eval isn't needed. A (traditional Lisp) macro (in one sense) is a function, which receives it's arguments as "unevaluated" that is, as typed in code, and whatever the macro returns, becomes the code in place of the "macro call".
Anyway, to get around the limitation of needing eval for that, you need a primitive for getting the contents of a named variable. AFAIK there is no such primitive in Scheme, but in Common Lisp one can use "symbol-value" to access the value of a (global) variable named by the symbol, for example (using CLisp):
Code: Select all
[1]> (setq foobar 1234)
1234
[2]> (symbol-value 'foobar)
1234
Code: Select all
(funcall (symbol-function (find-symbol "SQRT")) 2)