diff options
| author | Marshall Lochbaum <mwlochbaum@gmail.com> | 2021-07-18 17:53:37 -0400 |
|---|---|---|
| committer | Marshall Lochbaum <mwlochbaum@gmail.com> | 2021-07-18 17:53:37 -0400 |
| commit | 7e0e38bd155fab76fa3b6776f9184611d044903d (patch) | |
| tree | 9cbd13e8aae249cb97b1dd2b22a084817093890c /docs/doc/functional.html | |
| parent | bbecd676b7c127fead3ef172bbae3ddf2fb7f19a (diff) | |
Finish lexical scope documentation
Diffstat (limited to 'docs/doc/functional.html')
| -rw-r--r-- | docs/doc/functional.html | 4 |
1 files changed, 2 insertions, 2 deletions
diff --git a/docs/doc/functional.html b/docs/doc/functional.html index f0149660..50d70af5 100644 --- a/docs/doc/functional.html +++ b/docs/doc/functional.html @@ -60,7 +60,7 @@ </svg> <p>The term <em>functional programming</em> is more contentious, and has many meanings some of which can be vague. Here I use it for what might be called <em>first-class functional programming</em>, programming that makes significant use of first-class functions; in this usage, Scheme is probably the archetypal functional programming language. However, other definitions are also worth mentioning. APL is often called a functional programming language on the grounds that functions can be assigned and manipulated, and called recursively, all characteristics it shares with Lisp. I prefer the term <em>function-level programming</em> for this usage. A newer usage, which I call <em>pure functional programming</em>, restricts the term "function" to mathematical functions, which have no side effects, so that functional programming is programming with no side effects, often using monads to accumulate effects as part of arguments and results instead. Finally, <em>typed functional programming</em> is closely associated with pure functional programming and refers to languages influenced by type theory such as Haskell, F#, and Idris (the last of which even supports <em>dependently-typed functional programming</em>, but I already said "finally" so we'll stop there). Of these, BQN supports first-class functional and function-level programming, allows but doesn't encourage pure functional programming, and does not support typed functional programming, as it's dynamically and not statically typed.</p> -<p>Another topic we are interested in is <em>lexical scoping</em> and <em>closures</em>. Lexical scoping means that the realm in which a variable exists is determined by its containing context (in BQN, the surrounding set of curly braces <code><span class='Brace'>{}</span></code>, if any) within the source code. A closure is really an implementation mechanism, but it's often used to refer to a property of lexical scoping that appears when functions defined in a particular block can be accessed after the block finishes execution. For example, they might be returned from a function or assigned to a variable outside of that function's scope. In this case the functions can still access variables in the original scope. I consider this property to be a requirement for a correct lexical scoping implementation, but it's traditionally not a part of APL: implementation might not have lexical scoping (for example, J and I believe A+ use static scoping where functions can't access variables in containing scopes) or might cut off the scope once execution ends, leading to value errors that one wouldn't predict from the rules of lexical scoping.</p> +<p>Another topic we are interested in is <em>lexical scoping</em> and <em>closures</em>. <a href="lexical.html">Lexical scoping</a> means that the realm in which a variable exists is determined by its containing context (in BQN, the surrounding set of curly braces <code><span class='Brace'>{}</span></code>, if any) within the source code. A closure is really an implementation mechanism, but it's often used to refer to a property of lexical scoping that appears when functions defined in a particular block can be accessed after the block finishes execution. For example, they might be returned from a function or assigned to a variable outside of that function's scope. In this case the functions can still access variables in the original scope. I consider this property to be a requirement for a correct lexical scoping implementation, but it's traditionally not a part of APL: implementation might not have lexical scoping (for example, J and I believe A+ use static scoping where functions can't access variables in containing scopes) or might cut off the scope once execution ends, leading to value errors that one wouldn't predict from the rules of lexical scoping.</p> <h2 id="functions-in-apl">Functions in APL</h2> <p>This seems like a good place for a brief and entirely optional discussion of how APL handles functions and why it does it this way. As mentioned above, APL's functions are second class rather than first class. But the barriers to making functions first-class objects have been entirely syntactic and conceptual, not technical. In fact, the J language has for a long time had <a href="http://www.jsoftware.com/pipermail/programming/2013-January/031260.html">a bug</a> that allows an array containing a function to be created: by selecting from the array, the function itself can even be passed through tacit functions as an argument!</p> <p>The primary reason why APL doesn't allow functions to be passed as arguments is probably syntax: in particular, there's no way to say that a function should be used as the left argument to another function, as an expression like <code><span class='Function'>F</span> <span class='Function'>G</span> <span class='Value'>x</span></code> with functions <code><span class='Function'>F</span></code> and <code><span class='Function'>G</span></code> and an array <code><span class='Value'>x</span></code> will simply be evaluated as two monadic function applications. However, there's no syntactic rule that prevents a function from returning a function, and Dyalog APL for example allows this (so <code><span class='Value'>⍎</span><span class='String'>'+'</span></code> returns the function <code><span class='Function'>+</span></code>). Dyalog's <code><span class='Value'>⎕</span><span class='Function'>OR</span></code> is another interesting phenomenon in this context: it creates an array from a function or operator, which can then be used as an element or argument like any array. The mechanism is essentially the same as BQN's first class functions, and in fact <code><span class='Value'>⎕</span><span class='Function'>OR</span></code>s even share a form of BQN's <a href="../commentary/problems.html#syntactic-type-erasure">syntactic type erasure</a>, as a <code><span class='Value'>⎕</span><span class='Function'>OR</span></code> of a function passed as an operand magically becomes a function again. But outside of this property, it's cumbersome and slow to convert functions to and from <code><span class='Value'>⎕</span><span class='Function'>OR</span></code>s, so they don't work very well as a first-class function mechanism.</p> @@ -75,7 +75,7 @@ <span class='Value'>v0</span> <span class='Function'>+</span> <span class='Paren'>((</span><span class='Function'>𝕏</span> <span class='Number'>1</span><span class='Paren'>)</span> <span class='Function'>-</span> <span class='Value'>v0</span><span class='Paren'>)</span> <span class='Function'>×</span> <span class='Function'>⊢</span> <span class='Brace'>}</span> </pre> -<p>We can pass it the <a href="arithmetic.html#basic-arithmetic">exponential</a> function as an argument by giving it the name <code><span class='Function'>Exp</span></code> and then referring to it in lowercase (that is, in a subject role). The result is a <a href="train.html">train</a> that adds 1 to <em>e</em>-1 times the argument.</p> +<p>We can pass it the <a href="arithmetic.html#basic-arithmetic">exponential</a> function as an argument by giving it the name <code><span class='Function'>Exp</span></code> and then referring to it in lowercase (that is, in a subject role). The result is a <a href="train.html">train</a> that adds 1 to <em>e</em>-1 times the argument (we'll discuss only tacit functions here; for blocks see <a href="lexical.html">lexical scoping</a>).</p> <a class="replLink" title="Open in the REPL" target="_blank" href="https://mlochbaum.github.io/BQN/try.html#code=TGluIOKGkCB7IHYw4oaQ8J2VjzAg4ouEIHYwKygo8J2VjzEpLXYwKcOX4oqiIH0gICMgKGNvcHkgb2YgYWJvdmUpCkV4cCDihpAg4ouGCkxpbiBleHA=">↗️</a><pre> <span class='Function'>Lin</span> <span class='Gets'>←</span> <span class='Brace'>{</span> <span class='Value'>v0</span><span class='Gets'>←</span><span class='Function'>𝕏</span><span class='Number'>0</span> <span class='Separator'>⋄</span> <span class='Value'>v0</span><span class='Function'>+</span><span class='Paren'>((</span><span class='Function'>𝕏</span><span class='Number'>1</span><span class='Paren'>)</span><span class='Function'>-</span><span class='Value'>v0</span><span class='Paren'>)</span><span class='Function'>×⊢</span> <span class='Brace'>}</span> <span class='Comment'># (copy of above) </span> <span class='Function'>Exp</span> <span class='Gets'>←</span> <span class='Function'>⋆</span> <span class='Function'>Lin</span> <span class='Value'>exp</span> |
