Runtime evaluation/In an environment: Difference between revisions

From Rosetta Code
Content added Content deleted
(apply nimpretty to codes)
(Added FreeBASIC)
 
(13 intermediate revisions by 10 users not shown)
Line 22: Line 22:
<!-- {{does not work with|ELLA ALGOL 68|Any This implementation is a compiler}} -->
<!-- {{does not work with|ELLA ALGOL 68|Any This implementation is a compiler}} -->
Variable names are generally not visible at run time with classic compilers. However '''ALGOL 68G''' is an interpretor and it retains this ability. Note that ''evaluate'' returns a '''string'''.
Variable names are generally not visible at run time with classic compilers. However '''ALGOL 68G''' is an interpretor and it retains this ability. Note that ''evaluate'' returns a '''string'''.
<lang algol68>PROC eval_with_x = (STRING code, INT a, b)STRING:
<syntaxhighlight lang="algol68">PROC eval_with_x = (STRING code, INT a, b)STRING:
(INT x=a; evaluate(code) ) + (INT x=b; evaluate(code));
(INT x=a; evaluate(code) ) + (INT x=b; evaluate(code));
print((eval_with_x("2 ** x", 3, 5), new line))</lang>
print((eval_with_x("2 ** x", 3, 5), new line))</syntaxhighlight>
Output:
Output:
<pre>
<pre>
Line 38: Line 38:
<br>
<br>
Given the above, the task may easily be implemented along these lines:
Given the above, the task may easily be implemented along these lines:
<syntaxhighlight lang="applescript">
<lang AppleScript>
on task_with_x(pgrm, x1, x2)
on task_with_x(pgrm, x1, x2)
local rslt1, rslt2
local rslt1, rslt2
Line 45: Line 45:
rslt2 - rslt1
rslt2 - rslt1
end task_with_x
end task_with_x
</syntaxhighlight>
</lang>
Example usage (for legibility purposes, the program is stored into an intermediate variable):
Example usage (for legibility purposes, the program is stored into an intermediate variable):
<syntaxhighlight lang="applescript">
<lang AppleScript>
set pgrm_with_x to "
set pgrm_with_x to "
on run {x}
on run {x}
Line 54: Line 54:


task_with_x(pgrm_with_x, 3, 5)
task_with_x(pgrm_with_x, 3, 5)
</syntaxhighlight>
</lang>
The result is 24.0 (a real number).
The result is 24.0 (a real number).

=={{header|Arturo}}==
<syntaxhighlight lang="arturo">code: [x * 2]
fn: function [x]->
do with 'x code

a: fn 2
b: fn 4

print b - a</syntaxhighlight>

{{out}}

<pre>4</pre>


=={{header|AutoHotkey}}==
=={{header|AutoHotkey}}==
Line 61: Line 75:


AutoHotkey does not provide an API to the local symbol table. Local variables are also not supported within scopes outside functions. However, a local environment can be simulated by wrapping code in a temporary function.
AutoHotkey does not provide an API to the local symbol table. Local variables are also not supported within scopes outside functions. However, a local environment can be simulated by wrapping code in a temporary function.
<lang AutoHotkey>msgbox % first := evalWithX("x + 4", 5)
<syntaxhighlight lang="autohotkey">msgbox % first := evalWithX("x + 4", 5)
msgbox % second := evalWithX("x + 4", 6)
msgbox % second := evalWithX("x + 4", 6)
msgbox % second - first
msgbox % second - first
Line 92: Line 106:
if fnp := FindFunc(funcName)
if fnp := FindFunc(funcName)
numput(&x%newname%, fnp+0, 0, "uint")
numput(&x%newname%, fnp+0, 0, "uint")
}</lang>
}</syntaxhighlight>


=={{header|BBC BASIC}}==
=={{header|BBC BASIC}}==
<lang bbcbasic> expression$ = "x^2 - 7"
<syntaxhighlight lang="bbcbasic"> expression$ = "x^2 - 7"
one = FN_eval_with_x(expression$, 1.2)
one = FN_eval_with_x(expression$, 1.2)
two = FN_eval_with_x(expression$, 3.4)
two = FN_eval_with_x(expression$, 3.4)
Line 102: Line 116:
DEF FN_eval_with_x(expr$, x)
DEF FN_eval_with_x(expr$, x)
= EVAL(expr$)</lang>
= EVAL(expr$)</syntaxhighlight>


=={{header|Bracmat}}==
=={{header|Bracmat}}==
<lang>( ( eval-with-x
<syntaxhighlight lang="text">( ( eval-with-x
= code a b argument
= code a b argument
. !arg:((=?code),?a,?b,?argument)
. !arg:((=?code),?a,?b,?argument)
Line 113: Line 127:
& out$(eval-with-x$((='(.$x^!arg)),3,5,2))
& out$(eval-with-x$((='(.$x^!arg)),3,5,2))
& out$(eval-with-x$((='(.$x^!arg)),12,13,2))
& out$(eval-with-x$((='(.$x^!arg)),12,13,2))
);</lang>
);</syntaxhighlight>
Output:
Output:
<pre>16
<pre>16
Line 121: Line 135:


We must define x as global, but we use dynamic bindings. Only functions within the binding will see the newly bound value of x, before it re-establishes the bindings that existed before.
We must define x as global, but we use dynamic bindings. Only functions within the binding will see the newly bound value of x, before it re-establishes the bindings that existed before.
<lang clojure>(def ^:dynamic x nil)
<syntaxhighlight lang="clojure">(def ^:dynamic x nil)


(defn eval-with-x [program a b]
(defn eval-with-x [program a b]
(- (binding [x b] (eval program))
(- (binding [x b] (eval program))
(binding [x a] (eval program))))</lang>
(binding [x a] (eval program))))</syntaxhighlight>


<lang clojure>(eval-with-x '(* x x) 4 9)
<syntaxhighlight lang="clojure">(eval-with-x '(* x x) 4 9)
=> 65</lang>
=> 65</syntaxhighlight>


Here's another version which avoids the global by compiling a local function with a single argument x (the ~'x is how to avoid automatic namespace qualification of symbols in a syntax quote):
Here's another version which avoids the global by compiling a local function with a single argument x (the ~'x is how to avoid automatic namespace qualification of symbols in a syntax quote):
<lang clojure>
<syntaxhighlight lang="clojure">
(defn eval-with-x [program a b]
(defn eval-with-x [program a b]
(let [func (eval `(fn [~'x] ~program))]
(let [func (eval `(fn [~'x] ~program))]
(- (func b) (func a))))
(- (func b) (func a))))
</syntaxhighlight>
</lang>
<lang clojure>(eval-with-x '(* x x) 4 9)
<syntaxhighlight lang="clojure">(eval-with-x '(* x x) 4 9)
=> 65</lang>
=> 65</syntaxhighlight>


=={{header|Common Lisp}}==
=={{header|Common Lisp}}==


<lang lisp>(defun eval-with-x (program a b)
<syntaxhighlight lang="lisp">(defun eval-with-x (program a b)
(let ((at-a (eval `(let ((x ',a)) ,program)))
(let ((at-a (eval `(let ((x ',a)) ,program)))
(at-b (eval `(let ((x ',b)) ,program))))
(at-b (eval `(let ((x ',b)) ,program))))
(- at-b at-a)))</lang>
(- at-b at-a)))</syntaxhighlight>


<lang lisp>(eval-with-x '(exp x) 0 1)
<syntaxhighlight lang="lisp">(eval-with-x '(exp x) 0 1)
=> 1.7182817</lang>
=> 1.7182817</syntaxhighlight>


This version ensures that the program is compiled, once, for more efficient execution:
This version ensures that the program is compiled, once, for more efficient execution:


<lang lisp>(defun eval-with-x (program a b)
<syntaxhighlight lang="lisp">(defun eval-with-x (program a b)
(let* ((f (compile nil `(lambda (x) ,program)))
(let* ((f (compile nil `(lambda (x) ,program)))
(at-a (funcall f a))
(at-a (funcall f a))
(at-b (funcall f b)))
(at-b (funcall f b)))
(- at-b at-a)))</lang>
(- at-b at-a)))</syntaxhighlight>


=={{header|Déjà Vu}}==
=={{header|Déjà Vu}}==
<lang dejavu>local fib n:
<syntaxhighlight lang="dejavu">local fib n:
if <= n 1:
if <= n 1:
n
n
Line 168: Line 182:
!run-blob-in { :fib @fib :x 4 } code
!run-blob-in { :fib @fib :x 4 } code
!run-blob-in { :fib @fib :x 6 } code
!run-blob-in { :fib @fib :x 6 } code
!. -</lang>
!. -</syntaxhighlight>
{{out}}
{{out}}
<pre>5</pre>
<pre>5</pre>


=={{header|E}}==
=={{header|E}}==
<lang e># Constructing an environment has to be done by way of evaluation
<syntaxhighlight lang="e"># Constructing an environment has to be done by way of evaluation
#for historical reasons which will hopefully be entirely eliminated soon.
#for historical reasons which will hopefully be entirely eliminated soon.
def bindX(value) {
def bindX(value) {
Line 187: Line 201:
def atB := program.eval(bindX(b))
def atB := program.eval(bindX(b))
return atB - atA
return atB - atA
}</lang>
}</syntaxhighlight>


<lang e>? evalWithX(e`(x :float64).exp()`, 0, 1)
<syntaxhighlight lang="e">? evalWithX(e`(x :float64).exp()`, 0, 1)
# value: 1.7182818284590455</lang>
# value: 1.7182818284590455</syntaxhighlight>


=={{header|EchoLisp}}==
=={{header|EchoLisp}}==
We evaluate prog in a new environment which is an association list ((x x-value)), and could be ((x x-value) (y y-value)....)
We evaluate prog in a new environment which is an association list ((x x-value)), and could be ((x x-value) (y y-value)....)
<lang lisp>
<syntaxhighlight lang="lisp">
(define (eval-with-x prog x)
(define (eval-with-x prog x)
(eval prog (environment-new (list (list 'x x)))))
(eval prog (environment-new (list (list 'x x)))))
Line 207: Line 221:
x
x
😖️ error: #|user| : unbound variable : x
😖️ error: #|user| : unbound variable : x
</syntaxhighlight>
</lang>


=={{header|Elena}}==
=={{header|Elena}}==
ELENA 5.0:
ELENA 6.x:


Using VM console client:
Using VM console client:
<lang elena>import extensions;
<syntaxhighlight lang="elena">import extensions;
import extensions'scripting;
import extensions'scripting;


Line 221: Line 235:
var arg := program_arguments[2];
var arg := program_arguments[2];
var program := lscript.interpret(text);
var program := lscript.interpretLine(text);
console.printLine(
console.printLine(
text,",",arg," = ",program.eval(arg.toReal()));
text,",",arg," = ",program.eval(arg.toReal()));
}</lang>
}</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>
Line 236: Line 250:
=={{header|Erlang}}==
=={{header|Erlang}}==
Functions below are used by [[Dynamic_variable_names#Erlang| dynamic variable names]]. Any changes here needs to be backwards compatible, or [[Dynamic_variable_names#Erlang| dynamic variable names]] must also be changed.
Functions below are used by [[Dynamic_variable_names#Erlang| dynamic variable names]]. Any changes here needs to be backwards compatible, or [[Dynamic_variable_names#Erlang| dynamic variable names]] must also be changed.
<syntaxhighlight lang="erlang">
<lang Erlang>
-module( runtime_evaluation ).
-module( runtime_evaluation ).


Line 258: Line 272:
io:fwrite( "~p~n", [Variable2] ),
io:fwrite( "~p~n", [Variable2] ),
io:fwrite( "~p~n", [Variable2 - Variable1] ).
io:fwrite( "~p~n", [Variable2 - Variable1] ).
</syntaxhighlight>
</lang>


{{out}}
{{out}}
Line 270: Line 284:
=={{header|Factor}}==
=={{header|Factor}}==
Being a stack-based language, there is usually no need to bind data stack objects to a variable name. This is the idiomatic way to do it, with <code>eval</code> referencing what it needs from the data stack:
Being a stack-based language, there is usually no need to bind data stack objects to a variable name. This is the idiomatic way to do it, with <code>eval</code> referencing what it needs from the data stack:
<lang factor>USE: eval
<syntaxhighlight lang="factor">USE: eval
: eval-bi@- ( a b program -- n )
: eval-bi@- ( a b program -- n )
tuck [ ( y -- z ) eval ] 2bi@ - ;</lang>
tuck [ ( y -- z ) eval ] 2bi@ - ;</syntaxhighlight>
<lang factor>IN: scratchpad 9 4 "dup *" eval-bi@- .
<syntaxhighlight lang="factor">IN: scratchpad 9 4 "dup *" eval-bi@- .
65</lang>
65</syntaxhighlight>
Also note that, since programs are first-class denizens in Factor, the use cases for <code>eval</code> are few. Normally, you would pass in a program as a quotation:
Also note that, since programs are first-class denizens in Factor, the use cases for <code>eval</code> are few. Normally, you would pass in a program as a quotation:
<lang factor>: bi@- ( a b quot -- n ) bi@ - ; inline</lang>
<syntaxhighlight lang="factor">: bi@- ( a b quot -- n ) bi@ - ; inline</syntaxhighlight>
<lang factor>IN: scratchpad 9 4 [ dup * ] bi@- .
<syntaxhighlight lang="factor">IN: scratchpad 9 4 [ dup * ] bi@- .
65</lang>
65</syntaxhighlight>
However, we can adhere to the letter of the task. Although we are using a dynamic variable for x, it exists in a temporary, non-global namespace. As far as I can tell, <code>eval</code> is unaware of surrounding lexical scope.
However, we can adhere to the letter of the task. Although we are using a dynamic variable for x, it exists in a temporary, non-global namespace. As far as I can tell, <code>eval</code> is unaware of surrounding lexical scope.
<lang factor>SYMBOL: x
<syntaxhighlight lang="factor">SYMBOL: x
: eval-with-x ( a b program -- n )
: eval-with-x ( a b program -- n )
tuck
tuck
[ [ x ] dip [ ( -- y ) eval ] curry with-variable ] 2bi@ - ;</lang>
[ [ x ] dip [ ( -- y ) eval ] curry with-variable ] 2bi@ - ;</syntaxhighlight>
<lang factor>IN: scratchpad 9 4 "x get dup *" eval-with-x .
<syntaxhighlight lang="factor">IN: scratchpad 9 4 "x get dup *" eval-with-x .
65
65
IN: scratchpad x get .
IN: scratchpad x get .
f</lang>
f</syntaxhighlight>


=={{header|Forth}}==
=={{header|Forth}}==
EVALUATE invokes the Forth interpreter on the given string.
EVALUATE invokes the Forth interpreter on the given string.
<lang forth>: f-" ( a b snippet" -- )
<syntaxhighlight lang="forth">: f-" ( a b snippet" -- )
[char] " parse ( code len )
[char] " parse ( code len )
2dup 2>r evaluate
2dup 2>r evaluate
Line 297: Line 311:
- . ;
- . ;


2 3 f-" dup *" \ 5 (3*3 - 2*2)</lang>
2 3 f-" dup *" \ 5 (3*3 - 2*2)</syntaxhighlight>
This can be used to treat a data stream as code, or to provide a lightweight macro facility when used in an IMMEDIATE word.
This can be used to treat a data stream as code, or to provide a lightweight macro facility when used in an IMMEDIATE word.
<lang forth>: :macro ( "name <char> ccc<char>" -- )
<syntaxhighlight lang="forth">: :macro ( "name <char> ccc<char>" -- )
: [CHAR] ; PARSE POSTPONE SLITERAL POSTPONE EVALUATE
: [CHAR] ; PARSE POSTPONE SLITERAL POSTPONE EVALUATE
POSTPONE ; IMMEDIATE
POSTPONE ; IMMEDIATE
Line 313: Line 327:
DO .\" spam "
DO .\" spam "
LOOP
LOOP
; ok</lang>
; ok</syntaxhighlight>

=={{header|FreeBASIC}}==
<syntaxhighlight lang="vbnet">#include "solver.bi"

Dim As String expression = "(x ^ 2 )-7"

setVar("x",1.2)
Print "one = ";Solver(expression)
setVar("x",3.4)
Print "two = ";Solver(expression)

Sleep</syntaxhighlight>
{{out}}
<pre>one = -5.560000000000001
two = 4.559999999999999</pre>


=={{header|Genyris}}==
=={{header|Genyris}}==
One way is to use a macro. In genyris, macros are lazy functions which execute twice, the return value is also evaluated in the caller's environment:
One way is to use a macro. In genyris, macros are lazy functions which execute twice, the return value is also evaluated in the caller's environment:
<lang genyris>defmacro add100() (+ x 100)
<syntaxhighlight lang="genyris">defmacro add100() (+ x 100)


var x 23
var x 23
Line 323: Line 352:
x = 1000
x = 1000
print
print
+ firstresult (add100)</lang>
+ firstresult (add100)</syntaxhighlight>


This prints 1223.
This prints 1223.
Line 329: Line 358:
Another way is to use dynamically scoped variables. In Genyris, symbols prefixed with a period are looked up in the caller's environment, not the lexical environment of the closure. When a dictionary is the first element of the expression, an environment is created and the &rest is evaluated.
Another way is to use dynamically scoped variables. In Genyris, symbols prefixed with a period are looked up in the caller's environment, not the lexical environment of the closure. When a dictionary is the first element of the expression, an environment is created and the &rest is evaluated.


<lang genyris>def add100() (+ .x 100)
<syntaxhighlight lang="genyris">def add100() (+ .x 100)


(dict) # create an environment capable of holding dynamic bindings
(dict) # create an environment capable of holding dynamic bindings
Line 336: Line 365:
.x = 1000
.x = 1000
print
print
+ firstresult (add100)</lang>
+ firstresult (add100)</syntaxhighlight>
Dictionaries can hold bindings to dynamic symbols. To minimize the danger of dynamic scope there is no recursive ascent in the binding lookup.
Dictionaries can hold bindings to dynamic symbols. To minimize the danger of dynamic scope there is no recursive ascent in the binding lookup.
<lang genyris>(dict)
<syntaxhighlight lang="genyris">(dict)
var .x 23
var .x 23
(dict)
(dict)
print .x # fails</lang>
print .x # fails</syntaxhighlight>


=={{header|Go}}==
=={{header|Go}}==
<lang go>package main
<syntaxhighlight lang="go">package main


import (
import (
Line 410: Line 439:
func (v *intV) Assign(t *eval.Thread, o eval.Value) {
func (v *intV) Assign(t *eval.Thread, o eval.Value) {
*v = intV(o.(eval.IntValue).Get(t))
*v = intV(o.(eval.IntValue).Get(t))
}</lang>
}</syntaxhighlight>
Output:
Output:
<pre>
<pre>
Line 419: Line 448:


The solution:
The solution:
<lang groovy>def cruncher = { x1, x2, program ->
<syntaxhighlight lang="groovy">def cruncher = { x1, x2, program ->
Eval.x(x1, program) - Eval.x(x2, program)
Eval.x(x1, program) - Eval.x(x2, program)
}</lang>
}</syntaxhighlight>


Test Program:
Test Program:
<lang groovy>def fibonacciProgram = '''
<syntaxhighlight lang="groovy">def fibonacciProgram = '''
x < 1 ? 0 : x == 1 ? 1 : (2..x).inject([0,1]){i, j -> [i[1], i[0]+i[1]]}[1]
x < 1 ? 0 : x == 1 ? 1 : (2..x).inject([0,1]){i, j -> [i[1], i[0]+i[1]]}[1]
'''
'''


println "F(${10}) - F(${5}) = ${Eval.x(10, fibonacciProgram)} - ${Eval.x(5, fibonacciProgram)} = " + cruncher(10, 5, fibonacciProgram)</lang>
println "F(${10}) - F(${5}) = ${Eval.x(10, fibonacciProgram)} - ${Eval.x(5, fibonacciProgram)} = " + cruncher(10, 5, fibonacciProgram)</syntaxhighlight>


Output:
Output:
Line 436: Line 465:
===Explicit===
===Explicit===
The following satisfies the requirements:
The following satisfies the requirements:
<lang j> EvalWithX=. monad : 0
<syntaxhighlight lang="j"> EvalWithX=. monad : 0
'CODE V0 V1'=. y
'CODE V0 V1'=. y
(". CODE [ x=. V1) - (". CODE [ x=. V0)
(". CODE [ x=. V1) - (". CODE [ x=. V0)
Line 442: Line 471:
EvalWithX '^x';0;1
EvalWithX '^x';0;1
1.71828183</lang>
1.71828183</syntaxhighlight>
===Tacit===
===Tacit===
However, it is easier via point-free coding:
However, it is easier via point-free coding:
<lang j> (0&({::) -~&>/@:(128!:2&.>) 1 2&{) '^';0;1
<syntaxhighlight lang="j"> (0&({::) -~&>/@:(128!:2&.>) 1 2&{) '^';0;1
1.71828183</lang>
1.71828183</syntaxhighlight>


===Explicit again===
===Explicit again===


Or, using y as the free variable, instead of x:
Or, using y as the free variable, instead of x:
<lang J>EvalDiffWithY=: dyad define
<syntaxhighlight lang="j">EvalDiffWithY=: dyad define
-~/verb def x"_1 y
-~/verb def x"_1 y
)</lang>
)</syntaxhighlight>


Example use:
Example use:


<lang J> '^y' EvalDiffWithY 0 1
<syntaxhighlight lang="j"> '^y' EvalDiffWithY 0 1
1.71828</lang>
1.71828</syntaxhighlight>


This can be extended to support a user declared argument name:
This can be extended to support a user declared argument name:


<lang J>EvalDiffWithName=: adverb define
<syntaxhighlight lang="j">EvalDiffWithName=: adverb define
:
:
-~/m adverb def ('(m)=.y';x)"_1 y
-~/m adverb def ('(m)=.y';x)"_1 y
)</lang>
)</syntaxhighlight>


This works by preceding the user provided expression with a statement which assigns the argument value to a local variable whose name was provided by the user. [Note that this implementation skirts the requirement that the implementation does not manipulate strings -- instead we manipulate a structure containing strings.]
This works by preceding the user provided expression with a statement which assigns the argument value to a local variable whose name was provided by the user. [Note that this implementation skirts the requirement that the implementation does not manipulate strings -- instead we manipulate a structure containing strings.]
Line 471: Line 500:
Example use:
Example use:


<lang J> '^George' 'George' EvalDiffWithName 0 1
<syntaxhighlight lang="j"> '^George' 'George' EvalDiffWithName 0 1
1.71828
1.71828
'Z + 2^Z' 'Z' EvalDiffWithName 2 3
'Z + 2^Z' 'Z' EvalDiffWithName 2 3
5</lang>
5</syntaxhighlight>


Of course this could be re-defined such that the free variable declaration appears to the left of the expression (<code>'Z' 'Z + 2^Z' Example 2 3</code>). However, J's [[currying]] and precedence rules might make that less convenient to use, if this were ever used in a real program.
Of course this could be re-defined such that the free variable declaration appears to the left of the expression (<code>'Z' 'Z + 2^Z' Example 2 3</code>). However, J's [[currying]] and precedence rules might make that less convenient to use, if this were ever used in a real program.
Line 490: Line 519:
* the exception handling is minimal, but if something goes wrong you should get a stack dump and the exception ''might'' be helpful...
* the exception handling is minimal, but if something goes wrong you should get a stack dump and the exception ''might'' be helpful...


<lang java5>import java.io.File;
<syntaxhighlight lang="java5">import java.io.File;
import java.lang.reflect.Method;
import java.lang.reflect.Method;
import java.net.URI;
import java.net.URI;
Line 557: Line 586:
);
);
}
}
}</lang>
}</syntaxhighlight>


Example usage - calculating the difference of two squares (i.e. 9 - 2 = 7):
Example usage - calculating the difference of two squares (i.e. 9 - 2 = 7):
Line 569: Line 598:
eval uses the environment from the calling function.
eval uses the environment from the calling function.


<lang javascript>function evalWithX(expr, a, b) {
<syntaxhighlight lang="javascript">function evalWithX(expr, a, b) {
var x = a;
var x = a;
var atA = eval(expr);
var atA = eval(expr);
Line 575: Line 604:
var atB = eval(expr);
var atB = eval(expr);
return atB - atA;
return atB - atA;
}</lang>
}</syntaxhighlight>


<lang javascript>evalWithX('Math.exp(x)', 0, 1) // returns 1.718281828459045</lang>
<syntaxhighlight lang="javascript">evalWithX('Math.exp(x)', 0, 1) // returns 1.718281828459045</syntaxhighlight>


=={{header|Jsish}}==
=={{header|Jsish}}==
From Javascript entry.
From Javascript entry.
<lang javascript>/* Runtime evaluation in an environment, in Jsish */
<syntaxhighlight lang="javascript">/* Runtime evaluation in an environment, in Jsish */
function evalWithX(expr, a, b) {
function evalWithX(expr, a, b) {
var x = a;
var x = a;
Line 598: Line 627:
evalWithX('Math.exp(x)', 1, 0) ==> -1.71828182845905
evalWithX('Math.exp(x)', 1, 0) ==> -1.71828182845905
=!EXPECTEND!=
=!EXPECTEND!=
*/</lang>
*/</syntaxhighlight>


{{out}}
{{out}}
Line 607: Line 636:
{{works with|Julia|0.6}}
{{works with|Julia|0.6}}


<lang julia>macro evalwithx(expr, a, b)
<syntaxhighlight lang="julia">macro evalwithx(expr, a, b)
return quote
return quote
x = $a
x = $a
Line 616: Line 645:
end
end


@evalwithx(2 ^ x, 3, 5) # raw expression (AST)</lang>
@evalwithx(2 ^ x, 3, 5) # raw expression (AST)</syntaxhighlight>


One can even perform the task without using macros:
One can even perform the task without using macros:


<lang julia>function evalwithx(expr::Expr, a, b)
<syntaxhighlight lang="julia">function evalwithx(expr::Expr, a, b)
a = eval(quote let x = $a; return $expr end end)
a = eval(quote let x = $a; return $expr end end)
b = eval(quote let x = $b; return $expr end end)
b = eval(quote let x = $b; return $expr end end)
Line 628: Line 657:


evalwithx(:(2 ^ x), 3, 5)
evalwithx(:(2 ^ x), 3, 5)
evalwithx("2 ^ x", 3, 5)</lang>
evalwithx("2 ^ x", 3, 5)</syntaxhighlight>


=={{header|Kotlin}}==
=={{header|Kotlin}}==
{{trans|JavaScript}}
{{trans|JavaScript}}
When you try to compile the following program, it will appear to the compiler that the local variable 'x' is assigned but never used and warnings will be issued accordingly. You can get rid of these warnings by compiling using the -nowarn flag.
When you try to compile the following program, it will appear to the compiler that the local variable 'x' is assigned but never used and warnings will be issued accordingly. You can get rid of these warnings by compiling using the -nowarn flag.
<lang scala>// Kotlin JS version 1.1.4-3
<syntaxhighlight lang="scala">// Kotlin JS version 1.1.4-3


fun evalWithX(expr: String, a: Double, b: Double) {
fun evalWithX(expr: String, a: Double, b: Double) {
Line 645: Line 674:
fun main(args: Array<String>) {
fun main(args: Array<String>) {
println(evalWithX("Math.exp(x)", 0.0, 1.0))
println(evalWithX("Math.exp(x)", 0.0, 1.0))
}</lang>
}</syntaxhighlight>


{{out}}
{{out}}
Line 653: Line 682:


=={{header|Liberty BASIC}}==
=={{header|Liberty BASIC}}==
<syntaxhighlight lang="lb">
<lang lb>
expression$ = "x^2 - 7"
expression$ = "x^2 - 7"
Line 661: Line 690:
Function EvaluateWithX(expression$, x)
Function EvaluateWithX(expression$, x)
EvaluateWithX = Eval(expression$)
EvaluateWithX = Eval(expression$)
End Function </lang>
End Function </syntaxhighlight>


=={{header|Lua}}==
=={{header|Lua}}==
<lang lua>
<syntaxhighlight lang="lua">
code = loadstring"return x^2" --this doesn't really need to be input, does it?
code = loadstring"return x^2" --this doesn't really need to be input, does it?
val1 = setfenv(code, {x = io.read() + 0})()
val1 = setfenv(code, {x = io.read() + 0})()
val2 = setfenv(code, {x = io.read() + 0})()
val2 = setfenv(code, {x = io.read() + 0})()
print(val2 - val1)
print(val2 - val1)
</syntaxhighlight>
</lang>


In Lua 5.2 one can use the new <code>load</code> function to evaluate a string as Lua code and specify its environment:
In Lua 5.2 one can use the new <code>load</code> function to evaluate a string as Lua code and specify its environment:
Line 675: Line 704:
{{works with|Lua|5.2}}
{{works with|Lua|5.2}}


<lang lua>env = {}
<syntaxhighlight lang="lua">env = {}
f = load("return x", nil, nil, env)
f = load("return x", nil, nil, env)
env.x = tonumber(io.read()) -- user enters 2
env.x = tonumber(io.read()) -- user enters 2
Line 681: Line 710:
env.x = tonumber(io.read()) -- user enters 3
env.x = tonumber(io.read()) -- user enters 3
b = f()
b = f()
print(a + b) --> outputs 5</lang>
print(a + b) --> outputs 5</syntaxhighlight>


=={{header|Mathematica}}==
=={{header|Mathematica}}/{{header|Wolfram Language}}==
<lang Mathematica>Input source code is "10 x" , X is locally bound to 3 & 2 and the resulting expressions evaluated.
<syntaxhighlight lang="mathematica">Input source code is "10 x" , X is locally bound to 3 & 2 and the resulting expressions evaluated.
(10 x /. x -> 3 ) - (10 x /. x -> 2 )
(10 x /. x -> 3 ) - (10 x /. x -> 2 )
-> 10</lang>
-> 10</syntaxhighlight>


=={{header|MATLAB}} / {{header|Octave}}==
=={{header|MATLAB}} / {{header|Octave}}==
Line 692: Line 721:
In Octave, undeclared variables are local.
In Octave, undeclared variables are local.


<lang octave>function r = calcit(f, val1, val2)
<syntaxhighlight lang="octave">function r = calcit(f, val1, val2)
x = val1;
x = val1;
a = eval(f);
a = eval(f);
Line 698: Line 727:
b = eval(f);
b = eval(f);
r = b-a;
r = b-a;
end</lang>
end</syntaxhighlight>
Usage:
Usage:
<pre>p = 'x .* 2';
<pre>p = 'x .* 2';
Line 708: Line 737:
=={{header|Metafont}}==
=={{header|Metafont}}==


<lang metafont>vardef evalit(expr s, va, vb) =
<syntaxhighlight lang="metafont">vardef evalit(expr s, va, vb) =
save x,a,b; x := va; a := scantokens s;
save x,a,b; x := va; a := scantokens s;
x := vb; b := scantokens s; a-b
x := vb; b := scantokens s; a-b
Line 714: Line 743:


show(evalit("2x+1", 5, 3));
show(evalit("2x+1", 5, 3));
end</lang>
end</syntaxhighlight>


=={{header|Nim}}==
=={{header|Nim}}==
<lang nim>import macros, strformat
<syntaxhighlight lang="nim">import macros, strformat
macro eval(s, x: static[string]): untyped =
macro eval(s, x: static[string]): untyped =
parseStmt(&"let x={x}\n{s}")
parseStmt(&"let x={x}\n{s}")


echo(eval("x+1", "3.1"))</lang>
echo(eval("x+1", "3.1"))</syntaxhighlight>
{{out}}
Output:
<pre>
<pre>
4.1
4.1
Line 730: Line 759:
=={{header|ooRexx}}==
=={{header|ooRexx}}==
The ooRexx interpret instruction executes dynamically created ooRexx code in the current variable context.
The ooRexx interpret instruction executes dynamically created ooRexx code in the current variable context.
<syntaxhighlight lang="oorexx">
<lang ooRexx>
say evalWithX("x**2", 2)
say evalWithX("x**2", 2)
say evalWithX("x**2", 3.1415926)
say evalWithX("x**2", 3.1415926)
Line 739: Line 768:
-- X now has the value of the second argument
-- X now has the value of the second argument
interpret "return" expression
interpret "return" expression
</syntaxhighlight>
</lang>
Output:
Output:
<pre>
<pre>
Line 747: Line 776:


=={{header|Oz}}==
=={{header|Oz}}==
<lang oz>declare
<syntaxhighlight lang="oz">declare
fun {EvalWithX Program A B}
fun {EvalWithX Program A B}
{Compiler.evalExpression Program env('X':B) _}
{Compiler.evalExpression Program env('X':B) _}
Line 754: Line 783:
end
end
in
in
{Show {EvalWithX "{Exp X}" 0.0 1.0}}</lang>
{Show {EvalWithX "{Exp X}" 0.0 1.0}}</syntaxhighlight>


=={{header|PARI/GP}}==
=={{header|PARI/GP}}==
There are many ways of doing this depending on the particular interpretation of the requirements. This code assumes that <var>f</var> is a string representing a GP closure.
There are many ways of doing this depending on the particular interpretation of the requirements. This code assumes that <var>f</var> is a string representing a GP closure.
<lang parigp>test(f,a,b)=f=eval(f);f(a)-f(b);
<syntaxhighlight lang="parigp">test(f,a,b)=f=eval(f);f(a)-f(b);
test("x->print(x);x^2-sin(x)",1,3)</lang>
test("x->print(x);x^2-sin(x)",1,3)</syntaxhighlight>


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


<lang perl>sub eval_with_x
<syntaxhighlight lang="perl">sub eval_with_x
{my $code = shift;
{my $code = shift;
my $x = shift;
my $x = shift;
Line 770: Line 799:
return eval($code) - $first;}
return eval($code) - $first;}
print eval_with_x('3 * $x', 5, 10), "\n"; # Prints "15".</lang>
print eval_with_x('3 * $x', 5, 10), "\n"; # Prints "15".</syntaxhighlight>

=={{header|Phix}}==
See [[Runtime_evaluation#Phix]] for more details, or the docs.<br>
Evaluation occurs in a brand new context, and x must be explicitly provided/returned.
Note that nothing can escape the eval context: while x is not "global" here but could
trivially (/technically) be made one by prefixing its definition with "global", it would
still not escape the eval() context, and still have to be explicitly requested as a
return value, as per the second {"x"} parameter [aka rset] to eval().
<!--<syntaxhighlight lang="phix">(phixonline)-->
<span style="color: #008080;">without</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #7060A8;">requires</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"1.0.1"</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">include</span> <span style="color: #7060A8;">eval</span><span style="color: #0000FF;">.</span><span style="color: #000000;">e</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">eval_with_x</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">expr</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">integer</span> <span style="color: #000000;">a</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">b</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">return</span> <span style="color: #7060A8;">eval</span><span style="color: #0000FF;">(</span><span style="color: #000000;">expr</span><span style="color: #0000FF;">,{</span><span style="color: #008000;">"x"</span><span style="color: #0000FF;">},{{</span><span style="color: #008000;">"x"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">b</span><span style="color: #0000FF;">}})[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">-</span>
<span style="color: #7060A8;">eval</span><span style="color: #0000FF;">(</span><span style="color: #000000;">expr</span><span style="color: #0000FF;">,{</span><span style="color: #008000;">"x"</span><span style="color: #0000FF;">},{{</span><span style="color: #008000;">"x"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">a</span><span style="color: #0000FF;">}})[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #0000FF;">?</span><span style="color: #000000;">eval_with_x</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"integer x = power(2,x)"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">3</span><span style="color: #0000FF;">,</span><span style="color: #000000;">5</span><span style="color: #0000FF;">)</span>
<!--</syntaxhighlight>-->
{{out}}
(As in 2<small><sup>5</sup></small> - 2<small><sup>3</sup></small> === 32 - 8 === 24)
<pre>
24
</pre>


=={{header|PHP}}==
=={{header|PHP}}==


<lang php><?php
<syntaxhighlight lang="php"><?php
function eval_with_x($code, $a, $b) {
function eval_with_x($code, $a, $b) {
$x = $a;
$x = $a;
Line 784: Line 838:
echo eval_with_x('return 3 * $x;', 5, 10), "\n"; # Prints "15".
echo eval_with_x('return 3 * $x;', 5, 10), "\n"; # Prints "15".
?></lang>
?></syntaxhighlight>


=={{header|PicoLisp}}==
=={{header|PicoLisp}}==
<lang PicoLisp>(let Expression '(+ X (* X X)) # Local expression
<syntaxhighlight lang="picolisp">(let Expression '(+ X (* X X)) # Local expression
(println
(println
(+
(+
Line 798: Line 852:
(+
(+
(Function 3)
(Function 3)
(Function 4) ) ) ) )</lang>
(Function 4) ) ) ) )</syntaxhighlight>
Output:
Output:
<pre>32
<pre>32
Line 805: Line 859:
=={{header|Pike}}==
=={{header|Pike}}==
Pike can only compile complete classes. therefore binding a value to a variable is only possible by string manipulation. even Pikes own interactive mode which seemingly evaluates expressions wraps them into a class and replaces variable references before compiling:
Pike can only compile complete classes. therefore binding a value to a variable is only possible by string manipulation. even Pikes own interactive mode which seemingly evaluates expressions wraps them into a class and replaces variable references before compiling:
<lang Pike>> int x=10;
<syntaxhighlight lang="pike">> int x=10;
Result: 10
Result: 10
> x * 5;
> x * 5;
Line 815: Line 869:
003: mixed ___HilfeWrapper() { return (([mapping(string:int)](mixed)___hilfe)->x) * 5; ; }
003: mixed ___HilfeWrapper() { return (([mapping(string:int)](mixed)___hilfe)->x) * 5; ; }
004:
004:
></lang>
></syntaxhighlight>
___Hilfe is an object which stores all created variables;
___Hilfe is an object which stores all created variables;


to solve the problem in the task i would create a function that can take arguments:
to solve the problem in the task i would create a function that can take arguments:
<lang Pike>string payload = "x * 5";
<syntaxhighlight lang="pike">string payload = "x * 5";


program demo = compile_string("string eval(mixed x){ " + payload + "; }");
program demo = compile_string("string eval(mixed x){ " + payload + "; }");
Line 826: Line 880:
Result: 50
Result: 50
demo()->eval(20);
demo()->eval(20);
Result: 100</lang>
Result: 100</syntaxhighlight>


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


<lang python>>>> def eval_with_x(code, a, b):
<syntaxhighlight lang="python">>>> def eval_with_x(code, a, b):
return eval(code, {'x':b}) - eval(code, {'x':a})
return eval(code, {'x':b}) - eval(code, {'x':a})


>>> eval_with_x('2 ** x', 3, 5)
>>> eval_with_x('2 ** x', 3, 5)
24</lang>
24</syntaxhighlight>


A slight change allows the evaluation to take multiple names:
A slight change allows the evaluation to take multiple names:
<lang python>>>> def eval_with_args(code, **kwordargs):
<syntaxhighlight lang="python">>>> def eval_with_args(code, **kwordargs):
return eval(code, kwordargs)
return eval(code, kwordargs)


Line 845: Line 899:
>>> code = '3 * x + y'
>>> code = '3 * x + y'
>>> eval_with_args(code, x=5, y=2) - eval_with_args(code, x=3, y=1)
>>> eval_with_args(code, x=5, y=2) - eval_with_args(code, x=3, y=1)
7</lang>
7</syntaxhighlight>


=={{header|R}}==
=={{header|R}}==
We can set up thing so that the "unbound" variable can be any accepted symbol for variables.
We can set up thing so that the "unbound" variable can be any accepted symbol for variables.
<lang R>evalWithAB <- function(expr, var, a, b) {
<syntaxhighlight lang="r">evalWithAB <- function(expr, var, a, b) {
env <- new.env() # provide a separate env, so that the choosen
env <- new.env() # provide a separate env, so that the choosen
assign(var, a, envir=env) # var name do not collide with symbols inside
assign(var, a, envir=env) # var name do not collide with symbols inside
Line 863: Line 917:
print(evalWithAB("2*x+1", "x", 5, 3))
print(evalWithAB("2*x+1", "x", 5, 3))
print(evalWithAB("2*y+1", "y", 5, 3))
print(evalWithAB("2*y+1", "y", 5, 3))
print(evalWithAB("2*y+1", "x", 5, 3)) # error: object "y" not found</lang>
print(evalWithAB("2*y+1", "x", 5, 3)) # error: object "y" not found</syntaxhighlight>


=={{header|Racket}}==
=={{header|Racket}}==


Same hack as the on in the CL/Scheme entries:
Same hack as the on in the CL/Scheme entries:
<syntaxhighlight lang="racket">
<lang Racket>
#lang racket
#lang racket
(define ns (make-base-namespace))
(define ns (make-base-namespace))
Line 874: Line 928:
(define (with v) (eval `(let ([x ',v]) ,code) ns))
(define (with v) (eval `(let ([x ',v]) ,code) ns))
(- (with b) (with a)))
(- (with b) (with a)))
</syntaxhighlight>
</lang>


Better: a more direct use of eval with just the code (for example, this
Better: a more direct use of eval with just the code (for example, this
won't break if we use a namespace with a different meaning for
won't break if we use a namespace with a different meaning for
<tt>let</tt>, which is very possible in Racket):
<tt>let</tt>, which is very possible in Racket):
<syntaxhighlight lang="racket">
<lang Racket>
#lang racket
#lang racket
(define ns (make-base-namespace))
(define ns (make-base-namespace))
Line 887: Line 941:
(eval code ns))
(eval code ns))
(- (with b) (with a)))
(- (with b) (with a)))
</syntaxhighlight>
</lang>


=={{header|Raku}}==
=={{header|Raku}}==
Line 893: Line 947:
{{Works with|rakudo|2015-12-22}}
{{Works with|rakudo|2015-12-22}}
For security, you must explicitly allow use of 'EVAL'.
For security, you must explicitly allow use of 'EVAL'.
<lang perl6>use MONKEY-SEE-NO-EVAL;
<syntaxhighlight lang="raku" line>use MONKEY-SEE-NO-EVAL;
sub eval_with_x($code, *@x) { [R-] @x.map: -> \x { EVAL $code } }
sub eval_with_x($code, *@x) { [R-] @x.map: -> \x { EVAL $code } }


say eval_with_x('3 * x', 5, 10); # Says "15".
say eval_with_x('3 * x', 5, 10); # Says "15".
say eval_with_x('3 * x', 5, 10, 50); # Says "105".</lang>
say eval_with_x('3 * x', 5, 10, 50); # Says "105".</syntaxhighlight>


=={{header|REBOL}}==
=={{header|REBOL}}==
<lang rebol>prog: [x * 2]
<syntaxhighlight lang="rebol">prog: [x * 2]
fn: func [x] [do bind prog 'x]
fn: func [x] [do bind prog 'x]
a: fn 2
a: fn 2
b: fn 4
b: fn 4
subtract b a</lang>
subtract b a</syntaxhighlight>


Result:
Result:
Line 912: Line 966:


=={{header|REXX}}==
=={{header|REXX}}==
<lang rexx>/*REXX program demonstrates a run─time evaluation of an expression (entered at run─time)*/
<syntaxhighlight lang="rexx">/*REXX program demonstrates a run─time evaluation of an expression (entered at run─time)*/
say '──────── enter the 1st expression to be evaluated:'
say '──────── enter the 1st expression to be evaluated:'


Line 935: Line 989:


drop x /*X var. is no longer a global variable*/
drop x /*X var. is no longer a global variable*/
exit 0 /*stick a fork in it, we're all done. */</lang>
exit 0 /*stick a fork in it, we're all done. */</syntaxhighlight>
{{out|output|text=&nbsp;}}
{{out|output|text=&nbsp;}}
<pre>
<pre>
Line 951: Line 1,005:


=={{header|Ring}}==
=={{header|Ring}}==
<lang ring>
<syntaxhighlight lang="ring">
expression = "return pow(x,2) - 7"
expression = "return pow(x,2) - 7"
one = evalwithx(expression, 1.2)
one = evalwithx(expression, 1.2)
Line 959: Line 1,013:
func evalwithx expr, x
func evalwithx expr, x
return eval(expr)
return eval(expr)
</syntaxhighlight>
</lang>
Output:
Output:
<pre>
<pre>
one = -5.56
one = -5.56
two = 4.56
two = 4.56
</pre>

=={{header|RPL}}==
A first way to answer the task is to use the possibility of passing local variables from one program to another, the calling program being in charge of achieving the binding of values to the x variable.
≪ 2 x ^ ≫ 'POWR2' STO
≪ → x ≪ POWR2 SWAP ≫ → x ≪ POWR2 SWAP - ≫ ≫ 'DIFFP' STO
{{in}}
<pre>
5 3 DIFFP
</pre>
{{out}}
<pre>
1: 24
</pre>
Another solution is to let the algebraic interpreter do the binding:
≪ → x ≪ 2 x ^ ≫ ≫ 'POWR2' STO
{{in}}
<pre>
'POWR2(5)-POWR2(3)' EVAL
</pre>
{{out}}
<pre>
1: 24
</pre>
</pre>


=={{header|Ruby}}==
=={{header|Ruby}}==
<lang ruby>def bind_x_to_value(x)
<syntaxhighlight lang="ruby">def bind_x_to_value(x)
binding
binding
end
end
Line 975: Line 1,053:
end
end


puts eval_with_x('2 ** x', 3, 5) # Prints "24"</lang>
puts eval_with_x('2 ** x', 3, 5) # Prints "24"</syntaxhighlight>


The magic here is how the <code>binding</code> method works with the <code>bind_x_to_value(x)</code> method.
The magic here is how the <code>binding</code> method works with the <code>bind_x_to_value(x)</code> method.
Line 983: Line 1,061:


=={{header|Scala}}==
=={{header|Scala}}==
<lang Scala>object Eval extends App {
<syntaxhighlight lang="scala">object Eval extends App {


def evalWithX(expr: String, a: Double, b: Double)=
def evalWithX(expr: String, a: Double, b: Double)=
Line 990: Line 1,068:
println(evalWithX("Math.exp(x)", 0.0, 1.0))
println(evalWithX("Math.exp(x)", 0.0, 1.0))


}</lang>
}</syntaxhighlight>


=={{header|Scheme}}==
=={{header|Scheme}}==
Almost identical to the [[Common Lisp]] version above.
Almost identical to the [[Common Lisp]] version above.
<lang scheme>(define (eval-with-x prog a b)
<syntaxhighlight lang="scheme">(define (eval-with-x prog a b)
(let ((at-a (eval `(let ((x ',a)) ,prog)))
(let ((at-a (eval `(let ((x ',a)) ,prog)))
(at-b (eval `(let ((x ',b)) ,prog))))
(at-b (eval `(let ((x ',b)) ,prog))))
(- at-b at-a)))</lang>
(- at-b at-a)))</syntaxhighlight>


=={{header|Sidef}}==
=={{header|Sidef}}==
<lang ruby>func eval_with_x(code, x, y) {
<syntaxhighlight lang="ruby">func eval_with_x(code, x, y) {
var f = eval(code);
var f = eval(code);
x = y;
x = y;
Line 1,006: Line 1,084:
}
}


say eval_with_x(x: 3, y: 5, code: '2 ** x'); # => 24</lang>
say eval_with_x(x: 3, y: 5, code: '2 ** x'); # => 24</syntaxhighlight>


=={{header|Simula}}==
=={{header|Simula}}==
<lang simula>BEGIN
<syntaxhighlight lang="simula">BEGIN


CLASS ENV;
CLASS ENV;
Line 1,273: Line 1,351:


END.
END.
</syntaxhighlight>
</lang>
{{out}}
{{out}}
<pre>
<pre>
Line 1,282: Line 1,360:
This program defines (at runtime) a function triple(), compiles it, and then executes it twice, with values x = 1 and then x = 3. The program subtracts the returned value from the first call from the value returned from the first call, and prints the result. In this example, the value x is passed as a parameter to the function triple().
This program defines (at runtime) a function triple(), compiles it, and then executes it twice, with values x = 1 and then x = 3. The program subtracts the returned value from the first call from the value returned from the first call, and prints the result. In this example, the value x is passed as a parameter to the function triple().


<lang SNOBOL4> compiled = code(' define("triple(x)") :(a);triple triple = 3 * x :(return)') :<compiled>
<syntaxhighlight lang="snobol4"> compiled = code(' define("triple(x)") :(a);triple triple = 3 * x :(return)') :<compiled>
a x = 1
a x = 1
first = triple(x)
first = triple(x)
x = 3
x = 3
output = triple(x) - first
output = triple(x) - first
end</lang>
end</syntaxhighlight>


Output:
Output:
Line 1,294: Line 1,372:
If you specifically wanted to not pass x as a parameter but instead use it as a value from the environment, that's easy too:
If you specifically wanted to not pass x as a parameter but instead use it as a value from the environment, that's easy too:


<lang SNOBOL4> compiled = code(' define("triple()") :(a);triple triple = 3 * x :(return)') :<compiled>
<syntaxhighlight lang="snobol4"> compiled = code(' define("triple()") :(a);triple triple = 3 * x :(return)') :<compiled>
a x = 1
a x = 1
first = triple(x)
first = triple(x)
x = 3
x = 3
output = triple(x) - first
output = triple(x) - first
end</lang>
end</syntaxhighlight>


The output is the same.
The output is the same.


=={{header|Tcl}}==
=={{header|Tcl}}==
<lang tcl>proc eval_twice {func a b} {
<syntaxhighlight lang="tcl">proc eval_twice {func a b} {
set x $a
set x $a
set 1st [expr $func]
set 1st [expr $func]
Line 1,312: Line 1,390:
}
}


puts [eval_twice {2 ** $x} 3 5] ;# ==> 24</lang>
puts [eval_twice {2 ** $x} 3 5] ;# ==> 24</syntaxhighlight>


Here's another take, similar to other answers. It passes a code block to be <code>eval</code>ed, not just an expression for <code>expr</code>
Here's another take, similar to other answers. It passes a code block to be <code>eval</code>ed, not just an expression for <code>expr</code>
<lang tcl>proc eval_with_x {code val1 val2} {
<syntaxhighlight lang="tcl">proc eval_with_x {code val1 val2} {
expr {[set x $val2; eval $code] - [set x $val1; eval $code]}
expr {[set x $val2; eval $code] - [set x $val1; eval $code]}
}
}
eval_with_x {expr {2**$x}} 3 5 ;# ==> 24</lang>
eval_with_x {expr {2**$x}} 3 5 ;# ==> 24</syntaxhighlight>


In 8.5, <tt>apply</tt> makes environments like this "first class":
In 8.5, <tt>apply</tt> makes environments like this "first class":


{{works with|Tcl|8.5}}
{{works with|Tcl|8.5}}
<lang tcl>package require Tcl 8.5
<syntaxhighlight lang="tcl">package require Tcl 8.5
proc eval_with {body a b} {
proc eval_with {body a b} {
set lambda [list x $body]
set lambda [list x $body]
Line 1,329: Line 1,407:
}
}


eval_with {expr {2**$x}} 3 5 ;# ==> 24</lang>
eval_with {expr {2**$x}} 3 5 ;# ==> 24</syntaxhighlight>


=={{header|TI-89 BASIC}}==
=={{header|TI-89 BASIC}}==


<lang ti89b>evalx(prog, a, b)
<syntaxhighlight lang="ti89b">evalx(prog, a, b)
Func
Func
Local x,eresult1,eresult2
Local x,eresult1,eresult2
Line 1,344: Line 1,422:


■ evalx("ℯ^x", 0., 1)
■ evalx("ℯ^x", 0., 1)
1.71828</lang>
1.71828</syntaxhighlight>


There are no facilities for control over the environment; expr() evaluates in the same environment as the caller, including local variables. [Someone please verify this statement.] [[Category:TI-89 BASIC examples needing attention]]
There are no facilities for control over the environment; expr() evaluates in the same environment as the caller, including local variables. [Someone please verify this statement.] [[Category:TI-89 BASIC examples needing attention]]

=={{header|Transd}}==
The <code>(eval)</code> function returns a pair, where the first element is boolean flag indicating success of running the code, and the second element is a string containing the output of code execution.

<syntaxhighlight lang="scheme">#lang transd

MainModule: {
code: "(+ 5 x)",

_start: (lambda (textout
(- (to-Int (with x 100 (snd (eval code))))
(to-Int (with x 1 (snd (eval code)))))
))
}</syntaxhighlight>
{{out}}
<pre>
99
</pre>


=={{header|TXR}}==
=={{header|TXR}}==
Line 1,354: Line 1,450:
In TXR's embedded Lisp dialect, we can implement the same solution as Lisp or Scheme: transform the code fragment by wrapping a <code>let</code> around it which binds a variable, and then evaluating the whole thing:
In TXR's embedded Lisp dialect, we can implement the same solution as Lisp or Scheme: transform the code fragment by wrapping a <code>let</code> around it which binds a variable, and then evaluating the whole thing:


<lang txrlisp>(defun eval-subtract-for-two-values-of-x (code-fragment x1 x0)
<syntaxhighlight lang="txrlisp">(defun eval-subtract-for-two-values-of-x (code-fragment x1 x0)
(- (eval ^(let ((x ,x1)) ,code-fragment))
(- (eval ^(let ((x ,x1)) ,code-fragment))
(eval ^(let ((x ,x0)) ,code-fragment))))
(eval ^(let ((x ,x0)) ,code-fragment))))


(eval-subtract-for-two-values-of-x 1 2) ;; yields -4.67077427047161</lang>
(eval-subtract-for-two-values-of-x 1 2) ;; yields -4.67077427047161</syntaxhighlight>


Cutting edge TXR code provides access to the environment manipulation functions, making this possible:
Cutting edge TXR code provides access to the environment manipulation functions, making this possible:


<lang txrlisp>(defun eval-subtract-for-two-values-of-x (code-fragment x1 x0)
<syntaxhighlight lang="txrlisp">(defun eval-subtract-for-two-values-of-x (code-fragment x1 x0)
(let ((e1 (make-env (list (cons 'x x1)))) ;; create two environments stuffed with binding for x
(let ((e1 (make-env (list (cons 'x x1)))) ;; create two environments stuffed with binding for x
(e0 (make-env (list (cons 'x x0)))))
(e0 (make-env (list (cons 'x x0)))))
Line 1,368: Line 1,464:
(eval code-fragment e0))))
(eval code-fragment e0))))
(eval-subtract-for-two-values-of-x '(exp x) 1 2)</lang>
(eval-subtract-for-two-values-of-x '(exp x) 1 2)</syntaxhighlight>


Alternatively, empty environments can be made and extended with bindings:
Alternatively, empty environments can be made and extended with bindings:


<lang txrlisp>(defun eval-subtract-for-two-values-of-x (code-fragment x1 x0)
<syntaxhighlight lang="txrlisp">(defun eval-subtract-for-two-values-of-x (code-fragment x1 x0)
(let ((e1 (make-env))
(let ((e1 (make-env))
(e0 (make-env)))
(e0 (make-env)))
Line 1,380: Line 1,476:
(eval code-fragment e0))))
(eval code-fragment e0))))
(eval-subtract-for-two-values-of-x '(exp x) 1 2)</lang>
(eval-subtract-for-two-values-of-x '(exp x) 1 2)</syntaxhighlight>


Explicit environment manipulation has the disadvantage of being hostile against compiling. (See notes about compilation in the Common Lisp example.)
Explicit environment manipulation has the disadvantage of being hostile against compiling. (See notes about compilation in the Common Lisp example.)
Line 1,392: Line 1,488:
However, our two <code>let</code> constructs carefully save and restore the dynamic environment (and therefore any prior value of <code>x</code>), even in the face of exceptions, and
However, our two <code>let</code> constructs carefully save and restore the dynamic environment (and therefore any prior value of <code>x</code>), even in the face of exceptions, and


<lang txrlisp>(defvar x)
<syntaxhighlight lang="txrlisp">(defvar x)


(defun eval-subtract-for-two-values-of-x (code-fragment x1 x0)
(defun eval-subtract-for-two-values-of-x (code-fragment x1 x0)
Line 1,398: Line 1,494:
(let ((x x0)) (eval code-fragment))))
(let ((x x0)) (eval code-fragment))))


(eval-subtract-for-two-values-of-x '(exp x) 1 2)</lang>
(eval-subtract-for-two-values-of-x '(exp x) 1 2)</syntaxhighlight>


=={{header|UNIX Shell}}==
=={{header|UNIX Shell}}==
The backquotes <tt>` ... `</tt> capture the standard output of a subshell. Changes to parameter ''x'' in the subshell will not affect its parent shell.
The backquotes <tt>` ... `</tt> capture the standard output of a subshell. Changes to parameter ''x'' in the subshell will not affect its parent shell.


<lang bash>eval_with_x() {
<syntaxhighlight lang="bash">eval_with_x() {
set -- "`x=$2; eval "$1"`" "`x=$3; eval "$1"`"
set -- "`x=$2; eval "$1"`" "`x=$3; eval "$1"`"
expr "$2" - "$1"
expr "$2" - "$1"
Line 1,417: Line 1,513:
echo $p
echo $p
' 3 5
' 3 5
# Prints '24'</lang>
# Prints '24'</syntaxhighlight>


=={{header|Wren}}==
=={{header|Wren}}==
Wren has an undocumented method called ''Meta.eval'' which can do runtime evaluation.
Wren has a library method called ''Meta.eval'' which can do runtime evaluation.


However, it only appears to work with module level variables.
However, it only appears to work with module level variables.
<lang ecmascript>import "meta" for Meta
<syntaxhighlight lang="wren">import "meta" for Meta


var x
var x
Line 1,434: Line 1,530:


Meta.eval("x = x - y")
Meta.eval("x = x - y")
System.print("Delta x = %(x)")</lang>
System.print("Delta x = %(x)")</syntaxhighlight>


{{out}}
{{out}}
Line 1,444: Line 1,540:


=={{header|zkl}}==
=={{header|zkl}}==
<lang zkl>fcn evalWithX(text,x) {
<syntaxhighlight lang="zkl">fcn evalWithX(text,x) {
f:=Compiler.Compiler.compileText(text);
f:=Compiler.Compiler.compileText(text);
f.x = x; // set free var in compiled blob
f.x = x; // set free var in compiled blob
Line 1,451: Line 1,547:
}
}
const TEXT="var x; x*2"; // variables need to be declared
const TEXT="var x; x*2"; // variables need to be declared
evalWithX(TEXT,5) - evalWithX(TEXT,3) #--> 4</lang>
evalWithX(TEXT,5) - evalWithX(TEXT,3) #--> 4</syntaxhighlight>
This is not a complete solution but close.
This is not a complete solution but close.


Another way to do this is to create a class on the fly that contains the code to be run and reusing that class. The class just acts like as a container for x and a function:
Another way to do this is to create a class on the fly that contains the code to be run and reusing that class. The class just acts like as a container for x and a function:
<lang zkl>var klass=Compiler.Compiler.compileText("var x; returnClass(x*2)");
<syntaxhighlight lang="zkl">var klass=Compiler.Compiler.compileText("var x; returnClass(x*2)");
(klass.__constructor(klass.x=5) - klass.__constructor(klass.x=3)).println();</lang>
(klass.__constructor(klass.x=5) - klass.__constructor(klass.x=3)).println();</syntaxhighlight>
returnClass(x) is required in a constructor if you want to return something other than self. klass.x=y pokes y into the instance variable x. Running the constructor runs x*2.
returnClass(x) is required in a constructor if you want to return something other than self. klass.x=y pokes y into the instance variable x. Running the constructor runs x*2.
{{out}}<pre>4</pre>
{{out}}<pre>4</pre>
Line 1,467: Line 1,563:
{{omit from|GUISS|Does not have variables}}
{{omit from|GUISS|Does not have variables}}
{{omit from|Lily}}
{{omit from|Lily}}
{{omit from|Insitux}}

Latest revision as of 18:32, 21 April 2024

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 (as a string or AST) with a free variable named x (or another name if that is not valid syntax), evaluate it with x 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.


Do so in a way which:

  • does not involve string manipulation of the input source code
  • is plausibly extensible to a runtime-chosen set of bindings rather than just x
  • does not make x a global variable


or note that these are impossible.


See also



ALGOL 68

Works with: ALGOL 68G version Any - tested with release mk15-0.8b.fc9.i386 - this implementation is an interpretor, and evaluate is an extension to the standard

Variable names are generally not visible at run time with classic compilers. However ALGOL 68G is an interpretor and it retains this ability. Note that evaluate returns a string.

PROC eval_with_x = (STRING code, INT a, b)STRING:
	(INT x=a; evaluate(code) ) + (INT x=b; evaluate(code));
print((eval_with_x("2 ** x", 3, 5), new line))

Output:

         +8        +32

AppleScript

AppleScript's run script command allows to interpret and execute the string passed to it as an arbitrarily complex (or simple) script; such a string may thus be viewed as the "program" considered in the task description.
Each invocation of the run script command dynamically happens in a separate execution context, so there are no side-effects; on the other hand, this means that such an invocation is quite costly.
Arguments may be passed as a list of arbitrary values; this however requires the program to be written with an explicit run handler.
The result is the value (if any) returned by the program; any valid AppleScript value may be returned.

Given the above, the task may easily be implemented along these lines:

on task_with_x(pgrm, x1, x2)
	local rslt1, rslt2
	set rslt1 to run script pgrm with parameters {x1}
	set rslt2 to run script pgrm with parameters {x2}
	rslt2 - rslt1
end task_with_x

Example usage (for legibility purposes, the program is stored into an intermediate variable):

set pgrm_with_x to "
on run {x}
	2^x
end"

task_with_x(pgrm_with_x, 3, 5)

The result is 24.0 (a real number).

Arturo

code: [x * 2]
fn: function [x]-> 
    do with 'x code

a: fn 2
b: fn 4

print b - a
Output:
4

AutoHotkey

Works with: AutoHotkey_H

AutoHotkey does not provide an API to the local symbol table. Local variables are also not supported within scopes outside functions. However, a local environment can be simulated by wrapping code in a temporary function.

msgbox % first := evalWithX("x + 4", 5)
msgbox % second := evalWithX("x + 4", 6)
msgbox % second - first
return

evalWithX(expression, xvalue)
{
global script
script = 
(
    expression(){
    x = %xvalue%  ; := would need quotes
    return %expression%
  }
)
renameFunction("expression", "")  ; remove any previous expressions
gosub load ; cannot use addScript inside a function yet
exp := "expression"
return %exp%()
}

load:
DllCall(A_AhkPath "\addScript","Str",script,"Uchar",0,"Cdecl UInt")
return

renameFunction(funcName, newname){
static         
x%newname% := newname   ; store newname in a static variable so its memory is not freed
strput(newname, &x%newname%, strlen(newname) + 1)
if fnp := FindFunc(funcName)
  numput(&x%newname%, fnp+0, 0, "uint")
}

BBC BASIC

      expression$ = "x^2 - 7"
      one = FN_eval_with_x(expression$, 1.2)
      two = FN_eval_with_x(expression$, 3.4)
      PRINT two - one
      END
      
      DEF FN_eval_with_x(expr$, x)
      = EVAL(expr$)

Bracmat

( ( eval-with-x
  =   code a b argument
    .   !arg:((=?code),?a,?b,?argument)
      &   (!b:?x&!code$!argument)
        + -1*(!a:?x&!code$!argument)
  )
& out$(eval-with-x$((='(.$x^!arg)),3,5,2))
& out$(eval-with-x$((='(.$x^!arg)),12,13,2))
);

Output:

16
25

Clojure

We must define x as global, but we use dynamic bindings. Only functions within the binding will see the newly bound value of x, before it re-establishes the bindings that existed before.

(def ^:dynamic x nil)

(defn eval-with-x [program a b]
  (- (binding [x b] (eval program))
     (binding [x a] (eval program))))
(eval-with-x '(* x x) 4 9)
=> 65

Here's another version which avoids the global by compiling a local function with a single argument x (the ~'x is how to avoid automatic namespace qualification of symbols in a syntax quote):

(defn eval-with-x [program a b]
  (let [func (eval `(fn [~'x] ~program))]
    (- (func b) (func a))))
(eval-with-x '(* x x) 4 9)
=> 65

Common 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)))
(eval-with-x '(exp x) 0 1)
=> 1.7182817

This version ensures that the program is compiled, once, for more efficient execution:

(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)))

Déjà Vu

local fib n:
	if <= n 1:
		n
	else:
		+ fib - n 1 fib - n 2

local :code !compile-string dup "-- fib x" #one less than the xth fibonacci number

!run-blob-in { :fib @fib :x 4 } code
!run-blob-in { :fib @fib :x 6 } code
!. -
Output:
5

E

# Constructing an environment has to be done by way of evaluation
#for historical reasons which will hopefully be entirely eliminated soon.
def bindX(value) {
  def [resolver, env] := e`    # bind x and capture its resolver and the
    def x                      # resulting environment
  `.evalToPair(safeScope)
  resolver.resolve(value)      # set the value
  return env
}

def evalWithX(program, a, b) {
  def atA := program.eval(bindX(a))
  def atB := program.eval(bindX(b))
  return atB - atA
}
? evalWithX(e`(x :float64).exp()`, 0, 1)
# value: 1.7182818284590455

EchoLisp

We evaluate prog in a new environment which is an association list ((x x-value)), and could be ((x x-value) (y y-value)....)

(define (eval-with-x prog x)
    (eval prog (environment-new (list (list 'x x)))))

(define prog '( + 1 (* x x)))

(eval-with-x prog 10)  101
(eval-with-x prog 1000)  1000001
(- (eval-with-x prog 1000) (eval-with-x prog 10))  999900

;; check x is unbound (no global)
x
😖️ error: #|user| : unbound variable : x

Elena

ELENA 6.x:

Using VM console client:

import extensions;
import extensions'scripting;

public program()
{
    var text := program_arguments[1];
    var arg := program_arguments[2];
    
    var program := lscript.interpretLine(text);
    console.printLine(
        text,",",arg," = ",program.eval(arg.toReal()));
}
Output:
eval.exe "{ eval(x) { ^extensions'math'power(x,2); }}" 2
ELENA VM 5.0.4 (C)2005-2020 by Alex Rakov
Initializing...
Done...
{ eval(x) { ^extensions'math'power(x,2); }},2 = 4.0

Erlang

Functions below are used by dynamic variable names. Any changes here needs to be backwards compatible, or dynamic variable names must also be changed.

-module( runtime_evaluation ).

-export( [evaluate_form/2, form_from_string/1, task/0] ).

evaluate_form( Form, {Variable_name, Value} ) ->
	Bindings = erl_eval:add_binding( Variable_name, Value, erl_eval:new_bindings() ),
	{value, Evaluation, _} = erl_eval:expr( Form, Bindings ),
	Evaluation.

form_from_string( String ) ->
	{ok, Tokens, _} = erl_scan:string( String ),
	{ok, [Form]} = erl_parse:parse_exprs( Tokens ),
	Form.

task() ->
	Form = form_from_string( "X." ),
	Variable1 = evaluate_form( Form, {'X', 1} ),
	io:fwrite( "~p~n", [Variable1] ),
	Variable2 = evaluate_form( Form, {'X', 2} ),
	io:fwrite( "~p~n", [Variable2] ),
	io:fwrite( "~p~n", [Variable2 - Variable1] ).
Output:
14> runtime_evaluation:task().
1
2
1

Factor

Being a stack-based language, there is usually no need to bind data stack objects to a variable name. This is the idiomatic way to do it, with eval referencing what it needs from the data stack:

USE: eval
: eval-bi@- ( a b program -- n )
    tuck [ ( y -- z ) eval ] 2bi@ - ;
IN: scratchpad 9 4 "dup *" eval-bi@- .
65

Also note that, since programs are first-class denizens in Factor, the use cases for eval are few. Normally, you would pass in a program as a quotation:

: bi@- ( a b quot -- n ) bi@ - ; inline
IN: scratchpad 9 4 [ dup * ] bi@- .
65

However, we can adhere to the letter of the task. Although we are using a dynamic variable for x, it exists in a temporary, non-global namespace. As far as I can tell, eval is unaware of surrounding lexical scope.

SYMBOL: x
: eval-with-x ( a b program -- n )
    tuck
    [ [ x ] dip [ ( -- y ) eval ] curry with-variable ] 2bi@ - ;
IN: scratchpad 9 4 "x get dup *" eval-with-x .
65
IN: scratchpad x get .
f

Forth

EVALUATE invokes the Forth interpreter on the given string.

: f-" ( a b snippet" -- )
  [char] " parse   ( code len )
  2dup 2>r evaluate
  swap 2r> evaluate
  - . ;

2 3 f-" dup *"   \ 5  (3*3 - 2*2)

This can be used to treat a data stream as code, or to provide a lightweight macro facility when used in an IMMEDIATE word.

: :macro ( "name <char> ccc<char>" -- )
  : [CHAR] ; PARSE  POSTPONE SLITERAL  POSTPONE EVALUATE
  POSTPONE ; IMMEDIATE
;

:macro times   0 do ;

: test  8 times ." spam " loop ;

see test
: test  
  8 0 
  DO     .\" spam " 
  LOOP
  ; ok

FreeBASIC

#include "solver.bi"

Dim As String expression = "(x ^ 2 )-7"

setVar("x",1.2)
Print "one = ";Solver(expression)
setVar("x",3.4)
Print "two = ";Solver(expression)

Sleep
Output:
one = -5.560000000000001
two =  4.559999999999999

Genyris

One way is to use a macro. In genyris, macros are lazy functions which execute twice, the return value is also evaluated in the caller's environment:

defmacro add100() (+ x 100)

var x 23
var firstresult (add100)
x = 1000
print
    + firstresult (add100)

This prints 1223.

Another way is to use dynamically scoped variables. In Genyris, symbols prefixed with a period are looked up in the caller's environment, not the lexical environment of the closure. When a dictionary is the first element of the expression, an environment is created and the &rest is evaluated.

def add100() (+ .x 100)

(dict)                 # create an environment capable of holding dynamic bindings
   var .x 23           # create a binding in the dictionary
   var firstresult (add100)
   .x = 1000
   print 
       + firstresult (add100)

Dictionaries can hold bindings to dynamic symbols. To minimize the danger of dynamic scope there is no recursive ascent in the binding lookup.

(dict)                 
   var .x 23           
   (dict)
       print .x # fails

Go

package main

import (
    "bitbucket.org/binet/go-eval/pkg/eval"
    "fmt"
    "go/parser"
    "go/token"
)

func main() {
    // an expression on x
    squareExpr := "x*x"

    // parse to abstract syntax tree
    fset := token.NewFileSet()
    squareAst, err := parser.ParseExpr(squareExpr)
    if err != nil {
        fmt.Println(err)
        return
    }
    // create an environment or "world"
    w := eval.NewWorld()

    // allocate a variable
    wVar := new(intV)

    // bind the variable to the name x
    err = w.DefineVar("x", eval.IntType, wVar)
    if err != nil {
        fmt.Println(err)
        return
    }
    // bind the expression AST to the world
    squareCode, err := w.CompileExpr(fset, squareAst)
    if err != nil {
        fmt.Println(err)
        return
    }
    // directly manipulate value of variable within world
    *wVar = 5
    // evaluate
    r0, err := squareCode.Run()
    if err != nil {
        fmt.Println(err)
        return
    }
    // change value
    *wVar--
    // revaluate
    r1, err := squareCode.Run()
    if err != nil {
        fmt.Println(err)
        return
    }
    // print difference
    fmt.Println(r0.(eval.IntValue).Get(nil) - r1.(eval.IntValue).Get(nil))
}

// int value implementation.
type intV int64

func (v *intV) String() string              { return fmt.Sprint(*v) }
func (v *intV) Get(*eval.Thread) int64      { return int64(*v) }
func (v *intV) Set(_ *eval.Thread, x int64) { *v = intV(x) }
func (v *intV) Assign(t *eval.Thread, o eval.Value) {
    *v = intV(o.(eval.IntValue).Get(t))
}

Output:

9

Groovy

The solution:

def cruncher = { x1, x2, program ->
   Eval.x(x1, program) - Eval.x(x2, program)
}

Test Program:

def fibonacciProgram = '''
x < 1 ? 0 : x == 1 ? 1 : (2..x).inject([0,1]){i, j -> [i[1], i[0]+i[1]]}[1]
'''

println "F(${10}) - F(${5}) = ${Eval.x(10, fibonacciProgram)} - ${Eval.x(5, fibonacciProgram)} = " + cruncher(10, 5, fibonacciProgram)

Output:

F(10) - F(5) = 55 - 5 = 50

J

Explicit

The following satisfies the requirements:

   EvalWithX=. monad : 0
    'CODE V0 V1'=. y
    (". CODE [ x=. V1) - (". CODE [ x=. V0)
   )
   
   EvalWithX '^x';0;1
1.71828183

Tacit

However, it is easier via point-free coding:

   (0&({::) -~&>/@:(128!:2&.>) 1 2&{) '^';0;1
1.71828183

Explicit again

Or, using y as the free variable, instead of x:

EvalDiffWithY=: dyad define
   -~/verb def x"_1 y
)

Example use:

   '^y' EvalDiffWithY 0 1
1.71828

This can be extended to support a user declared argument name:

EvalDiffWithName=: adverb define
:
   -~/m adverb def ('(m)=.y';x)"_1 y
)

This works by preceding the user provided expression with a statement which assigns the argument value to a local variable whose name was provided by the user. [Note that this implementation skirts the requirement that the implementation does not manipulate strings -- instead we manipulate a structure containing strings.]

Example use:

  '^George' 'George' EvalDiffWithName 0 1
1.71828
   'Z + 2^Z' 'Z' EvalDiffWithName 2 3
5

Of course this could be re-defined such that the free variable declaration appears to the left of the expression ('Z' 'Z + 2^Z' Example 2 3). However, J's currying and precedence rules might make that less convenient to use, if this were ever used in a real program.

Java

Works with: Java version 6+

Although Java is a compiled static language and expression evaluation is not intrinsic part of Java, we can still generate a class at run time and so emulate evaluation of string expressions. Java 1.6 provides some APIs for this sort of thing.

Issues:

  • this is not thread-safe because it writes a generated class to the file system, then loads it
  • the supplied code to evaluate is assumed to be an expression rather than a series of statements
  • the supplied expression should evaluate to a number
  • the same class is generated twice - never mind
  • it's painfully verbose, but we're bending the language quite a bit
  • the exception handling is minimal, but if something goes wrong you should get a stack dump and the exception might be helpful...
import java.io.File;
import java.lang.reflect.Method;
import java.net.URI;
import java.util.Arrays;
import javax.tools.JavaCompiler;
import javax.tools.SimpleJavaFileObject;
import javax.tools.ToolProvider;

public class Eval {
    private static final String CLASS_NAME = "TempPleaseDeleteMe";

    private static class StringCompiler
            extends SimpleJavaFileObject {
        final String m_sourceCode;

        private StringCompiler( final String sourceCode ) {
            super( URI.create( "string:///" + CLASS_NAME + Kind.SOURCE.extension ), Kind.SOURCE );
            m_sourceCode = sourceCode;
        }

        @Override
        public CharSequence getCharContent( final boolean ignoreEncodingErrors ) {
            return m_sourceCode;
        }

        private boolean compile() {
            final JavaCompiler javac = ToolProvider.getSystemJavaCompiler();

            return javac.getTask( null, javac.getStandardFileManager( null, null, null ),
                null, null, null, Arrays.asList( this )
            ).call();
        }

        private double callEval( final double x )
                throws Exception {
            final Class<?> clarse = Class.forName( CLASS_NAME );
            final Method   eval   = clarse.getMethod( "eval", double.class );

            return ( Double ) eval.invoke( null, x );
        }
    }

    public static double evalWithX( final String code, final double x )
            throws Exception {
        final StringCompiler sc = new StringCompiler(
            "class "
                + CLASS_NAME
                + "{public static double eval(double x){return ("
                + code
                + ");}}"
            );

        if ( ! sc.compile() ) throw new RuntimeException( "Compiler error" );
        return sc.callEval( x );
    }

    public static void main( final String [] args ) 
            throws Exception /* lazy programmer */ {
        final String expression = args [ 0 ];
        final double x1         = Double.parseDouble( args [ 1 ] );
        final double x2         = Double.parseDouble( args [ 2 ] );

        System.out.println(
            evalWithX( expression, x1 )
            - evalWithX( expression, x2 )
        );
    }
}

Example usage - calculating the difference of two squares (i.e. 9 - 2 = 7):

java Eval "Math.pow(x,2)" 3 1.414213562373095

Output:

7.0

JavaScript

eval uses the environment from the calling function.

function evalWithX(expr, a, b) {
    var x = a;
    var atA = eval(expr);
    x = b;
    var atB = eval(expr);
    return atB - atA;
}
evalWithX('Math.exp(x)', 0, 1) // returns 1.718281828459045

Jsish

From Javascript entry.

/* Runtime evaluation in an environment, in Jsish */
function evalWithX(expr, a, b) {
    var x = a;
    var atA = eval(expr);
    x = b;
    var atB = eval(expr);
    return atB - atA;
}

;evalWithX('Math.exp(x)', 0, 1);
;evalWithX('Math.exp(x)', 1, 0);

/*
=!EXPECTSTART!=
evalWithX('Math.exp(x)', 0, 1) ==> 1.71828182845905
evalWithX('Math.exp(x)', 1, 0) ==> -1.71828182845905
=!EXPECTEND!=
*/
Output:
prompt$ jsish -u runtimeEnvironmentEvaluation.jsi
[PASS] runtimeEnvironmentEvaluation.jsi

Julia

Works with: Julia version 0.6
macro evalwithx(expr, a, b)
    return quote
        x = $a
        tmp = $expr
        x = $b
        return $expr - tmp
    end
end

@evalwithx(2 ^ x, 3, 5)     # raw expression (AST)

One can even perform the task without using macros:

function evalwithx(expr::Expr, a, b)
    a = eval(quote let x = $a; return $expr end end)
    b = eval(quote let x = $b; return $expr end end)
    return b - a
end
evalwithx(expr::AbstractString, a, b) = evalwithx(parse(expr), a, b)

evalwithx(:(2 ^ x), 3, 5)
evalwithx("2 ^ x", 3, 5)

Kotlin

Translation of: JavaScript

When you try to compile the following program, it will appear to the compiler that the local variable 'x' is assigned but never used and warnings will be issued accordingly. You can get rid of these warnings by compiling using the -nowarn flag.

// Kotlin JS version 1.1.4-3

fun evalWithX(expr: String, a: Double, b: Double) {
    var x = a
    val atA = eval(expr)
    x = b
    val atB = eval(expr)
    return atB - atA
}

fun main(args: Array<String>) {
    println(evalWithX("Math.exp(x)", 0.0, 1.0))
}
Output:
1.718281828459045 

Liberty BASIC

 
 expression$ = "x^2 - 7"
Print (EvaluateWithX(expression$, 5) - EvaluateWithX(expression$, 3))
End

Function EvaluateWithX(expression$, x)
    EvaluateWithX = Eval(expression$)
End Function

Lua

code = loadstring"return x^2" --this doesn't really need to be input, does it?
val1 = setfenv(code, {x = io.read() + 0})()
val2 = setfenv(code, {x = io.read() + 0})()
print(val2 - val1)

In Lua 5.2 one can use the new load function to evaluate a string as Lua code and specify its environment:

Works with: Lua version 5.2
env = {}
f = load("return x", nil, nil, env)
env.x = tonumber(io.read()) -- user enters 2
a = f()
env.x = tonumber(io.read()) -- user enters 3
b = f()
print(a + b) --> outputs 5

Mathematica/Wolfram Language

Input source code is "10 x" , X is locally bound to 3 & 2 and the resulting expressions evaluated.
(10 x /. x -> 3 ) - (10 x /. x -> 2 )
-> 10

MATLAB / Octave

In Octave, undeclared variables are local.

function r = calcit(f, val1, val2)
  x = val1;
  a = eval(f);
  x = val2;
  b = eval(f);
  r = b-a;
end

Usage:

p = 'x .* 2';
disp(calcit(p, [1:3], [4:6]));

Output:

6   6   6

Metafont

vardef evalit(expr s, va, vb) =
save x,a,b; x := va; a := scantokens s;
x := vb; b := scantokens s; a-b
enddef;

show(evalit("2x+1", 5, 3));
end

Nim

import macros, strformat
  
macro eval(s, x: static[string]): untyped =
  parseStmt(&"let x={x}\n{s}")

echo(eval("x+1", "3.1"))
Output:
4.1

ooRexx

The ooRexx interpret instruction executes dynamically created ooRexx code in the current variable context.

say evalWithX("x**2", 2)
say evalWithX("x**2", 3.1415926)

::routine evalWithX
  use arg expression, x

  -- X now has the value of the second argument
  interpret "return" expression

Output:

4
9.86960406

Oz

declare
   fun {EvalWithX Program A B}
      {Compiler.evalExpression Program env('X':B) _}
      -
      {Compiler.evalExpression Program env('X':A) _}   
   end
in
   {Show {EvalWithX "{Exp X}" 0.0 1.0}}

PARI/GP

There are many ways of doing this depending on the particular interpretation of the requirements. This code assumes that f is a string representing a GP closure.

test(f,a,b)=f=eval(f);f(a)-f(b);
test("x->print(x);x^2-sin(x)",1,3)

Perl

sub eval_with_x
   {my $code = shift;
    my $x = shift;
    my $first = eval $code;
    $x = shift;
    return eval($code) - $first;}
 
print eval_with_x('3 * $x', 5, 10), "\n"; # Prints "15".

Phix

See Runtime_evaluation#Phix for more details, or the docs.
Evaluation occurs in a brand new context, and x must be explicitly provided/returned. Note that nothing can escape the eval context: while x is not "global" here but could trivially (/technically) be made one by prefixing its definition with "global", it would still not escape the eval() context, and still have to be explicitly requested as a return value, as per the second {"x"} parameter [aka rset] to eval().

without javascript_semantics
requires("1.0.1")
include eval.e

function eval_with_x(string expr, integer a, b)
    return eval(expr,{"x"},{{"x",b}})[1] -
           eval(expr,{"x"},{{"x",a}})[1]
end function

?eval_with_x("integer x = power(2,x)",3,5)
Output:

(As in 25 - 23 === 32 - 8 === 24)

24

PHP

<?php
function eval_with_x($code, $a, $b) {
    $x = $a;
    $first = eval($code);
    $x = $b;
    $second = eval($code);
    return $second - $first;
}
 
echo eval_with_x('return 3 * $x;', 5, 10), "\n"; # Prints "15".
?>

PicoLisp

(let Expression '(+ X (* X X))            # Local expression
   (println
      (+
         (let X 3
            (eval Expression) )
         (let X 4
            (eval Expression) ) ) )
   (let Function (list '(X) Expression)   # Build a local function
      (println
         (+
            (Function 3)
            (Function 4) ) ) ) )

Output:

32
32

Pike

Pike can only compile complete classes. therefore binding a value to a variable is only possible by string manipulation. even Pikes own interactive mode which seemingly evaluates expressions wraps them into a class and replaces variable references before compiling:

> int x=10;
Result: 10
> x * 5;      
Result: 50
> dump wrapper
Last compiled wrapper:
001: mapping(string:mixed) ___hilfe = ___Hilfe->variables;
002: # 1
003: mixed ___HilfeWrapper() { return (([mapping(string:int)](mixed)___hilfe)->x) * 5; ; } 
004: 
>

___Hilfe is an object which stores all created variables;

to solve the problem in the task i would create a function that can take arguments:

string payload = "x * 5";

program demo = compile_string("string eval(mixed x){ " + payload + "; }");
 
demo()->eval(10);
Result: 50
demo()->eval(20);
Result: 100

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

A slight change allows the evaluation to take multiple names:

>>> 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

R

We can set up thing so that the "unbound" variable can be any accepted symbol for variables.

evalWithAB <- function(expr, var, a, b) {
  env <- new.env()           # provide a separate env, so that the choosen
  assign(var, a, envir=env)  # var name do not collide with symbols inside
                             # this function (e.g. it could be even "env")
  atA <- eval(parse(text=expr), env)
                             # and then evaluate the expression inside this
                             # ad hoc env-ironment
  assign(var, b, envir=env)
  atB <- eval(parse(text=expr), env)
  return(atB - atA)
}

print(evalWithAB("2*x+1", "x", 5, 3))
print(evalWithAB("2*y+1", "y", 5, 3))
print(evalWithAB("2*y+1", "x", 5, 3)) # error: object "y" not found

Racket

Same hack as the on in the CL/Scheme entries:

#lang racket
(define ns (make-base-namespace))
(define (eval-with-x code a b)
  (define (with v) (eval `(let ([x ',v]) ,code) ns))
  (- (with b) (with a)))

Better: a more direct use of eval with just the code (for example, this won't break if we use a namespace with a different meaning for let, which is very possible in Racket):

#lang racket
(define ns (make-base-namespace))
(define (eval-with-x code a b)
  (define (with v)
    (namespace-set-variable-value! 'x v #f ns)
    (eval code ns))
  (- (with b) (with a)))

Raku

(formerly Perl 6)

Works with: rakudo version 2015-12-22

For security, you must explicitly allow use of 'EVAL'.

use MONKEY-SEE-NO-EVAL;
sub eval_with_x($code, *@x) { [R-] @x.map: -> \x { EVAL $code } }

say eval_with_x('3 * x', 5, 10);      # Says "15".
say eval_with_x('3 * x', 5, 10, 50);  # Says "105".

REBOL

prog: [x * 2]
fn: func [x] [do bind prog 'x]
a: fn 2
b: fn 4
subtract b a

Result:

4

REXX

/*REXX program demonstrates a run─time evaluation of an expression (entered at run─time)*/
say '──────── enter the 1st expression to be evaluated:'

parse pull x                                     /*obtain an expression from the console*/
y.1= x                                           /*save the provided expression for  X. */
say

say '──────── enter the 2nd expression to be evaluated:'

parse pull x                                     /*obtain an expression from the console*/
y.2= x                                           /*save the provided expression for  X. */

say
say '────────  1st expression entered is: '  y.1
say '────────  2nd expression entered is: '  y.2
say

interpret 'say "──────── value of the difference is: "' y.2  "-"  '('y.1")"  /* ◄─────┐ */
                                                                             /*       │ */
                                                                             /*       │ */
                                                 /*subtract 1st exp. from the 2nd──►──┘ */

drop x                                           /*X var. is no longer a global variable*/
exit 0                                           /*stick a fork in it,  we're all done. */
output  
──────── enter the 1st expression to be evaluated:
42 + 2                            ◄■■■■■■■■■ entered by the user

──────── enter the 2nd expression to be evaluated:
12**2                             ◄■■■■■■■■■ entered by the user

────────  1st expression entered is:  42 + 2
────────  2nd expression entered is:  12**2

──────── value of the difference is:  100

Ring

expression = "return pow(x,2) - 7"
one = evalwithx(expression, 1.2)
two = evalwithx(expression, 3.4)
see "one = " + one + nl + "two = " + two + nl
 
func evalwithx expr, x
     return eval(expr)

Output:

one = -5.56
two = 4.56

RPL

A first way to answer the task is to use the possibility of passing local variables from one program to another, the calling program being in charge of achieving the binding of values to the x variable.

≪ 2 x ^ ≫ 'POWR2' STO

≪ → x ≪ POWR2 SWAP ≫ → x ≪ POWR2 SWAP - ≫ ≫ 'DIFFP' STO
Input:
5 3 DIFFP
Output:
1: 24

Another solution is to let the algebraic interpreter do the binding:

≪ → x ≪ 2 x ^ ≫ ≫ 'POWR2' STO
Input:
'POWR2(5)-POWR2(3)' EVAL
Output:
1: 24

Ruby

def bind_x_to_value(x)
  binding
end

def eval_with_x(code, a, b)
  eval(code, bind_x_to_value(b)) - eval(code, bind_x_to_value(a))
end

puts eval_with_x('2 ** x', 3, 5) # Prints "24"

The magic here is how the binding method works with the bind_x_to_value(x) method. When bind_x_to_value is called, it sets its local variable x to the value passed. The binding method then returns a reference to the current context (or stack frame) to the caller. eval can then use the local variable x in this context.

Scala

object Eval extends App {

  def evalWithX(expr: String, a: Double, b: Double)=
    {val x = b; eval(expr)} - {val x = a; eval(expr)}

  println(evalWithX("Math.exp(x)", 0.0, 1.0))

}

Scheme

Almost identical to the Common Lisp version above.

(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)))

Sidef

func eval_with_x(code, x, y) {
    var f = eval(code);
    x = y;
    eval(code) - f;
}

say eval_with_x(x: 3, y: 5, code: '2 ** x');   # => 24

Simula

BEGIN

    CLASS ENV;
    BEGIN

        CLASS ITEM(N, X); TEXT N; REAL X;
        BEGIN
            REF(ITEM) NEXT; NEXT :- HEAD; HEAD :- THIS ITEM;
        END ITEM;

        REF(ITEM) HEAD;

        REF(ITEM) PROCEDURE LOOKUP(V); TEXT V;
        BEGIN
            REF(ITEM) I; BOOLEAN FOUND; I :- HEAD;
            WHILE NOT FOUND DO
                IF I == NONE OR ELSE I.N = V
                THEN FOUND := TRUE
                ELSE I :- I.NEXT;
            LOOKUP :- I;
        END LOOKUP;

        REF(ENV) PROCEDURE SET(V, X); TEXT V; REAL X;
        BEGIN
            REF(ITEM) I; I :- LOOKUP(V);
            IF I == NONE THEN I :- NEW ITEM(V, X) ELSE I.X := X;
            SET :- THIS ENV;
        END SET;

        REAL PROCEDURE GET(V); TEXT V;
            GET := LOOKUP(V).X;

    END ENV;

    CLASS EXPR(EV); REF(ENV) EV;
    BEGIN


        REAL PROCEDURE POP;
        BEGIN
            IF STACKPOS > 0 THEN
            BEGIN STACKPOS := STACKPOS - 1; POP := STACK(STACKPOS); END;
        END POP;


        PROCEDURE PUSH(NEWTOP); REAL NEWTOP;
        BEGIN
            STACK(STACKPOS) := NEWTOP;
            STACKPOS := STACKPOS + 1;
        END PUSH;


        REAL PROCEDURE CALC(OPERATOR, ERR); CHARACTER OPERATOR; LABEL ERR;
        BEGIN
            REAL X, Y; X := POP; Y := POP;
            IF      OPERATOR = '+' THEN PUSH(Y + X)
            ELSE IF OPERATOR = '-' THEN PUSH(Y - X)
            ELSE IF OPERATOR = '*' THEN PUSH(Y * X)
            ELSE IF OPERATOR = '/' THEN BEGIN
                                            IF X = 0 THEN
                                            BEGIN
                                                EVALUATEDERR :- "DIV BY ZERO";
                                                GOTO ERR;
                                            END;
                                            PUSH(Y / X);
                                        END
            ELSE IF OPERATOR = '^' THEN PUSH(Y ** X)
            ELSE
            BEGIN
                EVALUATEDERR :- "UNKNOWN OPERATOR";
                GOTO ERR;
            END
        END CALC;


        PROCEDURE READCHAR(CH); NAME CH; CHARACTER CH;
        BEGIN
            IF T.MORE THEN CH := T.GETCHAR ELSE CH := EOT;
        END READCHAR;


        PROCEDURE SKIPWHITESPACE(CH); NAME CH; CHARACTER CH;
        BEGIN
            WHILE (CH = SPACE) OR (CH = TAB) OR (CH = CR) OR (CH = LF) DO
                READCHAR(CH);
        END SKIPWHITESPACE;


        PROCEDURE BUSYBOX(OP, ERR); INTEGER OP; LABEL ERR;
        BEGIN
            CHARACTER OPERATOR;
            REAL NUMBR;
            BOOLEAN NEGATIVE;

            SKIPWHITESPACE(CH);

            IF OP = EXPRESSION THEN
            BEGIN

                NEGATIVE := FALSE;
                WHILE (CH = '+') OR (CH = '-') DO
                BEGIN
                    IF CH = '-' THEN NEGATIVE :=  NOT NEGATIVE;
                    READCHAR(CH);
                END;

                BUSYBOX(TERM, ERR);

                IF NEGATIVE THEN
                BEGIN
                    NUMBR := POP; PUSH(0 - NUMBR);
                END;

                WHILE (CH = '+') OR (CH = '-') DO
                BEGIN
                    OPERATOR := CH; READCHAR(CH);
                    BUSYBOX(TERM, ERR); CALC(OPERATOR, ERR);
                END;

            END
            ELSE IF OP = TERM THEN
            BEGIN

                BUSYBOX(FACTOR, ERR);
                WHILE (CH = '*') OR (CH = '/') DO
                BEGIN
                    OPERATOR := CH; READCHAR(CH);
                    BUSYBOX(FACTOR, ERR); CALC(OPERATOR, ERR)
                END

            END
            ELSE IF OP = FACTOR THEN
            BEGIN

                BUSYBOX(POWER, ERR);
                WHILE CH = '^' DO
                BEGIN
                    OPERATOR := CH; READCHAR(CH);
                    BUSYBOX(POWER, ERR); CALC(OPERATOR, ERR)
                END

            END
            ELSE IF OP = POWER THEN
            BEGIN

                IF (CH = '+') OR (CH = '-') THEN
                    BUSYBOX(EXPRESSION, ERR)
                ELSE IF (CH >= '0') AND (CH <= '9') THEN
                    BUSYBOX(NUMBER, ERR)
                ELSE IF (CH >= 'A') AND (CH <= 'Z') THEN
                    BUSYBOX(VARIABLE, ERR)
                ELSE IF CH = '(' THEN
                BEGIN
                    READCHAR(CH);
                    BUSYBOX(EXPRESSION, ERR);
                    IF CH = ')' THEN READCHAR(CH) ELSE GOTO ERR;
                END
                ELSE GOTO ERR;

            END
            ELSE IF OP = VARIABLE THEN
            BEGIN

                TEXT VARNAM;
                VARNAM :- BLANKS(32);
                WHILE (CH >= 'A') AND (CH <= 'Z')
                   OR (CH >= '0') AND (CH <= '9') DO
                BEGIN
                    VARNAM.PUTCHAR(CH);
                    READCHAR(CH);
                END;
                PUSH(EV.GET(VARNAM.STRIP));

            END
            ELSE IF OP = NUMBER THEN
            BEGIN

                NUMBR := 0;
                WHILE (CH >= '0') AND (CH <= '9') DO
                BEGIN
                    NUMBR := 10 * NUMBR + RANK(CH) - RANK('0'); READCHAR(CH);
                END;
                IF CH = '.' THEN
                BEGIN
                    REAL FAKTOR;
                    READCHAR(CH);
                    FAKTOR := 10;
                    WHILE (CH >= '0') AND (CH <= '9') DO
                    BEGIN
                        NUMBR := NUMBR + (RANK(CH) - RANK('0')) / FAKTOR;
                        FAKTOR := 10 * FAKTOR;
                        READCHAR(CH);
                    END;
                END;
                PUSH(NUMBR);

            END;

            SKIPWHITESPACE(CH);

        END BUSYBOX;


        BOOLEAN PROCEDURE EVAL(INP); TEXT INP;
        BEGIN
            EVALUATEDERR :- NOTEXT;
            STACKPOS := 0;
            T :- COPY(INP.STRIP);
            READCHAR(CH);
            BUSYBOX(EXPRESSION, ERRORLABEL);
            IF NOT T.MORE AND STACKPOS = 1 AND CH = EOT THEN
            BEGIN
                EVALUATED := POP;
                EVAL := TRUE;
                GOTO NOERRORLABEL;
            END;
    ERRORLABEL:
            EVAL := FALSE;
            IF EVALUATEDERR = NOTEXT THEN
                EVALUATEDERR :- "INVALID EXPRESSION: " & INP;
    NOERRORLABEL:
        END EVAL;

        
        REAL PROCEDURE RESULT;
            RESULT := EVALUATED;

        TEXT PROCEDURE ERR;
            ERR :- EVALUATEDERR;

        INTEGER EXPRESSION, TERM, FACTOR, POWER, NUMBER, VARIABLE;
        CHARACTER TAB, LF, CR, SPACE, EOT, CH;
        REAL ARRAY STACK(0:31);
        INTEGER STACKPOS;
        REAL EVALUATED;
        TEXT EVALUATEDERR, T;

        EXPRESSION := 1;
        TERM := 2;
        FACTOR := 3;
        POWER := 4;
        NUMBER := 5;
        VARIABLE := 6;

        TAB := CHAR(9);
        LF := CHAR(10);
        CR := CHAR(13);
        SPACE := CHAR(32);
        EOT := CHAR(0);

    END EXPR;

    REF(EXPR) EXA, EXB;
    EXA :- NEW EXPR(NEW ENV.SET("X", 3));
    EXB :- NEW EXPR(NEW ENV.SET("X", 5));
    IF EXA.EVAL("2 ^ X") THEN
    BEGIN
        IF EXB.EVAL("2 ^ X")
        THEN OUTFIX(EXB.RESULT - EXA.RESULT, 3, 10)
        ELSE OUTTEXT(EXB.ERR)
    END ELSE OUTTEXT(EXA.ERR);
    OUTIMAGE;

END.
Output:
    24.000

SNOBOL4

This program defines (at runtime) a function triple(), compiles it, and then executes it twice, with values x = 1 and then x = 3. The program subtracts the returned value from the first call from the value returned from the first call, and prints the result. In this example, the value x is passed as a parameter to the function triple().

     compiled = code(' define("triple(x)") :(a);triple triple = 3 * x :(return)')  :<compiled>
a    x = 1
     first = triple(x)
     x = 3
     output = triple(x) - first  
end

Output:

6

If you specifically wanted to not pass x as a parameter but instead use it as a value from the environment, that's easy too:

     compiled = code(' define("triple()") :(a);triple triple = 3 * x :(return)')  :<compiled>
a    x = 1
     first = triple(x)
     x = 3
     output = triple(x) - first  
end

The output is the same.

Tcl

proc eval_twice {func a b} {
    set x $a
    set 1st [expr $func]
    set x $b
    set 2nd [expr $func]
    expr {$2nd - $1st}
}

puts [eval_twice {2 ** $x} 3 5] ;# ==> 24

Here's another take, similar to other answers. It passes a code block to be evaled, not just an expression for expr

proc eval_with_x {code val1 val2} {
    expr {[set x $val2; eval $code] - [set x $val1; eval $code]}
}
eval_with_x {expr {2**$x}} 3 5 ;# ==> 24

In 8.5, apply makes environments like this "first class":

Works with: Tcl version 8.5
package require Tcl 8.5
proc eval_with {body a b} {
    set lambda [list x $body]
    expr {[apply $lambda $b] - [apply $lambda $a]}
}

eval_with {expr {2**$x}} 3 5  ;# ==> 24

TI-89 BASIC

evalx(prog, a, b)
Func
  Local x,eresult1,eresult2
  a→x
  expr(prog)→eresult1
  b→x
  expr(prog)→eresult2
  Return eresult2-eresult1
EndFunc

■ evalx("ℯ^x", 0., 1)
                      1.71828

There are no facilities for control over the environment; expr() evaluates in the same environment as the caller, including local variables. [Someone please verify this statement.]

Transd

The (eval) function returns a pair, where the first element is boolean flag indicating success of running the code, and the second element is a string containing the output of code execution.

#lang transd

MainModule: {
    code: "(+ 5 x)",

    _start: (lambda (textout 
        (- (to-Int (with x 100 (snd (eval code))))
           (to-Int (with x 1 (snd (eval code)))))
        ))
}
Output:
99

TXR

Translation of: Common Lisp

In TXR's embedded Lisp dialect, we can implement the same solution as Lisp or Scheme: transform the code fragment by wrapping a let around it which binds a variable, and then evaluating the whole thing:

(defun eval-subtract-for-two-values-of-x (code-fragment x1 x0)
  (- (eval ^(let ((x ,x1)) ,code-fragment))
     (eval ^(let ((x ,x0)) ,code-fragment))))

(eval-subtract-for-two-values-of-x 1 2) ;; yields -4.67077427047161

Cutting edge TXR code provides access to the environment manipulation functions, making this possible:

(defun eval-subtract-for-two-values-of-x (code-fragment x1 x0)
  (let ((e1 (make-env (list (cons 'x x1))))   ;; create two environments stuffed with binding for x
        (e0 (make-env (list (cons 'x x0)))))
    (- (eval code-fragment e1)                ;; pass these environment to eval
       (eval code-fragment e0))))
 
(eval-subtract-for-two-values-of-x '(exp x) 1 2)

Alternatively, empty environments can be made and extended with bindings:

(defun eval-subtract-for-two-values-of-x (code-fragment x1 x0)
  (let ((e1 (make-env))
        (e0 (make-env)))
    (env-vbind e1 'x x1)
    (env-vbind e0 'x x0)
    (- (eval code-fragment e1)
       (eval code-fragment e0))))
 
(eval-subtract-for-two-values-of-x '(exp x) 1 2)

Explicit environment manipulation has the disadvantage of being hostile against compiling. (See notes about compilation in the Common Lisp example.)

there is an eval function which takes an environment parameter. However, currently there isn't any access to the manipulation of environment objects. It's probably a bad idea because run time tricks with lexical environments lead to programs that are not compilable.

Lastly, we can also solve this problem using dynamically scoped (a.k.a "special") variables. The problem description specifically says that the solution is not to use global variables. Though we must define the variables as global, we do not use the global bindings; we use dynamic bindings.

There is a hidden global variable, namely the dynamic environment itself. That's how eval is able to resolve the free-variable x occurring in code-fragment without receiving any environment parameter.

However, our two let constructs carefully save and restore the dynamic environment (and therefore any prior value of x), even in the face of exceptions, and

(defvar x)

(defun eval-subtract-for-two-values-of-x (code-fragment x1 x0)
  (- (let ((x x1)) (eval code-fragment))
     (let ((x x0)) (eval code-fragment))))

(eval-subtract-for-two-values-of-x '(exp x) 1 2)

UNIX Shell

The backquotes ` ... ` capture the standard output of a subshell. Changes to parameter x in the subshell will not affect its parent shell.

eval_with_x() {
	set -- "`x=$2; eval "$1"`" "`x=$3; eval "$1"`"
	expr "$2" - "$1"
}

eval_with_x '
	# compute 2 ** $x
	p=1
	while test $x -gt 0; do
		p=`expr $p \* 2`
		x=`expr $x - 1`
	done
	echo $p
' 3 5
# Prints '24'

Wren

Wren has a library method called Meta.eval which can do runtime evaluation.

However, it only appears to work with module level variables.

import "meta" for Meta

var x
Meta.eval("x = 2")
System.print("First  x = %(x)")
var y = x // save this value

Meta.eval("x = 5")
System.print("Second x = %(x)")

Meta.eval("x = x - y")
System.print("Delta  x = %(x)")
Output:
First  x = 2
Second x = 5
Delta  x = 3

zkl

fcn evalWithX(text,x) {
   f:=Compiler.Compiler.compileText(text);
   f.x = x; // set free var in compiled blob
   f.__constructor(); // run blob
   vm.regX   // compiler sets the VMs X register for cases like this
}
const TEXT="var x; x*2"; // variables need to be declared
evalWithX(TEXT,5) - evalWithX(TEXT,3) #--> 4

This is not a complete solution but close.

Another way to do this is to create a class on the fly that contains the code to be run and reusing that class. The class just acts like as a container for x and a function:

var klass=Compiler.Compiler.compileText("var x; returnClass(x*2)");
(klass.__constructor(klass.x=5) - klass.__constructor(klass.x=3)).println();

returnClass(x) is required in a constructor if you want to return something other than self. klass.x=y pokes y into the instance variable x. Running the constructor runs x*2.

Output:
4