diff --git a/bin/test-doc-examples b/bin/test-doc-examples index 2324bb1b..dcafd717 100755 --- a/bin/test-doc-examples +++ b/bin/test-doc-examples @@ -48,10 +48,11 @@ from pathlib import Path IMAGE = "exercism/factor-test-runner" DEFAULT_USING = ( - "kernel math math.functions math.order math.parser math.statistics " - "math.bitwise math.primes sequences strings arrays vectors hashtables " - "assocs combinators continuations splitting ascii prettyprint " - "io io.streams.string namespaces quotations literals fry" + "arrays ascii assocs combinators continuations fry hashtables " + "io io.streams.string kernel literals math math.bitwise " + "math.functions math.order math.parser math.primes math.statistics " + "namespaces prettyprint quotations sequences sorting splitting " + "strings vectors" ) SENTINEL = "###BLOCK-END###" diff --git a/docs/ABOUT.md b/docs/ABOUT.md index 1e97238e..1002818f 100644 --- a/docs/ABOUT.md +++ b/docs/ABOUT.md @@ -4,7 +4,7 @@ Factor was originally designed by Slava Pestov in 2002, as a scripting language Factor can create standalone, and even GUI applications that behave exactly the same on Linux, Windows and Mac OS. -Factor is a simple, yet powerful and expressive stack-oriented high-level language in the vein of Forth, Joy and Lisp. It proposes a concatenative (point-free and compositional) model of data flow, alongside extreme extensibility and a [CLOS](http://enwp.org/Common_Lisp_Object_System)-derived object system. +Factor is a simple, yet powerful and expressive stack-oriented high-level language in the vein of Forth, Joy and Lisp. It proposes a concatenative (point-free and compositional) model of data flow, alongside extreme extensibility and a [CLOS](https://enwp.org/Common_Lisp_Object_System)-derived object system. Homoiconicity is a large part of Factor's programming model. All values, including functions and blocks of Factor code, go on the same stack and can be manipulated in the same way. This is a simple, yet powerful paradigm that invites interesting solutions to problems, and indefinite extensibility. @@ -12,7 +12,7 @@ Factor requires from the reader a mindset apart from C or Python. Because of its The Factor programming language is open source, and you can find it in active development on [GitHub](https://github.com/factor/factor). -If you're even a little bit new to Factor, it's highly recommended you read the [Factor cookbook](http://docs.factorcode.org/content/article-cookbook.html) and [Your first program](http://docs.factorcode.org/content/article-first-program.html) sections of the Factor documentation before continuing. +If you're even a little bit new to Factor, it's highly recommended you read the [Factor cookbook](https://docs.factorcode.org/content/article-cookbook.html) and [Your first program](https://docs.factorcode.org/content/article-first-program.html) sections of the Factor documentation before continuing. ## Glossary of Factor terms diff --git a/docs/INSTALLATION.md b/docs/INSTALLATION.md index 997cfb5b..073c297a 100644 --- a/docs/INSTALLATION.md +++ b/docs/INSTALLATION.md @@ -9,7 +9,7 @@ Verify your installation by running `factor -e='vm-version print'` — it should --- ### Nightly - provides nightly binaries under the "Development release" section. These binaries are built from git, but only builds that pass are shown. + provides nightly binaries under the "Development release" section. These binaries are built from git, but only builds that pass are shown. --- @@ -21,7 +21,7 @@ With those simple requirements fulfilled, you can: 1. Download the `build` shell script: [**here** for Unix-likes / POSIX shells](https://raw.githubusercontent.com/factor/factor/master/build.sh) or [**here** for Windows](https://raw.githubusercontent.com/factor/factor/master/build.cmd). Put it in the directory under which Factor should be installed. A directory called `factor` containing the codebase will be created. -2. Run it like `./build.sh install`, or `.\build.cmd install` on Windows. This will clone Factor's `git` repository, build it, and download a Factor VM image from . This process may take between 2 and 20 minutes, scaling with your link and clock speeds. +2. Run it like `./build.sh install`, or `.\build.cmd install` on Windows. This will clone Factor's `git` repository, build it, and download a Factor VM image from . This process may take between 2 and 20 minutes, scaling with your link and clock speeds. 3. You can now run the `factor` or `factor.exe` binary generated inside the `factor` subdirectory. Try `factor --help` for help. You can also access documentation from the command line, or by pressing F1 in the GUI Listener, which will open the help browser. diff --git a/docs/TESTS.md b/docs/TESTS.md index be2b8c2a..0bcf8ed1 100644 --- a/docs/TESTS.md +++ b/docs/TESTS.md @@ -1,4 +1,4 @@ -# [The `tools.test` framework](http://docs.factorcode.org/content/vocab-tools.test.html) +# [The `tools.test` framework](https://docs.factorcode.org/content/vocab-tools.test.html) Factor's built-in testing framework, rather like Factor itself, marries simplicity with unbridled power. @@ -30,4 +30,4 @@ factor -roots=. -run=exercism-tools annalyns-infiltration The runner exits with status 0 when all tests pass, and non-zero with diagnostic output when any test fails. -For more information, see the Factor documentation on [Unit testing](http://docs.factorcode.org/content/article-tools.test.html). +For more information, see the Factor documentation on [Unit testing](https://docs.factorcode.org/content/article-tools.test.html). diff --git a/exercises/concept/backyard-birdcount/.docs/hints.md b/exercises/concept/backyard-birdcount/.docs/hints.md index bfd4e1b2..8d925623 100644 --- a/exercises/concept/backyard-birdcount/.docs/hints.md +++ b/exercises/concept/backyard-birdcount/.docs/hints.md @@ -4,9 +4,8 @@ - `if-empty` from [`sequences`][sequences] is the right base case for recursion: empty sequence one branch, non-empty the other. -- `unclip` returns `( seq -- rest first )` — exactly what a - recursive helper needs to consume one element and recurse on the - rest. +- `unclip` is exactly what a recursive helper needs to consume one + element and recurse on the rest. ## 1. Today's count @@ -16,7 +15,7 @@ ## 2. Increment today's count - `unclip 1 + prefix` peels the first element, increments it, and - glues it back on. `prefix` lives in [`sequences`][sequences]. + glues it back on. ## 3. Was there a day with no birds? diff --git a/exercises/concept/backyard-birdcount/.docs/introduction.md b/exercises/concept/backyard-birdcount/.docs/introduction.md index 2da210b8..a417aa55 100644 --- a/exercises/concept/backyard-birdcount/.docs/introduction.md +++ b/exercises/concept/backyard-birdcount/.docs/introduction.md @@ -18,29 +18,6 @@ modifier to ask it to assume self-consistency: ! prints 5 4 3 2 1 ``` -## Splitting a sequence into head and tail - -`unclip` (in [`sequences`][sequences]) peels the first element off a -sequence: - -``` -unclip ( seq -- rest first ) -``` - -```factor -{ 4 0 9 } unclip .s -! => { 0 9 } -! => 4 -``` - -`first` and `rest` give you the same two pieces *without* destructuring -in one step: - -```factor -{ 4 0 9 } first . ! => 4 -{ 4 0 9 } rest . ! => { 0 9 } -``` - ## Empty-or-not branching `if-empty` (in [`sequences`][sequences]) is the natural recursion @@ -72,19 +49,6 @@ When your recursion has more than two cases, `cond` (in } cond ; ``` -## `prefix` — building a sequence - -`prefix` (in [`sequences`][sequences]) is `suffix` from the other end: - -``` -prefix ( seq elt -- newseq ) -``` - -```factor -{ 7 9 } 3 prefix . -! => { 3 7 9 } -``` - ## Forward references with `DEFER:` A `:` definition can call itself directly, but when two words call diff --git a/exercises/concept/backyard-birdcount/.meta/design.md b/exercises/concept/backyard-birdcount/.meta/design.md index 95aefb68..0f29429b 100644 --- a/exercises/concept/backyard-birdcount/.meta/design.md +++ b/exercises/concept/backyard-birdcount/.meta/design.md @@ -11,8 +11,6 @@ themselves with `unclip` to peel off one element at a time. recursive step. - Use `if-empty` for the empty / non-empty split. - Use `cond` for multi-way branching inside a recursion. -- Use `unclip` and `rest` to advance to the next sub-problem. -- Build sequences with `prefix`. - Use `DEFER:` to forward-declare a word, enabling mutual recursion or out-of-order definitions. diff --git a/exercises/concept/backyard-birdwatcher/.docs/introduction.md b/exercises/concept/backyard-birdwatcher/.docs/introduction.md index 75439003..ce2802a5 100644 --- a/exercises/concept/backyard-birdwatcher/.docs/introduction.md +++ b/exercises/concept/backyard-birdwatcher/.docs/introduction.md @@ -131,15 +131,29 @@ empty? ( seq -- ? ) ## Building a new sequence -`unclip-last` peels the final element off a sequence; `suffix` adds -one to the end. Combining them gives a non-destructive update of the -last element: +`suffix` adds an element to the end of a sequence; `prefix` adds one +to the front. `unclip` peels off the first element and `unclip-last` +peels off the last: ``` -unclip-last ( seq -- butlast last ) +prefix ( seq elt -- newseq ) suffix ( seq elt -- newseq ) +unclip ( seq -- rest first ) +unclip-last ( seq -- butlast last ) +``` + +```factor +{ 7 9 } 3 prefix . ! => { 3 7 9 } +{ 7 9 } 3 suffix . ! => { 7 9 3 } +{ 4 0 9 } unclip .s +! => { 0 9 } +! => 4 ``` +Combining `unclip-last` and `suffix` gives a non-destructive update +of the last element (and `unclip` + `prefix` does the same for the +first): + ```factor { 10 20 30 } unclip-last 2 * suffix . ! => { 10 20 60 } diff --git a/exercises/concept/backyard-birdwatcher/.meta/design.md b/exercises/concept/backyard-birdwatcher/.meta/design.md index f248e455..381a0746 100644 --- a/exercises/concept/backyard-birdwatcher/.meta/design.md +++ b/exercises/concept/backyard-birdwatcher/.meta/design.md @@ -12,7 +12,8 @@ counts. - Pad to a target length with `pad-tail` (and `pad-head`). - Aggregate with `sum` (from `math.statistics`). - Filter-count with `count` and test with `any?`. -- Build a new sequence with `unclip-last` and `suffix`. +- Build a new sequence with `prefix`/`suffix` and + `unclip`/`unclip-last`. ## Out of scope diff --git a/exercises/concept/pursers-pantry/.docs/introduction.md b/exercises/concept/pursers-pantry/.docs/introduction.md index 998464a2..ce575c32 100644 --- a/exercises/concept/pursers-pantry/.docs/introduction.md +++ b/exercises/concept/pursers-pantry/.docs/introduction.md @@ -60,11 +60,23 @@ H{ } clone "coal" over inc-at . ! => H{ { "coal" 1 } } ``` -## Iterating with `each` +## Applying a hashtable update across a sequence of keys -Just like sequences, an `each` over a hashtable iterates *and* gives -you a way to do something with each element. For "do this with each -key" you can stick to sequences and pass `seq` to `each` directly. +When the input is a sequence of keys and you want to update the +hashtable once per key, iterate the *sequence* with `each` and use +a fried quotation `'[ _ … ]` (from [`fry`][fry]) to bake the +hashtable into the loop body. For example, removing a list of keys: + +```factor +{ "wood" "iron" } H{ { "coal" 5 } { "wood" 3 } { "iron" 2 } } clone +[ '[ _ delete-at ] each ] keep . +! => H{ { "coal" 5 } } +``` + +`'[ _ delete-at ]` captures the hashtable above it on the stack so +that on every iteration `each` only needs to supply the key. +`keep` runs the quotation while preserving the hashtable for the +final `.`. ## Converting back to a sequence @@ -78,4 +90,5 @@ H{ { "wood" 11 } { "coal" 7 } } sort-keys . ``` [assocs]: https://docs.factorcode.org/content/vocab-assocs.html +[fry]: https://docs.factorcode.org/content/article-fry.html [sorting]: https://docs.factorcode.org/content/vocab-sorting.html