We are in early beta, and may not have tested Walnut in your browser/OS combination yet, so it may not look perfect. Thanks for your patience! ×
We are in early beta, and the documentation may be incomplete and/or have missing links. Thanks for your patience! ×

Walnut Core language reference

The Walnut Core language is a common language which is a subset of the world and visualization definition languages. It defines common syntax and semantics for values and their operations.

This document covers the whole language and provides specific details, but is not intended as a guide on how to use it. Read the environment design or agent design document first if you're new to Walnut

Lexical conventions

All Walnut input must be UTF-8 encoded text. The syntax is free-form, i.e. no rules on the use of whitespace are enforced. Whitespace is used only to delimit tokens, and no whitespace is required between tokens if there is no ambiguity: you need whitespace to separate variable from 9 because variable9 is a valid token, but a+b needs no whitespace between a, + and b. Whitespace is considered as any sequence of the ASCII space, carriage return, line feed or tabulation characters.

Any # character found outside a string literal begins a comment, which continues until the next carriage return or line feed character. The comment is completely ignored and has no effect on the semantics

A name character is any ASCII letter, number, or the underscore (_) character.

A name is a token which starts with a lowercase ASCII character, followed by zero or more name characters. They are typically used to denote variables, fields, arguments.

A label is a token which starts with an uppercase ASCII character, followed by zero or more name characters. They are typically used to denote constructors and types.

The following symbols have special meaning:

=  |  [  ]  ,  :  .  {  }  (  )  +
-  *  /  % == != <= >=  <  >  ?  _

Two-character symbols are considered a single token, and can not have whitespace between the two characters.

A string literal is a token consisting in any sequence of string characters enclosed by double quotes ("). A string character can be any unicode character except for double quotes and backslash (\). Other allowed string characters are the escape sequences in the table below. String literals may contain # symbols that do not start comments, and whitespace characters that are relevant.

Escape sequence Denoted character
\\ Backslash
\" Double quote
\b ASCII backspace
\f ASCII form feed
\n ASCII line feed
\r ASCII carraiage return
\t ASCII tab

A numeric literal is a token consisting on an optional "-" sign, followed by a non-empty sequence of digits (which can only start with "0" if it is exactly "0"), followed by an optional fractional part followed by an optional exponent part. A fractional part consists in a "." followed by a non-empty sequence of digits. An exponent part consists in a "e" or "E" character, followed by an optional "+" or "-" sign, followed by a non-empty sequence of digits. Note that this specification is exactly the one used in JSON.

The following words have special meaning and are considered as a keyword token instead of a name or label:

action actuator_for and agents_alternation
as config Dict do
else end_condition for if
then in import not
performance or role sensor
state type valid_when  

Types

Every value in Walnut has one of the basic types, or a user defined type. A type can be seen as a set of possible values with several allowed operations.

Some elements in Walnut world descriptions are explicitly typed. The purpose of doing this is:

  • Documentation, making clear the purposes of the world designer
  • Better detection and reporting of errors
  • Simplification of automatic tools (the environment editor is able to look at the types and figure out what is a grid with locations).

As a convention used in the syntax, the colon “:” is used to denote “has the type”, and is always followed by a type definition.

Types can be explicitly named in the syntax, using the following EBNF syntax

type ::= "?"
     |   "String"
     |   "Number"
     |   "Boolean"
     |   "Null"
     |   "[" type "]"
     |   "Dict" "{" type "}"
     |   constructor ("|" constructor)*
     |   LABEL

Simple Types

Provided basic types are:

  • String: unicode text string.
  • Number: double precision floating point. The values follow the semantics of IEEE-754.
  • Null: A unit type, only containing a value also called Null
  • Boolean: Truth values, values are True and False

There are no integer types. This design decision was taken to make interaction with JavaScript code easier and semantics more consistent.

Built-in Data structures

Walnut provides types to describe values with many sub-values (data structures)

You can define some basic data structures as:

  • [T], where T is any type, is a list of elements of type T. Lists are mutable and can change length during runtime.
  • Dict {T}, where T is any type, is a mapping from strings to elements of type T. Dictionaries are mutable and values can be added or removed.

Custom Types

Walnut allows you to define custom types which provide the role of simple labeled structures, enumerations, or complex data structures. Custom types are always defined based on constructor functions, which are essentially functions that “build” a value of the custom type. A custom type can have one or many constructors, and each constructor of a type can have different quantity or kinds of arguments.

You can define custom types defining the constructors for the type which can take arguments, with the constructor ("|" constructor)* syntax.

The syntax for each constructor is:

constructor ::= LABEL [ "(" (plain_fields | labeled_fields) ")" ]
plain_fields ::= type ("," type)*
labeled_fields ::= labeled_field ("," labeled_field)*
labeled_field ::= NAME ":" type

For example:

  • Red | Green | Blue is a type with two values, Red, Green and Blue
  • Point(Number, Number) is a type with a value for each different pair of numbers. Point is a constructor function for generating values of this type, like Point(3.14, -5)
  • Point(x: Number, y:Number) is a type with a value for each different pair of numbers. Point is a constructor function for generating values of this type, like Point(3.14, -5)

The semantics of the | operator is disjoint union. Each constructor builds the equivalent of a cartesian product of its fields.

Type declarations and references

Finally, if you use a single label which has been declared as a type in the world definition, it is a reference to the declared type. Types can only be declared in the world definition with

type_declaration ::= "type" LABEL "=" type

For types that consist on a single constructor option, the following syntactic shorthand is allowed:

type_declaration ::= "type" constructor

A declaration of this form (type SomeLabel(args)) has the exact same meaning as type SomeLabel = SomeLabel(args).

Recursive and mutually recursive declarations are allowed, as long as they are not just a trivial circle with no information; so the following are not allowed

# These are invalid!
type ARose = ARose
type Widget = Trinket
type Trinket = Widget

Each constructor will be tied to a single type. This means that you can not use the same labels in two types. This is an example of invalid repeats of constructor labels

# These are invalid! Left and Right constructors are repeated
type Direction = Up | Down | Left | Right
type PoliticalAlignment = Left | Right

Expressions

An expression is a formula that can be used to compute a value. An Walnut expression may have a value which depends on the value set to some variables; for example the value of the expression a + 1 depends on the value assigned to a at the time that this expression is evaluated. This assignment of variable to values is called a “context”. Evaluation never modifies the context nor have any other side effect.

In some cases an expression that is syntactically correct can not be evaluated, for example a+1 can not be evaluated if the current value of a is a string, and 1/x can not be evaluated if the current value of x is 0. In that case we will say that the expression evaluation “fails”.

Expressions are built with operands and operators. Walnut has a few unary operators, several binary operators, and a ternary operator. Some operators have higher precedence than others, so when evaluating A*B+C and C+A*B the multiplication is always performed first because the multiplication operator has a higher precedence than the addition operator. Operators with the same precedence are associated left to right.

The complete list of operators ordered by precedence is

Operators Description
(...) Parenthesis grouping; these are used to force higher precedence following standard conventions in math

func(...)

mod.func(...)

Constructor(...)

[ ... ]

Function Call

Module Call

Constructor Call

List construction / comprehension

.

[]

Field access (value.fieldName)

Index access (value[index])

+, - Unary plus and minus (sign change)
*, /, % Multiplicative operators: product, division, modulus
+, - Additive operators: addition, subtraction

==, !=

<, >

<=, >=

in

Relational operators: equality, inequality

less than, greater than

less than or equal, greater than or equal

membership test

not Boolean negation
and Boolean conjunction
or Boolean disjunction
if…then…else… Conditional expression

Operands

This section describe the elementary building blocks of expressions, called “atoms”.

atom ::= "(" expression ")"
     |   NUMBER_LITERAL
     |   STRING_LITERAL
     |   NAME
     |   NAME "(" [call_arguments] ")"
     |   NAME "." NAME "(" [call_arguments] ")"
     |   LABEL ["(" call_arguments ")"]
     |   "[" expression_list "]"
     |   "[" expression comprehension "]"

call_arguments ::= arguments
               |   expression_list

arguments ::= NAME "=" expression ("," NAME "=" expression)*
expression_list ::= expression ("," expression)*
comprehension ::= "for" pattern "in" expression ["if" expression]

A parenthesized expression “(e)” evaluates in the same way as e. The only purpose of parenthesis is to override operator precedence.

Number and string literals evaluate always to the value expressed, and never fail.

A single name evaluates to the value of the variable with that name. The evaluation fails only when the variable is not defined in the current context.

A built-in call expression “func(arg1, arg2, arg3)” evaluates by calling the built-in function with the given name passing the arguments (which are evaluated in the same context). The meaning of each built-in function is described in the [Built-ins] section. The evaluation fails if the built-in with that name does not exist, or if the number, names or types of the arguments are incompatible with the function. Evaluation of the arguments also means that the evaluation of the call fails. Some built-in functions have also additional conditions on the values of the arguments required for a successful evaluation.

A module call expression “mod.func(arg1, arg2, arg3)” looks up the function with the given name in the specified module, and calls it passing the arguments. The meaning of each function should be documented in the module documentation. The evaluation fails if there has been no module imported with the given module name. It also fails if the module does not contain a function with the given names. Again, evaluation fails if the number, names or types of the arguments are incompatible with the function. Evaluation of the arguments also means that the evaluation of the call fails. The function may also have additional conditions on the values of the arguments required for a successful evaluation; check its documentation for details.

A constructor call “Label” or “Label(arg1, arg2)” produces a new value with the given constructor. The type of the value is the type defined where the constructor was defined. If no constructor with the given label was defined, evaluation fails. If the evaluation of any argument fails, the constructor call fails. Evaluation also fails if the number of arguments does not match exactly the number of arguments on the constructor definition. If the arguments are unlabeled, each argument must have the type of the constructor parameter in the same position for a successful evaluation. If the arguments are named, the set of fields in the call must be the same set of fields on the constructor declaration, and the type of the argument must match the declared type for each field.

A list construction “[e1, e2, e3] evaluates to a new list value. Each comma-separated expression is evaluated, and if successful, added to the resulting list. If any expression evaluation fails, the list construction fails.

A list comprehension [e1 for p in some_list if condition] evaluates to a list where each element is built by applying some function to elements of another list, and optionally some filtering. Its semantics also depend on the use of [patterns]. The evaluation of a list comprehension starts by evaluating the expression after in, which must successfully evaluate to a list value to avoid failure. After that, each value in the resulting list is matched with the pattern (a non-match results in failure), which defines an updated context. Assuming no condition, then the initial expression is evaluated on that updated context and the result is added to the final list if successful (failure produces failure of the comprehension). If a condition is present, it is evaluated on the updated context; a False result means that this element is skipped and has no effect on the result, and a non Boolean condition or failure means that the list comprehension fails.

Element access

Walnut defines a single operator e1[e2] to access elements inside values of non-simple types (list, dictionaries, and custom types). Additionally, the syntax e1.field is equivalent to e1["field"].

The EBNF syntax for element access is:

primary ::= atom trailing*
trailing ::= "." NAME
         |   "[" expression "]"

Both expressions must evaluate successfully. The left one must evaluate to a non simple type or string. If it evaluates to a dictionary, the right expression must evaluate to a string. The string must be a key present in the dictionary, and the result will be the value attached to that key. For custom values, the right expression can evaluate to a string that must be the name of one of the fields, and the result will be the value of that field used when calling the constructor. Alternatively, the right expression can evaluate to a number which must be a non-negative integer smaller than the number of fields in the constructor, and the expression evaluates to the field in the given position counting from 0. If the left expression evaluates to a list or string, the right expression must evaluate to a Number; for success the number must be a non-negative integer smaller than the length of the list/string. For lists, the evaluation results in the element of the list with the position indicated by the right expression (counting from 0). For strings, the evaluation results in a string with length 1 containing the character at the position indicated by the right expression (again, counting from 0).

Arithmetic operators

The unary + and - operator only succeed on numeric operands. The + operator has no effect, while the - operand returns the negated value.

The syntax is

unary_expression ::= primary
                 |   "+" unary_expression
                 |   "-" unary_expression

All binary arithmetic operators (+, -, *, /, %) are able to successfully operate between two numeric values and return a numeric value. The division and modulus operators fail when the right operand evaluates to 0.

In addition to this, the + operator can operate between two lists (returning a new list with the concatenation of the two operands). It can also concatenate two strings. It can also operate between two dictionaries resulting in their union (the right operand has precedence in this case for keys present in both dictionaries).

Any other combination of operand types with arithmetic operators results in evaluation failure.

Syntax for arithmetic expressions is

additive_expression ::= multiplicative_expression (addop multiplicative_expression)*
    addop ::= "+" | "-"
multiplicative_expression ::= unary_expression (mulop unary_expression)*
    mulop ::= "*" | "/" | "%"

Relational operators

Relational operators allow comparing two values and always return a Boolean. Evaluation of both operands must succeed.

The “==” operator can be applied to operands of any type, but always returns False if operands have different types. If the operands are of equal types, it returns True iff the values are the same. For strings, booleans, and Null this has the intuitive meaning. For numbers this has the equality meaning of IEEE-754 (which is obvious in general, but it has special cases for NaNs and signed zeroes). Two lists are equal if they have the same length and each value is equal to the corresponding one in the other list (using recursively this definition of equality). Two dictionaries are equal if they have the same keys, and the attached values for each key are recursively equal. Two custom values are equal if they were built with the same constructor and the values passed to each field of the constructor are equal.

The “!=” operator can also receive operands of any type, and always returns the negation of the value that == would produce.

Comparison operators <, >, <= and >= fail unless both operands are of the same type which must be number, string, or lists of comparable elements. The ordering relation for each type is:

  • Numbers following the ordering of IEEE-754
  • Strings are compared lexicographically, by code-point of each character. If one is a prefix of the other, the shorter one is considered smaller.
  • Lists are compared lexicographically, element by element. If one is a prefix of the other, the shorter one is considered smaller.

The in operator fails if the right operator is not a list, dictionary or custom value. For lists it returns True iff the left operand evaluates to a value equal to any item in the list. For dictionaries it returns True iff the left operand evaluates to a key present in the dictionary. For custom values it returns True if the left operand evaluates to a string with one of the field names, or to a number which is a valid index on the value.

Syntax for relations is

relational_expression ::= additive_expression (relop additive_expression)*
    relop ::= "==" | "!=" | "<=" | "<" | ">" | ">=" | "in"

Boolean operators

Boolean operators work only on Boolean values. The binary operators are non-strict, meaning that they don't need a successful evaluation of the right operand if the left operand evaluates successfuly to something that determines the result.

The negation operator not succeeds if the expression after it evaluates to a Boolean, and returns the opposite boolean value.

The conjunction operator and evaluates the left operand. If the evaluation of the operand fails or returns a non-boolean then the evaluation of the conjunction fails. If the left operand evaluates to False, the right operand is not evaluated, and the conjunction returns False. Otherwise, the right operand is evaluated, and the conjunction succeeds and returns that value if the result is boolean, or fails otherwise.

The disjunction operator or evaluates the left operand. If the evaluation of the operand fails or returns a non-boolean then the evaluation of the disjunction fails. If the left operand evaluates to True, the right operand is not evaluated, and the disjunction returns True. Otherwise, the right operand is evaluated, and the disjunction succeeds and returns that value if the result is boolean, or fails otherwise.

Syntax for boolean operations is

or_test ::= and_test ("or" and_test)*
and_test ::= not_test ("and" not_test)*
not_test ::= ("not" not_test)
         |   relational_expression

Conditional operator

The conditional operator if cond then e1 else e2 allows choosing between two values based on a boolean condition. The operator is not strict, evaluating only the operands it needs.

Evaluation of the condition must succeed and return a Boolean value, otherwise the evaluation of the conditional expression fails. If the condition value is True, the whole expression is equivalent to the evaluation of the expression after then; otherwise the whole expression is equivalent to the evaluation of the expression after else.

The syntax of this operator and the syntax of expressions is defined as

ifelse ::= "if" or_test "then" or_test "else" or_test
       |   or_test
expression ::= ifelse

The syntactic definition is written in a way that avoids ambiguous chaining of conditional expressions without explicitly using parenthesis to disambiguate.

Patterns

Walnut has a form of pattern matching that provides a practical way of checking the form of a data structure, and easily assigning relevant components of that data to variables. Patterns are used in list comprehensions and in the world definition to select which actuator to apply for an action.

The pattern behavior can be described by detailing which values it does match (a pattern only matches a value or not, there is no middle ground), and which variables it add to the context when it matches. A non-match never modifies variables. Variable modifications typically affect only the evaluation context of elements “near” the pattern (for list comprehensions, only the list comprehension, and for actuators, only the actuator with the pattern).

Syntax for patterns is

pattern ::= NAME
        |   "_"
        |   STRING_LITERAL
        |   NUMBER_LITERAL
        |   LABEL ["(" pattern ("," pattern)* ")"]
        |   LABEL ["(" NAME "=" pattern ("," NAME "=" pattern)* ")"]
        |   list_pattern
list_pattern ::= "[" [element_pattern ("," element_pattern)* ] "]"
    element_pattern ::= ["*"] pattern

A single name used as a pattern always match, and binds the variable with that name to the value matched.

A “_” pattern always match, and does not modify the context.

String and number constants only match the exact string or number they represent, without modifying the context.

A pattern starting with a label matches only custom values that:

  • Are built with the constructor with that label
  • have the same number of arguments that the pattern.
  • if the pattern arguments have field names, the fields must mutch the constructor fields
  • each pattern (by field or position) must match the corresponding field of the value

If the value matches, the changes in the context are the changes done by all the sub-patterns.

A list pattern matches only with lists. In addition to the syntax shown, at most one of the element patterns can have the * prefix. If no star prefixed pattern appears, the list patterns matches lists with as many elements as sub-patterns there are, and where each element matches the corresponding pattern. In that case, the context is updated according to all the updates in the sub-patterns. If a star prefixed pattern appears, a match requires a list with at least as many elements as sub-patterns without star there are. The original value is split into 3 sub-lists: the head is the list prefix with as many elements as sub patterns are before the star prefix, the tail is the list suffix with as many elements as sub-patterns are after the start prefix, and the body is the list slice between the head and the tail. A positive match requires that the head matches element by element the patterns before the star and the body matches the star-prefixed pattern and the tail elements match the patterns after the star prefixed one. Again, the context modification is the list of modifications of each subpattern

Built-ins

The following is a list of Walnut built-in functions, grouped by category with a summary. Some functions appear in multiple categories. After that there is a full specification of each function, in alphabetical order.

Mathematical operations
  • abs : Absolute value of a number
  • ceil : Closest integer above given number
  • floor : Closest integer below given number
  • is_integer : Check if a number is an integer value or not
  • pow : Exponentiation of two numbers
  • round : Rounding numbers to closest integer, or with a given precision
Aggregation
  • all : Returns True iff all elements in a list are True
  • any : Returns True iff any element in a list is True
  • max : Return the largest element of a list
  • min : Return the smallest element of a list
  • product : Returns the product of a list of numbers
  • sum : Returns the sum of a list of numbers
Conversion
  • number : Converts a string with a number representation to number
  • string : Converts any value to a string representation
  • dictionary : Converts a list of pairs into a dictionary
List operations
  • count : Return the number of occurrences of an item on a list
  • enumerate : Returns the list of pairs index/item in a list.
  • index : Return the position of occurrences of an item on a list
  • len : Returns the length of a list
  • range : Generates a list with a sequence or any arithmetic progression
  • reversed : Returns a reversed version of a list
  • slice : Returns a sublist of a list
  • sorted : Returns a sorted version of a list
  • zip : Groups many list into a list of tuples
Dictionary operations
  • keys : returns the list of keys in a dictionary
  • values : returns the list of items in a dictionary
  • enumerate : returns the list of pairs key/item in a dictionary
  • get : returns an item of a dictionary with a given key if present, or a default if not
  • len : Returns the key count in a dictionary
Custom types
  • as_dictionary : returns a dictionary with the fields as keys, items as values
  • enumerate : returns the list of pairs field/element in a custom value
  • fields : returns a list with a value's field names
  • label : returns a string with the constructor label of a custom value
  • len : Returns the constructor argument count for a custom value
  • updated : returns a copy of a value with some of its fields modified
String manipulation
  • count : Returns the number of occurrences of a substring
  • ends_with : Checks if a string ends with a given suffix
  • index : Returns the index of a substring in a given string
  • join : Concatenates an array of strings with an optional separator
  • len : Returns the length of a string
  • lower : Returns a lowercase version of a string
  • replace : Replace occurrences of a substring for another substring
  • slice : Returns a substring
  • split : Split a list in substrings using some separator
  • starts_with : Checks if a string starts with a given prefix
  • strip : Remove leading and/or trailing whitespace
  • upper : Returns an uppercase version of a string
Generic
  • type_of : returns a string description about the type of a value.

abs

Type: abs(Number): Number

Return the absolute value of the argument.

all

Type: all([Boolean]): Boolean

Returns True if the input list is empty or if all its elements are True. Returns False otherwise.

It is typically used with list comprehensions to check a property over a list. For example, to check that all the numbers in a list are between 0 and 1 you can write

all([0 <= x and x <= 1 for x in my_list])

any

Type: all([Boolean]): Boolean

Returns False if the input list is empty or if all its elements are False. Returns True otherwise.

It is typically used with list comprehensions to find if some item in a list satisfies a property. For example, to check if a list contains any negative number you can write

any([x < 0 for x in my_list])

as_dictionary

TODO

ceil

Type: ceil(Number): Number

Return the closest integer number above or equal the given argument.

count

Type:

  • count([?], ?): Number
  • count(String, String): Number

If a List and an item are given, return the number of occurrences of the item in the list.

If two strings are given, return the number of non-overlapping occurrences of the second argument within the first.

dictionary

TODO
  • dictionary: Converts a list of pairs into a dictionary

ends_with

Type: ends_with(String, String): Boolean

Checks if a string ends with a given suffix.

enumerate

TODO
  • enumerate: Returns the list of pairs index/item in a list.
  • enumerate: returns the list of pairs key/item in a dictionary
  • enumerate: returns the list of pairs field/element in a custom value

fields

Type: fields(CustomType): [String]

Returns a list with the value's field names. If the value's fields are unlabeled, a list with fields indexes is returned. So, in either case, the returned list can be used to iterate on the value's fields. If the value has no fields, an empty list is returned.

floor

Type: floor(Number): Number

Return the closest integer number below or equal to the given argument.

get

TODO
  • get: returns an item of a dictionary with a given key if present, or a default if not

index

Type:

  • index([?], ?): Number
  • index(String, String): Number

If a List and an item are given, return the position of the first occurrence of item on the list.

If two strings are given, returns the index where the item substring starts in the container string.

is_integer

Type: is_integer(Number): Boolean

Returns True iff the argument has no fractional part.

join

Type:
  • join([String]): String
  • join([String], String): String

Concatenates an array of strings with an optional separator. If no separator is given, then ", " is used.

keys

TODO
  • keys: returns the list of keys in a dictionary

label

Type: label(CustomType): String

Returns a string with the constructor label of a custom value.

len

Type:

  • len(String): Number
  • len([?]): Number
  • len(Dict {?}): Number
  • len(CustomType): Number

Strings: Return the length of the string.

Lists: Return the number of elements of the list. len([]) returns 0, len([1,2,3]) returns 3

Dictionaries: Return the number of keys in a list.

Custom values: return the number of arguments accepted by the constructor of the value. For example, given the type Walk(angle: Number, speed:Number) | Duck | Fire, len(Duck) returns 0, and len(Walk(0, 4)) returns 2.

lower

Type: lower(String): String

Returns a lowercase version of a string.

max

Type: max([T]): T

The type T must be any type with elements that can be compared with the > operator.

max returns the largest element of the list (one that is greater than or equal to the others when compared with the >= operator). It fails if the list is empty.

min

Type: min([T]): T

The type T must be any type with elements that can be compared with the < operator.

min returns the smallest element of the list (one that is smaller than or equal to the others when compared with the <= operator). It fails if the list is empty.

number

Type number(String): Number

Converts the given string in a number. It fails if the argument is not a number representation.

pow

Type: pow(Number, Number): Number

Return x to the power of y. It follows the convention of the IEEE-754 standard which defines pow(0, 0), pow(1, ∞), and pow(∞, 0) as 1.

product

Type product([Number]): Number

Returns the arithmetic product of all the numbers in the input list. If the list is empty, the result is 1.

range

  • Type: range(Number): [Number]
  • Type: range(Number, Number): [Number]
  • Type: range(Number, Number, Number): [Number]

Generates an arithmetic progression [start, start+step, start+2*step, ..., start+k*step], where start+k*step < end <= start+(k+1)*step. If a single argument is provided, that argument is end, and start defaults to 0 and step defaults to 1. If 2 arguments are provided they are considered as start and end, and the step still defaults to 1. Otherwise, the arguments correspond to start, end step.

The function fails if step==0. If given a negative step, the ending condition is start+k*step > end >= start+(k+1)*step instead.

Note that some intervals may result in empty sequences if you specify reversed start and endpoints:

range(1, 5) -> [1,2,3,4]
range(5, 1) -> []
TODO
  • range: Generates a list with a sequence or any arithmetic progression

replace

Type:
  • replace(String, String, String): String
  • replace(String, String, String, Number): String

Given a target string and other two strings, old and new, return a copy of the first string with all occurrences of substring old replaced by new. If the optional integer argument count is given, only the first count occurrences are replaced.

reversed

Type:
  • reversed([T]): [T]

Return a reversed version of the given list.

round

Type:
  • round(Number): Number
  • round(Number, Number): Number

With only one argument, round it to the closest integer. Else, if a second argument is given, round the first argument to the precision (in decimal digits) given by the second argument, which must be integer. For example

slice

Type:

  • slice([?], Number | Null, Number | Null): [?]
  • slice(String, Number | Null, Number | Null): String

Returns a sublist of a List or a substring of a String.

The first argument is the List or String to slice.

The second argument, from, is a zero-based index where to begin the slice. If Null, 0 is used. As a negative index, from indicates an offset from the end of the list or string.

The last argument, end, is a zero-based index at which to end: slice extracts up to but not including end. If Null, the length of the first argument is used. As a negative index, end indicates an offset from the end of the list (or string).

For example,

  • slice(["a", "b", "c", "d"], 0, 2) returns ["a", "b"]
  • slice(["a", "b", "c", "d"], Null, 2) returns ["a", "b"]
  • slice(["a", "b", "c", "d"], -2, Null) returns ["c", "d"]
  • slice(["a", "b", "c", "d"], 1, -1) returns ["b", "c"]
  • slice("You're driving me Walnuts!", 18, 24) returns "Walnut"
  • slice("You're driving me Walnuts!", -8, -2) returns "Walnut"
  • slice("You're driving me Walnuts!", Null, 14) returns "You're driving"

sorted

Type: sorted([?]): [?]

Returns a sorted version of a list

split

Type:
  • split(String): [String]
  • split(String, String | Null): [String]
  • split(String, String | Null, Number): [String]

Return a list of the words in a string, using a sep as the delimiter string. If sep is not specified or is Null, any whitespace string is a separator and empty strings are removed from the result. If a maxsplit is given, at most maxsplit splits are done.

starts_with

Type: starts_with(String, String): Boolean

Checks if a string starts with a given prefix.

string

Type: string(?): String

Returns a string representation of the value. The representation will always be valid Walnut syntax to rebuild the value.

strip

Type: strip(String): String

Remove leading and/or trailing whitespace (space, tab and newlines) from the given string.

sum

Type sum([Number]): Number

Returns the arithmetic addition of all the numbers in the input list. If the list is empty, the result is 0.

updated

Type: updated(CustomValue, String | Number, ?):

Returns a copy of a value with some of its fields modified. The field can be identified by its name or index.

upper

Type: upper(String): String

Returns an uppercase version of a string.

values

Type: values(Dict {T}): [T]

Returns the list of items in a dictionary. The ordering of the items is arbitrary, but does not change between two successive calls, and corresponds to the order of keys and enumerate if no modifications are done to the dictionary

zip

Type: zip([[?]]): [[?]]

Groups many list into a list of tuples. For example zip([["a", "b", "c"], [1.0, 2.0, 3.0], [Null, Null, Null]]) returns [["a", 1.0, Null], ["b", 2.0, Null], ["c", 4.0, Null]]. The length of the shortest list is used.

type_of

Type: type_of(?): String

Returns a string description about the type of a value.