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

[REBOL] WYSIWYG programming

From: lmecir:geocities at: 25-Oct-2000 12:22

Part #2 Use as a code modifying function: --------------------------------- original-code7: [ temporary: "temporary" ] code7: copy original-code7 use [temporary] code7 same? first original-code7 first code7 == false You can say: "So what? The Use behaviour is normal!" The problem is, that you can unintentionally write a Self Modifying Code with all its disadvantages, as the next code shows: f7: func [level] [ use [temporary] [ if level = 0 [ temporary: "temporary" f7 level + 1 print ["Temporary:" temporary] ] ] ] f7 0 ** Script Error: temporary has no value. ** Where: temporary Is there a way out? Yes there is, quite simple: f8: func [level] [ use [temporary] copy/deep [ if level = 0 [ temporary: "temporary" f8 level + 1 print ["Temporary:" temporary] ] ] ] f8 0 Temporary: temporary *The WYSIWYG rule*: If you use a modifying function don't allow it to modify the executed code, supply it a code copy instead. Another way to cope with the above trouble is to create a non-modifying Use, e.g. like this: orig-use: :use use: func [ "Defines words local to a block." words [block! word!] "Local word(s) to the block" body [block!] "Block to evaluate" ] [ orig-use words copy/deep body ] Make as a code modifying function: ----------------------------------- f9: func [level] [ make object! [ a: 2 * level b: either zero? level [ f9 1 ] [ none ] a: a + 1 ] ] probe f9 0 make object! [ a: 0 b: unset ] Once again, Make modified its second argument, which happened to be the code in execution. The way out is easy: f10: func [level] [ make object! copy/deep [ a: 2 * level b: either zero? level [ f10 1 ] [ none ] a: a + 1 ] ] probe f10 0 make object! [ a: 1 b: make object! [ a: 3 b: none ] ] Repeat as a code modifying function: ------------------------------------- Let's try a more complicated example. In the Set Theory the sets modelling integer numbers 0,1,2,3,... are created as follows: 0 is modelled by empty set, which is normally denoted by 0 too every other number is modelled as the set containing all models of integers smaller than the modelled integer, i.e. 1 is modelled by [0] 2 is modelled by [0 [0]] 3 is modelled by [0 [0] [0 [0]]] ... A Rebol function to do this could be written as: f11: function [n] [result] [ if n = 0 [ return 0 ] result: copy [] repeat i n copy/deep [ append/only result f11 i - 1 ] ]
>> f11 0
== 0
>> f11 1
== [0]
>> f11 2
== [0 [0]]
>> f11 3
== [0 [0] [0 [0]]]
>> f11 4
== [0 [0] [0 [0]] [0 [0] [0 [0]]]]
>> f11 5
== [0 [0] [0 [0]] [0 [0] [0 [0]]] [0 [0] [0 [0]] [0 [0] [0 [0]]]]] What would happen, if we allowed Repeat to modify the executed code? Let's see: f12: function [n] [result] [ if n = 0 [ return 0 ] result: copy [] repeat i n [ append/only result f12 i - 1 ] ]
>> f12 0
== 0
>> f12 1
== [0]
>> f12 2
== [0 [0]]
>> f12 3
== [0 [0] [0]] Forskip is a Modifying Function too. Next part will contain more WYSIWYG examples. -Ladislav