Block Creation
[1/20] from: carl:cybercraft at: 18-Oct-2000 21:13
Here's a block query...
>> block1: []
== []
>> block2: to-block ""
== []
The above would appear to have created identical blocks, but as the
following little script shows they're not the same...
rebol []
for test1 1 5 1 [
block1: []
insert block1 "text1"
]
prin "block1: " print block1
for test2 1 5 1 [
block2: to-block ""
insert block2 "text2"
]
prin "block2: " print block2
The output from this is...
block1: text1 text1 text1 text1 text1
block2: text2
I'm assuming this is normal REBOL behaviour and not a bug, (and I
know...
block1: [] clear block1
would've given the same results as with to-block), but what's the
point of the difference?
Carl Read.
[2/20] from: joel:neely:fedex at: 18-Oct-2000 7:41
Hi, Carl,
[carl--cybercraft--co--nz] wrote:
> Here's a block query...
>
> >> block1: [] == []
>
> >> block2: to-block "" == []
>
> The above would appear to have created identical blocks, but ...
> ... they're not the same...
>
They're EQUAL? but not SAME? (they are two distinct containers with
the same content...)
> block1: text1 text1 text1 text1 text1
> block2: text2
<<quoted lines omitted: 3>>
> would've given the same results as with to-block), but what's the
> point of the difference?
Which difference? The difference between BLOCK1 and BLOCK2, or the
fact that there are two different ways to create an empty block?
If the former, they are different because you can create as many
distinct containers as you wish, in anticipation of later putting
different (or the same ;-) stuff into each.
If the latter, because REBOL has a rich variety of types and values,
and there are many expressions that evaluate to the same final
result. The same kind of thing can be done with other types than
BLOCK! of course...
>> block1: [] == []
>> block2: to-block "" == []
<<quoted lines omitted: 16>>
>> string2 = string3 == true
>> string1 = string3 == true
And if I've missed the point of your question entirely, I
apologize; please let me know if I'm off in left field.
-jn-
[3/20] from: jelinem1:nationwide at: 18-Oct-2000 8:05
The differences in your results is due to initializing the words
[referencing the blocks] WITHIN the loops. Try initializing 'block1 and
'block2 outside the loops and I'll bet your results will be the same.
In the case of:
>> block1: []
The word 'block1 is always set to reference the SAME block.
In the case of:
>> block2: to-block ""
A DIFFERENT block is created each time.
- Michael Jelinek
[carl--cybercraft--co--nz] on 10/18/2000 04:13:31 AM
From: [carl--cybercraft--co--nz] on 10/18/2000 04:13 AM
Please respond to [list--rebol--com]
To: [list--rebol--com]
cc:
Subject: [REBOL] Block Creation
Here's a block query...
>> block1: []
== []
>> block2: to-block ""
== []
The above would appear to have created identical blocks, but as the
following little script shows they're not the same...
rebol []
for test1 1 5 1 [
block1: []
insert block1 "text1"
]
prin "block1: " print block1
for test2 1 5 1 [
block2: to-block ""
insert block2 "text2"
]
prin "block2: " print block2
The output from this is...
block1: text1 text1 text1 text1 text1
block2: text2
I'm assuming this is normal REBOL behaviour and not a bug, (and I
know...
block1: [] clear block1
would've given the same results as with to-block), but what's the
point of the difference?
Carl Read.
[4/20] from: anton_rolls:melbourne at: 19-Oct-2000 17:31
Hi,
block1: []
Each time around, block1 is pointed at a growing block, starting out
initially as [].
The block is modified to include "text1" each time round.
Remember, the thing that is actually modified is the []!!!
To see this, try this one-liner:
do a: does [loop 3 [blk: [] insert blk 'gold source a]]
You should notice that the thing that blk is pointing to is actually
growing in the source.
block2: to-block ""
This code gets evaluated each time, which means that the thing that block2
used
to point to (["text2"]) is forgotten in favour of the newly created [].
Regards,
Anton.
[5/20] from: brett:codeconscious at: 19-Oct-2000 1:00
Hi Carl,
You've tripped over a usage which is normally comes up when people define
functions.
In the second example, each time through the loop a new block value is
created and block2 is set to this new value. So your insert modifies a
different block each time.
In the first example a block value is created once at some point when the
interpreter goes to execute your loop, then each time through the loop the
word block1 is set to this same value. Hence you are modifying the same
block (in memory).
Note: In my explanation I've made reference to memory and the interpreter. I
don't know if this is how it works for sure, but it should give you the
idea.
For more messages on the same theme see:
http://www.codeconscious.com/rebol/tips-and-techniques.html#Wordsarenotvaria
bles1
Brett.
[6/20] from: rebol:techscribe at: 18-Oct-2000 10:49
Hi Carl,
Anton and Brett already pointed out the difference. I merely want to add
that in the first case
>> block-1: []
you are assigning the word block as a reference to a LITERAL block. At
each loop iteration the word block-1 is being assigned to that same
LITERAL block.
Case 2:
>> block-2: to-block ""
Better yet:
>> block-2: to-block []
Here to-block creates a new block PROGRAMMATICALLY at each iteration
using the LITERAL block [] as a prototype. The prototype block remains
empty. The values are inserted into the empty PROGRAMMATICALLY (or
DYNAMICALLY) created block, not into its LITERAL prototype.
So,
>> repeat i 3 [block-1: [] insert block-1 i]
is the programmatic equivalent of
>> block-1: [3 2 1]
whereas
>> repeat i 3 [ block-2: to-block [] insert block-2 i]
is the programmatic equivalent of
>> block-2: [1]
>> block-2: [2]
>> block-2: [3]
A combination of the two allows you to do something like this:
repeat i 3 [
block-2: to-block block-1: []
append block-1 i
repeat j 3 [
append block-2 j
]
]
Here we modify the literal prototype block in the outer loop, and then
modify the result ing programmatically created block in the second loop.
Hope this sheds a little more light on how to utilize the difference.
Elan
[carl--cybercraft--co--nz] wrote:
[7/20] from: carl:cybercraft at: 19-Oct-2000 22:17
Thanks for all the replies on this everyone - I'm a little the wiser
now.
It was in a function I noticed the difference and I can see how it'd
be useful to be able to create a new block with the first call of a
function while having the subsequent calls not clear the block's
contents.
This is what I was actually trying to do...
block: [[[]]]
(for inserting stuff into later), and while the following works as I
wanted...
block: to-block "[[]]"
I notice that this doesn't...
block: to-block [[[]]]
Because, I assume, the inner blocks are not created anew?
Carl Read.
[8/20] from: joel:neely:fedex at: 19-Oct-2000 10:21
Hi, Carl,
Carl Read wrote:
> Thanks for all the replies on this everyone - I'm a little the wiser
> now.
>
I'm glad to see from the replies that other folks can do a better job
of reading the entire question than I did... ;-) Sorry if my first
answer was a bit too hasty!
> It was in a function I noticed the difference and I can see how it'd
> be useful to be able to create a new block with the first call of a
> function while having the subsequent calls not clear the block's
> contents.
>
At the risk of sounding picky, I think the wording of this sentence
may allow a misunderstanding of what's happening.
The "first call of a function" does *NOT* "create a new block". To
make a simple example. After evaluating...
phlarp: func [a [string!] /local b] [
b: []
append b a
]
...the literal block that is the second element of the body of PHLARP
is not a request for REBOL to create another empty block, it is *the*
empty block to which B is set.
Subsequent modifications to B are, via that reference, modifying the
literal block (second element of the body of PHLARP) to which B refers.
>> phlarp "hi"
== ["hi"]
>> source phlarp
phlarp: func [a [string!] /local b][
b: ["hi"]
append b a
]
> This is what I was actually trying to do...
> block: [[[]]]
<<quoted lines omitted: 4>>
> block: to-block [[[]]]
> Because, I assume, the inner blocks are not created anew?
Almost. In the case of
block: [[[]]]
we are asking REBOL to set BLOCK to a particular block value that
already exists, where in
block: to-block "[[]]"
or
block: to-block [[[]]]
we are asking REBOL first to create a new block and then set BLOCK
to refer to it. Therefore, in
block: [[[]]]
it is actually the case that *none* of the blocks at *any* level of
nesting are being created anew.
Having said all of that, please critique my next post for another way
to approach this point. As it is the most F of FAQ for REBOL (as far
as I have observed on this list), I've been wrestling with the issue
for how to describe what's happening for quite some time.
-jn-
--
; Joel Neely [joel--neely--fedex--com] 901-263-4460 38017/HKA/9677
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 ]
[9/20] from: joel:neely:fedex at: 19-Oct-2000 11:29
Hello, Carl and list,
Every time I try to verbalize what happens in cases such as:
rebol []
for test1 1 5 1 [
block1: []
insert block1 "text1"
]
I become very frustrated with myself. I end up with remarks that are
far more complex than my mental concept of what's happening. I take
that to mean that either I can't handle powerful languages (such as
American English or REBOL ;-) very well, OR that I'm going about the
explanation the wrong way.
Obviously, I'd prefer the second of these! Therefore, please let me
know what you think of the following stepwise description of how
REBOL handles literal series values in contexts such as the above.
I'll use blocks throughout, but any series type should follow the
same thought process. In all of these cases, the word 'a is made to
refer to a block which is subsequently modified (via 'a). The effect
of the modification can be seen via other ways to get to the block.
1) There can be more than one reference to the same series.
>> b: [] == []
>> a: b == []
>> append a "hi" == ["hi"]
>> b == ["hi"]
2) Any series can have multiple references to it, regardless of how it
is originally created.
>> b: make block! 0 == []
>> a: b == []
>> append a "hi" == ["hi"]
>> b == ["hi"]
3) This is not an issue of variables; a series contained by another
series still behaves this way.
>> b: [[]] == [[]]
>> a: b/1 == []
>> append a "hi" == ["hi"]
>> b == [["hi"]]
4) When we ask REBOL to DO a block, all expressions in the block are
evaluated, with the last of these values serving as the value of
the entire block evaluation.
>> b: [1 + 1 2 + 2 3 + 3] == [1 + 1 2 + 2 3 + 3]
>> do b == 6
5) This is also true when the expressions of the DOne block have
(or represent) series values.
>> b: [1 + 1 "Hi" []] == [1 + 1 "Hi" []]
>> do b == []
6) When the result of DOing a block is a series value, we can make
another word refer to that value, with the same behavior as in
points 1, 2, and 3 above.
>> b: [[]] == [[]]
>> a: do b == []
>> append a "hi" == ["hi"]
>> b == [["hi"]]
>> do b == ["hi"]
7) If we get tired of writing "do..." repeatedly, REBOL allows us to
create values that (in effect) DO themselves.
>> b: to-paren [[]] == ([])
>> a: b == []
>> append a "hi" == ["hi"]
>> :b == (["hi"])
>> b == ["hi"]
8) We can make such an automatically-done value in other ways.
>> b: does [[]]
>> a: b == []
>> append a "hi" == ["hi"]
>> b == ["hi"]
>> source b b: func [][["hi"]]
9) If that last line above was a surprise, just remember that DOES is
simply a shortcut for creating a function that has no arguments and
no local words.
>> source does
does: func [
{Defines a function that has no arguments or locals.} [catch]
body [block!] "The body block of the function"
][
throw-on-error [make function! [] body]
]
10) This means that we can create such a function "by hand".
>> b: func [] [[]]
>> a: b == []
>> append a "hi" == ["hi"]
>> b == ["hi"]
>> source b b: func [][["hi"]]
11) Note that the change above had nothing to do with the fact that we
used a function; it resulted from having a reference to the literal
block returned as the result of evaluating another block.
>> b: [[]] == [[]]
>> a: loop 3 b == []
>> append a "hi" == ["hi"]
>> b == [["hi"]]
12) A "chain of references" to a series may be created by passing
such references from "hand to hand". The variables (or other
forms) of these references don't matter -- only that the references
all refer to the same series.
>> b: [[]] == [[]]
>> a: first b == []
<<quoted lines omitted: 4>>
>> a == ["hi"]
>> b == [["hi"]]
13) It also doesn't matter where the modifications are done, only that
a shared series reference is being modified.
>> b: func [/local bb] [bb: [] append bb "hi"]
>> a: b == ["hi"]
>> append a " there!" == ["hi" " there!"]
>> source b
b: func [/local bb][bb: ["hi" " there!"] append bb "hi"]
14) All of this means that
b: func [/local bb] [b: [] append bb "hi"]
is actually equivalent to
b: func [][[] append first second :b "hi"]
(assuming that you know that SECOND :B is a way to get to the
block that is the body of B, of course!)
>> b: func [][[] append first second :b "hi"]
>> b == ["hi"]
<<quoted lines omitted: 4>>
>> b == ["hi" "hi"]
>> b == ["hi" "hi" "hi"]
14) Every time a series is created "from scratch" it is a different
series than any previously existing series.
>> b: make block! [[]] == [[]]
>> a: b/1 == []
<<quoted lines omitted: 3>>
>> b == [[]]
>> a == ["hi"]
15) The block that constitutes the body of a function (and all literal
values in it!) is created when FUNC is evaluated.
>> source-code: [b: func [/local bb] [bb: [] append bb "hi"]]
== [b: func [/local bb] [bb: [] append bb "hi"]]
>> do source-code
>> source b
b: func [/local bb][bb: [] append bb "hi"]
>> b
== ["hi"]
>> b
== ["hi" "hi"]
>> b
== ["hi" "hi" "hi"]
>> source b
b: func [/local bb][bb: ["hi" "hi" "hi"] append bb "hi"]
>> do source-code
>> source b
b: func [/local bb][bb: [] append bb "hi"]
>> b
== ["hi"]
When we ask REBOL to DO SOURCE-CODE again, the function is re-
created from the supplied source code, which means that the
second value of its body is (once again) an empty block.
One could go on in this vein, but that's more than enough for now.
Does this kind of progression make sense to anyone else as a way
to explain why we get the surprising-the-first-time-you-see-it behavior
of literal blocks?
-jn-
--
; Joel Neely [joel--neely--fedex--com] 901-263-4460 38017/HKA/9677
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 ]
[10/20] from: ingo:2b1 at: 19-Oct-2000 20:57
Hi Joel,
this explanation sounds really good to me, it's the most
understandable complete explanation. (Meaning most explanations
up to now have either been an understandable but short "look
at this" or a complete but but to my mind overly complex
description).
That said, I'd add a short "that's what we want to explain"
number
0) a: func [b] [ c: [] d: copy [] append c b append d b print remold [c d]]
a 1
a 1
source a
Once upon a time Joel Neely spoketh thus:
[11/20] from: joel:neely:fedex at: 20-Oct-2000 8:33
Hello, list (and self!)
, he said, following with the oft-quoted
phrase, "Silly me!"
There's an embarrassing typo in point 14. Cut and paste works much
better if you cut the CORRECT version to past into the essay! Also,
according to Professor Peano,
S(14) = 15 && S(14) <> 14
Sorry!
-jn-
Joel Neely wrote:
> ...
>
> 14) All of this means that
>
> b: func [/local bb] [b: [] append bb "hi"]
>
Of course, this should have been written as
b: func [/local bb] [bb: [] append bb "hi"]
(as it was in the console transcript a few lines below).
> is actually equivalent to
> b: func [][[] append first second :b "hi"]
<<quoted lines omitted: 8>>
> >> b == ["hi" "hi"]
> >> b == ["hi" "hi" "hi"]
And the following should have been 15...
> 14) Every time a series is created "from scratch" it is a different
> series than any previously existing series.
>
> ...
and 16!
> 15) The block that constitutes the body of a function (and all literal
> values in it!) is created when FUNC is evaluated.
>
> ...
--
; Joel Neely [joel--neely--fedex--com] 901-263-4460 38017/HKA/9677
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 ]
[12/20] from: joel:neely:fedex at: 20-Oct-2000 9:07
Hi, Ingo,
Ingo Hohmann wrote:
[snip]
> 0) a: func [b] [ c: [] d: copy [] append c b append d b print remold [c d]]
> a 1
> a 1
> source a
>
You're probably right -- certainly from the way I introduced it!
What I completely failed to state in my second paragraph was that
part of my intent in a "stepwise description" was to turn the whole
discussion in the opposite direction from the way it normally runs.
In my teaching role, I've often used a common device of following
some concepts/techniques with a problem or puzzle of one of the forms,
"But we still can't do ..."
or
"But now we can't ..."
or
"Look what happens when we ... That's not what we expected!"
and then showing how to solve the problem or resolve the puzzle.
This approach is presumed to engage and motivate the student, and
probably is still appropriate in some cases, but I've begun to
suspect that it can also be very frustrating! After all, if used
too much, it runs the risk of frequently sending the subliminal
message, "You don't know what's going on!"
I wanted to try starting with some obvious (or easy-to-digest) facts
and incrementally building a comfort level with series and literal
series behavior such that the "puzzle" cases would never appear as
challenges, but only as by-then-obvious consequences of what had
been covered already.
But even so, I should have included the mutated-series case as
the last step, since my preamble stated that as my goal!
Thanks for your reminder!
-jn-
PS:
In this connection, I might mention that Dijkstra has offered
strong criticism of the way Mathematics is often taught -- by
showing the student highly compact and elegant proofs which offer
no clue of how someone might have thought them up to begin with!
Thus the student is left with only the options of
1) giving up in frustration, assuming "I can't understand this!";
(This option deprives a large part of the population of the
joy and beauty of Mathematical thought, and the practical
benefits thereof.)
2) simply committing the proofs to rote memory;
(Which may work for simple cases, but may only postpone #1, as
it is actually contrary to the spirit of Mathematics!)
3) discovering for himself, unaided, how to invent such things.
(Which is a severe burden, and one which we do not place on
the student of most other disciplines! Imagine training
medical doctors -- from the beginning -- by showing them films
of successful open heart surgery and then saying, "Now that
you've seen it, you try it!")
--
; Joel Neely [joel--neely--fedex--com] 901-263-4460 38017/HKA/9677
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 ]
[13/20] from: ingo:2b1 at: 20-Oct-2000 20:24
Hi Joel,
thank you for the insight, as I am trying to teach, too,
it's really worth to contemplate about it.
regards,
Ingo
Once upon a time Joel Neely spoketh thus:
<...>
[14/20] from: carl:cybercraft at: 21-Oct-2000 11:48
On 20-Oct-00, Joel Neely wrote:
> Hello, Carl and list,
> Every time I try to verbalize what happens in cases such as:
<<quoted lines omitted: 11>>
> know what you think of the following stepwise description of how
> REBOL handles literal series values in contexts such as the above.
[snip 15-point explaination of series.]
That's excellent Joel! I've filed it for future reference. Short
examples that demonstrate just the one thing can be very helpful.
Perhaps you should write a book too? (:
Carl Read.
[15/20] from: rishi:picostar at: 20-Oct-2000 12:17
I don't remember Joel posting a 15-point explanation of series. What was the subject
of this message?
on a side note, I also think Joel should consider writing a book on rebol!
Rishi
Previously, you (Carl Read) wrote:
[16/20] from: brett:codeconscious at: 21-Oct-2000 12:08
Hi Joel,
Great approach!
Just wanted to give some feedback.
Overall yes I think your approach definitely helps to explain the "suprising
behaviour of literal blocks" (almost needs an acronym doesn't it? :) ).
I liked point 7. () are not something I used much - other than for making
code more readable, or using the compose function. But your point, makes me
think again.
I initially expected something else from point 12. At first I thought "Chain
of references" to mean some sort of data structure held together with
pointers, when actually it appears you were showing how a series reference
can get passed around.
Point 13 say "a shared series reference is being modified". Your point is
well made, but I would have expected the phrase "the same series is being
modified" was more accurate.
I want to give my little story of how I reconciled Rebol's behaviour in my
mind.
When I was trying to get my head around the observed behaviour of Rebol with
what I understood to be happening I came up with two ideas that provided a
reconciliation.
A) Ages ago a had a quick look at a communication theory book. It described
symbol, reference and context
. Another talked of "sign", "signifier" and
signified
. I though hmm.... In my mind I saw a strong correlation of
these ideas with Rebol's "words" and "values".
B) While looking through the code of "probe", "help" and "source" I
remembered Carl mentioning that Rebol was its own meta language. Typing
source source
certainly seems to confirm this.
For me A and B considered together gave me the following line of thought.
It occurred to me that the words (signifiers) I communicate to Rebol (type
at console/ execute script) are interpreted by Rebol into values
(signified). These values are in Rebol and I can never actually see them - I
had to use words to refer to them.
When Rebol communiates with me it uses the same language, that is the same
words (signifiers). I then interpret them and understand the values
signified
that Rebol has communicated to me.
So at the console I type
a: []
meaning "let a refer to an empty block"
Rebol responds with
== []
meaning "empty block"
Then I type,
b: :a
what is a?, let b refer to this
Rebol follows obviously with
== []
empty block
So then I type,
append b "hi"
what is b?, append to this the string 'hi'
Rebol,
== ["hi"]
Block with the string 'hi'
And of course I ask,
a
what is a?
Rebol response,
== ["hi"]
Block with the string 'hi'
What was the point of that tedium? the Rebol words "a" and "b" both became
signifiers with the same signified (a block).
Rebol cannot show this relationship to me visually
>> source a
a: ["hi"]
>> source b
b: ["hi"]
But I can ask it if this is the case
>> same? a b
== true
So while I realise that this may not be the best description for someone
learning the language, I believe this model (signifiers/signified) has value
in highlighting "the big picture" when using Rebol. Rebol is a messaging
language. A language that does not require you to have to think in "bits",
byte boundaries
, etc.
Brett.
----- Original Message -----
From: "Joel Neely" <[joel--neely--fedex--com]>
To: <[rebol-list--rebol--com]>
Sent: Friday, October 20, 2000 2:29 AM
Subject: [REBOL] Re: Block Creation Re:
> Hello, Carl and list,
> Every time I try to verbalize what happens in cases such as:
<<quoted lines omitted: 8>>
> American English or REBOL ;-) very well, OR that I'm going about the
> explanation the wrong way.
...
[17/20] from: joel:neely:fedex at: 22-Oct-2000 20:35
[rebol-bounce--rebol--com] wrote:
> I don't remember Joel posting a 15-point explanation of series.
> What was the subject of this message?
>
Earlier in this same thread, shortly after the switch of mail server
software. If you can't find it, send me your off-line email address
and I'll shoot you a copy (so as not to spam the entire list).
-jn-
[18/20] from: joel:neely:fedex at: 22-Oct-2000 21:30
Hi, Brett,
[rebol-bounce--rebol--com] wrote:
> Just wanted to give some feedback.
>
Thanks for the feedback!
> I liked point 7. () are not something I used much - other than
> for making code more readable, or using the compose function.
> But your point, makes me think again.
>
To be honest, I don't use PAREN! values as often as I could. I'm
getting ready to do a rewrite of a couple of substantial pieces of
code, so I'm going to keep my eyes open for places where PAREN!s
might be appropriate.
> I initially expected something else from point 12. At first I
> thought "Chain of references" to mean some sort of data structure
> held together with pointers, when actually it appears you were
> showing how a series reference can get passed around.
>
That's a good point. I was really thinking of something like
chain of assignments
but couldn't say that, as we don't have
an "assignment" operator in REBOL! ;-)
Perhaps I should have said "This behavior does not depend on how
or when the reference to the block was obtained." Do you think
that works as well or better?
> Point 13 say "a shared series reference is being modified".
> Your point is well made, but I would have expected the phrase
> "the same series is being modified" was more accurate.
>
My first attempt could stand some rewording here as well!
I avoid saying "the same series" because I consider it misleading.
What is the relationship between A and B in each of the following?
>> a: [1 2 3] == [1 2 3]
>> b: a == [1 2 3]
<<quoted lines omitted: 3>>
>> append a 4 == [1 2 3 4]
>> b == [2 3 4]
To my mind a "series" requires both a sequence of data values and
a position within that sequence. In the second set of expressions
above, I would contend that A and B *are not* the "same series",
both because REBOL says they're not, and because the position of
each is different. Unfortunately, the term "sequence" is not
politically correct REBOL terminology, so it's awkward to describe
the relationship!
If I try to use more precise language, I end up talking about
two series values that refer to the same data sequence (whether
at the same position or not), and my sentences start sounding
too convoluted for my taste. I'm still working on this one.
> I want to give my little story of how I reconciled Rebol's
> behaviour in my mind.
>
[...interesting discussion reluctantly snipped...]
> the Rebol words "a" and "b" both became
> signifiers with the same signified (a block).
<<quoted lines omitted: 12>>
> A language that does not require you to have to think in "bits",
> "byte boundaries", etc.
First of all, let me give that last sentence a wholehearted three
cheers, and then go further and say that having to think in bits,
bytes, etc. is precisely the characteristic that segregates low-
level languages from high level languages (in which one does NOT
have to think in such implementation details).
That said, I'd be interested in how to use the "signifier/signified"
model to describe this:
>> a:[] == []
>> b: reduce [1 a 2] == [1 [] 2]
>> c: reduce [3 a 4] == [3 [] 4]
>> a: reduce [b c] == [[1 [] 2] [3 [] 4]]
>> append b/2 "Hi!" == ["Hi!"]
>> a == [[1 ["Hi!"] 2] [3 ["Hi!"] 4]]
The point being that there doesn't have to be a "name" or "word"
to act as a signifier! It is entirely possible to have data
structures with shared references (or "with references to series
values that refer to the same sequence") which exhibit the
sharing surprise
without there being any names for the
shared parts.
-jn-
[19/20] from: brett:codeconscious at: 23-Oct-2000 16:48
Hi Joel,
> > I initially expected something else from point 12. At first I
> > thought "Chain of references" to mean some sort of data structure
<<quoted lines omitted: 7>>
> or when the reference to the block was obtained." Do you think
> that works as well or better?
I must say I'm not sure. I think the problem is that the word "reference" is
a heavily loaded term and here is doing double duty. In one case it means a
series reference (in a value sense) in another it means a word referring to
a series (in a set-word sense). There could be more.
> > Point 13 say "a shared series reference is being modified".
> > Your point is well made, but I would have expected the phrase
<<quoted lines omitted: 15>>
> both because REBOL says they're not, and because the position of
> each is different.
Down this route you probably should add that "series" has behaviour as
well - since hash! reacts differently to block!
I personally won't though! :)
>Unfortunately, the term "sequence" is not
> politically correct REBOL terminology, so it's awkward to describe
<<quoted lines omitted: 3>>
> at the same position or not), and my sentences start sounding
> too convoluted for my taste. I'm still working on this one.
I see your point. I think for simplicity of description your really have to
add another name to describe what is going on. To finally get the concept
into my head I created for myself the term "series handle" - a handle on the
series that can slide up and down the series. That way I can understand that
I can have other handles on the series and have them in different positions.
I agree that Rebol calls this type a series!, but in my mind something of
type series! is not the actual series... Oh well, it works for me but I look
forward to the results of your futher work on this one :)
>...
> That said, I'd be interested in how to use the "signifier/signified"
<<quoted lines omitted: 7>>
> The point being that there doesn't have to be a "name" or "word"
> to act as a signifier!
Ok, but you won't have anything signified!
> It is entirely possible to have data
> structures with shared references (or "with references to series
> values that refer to the same sequence") which exhibit the
> "sharing surprise" without there being any names for the
> shared parts.
Most definitely, but how then will you refer to that shared thing? You
cannot directly, but relative to something else - something with a
signifier.
Do you remember Prince's experiment with a no-name status? It was very
annoying on the radio because everyone had to keep referring to him as the
man "formerly known as Prince" ( a relative reference). If he had supplied a
raspberry sound to use when referring to him that would have been the
signifier a -"pffft".
Here's the last line of your eaxmple:
a == [[1 ["Hi!"] 2] [3 ["Hi!"] 4]]
How do I know that you have a block that can exhibit the sharing suprise?
Because I followed the example in my head with my mental model, or I tried
it out in Rebol. The text of Rebol's response in the last line of your email
gives no clue that Rebol has in its model a structure with two references to
the same series. But it was the best Rebol could do to explain back to me
the structure it created. It is relying on me having an accurate mental
model to understand its response.
So here's an alternative pehaps silly way to introduce all this.
Rebol interprets the words you in at the console to build a model in its
mind
that resembles the model you describe. If you type [] Rebol "thinks" of
an
empty block. If you had typed my-block: [], Rebol thinks of an empty
block
and accepts that the fact that you want to refer to it whenever you use
the word
"my-block". Borrowing a concept from communications theory you might
term the
empty block the "signified" and the word "my-block" as the "signifier".
Later you may
decide that you want another word to refer to the same empty block so in
Rebol you
can refer to the empty block using the name you gave it earlier - like
this empty-block: my-block.
Doing this means you have two signifiers for the same signified.
You can refer to blocks in another way. You can use another block!
Blocks are special.
They remember values. They remember value in the order that the values
were given. You can
get a block to remember a number of values like "[apple pear orange]".
But this is not enough,
if you don't give the block a name it will be forgotten. So this is
better fruits: [apple pear orange].
Blocks can remember other blocks like this
snacks: [chips biscuits chocolate-bar]
grocery-list: reduce [ fruits snacks fruits]
Why did I put fruits in twice? - I like fruit.
What happens if I decide that fruits should include banana? Well that's
ok because grocery-list
remembers I wanted fruit list entered twice. So I just change fruits
like this
append fruits 'banana.
So what is happening here? grocery-list is not remembering the
individual fruit it is instead
remembering that I said I wanted a list of the fruit list first, then
the snack list and then the
fruit list again. A list that has three references to other lists, but
in which two of the references
refer to the same list.
And so on...
With my description I tried to give a flavour of my thinking as opposed to a
watertight model. Though, I believe it still has value as a way of looking
at what is happening.
[20/20] from: lmecir:geocities at: 24-Oct-2000 12:49
Hi,
one comment:
Make Block! doesn't do, what a beginner might expect it to. See the
following example code:
; Example #1
code: [
a: make block! [[]]
]
do code
append first a 11
code
Result of the execution:
== [
a: make block! [[11]]
]
; Example #2
code: [
a: copy/deep [[]]
]
do code
append first a 11
code
Result of the execution:
== [
a: copy/deep [[]]
]
Regards
Ladislav
Notes
- Quoted lines have been omitted from some messages.
View the message alone to see the lines that have been omitted