Mailing List Archive: 49091 messages

# concurrent/parallel/multiple SETting

### [1/5] from: joel::neely::fedex::com at: 5-Jan-2002 9:01

Another bit of language trivia: Many languages and notations (e.g. Perl, LISP, Scheme, Dijkstra's guarded command notation, Tony Hoare's CSP, etc.) have the notion of concurrent/parallel/multiple assignment, in which several expressions are evaluated and the results then associated with variables. This has at least two obvious benefits: 1) At the purely practical level, this notion can be used to express computation without the use of extra temporary variables. The simplest example I can think of is the exchange of two values: (a, b) := (b, a) which in general requires another variable if done serially: c:= a ; a := b ; b := c This generalizes to the "rotation" of a fixed set of values, such as: (a, b, c, d, e) := (b, c, d, e, a) which performs a circular exchange among five values, again requiring one temporary variable if done serially. Other examples at this level are easy to construct. 2) At the conceptual level, it makes it easier to think of several evaluations as being performed "simultaneously" without having to complicate one's thinking with issues of which might need to be performed before/after which other(s). With (x, i) := (a[i], i+1) it's clear what's happening, without worrying about whether x := a[i] ; i := i + 1 or i := i + 1 ; x := a[i] is more appropriate (or correct!) REBOL also supports this concept, allowing SET to be applied to blocks of words and values, but there's no free lunch. Using the above example of rotating five values, I build the following REBOL function to time repeated rotations done with serial set-words (requiring an extra word) and done with the block form of SET. setter: func [ n [integer!] m [integer!] /local a b c d e f t0 t1 t2 ][ t1: 0 a: 1 b: c: d: e: f: 0 loop m [ t0: now/time/precise loop n [ f: e e: d d: c c: b b: a a: f] t1: t1 + now/time/precise - t0 ] t2: 0 a: 1 b: c: d: e: f: 0 loop m [ t0: now/time/precise loop n [ set [a b c d e] reduce [b c d e a]] t2: t2 + now/time/precise - t0 ] print [t1 t2] ] I was *quite* surprised by the results:
>> setter 1000 1000 => 0:00:08.69 0:00:41.29 4.75143843498274 >> setter 1000 2000 => 0:00:17.5 0:01:22.91 4.73771428571429 >> setter 2000 1000 => 0:00:16.93 0:01:21.95 4.84051978735972 >> setter 2000 2000 => 0:00:33.03 0:02:46.65 5.04541326067212
(This was performed on a 'doze box, so subsecond details are dubious at best...) Notice that the block SET takes about 5 times as long as the serial version, with the cost rising slowly as the number of iterations increases. This suggests to me that the overhead is related to the memory management involved in constructing (large numbers of) temporary blocks. I be interested in whether there's any other way to get the same result without so much overhead (or whether I've overlooked anything in the above test). -jn- -- ; sub REBOL {}; sub head (\$) {@_[0]} REBOL [] # despam: func [e] [replace replace/all e ":" "." "#" "@"] ; sub despam {my (\$e) = @_; \$e =~ tr/:#/.@/; return "\n\$e"} print head reverse despam "moc:xedef#yleen:leoj" ;

### [2/5] from: arolls:idatam:au at: 7-Jan-2002 15:07

In my quick test, I tried putting a use [a b c d e] block around the second loop. But it didn't seem to make any difference. I would suggest a function that returns some composed code to do, to optimise. Also, I'd like to complain ;) about the style below, (which is not quite style-guide compliant). If I paste this code straight into the console, it fails on the first line because func is expecting a block, but a newline indicated that the expression was finished and the console should do it. (Not to single you out Joel, some others here are guilty too. ;) It is a very small thing compared to the content...) Regards, Anton.

### [3/5] from: arolls:idatam:au at: 7-Jan-2002 15:13

Whoops, I totally missed your earlier flame-bai... I mean, thread, on source style - Sorry. Anton.

### [4/5] from: joel:neely:fedex at: 7-Jan-2002 5:44

Thanks to Volker and Carl the following is now a permament part of my REBOL toolkit: vv: does [do read clipboard://] It allows style-agnostic cut-and-paste. -jn- Anton Rolls wrote:
> Also, I'd like to complain ;) about the > style below, (which is not quite style-guide
<<quoted lines omitted: 3>>
> a block, but a newline indicated that the expression > was finished and the console should do it.
-- ; sub REBOL {}; sub head (\$) {@_[0]} REBOL [] # despam: func [e] [replace replace/all e ":" "." "#" "@"] ; sub despam {my (\$e) = @_; \$e =~ tr/:#/.@/; return "\n\$e"} print head reverse despam "moc:xedef#yleen:leoj" ;

### [5/5] from: joel:neely:fedex at: 7-Jan-2002 5:46

Hi, Anton, Anton Rolls wrote:
> Whoops, I totally missed your earlier flame-bai... > I mean, thread, on source style - Sorry. >
I would NEVER write anything to provoke a reaction! ;-) -jn- -- ; sub REBOL {}; sub head (\$) {@_[0]} REBOL [] # despam: func [e] [replace replace/all e ":" "." "#" "@"] ; sub despam {my (\$e) = @_; \$e =~ tr/:#/.@/; return "\n\$e"} print head reverse despam "moc:xedef#yleen:leoj" ;

Notes
• Quoted lines have been omitted from some messages.
View the message alone to see the lines that have been omitted