Fill in some more docs.

This commit is contained in:
Bob Nystrom
2015-01-01 18:48:59 -08:00
parent 0882897c6b
commit 8ab91bf6c2
8 changed files with 29 additions and 17 deletions

View File

@ -1,4 +1,6 @@
^title Embedding API
^category reference
**TODO**
As an embedded scripting language, the C API your host app uses to interact with Wren is one of the key facets of the system. It's so important that... I haven't fleshed it out much yet.
I believe good API design can't be done in a vacuum and I haven't built many applications that embed Wren yet, so I don't have a good testbed for the embedding API. Now that the language itself is further along, I'm starting to work on this, but it isn't quite there yet. Feedback and contributions are definitely welcome!

View File

@ -1,7 +1,7 @@
^title Functions
^category types
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 useful.
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.
Functions are objects like everything else in Wren, instances of the `Fn` class.
@ -9,7 +9,7 @@ Functions are objects like everything else in Wren, instances of the `Fn` class.
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 it's simplest, it looks like this:
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:
:::dart
blondie.callMe {
@ -106,7 +106,7 @@ Otherwise, the body returns `null` by default. You can explicitly return a value
## Closures
As you expect, functions are closures: they can access variables defined outside of their scope. They will hold onto closed-over variables even after leaving the scope where the function is defined:
As you expect, functions are closures—they can access variables defined outside of their scope. They will hold onto closed-over variables even after leaving the scope where the function is defined:
:::dart
class Counter {
@ -116,7 +116,7 @@ As you expect, functions are closures: they can access variables defined outside
}
}
Here, the `create` method returns the function created on its second line. That function references a variable `i` declared outside of the function. Even after the function is returned from `create`, it is still able to access `i`.
Here, the `create` method returns the function created on its second line. That function references a variable `i` declared outside of the function. Even after the function is returned from `create`, it is still able to read and assign to`i`:
:::dart
var counter = Counter.create

View File

@ -13,21 +13,35 @@ Here, we've created a list of three elements. Notice that the elements don't hav
You can access an element from a list by calling the [subscript operator](method-calls.html#subscript-operators) on it with the index of the element you want. Like most languages, indexes start at zero:
:::dart
var hirsute = ["sideburns", "porkchops", "'stache"]
var hirsute = ["sideburns", "porkchops", "'stache", "goatee"]
hirsute[0] // "sideburns".
hirsute[1] // "porkchops".
Negative indices counts backwards from the end:
:::dart
hirsute[-1] // "'stache".
hirsute[-2] // "porkchops".
hirsute[-1] // "goatee".
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:
:::dart
hirsute.count // 3.
## Slices and ranges
Sometimes you want to slice out a chunk of elements from a list. You can do that by passing a [range](values.html#ranges) to the subscript operator, like so:
:::dart
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 and do what you expect.
Negative bounds also work like they do when passing a single number, so to copy a list, you can just do:
:::dart
hirsute[0..-1]
## Adding elements
Lists are *mutable*, meaning their contents can be changed. You can swap out an existing element in the list using the subscript setter:
@ -72,5 +86,3 @@ If you want to remove everything from the list, you can clear it:
:::dart
hirsute.clear
IO.print(hirsute) // []
**TODO: Ranges, iteration, etc.**

View File

@ -57,7 +57,7 @@ So this program will print the numbers from 1 to 3, but will not print 4.
## Numeric ranges
Lists are one common use for `for` loops, but sometimes you want to walk over a sequence of numbers, or loop a number of times. For that, you can use a *range* expression, like so:
Lists are one common use for `for` loops, but sometimes you want to walk over a sequence of numbers, or loop a number of times. For that, you can create a [range object](values.html#ranges), like so:
:::dart
for (i in 1..100) {
@ -100,4 +100,4 @@ Each iteration, it calls `iterate()` on the sequence, passing in the current ite
If `false` is returned, Wren exits out of the loop and we're done. If anything else is returned, that means that we have advanced to a new valid element. To get that, Wren then calls `iteratorValue()` on the sequence and passes in the iterator value that it just got from calling `iterate()`. The sequence uses that to look up and return the appropriate element.
The built-in List and Range types implement `iterate()` and `iteratorValue()` to walk over their respective sequences. You can implement the same methods in your classes to make your own types iterable.
The built-in [List](lists.html) and [Range](values.html#ranges) types implement `iterate()` and `iteratorValue()` to walk over their respective sequences. You can implement the same methods in your classes to make your own types iterable.

View File

@ -1,4 +1,4 @@
^title Maps
^category types
**TODO**
Wren will have a built-in hash table type similar to objects in JavaScript and tables in Lua, but they haven't been implemented yet.

View File

@ -95,7 +95,7 @@ Most languages use square brackets (`[]`) for working with collection-like
objects. For example:
:::dart
list.add["item"]
first = list[0]
map["key"] = "value"
You know the refrain by now. In Wren, these are just method calls. Subscript

View File

@ -203,7 +203,7 @@ pre {
}
footer {
margin-top: 20px;
margin-top: 40px;
padding: 20px 0 40px 0;
font: 14px $body;
background: $dark;

View File

@ -65,5 +65,3 @@ assigned value.
:::dart
var a = "before"
IO.print(a = "after") // Prints "after".
**TODO: Forward references for globals, closures.**