Rebol: Dynamic Linking Block Words

In Rebol there are words such as foreach, which allow you to "parameterize the block" according to a given word and row, for example foreach w [1 2 3] [print w]. Since I think the syntax is very convenient (as opposed to passing func blocks), I would like to use it for my own words that work with lazy lists, for example map/stream x s [... x ... ]. What is the name of this syntactic idiom? How is this implemented correctly?

I was looking for documents, but I could not find a direct answer, so I tried to implement foreach myself. Basically, my implementation takes place in two parts. The first part is a function that associates a specific word in a block with a given value and gives a new block with related words.

bind-var: funct [block word value] [
  qw: load rejoin ["'" word]
  do compose [
      set (:qw) value
      bind [(block)] (:qw)
      [(block)] ; This shouldn't work? see Question 2
  ]
]

Using this, I implemented foreach as follows:

my-foreach: func ['word s block] [
    if empty? block [return none]
    until [
        do bind-var block word first s
        s: next s 
        tail? s
    ]
]

(, , ), , . , , , :

  • bind-var bind [(block)] (:qw), (block) "". ?

  • (?) 2 ( [(block)]), , my-foreach, , . [(block)], - . ?

+4
1

.:-) Rebol2 R3-Alpha ( , Red) . Rebol3 .

(, Ren-C . , . .)

bind-var bind [(block)] (:qw), (block) "". ?

, COMPOSE ... . , COMPOSE/ONLY, , .

qw: load rejoin ["'" word]

WORD! -! to lit-word! word. , . set quote (word) value qw.

LOAD , - . TO WORD! LIT-WORD!.

do compose [
    set (:qw) value
    bind [(block)] (:qw)
    [(block)] ; This shouldn't work? see Question 2
 ]

, COMPOSE/DEEP , ... COMPOSE PAREN! s cough, GROUP! s [(block)] .

[(block)], - . ?

my-foreach x [1] [print x probe bind? 'x], bind? , "" .

, MAKE! USE, . , , , x .

, . :

bind-var: func [block word value /local qw] [
    qw: load rejoin ["'" word]
    do compose/deep [
        use [(qw)] [
            set (:qw) value
            bind [(block)] (:qw)
            [(block)] ; This shouldn't work? see Question 2
        ]
    ]
]

, , - , . , , BIND , . , , . , :

do compose/deep [
    use [(qw)] [
        set (:qw) value
        [(block)]
    ]
]

( [(block)]), , my-foreach,

, , , . MAKE! :

bind-var: func [block word value /local obj qw] [
    do compose/deep [
        obj: make object! [(to-set-word word) none]
        qw: bind (to-lit-word word) obj
        set :qw value
        bind [(block)] :qw
        [(block)] ; This shouldn't work? see Question 2
    ]
]

, my-foreach x [1 2 3] [print x], , ... "x " (, - x, , 3 ).

, , :-), , my-foreach x [1 2 3] [loop 1 [print x]] . , , , , , COMPOSE BLOCK!. , " " , , :

>> original: [outer [inner]]
== [outer [inner]]

>> composed: compose [<a> (original) <b>]
== [<a> outer [inner] <b>]

>> append original/2 "mutation"
== [inner "mutation"]

>> composed
== [<a> outer [inner "mutation"] <b>]

, BIND , .

until [
    do bind-var block word first s
    s: next s 
    tail? s
]

COMPOSE BIND . , ( Ren-C, ), , , .

+4

Source: https://habr.com/ru/post/1689093/


All Articles