Ifs
[1/10] from: lmecir:geocities at: 11-Oct-2000 21:33
Hi Rebols,
in the case anybody would like to have an as correct and general as possible
version of Ifs, here you are:
ifs: func [
{If positive do positive-block, zero do zero-block, negative do
negative-block}
[throw]
condition [number! char! money! time!]
positive-block [block!]
zero-block [block!]
negative-block [block!]
] [
either positive? condition [do positive-block] [
either negative? condition [do negative-block] [do zero-block]
]
]
Look out! It is necessary to write the arguments in correct order!
Regards
Ladislav
[2/10] from: joel:neely:fedex at: 11-Oct-2000 16:20
Hi, all...
In honor of the newest REBOL book (and for those of us who can't count to
three in proper order, such as myself! ;-) and inspired by the keywords
feature of Common Lisp, I offer yet another ifs , which doesn't care
in which order the actions are specified:
>> a: 1
== 1
>> ifs-for-dummies a [positive: ["plus"] zero: ["zip"] negative: ["minus"]]
== "plus"
>> ifs-for-dummies a [zero: ["zip"] positive: ["plus"] negative: ["minus"]]
== "plus"
>> ifs-for-dummies a [negative: ["minus"] zero: ["zip"] positive: ["plus"]]
== "plus"
whether they are all specified:
>> ifs-for-dummies a [positive: ["biggerthanzero"]]
== "biggerthanzero"
>> ifs-for-dummies a [negative: ["smallerthanzero"]]
>> ifs-for-dummies a [zero: ["equaltozero"]]
>> ifs-for-dummies a [zero: ["equaltozero"] positive: ["bigger, again!"]]
== "bigger, again!"
or whether the selector has unstable side-effects:
>> a: 1
== 1
>> b: to-paren [a: 0 - a]
== (a: 0 - a)
>> ifs-for-dummies b [negative: ["minus"] zero: ["zip"] positive: ["plus"]]
== "minus"
>> ifs-for-dummies b [negative: ["minus"] zero: ["zip"] positive: ["plus"]]
== "plus"
>> ifs-for-dummies b [negative: ["minus"] zero: ["zip"] positive: ["plus"]]
== "minus"
>> ifs-for-dummies b [negative: ["minus"] zero: ["zip"] positive: ["plus"]]
== "plus"
This new candidate (which will run if evaluated, but not if elected), has a
running mate:
fortranif: make object! [
positive: []
negative: []
zero: []
selector: 0
compute: func [[throw] selexpr] [
selector: selexpr
either positive? selector [
do positive
][
either negative? selector [
do negative
][
do zero
]
]
]
]
and a campaign promise:
ifs-for-dummies: func [[throw] selexp conseq [block!] /local actor] [
actor: make fortranif conseq
actor/compute selexp
]
(In case you're wondering, the news coverage of the US election campaigns
hasn't affected me at all! "My fellow REBOLians...")
-jn-
Coding at the speed of a dummy!
--
; Joel Neely [joel--neely--fedex--com] 901-263-4460 38017/HKA/9677
REBOL [] print to-string debase decompress #{
789C0BCE0BAB4A7176CA48CAB53448740FABF474F3720BCC
B6F4F574CFC888342AC949CE74B50500E1710C0C24000000}
[3/10] from: lmecir:geocities at: 12-Oct-2000 8:23
Hi Joel,
I am not glad, that I must disappoint you, but see the following example:
a: 1
b: to paren! [to paren! [to paren! [to paren! [a: 0 - a]]]]
ifs-for-dummies b [negative: ["Negative"] zero: ["Zero"] positive:
["Positive"]]
== "Zero"
I think, you should read Exception #5 for Word Evaluation of my Rebol/Core
User's
Guide Comments once again and hope, that this will be interesting even for
others...
Regards
Ladislav
P.S. My strong opinion is, that the best you can get is:
signed-if: func [
{If positive do positive-block, zero do zero-block, negative do
negative-block}
[throw]
condition [number! char! money! time!]
positive-block [block!]
zero-block [block!]
negative-block [block!]
] [
either positive? condition [do positive-block] [
either negative? condition [do negative-block] [do zero-block]
]
]
I am afraid, that Signed-if-for-dummies may become a victim of the GC bug
and similar issues, when used recursively...
[4/10] from: g:santilli:tiscalinet:it at: 12-Oct-2000 11:34
[lmecir--geocities--com] wrote:
> condition [number! char! money! time!]
Aren't CHAR!s always positive?
>> positive? #"^(FF)"
== true
Oh, and perhaps this is a bug?
>> positive? #"^(00)"
== true
What do you think?
Regards,
Gabriele.
--
Gabriele Santilli <[giesse--writeme--com]> - Amigan - REBOL programmer
Amiga Group Italia sez. L'Aquila -- http://www.amyresource.it/AGI/
[5/10] from: joel::neely::fedex::com at: 12-Oct-2000 6:53
Hi, Gabriele,
[giesse--dsiaq1--ing--univaq--it] wrote:
> [lmecir--geocities--com] wrote:
>
> > condition [number! char! money! time!]
>
> Aren't CHAR!s always positive?
>
> >> positive? #"^(FF)"
> == true
>
I wondered about the inclusion of char! as an argument type as
well, and then thought to try
>> to-integer #"^@"
== 0
>> #"^@" - 1
== #"ÿ"
>> to-integer #"^@" - 1
== 255
Aha! I thought that Ladislav is very clever to include a type that
can exercise at least two legs of the three-legged stool. Then I
read your post...
> Oh, and perhaps this is a bug?
>
> >> positive? #"^(00)"
> == true
>
> What do you think?
>
...and (confirming the change of notation, just for formality)...
>> zero? #"^@"
== true
>> positive? #"^@"
== true
I think you are right! This smells exceedingly buggish!
(I still think Ladislav is very clever. I'm less persuaded that
Zero? and Positive? are... ;-)
-jn-
[6/10] from: joel:neely:fedex at: 12-Oct-2000 7:27
[lmecir--geocities--com] wrote:
> Hi Joel,
>
> I am not glad, that I must disappoint you, [...]
>
Not at all! It's just that I, being a Bear of Small Brain, find it
difficult to give up. I'm very appreciative of the feedback!
I've forgotten the source, but recall the saying, "In science, a
successful experiment teaches nothing, as only the expected result
is obtained. One learns only when an experiment fails, providing a
challenge for new thought."
Thanks for the excellent teaching!
> but see the following example:
> a: 1
<<quoted lines omitted: 4>>
> I think, you should read Exception #5 for Word Evaluation of my
> Rebol/Core User's Guide Comments once again [...]
Have done.
> and hope, that this will be interesting even for others...
>
I also.
Trying yet again, (I'm running the risk of keeping two distinct issues
entangled here -- the get-to-the-bottom-of-a-strange-selector puzzle,
and the object-for-named-parameters gimmick)...
unravel: func [[throw] exp /local val] [
val: exp
while [not any[ number? val char? val money? val time? val]]
[
val: do val ]
val ]
signed-choice: make object! [
positive: []
negative: []
zero: []
selector: 0
compute: func [[throw] selexpr] [
selector: unravel selexpr
either positive? selector [
do positive
][
either negative? selector [
do negative
][
do zero
] ] ] ]
ifs-for-dummies-who-play-with-fire: func [
[throw] selexp conseq [block!] /local actor
][
actor: make signed-choice conseq
actor/compute selexp ]
After which I can conduct more experiments...
>> c: [{[{[{"-1"}]}]}]
== [{[{[{"-1"}]}]}]
>> ifs-for-dummies-who-play-with-fire c [
positive: ["+"] negative: ["-"] zero: ["0"]]
== "-"
>> c: [{[{[{"1"}]}]}]
== [{[{[{"1"}]}]}]
>> ifs-for-dummies-who-play-with-fire c [
positive: ["+"] negative: ["-"] zero: ["0"]]
== "+"
>> c: [{[{[{"2 - 2"}]}]}]
== [{[{[{"2 - 2"}]}]}]
>> ifs-for-dummies-who-play-with-fire c [
positive: ["+"] negative: ["-"] zero: ["0"]]
== "0"
>>
>
> I am afraid, that Signed-if-for-dummies may become a victim of the GC bug
> and similar issues, when used recursively...
>
I haven't had time to play with that issue, but will do so when I can.
Thanks again!
-jn-
[7/10] from: lmecir:geocities at: 12-Oct-2000 16:18
Hi,
a stupid example:
f: func [x [any-type!]] [1]
b: to paren! [to paren! [:f]]
ifs-for-dummies-who-play-with-fire b [positive: [print "positive"] negative:
[print "negative"] zero: [print "zero"]]
The result:
zero
== 1
Regards
Ladislav
[8/10] from: joel:neely:fedex at: 12-Oct-2000 11:53
Hi, Ladislav,
That was severely subtle! (And AFAIAC sounded the death knell on the notion
that REBOL is a simple language for non-programmers! ;-)
[lmecir--geocities--com] wrote:
> Hi,
>
> a stupid example:
>
replace read previous-message-in-thread "stupid" "challenging"
> f: func [x [any-type!]] [1]
> b: to paren! [to paren! [:f]]
<<quoted lines omitted: 3>>
> zero
> == 1
Even knowing the dynamic, code=data=code=data... nature of REBOL, I hadn't
thought of the possibility of supplying a value that totally changes the
evaluation pattern of another bit of code. Of course, this creates a whole
new level of threat models for trying to write defenses against potentially
hostile external code.
At any rate, the following mod seems to close the wormhole:
signed-choice: make object! [
positive: []
negative: []
zero: []
selector: 0
compute: func [[throw] selexpr] [
selector: (unravel selexpr)
either positive? selector [
do positive
][
either negative? selector [
do negative
][
do zero
] ] ] ]
...allowing...
ifs-for-dummies-who-play-with-fire b [
positive: ["+"] negative: ["-"] zero: ["0"]
]
== "+"
ifs-for-dummies-who-play-with-fire b [
positive: ["+"] negative: ["-"] zero: ["0"]
]
== "+"
Thanks!
-jn-
[9/10] from: lmecir:geocities at: 12-Oct-2000 21:10
Well, the problem is, that you are trying to disobey the KISS rule. That
rule means, that your signed-if-for-dummies should do one thing and do it
well. I think, that it should execute the properly chosen block. It shoudn't
try to evaluate its first argument at any price, because supplying it is a
work for the caller IMO. I am pretty sure, that the code is much more
brittle
and cryptic, than the proper solution, which should work for
useful first argument values and not for any garbage. E.g. your solution has
the worst possible property of any algorithm: there are some inputs, for
which the algorithm doesn't stop.
Regards
Ladislav
[10/10] from: g:santilli:tiscalinet:it at: 13-Oct-2000 11:06
[joel--neely--fedex--com] wrote:
> Even knowing the dynamic, code=data=code=data... nature of REBOL, I hadn't
> thought of the possibility of supplying a value that totally changes the
> evaluation pattern of another bit of code. Of course, this creates a whole
> new level of threat models for trying to write defenses against potentially
> hostile external code.
This is the reason I enforced [NUMBER!] on my IFS. ;)
After all, what's the point in passing code to it? You are
evaluating it once anyway (else it won't work), so you can simply
evaluate it before passing. Let's Keep It Simple!
Regards,
Gabriele.
--
Gabriele Santilli <[giesse--writeme--com]> - Amigan - REBOL programmer
Amiga Group Italia sez. L'Aquila -- http://www.amyresource.it/AGI/
Notes
- Quoted lines have been omitted from some messages.
View the message alone to see the lines that have been omitted