diff --git a/doc/site/lists.markdown b/doc/site/lists.markdown index f9521085..6e5bdd73 100644 --- a/doc/site/lists.markdown +++ b/doc/site/lists.markdown @@ -20,20 +20,20 @@ element you want. Like most languages, indexes start at zero: :::wren var hirsute = ["sideburns", "porkchops", "'stache", "goatee"] - hirsute[0] //> sideburns - hirsute[1] //> porkchops + System.print(hirsute[0]) //> sideburns + System.print(hirsute[1]) //> porkchops Negative indices counts backwards from the end: :::wren - hirsute[-1] //> goatee - hirsute[-2] //> 'stache + System.print(hirsute[-1]) //> goatee + System.print(hirsute[-2]) //> 'stache 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: :::wren - hirsute.count //> 4 + System.print(hirsute.count) //> 4 ## Slices and ranges @@ -41,7 +41,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: :::wren - hirsute[1..2] //> [porkchops, 'stache] + System.print(hirsute[1..2]) //> [porkchops, 'stache] This returns a new list containing the elements of the original list whose indices are within the given range. Both inclusive and exclusive ranges work @@ -85,9 +85,9 @@ back. Doing so counts back from the size of the list *after* it's grown by one: :::wren var letters = ["a", "b", "c"] letters.insert(3, "d") // OK: inserts at end. - System.print(letters) //> [a, b, c, d] + System.print(letters) //> [a, b, c, d] letters.insert(-2, "e") // Counts back from size after insert. - System.print(letters) //> [a, b, c, e, d] + System.print(letters) //> [a, b, c, e, d] ## Removing elements diff --git a/doc/site/maps.markdown b/doc/site/maps.markdown index 06062c3b..feaa74a6 100644 --- a/doc/site/maps.markdown +++ b/doc/site/maps.markdown @@ -10,13 +10,13 @@ curly braces. Each entry is a key and a value separated by a colon: :::wren { "George": "Harrison", - "John": "Lennon", - "Paul": "McCartney", - "Ringo": "Starr" + "John": "Lennon", + "Paul": "McCartney", + "Ringo": "Starr" } -This creates a map that maps the first names of the Beatles to their last -names. Syntactically, in a map literal, keys can be any literal, a variable +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. @@ -28,12 +28,6 @@ You can also use a [class object][] as a key. [value types]: values.html [class object]: classes.html -In addition, even though they aren't strictly immutable, [fibers][] can be used -as map keys. This is handy for storing data that's roughly "thread-local" by -using the current fiber as a map key. - -[fibers]: concurrency.html - The reason for this limitation—and the reason maps are called "*hash* tables" in other languages—is that each key is used to generate a numeric *hash code*. This lets a map locate the value associated with a key in constant @@ -42,7 +36,7 @@ built-in types, only those can be used as keys. ## Adding entries -You add new key-value pairs to the map by using the [subscript operator][]: +You add new key-value pairs to the map using the [subscript operator][]: [subscript operator]: method-calls.html#subscripts @@ -98,8 +92,8 @@ If the key was found, this returns the value that was associated with it: If the key wasn't in the map to begin with, `remove()` just returns `null`. -If you want to remove *everything* from the map, just like with [lists][], you -can just call `clear()`: +If you want to remove *everything* from the map, like with [lists][], you call +`clear()`: [lists]: lists.html @@ -133,10 +127,10 @@ iterate over the keys and use each to look up its value: System.print("The state bird of " + state + " is " + birds[state]) } -This program will print the three states and their birds. However, the *order* +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 will be iterated in when you use these methods. All it promises -is that every entry will appear exactly once. +keys and values are iterated in when you use these methods. All it promises is +that every entry will appear exactly once. Method Calls → ← Lists diff --git a/doc/site/method-calls.markdown b/doc/site/method-calls.markdown index d9284b94..2814a071 100644 --- a/doc/site/method-calls.markdown +++ b/doc/site/method-calls.markdown @@ -4,10 +4,10 @@ Wren is deeply object oriented, so most code consists of invoking methods on objects, usually something like this: :::wren - System.print("hello") + System.print("Heyoo!") //> Heyoo! You have a *receiver* expression (here `System`) followed by a `.`, then a name -(`print`) and an argument list in parentheses (`("hello")`). Multiple arguments +(`print`) and an argument list in parentheses (`("Heyoo!")`). Multiple arguments are separated by commas: :::wren @@ -18,7 +18,7 @@ The argument list can also be empty: :::wren list.clear() -Semantically, all method calls work like this: +The VM executes a method call like so: 1. Evaluate the receiver and arguments from left to right. 2. Look up the method on the receiver's [class][]. diff --git a/doc/site/performance.markdown b/doc/site/performance.markdown index 56269153..54502ce5 100644 --- a/doc/site/performance.markdown +++ b/doc/site/performance.markdown @@ -6,76 +6,76 @@ seem to like them, so here's a few:

Method Call

- + - + - + - + - + - +
wren
0.15s 
wren
0.12s 
luajit (-joff)
0.23s 
luajit (-joff)
0.16s 
ruby
0.36s 
ruby
0.20s 
lua
0.58s 
lua
0.35s 
python3
1.18s 
python3
0.78s 
python
1.33s 
python
0.85s 

DeltaBlue

- + - + - +
wren
0.13s 
wren
0.13s 
python3
0.44s 
python3
0.48s 
python
0.47s 
python
0.57s 

Binary Trees

- + - + - + - + - + - +
luajit (-joff)
0.16s 
luajit (-joff)
0.11s 
wren
0.29s 
wren
0.22s 
ruby
0.37s 
ruby
0.24s 
python3
0.52s 
python
0.37s 
lua
0.73s 
python3
0.38s 
python
0.75s 
lua
0.52s 

Recursive Fibonacci

- + - + - + - + - + - +
luajit (-joff)
0.15s 
luajit (-joff)
0.10s 
wren
0.31s 
wren
0.20s 
ruby
0.33s 
ruby
0.22s 
lua
0.35s 
lua
0.28s 
python3
0.78s 
python
0.51s 
python
0.81s 
python3
0.57s 
@@ -184,6 +184,19 @@ means that we can copy down all inherited methods in the subclass when it's created since we know those will never change. Method dispatch then just requires locating the method in the class of the receiver. +### Method signatures + +Wren supports overloading by arity using its concept of [signatures]. This makes +the language more expressive, but also faster. When a method is called, we look +it up on the receiver's class. If we succeed in finding it, we also know it has +the right number of parameters. + +This lets Wren avoid the extra checking most languages need to do at runtime to +handle too few or too many arguments being passed to a method. In Wren, it's not +*syntactically* possible to call a method with the wrong number of arguments. + +[signatures]: method-calls.html#signature + ### Computed gotos On compilers that support it, Wren's core bytecode interpreter loop uses