Runtime evaluation/In an environment: Difference between revisions

Added FreeBASIC
No edit summary
(Added FreeBASIC)
 
(44 intermediate revisions by 19 users not shown)
Line 1:
{{task}} Given a program in the language (as a string or AST) with a free variable named <var>x</var> (or another name if that is not valid syntax), evaluate it with <var>x</var> bound to a provided value, then evaluate it again with <var>x</var> 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:
Line 5 ⟶ 6:
* is plausibly extensible to a runtime-chosen set of bindings rather than just <var>x</var>
* does not make <var>x</var> a ''global'' variable
 
 
or note that these are impossible.
 
 
===See also===
;See also:
* For more general examples and language-specific details, see [[Eval]].
* [[Dynamic variable names]] is a similar task.
<br><br>
 
=={{header|ALGOL 68}}==
Line 17 ⟶ 22:
<!-- {{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'''.
<langsyntaxhighlight lang="algol68">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))</langsyntaxhighlight>
Output:
<pre>
+8 +32
</pre>
 
=={{header|AppleScript}}==
<!-- In progress... trying to understand how that works... -->
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.<br/>
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.<br/>
Arguments may be passed as a list of arbitrary values; this however requires the program to be written with an explicit '''run''' handler.<br/>
The result is the value (if any) returned by the program; any valid AppleScript value may be returned.<br/>
<br>
Given the above, the task may easily be implemented along these lines:
<syntaxhighlight lang="applescript">
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
</syntaxhighlight>
Example usage (for legibility purposes, the program is stored into an intermediate variable):
<syntaxhighlight lang="applescript">
set pgrm_with_x to "
on run {x}
2^x
end"
 
task_with_x(pgrm_with_x, 3, 5)
</syntaxhighlight>
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}}==
{{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.
<langsyntaxhighlight AutoHotkeylang="autohotkey">msgbox % first := evalWithX("x + 4", 5)
msgbox % second := evalWithX("x + 4", 6)
msgbox % second - first
Line 59 ⟶ 106:
if fnp := FindFunc(funcName)
numput(&x%newname%, fnp+0, 0, "uint")
}</langsyntaxhighlight>
 
=={{header|BBC BASIC}}==
<langsyntaxhighlight lang="bbcbasic"> expression$ = "x^2 - 7"
one = FN_eval_with_x(expression$, 1.2)
two = FN_eval_with_x(expression$, 3.4)
Line 69 ⟶ 116:
DEF FN_eval_with_x(expr$, x)
= EVAL(expr$)</langsyntaxhighlight>
 
=={{header|Bracmat}}==
<syntaxhighlight lang="text">( ( eval-with-x
= code a b argument
. !arg:((=?code),?a,?b,?argument)
Line 80 ⟶ 127:
& out$(eval-with-x$((='(.$x^!arg)),3,5,2))
& out$(eval-with-x$((='(.$x^!arg)),12,13,2))
);</langsyntaxhighlight>
Output:
<pre>16
Line 88 ⟶ 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.
<langsyntaxhighlight lang="clojure">(def ^:dynamic x nil)
 
(defn eval-with-x [program a b]
(- (binding [x b] (eval program))
(binding [x a] (eval program))))</langsyntaxhighlight>
 
<langsyntaxhighlight lang="clojure">(eval-with-x '(* x x) 4 9)
=> 65</langsyntaxhighlight>
 
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):
<syntaxhighlight lang="clojure">
(defn eval-with-x [program a b]
(let [func (eval `(fn [~'x] ~program))]
(- (func b) (func a))))
</syntaxhighlight>
<syntaxhighlight lang="clojure">(eval-with-x '(* x x) 4 9)
=> 65</syntaxhighlight>
 
=={{header|Common Lisp}}==
 
<langsyntaxhighlight lang="lisp">(defun eval-with-x (program a b)
(let ((at-a (eval `(let ((x ',a)) ,program)))
(at-b (eval `(let ((x ',b)) ,program))))
(- at-b at-a)))</langsyntaxhighlight>
 
<langsyntaxhighlight lang="lisp">(eval-with-x '(exp x) 0 1)
=> 1.7182817</langsyntaxhighlight>
 
This version ensures that the program is compiled, once, for more efficient execution:
 
<langsyntaxhighlight lang="lisp">(defun eval-with-x (program a b)
(let* ((f (compile nil `(lambda (x) ,program)))
(at-a (funcall f a))
(at-b (funcall f b)))
(- at-b at-a)))</langsyntaxhighlight>
 
=={{header|Déjà Vu}}==
<langsyntaxhighlight lang="dejavu">local fib n:
if <= n 1:
n
Line 127 ⟶ 182:
!run-blob-in { :fib @fib :x 4 } code
!run-blob-in { :fib @fib :x 6 } code
!. -</langsyntaxhighlight>
{{out}}
<pre>5</pre>
 
=={{header|E}}==
<langsyntaxhighlight lang="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) {
Line 146 ⟶ 201:
def atB := program.eval(bindX(b))
return atB - atA
}</langsyntaxhighlight>
 
<langsyntaxhighlight lang="e">? evalWithX(e`(x :float64).exp()`, 0, 1)
# value: 1.7182818284590455</langsyntaxhighlight>
 
=={{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)....)
<langsyntaxhighlight lang="lisp">
(define (eval-with-x prog x)
(eval prog (environment-new (list (list 'x x)))))
Line 166 ⟶ 221:
x
😖️ error: #|user| : unbound variable : x
</syntaxhighlight>
</lang>
 
=={{header|Elena}}==
ELENA 6.x:
 
Using VM console client:
<syntaxhighlight lang="elena">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()));
}</syntaxhighlight>
{{out}}
<pre>
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
</pre>
 
=={{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.
<syntaxhighlight lang="erlang">
<lang Erlang>
-module( runtime_evaluation ).
 
Line 192 ⟶ 272:
io:fwrite( "~p~n", [Variable2] ),
io:fwrite( "~p~n", [Variable2 - Variable1] ).
</syntaxhighlight>
</lang>
 
{{out}}
Line 201 ⟶ 281:
1
</pre>
 
=={{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:
<syntaxhighlight lang="factor">USE: eval
: eval-bi@- ( a b program -- n )
tuck [ ( y -- z ) eval ] 2bi@ - ;</syntaxhighlight>
<syntaxhighlight lang="factor">IN: scratchpad 9 4 "dup *" eval-bi@- .
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:
<syntaxhighlight lang="factor">: bi@- ( a b quot -- n ) bi@ - ; inline</syntaxhighlight>
<syntaxhighlight lang="factor">IN: scratchpad 9 4 [ dup * ] bi@- .
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.
<syntaxhighlight lang="factor">SYMBOL: x
: eval-with-x ( a b program -- n )
tuck
[ [ x ] dip [ ( -- y ) eval ] curry with-variable ] 2bi@ - ;</syntaxhighlight>
<syntaxhighlight lang="factor">IN: scratchpad 9 4 "x get dup *" eval-with-x .
65
IN: scratchpad x get .
f</syntaxhighlight>
 
=={{header|Forth}}==
EVALUATE invokes the Forth interpreter on the given string.
<langsyntaxhighlight lang="forth">: f-" ( a b snippet" -- )
[char] " parse ( code len )
2dup 2>r evaluate
Line 210 ⟶ 311:
- . ;
 
2 3 f-" dup *" \ 5 (3*3 - 2*2)</langsyntaxhighlight>
This can be used to treat a data stream as code, or to provide a lightweight macro facility when used in an IMMEDIATE word.
<langsyntaxhighlight lang="forth">: :macro ( "name <char> ccc<char>" -- )
: [CHAR] ; PARSE POSTPONE SLITERAL POSTPONE EVALUATE
POSTPONE ; IMMEDIATE
Line 226 ⟶ 327:
DO .\" spam "
LOOP
; ok</langsyntaxhighlight>
 
=={{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}}==
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:
<langsyntaxhighlight lang="genyris">defmacro add100() (+ x 100)
 
var x 23
Line 236 ⟶ 352:
x = 1000
print
+ firstresult (add100)</langsyntaxhighlight>
 
This prints 1223.
Line 242 ⟶ 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.
 
<langsyntaxhighlight lang="genyris">def add100() (+ .x 100)
 
(dict) # create an environment capable of holding dynamic bindings
Line 249 ⟶ 365:
.x = 1000
print
+ firstresult (add100)</langsyntaxhighlight>
Dictionaries can hold bindings to dynamic symbols. To minimize the danger of dynamic scope there is no recursive ascent in the binding lookup.
<langsyntaxhighlight lang="genyris">(dict)
var .x 23
(dict)
print .x # fails</langsyntaxhighlight>
 
=={{header|Go}}==
<langsyntaxhighlight lang="go">package main
 
import (
Line 322 ⟶ 439:
func (v *intV) Assign(t *eval.Thread, o eval.Value) {
*v = intV(o.(eval.IntValue).Get(t))
}</langsyntaxhighlight>
Output:
<pre>
Line 331 ⟶ 448:
 
The solution:
<langsyntaxhighlight lang="groovy">def cruncher = { x1, x2, program ->
Eval.x(x1, program) - Eval.x(x2, program)
}</langsyntaxhighlight>
 
Test Program:
<langsyntaxhighlight lang="groovy">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)</langsyntaxhighlight>
 
Output:
Line 348 ⟶ 465:
===Explicit===
The following satisfies the requirements:
<langsyntaxhighlight lang="j"> EvalWithX=. monad : 0
'CODE V0 V1'=. y
(". CODE [ x=. V1) - (". CODE [ x=. V0)
Line 354 ⟶ 471:
EvalWithX '^x';0;1
1.71828183</langsyntaxhighlight>
===Tacit===
However, it is easier via point-free coding:
<langsyntaxhighlight lang="j"> (0&({::) -~&>/@:(128!:2&.>) 1 2&{) '^';0;1
1.71828183</langsyntaxhighlight>
 
===Explicit again===
 
Or, using y as the free variable, instead of x:
<langsyntaxhighlight Jlang="j">EvalDiffWithY=: dyad define
-~/verb def x"_1 y
)</langsyntaxhighlight>
 
Example use:
 
<langsyntaxhighlight Jlang="j"> '^y' EvalDiffWithY 0 1
1.71828</langsyntaxhighlight>
 
This can be extended to support a user declared argument name:
 
<langsyntaxhighlight Jlang="j">EvalDiffWithName=: adverb define
:
-~/m adverb def ('(m)=.y';x)"_1 y
)</langsyntaxhighlight>
 
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 383 ⟶ 500:
Example use:
 
<langsyntaxhighlight Jlang="j"> '^George' 'George' EvalDiffWithName 0 1
1.71828
'Z + 2^Z' 'Z' EvalDiffWithName 2 3
5</langsyntaxhighlight>
 
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 402 ⟶ 519:
* the exception handling is minimal, but if something goes wrong you should get a stack dump and the exception ''might'' be helpful...
 
<langsyntaxhighlight lang="java5">import java.io.File;
import java.lang.reflect.Method;
import java.net.URI;
Line 469 ⟶ 586:
);
}
}</langsyntaxhighlight>
 
Example usage - calculating the difference of two squares (i.e. 9 - 2 = 7):
Line 481 ⟶ 598:
eval uses the environment from the calling function.
 
<langsyntaxhighlight lang="javascript">function evalWithX(expr, a, b) {
var x = a;
var atA = eval(expr);
Line 487 ⟶ 604:
var atB = eval(expr);
return atB - atA;
}</langsyntaxhighlight>
 
<langsyntaxhighlight lang="javascript">evalWithX('Math.exp(x)', 0, 1) // returns 1.718281828459045</langsyntaxhighlight>
 
=={{header|Jsish}}==
From Javascript entry.
<syntaxhighlight lang="javascript">/* 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!=
*/</syntaxhighlight>
 
{{out}}
<pre>prompt$ jsish -u runtimeEnvironmentEvaluation.jsi
[PASS] runtimeEnvironmentEvaluation.jsi</pre>
 
=={{header|Julia}}==
{{works with|Julia|0.6}}
 
<syntaxhighlight lang="julia">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)</syntaxhighlight>
 
One can even perform the task without using macros:
 
<syntaxhighlight lang="julia">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)</syntaxhighlight>
 
=={{header|Kotlin}}==
{{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.
<syntaxhighlight lang="scala">// 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))
}</syntaxhighlight>
 
{{out}}
<pre>
1.718281828459045
</pre>
 
=={{header|Liberty BASIC}}==
<syntaxhighlight lang="lb">
<lang lb>
expression$ = "x^2 - 7"
Line 500 ⟶ 690:
Function EvaluateWithX(expression$, x)
EvaluateWithX = Eval(expression$)
End Function </langsyntaxhighlight>
 
=={{header|Lua}}==
<langsyntaxhighlight lang="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)
</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:
Line 514 ⟶ 704:
{{works with|Lua|5.2}}
 
<langsyntaxhighlight lang="lua">env = {}
f = load("return x", nil, nil, env)
env.x = tonumber(io.read()) -- user enters 2
Line 520 ⟶ 710:
env.x = tonumber(io.read()) -- user enters 3
b = f()
print(a + b) --> outputs 5</langsyntaxhighlight>
 
=={{header|Mathematica}}/{{header|Wolfram Language}}==
<langsyntaxhighlight Mathematicalang="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</langsyntaxhighlight>
 
=={{header|MATLAB}} / {{header|Octave}}==
Line 531 ⟶ 721:
In Octave, undeclared variables are local.
 
<langsyntaxhighlight lang="octave">function r = calcit(f, val1, val2)
x = val1;
a = eval(f);
Line 537 ⟶ 727:
b = eval(f);
r = b-a;
end</langsyntaxhighlight>
Usage:
<pre>p = 'x .* 2';
Line 547 ⟶ 737:
=={{header|Metafont}}==
 
<langsyntaxhighlight lang="metafont">vardef evalit(expr s, va, vb) =
save x,a,b; x := va; a := scantokens s;
x := vb; b := scantokens s; a-b
Line 553 ⟶ 743:
 
show(evalit("2x+1", 5, 3));
end</langsyntaxhighlight>
 
=={{header|Nim}}==
<syntaxhighlight lang="nim">import macros, strformat
macro eval(s, x: static[string]): untyped =
parseStmt(&"let x={x}\n{s}")
 
echo(eval("x+1", "3.1"))</syntaxhighlight>
{{out}}
<pre>
4.1
</pre>
 
=={{header|ooRexx}}==
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", 3.1415926)
Line 566 ⟶ 768:
-- X now has the value of the second argument
interpret "return" expression
</syntaxhighlight>
</lang>
Output:
<pre>
Line 574 ⟶ 776:
 
=={{header|Oz}}==
<langsyntaxhighlight lang="oz">declare
fun {EvalWithX Program A B}
{Compiler.evalExpression Program env('X':B) _}
Line 581 ⟶ 783:
end
in
{Show {EvalWithX "{Exp X}" 0.0 1.0}}</langsyntaxhighlight>
 
=={{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.
<langsyntaxhighlight lang="parigp">test(f,a,b)=f=eval(f);f(a)-f(b);
test("x->print(x);x^2-sin(x)",1,3)</langsyntaxhighlight>
 
=={{header|Perl}}==
 
<langsyntaxhighlight lang="perl">sub eval_with_x
{my $code = shift;
my $x = shift;
Line 597 ⟶ 799:
return eval($code) - $first;}
print eval_with_x('3 * $x', 5, 10), "\n"; # Prints "15".</langsyntaxhighlight>
 
=={{header|Perl 6Phix}}==
See [[Runtime_evaluation#Phix]] for more details, or the docs.<br>
{{Works with|rakudo|2015-12-22}}
Evaluation occurs in a brand new context, and x must be explicitly provided/returned.
For security, you must explicitly allow use of 'EVAL'.
Note that nothing can escape the eval context: while x is not "global" here but could
<lang perl6>use MONKEY-SEE-NO-EVAL;
trivially (/technically) be made one by prefixing its definition with "global", it would
sub eval_with_x($code, *@x) { [R-] @x.map: -> \x { EVAL $code } }
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().
say eval_with_x('3 * x', 5, 10); # Says "15".
<!--<syntaxhighlight lang="phix">(phixonline)-->
say eval_with_x('3 * x', 5, 10, 50); # Says "105".</lang>
<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}}==
 
<langsyntaxhighlight lang="php"><?php
function eval_with_x($code, $a, $b) {
$x = $a;
Line 620 ⟶ 838:
echo eval_with_x('return 3 * $x;', 5, 10), "\n"; # Prints "15".
?></langsyntaxhighlight>
 
=={{header|PicoLisp}}==
<langsyntaxhighlight PicoLisplang="picolisp">(let Expression '(+ X (* X X)) # Local expression
(println
(+
Line 634 ⟶ 852:
(+
(Function 3)
(Function 4) ) ) ) )</langsyntaxhighlight>
Output:
<pre>32
Line 641 ⟶ 859:
=={{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:
<langsyntaxhighlight Pikelang="pike">> int x=10;
Result: 10
> x * 5;
Line 651 ⟶ 869:
003: mixed ___HilfeWrapper() { return (([mapping(string:int)](mixed)___hilfe)->x) * 5; ; }
004:
></langsyntaxhighlight>
___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:
<langsyntaxhighlight Pikelang="pike">string payload = "x * 5";
 
program demo = compile_string("string eval(mixed x){ " + payload + "; }");
Line 662 ⟶ 880:
Result: 50
demo()->eval(20);
Result: 100</langsyntaxhighlight>
 
=={{header|Python}}==
 
<langsyntaxhighlight lang="python">>>> def eval_with_x(code, a, b):
return eval(code, {'x':b}) - eval(code, {'x':a})
 
>>> eval_with_x('2 ** x', 3, 5)
24</langsyntaxhighlight>
 
A slight change allows the evaluation to take multiple names:
<langsyntaxhighlight lang="python">>>> def eval_with_args(code, **kwordargs):
return eval(code, kwordargs)
 
Line 681 ⟶ 899:
>>> code = '3 * x + y'
>>> eval_with_args(code, x=5, y=2) - eval_with_args(code, x=3, y=1)
7</langsyntaxhighlight>
 
=={{header|R}}==
We can set up thing so that the "unbound" variable can be any accepted symbol for variables.
<langsyntaxhighlight Rlang="r">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
Line 699 ⟶ 917:
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</langsyntaxhighlight>
 
=={{header|Racket}}==
 
Same hack as the on in the CL/Scheme entries:
<syntaxhighlight lang="racket">
<lang Racket>
#lang racket
(define ns (make-base-namespace))
Line 710 ⟶ 928:
(define (with v) (eval `(let ([x ',v]) ,code) ns))
(- (with b) (with a)))
</syntaxhighlight>
</lang>
 
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
<tt>let</tt>, which is very possible in Racket):
<syntaxhighlight lang="racket">
<lang Racket>
#lang racket
(define ns (make-base-namespace))
Line 723 ⟶ 941:
(eval code ns))
(- (with b) (with a)))
</syntaxhighlight>
</lang>
 
=={{header|Raku}}==
(formerly Perl 6)
{{Works with|rakudo|2015-12-22}}
For security, you must explicitly allow use of 'EVAL'.
<syntaxhighlight lang="raku" line>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".</syntaxhighlight>
 
=={{header|REBOL}}==
<langsyntaxhighlight lang="rebol">prog: [x * 2]
fn: func [x] [do bind prog 'x]
a: fn 2
b: fn 4
subtract b a</langsyntaxhighlight>
 
Result:
Line 738 ⟶ 966:
 
=={{header|REXX}}==
<syntaxhighlight lang ="rexx">/*REXX program to demonstrate some run-time evaulations. 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*/
a=fact(3)
y.1= x /*save the provided expression for X. */
b=fact(4)
say b-a
exit /*stick a fork in it, we're done.*/
 
say '──────── enter the 2nd expression to be evaluated:'
/*───────────────────────────────────FACT subroutine────────────────────*/
 
fact: procedure; parse arg n; !=1; do j=2 to n; !=!*j; end; return !</lang>
parse pull x /*obtain an expression from the console*/
'''output'''
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. */</syntaxhighlight>
{{out|output|text=&nbsp;}}
<pre>
──────── enter the 1st expression to be evaluated:
18
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
</pre>
 
=={{header|Ring}}==
<langsyntaxhighlight lang="ring">
expression = "return pow(x,2) - 7"
one = evalwithx(expression, 1.2)
Line 761 ⟶ 1,013:
func evalwithx expr, x
return eval(expr)
</syntaxhighlight>
</lang>
Output:
<pre>
one = -5.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>
 
=={{header|Ruby}}==
<langsyntaxhighlight lang="ruby">def bind_x_to_value(x)
binding
end
Line 777 ⟶ 1,053:
end
 
puts eval_with_x('2 ** x', 3, 5) # Prints "24"</langsyntaxhighlight>
 
The magic here is how the <code>binding</code> method works with the <code>bind_x_to_value(x)</code> method.
Line 783 ⟶ 1,059:
The <code>binding</code> method then returns a reference to the current context (or stack frame) to the caller.
<code>eval</code> can then use the local variable <code>x</code> in this context.
 
=={{header|Scala}}==
<syntaxhighlight lang="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))
 
}</syntaxhighlight>
 
=={{header|Scheme}}==
Almost identical to the [[Common Lisp]] version above.
<langsyntaxhighlight lang="scheme">(define (eval-with-x prog a b)
(let ((at-a (eval `(let ((x ',a)) ,prog)))
(at-b (eval `(let ((x ',b)) ,prog))))
(- at-b at-a)))</langsyntaxhighlight>
 
 
=={{header|Sidef}}==
<langsyntaxhighlight lang="ruby">func eval_with_x(code, x, y) {
var f = eval(code);
x = y;
Line 799 ⟶ 1,084:
}
 
say eval_with_x(x: 3, y: 5, code: '2 ** x'); # => 24</langsyntaxhighlight>
 
=={{header|Simula}}==
<syntaxhighlight lang="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.
</syntaxhighlight>
{{out}}
<pre>
24.000
</pre>
 
=={{header|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().
 
<langsyntaxhighlight SNOBOL4lang="snobol4"> 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</langsyntaxhighlight>
 
Output:
Line 816 ⟶ 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:
 
<langsyntaxhighlight SNOBOL4lang="snobol4"> compiled = code(' define("triple()") :(a);triple triple = 3 * x :(return)') :<compiled>
a x = 1
first = triple(x)
x = 3
output = triple(x) - first
end</langsyntaxhighlight>
 
The output is the same.
 
=={{header|Tcl}}==
<langsyntaxhighlight lang="tcl">proc eval_twice {func a b} {
set x $a
set 1st [expr $func]
Line 834 ⟶ 1,390:
}
 
puts [eval_twice {2 ** $x} 3 5] ;# ==> 24</langsyntaxhighlight>
 
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>
<langsyntaxhighlight lang="tcl">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</langsyntaxhighlight>
 
In 8.5, <tt>apply</tt> makes environments like this "first class":
 
{{works with|Tcl|8.5}}
<langsyntaxhighlight lang="tcl">package require Tcl 8.5
proc eval_with {body a b} {
set lambda [list x $body]
Line 851 ⟶ 1,407:
}
 
eval_with {expr {2**$x}} 3 5 ;# ==> 24</langsyntaxhighlight>
 
=={{header|TI-89 BASIC}}==
 
<syntaxhighlight lang="ti89b">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</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]]
 
=={{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}}==
Line 859 ⟶ 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:
 
<langsyntaxhighlight lang="txrlisp">(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</langsyntaxhighlight>
 
Cutting edge TXR code provides access to the environment manipulation functions, making this possible:
 
<langsyntaxhighlight 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
(e0 (make-env (list (cons 'x x0)))))
Line 873 ⟶ 1,464:
(eval code-fragment e0))))
(eval-subtract-for-two-values-of-x '(exp x) 1 2)</langsyntaxhighlight>
 
Alternatively, empty environments can be made and extended with bindings:
 
<langsyntaxhighlight lang="txrlisp">(defun eval-subtract-for-two-values-of-x (code-fragment x1 x0)
(let ((e1 (make-env))
(e0 (make-env)))
Line 885 ⟶ 1,476:
(eval code-fragment e0))))
(eval-subtract-for-two-values-of-x '(exp x) 1 2)</langsyntaxhighlight>
 
Explicit environment manipulation has the disadvantage of being hostile against compiling. (See notes about compilation in the Common Lisp example.)
Line 897 ⟶ 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
 
<langsyntaxhighlight lang="txrlisp">(defvar x)
 
(defun eval-subtract-for-two-values-of-x (code-fragment x1 x0)
Line 903 ⟶ 1,494:
(let ((x x0)) (eval code-fragment))))
 
(eval-subtract-for-two-values-of-x '(exp x) 1 2)</langsyntaxhighlight>
 
=={{header|TI-89 BASIC}}==
 
<lang ti89b>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</lang>
 
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|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.
 
<langsyntaxhighlight lang="bash">eval_with_x() {
set -- "`x=$2; eval "$1"`" "`x=$3; eval "$1"`"
expr "$2" - "$1"
Line 939 ⟶ 1,513:
echo $p
' 3 5
# Prints '24'</langsyntaxhighlight>
 
=={{header|Wren}}==
Wren has a library method called ''Meta.eval'' which can do runtime evaluation.
 
However, it only appears to work with module level variables.
<syntaxhighlight lang="wren">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)")</syntaxhighlight>
 
{{out}}
<pre>
First x = 2
Second x = 5
Delta x = 3
</pre>
 
=={{header|zkl}}==
<langsyntaxhighlight lang="zkl">fcn evalWithX(text,x) {
f:=Compiler.Compiler.compileText(text);
f.x = x; // set free var in compiled blob
Line 949 ⟶ 1,547:
}
const TEXT="var x; x*2"; // variables need to be declared
evalWithX(TEXT,5) - evalWithX(TEXT,3) #--> 4</langsyntaxhighlight>
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:
<langsyntaxhighlight lang="zkl">var klass=Compiler.Compiler.compileText("var x; returnClass(x*2)");
(klass.__constructor(klass.x=5) - klass.__constructor(klass.x=3)).println();</langsyntaxhighlight>
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>
Line 965 ⟶ 1,563:
{{omit from|GUISS|Does not have variables}}
{{omit from|Lily}}
{{omit from|Insitux}}
2,122

edits