Eval
≈ 9 min read
Names in other languages
No names in other languages are held for this entry yet.
Article bodies are English and are not machine-translated. A name in another language is not a translation of the article.
In some programming languages, eval , short for evaluate, is a function which evaluates a string as though it were an expression in the language, and returns a result; in others, it executes multiple lines of code as though they had been included instead of the line including the eval . The input to eval is not necessarily a string; it may be structured representation of code, such as an abstract syntax tree (like Lisp forms), or of special type such as code (as in Python). The analog for a statement is exec, which executes a string (or code in other format) as if it were a statement; in some languages, such as Python, both are present, while in other languages only one of either eval or exec is.
In some programming languages, eval , short for evaluate, is a function which evaluates a string as though it were an expression in the language, and returns a result; in others, it executes multiple lines of code as though they had been included instead of the line including the eval . The input to eval is not necessarily a string; it may be structured representation of code, such as an abstract syntax tree (like Lisp forms), or of special type such as code (as in Python). The analog for a statement is exec, which executes a string (or code in other format) as if it were a statement; in some languages, such as Python, both are present, while in other languages only one of either eval or exec is. session["authenticated"] = False data = get_data() foo = eval(data) An attacker could supply the program with the string "session.update(authenticated=True)" as data, which would update the session dictionary to set an authenticated key to be True. To remedy this, all data which will be used with eval must be escaped, or it must be run without access to potentially harmful functions. foo = 2; alert(eval('foo + 2')); Example as a statement executor: foo = 2; eval('foo = foo + 2;alert(foo);'); One use of JavaScript's eval is to parse JSON text, perhaps as part of an Ajax framework. However, modern browsers provide JSON.parse as a more secure alternative for this task. A form which calls the + function with 1,2 and 3 as arguments. It returns 6. (+ 1 2 3) In Lisp any form is meant to be evaluated, therefore the call to + was performed. We can prevent Lisp from performing evaluation of a form by prefixing it with "'", for example: (setq form1 '(+ 1 2 3)) Now form1 contains a form that can be used by eval, for example: (eval form1) eval evaluated (+ 1 2 3) and returned 6. Lisp is well known to be very flexible and so is the eval function. For example, to evaluate the content of a string, the string would first have to be converted into a Lisp form using the read-from-string function and then the resulting form would have to be passed to eval : (eval (read-from-string "(format t \"Hello World!!!~%\")")) One major point of confusion is the question, in which context the symbols in the form will be evaluated. In the above example, form1 contains the symbol + . Evaluation of this symbol must yield the function for addition to make the example work as intended. Thus some dialects of Lisp allow an additional parameter for eval to specify the context of evaluation (similar to the optional arguments to Python's eval function - see below). An example in the Scheme dialect of Lisp (R 5 RS and later): Define some simple form as in the above example. (define form2 '(+ 5 2)) Value: form2 Evaluate the form within the initial context. A context for evaluation is called an "environment" in Scheme slang. (eval form2 user-initial-environment) Value: 7 Confuse the initial environment, so that + will be a name for the subtraction function. (environment-define user-initial-environment '+ -) Value: + Evaluate the form again. Notice that the returned value has changed. (eval form2 user-initial-environment) Value: 3 $foo = 2; print eval('$foo + 2'), "\n"; Example as a statement executor: $foo = 2; eval('$foo += 2; print "$foo\n";'); Perl also has eval blocks, which serves as its exception handling mechanism (see Exception handling syntax#Perl). This differs from the above use of eval with strings in that code inside eval blocks is interpreted at compile-time instead of run-time, so it is not the meaning of eval used in this article. Example returning a value: ===Lua=== In Lua 5.1, loadstring compiles Lua code into an anonymous function. Example as an expression evaluator: loadstring("print('Hello World!')")() Example to do the evaluation in two steps: a = 1 f = loadstring("return a + 1") -- compile the expression to an anonymous function print(f()) -- execute (and print the result '2') Lua 5.2 deprecates loadstring in favor of the existing load function, which has been augmented to accept strings. In addition, it allows providing the function's environment directly, as environments are now upvalues. load("print('Hello ' .. a)", "", "t", { a = "World!", print = print })() ((Hello World) =) cvx exec converts the PostScript expression (Hello World) = which pops the string "Hello World" off the stack and displays it on the screen, to have an executable type, then is executed. PostScript's run operator is similar in functionality but instead the interpreter interprets PostScript expressions in a file, itself. (file.ps) run >>> x = 1 >>> eval("x + 1") 2 >>> eval("x") 1 The eval function takes two optional arguments, global and locals , which allow the programmer to set up a restricted environment for the evaluation of the expression. The exec statement (or the exec function in Python 3.x) executes statements: exec example (interactive shell): >>> x = 1 >>> y = 1 >>> exec "x += 1; y -= 1" >>> x 2 >>> y 0 The most general form for evaluating statements/expressions is using code objects. Those can be created by invoking the compile() function and by telling it what kind of input it has to compile: an " exec " statement, an " eval " statement or a " single " statement: compile example (interactive shell): >>> x = 1 >>> y = 2 >>> eval(compile("print 'x + y = ', x + y", "compile-sample.py", "single")) x + y = 3 import std.stdio; void main() { int num = 0; mixin("num++;"); writeln(num); // Prints 1. } The above example will compile to exactly the same assembly language instructions as if " num++; " had been written directly instead of mixed in. The argument to mixin doesn't need to be a string literal, but arbitrary expressions resulting in a string value, including function calls, that can be evaluated at compile time. It is particularly useful when users need to programmatically choose the variable they want to read from. a = 1 eval('a + 1') # (evaluates to 2) evaluating within a context def get_binding(a) binding end eval('a + 1', get_binding(3)) # (evaluates to 4, because 'a' in the context of get_binding is 3) class Test; end Test.class_eval("def hello; return 'hello';end") # add a method 'hello' to this class Test.new.hello # evaluates to "hello" S" 2 2 + ." EVALUATE \ Outputs "4" Compiler evaluate:'1 + 2' Because class and method definitions are also implemented by message-sends (to class objects), even code changes are possible: Compiler evaluate:'Object subclass:#Foo' set foo { while {[incr i] PS > $foo = 2 PS > Invoke-Expression '$foo + 2' Example as a statement executor: PS > $foo = 2 PS > Invoke-Expression '$foo += 2; $foo' ==Microcode== In 1966 IBM Conversational Programming System (CPS) introduced a microprogrammed function EVAL to perform "interpretive evaluation of expressions which are written in a modified Polish-string notation" on an IBM System/360 Model 50. Microcoding this function was "substantially more" than five times faster compared to a program that interpreted an assignment statement. ==Theory== In theoretical computer science, a careful distinction is commonly made between eval and apply. Eval is understood to be the step of converting a quoted string into a callable function and its arguments, whereas apply is the actual call of the function with a given set of arguments. The distinction is particularly noticeable in functional languages, and languages based on lambda calculus, such as LISP and Scheme. Thus, for example, in Scheme, the distinction is between (eval '(f x) ) where the form (f x) is to be evaluated, and (apply f (list x)) where the function f is to be called with argument x. Eval and apply are the two interdependent components of the eval-apply cycle, which is the essence of evaluating Lisp, described in SICP. In category theory, the eval morphism is used to define the closed monoidal category. Thus, for example, the category of sets, with functions taken as morphisms, and the cartesian product taken as the product, forms a Cartesian closed category. Here, eval (or, properly speaking, apply) together with its right adjoint, currying, form the simply typed lambda calculus, which can be interpreted to be the morphisms of Cartesian closed categories. ==See also== Data as code ==References== ==External links== ANSI and GNU Common Lisp Document: eval function Python Library Reference: eval built-in function Jonathan Johnson on exposing classes to RBScript Examples of runtime evaluation in several languages on Rosetta Code
Text derived from https://en.wikipedia.org/w/index.php?oldid=1357930457 under CC BY-SA 4.0; modifications have been made.