1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
|
<head>
<link href="../favicon.ico" rel="shortcut icon" type="image/x-icon"/>
<link href="../style.css" rel="stylesheet"/>
<title>BQN: Namespaces</title>
</head>
<div class="nav"><a href="https://github.com/mlochbaum/BQN">BQN</a> / <a href="../index.html">main</a> / <a href="index.html">doc</a></div>
<h1 id="namespaces">Namespaces</h1>
<p>A namespace is a type of value that groups together several values (fields) from the same scope. A block or file returns a namespace if it contains any export arrows <code><span class='Gets'>⇐</span></code> at the top level, and fields from namespaces can be accessed with either dot syntax or destructuring assignment. A namespace can be mutable only if any of the code in it uses <code><span class='Gets'>↩</span></code> to change the value of a field.</p>
<p>The following quick example shows a few ways to use a namespace returned by <code><span class='Function'>•Import</span></code>:</p>
<pre><span class='Value'>ns</span> <span class='Gets'>←</span> <span class='Function'>•Import</span> <span class='String'>"file.bqn"</span>
<span class='Bracket'>⟨</span><span class='Value'>something</span><span class='Separator'>,</span> <span class='Value'>abbr</span><span class='Gets'>⇐</span><span class='Value'>abbreviation</span><span class='Bracket'>⟩</span> <span class='Gets'>←</span> <span class='Value'>ns</span> <span class='Comment'># Destructure
</span><span class='Value'>ns.</span><span class='Function'>DoThing</span> <span class='Number'>6</span> <span class='Comment'># Dot syntax
</span></pre>
<p>An here's how the contents of file.bqn might look in order to define the variables used above:</p>
<pre><span class='Bracket'>⟨</span><span class='Value'>something</span><span class='Separator'>,</span> <span class='Function'>DoThing</span><span class='Bracket'>⟩</span><span class='Gets'>⇐</span> <span class='Comment'># Declare exports
</span><span class='Value'>abbreviation</span> <span class='Gets'>⇐</span> <span class='String'>"sth"</span> <span class='Comment'># Define and export
</span><span class='Modifier'>_something</span> <span class='Gets'>←</span> <span class='Brace'>{</span><span class='Value'>𝕗</span><span class='Brace'>}</span> <span class='Comment'># Separate definition
</span><span class='Function'>DoThing</span> <span class='Gets'>←</span> <span class='String'>"TODO"</span><span class='Modifier2'>⊸</span><span class='Function'>!</span>
</pre>
<h2 id="uses">Uses</h2>
<p>The features of namespaces that make them useful in BQN programming are encapsulation and mutability. But these are exactly the same features that <a href="lexical.html#closures">closures</a> provide! In fact a namespace is not much more than a closure with a name lookup system. Consequently namespaces don't really expand the basic functionality of the language, but just make it easier to use.</p>
<p>Namespaces improve encapsulation by allowing many values to be exported at once. With only one way to call them, functions and modifiers aren't such a good way to define a large part of a program. With a namespace you can define lots of things and expose exactly the ones you want to the rest of the world. For example, it's typical for files to define namespaces. A reader can see the exported values just by searching for <code><span class='Gets'>⇐</span></code>, and if you're nice, you might declare them all at the beginning of the file. Careful use of exports can guarantee that potentially dangerous functions are used correctly: if it's only valid to call function <code><span class='Function'>B</span></code> after function <code><span class='Function'>A</span></code> has been called, export <code><span class='Function'>AB</span><span class='Gets'>⇐</span><span class='Brace'>{</span><span class='Function'>A</span><span class='Value'>𝕩</span><span class='Separator'>⋄</span><span class='Function'>B</span><span class='Value'>𝕩</span><span class='Brace'>}</span></code> and don't export <code><span class='Function'>B</span></code>.</p>
<p>Mutability means that the behavior of one namespace can change over the course of the program. Mutability is often a liability, so make sure you really need it before leaning too heavily on this property. While there's no way to tell from the outside that a particular namespace is mutable, you can tell it isn't if the source code doesn't contain <code><span class='Gets'>↩</span></code>, as this is the only way it can modify the variables it contains.</p>
<p>A namespace that makes use of mutability is essentially an object: a collection of state along with operations that act on it. <a href="oop.html">Object-oriented programming</a> is the other major use of namespaces. Contrary to the name, there's never a need to orient your programming around objects, and it's perfectly fine to use an object here or there when you need to, for instance to build a mutable queue of values.</p>
<h2 id="exports">Exports</h2>
<p>The double arrow <code><span class='Gets'>⇐</span></code> is used to export variables from a block or file, making the result a namespace instead of the result of the last line. There are two ways to export variables. First, <code><span class='Gets'>←</span></code> in the variable definition can be replaced with <code><span class='Gets'>⇐</span></code> to export the variable as it's defined. Second, an export statement consisting of an assignment target followed by <code><span class='Gets'>⇐</span></code>, with nothing to the right, exports the variables in the target and does nothing else. These 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. The block in the example below has two statements that export variables, exporting <code><span class='Value'>a</span></code>, <code><span class='Value'>b</span></code>, and <code><span class='Value'>c</span></code>.</p>
<pre><span class='Value'>example</span> <span class='Gets'>←</span> <span class='Brace'>{</span>
<span class='Value'>b</span><span class='Ligature'>‿</span><span class='Value'>c</span><span class='Gets'>⇐</span> <span class='Comment'># Non-definition exports can go anywhere
</span> <span class='Value'>a</span><span class='Gets'>⇐</span><span class='Number'>2</span> <span class='Comment'># Define and export
</span> <span class='Value'>b</span><span class='Gets'>←</span><span class='Number'>1</span><span class='Function'>+</span><span class='Value'>a</span>
<span class='Value'>c</span><span class='Gets'>←</span><span class='Value'>b</span><span class='Ligature'>‿</span><span class='String'>"str"</span>
<span class='Brace'>}</span>
</pre>
<h2 id="imports">Imports</h2>
<p>There are also two ways to get values out of a namespace, such as <code><span class='Value'>example</span></code> defined above. First, it might be used in a destructuring assignment like the one below. This assignment's target looks like a list, where each entry specifies one of the names exported by the block and what it should be assigned to. The element can be either a single name, like <code><span class='Value'>b</span></code>, which gives both, or an aliasing expression like <code><span class='Value'>b2</span><span class='Gets'>⇐</span><span class='Value'>b</span></code>. In this case, the value <code><span class='Value'>b</span></code> from the namespace is used, but it's given the name <code><span class='Value'>b2</span></code> instead of <code><span class='Value'>b</span></code>. Imported names can be repeated—but the variables defined can't—and all the names can be spelled with any role (the role is ignored).</p>
<pre><span class='Bracket'>⟨</span><span class='Value'>alias</span><span class='Gets'>⇐</span><span class='Value'>a</span><span class='Separator'>,</span> <span class='Value'>b</span><span class='Separator'>,</span> <span class='Value'>c0</span><span class='Ligature'>‿</span><span class='Value'>c1</span><span class='Gets'>⇐</span><span class='Value'>c</span><span class='Separator'>,</span> <span class='Value'>b2</span><span class='Gets'>⇐</span><span class='Value'>b</span><span class='Bracket'>⟩</span> <span class='Gets'>←</span> <span class='Value'>example</span>
</pre>
<p>If aliasing with <code><span class='Gets'>⇐</span></code> is never used, the names can be given as a strand with <code><span class='Ligature'>‿</span></code>.</p>
<pre><span class='Value'>c</span><span class='Ligature'>‿</span><span class='Value'>a</span> <span class='Gets'>←</span> <span class='Value'>example</span>
</pre>
<p>The arrows <code><span class='Gets'>⇐</span></code> used for importing don't indicate that the surrounding block is a namespace or export variables. However, a single statement can both import and export, if it's a destructuring assignment and the main assignment arrow is <code><span class='Gets'>⇐</span></code>.</p>
<pre><span class='Bracket'>⟨</span><span class='Value'>two</span><span class='Separator'>,</span> <span class='Value'>vars</span><span class='Bracket'>⟩</span> <span class='Gets'>⇐</span> <span class='Function'>•Import</span> <span class='String'>"stuff.bqn"</span>
</pre>
<p>The second way to get a value (just one at a time) from a namespace is dot syntax: write the namespace, then a dot <code><span class='Value'>.</span></code>, then another name.</p>
<pre><span class='Value'>example.b</span>
<span class='Brace'>{</span><span class='Value'>n</span><span class='Gets'>⇐</span><span class='Number'>7</span><span class='Brace'>}</span><span class='Value'>.n</span>
</pre>
<p>The syntax is any subject followed by a dot and then a name. This can be chained like <code><span class='Value'>a.b.c</span></code> if a namespace has a value that is also a namespace (and so on).</p>
|