# Expressions

`ll.ul4c`

supports many of the operators supported by Python. The following
subchapters describe all expressions/operators that UL4 supports and are ordered
from highest precedence to lowest.

## Generator expressions

UL4 supports generator expressions with look like list comprehensions without the square brackets. Generator expression do not create lists in memory but instead return an iterable that can be iterated once. Function and methods that require an iterable argument can directly consume such iterables:

```
<?print ", ".join("(" + c + ")" for c in "gurk")?>
```

will output

```
(g), (u), (r), (k)
```

Outside of function/method arguments (or when more that one argument is passed) parentheses are required around generator expressions:

```
<?code ge = ("(" + c + ")" for c in "gurk")?>
<?print ", ".join(ge)?>
```

Hint

Generator expressions are implemented by
`ll.ul4c.GeneratorExpressionAST`

.

## Index/slice access

Index and slice access is available for all container types, i.e. in the
expression `a[b]`

the following type combinations are supported:

string, integer: Returns the

`b`

th character from the string`a`

. Note that negative`b`

values are supported and are relative to the end, so`a[-1]`

is the last character.list, integer: Returns the

`b`

th list entry of the list`a`

. Negative`b`

values are supported too.dict, string: Return the value from the dictionary

`a`

corresponding to the key`b`

. Note that some implementations might support keys other than strings too. (The Python and Java implementations do for example. The Javascript implementation does too, if`Map`

is supported.)

If the specified key doesn’t exist or the index is out of range for the string or list, a special “undefined” object is returned.

Slices are also supported (for list and string objects). As in Python one or both of the indexes may be missing to start at the first or end after the last character/item. Negative indexes are relative to the end. Indexes that are out of bounds are simply clipped, so

```
<?print "Hello, World!"[7:-1]?>
```

prints `World`

and

```
<?print "Hello, World!"[:-8]?>
```

prints `Hello`

.

Hint

Index/slice access is implemented by `ll.ul4c.ItemAST`

.

## Attribute access

For string keys it’s also possible to access dictionary entries via the
attribute access operator `.`

, i.e. `foo.key`

is the same as `foo["key"]`

if `foo`

is a dictionary.

Hint

Attribute access is implemented by `ll.ul4c.AttrAST`

.

## Function calls

A function call in UL4 looks like this: `date(2014, 10, 9, 17, 29)`

.
(this returns the date object `@(2014-10-09T17:29)`

). Some of the trailing
arguments in a function call might be optional and have default values.
For example the first three arguments for the `date`

function (`year`

,
`month`

and `day`

) are required, the remaining four arguments (`hour`

,
`minute`

, `second`

and `microsecond`

) are optional and default to `0`

.

Parameter values can also be passed via keyword arguments, i.e.
`date(2014, 10, 9)`

could also be written as
`date(day=9, month=10, year=2014)`

.

Furthermore Python’s `*`

and `**`

syntax is supported for passing additional
positional or keyword arguments. For example:

```
<?code args = [2014, 10, 9, 17, 29]?>
<?code d = date(*args)?>
```

is the same as:

```
<?code d = date(2014, 10, 9, 17, 29)?>
```

The same can also be done with a keyword dictionary and the `**`

syntax:

```
<?code kwargs = {"day": 9, "month": 10, "year": 2014, "hour": 17: "minute": 29}?>
<?code d = date(**kwargs)?>
```

Of course it’s also possible to mix argument passing mechanics:

```
<?code d = date(2014, *[10, 9], **{"hour": 17, "minute": 29})?>
```

or

```
<?code d = date(2014, month=10, day=9, **{'hour': 17, 'minute': 29})?>
```

However the `*`

and `**`

arguments can only be use at the end of the
argument list and positional arguments must always be before keyword arguments.

A list of builtin functions can be found in Functions.

Hint

This documentation uses Python’s / and * notation to specify positional-only and keyword-only arguments. So

```
<?ul4 f(x, /, y, *, z)?>
```

means that the function f accepts the parameter `x`

only when passed by
position, y can be passed either by position or by keyword and z will
only be accepted when passed by keyword.

Hint

Function calls are implemented by `ll.ul4c.CallAST`

.

## Unary operators

### Arithmetic negation

The unary operator `-`

inverts the sign of its operand, which must be an
integer, float of boolean value:

```
<?code x = 42?><?print -x?>
```

prints `-42`

. For `-`

boolean values are treated as the numbers `0`

and
`1`

, i.e.:

```
<?code x = True?><?print -x?>
```

prints `-1`

.

Hint

Arithmetic negation is implemented by `ll.ul4c.NegAST`

.

### Binary negation

The unary operator `~`

inverts the bits of an integer or boolean value.
Non-negative numbers are interpreted as having an unlimited number of leading
`0`

bits and negative numbers are interpreted as having an unlimited number
of leading `1`

bits. The means that `~x`

will be negative if `x`

is
non-negative and vice versa.

Hint

Arithmetic negation is implemented by `ll.ul4c.BitNotAST`

.

## Multiplicative binary operators

### Multiplication

The multiplication operator `*`

returns the arithmetic product of its
operands (which must be integer, float or boolean values). Furthermore it’s
possible to multiply a sequence (i.e. a string or list) with a non-negative
integer to get a new sequences that repeats the items of the original sequence a
number of times, e.g. `"foo" * 2`

returns `"foofoo"`

and `[1, 2, 3] * 3`

return `[1, 2, 3, 1, 2, 3, 1, 2, 3]`

. Multiplying with `0`

returns an empty
string or list.

Hint

Multiplication is implemented by `ll.ul4c.MulAST`

.

### True division

The true division operator `/`

returns the quotient of its operands (which
must be integer, float or boolean values). The result is always a float value.
`1/2`

returns `0.5`

.

Hint

True division is implemented by `ll.ul4c.TrueDivAST`

.

### Floor division

The float division operator `//`

returns the quotient of its operands (which
must be integer, float or boolean values) rounded down to an integer (rounding
is always done towards -infinity, i.e. `(-25)/10`

returns `-3`

). If any of
the operands is a float the result is a float too, otherwise it’s an integer.

Hint

Floor division is implemented by `ll.ul4c.FloorDivAST`

.

### Modulo

The modulo operator `%`

returns the remainder from the division of the first
operand by the second, e.g. `15 % 7`

returns `1`

.

Hint

The modulo operator is implemented by `ll.ul4c.ModAST`

.

## Additive binary operators

### Addition

The addition operator `+`

returns the sum of its operands (which must be
integer, float or boolean values). Furthermore sequences of the same type can be
added, so `"foo" + "bar"`

returns `"foobar"`

and `[1, 2] + [3, 4]`

returns
`[1, 2, 3, 4]`

.

Hint

Addition is implemented by `ll.ul4c.AddAST`

.

### Subtraction

The subtraction operator `-`

returns the difference of its operands (which
must be integer, float or boolean values).

Hint

Subtraction is implemented by `ll.ul4c.SubAST`

.

## Bit shift operators

### Binary left shift operator

The binary left shift operator `<<`

shifts the bits of its first operand (an
integer or boolean) to the left by the number of positions given by the second
operand (which must also be an integer or boolean).

Hint

The binary left shift operator is implemented by `ll.ul4c.ShiftLeftAST`

.

### Binary right shift operator

The binary right shift operator `>>`

shifts the bits of its first operand (an
integer or boolean) to the right by the number of positions given by the second
operand (which must also be an integer or boolean).

Hint

The binary right shift operator is implemented by `ll.ul4c.ShiftRightAST`

.

## Binary bitwise “and” operator

The bitwise and operator `&`

returns the bitwise “and” combination of its
operands (which must be integer or boolean values). E.g. `6 & 3`

returns `2`

.

As with the unary operator `~`

, negative numbers are interpreted as having an
unlimited number of leading `1`

bits.

Hint

The binary bitwise “and” operator is implemented by `ll.ul4c.BitAndAST`

.

## Binary bitwise “exclusive or” operator

The bitwise exclusive or operator `^`

returns the bitwise exclusive “or”
combination of its operands (which must be integer or boolean values).
E.g. `6 ^ 3`

returns `5`

.

Negative numbers are again interpreted as having an unlimited number of leading
`1`

bits.

Hint

The binary bitwise “exclusive or” operator is implemented by
`ll.ul4c.BitXOrAST`

.

## Binary bitwise “inclusive or” operator

The bitwise inclusive or operator `|`

returns the bitwise inclusive “or”
combination of its operands (which must be integer or boolean values).
E.g. `6 | 3`

returns `7`

.

Negative numbers are again interpreted as having an unlimited number of leading
`1`

bits.

Hint

The binary bitwise “inclusive or” operator is implemented by
`ll.ul4c.BitOrAST`

.

## Binary comparison operators

The comparison operators `==`

, `!=`

, `<`

, `<=`

, `>`

and `>=`

compare
the value of the two operands. `==`

and `!=`

support comparison of all
types of object. All others support comparison of “compatible” objects, which
means all “number” objects (integer, float and boolean) can be compared with
each other, all other objects can only be compared to objects of the same type.

Hint

These operators are implemented by `ll.ul4c.EQAST`

,
`ll.ul4c.NEAST`

, `ll.ul4c.LTAST`

, `ll.ul4c.LEAST`

,
`ll.ul4c.GTAST`

and `ll.ul4c.GEAST`

.

## Identity comparison operators

The comparison operators `is`

and `is not`

test whether both operands refer
to the same object or not.

Note that the behaviour of these operators for “atomic” immutable objects (like integers, floats and strings) is implementation defined.

Hint

These operators are implemented by `ll.ul4c.IsAST`

and
`ll.ul4c.IsNotAST`

.

## Containment tests

### The `in`

operator

The `in`

operator tests whether the first operand is contained in the second
operand. In the expression `a in b`

the following type combinations are
supported:

string, string: Checks whether

`a`

is a substring of`b`

.any object, list: Checks whether the object

`a`

is in the list`b`

(comparison is done by value not by identity)string, dict: Checks whether the key

`a`

is in the dictionary`b`

. (Note that some implementations might support keys other than strings too. E.g. Python and Java do, Javascript does only for`Map`

objects.)

Hint

The `in`

operator is implemented by `ll.ul4c.ContainsAST`

.

### The `not in`

operator

The `not in`

operator returns the inverted result of the `in`

operator, i.e.
it tests whether the first operand is not contained in the second operand.

Hint

The `not in`

operator is implemented by `ll.ul4c.NotContainsAST`

.

## Boolean negation

The unary operator `not`

inverts the truth value of its operand. I.e.
`not x`

is `True`

for `None`

, `False`

, the undefined value, `0`

,
`0.0`

, empty lists, strings, dictionaries and other empty containers and
`False`

for everything else.

Hint

The boolean negation operator is implemented by `ll.ul4c.NotAST`

.

## Boolean “and” operator

The binary operator `and`

returns whether both of its operands are true.
It works like Python `and`

operator by short-circuiting operand evaluation,
i.e. if the result is clear from the first operand the seconds won’t be
evaluated.

Furthermore `and`

always return one of the operands.

So `a and b`

first evaluates `a`

; if `a`

is false, its value is returned;
otherwise, `b`

is evaluated and the resulting value is returned.

Hint

The boolean “and” operator is implemented by `ll.ul4c.AndAST`

.

## Boolean “or” operator

The binary operator `or`

returns whether any of its operands is true. Like
`and`

evaluation is short-circuited and one of the operands is returned.

For example, the following code will output the `data.title`

object if it’s
true, else `data.id`

will be output:

```
<?printx data.title or data.id?>
```

Hint

The boolean “or” operator is implemented by `ll.ul4c.OrAST`

.

## Conditional expression

The conditional expression (also called an “inline if”) `a if c else b`

first
evaluates the condition `c`

. If it is true `a`

is evaluated and returned
else `b`

is evaluated and returned.

Hint

The “inline if” operator is implemented by `ll.ul4c.IfAST`

.