diff --git a/bin/test-doc-examples b/bin/test-doc-examples index dcafd71..3c5058f 100755 --- a/bin/test-doc-examples +++ b/bin/test-doc-examples @@ -49,10 +49,10 @@ IMAGE = "exercism/factor-test-runner" DEFAULT_USING = ( "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" + "io io.streams.string kernel literals locals math math.bitwise " + "math.constants math.functions math.order math.parser math.primes " + "math.statistics namespaces prettyprint quotations sequences " + "sorting splitting strings typed vectors" ) SENTINEL = "###BLOCK-END###" diff --git a/concepts/deques/about.md b/concepts/deques/about.md index 9d78eff..5c82274 100644 --- a/concepts/deques/about.md +++ b/concepts/deques/about.md @@ -14,7 +14,8 @@ can implement them. | `pop-back` | `( deque -- elt )` — remove from the back | | `peek-front` | `( deque -- elt )` — read the front without removing | | `peek-back` | `( deque -- elt )` — read the back without removing | -| `deque-empty?` | `( deque -- ? )` — also written `empty?` (sequence protocol) | +| `deque-empty?` | `( deque -- ? )` — is the deque empty? | +| `dlist-length` | `( dlist -- n )` — element count | All push/pop operations mutate the deque in place — passing a deque to a routine and then reading from it again is the normal diff --git a/concepts/sequences/about.md b/concepts/sequences/about.md index ff176ef..bfea64e 100644 --- a/concepts/sequences/about.md +++ b/concepts/sequences/about.md @@ -42,7 +42,7 @@ with the others. | `find-last` | `( seq quot -- i/f elt/f )` | | `produce` | `( pred quot -- seq )` | -Arrays are immutable; the `prefix`/`suffix`/`append` operations all +Arrays are immutable; the `prefix`/`suffix`/`append`/`prepend` operations all return new sequences without modifying the original. Vectors are mutable — `push` and `pop` work in place — but `clone` is the right starting point if you want a fresh copy. diff --git a/exercises/concept/annalyns-infiltration/.docs/introduction.md b/exercises/concept/annalyns-infiltration/.docs/introduction.md index 1af99df..a2ce46c 100644 --- a/exercises/concept/annalyns-infiltration/.docs/introduction.md +++ b/exercises/concept/annalyns-infiltration/.docs/introduction.md @@ -27,6 +27,8 @@ tuck ( x y -- y x y ) 3dup ( x y z -- x y z x y z ) 4dup ( w x y z -- w x y z w x y z ) 2drop ( x y -- ) +3drop ( x y z -- ) +4drop ( w x y z -- ) 2nip ( x y z -- z ) 2swap ( x y z w -- z w x y ) ``` diff --git a/exercises/concept/bering-bearings/.docs/introduction.md b/exercises/concept/bering-bearings/.docs/introduction.md index 901b613..dcd29c1 100644 --- a/exercises/concept/bering-bearings/.docs/introduction.md +++ b/exercises/concept/bering-bearings/.docs/introduction.md @@ -5,15 +5,15 @@ on the *class* of one of its arguments. Concrete behaviour comes from *methods*, defined with `M:`. ```factor -USING: kernel math ; - GENERIC: area ( shape -- n ) TUPLE: square side ; TUPLE: circle radius ; -M: square area side>> dup * ; -M: circle area radius>> dup * pi * ; +M: square area + side>> dup * ; +M: circle area + radius>> dup * pi * ; ``` When `area` is called, Factor inspects the top of the stack, @@ -21,15 +21,18 @@ looks up the most-specific method whose class matches, and runs it. With locals you can use `M::`: ```factor -USING: locals ; +TUPLE: rectangle width height ; + +M:: rectangle area ( r -- n ) + r width>> r height>> * ; -M:: square area ( s -- n ) - s side>> :> a a a * ; +T{ rectangle { width 3 } { height 4 } } area . ! => 12 ``` Generics let you add new representations later without changing -the calling code. Anywhere `area` was called, the new method is -picked up automatically. +the calling code: `area` already worked for `square` and `circle`, +and the `rectangle` method is picked up automatically wherever +`area` is called. ## When a generic is the right choice @@ -52,8 +55,14 @@ tuple can opt into the protocol's default methods by declaring itself an instance: ```factor -TUPLE: my-shape ... ; -INSTANCE: my-shape shape ! my-shape is now a `shape` +MIXIN: shape +M: shape area ! a default area for any shape + drop 0 ; + +TUPLE: my-shape ; +INSTANCE: my-shape shape ! my-shape is now a `shape` + +T{ my-shape } area . ! => 0 ``` After `INSTANCE:`, every default method `M: shape …` automatically @@ -61,6 +70,27 @@ dispatches on `my-shape`, and any code that asks for a `shape` accepts a `my-shape`. `M:` is for adding methods to a generic; `INSTANCE:` is for joining a class to a mixin. +## `TYPED::` — checked inputs for a plain word + +`GENERIC:`/`M:` choose a method by the class of an argument. +Sometimes you don't want dispatch — just *one* word that insists +its inputs are of a given class. `TYPED::` (in the `typed` +vocabulary) is `::` with a class written after each input name: + +```factor +TYPED:: triple ( n: integer -- m ) + n 3 * ; + +14 triple . ! => 42 +``` + +`n: integer` reads like the locals you already use, with the +class spelled after the colon. There's no dispatch — one +definition, one behaviour — but each argument is now checked +against its class: a mismatch like `"x" triple` is rejected +(*expected input value of type integer but got string*) rather +than silently flowing through. + ## Math functions and constants This exercise also leans on a few words from `math.constants` @@ -73,7 +103,6 @@ and `math.functions` that you'll meet for the first time here: arbitrary base, use `^`.) ```factor -USING: math.constants math.functions ; pi 2 / sin ! → 1.0 0 cos ! → 1.0 1 e^ ! → 2.718281828459045 diff --git a/exercises/concept/high-school-sweetheart/.docs/introduction.md b/exercises/concept/high-school-sweetheart/.docs/introduction.md index d0f56b8..e784371 100644 --- a/exercises/concept/high-school-sweetheart/.docs/introduction.md +++ b/exercises/concept/high-school-sweetheart/.docs/introduction.md @@ -81,6 +81,8 @@ The exercise needs five small string words from the - `1string ( char -- str )` — wrap a single character as a string. - `>upper ( str -- upper )` — uppercase a string. - `append ( s1 s2 -- s )` — concatenate two strings. +- `prepend ( s1 s2 -- s )` — concatenate `s2` then `s1` (`append` with + its inputs in the other order). - `glue ( s1 s2 sep -- s )` — concatenate two strings with a separator between them. - `surround ( seq pre post -- new )` — wrap a string with a prefix and diff --git a/exercises/concept/joiners-journey/.docs/introduction.md b/exercises/concept/joiners-journey/.docs/introduction.md index 4127ddf..7f7239f 100644 --- a/exercises/concept/joiners-journey/.docs/introduction.md +++ b/exercises/concept/joiners-journey/.docs/introduction.md @@ -30,6 +30,8 @@ tuck ( x y -- y x y ) 3dup ( x y z -- x y z x y z ) 4dup ( w x y z -- w x y z w x y z ) 2drop ( x y -- ) +3drop ( x y z -- ) +4drop ( w x y z -- ) 2nip ( x y z -- z ) 2swap ( x y z w -- z w x y ) ``` diff --git a/exercises/concept/pirates-path/.docs/introduction.md b/exercises/concept/pirates-path/.docs/introduction.md index c38bb0b..a19adda 100644 --- a/exercises/concept/pirates-path/.docs/introduction.md +++ b/exercises/concept/pirates-path/.docs/introduction.md @@ -14,6 +14,7 @@ push-back ( elt deque -- ) pop-front ( deque -- elt ) pop-back ( deque -- elt ) deque-empty? ( deque -- ? ) +dlist-length ( dlist -- n ) clear-deque ( deque -- ) ```