Is it possible to implement the DO + function in pure REBOL?

When a DOfunction follows, this function is executed, and the remaining values ​​are consumed as arguments in accordance with the arity of this function, for example,

do :multiply 3 4
multiply 3 4

These two statements are identical in their effects. But I think that the DO+ function receives a special appeal with the help of the REBOL interpreter, because I do not consider it possible to implement my own DO(with the same syntax) in pure REBOL, for example,

perform: func [f [any-function!]] [
    ; What goes here?
]

Is it correct?

Explanation

DO. "". REBOL: Bindology ( , ), , . (, - cascade REBOL. , Vim REBOL.)

- . , , , . , , DO, :

do :multiply 3 4
double: func [n] [n * 2]
do :double 5

, do :double do :multiply REBOL . , . , REBOL, DO this.

, REBOL, DO - , - , .

+4
3

, , Rebol DO.

/***********************************************************************
**
*/  REBNATIVE(do)
/*
***********************************************************************/
{
    REBVAL *value = D_ARG(1);

    switch (VAL_TYPE(value)) {

       /* ... */

    case REB_NATIVE:
    case REB_ACTION:
    case REB_COMMAND:
    case REB_REBCODE:
    case REB_OP:
    case REB_CLOSURE:
    case REB_FUNCTION:
        VAL_SET_OPT(value, OPTS_REVAL); /* <-- that */
        return R_ARG1;

OPTS_REVAL sys-value.h, ... break ":

// Value option flags:
enum {
    OPTS_LINE = 0,  // Line break occurs before this value
    OPTS_LOCK,      // Lock word from modification
    OPTS_REVAL,     // Reevaluate result value
    OPTS_UNWORD,    // Not a normal word
    OPTS_TEMP,      // Temporary flag - variety of uses
    OPTS_HIDE,      // Hide the word
};

, , DO native , - "" . . , , - native DO.

, , APPLY .

+2

, Rebol 3:

>> perform: func [f [any-function!]] [return/redo :f]
>> perform :multiply 3 4
== 12

>> double: func [n] [n * 2]
>> perform :double 5
== 10

: return/redo , ?

+2

, . , .

:word get-word! get 'word. ,

do get 'multiply 3 4

multiply - word! Rebol.

do - , Rebol.

do, /​​, do. :

perform: func [ code [block!]] [ if equal? code [ 1 ] [ print "Hello" ] ]

perform , . "" , , , ( "" ), 1.

perform [ multiply 3 4 ] , code 1. -, block!, 1.

>> perform [ 1 ]    
Hello

:

perform: func [ code [block!]] [ if equal? code [ multiply 3 4 ] [ 42 ] ]

perform, -.

>> perform [ multiply 3 4 ]
== 42

do , , do, - .

This switching between dialects is a normal way of writing Rebol code, a good example of which is dialect parse

parse [ 1 2.4 3 ] [ some number! ]

which has its own syntax and even reuses existing dodialect words, such as skip, but with a different meaning.

0
source

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


All Articles