mirror of
https://github.com/wren-lang/wren.git
synced 2026-01-11 22:28:45 +01:00
documentation revisions and missing pieces
This commit is contained in:
@ -267,7 +267,7 @@ inside a method works like this:
|
||||
|
||||
So, in the above example, we hit case #2 and it prints "Francis". Distinguishing
|
||||
self sends from outer variables based on the *case* of the first letter in the
|
||||
name probably seems crazy but it works surprisingly well. Method names are
|
||||
name probably seems weird but it works surprisingly well. Method names are
|
||||
lowercase in Wren. Class names are capitalized.
|
||||
|
||||
Most of the time, when you're in a method and want to access a name from outside
|
||||
|
||||
@ -88,8 +88,7 @@ The basic process is simple:
|
||||
If there are no failures, you're good to go.
|
||||
|
||||
2. **[Fork the repo][fork] so you can change it locally.** Please make your
|
||||
changes in separate [feature branches][] to make things a little easier on
|
||||
me.
|
||||
changes in separate [feature branches][] to make things a little easier.
|
||||
|
||||
3. **Change the code.** Please follow the style of the surrounding code. That
|
||||
basically means `camelCase` names, `{` on the next line, keep within 80
|
||||
@ -105,8 +104,7 @@ The basic process is simple:
|
||||
6. **Add your name and email to the [AUTHORS][] file if you haven't already.**
|
||||
|
||||
7. **Send a [pull request][].** Pat yourself on the back for contributing to a
|
||||
fun open source project! I'll take it from here and hopefully we'll get it
|
||||
landed smoothly.
|
||||
fun open source project!
|
||||
|
||||
## Getting help
|
||||
|
||||
|
||||
@ -65,7 +65,7 @@ if (ready) {
|
||||
|
||||
Unlike most other [operators][] in Wren which are just a special syntax for
|
||||
[method calls][], the `&&` and `||` operators are special. This is because they
|
||||
only conditionally evaluate right operand—they short-circuit.
|
||||
only conditionally evaluate the right operand—they short-circuit.
|
||||
|
||||
[operators]: method-calls.html#operators
|
||||
[method calls]: method-calls.html
|
||||
@ -92,7 +92,7 @@ System.print(1 || 2) //> 1
|
||||
|
||||
Also known as the "ternary" operator since it takes three arguments, Wren has
|
||||
the little "if statement in the form of an expression" you know and love from C
|
||||
and its brethren.
|
||||
and similar languages.
|
||||
|
||||
<pre class="snippet">
|
||||
System.print(1 != 2 ? "math is sane" : "math is not sane!")
|
||||
|
||||
@ -1,129 +1,43 @@
|
||||
^title Functions
|
||||
|
||||
No self-respecting language today can get by without functions—first
|
||||
class little bundles of code. Since Wren is object-oriented, most of your code
|
||||
will live in methods on classes, but free-floating functions are still
|
||||
eminently handy.
|
||||
Like many languages today, functions in Wren are little bundles of code
|
||||
you can store in a variable, or pass as an argument to a method.
|
||||
|
||||
Notice there's a difference between _function_ and _method_.
|
||||
|
||||
Since Wren is object-oriented, most of your code will live in methods on
|
||||
classes, but free-floating functions are still eminently handy.
|
||||
|
||||
Functions are objects like everything else in Wren, instances of the `Fn`
|
||||
class.
|
||||
|
||||
## Block arguments
|
||||
## Creating a function
|
||||
|
||||
Most of the time you create a function just to pass it to some method. For
|
||||
example, if you want to filter a [list](lists.html) by some criteria, you'll
|
||||
call its `where` method, passing in a function that defines the predicate
|
||||
you're filtering on.
|
||||
|
||||
Since that's the most common usage pattern, Wren's syntax optimizes for that.
|
||||
Taking a page from Ruby, a function is created by passing a *block argument* to
|
||||
a method. At its simplest, it looks like this:
|
||||
To create a function, we call `Fn.new`, which takes a block to execute.
|
||||
To call the function, we use `.call()` on the function instance.
|
||||
|
||||
<pre class="snippet">
|
||||
blondie.callMe {
|
||||
System.print("This is the body!")
|
||||
}
|
||||
var sayHello = Fn.new { System.print("hello") }
|
||||
|
||||
sayHello.call() //> hello
|
||||
</pre>
|
||||
|
||||
Here we're invoking the `callMe` method on `blondie`. We're passing one
|
||||
argument, a function whose body is the
|
||||
following [block](syntax.html#blocks)—everything between that pair of
|
||||
curly braces.
|
||||
|
||||
Methods that take a block argument receive it as a normal parameter. `callMe`
|
||||
could be defined like so:
|
||||
|
||||
<pre class="snippet">
|
||||
class Blondie {
|
||||
callMe(fn) {
|
||||
// Call it...
|
||||
}
|
||||
}
|
||||
|
||||
var blondie = Blondie.new()
|
||||
</pre>
|
||||
|
||||
A method can take other arguments in addition to the block. They appear before
|
||||
the block just like a regular argument list. For example:
|
||||
|
||||
<pre class="snippet">
|
||||
blondie.callMeAt(867, 5309) {
|
||||
System.print("This is the body!")
|
||||
}
|
||||
</pre>
|
||||
|
||||
Of course, you don't *have* to use a block argument to pass a function to a
|
||||
method. If you already have a function object, you can pass it like a regular
|
||||
argument:
|
||||
|
||||
<pre class="snippet">
|
||||
var someFn = // Get a function...
|
||||
blondie.callMe(someFn)
|
||||
</pre>
|
||||
|
||||
Block arguments are purely sugar for creating a function and passing it in one
|
||||
little blob of syntax. There are some times when you want to create a function
|
||||
but *don't* need to pass it to a method. For that, you can call the `Fn`
|
||||
class's constructor:
|
||||
|
||||
<pre class="snippet">
|
||||
var someFn = Fn.new {
|
||||
System.print("Hi!")
|
||||
}
|
||||
</pre>
|
||||
|
||||
As you can see it takes a block argument too! All the constructor does is
|
||||
return that argument, so this exists purely as a convenience method for you.
|
||||
|
||||
## Calling functions
|
||||
|
||||
Once you have a function, how do you invoke it? Like everything in Wren, you do
|
||||
so by calling a method on it:
|
||||
|
||||
<pre class="snippet">
|
||||
class Blondie {
|
||||
callMe(fn) {
|
||||
fn.call()
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
|
||||
Functions expose a `call()` method that executes the body of the function. This
|
||||
method is dynamically-dispatched like any other, so you can define your own
|
||||
"function-like" classes and pass them to methods that expect "real" functions.
|
||||
|
||||
<pre class="snippet">
|
||||
class FakeFn {
|
||||
call() {
|
||||
System.print("I'm feeling functional!")
|
||||
}
|
||||
}
|
||||
|
||||
blondie.callMe(FakeFn.new())
|
||||
</pre>
|
||||
Note that we'll see a shorthand syntax for creating a function below.
|
||||
|
||||
## Function parameters
|
||||
|
||||
Of course, functions aren't very useful if you can't pass values to them. The
|
||||
functions that we've seen so far take no arguments. To change that, you can
|
||||
provide a parameter list surrounded by `|` immediately after the opening brace
|
||||
of the body, like so:
|
||||
function above takes no arguments. To change that, you can provide a parameter
|
||||
list surrounded by `|` immediately after the opening brace of the body.
|
||||
|
||||
To pass arguments to the function, pass them to the `call` method:
|
||||
|
||||
<pre class="snippet">
|
||||
blondie.callMe {|first, last|
|
||||
System.print("Hi, " + first + " " + last + "!")
|
||||
var sayMessage {|recipient, message|
|
||||
System.print("message for %(recipient): %(message)")
|
||||
}
|
||||
</pre>
|
||||
|
||||
Here we're passing a function to `callMe` that takes two parameters, `first` and
|
||||
`last`. They are passed to the function when it's called:
|
||||
|
||||
<pre class="snippet">
|
||||
class Blondie {
|
||||
callMe(fn) {
|
||||
fn.call("Debbie", "Harry")
|
||||
}
|
||||
}
|
||||
sayMessage.call("Bob", "Good day!")
|
||||
</pre>
|
||||
|
||||
It's an error to call a function with fewer arguments than its parameter list
|
||||
@ -148,6 +62,14 @@ Fn.new {
|
||||
}
|
||||
</pre>
|
||||
|
||||
The return value is handed back to you when using `call`:
|
||||
|
||||
<pre class="snippet">
|
||||
var fn = Fn.new { "some value" }
|
||||
var result = fn.call()
|
||||
System.print(result) //> some value
|
||||
</pre>
|
||||
|
||||
## Closures
|
||||
|
||||
As you expect, functions are closures—they can access variables defined
|
||||
@ -175,6 +97,149 @@ System.print(counter.call()) //> 2
|
||||
System.print(counter.call()) //> 3
|
||||
</pre>
|
||||
|
||||
## Callable classes
|
||||
|
||||
Because `Fn` is a class, and responds to `call()`, any class can respond to
|
||||
`call()` and be used in place of a function. This is particularly handy when
|
||||
the function is passed to a method to be called, like a callback or event.
|
||||
|
||||
<pre class="snippet">
|
||||
class Callable {
|
||||
construct new() {}
|
||||
call(name, version) {
|
||||
System.print("called %(name) with version %(version)")
|
||||
}
|
||||
}
|
||||
|
||||
var fn = Callable.new()
|
||||
fn.call("wren", "0.4.0")
|
||||
</pre>
|
||||
|
||||
## Block arguments
|
||||
|
||||
Very frequently, functions are passed to methods to be called. There are
|
||||
countless examples of this in Wren, like [list](lists.html) can be filtered
|
||||
using a method `where` which accepts a function:
|
||||
|
||||
<pre class="snippet">
|
||||
var list = [1, 2, 3, 4, 5]
|
||||
var filtered = list.where(Fn.new {|value| value > 3 })
|
||||
System.print(filtered.toList) //> [4, 5]
|
||||
</pre>
|
||||
|
||||
This syntax is a bit less fun to read and write, so Wren implements the
|
||||
_block argument_ concept. When a function is being passed to a method,
|
||||
and is the last argument to the method, it can use a shorter syntax:
|
||||
_just the block part_.
|
||||
|
||||
Let's use a block argument for `list.where`, it's the last (only) argument:
|
||||
|
||||
<pre class="snippet">
|
||||
var list = [1, 2, 3, 4, 5]
|
||||
var filtered = list.where {|value| value > 3 }
|
||||
System.print(filtered.toList) //> [4, 5]
|
||||
</pre>
|
||||
|
||||
We've seen this before in a previous page using `map` and `where`:
|
||||
|
||||
<pre class="snippet">
|
||||
numbers.map {|n| n * 2 }.where {|n| n < 100 }
|
||||
</pre>
|
||||
|
||||
## Block argument example
|
||||
|
||||
Let's look at a complete example, so we can see both ends.
|
||||
|
||||
This may be a bit of a spoiler for [classes](classes.html), so feel free
|
||||
to read that page first and come back.
|
||||
|
||||
Here's a fictional class for something that will call a function
|
||||
when a click event is sent to it. It allows us to pass just a
|
||||
function and assume the left mouse button, or to pass a button and a function.
|
||||
|
||||
<pre class="snippet">
|
||||
class Clickable {
|
||||
construct new() {
|
||||
_fn = null
|
||||
_button = 0
|
||||
}
|
||||
|
||||
onClick(fn) {
|
||||
_fn = fn
|
||||
}
|
||||
|
||||
onClick(button, fn) {
|
||||
_button = button
|
||||
_fn = fn
|
||||
}
|
||||
|
||||
fireEvent(button) {
|
||||
if(_fn && button == _button) {
|
||||
_fn.call(button)
|
||||
}
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
|
||||
Now that we've got the clickable class, let's use it.
|
||||
We'll start by using the method that accepts just a function
|
||||
because we're fine with it just being the default left mouse button.
|
||||
|
||||
<pre class="snippet">
|
||||
var link = Clickable.new()
|
||||
|
||||
link.onClick {|button|
|
||||
System.print("I was clicked by button %(button)")
|
||||
}
|
||||
|
||||
// send a left mouse click
|
||||
// normally this would happen from elsewhere
|
||||
|
||||
link.fireEvent(0) //> I was clicked by button 0
|
||||
</pre>
|
||||
|
||||
Now let's try with the extra button argument:
|
||||
|
||||
<pre class="snippet">
|
||||
var contextMenu = Clickable.new()
|
||||
|
||||
contextMenu.onClick(1) {|button|
|
||||
System.print("I was right-clicked")
|
||||
}
|
||||
|
||||
link.fireEvent(0) //> (nothing happened)
|
||||
link.fireEvent(1) //> I was right-clicked
|
||||
</pre>
|
||||
|
||||
Notice that we still pass the other arguments normally,
|
||||
it's only the last argument that is special.
|
||||
|
||||
**Just a regular function**
|
||||
|
||||
Block arguments are purely syntax sugar for creating a function and passing it
|
||||
in one little blob of syntax. These two are equivalent:
|
||||
|
||||
<pre class="snippet">
|
||||
onClick(Fn.new { System.print("clicked") })
|
||||
onClick { System.print("clicked") }
|
||||
</pre>
|
||||
|
||||
And this is just as valid:
|
||||
|
||||
<pre class="snippet">
|
||||
var onEvent = Fn.new {|button|
|
||||
System.print("clicked by button %(button)")
|
||||
}
|
||||
|
||||
onClick(onEvent)
|
||||
onClick(1, onEvent)
|
||||
</pre>
|
||||
|
||||
**Fn.new**
|
||||
As you may have noticed by now, `Fn` accepts a block argument for the `Fn.new`.
|
||||
All the constructor does is return that argument right back to you!
|
||||
|
||||
|
||||
<br><hr>
|
||||
<a class="right" href="classes.html">Classes →</a>
|
||||
<a href="variables.html">← Variables</a>
|
||||
|
||||
@ -20,23 +20,23 @@ element you want. Like most languages, indexes start at zero:
|
||||
[subscript operator]: method-calls.html#subscripts
|
||||
|
||||
<pre class="snippet">
|
||||
var hirsute = ["sideburns", "porkchops", "'stache", "goatee"]
|
||||
System.print(hirsute[0]) //> sideburns
|
||||
System.print(hirsute[1]) //> porkchops
|
||||
var trees = ["cedar", "birch", "oak", "willow"]
|
||||
System.print(trees[0]) //> cedar
|
||||
System.print(trees[1]) //> birch
|
||||
</pre>
|
||||
|
||||
Negative indices counts backwards from the end:
|
||||
|
||||
<pre class="snippet">
|
||||
System.print(hirsute[-1]) //> goatee
|
||||
System.print(hirsute[-2]) //> 'stache
|
||||
System.print(trees[-1]) //> willow
|
||||
System.print(trees[-2]) //> oak
|
||||
</pre>
|
||||
|
||||
It's a runtime error to pass an index outside of the bounds of the list. If you
|
||||
don't know what those bounds are, you can find out using count:
|
||||
|
||||
<pre class="snippet">
|
||||
System.print(hirsute.count) //> 4
|
||||
System.print(trees.count) //> 4
|
||||
</pre>
|
||||
|
||||
## Slices and ranges
|
||||
@ -45,7 +45,7 @@ Sometimes you want to copy a chunk of elements from a list. You can do that by
|
||||
passing a [range](values.html#ranges) to the subscript operator, like so:
|
||||
|
||||
<pre class="snippet">
|
||||
System.print(hirsute[1..2]) //> [porkchops, 'stache]
|
||||
System.print(trees[1..2]) //> [birch, oak]
|
||||
</pre>
|
||||
|
||||
This returns a new list containing the elements of the original list whose
|
||||
@ -56,7 +56,7 @@ Negative bounds also work like they do when passing a single number, so to copy
|
||||
a list, you can just do:
|
||||
|
||||
<pre class="snippet">
|
||||
hirsute[0..-1]
|
||||
trees[0..-1]
|
||||
</pre>
|
||||
|
||||
## Adding elements
|
||||
@ -65,22 +65,22 @@ Lists are *mutable*, meaning their contents can be changed. You can swap out an
|
||||
existing element in the list using the subscript setter:
|
||||
|
||||
<pre class="snippet">
|
||||
hirsute[1] = "muttonchops"
|
||||
System.print(hirsute[1]) //> muttonchops
|
||||
trees[1] = "spruce"
|
||||
System.print(trees[1]) //> spruce
|
||||
</pre>
|
||||
|
||||
It's an error to set an element that's out of bounds. To grow a list, you can
|
||||
use `add` to append a single item to the end:
|
||||
|
||||
<pre class="snippet">
|
||||
hirsute.add("goatee")
|
||||
System.print(hirsute.count) //> 5
|
||||
trees.add("maple")
|
||||
System.print(trees.count) //> 5
|
||||
</pre>
|
||||
|
||||
You can insert a new element at a specific position using `insert`:
|
||||
|
||||
<pre class="snippet">
|
||||
hirsute.insert(2, "soul patch")
|
||||
trees.insert(2, "hickory")
|
||||
</pre>
|
||||
|
||||
The first argument is the index to insert at, and the second is the value to
|
||||
@ -143,8 +143,8 @@ System.print(letters.remove("not found")) //> null
|
||||
If you want to remove everything from the list, you can clear it:
|
||||
|
||||
<pre class="snippet">
|
||||
hirsute.clear()
|
||||
System.print(hirsute) //> []
|
||||
trees.clear()
|
||||
System.print(trees) //> []
|
||||
</pre>
|
||||
|
||||
<br><hr>
|
||||
|
||||
@ -9,22 +9,26 @@ curly braces. Each entry is a key and a value separated by a colon:
|
||||
|
||||
<pre class="snippet">
|
||||
{
|
||||
"George": "Harrison",
|
||||
"John": "Lennon",
|
||||
"Paul": "McCartney",
|
||||
"Ringo": "Starr"
|
||||
"maple": "Sugar Maple (Acer Saccharum)",
|
||||
"larch": "Alpine Larch (Larix Lyallii)",
|
||||
"oak": "Red Oak (Quercus Rubra)",
|
||||
"fir": "Fraser Fir (Abies Fraseri)"
|
||||
}
|
||||
</pre>
|
||||
|
||||
This creates a map that associates the first name of each Beatle with his last
|
||||
name. Syntactically, in a map literal, keys can be any literal, a variable
|
||||
name, or a parenthesized expression. Values can be any expression. Here, we're
|
||||
using string literals for both keys and values.
|
||||
This creates a map that associates a type of tree (key) to a specific
|
||||
tree within that family (value). Syntactically, in a map literal, keys
|
||||
can be any literal, a variable name, or a parenthesized expression.
|
||||
Values can be any expression. Here, we're using string literals for both keys
|
||||
and values.
|
||||
|
||||
*Semantically*, values can be any object, and multiple keys may map to the same
|
||||
value. Keys have a few limitations. They must be one of the immutable built-in
|
||||
value.
|
||||
|
||||
Keys have a few limitations. They must be one of the immutable built-in
|
||||
[value types][] in Wren. That means a number, string, range, bool, or `null`.
|
||||
You can also use a [class object][] as a key.
|
||||
You can also use a [class object][] as a key (not an instance of that class,
|
||||
the actual class itself).
|
||||
|
||||
[value types]: values.html
|
||||
[class object]: classes.html
|
||||
@ -67,12 +71,12 @@ doesn't necessarily mean the key wasn't found.
|
||||
To tell definitively if a key exists, you can call `containsKey()`:
|
||||
|
||||
<pre class="snippet">
|
||||
var belief = {"nihilism": null}
|
||||
var capitals = {"Georgia": null}
|
||||
|
||||
System.print(belief["nihilism"]) //> null (though key exists)
|
||||
System.print(belief["solipsism"]) //> null
|
||||
System.print(belief.containsKey("nihilism")) //> true
|
||||
System.print(belief.containsKey("solipsism")) //> false
|
||||
System.print(capitals["Georgia"]) //> null (though key exists)
|
||||
System.print(capitals["Idaho"]) //> null
|
||||
System.print(capitals.containsKey("Georgia")) //> true
|
||||
System.print(capitals.containsKey("Idaho")) //> false
|
||||
</pre>
|
||||
|
||||
You can see how many entries a map contains using `count`:
|
||||
@ -113,16 +117,38 @@ System.print(capitals.count) //> 0
|
||||
|
||||
The subscript operator works well for finding values when you know the key
|
||||
you're looking for, but sometimes you want to see everything that's in the map.
|
||||
For that, map exposes two methods: `keys` and `values`.
|
||||
You can use a regular for loop to iterate the contents, and map exposes two
|
||||
additional methods to access the contents: `keys` and `values`.
|
||||
|
||||
The first returns a [Sequence][] that [iterates][] over all of the keys in the
|
||||
map, and the second returns one that iterates over the values.
|
||||
The `keys` method on a map returns a [Sequence][] that [iterates][] over all of
|
||||
the keys in the map, and the `values` method returns one that iterates over the values.
|
||||
|
||||
[sequence]: modules/core/sequence.html
|
||||
[iterates]: control-flow.html#the-iterator-protocol
|
||||
|
||||
If you want to see all of the key-value pairs in a map, the easiest way is to
|
||||
iterate over the keys and use each to look up its value:
|
||||
Regardless of how you iterate, the *order* that things are iterated in
|
||||
isn't defined. Wren makes no promises about what order keys and values are
|
||||
iterated. All it promises is that every entry will appear exactly once.
|
||||
|
||||
**Iterating with for(entry in map)**
|
||||
When you iterate a map with `for`, you'll be handed an _entry_, which contains
|
||||
a `key` and a `value` field. That gives you the info for each element in the map.
|
||||
|
||||
<pre class="snippet">
|
||||
var birds = {
|
||||
"Arizona": "Cactus wren",
|
||||
"Hawaii": "Nēnē",
|
||||
"Ohio": "Northern Cardinal"
|
||||
}
|
||||
|
||||
for (bird in birds) {
|
||||
System.print("The state bird of %(bird.key) is %(bird.value)")
|
||||
}
|
||||
</pre>
|
||||
|
||||
**Iterating using the keys**
|
||||
|
||||
You can also iterate over the keys and use each to look up its value:
|
||||
|
||||
<pre class="snippet">
|
||||
var birds = {
|
||||
@ -132,15 +158,10 @@ var birds = {
|
||||
}
|
||||
|
||||
for (state in birds.keys) {
|
||||
System.print("The state bird of " + state + " is " + birds[state])
|
||||
System.print("The state bird of %(state) is " + birds[state])
|
||||
}
|
||||
</pre>
|
||||
|
||||
This program prints the three states and their birds. However, the *order*
|
||||
that they are printed isn't defined. Wren makes no promises about what order
|
||||
keys and values are iterated in when you use these methods. All it promises is
|
||||
that every entry will appear exactly once.
|
||||
|
||||
<br><hr>
|
||||
<a class="right" href="method-calls.html">Method Calls →</a>
|
||||
<a href="lists.html">← Lists</a>
|
||||
|
||||
@ -52,7 +52,9 @@ In a language like Python or JavaScript, these would both call a single `int()`
|
||||
method, which has some kind of "optional" parameter. The body of the method
|
||||
figures out how many arguments were passed and uses control flow to handle the
|
||||
two different behaviors. That means first parameter represents "max unless
|
||||
another parameter was passed, in which case it's min". Kind of gross.
|
||||
another parameter was passed, in which case it's min".
|
||||
|
||||
This type of 'variadic' code isn't ideal, so Wren doesn't encourage it.
|
||||
|
||||
In Wren, these are calls to two entirely separate methods, `int(_,_)` and
|
||||
`int(_)`. This makes it easier to define "overloads" like this since you don't
|
||||
@ -163,7 +165,7 @@ like mocks or proxies where you want an object to masquerade as a certain class.
|
||||
|
||||
## Subscripts
|
||||
|
||||
Another familiar syntax from math class is *subscripting* using square brackets
|
||||
Another familiar syntax from math is *subscripting* using square brackets
|
||||
(`[]`). It's handy for working with collection-like objects. For example:
|
||||
|
||||
<pre class="snippet">
|
||||
|
||||
@ -149,7 +149,7 @@ put a newline in there:
|
||||
</pre>
|
||||
|
||||
Using an initial newline after the `{` does feel a little weird or magical, but
|
||||
newlines are already significant in Wren, so it's not totally crazy. The nice
|
||||
newlines are already significant in Wren, so it's not totally unreasonable. The nice
|
||||
thing about this syntax as opposed to something like `=>` is that the *end* of
|
||||
the block has an explicit delimiter. That helps when chaining:
|
||||
|
||||
|
||||
@ -199,12 +199,16 @@ This creates a range from four to six *not* including six itself. Ranges are
|
||||
commonly used for [iterating](control-flow.html#for-statements) over a
|
||||
sequences of numbers, but are useful in other places too. You can pass them to
|
||||
a [list](lists.html)'s subscript operator to return a subset of the list, for
|
||||
example:
|
||||
example, or on a String, the substring in that range:
|
||||
|
||||
<pre class="snippet">
|
||||
var list = ["a", "b", "c", "d", "e"]
|
||||
var slice = list[1..3]
|
||||
System.print(slice) //> [b, c, d]
|
||||
|
||||
var string = "hello wren"
|
||||
var wren = string[-4..-1]
|
||||
System.print(wren) //> wren
|
||||
</pre>
|
||||
|
||||
Their class is [Range][].
|
||||
|
||||
@ -54,7 +54,7 @@ var a = "again" //! "a" is already declared.
|
||||
|
||||
## Assignment
|
||||
|
||||
After a variable has been declared, you can assign to it using `=`:
|
||||
After a variable has been declared, you can assign to it using `=`
|
||||
|
||||
<pre class="snippet">
|
||||
var a = 123
|
||||
|
||||
Reference in New Issue
Block a user