Skip to main content

Variables & Functions

Variables are both created and updated like a = ....

foo = 3
println(foo) # 3
foo = 4
println(foo) # 4

Unlike some languages, variables don't have any fixed "type" – a variable can change from holding a number to holding a string, for example.

bar = 17
println(a)17
bar = "hello, world"
println(a) # hello, world
info

See Variables & Scope for detailed rules about variable assignments. Literals like numbers (17) and strings ("hello, world") work in familiar ways, but see Literals & Comments for more info.

Function Calls

Calling functions is the same as in many other languages. A list of arguments is provided within brackets () and separated by commas ,.

println("hello, world") # a function of a single argument

greeting = "hello, "
subject = "world"
concat(greeting, subject) # a function of two arguments

Raven also has many standard mathematical operators, like + and *. Operators are also functions, but can be called using infix notation.

println((5^2) + 1) # => 26

Lists

Some Raven functions return data structures.

xs = list(1, 2, 3)
println(xs) # => [1, 2, 3]

Here list returns those same numbers 1, 2, 3 as a list, an ordered collection of items. Because lists come up all the time, we have a shorter notation for them:

xs = [1, 2, 3]

As with variables, there's no requirement that list items are similar or have the same type. This is a valid list, which contains another (empty) list as the third element.

xs = [1, "foo", []]

Indexing

After putting things into lists we need to be able to get them out again. We can use the get function to index a list, pulling out the element at a particular location.

xs = [1, "foo", []]
println(get(xs, 2)) # => foo

Again though, indexing is common enough to deserve a special notation. The same brackets [] are used as a shorthand.

xs = [1, "foo", []]
println(xs[2]) # => foo

Splats

The ellipsis ... lets us provide multiple arguments to a function at once, known as splatting. For example,

xs = ["hello, ", "world"]
greeting = concat(xs...)

The splat xs... need not be the only argument. f(a, xs...) and f(a, b, xs..., c) are examples of valid splats.

Swap Arguments

In Raven most objects are immutable, meaning we can't directly alter them. To append an item to a list, for example, we can create a new list and assign it to the same variable.

xs = [1, 2, 3]
xs = push(xs, 4)
println(xs) # => [1, 2, 3, 4]

We can make this a bit more convenient by using the swap operator &, which tells push to give us a new value for xs when it's done. We sometimes say that xs was changed by push.

xs = [1, 2, 3]
push(&xs, 4)
println(xs) # => [1, 2, 3, 4]

Conversely, if we avoid &, xs will be left alone.

xs = [1, 2, 3]
ys = push(xs, 4)
println(ys) # => [1, 2, 3, 4]
println(xs) # => [1, 2, 3]

The documentation for functions like push will say whether they support swapping, and how any swapped variables will be changed. Any variables without & will be left alone, regardless of whether the function supports swapping. Functions can only make changes with permission.

note

Swapping feels a lot like altering data. But note some differences from languages with mutable state. A change to one variable cannot affect another variable.

xs = [1, 2, 3]
ys = xs
push(&ys, 4)
println(xs) # => [1, 2, 3]
println(ys) # => [1, 2, 3, 4]

Similarly, examples that might create circular references in some languages don't in Raven.

xs = []
push(&xs, xs)
println(xs) # => [[]]
info

See Defining Functions for how to make your own swapping functions.

Keyword arguments

caution

Not implemented