Runtime evaluation/In an environment: Difference between revisions
(→{{header|Python}}: alternate implementation using compile & introspection) |
|||
Line 59: | Line 59: | ||
x[1]: 5 |
x[1]: 5 |
||
f(3) = 8; f(5) = 32; f(5) - f(3) = 24</lang> |
f(3) = 8; f(5) = 32; f(5) - f(3) = 24</lang> |
||
===Python using introspection=== |
|||
In Python, one can compile an expression then query the compiled object to find out the names that are used. This second example uses this method: |
|||
<lang python>func = compile( raw_input('Enter expression: '), |
|||
'compile_error.txt', |
|||
'eval' ) |
|||
# ask for two sets of any names used in the expression |
|||
name = [{}, {}] |
|||
for n in func.co_names: name[0][n] = input('First value of %s: ' % n) |
|||
for n in func.co_names: name[1][n] = input('Second value of %s: ' % n) |
|||
print "\n<Expression at second value set> - <Expression at first> =", \ |
|||
eval(func, name[1]) - eval(func, name[0]) |
|||
</lang> |
|||
A simple use would be: |
|||
<lang python>Enter expression: 2**x |
|||
First value of x: 3 |
|||
Second value of x: 5 |
|||
<Expression at second value set> - <Expression at first> = 24</lang> |
|||
and for an initial expression using multiple variables: |
|||
<lang python>Enter expression: 3 * x + y |
|||
First value of x: 1 |
|||
First value of y: 2 |
|||
Second value of x: 3 |
|||
Second value of y: 4 |
|||
<Expression at second value set> - <Expression at first> = 8</lang> |
|||
=={{header|Ruby}}== |
=={{header|Ruby}}== |
Revision as of 07:38, 18 February 2009
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>code = raw_input('f(x): ') x = [input('x[%i]: ' % i) for i in [0,1]] fx = [eval(code, {"x": xv}) for xv in x] print "f({x[0]}) = {f0}; f({x[1]}) = {f1}; f({x[1]}) - f({x[0]}) = {ans}".format(
x=x, f0=fx[0], f1=fx[1], ans= fx[1] - fx[0] )</lang>
Typical use would be (user input is after the initial colon in a line): <lang python>f(x): 2**x x[0]: 3 x[1]: 5 f(3) = 8; f(5) = 32; f(5) - f(3) = 24</lang>
Python using introspection
In Python, one can compile an expression then query the compiled object to find out the names that are used. This second example uses this method: <lang python>func = compile( raw_input('Enter expression: '),
'compile_error.txt', 'eval' )
- ask for two sets of any names used in the expression
name = [{}, {}] for n in func.co_names: name[0][n] = input('First value of %s: ' % n) for n in func.co_names: name[1][n] = input('Second value of %s: ' % n)
print "\n<Expression at second value set> - <Expression at first> =", \
eval(func, name[1]) - eval(func, name[0])
</lang> A simple use would be: <lang python>Enter expression: 2**x First value of x: 3 Second value of x: 5
<Expression at second value set> - <Expression at first> = 24</lang> and for an initial expression using multiple variables: <lang python>Enter expression: 3 * x + y First value of x: 1 First value of y: 2 Second value of x: 3 Second value of y: 4
<Expression at second value set> - <Expression at first> = 8</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>