aboutsummaryrefslogtreecommitdiff
path: root/doc/expression.md
diff options
context:
space:
mode:
authorMarshall Lochbaum <mwlochbaum@gmail.com>2021-11-15 22:16:46 -0500
committerMarshall Lochbaum <mwlochbaum@gmail.com>2021-11-15 22:16:46 -0500
commit25311370e215cd12018dde8bd162583dbe36d473 (patch)
tree271c8d0119a916d37fb295edd4dffe805bd4e115 /doc/expression.md
parent831b556f20d1e6427d561c0fcb4bb0c6d592314a (diff)
Compress expression section in syntax summary, moving details to expression page
Diffstat (limited to 'doc/expression.md')
-rw-r--r--doc/expression.md29
1 files changed, 29 insertions, 0 deletions
diff --git a/doc/expression.md b/doc/expression.md
index 2ec43994..61985d4b 100644
--- a/doc/expression.md
+++ b/doc/expression.md
@@ -31,6 +31,10 @@ In APL, the way one part of an expression interacts with others is determined by
Syntactic role is a property of an expression, not its value. To describe it in terms of English grammar, you might say "I like BQN", using "BQN" as an object, or "BQN scares me", using it as a subject. BQN itself isn't a subject or object, it's a programming language. Similarly you might write `F g`, placing `f` in a function role to apply it to `g`, or `G f` to use `f` as an argument. Maybe even in the same program, although it's unlikely.
+Below, the function `{π•Žπ•©}` treats its left argument `π•Ž` as a function and its right argument `𝕩` as a subject. With a list of functions, we can make a table of the square and square root of a few numbers:
+
+ βŸ¨Γ—Λœ,√⟩ {π•Žπ•©}⌜ 1β€Ώ4β€Ώ9
+
### Role spellings
The four roles are **subject**, **function**, **1-modifier**, and **2-modifier**, as shown in the table below. Each type has an associated role (with non-operation types all corresponding to subjects), and the value of an expression will often have a matching type, but it doesn't have to.
@@ -78,3 +82,28 @@ Here is a table of the modifier and function application rules:
| `F*` | `_c_` | | 1-Modifier | Partial application
A function with an asterisk indicates that a subject can also be used. Since the role doesn't exist after parsing, function and subject spellings are indistinguishable in these positions. Modifier applications bind more tightly than functions, and associate left-to-right while functions associate right-to-left.
+
+### Assignment
+
+Another element that can be included in expressions is assignment, which is written with `←` to *define* (also called "declare" in many other languages) a variable and `↩` to *change* its definition. A variable can only be defined once within a [scope](lexical.md), and can only be changed if it has already been defined. However, it can be shadowed, meaning that it is defined again in an inner scope even though it has a definition in an outer scope already.
+
+ x←1 β‹„ {x←2 β‹„ x↩3 β‹„ x}
+ x
+
+Assignment can be used inline in an expression, and its result is always the value being assigned. The role of the identifier used must match the value being assigned.
+
+ 2Γ—a←(Neg←-)3
+ a
+
+### Exports
+
+The double arrow `⇐` is used to export variables from a block or program, causing the result to be a [namespace](namespace.md). There are two ways to export variables. First, `←` in the variable definition can be replaced with `⇐` to export the variable as it's defined. Second, an export statement consisting of an assignment target followed by `⇐` with nothing to the right exports the variables in the assignment target and does nothing else. Export statements can be placed anywhere in the relevant program or body, including before declaration or on the last line, and a given variable can be exported any number of times.
+
+ ⟨alias⇐a, b, c0β€Ώc1⇐c, b2⇐bβŸ©β†{
+ bβ€Ώc⇐ # Non-definition exports can go anywhere
+ a⇐2 # Define and export
+ b←1+a
+ c←bβ€Ώ"str"
+ }
+
+Fields of the resulting namespace can be accessed either directly using `namespace.field` syntax, or with a destructuring assignment as shown above. This assignment's target is a list where each element specifies one of the names exported by the block and what it should be assigned to. The element can be either a single name (such as `b` above), which gives both, or a combination of the assignment target, then `⇐`, then a name. If `⇐` is never used, the names can be given as a strand with `β€Ώ`. To use `⇐` for aliases, bracket syntax `⟨⟩` is needed. Imported names can be repeated and can be spelled with any role (the role is ignored).