mirror of
https://github.com/wren-lang/wren.git
synced 2026-01-18 13:49:59 +01:00
Fill in some more docs.
This commit is contained in:
@ -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!
|
||||
@ -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
|
||||
|
||||
@ -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.**
|
||||
|
||||
@ -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.
|
||||
|
||||
@ -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.
|
||||
@ -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
|
||||
|
||||
@ -203,7 +203,7 @@ pre {
|
||||
}
|
||||
|
||||
footer {
|
||||
margin-top: 20px;
|
||||
margin-top: 40px;
|
||||
padding: 20px 0 40px 0;
|
||||
font: 14px $body;
|
||||
background: $dark;
|
||||
|
||||
@ -65,5 +65,3 @@ assigned value.
|
||||
:::dart
|
||||
var a = "before"
|
||||
IO.print(a = "after") // Prints "after".
|
||||
|
||||
**TODO: Forward references for globals, closures.**
|
||||
|
||||
Reference in New Issue
Block a user