"NodeJS" (External Evaluation System)
Details
- Node.js Version 7.10.1 and higher is supported.
- Node.js is a JavaScript runtime built on Chrome's V8 JavaScript engine.
- To configure Node.js for use in the Wolfram Language, follow the instructions from the Configure NodeJS for ExternalEvaluate workflow.
ExternalEvaluate Usage
- ExternalEvaluate["NodeJS",code] executes the code string in a Node.js REPL and returns the results as a Wolfram Language expression.
- ExternalEvaluate["NodeJS""String",code] executes the code string in a Node.js REPL and does not interpret the results.
- Possible settings for "type" in ExternalEvaluate["NodeJS""type",code] include:
-
"Expression" attempt to convert to a Wolfram Language expression "String" give the raw string output by the external evaluator "ExternalObject" return the result as ExternalObject
Data Types
- The following JavaScript built-in types are supported:
-
Boolean True | False Boolean True/False values Number Integer,Real integer or real number String String string of characters Array List list of objects Map Association associative array Undefined Null undefined value - Any unsupported NodeJS type that is a function returns an ExternalFunction; any other unsupported NodeJS type returns an ExternalObject.
Supported External Operations
- ExternalOperation["Eval","code"] represents an external evaluation of "code".
- ExternalOperation["Eval","code",assoc] represents an external evaluation of "code" with parameters given by assoc.
- ExternalOperation["Call",func,arg1,arg2,…] calls the function func with the given arguments arg1, arg2, ….
- ExternalOperation["GetAttribute",obj,"attr"] gets the attribute "attr" of obj.
- ExternalOperation["SetAttribute",obj,"attr",val] sets the attribute "attr" of obj to the given value val.
- ExternalOperation["Cast",obj,"type"]casts obj to the given "type".
Examples
open all close allBasic Examples (2)
ExternalEvaluate["NodeJS", "2+2"]ExternalEvaluate["NodeJS", "[1,2,3,4]"]Use the File wrapper to execute code contained in a file:
path = Export[CreateFile[], "[1, 2, 'hello']", "String"]ExternalEvaluate["NodeJS", File[path]]Deploy code using CloudDeploy and then run the code directly from a CloudObject:
cobj = CloudExport["[1, 2, 'hello']", "String"]ExternalEvaluate["NodeJS", cobj]Use a URL wrapper to directly run code hosted online:
functions = URL["https://exampledata.wolfram.com/script.js"]ExternalEvaluate["NodeJS", {functions, "cube(3)"}]Scope (27)
session = StartExternalSession["NodeJS"]Evaluate a Boolean statement in NodeJS and return it:
ExternalEvaluate[session, "true || false"]Concatenate strings in NodeJS and return the result:
ExternalEvaluate[session, "'hello'+' '+'world'"]Create an ExternalFunction with NodeJS:
incr = ExternalFunction[session, "x => x + 1"]incr[3]DeleteObject[session]Session Options (8)
"ReturnType" (3)
For NodeJS, the default return type is "Expression":
ExternalEvaluate["NodeJS", "2+2"] === ExternalEvaluate["NodeJS" -> "Expression", "2+2"]Numbers, strings, lists and associations are automatically imported for the "Expression" return type:
ExternalEvaluate["NodeJS", "[2, 3]"]The return type of "String" returns a string, using JSON:
ExternalEvaluate["NodeJS" -> "String", "[1, 2, 'א']"]StringQ[%]"Evaluator" (1)
"SessionProlog" (1)
"SessionEpilog" (1)
"Prolog" (1)
Command Options (10)
"Command" (4)
When a string is provided, the command is directly executed:
ExternalEvaluate["NodeJS", "[1, 2, 3]"]The above is equivalent to writing the command using this form:
ExternalEvaluate["NodeJS", <|"Command" -> "[1, 2, 3]"|>]Use a File wrapper to run the code from a file:
ExternalEvaluate["NodeJS", {
<|"Command" -> File["ExampleData/powers.js"]|>,
<|"Command" -> "square(3)"|>,
<|"Command" -> "cube(3)"|>
}]The above is equivalent to writing the command using this form:
ExternalEvaluate["NodeJS", {
File["ExampleData/powers.js"],
"square(3)",
"cube(3)"
}]Use a URL wrapper to directly run code hosted online:
ExternalEvaluate["NodeJS", {
<|"Command" -> URL["https://exampledata.wolfram.com/script.js"]|>,
<|"Command" -> "cube(3)"|>
}]The above is equivalent to writing the command using this form:
ExternalEvaluate["NodeJS", {
URL["https://exampledata.wolfram.com/script.js"],
"cube(3)"
}]Put code in a CloudObject:
cloudObj = CloudExport["console.log('Hello World!')", "Text", CloudObject["hello-world-js"]]Evaluate directly from the cloud:
ExternalEvaluate["NodeJS", <|"Command" -> cloudObj|>]The above is equivalent to writing the command using this form:
ExternalEvaluate["NodeJS", cloudObj]"ReturnType" (1)
"Arguments" (2)
Use "Arguments" to call the command with arguments:
ExternalEvaluate[
"NodeJS",
<|"Command" -> "(a, b) => a + b", "Arguments" -> {1, 2}|>
]For a single argument, you do not need to use a list:
ExternalEvaluate[
"NodeJS",
<|"Command" -> "a => a", "Arguments" -> 1|>
]If you need to pass a list as the first argument, wrap it with an extra list explicitly:
ExternalEvaluate[
"NodeJS",
{
<|"Command" -> "a => a", "Arguments" -> 1|>,
<|"Command" -> "a => a", "Arguments" -> {1}|>,
<|"Command" -> "a => a", "Arguments" -> {{1}}|>
}
]You can name a function in "Command" and directly call it with "Arguments":
ExternalEvaluate[
"NodeJS",
<|"Command" -> "parseInt", "Arguments" -> "123"|>
]The same result can be archived by using a Rule:
ExternalEvaluate[
"NodeJS",
"parseInt" -> "123"
]An alternative method is to define an ExternalFunction:
session = StartExternalSession["NodeJS"]function = ExternalFunction[session, "parseInt"]function["123"]DeleteObject[session]"Constants" (1)
"TemplateArguments" (2)
When running a command, you can inline a TemplateExpression:
x = RandomReal[]
ExternalEvaluate["NodeJS", "1 + <* x *>"]You can explicitly fill TemplateSlot using "TemplateArguments":
ExternalEvaluate[
"NodeJS",
<|"Command" -> "2 + ``", "TemplateArguments" -> 1|>
]If you need to pass a list as the first argument, wrap it with an extra list explicitly:
ExternalEvaluate[
"NodeJS",
{
<|"Command" -> "JSON.stringify(``)", "TemplateArguments" -> 1|>,
<|"Command" -> "JSON.stringify(``)", "TemplateArguments" -> {1}|>,
<|"Command" -> "JSON.stringify(``)", "TemplateArguments" -> {{1, 2}}|>
}
]You can name template slots and use an Association to pass named arguments to the template:
ExternalEvaluate[
"Python",
<|"Command" -> "(`x` - `y` + `z`)", "TemplateArguments" -> <|"x" -> 10, "y" -> 3, "z" -> 2|>|>
]External Operations (8)
"Eval" (1)
Run an ExternalOperation that represents arbitrary code evaluation in Python:
ExternalEvaluate["NodeJS", ExternalOperation["Eval", "2+2"]]Use the second argument to pass an evaluation context:
ExternalEvaluate["NodeJS", ExternalOperation["Eval", "a + b", <|"a" -> 2, "b" -> 3|>]]"Call" (3)
Define an ExternalOperation that creates a function in NodeJS:
op = ExternalOperation["Eval", "Math.max"]Call the function by running the ExternalOperation "Call":
call = ExternalOperation["Call", op, 1, 2]Run the operation using ExternalEvaluate:
ExternalEvaluate["NodeJS", call]Any argument of the "Call" operation can be an ExternalOperation:
ExternalEvaluate["NodeJS", ExternalOperation["Call", op, 1, ExternalOperation["Eval", "2+2"]]]Arguments can also be passed directly in ExternalEvaluate by doing the following:
ExternalEvaluate["NodeJS", op -> {1, 2}]The result is equivalent to running the following NodeJS code:
ExternalEvaluate["NodeJS", "Math.max(1, 2)"]Create an ExternalFunction for the NodeJS function max:
max = ExternalFunction["NodeJS", "Math.max"]Call the function by running the operation "Call":
ExternalEvaluate["NodeJS", ExternalOperation["Call", max, 1, 2]]The same result can be achieved by doing the following:
ExternalEvaluate["NodeJS", max -> {1, 2}]Create an ExternalFunction for a NodeJS function:
session = StartExternalSession["NodeJS"]max = ExternalEvaluate[session, <|"Command" -> "Math.max", "ReturnType" -> "ExternalObject"|>]Call the function by running the operation "Call":
ExternalEvaluate[session, ExternalOperation["Call", max, 1, 2]]The same result can be achieved by doing the following:
ExternalEvaluate[session, max -> {1, 2}]Or by using ExternalObject subvalues:
ExternalObject[max][ExternalOperation["Call", 1, 2]]DeleteObject[session]"GetAttribute" (2)
Start a NodeJS session to work with dates:
session = StartExternalSession["NodeJS"];Return an ExternalObject for a "Math" object:
math = ExternalEvaluate[session, <|"Command" -> "Math", "ReturnType" -> "ExternalObject"|>]Extract a function by using "GetAttribute":
ExternalEvaluate[session, ExternalOperation["GetAttribute", math, "max"]]ExternalEvaluate[session, ExternalOperation["GetAttribute", math, "max"] -> {1, 2}]The result is equivalent to running the following NodeJS code:
ExternalEvaluate[session, "Math.max(1, 2)"]DeleteObject[session]Create an ExternalObject that represents the "Math" object:
session = StartExternalSession["NodeJS"]math = ExternalEvaluate[session, <|"Command" -> "Math", "ReturnType" -> "ExternalObject"|>]Use ExternalOperation to get a function:
math[ExternalOperation["GetAttribute", "max"]]For most evaluators, "GetAttribute" is the default operation, and ExternalOperation can be omitted:
math["max"]The function can be called directly by chaining a "Call" operation:
math["max", ExternalOperation["Call", 1, 2]]Function call can also be archived by doing the following:
math["max" -> {1, 2}]DeleteObject[session]"SetAttribute" (1)
Start a NodeJS session to work with an object:
session = StartExternalSession["NodeJS"];Create an object in NodeJS; when creating a single object, it must be surrounded by parentheses:
obj = ExternalEvaluate[session, <|"Command" -> "({})", "ReturnType" -> "ExternalObject"|>]ExternalEvaluate[session, ExternalOperation["SetAttribute", obj, "b", 6]]Check that the attribute was set to 6:
ExternalEvaluate[session, ExternalOperation["GetAttribute", obj, "b"]]The result is equivalent to running the following NodeJS code:
ExternalEvaluate[session, "obj = {}; obj.b = 6"]DeleteObject[session]"Cast" (1)
Create an ExternalObject that represents an array:
session = StartExternalSession["NodeJS"];now = ExternalEvaluate[session, <|"Command" -> "[1, 2, 3]", "ReturnType" -> "ExternalObject"|>]Use "Expression" to return the object as a Wolfram Language expression:
ExternalEvaluate[session, ExternalOperation["Cast", now, "Expression"]]The Cast operation can also run in ExternalObject subvalues:
now[ExternalOperation["Cast", "Expression"]]The symbol Expression is a shortcut for the same:
now[Expression]Return the object as a string:
now[ExternalOperation["Cast", "String"]]The symbol String is a shortcut for the same:
now[String]Return the object as an ExternalObject:
now[ExternalOperation["Cast", "ExternalObject"]]The symbol ExternalObject is a shortcut for the same:
now[ExternalObject]The same can be achieved by using "ReturnType" in ExternalEvaluate:
ExternalEvaluate[session, <|"Command" -> now, "ReturnType" -> "String"|>]DeleteObject[session]Applications (2)
Define the Range function in NodeJS:
range[n1_, n2_, step_ : 1] :=
ExternalEvaluate["NodeJS", <|
"Command" -> "(n1, n2, step=1) => {
if (! n2 && ! n2 == 0) {
return range(0,n1-1,step)
}
const arr=[];
for (let i=n1;i<=n2;i+=step) {
arr.push(i)
}
return arr
}",
"Arguments" -> {n1, n2, step}
|>]range[1, 10]Use prettier to reformat a string of JavaScript code:
reformatJavascriptCode[code_] :=
Last @ ExternalEvaluate["NodeJS", {
"const prettier = require('prettier')",
<|
"Command" -> "prettier.format",
"Arguments" -> code
|>
}]reformatJavascriptCode["foo(reallyLongArg(), omgSoManyParameters(), IShouldRefactorThis(), isThereSeriouslyAnotherOne());"]Related Guides
Related Workflows
- Configure NodeJS for ExternalEvaluate
History
Introduced in 2018 (11.3)