[REBOL] Re: Antwort: Re: WYSIWYG programming
From: ryanc:iesco-dms at: 25-Oct-2000 11:32
First I would like to thank Holger for the very enlightening explanation. I am forever
changed.
--Ryan
Holger Kruse wrote:
> On Wed, Oct 25, 2000 at 02:52:45PM +0100, [Sharriff--Aina--med-iq--de] wrote:
> >
> > Very important thread, it is very helpful that so many people on the list
> > take such matters into consideration. Its just strange that RT seems very
> > silent about this issue...
>
> As mentioned before, this is because we are extremely busy. I'll make an
> attempt at a response though. In any case, this should be considered my
> personal opinion only. It does not represent the official position of
> REBOL Technologies. Carl, e.g., is much more of an expert in programming
> languages than I am, and may see some things differently, or place
> different emphasis.
>
> First of all, I consider most of what Ladislav mentioned to be the result of
> "switching pain", difficulties when switching from one language to another
> one, and adjusting to a different way of thinking. It is easy to keep using
> paradigms that are common in C or Pascal when switching to REBOL (paradigms
> such as "code", "variables", "execution" etc.), instead of switching to the
> REBOL way of thinking. This sometimes gets people into trouble. From the
> terminology Ladislav used I suspect that this may be the case here, too. See
> below.
>
> "Switching pain" is not unique to REBOL. It happens almost any time someone
> switches from any language to any other language. If you ever had to switch
> from Modula/Pascal to C you probably found that 'a:=""' does not simply
> become 'a=""', and that in C "if(a=1)" may not do what you want :-).
>
> It would be very nice to have "quick quides" such as "REBOL for C programmers",
> "REBOL for Modula programmers" or even "REBOL for PERL programmers" (ouch!),
> which briefly explained the major paradigm differences and specific things to
> watch out for, e.g. knowing that in REBOL "a: []" does NOT mean "copy an empty
> block to the variable 'a'". Or the fact that in REBOL arithmetic evaluation
> is left-to-right, without precedence rules. We may eventually provide such
> guides, but, you know, limited time... Maybe someone out in the community
> could write a first draft.
>
> I agree with Joel that, in order to become really adept at REBOL, you have
> to understand some of its concepts (values, references, NO variables !, blocks,
> contexts, words etc.), but then that is true for any language. Try programming
> in C without knowing what a pointer is, how to use it, what the difference
> between a global, a static, an auto or an extern declaration is, or what you need
> to do to handle strings (doing memory management yourself etc.).
>
> In comparison REBOL seems a lot easier, but even with REBOL, if you don't know
> what words, references, contexts or blocks are you will eventually run into road
> blocks (no pun intended). Interestingly enough, from our experience users who have
> never used other languages before often have FEWER problems adjusting to REBOL's
> way of thinking than experienced programmers. That's probably because experienced
> programmers tend to skip forewords and introductory chapters in manuals (the "I know
> that already" syndrome), and don't even realize until much later that they are stuck
> with a way of thinking that does not fully apply and that tends to make things more
> difficult for them.
>
> To me, this whole issue is about collecting information on what particular
> areas cause problems for users which backgrounds, and presenting/distributing
> this information in a way that makes it easier for users to adjust.
>
> Now about the particular discussion regarding "self-modifying code" (shudder),
> and a slight attempt at "re-education" :-).
>
> First of all, I appreciate Ladislav's attempt at explaining those "gotchas". I don't
> fully agree with his explanation or interpretation though :-), for several reasons.
> Ladislav seems to apply terms that are not really appropriate, such as "self-modifying
> code" (or even just "code"), "executed code", "code in execution" etc. This is not
> the REBOL way of thinking, and in some situations it may even make issues more difficult
> to understand.
>
> In REBOL everything is data, so you never have "self-modifying code". A block of data
> may get evaluated, and in the process even modified, but you start off with data and
end
> up with data. This may seem like unnecessary emphasis on terminology (and I am usually
> not a stickler for terminology), but you will see the benefits in a minute...
>
> Part of the confusion results from a misunderstanding exactly what
>
> a: []
>
> means. Some users may intuitively think that a ":" in REBOL is similar to a ":=" in
> Pascal/Modula, and that "a: []" means "create the variable 'a' and initialize it to
> an empty block". If they find that the same part of their script later reads
>
> a: ["text"]
>
> they may assume that something "modified their code", and that "if the statement is
> executed again the variable 'a' is now assigned to a different value". That is NOT
> the case. It is incorrect thinking that is leading to a misinterpretation of what is
> happening.
>
> Here is what
>
> a: []
>
> really means: First keep in mind, that both the "a:" and the "[]" are within another
> block, i.e. they are just pieces of data. That means the "[]" is a block that exists
> before the function is even evaluated. The block was created when the script was first
> loaded, and at THAT time the block is created empty.
>
> When "a: []" is evaluated, a reference from the word "a" to the block following the
> "a:" is created. That is ALL that happens. No data is copied, no data is initialized.
> The effect is that, from that point on, evaluating the word "a" returns the block
> "a" is referencing, regardless of its value. That block starts off being empty, but,
> as with any other block, its value can change. The fact that the block is located inside
> of another block, which just happens to be a function body, makes no difference. REBOL
> does not enforce the block to be "constant". If you create a reference to it and then
> change the block through the reference -- then the block will get changed, even if
it
> was defined inside of a function body.
>
> This is not "self-modifying code", but simply "data being modified", which is what
> programming is all about. The "code" is still the same. When evaluated it creates
> a reference from the word "a" to the block following the "a:" and it does that same
> thing every time. The contents of the block may have changed, but it is still the
> same block, so the evaluation still does the same thing and will always create the
> same reference.
>
> If you really want to compare this to something in other programming languages,
> then compare it to something like the following in C:
>
> char data[16]="abc";
>
> void f(void) {
> char *a=data;
>
> printf("%s\n",a);
> strcat(a,"1");
> }
>
> The first time you call the function it prints "abc", the next time "abc1", then
> "abc11" etc., eventually it crashes :-). No self-modifying code here either. Observe
> how the "a=data" pointer assignment (somewhat similar to reference in REBOL, not
> 100% though) executes the exact same code every time the function is called. Not
> "strange" behavior at all.
>
> You could even put the "abc" into the function and make "a" static. Same effect. We
> need pointers and string manipulation here to "emulate" what REBOL does. That's
> because "variables" behave differently than "references".
>
> > 2) The current state of REBOL is beginning to remind me of the state
> > of FORTH when I last used it seriously (mid-80s). One issue that
> > hindered the growth and acceptance of FORTH was the fact that one
> > had to understand most of its language-level concepts in terms of
> > implementation details; to effectively use the language, one had
> > to understand ALL of the way that ALL of the core was built. I'd
> > hate to see REBOL suffer the same marginalization.
>
> I don't think users need to know any implementation details of REBOL. The main
> stumbling block seems to be a conceptual misunderstanding what a "reference" or
> "value" is, e.g. compared to a "variable". Knowing how REBOL internally represents
> a series or a word would not help.
>
> > To use REBOL control structures reliably, one MUST first
> > understand the significance of copying, deep copying, function
> > definition, and contexts. I worry about whether this cost is
> > so high as to prove prohibitive to entry-level REBOL users.
>
> Ladislav suggests deep copying everything. I don't think that is necessary or
> appropriate (from a performance point of view). Just as you do not want to
> fork() lots of processes in C only because there is a static variable somewhere in
> your code. You just need to think about what behavior you want, and what it means
> in terms of references to data items. Using the example
>
> code1: [
> i: 0
> while [(i: i + 1) <= 5] [
> block: []
> insert block "text"
> ]
> block
> ]
>
> Here "block: []" means "Create a reference to a block embedded in the function
> body." (the block following "block:"). At the end of the function "block" means
> "evaluate block and return the result", which just happens to be a reference to a
> block embedded in the function body, because that is what you set the word "block"
> to. This may not be what you want though.
>
> Not only is evaluating "block: []" inside of the while loop redundant (because the
> reference never changes, so you can just as well do it only once, before the
> loop, making the code more readable and efficient), but you are also returning a
> reference to an item inside of your function. The caller would not be free to
> manipulate it without causing side effects, and different callers would get
> references to the SAME item every time.
>
> THAT is why you should use "copy". "block: copy []" really gives you a NEW empty block,
> not a reference to an existing block. It means "use the following (empty) block as
> a template to give me a reference to a new empty block". It is somewhat like the
> "new" operator in C++.
>
> If it makes things easier to understand, consider "copy []" to be a constructor for
> a new empty block. Same thing regarding empty strings (or any series in general).
> Also, always keep in mind that "a: []" creates a reference, but does not copy any
> data and does not create any new "object"/"entity". That kind of thinking should
> explain REBOL's behavior quite nicely, without resorting to wild copy/deep workarounds
> for "self-modifying code" :-).
>
> --
> Holger Kruse
> [holger--rebol--com]
>
> --
> To unsubscribe from this list, please send an email to
> [rebol-request--rebol--com] with "unsubscribe" in the
> subject, without the quotes.
--
Ryan Cole
Programmer Analyst
www.iesco-dms.com
707-468-5400
I am enough of an artist to draw freely upon my imagination.
Imagination is more important than knowledge. Knowledge is
limited. Imagination encircles the world.
-Einstein