set-if
[1/5] from: anton::wilddsl::net::au at: 15-Apr-2007 20:27
I am sure this issue came up before, but I didn't do much about it.
This idiom aggravates me and I don't want to write it any more,
because of the repetition:
climber: self while [climber/parent][climber: climber/parent]
Instead I want to write this:
climber: self while [set-if 'climber climber/parent][]
which only sets climber *if* there is a following value (ie. not none?
climber/parent)
and introduces a new function "set-if".
Implementation:
Simple version:
set-if: func [word value][if value [set word value] get value]
More complex version, also handling "hot" values like functions:
set-if: func [word value][if get/any 'value [set/any word get/any 'value]
get/any 'value]
Test:
; First, make a hierarchy of 3 objects, top-level, its child, and its
grandchild ("bottom").
top-level: context [
parent: none
child: none
spawn: does [
child: make self compose [
parent: (self)
child: none
]
]
]
top-level/spawn
top-level/child/spawn
bottom: top-level/child/child/spawn
; Now set the climber at the bottom and make him climb:
climber: bottom while [set-if 'climber climber/parent][]
same? climber top-level ; == true
Regards,
Anton.
[2/5] from: gregg::pointillistic::com at: 15-Apr-2007 10:52
Hi Anton,
AR> This idiom aggravates me and I don't want to write it any more,
AR> because of the repetition:
AR> climber: self while [climber/parent][climber: climber/parent]
...
AR> More complex version, also handling "hot" values like functions:
AR> set-if: func [word value] [
AR> if get/any 'value [set/any word get/any 'value]
AR> get/any 'value
AR> ]
What should it do in the case of unset! and error! values?
-- Gregg
[3/5] from: anton::wilddsl::net::au at: 16-Apr-2007 10:30
I think it reacts well to unset! values, eg:
>> set-if 'a
** Script Error: set-if is missing its value argument
** Near: set-if 'a
which is similar to how a set-word! reacts.
An error! value can't be passed into the function unless
it is disarmed, so that's also just like a set-word!:
>> set-if 'a disarm try [1 / 0]
>> set-if 'a try [1 / 0]
** Math Error: Attempt to divide by zero
** Near: 1 / 0
Regards,
Anton.
[4/5] from: gregg::pointillistic::com at: 16-Apr-2007 9:44
Hi Anton,
AR> I think it reacts well to unset! values, eg:
AR> >> set-if 'a
AR> ** Script Error: set-if is missing its value argument
AR> ** Near: set-if 'a
AR> which is similar to how a set-word! reacts.
Sorry, I wasn't clear. I meant in your climber example usage. If one
of the objects has a parent value that is unset it will error out, but
leave a side effect.
-- Gregg
[5/5] from: anton::wilddsl::net::au at: 17-Apr-2007 22:30
Hi Gregg,
Oh I see (I think).
You mean that the climber only makes it half-way up is the side effect.
That's not a problem.
I can be sure the object system links child<->parent correctly
(in my example at least !)
And, the same effect occurs in the original example, not using
set-if at all.
So let me state that I am not trying to fix surrounding code
with this function ! :) only cut down a bit of repetition.
Regards,
Anton.