[REBOL] Re: Limitation coming from the "initialize" refinement usedwith the "Arr
From: joel:neely:fedex at: 27-Jun-2002 17:15
Hi, Gerard,
Gerard Cote wrote:
> The original try was :
>
> set [ 'n1 'n2 'total 'diff ] [ 15 25 n1 + n2 n2 - n1]
>
>> set [n1 n2] [15 25]
== [15 25]
>> set [tot dif] reduce [n2 + n1 n2 - n1]
== [40 10]
gets your expected result:
>> print [n1 n2 tot dif]
15 25 40 10
- If the first argument to SET is a block, the words are already
"protected" from evaluation, and therefore don't need to be
lit-words.
- If both arguments to SET are blocks, the second block contains
the corresponding values for the words; therefore REDUCE is
needed in the second SET to cause the evaluation of the
expressions, to produce a two-element block. Unreduced, that
block contains six words! Being able to play around with
unevaluated blocks is one of the more powerful features of
REBOL:
>> w0: [a b]
== [a b]
>> print mold w0
[a b]
>> print w0
** Script Error: a has no value
** Near: a b
>> v0: [15 25]
== [15 25]
>> length? v0
== 2
>> v1: [b + a b - a]
== [b + a b - a]
>> length? v1
== 6
>> w1: [t d]
== [t d]
>> set w0 v0 set w1 v1 print [a b t d]
15 25 b +
>> set w0 v0 set w1 reduce v1 print [a b t d]
15 25 40 10
- Before we can REDUCE (evaluate the expressions in) the block V1
all of the words in that block must be defined/set. That's why
two SETs are needed for the example at hand.
> And the related question : Is there is a way for REBOL to assign
> many variables simultaneously (that is in a pseudo-parallel form
> on the same line instead of serializing them by putting them on
> many successive lines) like I was able to do in the Lisp language
> with the LET (for parallel assignment) and LET* (for serial
> assignment) statements.
>
Sure. If you give SET two arguments, the first a block of words
and the second a block of values (both blocks of the same length),
all of the words will be set to the corresponding values.
In the context of your question, SET is parallel and *not* serial,
otherwise e.g., the following trick to swap two values would not
work properly.
>> x: 13
== 13
>> y: 42
== 42
>> set [x y] reduce [y x]
== [42 13]
>> print [x y]
42 13
The gotcha is that your original attempt would have to have been
written as
set [n1 n2 total diff] reduce [15 25 n1 + n2 n2 - n1]
to get the effect you wanted, where the
reduce [15 25 n1 + n2 n2 - n1]
part is a subexpression that must be evaluated *before* the SET is
done, because the *result* of REDUCE *is* the second argument to
SET. That evaluation would use the values of N1 and N2 as of the
time of the REDUCE (prior to evaluation of SET on two block args).
As written (nearly), your example can be evaluated, but it doesn't
do what you expected:
>> unset [n1 n2 total diff]
>> set [n1 n2 total diff] [15 25 n1 + n2 n2 - n1]
== [15 25 n1 + n2 n2 - n1]
>> print [n1 n2 total diff]
15 25 n1 +
The second argument to SET contained eight elements: two integers
and six words; N1 and N2 were set to the two integers, while TOTAL
and DIFF were set to the first two of the words.
Hope this helps!
-jn-
--
; Joel Neely joeldotneelyatfedexdotcom
REBOL [] do [ do func [s] [ foreach [a b] s [prin b] ] sort/skip
do function [s] [t] [ t: "" foreach [a b] s [repend t [b a]] t ] {
| e s m!zauafBpcvekexEohthjJakwLrngohOqrlryRnsctdtiub} 2 ]