-
-
Save hiiamboris/c82b5ee7250bab09fcee0289321a199e to your computer and use it in GitHub Desktop.
Red [title: "An experiment with INTO separation"] | |
; do %/d/devel/red/common/with.red | |
buffers*: [] | |
into: func [buffer [series!]] [append/only buffers* buffer exit] | |
collect': function [code [block!]] [ | |
also buffer: any [ | |
take/last buffers* | |
make [] 10 | |
] | |
do code | |
] | |
keep: function [value [any-type!] /only] bind [ | |
either only [append/only buffer :value][append buffer :value] | |
:value | |
] :collect' | |
; keep: function [value [any-type!] /only] with :collect' [ | |
; either only [append/only buffer :value][append buffer :value] | |
; :value | |
; ] | |
compose': function [block [block!]] [ | |
head compose/into block tail any [ | |
take/last buffers* | |
clear copy block | |
] | |
] | |
test: func [code] [prin [mold/only code "^-=> "] probe do code] | |
test [collect' [keep [1 2 3] keep keep 4]] | |
test [into [a b c] collect' [keep [1 2 3] keep keep 4]] | |
test [into [a b c] compose' [(1 + 3) (2 * 4)]] | |
test [into [a b c] collect' [keep [1 2 3] keep compose' [(1 + 3) (2 * 4)]]] | |
test [into [-] collect' [ | |
into [a b c] | |
into [d e f] keep compose' [(1 + 3) (2 * 4)] | |
keep compose' [(3 * 3) (2 ** 4)] | |
keep compose' [(10 * 10)] | |
]] | |
So the accumulating buffer becomes fixed and global? That's really not desirable.
So the accumulating buffer becomes fixed and global? That's really not desirable.
Agreed. It's also exploitable, as user code might affect the code that called it. This example is to provoke thoughts in others :)
What I would like to have ideally is into buffer
affecting only the next expression after it, but that's not possible without some kind of thunks, is it? into buffer expression
evaluates expression
before it enters into
and can assign the buffer to anywhere.
into buffer [expression in a block]
is less readable, and has bigger problems if block contains more than one expression:
- if only first expression uses the buffer, it just looks misleading
- if all expressions use the buffer, user will have to explicitly reset it (e.g. with
into []
) when he doesn't want other expressions to use it (it becomes very messy)
I could solve it with a macro: under the hood put everything after into buffer
into a separate block argument, but only let the first expression use the buffer. Will be readable, but will trap exit/return and will mess up error reports a lot.
So I don't see a perfect solution yet.
Output: