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