Eval

Last updated

In some programming languages, eval , short for the English 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.

Contents

Eval and apply are instances of meta-circular evaluators, interpreters of a language that can be invoked within the language itself.[ citation needed ]

Security risks

Using eval with data from an untrusted source may introduce security vulnerabilities. For instance, assuming that the get_data() function gets data from the Internet, this Python code is insecure:

session['authenticated']=Falsedata=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.

Implementation

In interpreted languages, eval is almost always implemented with the same interpreter as normal code. In compiled languages, the same compiler used to compile programs may be embedded in programs using the eval function; separate interpreters are sometimes used, though this results in code duplication.

Programming languages

ECMAScript

JavaScript

In JavaScript, eval is something of a hybrid between an expression evaluator and a statement executor. It returns the result of the last expression evaluated.

Example as an expression evaluator:

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.

ActionScript

In ActionScript (Flash's programming language), eval cannot be used to evaluate arbitrary expressions. According to the Flash 8 documentation, its usage is limited to expressions which represent "the name of a variable, property, object, or movie clip to retrieve. This parameter can be either a String or a direct reference to the object instance." [1]

ActionScript 3 does not support eval.

The ActionScript 3 Eval Library [2] and the D.eval API [3] were development projects to create equivalents to eval in ActionScript 3. Both have ended, as Adobe Flash Player has reached its end-of-life.

Lisp

Lisp was the original language to make use of an eval function in 1958. In fact, definition of the eval function led to the first implementation of the language interpreter. [4] Before the eval function was defined, Lisp functions were manually compiled to assembly language statements. However, once the eval function had been manually compiled it was then used as part of a simple read-eval-print loop which formed the basis of the first Lisp interpreter.

Later versions of the Lisp eval function have also been implemented as compilers.

The eval function in Lisp expects a form to be evaluated and executed as argument. The return value of the given form will be the return value of the call to eval.

This is an example Lisp code:

; A form which calls the + function with 1,2 and 3 as arguments.; It returns 6.(+123); 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:(setqform1'(+123)); Now form1 contains a form that can be used by eval, for; example:(evalform1); 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 (R5RS and later):

;; Define some simple form as in the above example.(defineform2'(+52));Value: form2;; Evaluate the form within the initial context.;; A context for evaluation is called an "environment" in Scheme slang.(evalform2user-initial-environment);Value: 7;; Confuse the initial environment, so that + will be;; a name for the subtraction function.(environment-defineuser-initial-environment'+-);Value: +;; Evaluate the form again.;; Notice that the returned value has changed.(evalform2user-initial-environment);Value: 3

Perl

In Perl, the eval function is something of a hybrid between an expression evaluator and a statement executor. It returns the result of the last expression evaluated (all statements are expressions in Perl programming), and allows the final semicolon to be left off.

Example as an expression evaluator:

$foo=2;printeval('$foo + 2'),"\n";

Example as a statement executor:

$foo=2;eval('$foo += 2; print "$foo\n";');

Perl also has evalblocks, 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.

PHP

In PHP, eval executes code in a string almost exactly as if it had been put in the file instead of the call to eval(). The only exception is that errors are reported as coming from a call to eval(), and return statements become the result of the function.

Unlike some languages, the argument to eval must be a string of one or more complete statements, not just expressions; however, one can get the "expression" form of eval by putting the expression in a return statement, which causes eval to return the result of that expression.

Unlike some languages, PHP's eval is a "language construct" rather than a function, [5] and so cannot be used in some contexts where functions can be, like higher-order functions.

Example using echo:

<?php$foo="Hello, world!\n";eval('echo "$foo";');?>

Example returning a value:

<?php$foo="Goodbye, world!\n";//does not work in PHP5echoeval('return $foo;');?>

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=1f=loadstring("return a + 1")-- compile the expression to an anonymous functionprint(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})()

PostScript

PostScript's exec operator takes an operand — if it is a simple literal it pushes it back on the stack. If one takes a string containing a PostScript expression however, one can convert the string to an executable which then can be executed by the interpreter, for example:

((Hello World) =)cvxexec

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

Python

In Python, the eval function in its simplest form evaluates a single expression.

eval example (interactive shell):

>>> 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">>> x2>>> y0

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

D

D is a statically compiled language and therefore does not include an "eval" statement in the traditional sense, but does include the related "mixin" statement. The difference is that, where "eval" interprets a string as code at runtime, with a "mixin" the string is statically compiled like ordinary code and must be known at compile time. For example:

importstd.stdio;voidmain(){intnum=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.

ColdFusion

ColdFusion's evaluate function lets you evaluate a string expression at runtime.

<cfsetx="int(1+1)"><cfsety=Evaluate(x)>

It is particularly useful when you need to programatically choose the variable you want to read from.

<cfsetx=Evaluate("queryname.#columnname#[rownumber]")>

Ruby

The Ruby programming language interpreter offers an eval function similar to Python or Perl, and also allows a scope, or binding, to be specified.

Aside from specifying a function's binding, eval may also be used to evaluate an expression within a specific class definition binding or object instance binding, allowing classes to be extended with new methods specified in strings.

a=1eval('a + 1')#  (evaluates to 2)# evaluating within a contextdefget_binding(a)bindingendeval('a+1',get_binding(3))# (evaluates to 4, because 'a' in the context of get_binding is 3)
classTest;endTest.class_eval("def hello; return 'hello';end")# add a method 'hello' to this classTest.new.hello# evaluates to "hello"

Forth

Most standard implementations of Forth have two variants of eval: EVALUATE and INTERPRET.

Win32FORTH code example:

S"2 2 + ."EVALUATE\ Outputs "4"

BASIC

REALbasic

In REALbasic, there is a class called RBScript which can execute REALbasic code at runtime. RBScript is very sandboxed—only the most core language features are there, and you have to allow it access to things you want it to have. You can optionally assign an object to the context property. This allows for the code in RBScript to call functions and use properties of the context object. However, it is still limited to only understanding the most basic types, so if you have a function that returns a Dictionary or MySpiffyObject, RBScript will be unable to use it. You can also communicate with your RBScript through the Print and Input events.

VBScript

Microsoft's VBScript, which is an interpreted language, has two constructs. Eval is a function evaluator that can include calls to user-defined functions. (These functions may have side-effects such as changing the values of global variables.) Execute executes one or more colon-separated statements, which can change global state.

Both VBScript and JScript eval are available to developers of compiled Windows applications (written in languages which do not support Eval) through an ActiveX control called the Microsoft Script Control, whose Eval method can be called by application code. To support calling of user-defined functions, one must first initialize the control with the AddCode method, which loads a string (or a string resource) containing a library of user-defined functions defined in the language of one's choice, prior to calling Eval.

Visual Basic for Applications

Visual Basic for Applications (VBA), the programming language of Microsoft Office, is a virtual machine language where the runtime environment compiles and runs p-code. Its flavor of Eval supports only expression evaluation, where the expression may include user-defined functions and objects (but not user-defined variable names). Of note, the evaluator is different from VBS, and invocation of certain user-defined functions may work differently in VBA than the identical code in VBScript.

Smalltalk

As Smalltalk's compiler classes are part of the standard class library and usually present at run time, these can be used to evaluate a code string.

Compilerevaluate:'1 + 2'

Because class and method definitions are also implemented by message-sends (to class objects), even code changes are possible:

Compilerevaluate:'Object subclass:#Foo'

Tcl

The Tcl programming language has a command called eval, which executes the source code provided as an argument. Tcl represents all source code as strings, with curly braces acting as quotation marks, so that the argument to eval can have the same formatting as any other source code.

setfoo{while{[incri]<10}{puts"$i squared is [expr $i*$i]"}}eval$foo

bs

bs has an eval function that takes one string argument. The function is both an expression evaluator and a statement executor. In the latter role, it can also be used for error handling. The following examples and text are from the bs man page as appears in the UNIX System V Release 3.2 Programmer's Manual. [6]

The string argument is evaluated as a bs expression. The function is handy for converting numeric strings to numeric internal form. The eval can also be used as a crude form of indirection, as in the following (Note that, in bs, _ (underscore) is the concatenation operator.):

name="xyz" eval("++"_name)

which increments the variable xyz.

In addition, eval preceded by the interrogation operator, ?, permits the user to control bs error conditions. For example:

?eval("open(\"X\", \"XXX\", \"r\")")

returns the value zero if there is no file named "XXX" (instead of halting the user's program).

The following executes a goto to the label L (if it exists):

label="L"if!(?eval("goto "_label))puterr="no label"

Command-line interpreters

Unix shells

The eval command is present in all Unix shells, including the original "sh" (Bourne shell). It concatenates all the arguments with spaces, then re-parses and executes the result as a command. sh(1)    FreeBSD General Commands Manual

Windows PowerShell

In Windows PowerShell, the Invoke-Expression Cmdlet serves the same purpose as the eval function in programming languages like JavaScript, PHP and Python. The Cmdlet runs any Windows PowerShell expression that is provided as a command parameter in the form of a string and outputs the result of the specified expression. Usually, the output of the Cmdlet is of the same type as the result of executing the expression. However, if the result is an empty array, it outputs $null. In case the result is a single-element array, it outputs that single element. Similar to JavaScript, Windows PowerShell allows the final semicolon to be left off.

Example as an expression evaluator:

PS  > $foo=2PS  > invoke-expression'$foo + 2'

Example as a statement executor:

PS  > $foo=2PS  > 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. [7] Microcoding this function was "substantially more" than five times faster compared to a program that interpreted an assignment statement. [8]

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

where the form (f x) is to be evaluated, and

(applyf(listx))

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. [9]

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

Related Research Articles

<span class="mw-page-title-main">Common Lisp</span> Programming language standard

Common Lisp (CL) is a dialect of the Lisp programming language, published in American National Standards Institute (ANSI) standard document ANSI INCITS 226-1994 (S20018). The Common Lisp HyperSpec, a hyperlinked HTML version, has been derived from the ANSI Common Lisp standard.

<span class="mw-page-title-main">Lisp (programming language)</span> Programming language family

Lisp is a family of programming languages with a long history and a distinctive, fully parenthesized prefix notation. Originally specified in 1960, Lisp is the second-oldest high-level programming language still in common use, after Fortran. Lisp has changed since its early days, and many dialects have existed over its history. Today, the best-known general-purpose Lisp dialects are Common Lisp, Scheme, Racket, and Clojure.

<span class="mw-page-title-main">Quine (computing)</span> Self-replicating program

A quine is a computer program which takes no input and produces a copy of its own source code as its only output. The standard terms for these programs in the computability theory and computer science literature are "self-replicating programs", "self-reproducing programs", and "self-copying programs".

Rebol is a cross-platform data exchange language and a multi-paradigm dynamic programming language designed by Carl Sassenrath for network communications and distributed computing. It introduces the concept of dialecting: small, optimized, domain-specific languages for code and data, which is also the most notable property of the language according to its designer Carl Sassenrath:

Although it can be used for programming, writing functions, and performing processes, its greatest strength is the ability to easily create domain-specific languages or dialects

<span class="mw-page-title-main">Scheme (programming language)</span> Dialect of Lisp

Scheme is a dialect of the Lisp family of programming languages. Scheme was created during the 1970s at the MIT Computer Science and Artificial Intelligence Laboratory and released by its developers, Guy L. Steele and Gerald Jay Sussman, via a series of memos now known as the Lambda Papers. It was the first dialect of Lisp to choose lexical scope and the first to require implementations to perform tail-call optimization, giving stronger support for functional programming and associated techniques such as recursive algorithms. It was also one of the first programming languages to support first-class continuations. It had a significant influence on the effort that led to the development of Common Lisp.

<span class="mw-page-title-main">Lua (programming language)</span> Lightweight programming language

Lua is a lightweight, high-level, multi-paradigm programming language designed primarily for embedded use in applications. Lua is cross-platform, since the interpreter of compiled bytecode is written in ANSI C, and Lua has a relatively simple C API to embed it into applications.

In computer programming, the scope of a name binding is the part of a program where the name binding is valid; that is, where the name can be used to refer to the entity. In other parts of the program, the name may refer to a different entity, or to nothing at all. Scope helps prevent name collisions by allowing the same name to refer to different objects – as long as the names have separate scopes. The scope of a name binding is also known as the visibility of an entity, particularly in older or more technical literature—this is from the perspective of the referenced entity, not the referencing name.

In programming languages, a closure, also lexical closure or function closure, is a technique for implementing lexically scoped name binding in a language with first-class functions. Operationally, a closure is a record storing a function together with an environment. The environment is a mapping associating each free variable of the function with the value or reference to which the name was bound when the closure was created. Unlike a plain function, a closure allows the function to access those captured variables through the closure's copies of their values or references, even when the function is invoked outside their scope.

In computer science, a dynamic programming language is a class of high-level programming languages, which at runtime execute many common programming behaviours that static programming languages perform during compilation. These behaviors could include an extension of the program, by adding new code, by extending objects and definitions, or by modifying the type system. Although similar behaviors can be emulated in nearly any language, with varying degrees of difficulty, complexity and performance costs, dynamic languages provide direct tools to make use of them. Many of these features were first implemented as native features in the Lisp programming language.

In computer science, reflective programming or reflection is the ability of a process to examine, introspect, and modify its own structure and behavior.

Metaprogramming is a programming technique in which computer programs have the ability to treat other programs as their data. It means that a program can be designed to read, generate, analyze or transform other programs, and even modify itself while running. In some cases, this allows programmers to minimize the number of lines of code to express a solution, in turn reducing development time. It also allows programs a greater flexibility to efficiently handle new situations without recompilation.

<span class="mw-page-title-main">Conditional (computer programming)</span> Control flow statement that executes code according to some condition(s)

In computer science, conditionals are programming language commands for handling decisions. Specifically, conditionals perform different computations or actions depending on whether a programmer-defined Boolean condition evaluates to true or false. In terms of control flow, the decision is always achieved by selectively altering the control flow based on some condition . Although dynamic dispatch is not usually classified as a conditional construct, it is another way to select between alternatives at runtime. Conditional statements are the checkpoints in the programe that determines behaviour according to situation.

In computer programming, an entry point is the place in a program where the execution of a program begins, and where the program has access to command line arguments.

A read–eval–print loop (REPL), also termed an interactive toplevel or language shell, is a simple interactive computer programming environment that takes single user inputs, executes them, and returns the result to the user; a program written in a REPL environment is executed piecewise. The term usually refers to programming interfaces similar to the classic Lisp machine interactive environment. Common examples include command-line shells and similar environments for programming languages, and the technique is very characteristic of scripting languages.

In computer programming, homoiconicity is a property of some programming languages. A language is homoiconic if a program written in it can be manipulated as data using the language, and thus the program's internal representation can be inferred just by reading the program itself. This property is often summarized by saying that the language treats code as data.

<span class="mw-page-title-main">Python syntax and semantics</span> Set of rules defining correctly structured programs

The syntax of the Python programming language is the set of rules that defines how a Python program will be written and interpreted. The Python language has many similarities to Perl, C, and Java. However, there are some definite differences between the languages. It supports multiple programming paradigms, including structured, object-oriented programming, and functional programming, and boasts a dynamic type system and automatic memory management.

In computer programming, an anonymous function is a function definition that is not bound to an identifier. Anonymous functions are often arguments being passed to higher-order functions or used for constructing the result of a higher-order function that needs to return a function. If the function is only used once, or a limited number of times, an anonymous function may be syntactically lighter than using a named function. Anonymous functions are ubiquitous in functional programming languages and other languages with first-class functions, where they fulfil the same role for the function type as literals do for other data types.

This comparison of programming languages compares the features of language syntax (format) for over 50 computer programming languages.

<span class="mw-page-title-main">Scripting language</span> Programming language for run-time events

A scripting language or script language is a programming language that is used to manipulate, customize, and automate the facilities of an existing system. Scripting languages are usually interpreted at runtime rather than compiled.

Nemerle is a general-purpose, high-level, statically typed programming language designed for platforms using the Common Language Infrastructure (.NET/Mono). It offers functional, object-oriented, aspect-oriented, reflective and imperative features. It has a simple C#-like syntax and a powerful metaprogramming system.

References

  1. "Flash 8 LiveDocs". 2006-10-10. Archived from the original on 2006-10-10.
  2. ActionScript 3 Eval Library
  3. "The D.eval API". Archived from the original on 2013-03-14.
  4. John McCarthy, "History of Lisp - The Implementation of Lisp"
  5. "PHP: eval - Manual". PHP.net. Retrieved 2015-09-10.
  6. "Volume 1 Commands and Utilities". UNIX Programmer's Manual (PDF). AT&T. 1986. p. 41.
  7. Allen-Babcock. "Draft EVAL Microprogram" (PDF). Bitsavers.org. Retrieved Jan 17, 2016.
  8. Rochester, Nathaniel. "Conversational Programming System Progress Report" (PDF). Bitsavers.org. Retrieved Jan 17, 2016.
  9. The Metacircular Evaluator (SICP Section 4.1)