Mailing List Archive: 49091 messages
  • Home
  • Script library
  • AltME Archive
  • Mailing list
  • Articles Index
  • Site search
 

WYSIWYG programming (was: Block Creation)

 [1/7] from: lmecir:geocities at: 25-Oct-2000 2:54


Hello list, I decided to write this, because I feel, that there is still a room for a totally different description of What Is Going On and What Shall We Do. code1: [ i: 0 while [(i: i + 1) <= 5] [ block: [] insert block "text" ] block ] ; Let's look at the result: do code1 *Every* newcomer labels the behaviour of Code1 as strange. Why? The reason is not the surprise, that Block

 [2/7] from: lmecir:geocities at: 25-Oct-2000 3:05


This is for the people, who feel certain discomfort seeing some "surprising once, surprising always" effects. I am trying to demonstrate for them (and for myself) that: 1) They are right when they are telling: "There must be something wrong with it." 2) How should we write our code to feel comfortable. Part #1 Let's start with an example: code1: [ i: 0 while [(i: i + 1) <= 5] [ block: [] insert block "text" ] block ] do code1 == ["text" "text" "text" "text" "text"] Allow me to label the behaviour of Code1 as *strange*. Now a second example: code2: [ i: 0 block: copy [] while [(i: i + 1) <= 5] [ insert block "text" ] block ] do code2 == ["text" "text" "text" "text" "text"] I would label this behaviour as *normal*. What is wrong with Code1? Code1, as opposed to Code2 changed during its execution! Let's see: probe code1 [ i: 0 while [(i: i + 1) <= 5] [ block: ["text" "text" "text" "text" "text"] insert block "text" ] block ] Conclusion: Code1 is not What You See Is What You Get Code. (Any suggestions, how to call such code? I have got: What You See Is Not What You Get Code, (Pure) Self Modifying Code, an analogy to Vivisection came to my mind,...) As we saw, copying can improve the behaviour of code WRT WYSIWYG properties sometimes. An experiment: code3: [ i: 0 while [(i: i + 1) <= 5] [ block: [] insert block "text" ] block ] do copy/deep code3 == ["text" "text" "text" "text" "text"] probe code3 [ i: 0 while [(i: i + 1) <= 5] [ block: [] insert block "text" ] block ] Here it looks, that Code3 is now OK, because it didn't modify itself. What went wrong? The problem is, that the deep copy of Code3 modified itself during its execution! (You can easily prove that, if you store the copy in a variable for future reference.) I think, that this example deserves the same name as above. Now a more advanced example (courtesy of Joel Neely): code4: [ for test1 1 5 1 [ block: [] insert block "text" ] block ] do code4 == ["text" "text" "text" "text" "text"] probe code4 [ for test1 1 5 1 [ block: [] insert block "text" ] block ] Here again, Code4 looks OK, because it didn't change. What went wrong? The code *is* Self Modifying similarly as Code3. When we look at the code, we see, that For is executed. As everybody suspects, For has to execute the supplied body somehow. Instead of executing it directly it creates a Do-body function. What is modifying itself during the execution is the Do-body function, which uses a *deep copy* (See the similarity with Code3?) of the supplied body, which means, that the supplied body will not be modified. source for for: func [ "Repeats a block over a range of values." [catch throw] 'word [word!] "Variable to hold current value" start [number! series! money! time! date! char!] "Starting value" end [number! series! money! time! date! char!] "Ending value" bump [number! money! time! char!] "Amount to skip each time" body [block!] "Block to evaluate" /local result do-body op ][ if (type? start) <> (type? end) [ throw make error! reduce ['script 'expect-arg 'for 'end type? start] ] do-body: func reduce [[throw] word] body op: :greater-or-equal? either series? start [ if not same? head start head end [ throw make error! reduce ['script 'invalid-arg end] ] if (negative? bump) [op: :lesser?] while [op index? end index? start] [ set/any 'result do-body start start: skip start bump ] if (negative? bump) [set/any 'result do-body start] ] [ if (negative? bump) [op: :lesser-or-equal?] while [op end start] [ set/any 'result do-body start start: start + bump ] ] get/any 'result ] Another example showing what is wrong with the Self Modifying Code: a: [append a [+ 1] 1]
>> do a
== 1
>> do a
== 2
>> do a
== 3
>> do a
== 4
>> do a
== 5
>> do a
== 6
>> do a
== 8 Although it seems like a bug, this example just demonstrates, that the result of a Self Modifying Code cannot be "forecasted" without the detailed knowledge of the implementation. Another example of this kind: code6: [1 (remove code6) 2] do code6 == [(remove code6) 2] As well as this we might have expected 2 to be the result. In the next part I am going to show you some less usual examples of Self Modifying Code. -Ladislav

 [3/7] from: holger:rebol at: 30-Oct-2000 9:32


On Wed, Oct 25, 2000 at 03:05:21AM +0200, Ladislav Mecir wrote:
> Another example showing what is wrong with the Self Modifying Code: > > a: [append a [+ 1] 1]
The above expression modifies a block while it is being evaluated. AFAICT at this time the result of such an operation should be considered "undefined" and implementation-dependent . In other words: don't do that ! I don't think the behavior can be called a bug as long as no specs have been defined for how the language should behave in this case. Most languages have expressions which are well-formed within the language, yet have unspecified semantics. An example is something like a: (*p++)+(*p++) in C. Here it is undefined whether the second access to "p" occurs before or after incrementing it for the first time (assuming I remember the C specs correctly...) A "legal" way to rewrite the above REBOL expression would, e.g., be: a: [append last a [+ 1] do [1]] This way the main block does not get changed during evaluation. Only the block referenced from the main block (the one initialized to be [1]) gets changed. That is completely legal. I hope you can see now why I dislike the term "self-modifying code". There is conceptually a huge difference between the first and second example, and the term "self-modifying code" tries to be a catch-all phrase that encompasses (and discourages) within the same category both legal (and potentially useful) and illegal practices. -- Holger Kruse [holger--rebol--com]

 [4/7] from: jeff:rebol at: 30-Oct-2000 8:39


Howdy, Holger:
> Most languages have expressions which are well-formed > within the language, yet have unspecified semantics. An > example is something like > > a: (*p++)+(*p++) > > in C. Here it is undefined
You bet it's undefined. What are you gunna do: goto the label a;? ;-) -jeff

 [5/7] from: holger:rebol at: 30-Oct-2000 10:00


On Mon, Oct 30, 2000 at 08:39:45AM -0800, [jeff--rebol--net] wrote:
> Howdy, Holger: > > Most languages have expressions which are well-formed
<<quoted lines omitted: 6>>
> You bet it's undefined. What are you gunna do: goto the > label a;? ;-)
Argl... Too much REBOL. I see colons everywhere :). a=(*p++)+(*p++); -- Holger Kruse [holger--rebol--com]

 [6/7] from: lmecir:geocities at: 30-Oct-2000 19:44


Hi Holger, I am glad I provoked this nice discussion! My point was *very* similar to yours. I wanted to suggest everyone to prefer the use of (at least relatively) WYSIWYG code, defined as follows: a) I call a Rebol value a Self Modifying (Rebol Code), if its evaluation (with a help of Do e.g.) causes its change (to be precise, I should define what is a Change, but let's leave that for a future discussion). (This definition differs from a "usual" definition of a Self Modifying Code!) b) I call a Rebol value a WYSIWYG (Rebol Code), if its evaluation (using Do e.g.) doesn't cause an evaluation of a Self Modifying Rebol Code. c) There are some Rebol values, like functions/natives If, Either, For, While, Make, ..., for whose the latter depends on the argument(s) they receive or on some other unknowns. Such values I call (relatively) WYSIWYG. See a more complete Message-ID: <005801c041bb$902f90a0$[497114d4--LadislavMe]>. Regards Ladislav

 [7/7] from: chaz:innocent at: 30-Oct-2000 20:51


I'm also glad you provoked this nice discussion. I always enjoy it when RT staff can be teased out their cubicles and into the lists. Haven't seen Holger for a while - thanks to you and Joe tag-teaming him, now we see him nearly every day! chaz At 07:44 PM 10/30/00 +0100, you wrote:

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