Last active
June 21, 2026 03:20
-
-
Save hinjolicious/c20080d29db1872d744814cc50141689 to your computer and use it in GitHub Desktop.
Pipelining - Mapping Library for Red
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Red [ | |
| title: "Piping (Pipelining) and Mapping for Red" | |
| author: "hinjolicious" | |
| resource: "Gemini AI" | |
| ] | |
| #include %dev.red | |
| ; == PIPE / PIPELINING | |
| ; Piping / pipelining is applying an action (operation) to a variable: [3 2 6 3 8 1 0 9] |> sort, | |
| ; or chained several times as required: 'a |> to-string |> uppercase | |
| ; Mapping is applying an action to a list of items: [a b c] ||> to-string ||> uppercase | |
| PIPE: function [x 'f][ | |
| ; x [any-type!] "A value or values (literal, variable, block, etc.)" | |
| ; f [any-type!] "An operation (function, 'code-block', variable, literal, etc.)" | |
| ; list of operators recognized for the "simple code-block" construct: [* 2] | |
| ops: [ | |
| + - * / ** // % << >> >>> ; arith, math | |
| = == < > <= >= <> =? and or xor not ; comparison, logic | |
| in ; series, context | |
| ] | |
| case [ | |
| word? f [ ; a word could be func or var | |
| ff: get f ; get what it refer to | |
| either any-function? :ff [ | |
| ff x ; a func, call it with prev value: x |> sin | |
| ][ | |
| ff ; ; a var, just eval it (will replace prev val): x |> "hello" | |
| ] | |
| ] | |
| block? f [ ; a block | |
| either empty? f [ | |
| [] ; empty block, just return it: x |> [] | |
| ][ | |
| a: f/1 ; first elem should be arg, or op | |
| case [ | |
| word? a [ ; arg is word | |
| either find ops a [ ; any signature op? | |
| do compose [(x) (f)] ; a "simple code-block": x |> [* 2] | |
| ][ ; a word, but not op? try using 'it' template | |
| ff: function [it] f | |
| ff x ; e.g.: x |> [sin it * 2] | |
| ] | |
| ] | |
| block? a [ ; arg is a block: "complex code-block" construct | |
| la: length? a ; how many args? | |
| ff: function a next f | |
| switch/default la [ | |
| 0 [ff] ; eval without arg: x |> [[] pi] | |
| 1 [ff x] ; single arg: x |> [[x] sin x] | |
| ][apply :ff x] ; multiple args: x |> [[x y] x + y] | |
| ] | |
| true [ ; first elem is something else | |
| ff: function [it] f ; try using 'it' template: [2 * pi] | |
| ff x | |
| ] | |
| ] | |
| ] | |
| ] | |
| true [f] ; literal: x |> "hello" | |
| ] | |
| ] ; /pipe | |
| |>: make op! :PIPE ; pipe operator: x |> sin |> [* pi] or [10 20] |> [[a b] a * b] | |
| !: :|> ; alias pipe operator, if you prefer it | |
| ; == MAP == | |
| ; Mapping is just a simple extension for pipe! | |
| MAP: function [x 'f][collect [foreach e x [keep/only e |> :f]]] | |
| ||>: make op! :MAP ; mapping operator | |
| ;== TEST == | |
| ; == Some test cases from @hiiamboris | |
| ;>> map-each x [a b c] [uppercase form x] | |
| ;== ["A" "B" "C"] | |
| >> [a b c] ||> form ||> uppercase | |
| == ["A" "B" "C"] | |
| ;>> map-each x [1 + 2 * 3] [type? x] | |
| ;== [integer! word! integer! word! integer!] | |
| >> [1 + 2 * 3] ||> type? | |
| == [integer! word! integer! word! integer!] | |
| ; == more test | |
| double: func [x][x * 2] | |
| b: 2 | |
| >> [1 b pi] ||> [* 2] | |
| >> 10 |> negate ; -10 | |
| >> 10 |> [[x] x * 2] ; 20 | |
| >> 10 |> [* 3] ; 30 | |
| >> 10 |> [[v] either v > 5 ["Big"]["Small"]] ; "Big" | |
| >> [10 20] |> [[a b] a + b] | |
| ; == matrix manipulation example | |
| >> [1 2 3 4] ||> [[x] x ** 2] | |
| == [1 4 9 16] | |
| >> [[1 2][3 4][5 6]] ||> [[a b] a + b] | |
| == [3 7 11] | |
| #include %reduce-deep.red | |
| ; re-arrange elements in each row | |
| >> [ [1 2 3 4] [5 6 7 8] ] ||> [[a b c d] reduce-deep [a c b d]] | |
| == [[1 3 2 4] [5 7 6 8]] | |
| ; re-arrange elements and put it into deeper sub-block | |
| >> [ [1 2 3 4] [5 6 7 8] ] ||> [[a b c d] reduce-deep [[a c][b d]]] | |
| == [[[1 3] [2 4]] [[5 7] [6 8]]] | |
| ; simple matrix transpose | |
| >> [ [1 2 3] [4 5 6] ] |> [[a b] reduce-deep [[a/1 b/1][a/2 b/2][a/3 b/3]]] | |
| == [[1 4] [2 5] [3 6]] | |
| mat: [ [1 2 3 4] | |
| [5 6 7 8] | |
| [9 10 11 12] ] | |
| >> mat |> [[a b c] | |
| collect [repeat i length? a [ | |
| keep/only reduce [a/:i b/:i c/:i] | |
| ]] | |
| ] | |
| == [[1 5 9] [2 6 10] [3 7 11] [4 8 12]] | |
| >> mat |> [[m] | |
| collect [repeat i length? m/1 [ | |
| keep/only collect [repeat j length? m [ | |
| keep reduce [m/:j/:i] | |
| ]] | |
| ]] | |
| ] | |
| == [[1 5 9] [2 6 10] [3 7 11] [4 8 12]] |
Author
Author
Warning, the ">>" function does break bit shifts. If your code use bit shifts, then this ">>" should not be used in that particular source files.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Some other code in used above: