From 8389e763344637c01d0d7161091e5f2cd9b14251 Mon Sep 17 00:00:00 2001 From: Marshall Lochbaum Date: Mon, 27 Jun 2022 22:00:55 -0400 Subject: Yet still more editing --- doc/control.md | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) (limited to 'doc/control.md') diff --git a/doc/control.md b/doc/control.md index fe2e77e9..dcded65e 100644 --- a/doc/control.md +++ b/doc/control.md @@ -2,13 +2,13 @@ # Control flow in BQN -BQN does not have ALGOL-style control structures. Instead, functional techniques can be used to control when code is evaluated. This page describes how BQN functionality can be used to emulate something more familiar to an imperative programmer. +BQN does not have ALGOL-style control structures. Instead, [functional](functional.md) techniques can be used to control when code is evaluated. This page describes how BQN functionality can be used to emulate something more familiar to an imperative programmer. Control structures here are always functions that act on lists of functions, although alternatives might be presented. This is because stranded functions can be formatted in a very similar way to blocks in curly-brace languages. However, there are many ways to write control flow, including simple operators and a mix of operators and more control-structure-like code. Implementing a control structure rarely takes much code with any method, so there are usually several simple ways to implement a given flow or a variation of it. The surfeit of ways to write control structures could be a bit of an issue for reading BQN. My hope is that the community can eventually settle on a smaller set of standard forms to recommend so that you won't have to recognize all the variants given here. On the other hand, the cost of using specialized control structures is lower in a large project without too many contributors. In this case BQN's flexibility allows developers to adapt to the project's particular demands (for example, some programs use switch/case statements heavily but most do not). -The useful control structures introduced here are collected as shortened definitions below. `While` uses the slightly more complicated implementation that avoids stack overflow, and `DoWhile` and `For` are written in terms of it in order to share this property. The more direct versions with linear stack use appear in the main text. +The most useful control structures introduced here are collected as shortened definitions below. `While` uses the slightly more complicated implementation that avoids stack overflow, and `DoWhile` and `For` are written in terms of it in order to share this property. The more direct versions with linear stack use appear in the main text. If ← {π•βŸπ•Ž@}Β΄ # Also Repeat IfElse ← {cβ€ΏTβ€ΏF: cβ—ΆFβ€ΏT@} @@ -19,18 +19,18 @@ The useful control structures introduced here are collected as shortened definit # Switch/case statements have many variations; these are a few Match ← {𝕏𝕨}Β΄ Select ← {(βŠ‘π•©)β—Ά(1↓𝕩)@} - Switch ← {cβ†βŠ‘π•© β‹„ mβ€Ώa←<Λ˜β‰βˆ˜β€Ώ2β₯Š1↓𝕩 β‹„ (m⊸⊐⌾{m+=1;n*=2}; fn() Fn ← {𝕀⋄ m+↩1,n×↩2}, Fn @ @@ -39,7 +39,7 @@ Control structures are called "statements" below to match common usage, but they ## If -The if statement conditionally performs some action. It is similar to the Repeat (`⍟`) modifier with a right operand returning a boolean: `Fn⍟Cond 𝕩` gives `Fn 𝕩` if `Cond 𝕩` is `1`, and returns `𝕩` without calling `Fn` if `Cond 𝕩` is `0`. Here is how we might make it behave like a control structure. +The if statement conditionally performs some action. It's similar to the [Repeat](repeat.md) (`⍟`) modifier with a right operand that returns a boolean: `Fn⍟Cond 𝕩` gives `Fn 𝕩` if `Cond 𝕩` is `1`, and returns `𝕩` without calling `Fn` if `Cond 𝕩` is `0`. Here's how we might make it behave like a control structure. {𝕀⋄a+↩10}⍟(a<10) @ @@ -58,7 +58,7 @@ For a more conventional presentation, the condition and action can be placed in The result of any of these if statements is the result of the action if it's performed, and otherwise it's whatever argument was passed to the statement, which is `@` or `10` here. -BQN's syntax for a pure if statement isn't so good, but predicates handle [if-else](#if-else) statements nicely. So in most cases you'd forego the definitions above in favor of an if-else with nothing in the else branch: +BQN's syntax for a pure if statement isn't so good, but [predicates](block.md#predicates) handle [if-else](#if-else) statements nicely. So in most cases you'd forego the definitions above in favor of an if-else with nothing in the else branch: { a<10 ? a+↩10 ; @ } @@ -70,7 +70,7 @@ Another option is to use a [for-each](#for) statement with an argument of `↕n` ## If-Else -In most cases, the easy way to write an if-else statement is with [predicates](block.md#predicates): +In most cases, the easy way to write an if-else statement is with a [predicate](block.md#predicates): { threshold < 6 ? @@ -78,7 +78,7 @@ In most cases, the easy way to write an if-else statement is with [predicates](b b ↩ 1 Large threshold # If it wasn't } -We might also think of an if-else statement as a kind of [switch-case](#switch-case) statement, where the two cases are true (`1`) and false (`0`). As a result, we can implement it either with Choose (`β—Ά`) or with [case headers](block.md#case-headers) of `1` and `0`. +We might also think of an if-else statement as a kind of [switch-case](#switch-case) statement, where the two cases are true (`1`) and false (`0`). As a result, we can implement it either with [Choose](choose.md) (`β—Ά`) or with [case headers](block.md#case-headers) of `1` and `0`. When using Choose, note that the natural ordering places the false case before the true one to match list index ordering. To get the typical if-else order, the condition should be negated or the statements reversed. Here's a function to get an if-else statement by swapping the conditions, and two ways its application might be written. @@ -122,7 +122,7 @@ For a function-based approach, it's possible to nest `IfElse` expressions, but i Test ⟨ ( a