Runtime evaluation/In an environment: Difference between revisions

From Rosetta Code
Content added Content deleted
(→‎{{header|Python}}: mark incorrect (source code, not closures; and the name x should be chosen by the operation, not the provided program -- that's the point of this task vs. 'call a function')
Line 30: Line 30:


=={{header|Perl}}==
=={{header|Perl}}==

{{incorrect|Perl|Accepts a closure, not source code.}}


<lang perl>our $x;
<lang perl>our $x;
# Only necessary if "use strict" is in effect or a
# Only necessary if "use strict" is in effect or a
# lexical $x (declared with "my") exists in this scope.
# lexical $x (declared with "my") exists in this scope.

sub eval_with_x
sub eval_with_x
{my $code = shift;
{my $code = shift;
local $x = shift;
local $x = shift;
my $first = $code->();
my $first = eval $code;
local $x = shift;
local $x = shift;
return $code->() - $first;}
return (eval $code) - $first;}

print eval_with_x(sub {3 * $x}, 5, 10), "\n"; # Prints "15\n".</lang>
print eval_with_x('3 * $x', 5, 10), "\n"; # Prints "15\n".</lang>


Note that this is a ''dynamic'', not lexical, binding of <var><code>$x</code></var>.
Note that this is a [[wp:Dynamic scope|''dynamic'', not lexical, binding]] of <var><code>$x</code></var>.


=={{header|Python}}==
=={{header|Python}}==

Revision as of 20:41, 17 February 2009

Task
Runtime evaluation/In an environment
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

This example is incorrect. Please fix the code and remove this message.

Details: Depends on the provided program making the binding of x, not itself.

Python 2.x's input statement will evaluate its input string as an expression, so by supplying a lambda expression to generate a function we get: <lang python>func = input('f(x): ') x = [input('x[%i]: ' % i) for i in [0,1]] print "f({x[0]}) = {f0}; f({x[1]}) = {f1}; f({x[1]}) - f({x[0]}) = {ans}".format(

   x=x, f0=func(x[0]), f1=func(x[1]), ans= func(x[1]) - func(x[0]) )</lang>

Typical use would be (user input is after the initial colon in a line): <lang python>f(x): lambda x: 2**x x[0]: 3 x[1]: 5 f(3) = 8; f(5) = 32; f(5) - f(3) = 24</lang>