Skip to main content

Expressions

Expression is an expression language which consists of the functions provided by Excel with a few additions.

Like with functions, expressions can be used directly in cards.

Expressions syntax

Expressions can be referenced directly in the code, but need to be prefixed with a @ symbol when used inside strings. When used inside strings, it is also possible to define an expression block @(), inside which expressions can be used without the @ prefix.

Function and variable names are not case-sensitive, so UPPER is equivalent to upper.

The following example shows three different ways of using expressions to concatenate strings:

card First, then: Second do
a = "pizza"
b = "cheese"

# Reference expressions directly
result = concatenate(a, " with ", b)

# Sends "Tonight we have pizza with cheese"
text("Tonight we have @result")
end

card Second, then: Third do
a = "pizza"
b = "cheese"

# Reference expressions in a @() block inside a string
# Sends "Tonight we have pizza with cheese"
text("Tonight we have @(concatenate(a, \" with \", b))")
end

card Third do
a = "pizza"
b = "cheese"

# Reference expressions inside a string
# Sends "Tonight we have pizza with cheese"
text("Tonight we have @a with @b")
end

Dynamic replies

Here is an example that uses an expression to respond with the contact's name in capitalized form:

card Card do
text("Hello @PROPER(contact.name)")
end

Here is a Math Quiz example that uses expressions to generate random numbers and check the response.


card Calculator, "try again!", then: Answer do
calculator_number_1 = rand_between(1, 10)
calculator_number_2 = rand_between(1, 10)

ask("What is @calculator_number_1 * @calculator_number_2 ?")
end

card Answer when calculator == calculator_number_1 * calculator_number_2, then: Calculator do
buttons([Calculator]) do
text("That is correct!")
end
end

card Answer, then: Calculator do
buttons([Calculator]) do
text("""
@calculator is incorrect, the correct answer is:
@(calculator_number_1 * calculator_number_2)
""")
end
end

Dynamic buttons

Going back to our button message example. Let's say the pool of options for buttons isn't known ahead of time, it is possible to generate the button options dynamically using expressions as per this example.

You'll notice that the end result is the same as the previous example but we're looping over a list called options which has the value ["one", "two", "three"].

The & operator in this example indicates an anonymous function and &1 is the first argument given to the anonymous function. Please check the reference for more details.

card Card do
button_picked = buttons(ButtonPicked, map(options, &[&1, concatenate("Option ", &1)]))
text("pick an option!")
end

card ButtonPicked do
text("You selected @button_picked")
end

Reference

There is a long list of available Expressions. You can find all of them here

Here we report some of the most commonly used expressions.

abs()

Returns the absolute value of a number.

card MyCard do
# Sends "The absolute value of -1 is 1"
text("The absolute value of -1 is @abs(-1)")
end

and()

Returns true if and only if all its arguments evaluate to true.

concatenate()

Joins text strings into one text string.

card MyCard do
a = "Hi"
b = "and"
c = "welcome!"
text = concatenate(a, " ", b, " ", c)
# Sends "Hi and welcome!"
text("@text")
end

filter()

Filters a list, i.e. returns only those elements for which the provided expression returns a truthy value.

The expression must be proceeded by the character &, and the current list item being evaluated by the expression is available with the placeholder &1:

card MyCard do
items = ["apple ", "bank ", "app ", "office ", "appointment "]
# Sends "apple app appointment"
text("@filter(items, &has_beginning(&1, \"app\"))")
end

find()

Finds the first element in the list for which the provided expression is truthy.

The expression must be proceeded by the character &, and the current list item being evaluated by the expression is available with the placeholder &1:

card MyCard do
items = [["Hello", "World"], ["Hi", "World"]]
# Result is ["Hi", "World"]
result = find(items, & &1[0] == "Hi")
# Sends "Hi"
text("@result[0]")
end

first_word()

Returns the first word in a string

card MyCard do
input = "One Two Three Four"
# Sends "One"
text("@first_word(input)")
end

fixed()

Formats the given number in decimal format using a period and commas.

card MyCard do
result = 4.209922
# Sends "The result is 4.21"
text("The result is @fixed(4.209922, 2)")
end

has_beginning()

card MyCard do
text = "The Quick Brown Fox"
start = "the quick"
# Sends "true"
text("@has_beginning(text, start)")
end

isbool()

Returns true if the argument is a boolean.

card MyCard do
a = "a"
# Sends "false"
text("@isbool(a)")
end

isnumber()

Returns true if the argument is a number.

card MyCard do
a = 32
# Sends "true"
text("@isnumber(a)")
end

isstring()

Returns true if the argument is a string.

card MyCard do
a = "Hey!"
# Sends "true"
text("@isstring(a)")
end

left()

Returns the first characters in a text string. This is Unicode safe.

card MyCard do
text = "The quick brown fox"
# Sends "The q"
text("@left(text, 5)")
end

lower()

Converts a text string to lowercase.

card MyCard do
text = "HELLO!"
# Sends "hello!"
text("@lower(text)")
end

map()

Returns a list where each element is the result of invoking the provided expression on each corresponding element of the provided list.

The expression must be proceeded by the character &, and the current list item being evaluated by the expression is available with the placeholder &1:

card MyCard do
items = ["a", "b", "c"]
# Sends "ABC"
text("@map(items, &upper(&1))")
end

reduce()

Reduces elements from a list by applying a function and collecting the results in an accumulator.

The expression must be proceeded by the character &. The current list item being evaluated by the expression is available with the placeholder &1 and the accumulator is available within the placeholder &2:

card MyCard do
# Sends 6
text("@reduce(1..3, 0, & &1 + &2)")
end

reject()

Rejects items from list, i.e. returns only those elements for which the provided expression returns a false value.

The expression must be proceeded by the character &, and the current list item being evaluated by the expression is available with the placeholder &1:

card MyCard do
items = ["apple ", "bank ", "app ", "office ", "appointment "]
# Sends "bank office"
text("@reject(items, &has_beginning(&1, \"app\"))")
end

uniq()

Removes duplicate values from a list.

card MyCard do
items = ["A", "B", "B", "C"]
# Result is ["A", "B", "C"]
result = uniq(items)
end

upper()

Converts a text string to UPPERCASE.

card MyCard do
text = "hello!"
# Sends "HELLO!"
text("@upper(text)")
end

with_index()

Wraps each item of the list in a new list with the item itself and its index in the original list.

card MyCard do
items = ["A", "B", "C"]
# Result is [["A", 0], ["B", 1], ["C", 1]]
result = with_index(items)
end