Scope? Any advice would be appreciated.
[1/19] from: rebol::mascari::org at: 27-Jan-2001 23:22
I stumbled across something tonight that appears to me to be a rather
another nasty paradigm shift that I have to make (or perhaps its a bug).
I have reduced the problem and wrote this function to illustrate it (I
named it lcDoesnt because it doesn'd do what I expect):
lcDoesnt: func [ /local b ]
[
b: [ 0 0 0 ]
print "The following line should ALWAYS be: 0 0 0 "
print b
b/3: b/3 + 1
print "The follwing line should ALWAYS be: 0 0 1 "
print b
print "......................."
]
My expectations are the following:
(1) the local variable "b" will be explicity set to [ 0 0 0 ]
(2) the third element of "b" will be incremented by one, thus resulting in
[ 0 0 1 ]
(3) because "b" is declared local, it should not be accessable outside of
the function
(4) "b" will be destroyed when the function exits
This pattern should repeat indefinitely as "b" is being explicity set
within the function. However, this is *not* the case. Only item #3 holds.
The problem is that "b" is somehow static, and so static, that even when
the function explicitly *assigns* its value, that the explicit assignment
is ignored in subsequent calls to the function (but not the first).
Here is the output from my Rebol/View console (as you can see, the third
element is being incremented, and is acting like a counter). Also note
that "b" is indeed not accessable to the global area as it should be, but
it must still exist somewhere else.
>> lcdoesnt
The following line should ALWAYS be: 0 0 0
0 0 0
The follwing line should ALWAYS be: 0 0 1
0 0 1
.......................
>> lcdoesnt
The following line should ALWAYS be: 0 0 0
0 0 1
The follwing line should ALWAYS be: 0 0 1
0 0 2
.......................
>> b
** Script Error: b has no value.
** Where: b
>>
Any advice would be appreciated.
Thanks,
Victor Mascari
[2/19] from: petr:krenzelok:trz:cz at: 28-Jan-2001 5:53
----- Original Message -----
From: <[rebol--mascari--org]>
To: <[rebol-list--rebol--com]>
Sent: Sunday, January 28, 2001 5:22 AM
Subject: [REBOL] Scope? Any advice would be appreciated.
> I stumbled across something tonight that appears to me to be a rather
> another nasty paradigm shift that I have to make (or perhaps its a bug).
<<quoted lines omitted: 11>>
> ]
> My expectations are the following:
Hi :-)
I am not sure I am the one to answer context specific issues, but will try
to :-)
> (1) the local variable "b" will be explicity set to [ 0 0 0 ]
right
> (2) the third element of "b" will be incremented by one, thus resulting
in
> [ 0 0 1 ]
right
> (3) because "b" is declared local, it should not be accessable outside of
> the function
right
> (4) "b" will be destroyed when the function exits
not sure, the concet is called indefinite extent? Maybe it doesn't seem
logical to you, but once you defined function, it is still alive (defined)
and so reference to your block 'b exists ...
The easiest solution is to use b: copy [0 0 0] as a declaration and Rebol
will give you fresh copy of data you need, not those already referenced by
local word 'b, which lives inside the context of the function ...
> This pattern should repeat indefinitely as "b" is being explicity set
> within the function. However, this is *not* the case. Only item #3
holds.
> The problem is that "b" is somehow static, and so static, that even when
> the function explicitly *assigns* its value, that the explicit assignment
> is ignored in subsequent calls to the function (but not the first).
I don't think 'b is static - it should be really local to your function....
> Here is the output from my Rebol/View console (as you can see, the third
> element is being incremented, and is acting like a counter). Also note
<<quoted lines omitted: 16>>
> ** Where: b
> >>
And the result matches exactly to what I said above ....
Hope-that-helps
Cheers,
-pekr-
[3/19] from: al:bri:xtra at: 28-Jan-2001 23:17
Victor Mascari wrote:
> lcDoesnt: func [ /local b ]
> [
<<quoted lines omitted: 6>>
> print "......................."
> ]
It's normal behaviour. You'll need to read either "Rebol: The Official
Guide", "Rebol for Dummies" or the Core manual book or PDF. They explain
your "problem" in better detail. Basically the block assigned to the local
word 'b in the function assigned to the word 'lcDoesnt "hangs around". It's
called "indefinite extent", IIRC. It's like allocating an array to a pointer
in C or Pascal.
Andrew Martin
ICQ: 26227169 http://members.nbci.com/AndrewMartin/
[4/19] from: g:santilli:tiscalinet:it at: 28-Jan-2001 11:32
Hello [rebol--mascari--org]!
On 28-Gen-01, you wrote:
r> I stumbled across something tonight that appears to me to be a
r> rather another nasty paradigm shift that I have to make (or
r> perhaps its a bug).
You will be enlightened if you look at the source of your
function.
>> source lcdoesnt
lcdoesnt: func [/local b][
b: [0 0 0]
print "The following line should ALWAYS be: 0 0 0 "
print b
b/3: b/3 + 1
print "The follwing line should ALWAYS be: 0 0 1 "
print b
print "......................."
]
>> lcdoesnt
The following line should ALWAYS be: 0 0 0
0 0 0
The follwing line should ALWAYS be: 0 0 1
0 0 1
.......................
>> source lcdoesnt
lcdoesnt: func [/local b][
b: [0 0 1]
print "The following line should ALWAYS be: 0 0 0 "
print b
b/3: b/3 + 1
print "The follwing line should ALWAYS be: 0 0 1 "
print b
print "......................."
]
All this is because you are still thinking in terms of variables,
but REBOL does not have variables. REBOL has values only, and your
'b is a value of type WORD!. Words are able to refer to ONE other
value (that is said to be its meaning). (Blocks are able to refer
to MANY other values.) In the code above, you are changing the
meaning of 'b, not 'b itself; 'b is "local" (actually, the
association between 'b and its meaning is "local"), but the value
it refers to is that very block above, not something that gets
created and destroyed for every function call.
To create a fresh block for each call, use:
b: copy [0 0 0]
or:
b: make block! [0 0 0]
Regards,
Gabriele.
--
Gabriele Santilli <[giesse--writeme--com]> - Amigan - REBOL programmer
Amiga Group Italia sez. L'Aquila -- http://www.amyresource.it/AGI/
[5/19] from: lmecir:mbox:vol:cz at: 28-Jan-2001 15:55
Hi Victor,
I will try to explain the difference between the way Rebol works and you
expect it to
> lcDoesnt: func [ /local b ]
> [
<<quoted lines omitted: 8>>
> My expectations are the following:
> (1) the local variable "b" will be explicity set to [ 0 0 0 ]
Rebol: the local variable B will be set to the second value of the
LCDOESNT's
body
> (2) the third element of "b" will be incremented by one, thus resulting
in
> [ 0 0 1 ]
Rebol: the third element of B will be incremented by one.
> (3) because "b" is declared local, it should not be accessable outside of
> the function
Rebol: the value is accessible as the second value of the LCDOESNT's body
> (4) "b" will be destroyed when the function exits
Rebol: no destruction
Rebgards
Ladislav
[6/19] from: rebol:mascari at: 28-Jan-2001 10:47
Thanks to all that replied!
Everything somewhat makes sense. Everything is just an "object" that
maintains itself once declared. And code appears to be self-modifying.
Ok.
However, I have a follow-up question. The following routine *does* work:
lcWorks: func [ /local b ]
[
b: 0
print "The following line s/b 0"
print b
b: b + 1
print "The follwing line s/b 1"
print b
]
It doesn't need to use "copy" to make it work. I guess this issue just
boils down to assignment techniques.
Why do I have to use different assignment techniques? That is, in the
above example, a straightforward assignment of 0 to b works as one would
expect. However, the same concept applied to a block, b: [ 0 0 0 ] as in
the earlier example, does not work. Instead I have to make a copy of [ 0 0
0 ] - b: copy [ 0 0 0 ].
I am not clear as to why I would need to make a copy - why wouldn't the b:
[ 0 0 0 ] just blow away the current contents, even if the function and its
properties are maintained between calls? Similarly, in one of the previous
answers from Gabriele, he showed what appears to me to be behavior of self
modifying code. However, I still don't understand why using "copy" forces
the code to update, whereas the normal assignment operator does not.
Lastly, since the code appears to be self-modifying, and behavior of
assignments change depdending upon whether it is the first call or a
subsequent one, I am curious as to what advantages this has vs the
confusion that it will cause people coming from other programming
environments.
Thanks again,
Victor Mascari
[7/19] from: g:santilli:tiscalinet:it at: 28-Jan-2001 20:48
Hello [rebol--mascari--org]!
On 28-Gen-01, you wrote:
r> Everything somewhat makes sense. Everything is just an
r> "object" that maintains itself once declared. And code appears
r> to be self-modifying. Ok.
Yes, because code is nothing more than data.
r> However, I have a follow-up question. The following routine
r> *does* work:
[...]
I was expecting that question. :-)
This is a matter of immutable vs mutable values. You cannot change
an INTEGER! value in REBOL (in your function you are using the ADD
native to create a *new* integer value), but you can change the
elements of a BLOCK! value (you don't create a new BLOCK! value,
you just change one of its elements).
r> works as one would expect. However, the same concept applied
r> to a block, b: [ 0 0 0 ] as in the earlier example, does not
r> work. Instead I have to make a copy of [ 0 0 0 ] - b: copy [ 0
r> 0 0 ].
You need to create a new fresh block each time only if you really
need it (that is, if you're going to change it). Doing this
automatically for each block wouldn't be a good idea, because most
of the time blocks are not changed (think about code blocks).
r> I am not clear as to why I would need to make a copy - why
r> wouldn't the b: [ 0 0 0 ] just blow away the current contents,
The matter is not the assignments itself, but is what you are
assigning. As you see, you changed that very block in the
function, so the second call looks like:
b: [0 0 1]
and not:
b: [0 0 0]
r> Gabriele, he showed what appears to me to be behavior of self
r> modifying code. However, I still don't understand why using
r> "copy" forces the code to update, whereas the normal
r> assignment operator does not.
Because then 'b will refer to a copy of that block in the code,
NOT that very block in the code. If you change the copy, the
original remains the same.
r> Lastly, since the code appears to be self-modifying, and
r> behavior of assignments change depdending upon whether it is
r> the first call or a subsequent one, I am curious as to what
r> advantages this has vs the confusion that it will cause people
r> coming from other programming environments.
It's a bit confusing in the beginning, but you'll find it obvious
and natural when you'll have some more experience with REBOL.
To be better, you have to be different. :-)
Regards,
Gabriele.
--
Gabriele Santilli <[giesse--writeme--com]> - Amigan - REBOL programmer
Amiga Group Italia sez. L'Aquila -- http://www.amyresource.it/AGI/
[8/19] from: lmecir:mbox:vol:cz at: 28-Jan-2001 21:07
Hi Victor,
> Thanks to all that replied!
> Everything somewhat makes sense. Everything is just an "object" that
<<quoted lines omitted: 12>>
> It doesn't need to use "copy" to make it work. I guess this issue just
> boils down to assignment techniques.
This issue doesn't have anything in common with the "assignment techniques".
> Why do I have to use different assignment techniques? That is, in the
> above example, a straightforward assignment of 0 to b works as one would
> expect.
The difference lies in the fact, that the expression b: b + 1 doesn't change
the second value of the LCWORK function's body. In a different wording: the
second value of the LCWORK's body remains unchanged, because it is
Immutable. For more info on Immutable vs. Mutable see e.g.
http://www.sweb.cz/LMecir/evaluation.html
> However, the same concept applied to a block, b: [ 0 0 0 ] as in
> the earlier example, does not work. Instead I have to make a copy of [ 0
0
> 0 ] - b: copy [ 0 0 0 ].
>
> I am not clear as to why I would need to make a copy - why wouldn't the b:
> [ 0 0 0 ] just blow away the current contents, even if the function and
its
> properties are maintained between calls?
It would, but the problem lies in the fact, that the code looks different
when modified. If you make a copy, any subsequent change will modify only a
copy of the second value contained in the function body.
> Similarly, in one of the previous
> answers from Gabriele, he showed what appears to me to be behavior of self
> modifying code. However, I still don't understand why using "copy" forces
> the code to update, whereas the normal assignment operator does not.
>
As you might have seen above, quite the opposite is true. If you don't make
a copy, a modification "updates" your code. If you make a copy, no
modification of the original occurs.
> Lastly, since the code appears to be self-modifying, and behavior of
> assignments change depdending upon whether it is the first call or a
<<quoted lines omitted: 7>>
> [rebol-request--rebol--com] with "unsubscribe" in the
> subject, without the quotes.
HTH
Ladislav
[9/19] from: dvydra2:yah:oo at: 28-Jan-2001 20:24
Gabriele,
Is this a simple optimization issue or is there a
deeper logic for this "strange" behaviour?
[10/19] from: rebol:techscribe at: 28-Jan-2001 22:41
Hi David,
The body of a function is a block and behaves like a block. What strikes
you as an unusual behavior is part of REBOL's consistency. REBOL is
different from other programming languages in that it applies a
relatively small set of rules consistently across most of its types
(including functions). Just as you expect any block (even one that is
embedded in an outer block) to preserve its values, so too does REBOL
preserve the values of a block that is embedded in a block even though
the host block, besides being a block, also happens to be the body of a
function.
Given the block b that contains a single element, a block that in turn
contains three integers, all of which are 0
>> b: [ [0 0 0] ]
I can access the internal block using the path notation with the index
1:
>> b/1
== [0 0 0]
Now let me change the first 0 in the inner block to a 3
>> change b/1 3
== [0 0]
The block b now contains a block that contains the three integers 3, 0,
and 0
>> b/1
== [3 0 0]
Now for a simple function whose body contains a block that contains
three 0s
>> f: does [ [0 0 0] ]
I can access the body block of the function using the second function:
>> second :f
== [[0 0 0]]
I can assign the word c as a reference to the body block:
>> c: second :f
The wird c is now a reference to a block (namely the body block of the
function) like b is a reference to a block
>> c
== [[0 0 0]]
>> b
== [[3 0 0]]
I can now change the first value of c's embedded block:
>> change c/1 3
== [0 0]
Now c/1 looks like b/1:
>> c/1
== [3 0 0]
>> b/1
== [3 0 0]
Indeed the are equal:
>> b/1 = c/1
== true
Let me add a set-word! called block: to both blocks:
>> insert b [block:]
== [[3 0 0 ]]
and let's do the same to c
>> insert c [block:]
== [[3 0 0]]
What does b contain?
>> b
== [block: [3 0 0]]
What does c contain?
>> c
== [block: [3 0 0]]
If we try to get the value associated with block we get an error message
in both cases, because the blocks haven't been evaluated yet, and
therefore the set-words have not been associated with anything:
>> get b/1
** Script Error: block has no value.
** Where: get b/1
>> get c/1
** Script Error: block has no value.
** Where: get c/1
Now let's evaluate the function, which means that the block is reduced:
>> f
== [3 0 0 ]
Now we can get the value of the set-word! block: in c (recall that c is
simply a word associated with f's body block):
>> get c/1
== [3 0 0]
Now block: is associated with the block [0 0 0] in the function f. Let's
first get rid of this association, and then we'll look at b:
>> unset 'block
How about b? Since b's block is not associated with a function, we
cannot evaluate this non-existent function. We can, however, reduce the
block programmtically (reducing a block means evaluating its elements):
>> reduce b
== [[3 0 0]]
The reduction has caused the set-word block! to be associated with the
block [3 0 0] in the block b:
>> get b/1
== [3 0 0]
Finally, we can express evaluation of a function without arguments,
refinements, and locals as a block reduction:
eval-function: func [body [block!] [ reduce body ]
Let's first unset block:
>> unset 'block
If some f is a "does" function (i.e. without arguments, refinements, or
locals), then evaluating the function is the equivalent of passing the
function's body to our eval-function:
>> f: does [ block: [0 0 0] ]
>> first second :f
== block:
>> get first second :f
** Script Error: block has no value.
** Where: get first second :f
>> fbody: second :f
>> eval-function fbody
== [[0 0 0]]
>> get fbody/1
== [0 0 0]
>> first second :f
== block:
>> get first second :f
== [0 0 0]
Hope this makes it more digestable.
Elan
David Vydra wrote:
[11/19] from: lmecir:mbox:vol:cz at: 29-Jan-2001 21:05
Hi David,
> Is this a simple optimization issue or is there a
> deeper logic for this "strange" behaviour?
Yes, if you would like to have even the "natural" behaviour, you would have
to use a different datatype, namely an immutable-block datatype, which might
complicate the datatype system and therefore even Rebol a bit. Another point
of view may be, that the benefits of such a change can be greater than the
complications caused by the datatype addition.
[12/19] from: dvydra2::yahoo at: 29-Jan-2001 13:29
Thanks to Laidslav and Elan for your answers.
Personally I can get used to the current
implementation of block assignment in functions.
However, I am a bit concerned about the wider
acceptance of REBOL in the corporate community, after
all that's probably where RT's payroll will come from
:)
I have always been interested in using higher-level
languages to be productive. My career has progressed
from dBase->Clarion->Gupta SqlWindows->Forte --->Java
and Rebol. All of the above, except Java have a small
market share these days. I just hope Rebol will stay
around long enough for ME to get tired of it -- and
that may be a long time :)
Regards,
David
--- Ladislav Mecir <[lmecir--mbox--vol--cz]> wrote:
[13/19] from: dvydra2:y:ahoo at: 30-Jan-2001 18:15
Elan,
Thanks for your reply. A few clarifications are in
order:
--- Elan <[rebol--techscribe--com]> wrote:
> A few comments:
> 1. SQlWindows is not a programming language. It is a
<<quoted lines omitted: 8>>
> kicking last time I
> checked ;-).
You are probably confusing SqlWindows with SqlBase.
SqlWindows (now Centura developer) uses a language
called SAL which is quite OO, even supports multiple
inheritance.
> True, dBase includes its own programming language,
> as does Clarion (so
<<quoted lines omitted: 10>>
> competition (of course, after all Oracle is also SQL
> based).
actually Clarion bought TopSpeed which had
cross-compilers for Pascal and some other language, I
cant recall. It was something like MS .NET. I wrote
systems in Clarion that had nothing to do with a DBMS.
> As for Forte, I'm not quite sure which Forte you are
> referring to. I am
<<quoted lines omitted: 3>>
> mean something
> else?
sorry I meant Forte 4GL www.forte.com, my once
employer, now owned by Sun. I guess they liked the
name adn
> 2. As for the specific REBOL feature we were
> investigating: statically
<<quoted lines omitted: 26>>
> for quite a few
> years, REBOL is quite safe.
actually C++ had a poor reputation in many IT shops
that tried to build a system with it without having
proper "geeks" on staff.
> I don't think that REBOL is weird, and I doubt that
> the weirdness of a
> language is a guarantee for its success. But Tcl,
> Perl, and Visual Basic
> still seem to be doing quite well ...
its all in the marketing, right? :)
anyway, I really like REBOL. We started using it
instead of JavaCC to write a domain-language to XML
compiler. So far, it works well.
david
=====
please reply to: [david--vydra--net]
[14/19] from: rebol:techscribe at: 30-Jan-2001 21:32
Hi David,
I was talking about versions of the software that came out in the mid or
late eighties. At the time the packages you mentioned were competing on
the DBMS market. I think this would also be true for 4GL languages, even
if they were not marketed as a companion product to a proprietary DBMS
technology. Their fate is determined by the dynamics of the DBMS market.
If a DBMS company eventually takes over a significant market share
(Oracle), then it sets standards not only with respect to the DBMS
itself, but also with respect to accompanying products.
I believe that, in contrast, REBOL is competing on what has been
traditionally the scripting or programming languages market. Here the
dynamics may be a little different. A DBMS oriented product (also 4GL)
will attempt to improve something with respect to existing DBMS
technologies. A programming or scripting language, on the other hand,
may include support for DBMSs to extend the sphere of influence of
programmers who use this language. These two distinct developments may
occassionally overlap, where a DBMS oriented shop will invest in a
scripting language because it feels that the language improves their
abilities to solve problems that are specific to their DBMS market, for
instance, but that does not mean that the fate of the language is has
now beomce dependent on the dynamics of the DBMS market, as a 4GL would
be.
Hope this clears it up,
Elan
[15/19] from: chaz:innocent at: 30-Jan-2001 22:31
Late and way off the tangent, here I am!
At 11:22 PM 1/27/01 -0500, you wrote:
>I stumbled across something tonight that appears to me to be a rather
>another nasty paradigm shift that I have to make (or perhaps its a bug).
<<quoted lines omitted: 12>>
>My expectations are the following:
>(1) the local variable "b" will be explicity set to [ 0 0 0 ]
I would expect the local variable "b" to be set to a location in memory.
You've initialized the contents of that location with 0 0 0
>(2) the third element of "b" will be incremented by one, thus resulting in
>[ 0 0 1 ]
I would expect the same.
>(3) because "b" is declared local, it should not be accessable outside of
>the function
It's not local scope, it's a local context, but it won't be visible in the
global context, no.
>(4) "b" will be destroyed when the function exits
I don't expect that, because the current state of the block that is giving
value to lcDoesnt is stored in system/words.
b will be "destroyed" when the set-word lcDoesnt: is placed before a
different word or a different block
lcDoesnt: "b is gone"
>This pattern should repeat indefinitely as "b" is being explicity set
>within the function. However, this is *not* the case. Only item #3 holds.
>The problem is that "b" is somehow static, and so static, that even when
>the function explicitly *assigns* its value, that the explicit assignment
>is ignored in subsequent calls to the function (but not the first).
The set-word lcDoesnt takes the value of the function block it is adjacent to.
The function block has been modified, so lcDoesnt acts accordingly.
Source lcDoesnt shows the modifications of the block.
>> lcDoesnt: func [ /local b ][
[ b: [ 0 0 0 ]
[ print "The following line should ALWAYS be: 0 0 0 "
[ print b
[
[ b/3: b/3 + 1
[
[ print "The follwing line should ALWAYS be: 0 0 1 "
[ print b
[ print "......................."
[ ]
>> lcDoesnt
The following line should ALWAYS be: 0 0 0
0 0 0
The follwing line should ALWAYS be: 0 0 1
0 0 1
.......................
>> source lcDoesnt
lcDoesnt: func [/local b][
b: [0 0 1]
print "The following line should ALWAYS be: 0 0 0 "
print b
b/3: b/3 + 1
print "The follwing line should ALWAYS be: 0 0 1 "
print b
print "......................."
]
>> lcDoesnt
The following line should ALWAYS be: 0 0 0
0 0 1
The follwing line should ALWAYS be: 0 0 1
0 0 2
.......................
>> source lcDoesnt
lcDoesnt: func [/local b][
b: [0 0 2]
print "The following line should ALWAYS be: 0 0 0 "
print b
b/3: b/3 + 1
print "The follwing line should ALWAYS be: 0 0 1 "
print b
print "......................."
]
>Any advice would be appreciated.
>
In my computer, there isn't "Code RAM" and "Data RAM", it's just all RAM,
and all of it is there for me to modify at my will.
[16/19] from: rebol:techscribe at: 29-Jan-2001 22:06
Hi David,
> I have always been interested in using higher-level
> languages to be productive. My career has progressed
<<quoted lines omitted: 3>>
> around long enough for ME to get tired of it -- and
> that may be a long time :)
A few comments:
1. SQlWindows is not a programming language. It is a product - a
database management system - that happens to use SQL. The DBMS product
may not have a major market share, but REBOL is not a dbms product, it's
a programming language. So we should be comparing it to SqlWindow's
programming language. And SQL is quite alive and kicking last time I
checked ;-).
True, dBase includes its own programming language, as does Clarion (so
you never programmed in Paradox, huh?). But in both cases we are again
talking about programming languages that are specific to a DBMS product.
So the competition here is about DBMS products, not about programming
languages. In other words dBase and Clarion (and SqlWindows) lost the
database management system competition, not the programming language
competition (of course, after all Oracle is also SQL based).
As for Forte, I'm not quite sure which Forte you are referring to. I am
aware of a Forte Newsgroup reader, and there's a Fort Java IDE. Right,
there's also a theorem prover called Forte. You must mean something
else?
2. As for the specific REBOL feature we were investigating: statically
scoped local variables have been part of C for roughly thirty years and
have happily made it into ANSI C++. That's pretty mainstream.
The only thing that a C/C++ programmer has to realize is that a (REBOL)
word that references a literal block (under all circumstances) acts
similar to a (C) local variable that is a pointer (word) referencing a
locally declared static buffer (or a globally declared buffer) (== REBOL
literal block). Even though you may reassign the pointer to the buffer
each time you enter the function, if that buffer was declared static (or
the buffer is global), then the buffer will contain whatever was
previously put into it during the previous evaluation of the C function.
There's really nothing to it.
My argument then is that if REBOL's success depends on the acceptance of
REBOL's literal block behavior, then, given that mainstream languages C
and C++ have been supporting an equivalent feature for quite a few
years, REBOL is quite safe.
I don't think that REBOL is weird, and I doubt that the weirdness of a
language is a guarantee for its success. But Tcl, Perl, and Visual Basic
still seem to be doing quite well ...
Take Care,
Elan
[17/19] from: lmecir:mbox:vol:cz at: 30-Jan-2001 8:48
Hi Victor,
I would like to answer your questions.
> Although I can "see" that the datatype determines the functionality of the
> assignment operator,
The above is incorrect. Compare the samples:
s1: function [] [x] [
x: 1
print either x = 1 ["Expected!"] ["Unexpected!"]
x: 2
]
s1 ; Expected!
; == 2
s2: function [] [x] [
x: [1]
print either x = [1] ["Expected!"] ["Unexpected!"]
x: [2]
]
s1 ; Expected!
; == [2]
> its not documented in the Rebol guide under "Setting
> Words" and the behavior is not consistent with immutables.
>
The assignment operator behaviour is consistent with immutables/immutables
(see above). The only thing, that is inconsistent with mutables as opposed
to immutables is the fact, that if you change the mutables contained in your
code, you are causing the code to become self modifying, which is surely a
dangerous practice, especially if you don't know what you are doing.
> On the surface, the first pass through the routine, b: [ 0 0 0 ] does the
> same thing as b: 0. But on subsequent runs the behaviors part paths and
> cause confusion and unexpected behavior for those of us who do not
> understand the underlying logic of Rebol. But, then again, why should I
> need to understand the underlying logic of Rebol? If the basic
instruction
> manual doesn't explain this, then how is anyone to know it? How many
other
> undocumented design decisions are there that impact basic operational
> usage?
>
> Also, I still don't see the value here - what benefit is secured by making
> these two different? Why do I have to use "copy" to accomplish with
> mutables the same thing that is accomplished without "copy" for
immutables?
Even with copy you still cannot accomplish exactly the same with mutables as
with immutables. Immutables are really protected against change (no way to
change them at all, which protects a programmer against a lot of errors). To
have a better symmetry, the introduction of immutable blocks as a new dataty
pe might help (especially the beginners may be less confused)?
[18/19] from: g:santilli:tiscalinet:it at: 30-Jan-2001 12:05
David Vydra wrote:
> Is this a simple optimization issue or is there a
> deeper logic for this "strange" behaviour?
Mora than "optimization", it's for simplification. The interpreter
is very simple this way, yet very powerful (more than most
languages).
Regards,
Gabriele.
--
Gabriele Santilli <[giesse--writeme--com]> - Amigan - REBOL programmer
Amiga Group Italia sez. L'Aquila -- http://www.amyresource.it/AGI/
[19/19] from: rebol:mascari at: 29-Jan-2001 19:17
Thank-you all for the clarification of immutable and mutable.
This fixes my problem, but just as David mentioned in a previous post, the
lack of consistency in operations can confuse people unless they are
intimate with the logical decisions that govern Rebol's design.
Although I can "see" that the datatype determines the functionality of the
assignment operator, its not documented in the Rebol guide under "Setting
Words" and the behavior is not consistent with immutables.
On the surface, the first pass through the routine, b: [ 0 0 0 ] does the
same thing as b: 0. But on subsequent runs the behaviors part paths and
cause confusion and unexpected behavior for those of us who do not
understand the underlying logic of Rebol. But, then again, why should I
need to understand the underlying logic of Rebol? If the basic instruction
manual doesn't explain this, then how is anyone to know it? How many other
undocumented design decisions are there that impact basic operational
usage?
Also, I still don't see the value here - what benefit is secured by making
these two different? Why do I have to use "copy" to accomplish with
mutables the same thing that is accomplished without "copy" for immutables?
Shouldn't a single operator implement a single concept?
I know there are a lot of questions above, but in order for me to
understand the goals of the Rebol product, I need to ask them. I still
don't see the big picture.
Again, thanks to all,
Victor Mascari
Notes
- Quoted lines have been omitted from some messages.
View the message alone to see the lines that have been omitted