Mailing List Archive: 49091 messages
  • Home
  • Script library
  • AltME Archive
  • Mailing list
  • Articles Index
  • Site search
 

[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 ]