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

[REBOL] WYSIWYG programming (was: Block Creation)

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