Cascade in Rebola

In the logo language cascade, this is a procedure to compose a function with you several times (it is almost similar to folda functional language).
Example:

   add 4 add 4 add 4 5  -->  cascade 3 [add 4 ?1] 5 ==  17
   2^8 -->  cascade 8 [?1 * 2] 1
   fibonacci 5 --> (cascade 5 [?1 + ?2] 1 [?1] 0)
   factorial 5 --> (cascade 5 [?1 * ?2] 1 [?2 + 1] 1)

The general designation for a cascade with several inputs, in the logo:
(cascade, how many functions1 start1 function2 start2 ...) with:

function1 -> ?1 ,  
function2 -> ?2 ... 

Does cascade return final value? 1.

In Rebol:

cascade1: func [howmany function1 start1] [....]      
cascade2: func [howmany function1 start1 function2 start2] [....]

How to write cascade1 and cascade2 in Rebol?

+2
source share
3 answers

With bind , which associates the words with the specified context (in this case, the local context of the function) and compose , I get:

cascade: func [  
    times
    template
    start 
] [
    use [?1] [
        ?1: start  
        template: compose [?1: (template)]  
        loop times bind template '?1  
        ?1
    ]  
]

cascade 8 [?1 * 2] 1
== 256
cascade 3 [add 4 ?1] 5
== 17  
val: 4
cascade 3 [add val ?1] 5
== 17



cascade2: func [
    times
    template1 start1
    template2 start2
    /local **temp**
] [
    use [?1 ?2] [ ; to bind only ?1 and ?2 and to avoid variable capture
        ?1: start1
        ?2: start2
        loop 
            times 
            bind 
                compose [**temp**: (template1) ?2: (template2) ?1: **temp**] 
                '?1
        ?1
    ]
]


 cascade2 5 [?1 * ?2] 1 [?2 + 1] 1
 == 120
 cascade2 5 [?1 + ?2] 1 [?1] 0
 == 8
+2
source

REBOL 3, 2 . ( REBOL 2, REBOL 2 .) cascade (.. "", ) REBOL: DSL.

cascade: funct [
  count [integer!]
  template [block!]
  /only "Don't reduce TEMPLATE"
  /local arg fun-block
][
  param-list: copy []
  param-number: 1
  arg-list: copy []
  fun-list: copy []
  template-rules: [
    some [
      copy fun-block block! (
        append param-list to word! rejoin ["?" ++ param-number]
        append fun-list fun-block
      )
      copy arg any-type! (
        append arg-list :arg
      )
    ]
    end
  ]
  unless only [template: reduce template]
  unless parse template template-rules [
    do make error! rejoin ["The template " mold/flat template " contained invalid syntax."]
  ]
  while [! tail? fun-list] [
    fun-list: change fun-list func param-list first fun-list
  ]
  fun-list: head fun-list
  loop count [
    temp-args: copy []
    for f 1 length? fun-list 1 [
      append/only temp-args apply pick fun-list f arg-list
    ]
    arg-list: copy temp-args
  ]
  first arg-list
]

:

print cascade 23 [[?1 + ?2] 1 [?1] 0]

46368 cascade, cascade, . DSL . , . , /only. , ,

cascade 5 [[?1] [1 2 3]]

, "", - , - "" .., .

, ( ) cascade. , REBOL. .

+2

Here are a few workers cascadeat Rebol. It will not work with a data type op!- that is. +, *- but he will be working with addand multiply. You can look at higher order script functions to see other examples. I have not had time to write cascade2yet

cascade: func [
    times [integer!]
    f [any-function!]
    partial-args [series!]
    last-arg
][
    expression: copy reduce [last-arg]
    repeat n times [
        insert head expression partial-args
        insert head expression get 'f
    ]
    expression
]

With examples:

probe cascade 3 :add [4] 5
print cascade 3 :add [4] 5

will result in:

[make action! [[
        "Returns the addition of two values."
        value1 [scalar! date!]
        value2
    ]] 4 make action! [[
        "Returns the addition of two values."
        value1 [scalar! date!]
        value2
    ]] 4 make action! [[
        "Returns the addition of two values."
        value1 [scalar! date!]
        value2
    ]] 4 5]

17

and

probe cascade 8 :multiply [2] 1
print cascade 8 :multiply [2] 1

will result in:

[make action! [[
        "Returns the first value multiplied by the second."
        value1 [scalar!]
        value2 [scalar!]
    ]] 2 make action! [[
        "Returns the first value multiplied by the second."
        value1 [scalar!]
        value2 [scalar!]
    ]] 2 make action! [[
        "Returns the first value multiplied by the second."
        value1 [scalar!]
        value2 [scalar!]
    ]] 2 make action! [[
        "Returns the first value multiplied by the second."
        value1 [scalar!]
        value2 [scalar!]
    ]] 2 make action! [[
        "Returns the first value multiplied by the second."
        value1 [scalar!]
        value2 [scalar!]
    ]] 2 make action! [[
        "Returns the first value multiplied by the second."
        value1 [scalar!]
        value2 [scalar!]
    ]] 2 make action! [[
        "Returns the first value multiplied by the second."
        value1 [scalar!]
        value2 [scalar!]
    ]] 2 make action! [[
        "Returns the first value multiplied by the second."
        value1 [scalar!]
        value2 [scalar!]
    ]] 2 1]

256
+1
source

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


All Articles