Runtime evaluation/In an environment: Difference between revisions
(→{{header|Python}}: alternate implementation using compile & introspection) |
(→{{header|Python}}: swapped introspection for another way to use more than one variable) |
||
Line 48:
=={{header|Python}}==
<lang python>>>> def eval_with_x(code,
>>> eval_with_x('2 ** x', 3, 5)
24</lang
===Python:
A slight change allows the evaluation to take multiple names:
<lang python>
return eval(code, kwordargs)
>>> code = '2 ** x'
>>> eval_with_args(code, x=5) - eval_with_args(code, x=3)
▲ eval(func, name[1]) - eval(func, name[0])
24
</lang>▼
>>> code = '3 * x + y'
>>> eval_with_args(code, x=5, y=2) - eval_with_args(code, x=3, y=1)
7
▲>>> </lang>
=={{header|Ruby}}==
|
Revision as of 07:55, 18 February 2009
![Task](http://static.miraheze.org/rosettacodewiki/thumb/b/ba/Rcode-button-task-crushed.png/64px-Rcode-button-task-crushed.png)
You are encouraged to solve this task according to the task description, using any language you may know.
Given a program in the language representing a function, evaluate it with the variable x (or another name if that is not valid) bound to a provided value, then evaluate it again with x bound to another provided value, then subtract the result of the first from the second and return or print it.
Preferably, do so in a way which does not involve string manipulation of source code, and is plausibly extensible to a runtime-chosen set of bindings.
For more general examples and language-specific details, see Eval.
Common Lisp
<lang lisp> (defun eval-with-x (program a b)
(let ((at-a (eval `(let ((x ',a)) ,program))) (at-b (eval `(let ((x ',b)) ,program)))) (- at-b at-a)))
</lang>
<lang lisp> (eval-with-x '(exp x) 0 1) => 1.7182817 </lang>
This version ensures that the program is compiled, once, for more efficient execution:
<lang lisp> (defun eval-with-x (program a b)
(let* ((f (compile nil `(lambda (x) ,program))) (at-a (funcall f a)) (at-b (funcall f b))) (- at-b at-a)))
</lang>
Perl
<lang perl>our $x;
# Only necessary if "use strict" is in effect or a # lexical $x (declared with "my") exists in this scope.
sub eval_with_x
{my $code = shift; local $x = shift; my $first = eval $code; local $x = shift; return eval($code) - $first;}
print eval_with_x('3 * $x', 5, 10), "\n"; # Prints "15\n".</lang>
Note that this is a dynamic, not lexical, binding of $x
.
Python
<lang python>>>> def eval_with_x(code, a, b): return eval(code, {'x':b}) - eval(code, {'x':a})
>>> eval_with_x('2 ** x', 3, 5) 24</lang>
Python: for multiple names
A slight change allows the evaluation to take multiple names: <lang python>>>> def eval_with_args(code, **kwordargs): return eval(code, kwordargs)
>>> code = '2 ** x' >>> eval_with_args(code, x=5) - eval_with_args(code, x=3) 24 >>> code = '3 * x + y' >>> eval_with_args(code, x=5, y=2) - eval_with_args(code, x=3, y=1) 7 >>> </lang>
Ruby
<lang ruby>def getBinding(x)
binding
end
def eval_with_x(code, a, b)
eval(code, getBinding(b)) - eval(code, getBinding(a))
end
puts eval_with_x('2 ** x', 3, 5) # Prints "24"</lang>
Scheme
Almost identical to the Common Lisp version above. <lang scheme>(define (eval-with-x prog a b)
(let ((at-a (eval `(let ((x ',a)) ,prog))) (at-b (eval `(let ((x ',b)) ,prog)))) (- at-b at-a)))</lang>