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
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.
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) # => [[]]
See Defining Functions for how to make your own swapping functions.
Keyword arguments
Not implemented