word
[1/17] from: fantam:mailandnews at: 13-Aug-2000 17:39
I am confused. Consider this small script:
REBOL []
block: ["a" "b" "c"]
code: [print member]
foreach member block [do code]
Upon execution, I get :
** Script Error: member has no value.
** Where: print member
>>
I guess I have to use 'bind or 'use somewhere, but I'm not sure which
and how.
Thanks for your help
--
Fantam
[2/17] from: tim:johnsons-web at: 13-Aug-2000 8:36
Hi Fantam:
> I am confused. Consider this small script:
>
>REBOL []
>
>block: ["a" "b" "c"]
>code: [print member]
>foreach member block [do code]
but this works:
block: ["a" "b" "c"]
mcode: func [member][print member]
m: "x"
foreach member block [m: member mcode m]
I believe that rebol enforces 'member as having a special
scope.
Your question is worthy of more discussion: perhaps some
of the more experienced members would like to chime in on
this...
-Tim
[3/17] from: ptretter:charter at: 13-Aug-2000 11:51
How about:
block: ["a" "b" "c"]
foreach member block [print member]
[4/17] from: fantam:mailandnews at: 13-Aug-2000 19:00
Thanks for your reply, Tim.
Your solution seems to me classical, C-like. I was trying to
think in Rebol terms (contexts) and, like you suggested, let's hope
advanced users will propose more Rebol-like approaches for this very
simple and common case.
Anyway, I hope I make some sense.
daniel
tjwc> Hi Fantam:
>> I am confused. Consider this small script:
>>
<<quoted lines omitted: 3>>
>>code: [print member]
>>foreach member block [do code]
tjwc> but this works:
tjwc> block: ["a" "b" "c"]
tjwc> mcode: func [member][print member]
tjwc> m: "x"
tjwc> foreach member block [m: member mcode m]
tjwc> I believe that rebol enforces 'member as having a special
tjwc> scope.
tjwc> Your question is worthy of more discussion: perhaps some
tjwc> of the more experienced members would like to chime in on
tjwc> this...
tjwc> -Tim
>>Upon execution, I get :
>>
<<quoted lines omitted: 8>>
>>--
>>Fantam
--
Fantam
[5/17] from: fantam:mailandnews at: 13-Aug-2000 19:12
Hello ptretter,
Obviously, but I intended to show a simplified script where you
prepare a chunk of code (containing words that are not set) meant to be
used later on.
Sorry I haven't specified it along with my first post.
daniel
pcn> block: ["a" "b" "c"]
pcn> foreach member block [print member]
pcn> -----Original Message-----
pcn> From: [Fantam--mailandnews--com] [mailto:[Fantam--mailandnews--com]]
pcn> Sent: Sunday, August 13, 2000 10:39 AM
pcn> To: [list--rebol--com]
pcn> Subject: [REBOL] word
pcn> I am confused. Consider this small script:
pcn> REBOL []
pcn> block: ["a" "b" "c"]
pcn> code: [print member]
pcn> foreach member block [do code]
pcn> Upon execution, I get :
pcn> ** Script Error: member has no value.
pcn> ** Where: print member
>>>
pcn> I guess I have to use 'bind or 'use somewhere, but I'm not sure which
pcn> and how.
pcn> Thanks for your help
--
Fantam
[6/17] from: larry:ecotope at: 13-Aug-2000 11:10
HI Fantam
The problem is that the word 'member inside the block referenced by 'code is
bound to the global context when the script is loaded, and it remains so
when the "do code" is executed inside the foreach loop. However,
foreach member block [...]
creates a local variable, also called 'member which will be set (bound)
successively to the items contained in 'block. The name of the iterator
variable is irrelevant to the problem. You will get the same problem if you
say
foreach x block [...]
because the local variable 'member is never used in the foreach body block.
You can use the function 'bind to bind the words in the external (to the
function foreach) 'code block to the local context of the foreach function
by binding the block to the local variable 'member.
>> block: ["a" "b" "c"]
== ["a" "b" "c"]
>> code: [print member] ;context for member made here, value given later
== [print member]
>> member: 5
== 5
>> foreach member block [do code]
5
5 ;member in code bound to global context
5
>> foreach member block [do bind code 'member]
a
b ;member in code bound to local var member
c
The latter gives the same result as moving the 'code definition inside the
foreach loop.
>> foreach member block [code: [print member] do code]
a
b
c
Some caution is necessary when using advanced functions like bind. For
instance, in a more general case than yours, there might be some words in
the external block that need to retain the values of their global binding
despite the fact that those words are also used locally in the calling
function and others that need to be rebound to the calling function's local
context. In such a case, using bind as above will not give the desired
effect.
The thing to remember is that words have values only within a context, and
the same word may have different values in different contexts.
HTH
-Larry
[7/17] from: rryost:home at: 13-Aug-2000 16:29
Here's a late response, but possibly it will show more clearly what the
problem is.
here's a console session
REBOL/View 0.9.9.3.1 1-Jun-2000
Copyright 2000 REBOL Technologies. All rights reserved.
Type DEMO to run demo if it is disabled
>> block: ["a" "b" "c"]
== ["a" "b" "c"]
>> code: [print memb]
== [print memb]
>> foreach member block [
[ memb: member
[ do code ]
a
b
c
>>
memb is a "global" word. In each loop, it's value is set equal to the value
of the foreach-internal word, member.
Russell [rryost--home--com]
[8/17] from: al:bri:xtra at: 14-Aug-2000 15:49
Fantam wrote:
> I am confused. Consider this small script:
> REBOL []
<<quoted lines omitted: 6>>
> >>
> I guess I have to use 'bind or 'use somewhere, but I'm not sure which and
how.
What's wrong with this method?
REBOL/View 0.9.9.3.1 1-Jun-2000
Copyright 2000 REBOL Technologies. All rights reserved.
Type DEMO to run demo if it is disabled
>> block: ["a" "b" "c"]
== ["a" "b" "c"]
>> code: [print member]
== [print member]
>> foreach member block code
a
b
c
>>
It seems to do directly what you intend and is simpler too.
Andrew Martin
ICQ: 26227169
http://members.xoom.com/AndrewMartin/
[9/17] from: fantam:mailandnews at: 14-Aug-2000 13:22
What a wonderful explanation. Thank you for the insight, Larry.
> HI Fantam
> The problem is that the word 'member inside the block referenced by 'code is
<<quoted lines omitted: 68>>
>>
>>
--
Fantam
[10/17] from: fantam:mailandnews at: 14-Aug-2000 13:31
Yes, you are right, nothing is wrong with this method, on the
contrary, it may be the most elegant solution. I just wanted to
understand how it had to be done with 'bind (see Larry's message), how
you can take an existing word and change its context.
> Fantam wrote:
>> I am confused. Consider this small script:
<<quoted lines omitted: 30>>
> ICQ: 26227169
> http://members.xoom.com/AndrewMartin/
->><-
--
Fantam
[11/17] from: al::bri::xtra::co::nz at: 14-Aug-2000 23:47
Fantam wrote:
> Yes, you are right, nothing is wrong with this method, on the contrary, it
may be the most elegant solution. I just wanted to understand how it had to
be done with 'bind (see Larry's message), how you can take an existing word
and change its context.
For more on this, see Web_Dialect list:
Home page for Web Dialect:
http://www.openip.org/
Community email addresses:
Post message: [Web_Dialect--egroups--com]
Subscribe: [Web_Dialect-subscribe--egroups--com]
Unsubscribe: [Web_Dialect-unsubscribe--egroups--com]
List owner: [Web_Dialect-owner--egroups--com]
Web access to Web_Dialect home page:
http://www.egroups.com/group/Web_Dialect
Where you'll find some interesting code on dialects and using 'bind.
Andrew Martin
ICQ: 26227169
http://members.xoom.com/AndrewMartin/
[12/17] from: tim:johnsons-web at: 14-Aug-2000 8:53
I have a question about the code that Russell
wrote to illustrate:
Let's contrast the two "files" below:
REBOL[]
memb: none ; "declared" at beginning of file, global
block: ["a" "b" "c"]
code: [print memb]
foreach member block
[
memb: member
do code
]
; EOF
; Now without the initial declaration
REBOL[]
; no global
block: ["a" "b" "c"]
code: [print memb]
foreach member block
[
memb: member
do code
]
; Is there a difference in machine overhead here? Is 'memb being "redeclared"
; in each loop or is it sort of cached. This may seem to be a subtle
distinction
'; in these days of "just do it", but in the case of several million loops,
it could
; make a difference.
Just wondering :)
Tim
memb is a "global" word. In each loop, it's value is set equal to the value
[13/17] from: larry:ecotope at: 14-Aug-2000 12:46
Hi Fantam
You wrote:
> What a wonderful explanation. Thank you for the insight, Larry.
>
You are welcome! I realized after my post that there is another important
point about 'bind and contexts which I failed to mention.
I showed you how to bind the words in the code block to the local variable
'member
>> block: ["a" "b" "c"]
>> code: [print member]
>> foreach member block [do bind code 'member]
a
b ;member in code bound to local var member
c
What I failed to mention is that the use of bind is permanent (until some
other 'bind occurs) so that the after the foreach loop the global block
referenced by 'code remains bound to the local context of foreach.
>> get second code
== "c"
This is a side effect of using 'bind as above, and may not be the desired
effect. It can also lead to a crash when accessing the value of the code
block if there has been a 'recycle or garbage collection which destroys the
local context of the 'foreach function. The easy way to leave the original
code block unchanged is to copy before the bind.
>> code: [print member]
>> get second code
** Script Error: member has no value.
** Where: get second code
So 'member is bound to the global context but has no value.
>> foreach member block [do bind copy code 'member]
a
b ;member in COPY of code bound to local var 'member
c
>> get second code
** Script Error: member has no value.
** Where: get second code
The global code block remains unchanged.
In general, it is probably better, when possible, to define code blocks in
the context in which they will be used, as there are further complications
with nested sub-blocks as well as in figuring out how to do the necessary
binding when the functions, function calls, and code blocks are complex. In
addition, when modules are added to REBOL some of our current code relying
on bind may be broken.
Cheers
-Larry
[14/17] from: rebol:techscribe at: 14-Aug-2000 15:30
Hi Tim,
1. memb is a global word in either case.
2.
>> memb: 12345
== 12345
>> zzz: 87907
== 87907
>> memb: 343434
== 343434
>> index? find first system/words 'memb
== 1402
>> index? find first system/words 'zzz
== 1403
Aha.
It stands to reason that:
a) when REBOL parses the word memb it checks in its global wordlist for
memb. If memb is found there it must be associated with the value it is
being assigned. If memb is not found in the global wordlist, then
b) an entry must be created for memb, and then a) must be performed for
this new entry.
In this scenario REBOL must do the same things it does for a previously
defined word memb, plus more, when it creates a new word memb.
Therefore associating an existing word with a new value is cheaper than
creating a new word.
This is true independend of whether you create the word outside the loop as
a separate step. If you did not previously create the word, and you create
the word in the loop, then the first time REBOL encounters the word in the
loop, it will be created (costly), and when it is encountered in the loop
again, it will be re-used (cheaper).
All that is pure speculation and may be completely incorrect :-).
;- Elan [ : - ) ]
author of REBOL: THE OFFICIAL GUIDE
REBOL Press: The Official Source for REBOL Books
http://www.REBOLpress.com
visit me at http://www.TechScribe.com
[15/17] from: tim:johnsons-web at: 14-Aug-2000 14:56
Hi Elan:
At 03:30 PM 8/14/00 -0700, you wrote:
>Hi Tim,
>1. memb is a global word in either case.
<<quoted lines omitted: 26>>
>again, it will be re-used (cheaper).
>All that is pure speculation and may be completely incorrect :-).
I'll take it on your authority that you are probably right. But, I just
might make it a habit of creating words outside of loops.
Always good to read your explanations of what is going on
under the hood
(my mother never could make me stop taking
things apart!)
Thanks :)
Tim
[16/17] from: fantam:mailandnews at: 16-Aug-2000 18:26
Marvelous. I'll try to remember all this.
Thanks again.
> Hi Fantam
> You wrote:
<<quoted lines omitted: 41>>
> Cheers
> -Larry
--
Fantam
[17/17] from: lmecir:geocities at: 20-Aug-2000 22:13
Hi,
how about:
block: ["a" "b" "c"]
code: [print member]
foreach member block [do bind code 'member]
The results:
a
b
c
Regards
Ladislav
Notes
- Quoted lines have been omitted from some messages.
View the message alone to see the lines that have been omitted