Lee Wilmott
(Starting to like KiXtart)
2003-01-08 06:27 PM
iif() stack overflow exception "problem"?

I am using KiX version 4.20 Beta 1.

I wrote the following Exp() function some time ago which I find very helpful for use with binary bit manipulation.

code:
Function Exp($Base, $Power)
;Returns a base value raised to the specified power
If $Power = 0
$Exp = 1
Else
$Exp = Exp($Base, $Power - 1) * $Base
EndIf
EndFunction

Anyway, since the release of 4.20 albeit Beta, I thought I could re-write it using the new iif() function.

However, the following code produces a "Stack overflow exception" error...

code:
Function Exp2($Base, $Power)
;Returns a base value raised to the specified power
$Exp2 = iif($Power = 0, 1, Exp2($Base, $Power - 1) * $Base)
EndFunction

Admittedly the function names are different (so I could test them in the same script file), but aren't these two functions programatically identical?

Should I be receiving "Stack Overflow" errors?

Lee


LonkeroAdministrator
(KiX Master Guru)
2003-01-08 06:34 PM
Re: iif() stack overflow exception "problem"?

will need to wait ruud's answer on this.

anyway, I never thought of using iif in this kind of nesting manner.

the stack was enchanged some time ago due to similar problem I had with exchaustive nesting script.

so, the key in here is should the if shortcut (iif) work in this manner or is it's usage limited.

anyway, good you found a usage for it, I haven't yet.


ShawnAdministrator
(KiX Supporter)
2003-01-08 07:02 PM
Re: iif() stack overflow exception "problem"?

Lee,

I just converted your UDF to VBS and was utterly shocked when I got exactly the same error !!! Would have bet the farm that this was a bug.

C:\t.vbs(8, 2) Microsoft VBScript runtime error: Out of stack space: 'Exp'

Heres the code:

code:
 
WScript.Echo Exp(5,5)

Function Exp(Base, Power)

' Returns a base value raised to the specified power

Exp = IIF(Power = 0, 1, Exp(Base, Power - 1) * Base)

' If Power = 0 Then
' Exp = 1
' Else
' Exp = Exp(Base, Power - 1) * Base
' End If

End Function

There must be more going on here than meets the eye !!!

-Shawn

[ 08. January 2003, 19:02: Message edited by: Shawn ]


Lee Wilmott
(Starting to like KiXtart)
2003-01-08 07:04 PM
Re: iif() stack overflow exception "problem"?

Shawn,

I didn't think of testing it with VB!

Anyway, yeah that is interesting.

Do I assume that you guys agree with me? - this shouldn't return a stack overflow error!

Lee


ShawnAdministrator
(KiX Supporter)
2003-01-08 07:11 PM
Re: iif() stack overflow exception "problem"?

The only reason I converted it to VBS is because I know thats probably what Ruud would have done. Arguably since it traps in both langauges there is more going on here that we dont understand.

My quess is (bear with me) is that IIF always evaluates both expressions - even if it is proved false in the first IIF parm (expression) - and because your recursing inside the IIF - it very quickly runs out of stack space.

Trying to think of a proof for that theory...

-Shawn

[edit]

Now that I think on it more - pretty positive that is whats going on.

[ 08. January 2003, 19:16: Message edited by: Shawn ]


LonkeroAdministrator
(KiX Master Guru)
2003-01-08 07:27 PM
Re: iif() stack overflow exception "problem"?

shawn, not sure is this what you mean but this got into my mind.

as iif first executes it's parameters (like any function) it does not behave in expected matter.

it seems that it tries to count the second parameter and as it kind of calls itself, it will keep calling until the stack-space roof has been reached...

yes, made a test script to prove this.

code:
$var=1
$loopcount
test()

function test()
$loopcount=$loopcount+1
$loopcount ?
$var=iif($var=1,$var,test())
endfunction



ShawnAdministrator
(KiX Supporter)
2003-01-08 07:47 PM
Re: iif() stack overflow exception "problem"?

agreed. I (personally) would classify this as unexpected behavior because (imho) would have expected IIF only to evaluate the expression that was true or false depending. But since this occurs in VBS as well I guess that Microsofts expectations are different from yours, mine and Lee's.

Put another way - its as if IIF first evaluates both expressions, than returns the required result (depending on the first expression) as opposed to evaluting the first expression first, than returning the result of only the required expression - my head hurts.

[ 08. January 2003, 19:52: Message edited by: Shawn ]


LonkeroAdministrator
(KiX Master Guru)
2003-01-08 07:51 PM
Re: iif() stack overflow exception "problem"?

so, as thought this way, iif has to be always slower than just if...

now, if the else part would be optional...


ShawnAdministrator
(KiX Supporter)
2003-01-08 07:56 PM
Re: iif() stack overflow exception "problem"?

Would be curious to see if this behavior is exhibited in a compiled language where short-circuiting is possible ...

LonkeroAdministrator
(KiX Master Guru)
2003-01-08 07:57 PM
Re: iif() stack overflow exception "problem"?

btw, as I said it's unexpected, have to correct...

one would indeed think it to work otherwise, but as the general execution rules apply, it is expected behavior.

just the same way as any other operation.
good reference is those AND, OR and NOT thingies some of has hard time fitting into mind.


ShawnAdministrator
(KiX Supporter)
2003-01-08 08:02 PM
Re: iif() stack overflow exception "problem"?

lol - just tried this in Visual Studio VB.Net and got the following error:

An unhandled exception of type 'System.StackOverflowException' occurred in mscorlib.dll


LonkeroAdministrator
(KiX Master Guru)
2003-01-08 08:04 PM
Re: iif() stack overflow exception "problem"?

to better explain the behavior as expected, one might try:
code:
$var=1,0
$loopcount
test()

function test()
$test=0
$loopcount=$loopcount+1
? $loopcount

$var[test()]
endfunction

it does the same thing, but this is more easily understood as will not work.

well, adding there a switch that stops looping after 1000 loops, makes it work, but anyway.


ShawnAdministrator
(KiX Supporter)
2003-01-08 08:08 PM
Re: iif() stack overflow exception "problem"?

Heres another proof I guess:

code:
break on

$x = iif(1=1,FuncOne(),FuncTwo())

exit 1

function FuncOne()
?"FuncOne..."
endfunction

function FuncTwo()
?"FuncTwo..."
endfunction

Output is:

code:
C:\>kix32 t

FuncOne...
FuncTwo...



[ 08. January 2003, 20:11: Message edited by: Shawn ]


ShawnAdministrator
(KiX Supporter)
2003-01-08 08:14 PM
Re: iif() stack overflow exception "problem"?

Actually calling VB.Net a compiled language is probably being too nice - be curious to try VB6.

ShawnAdministrator
(KiX Supporter)
2003-01-08 08:46 PM
Re: iif() stack overflow exception "problem"?

I think we've exhausted this discussion and reached the conclusion that despite how we think IIF should function - this is just how IIF works and we should accept it as such !?!?!?

My personal feeling at this point is that Microsoft (not Ruud) made an extremely poor naming choice in calling IIF "IIF" ... its NOT an "Immediate IF" at all - its an ass-backward conditional expression evaluator (ABCEE ?) that in no way behaves like an normal (yet compressed) IF statement.

And I think that this understanding is crucial when using IIF because you certainly wouldn't want to be calling functions that made some sort of permanent change from within an IIF because its going to get done regardless of the outcome - so maybe functions are not valid food for the IIF !!!

[ 08. January 2003, 21:02: Message edited by: Shawn ]


Lee Wilmott
(Starting to like KiXtart)
2003-01-08 10:10 PM
Re: iif() stack overflow exception "problem"?

Interesting topic - I think!

Shawn,

Your earlier example...

quote:
code:
$x = iif(1=1,FuncOne(),FuncTwo())


Which display's the two strings defined in BOTH functions really surprised me!

I 100% agree with you, iif() is clearly NOT the same as if ... else ... .

Although I see no reason why this shouldn't work - I also believe that KiX should perform in the same way that VB does - for interoperability reasons if nothing else.

Having said all that, I would be very interested in Ruud's views on this matter.

Lee


maciep
(Korg Regular)
2003-01-08 10:31 PM
Re: iif() stack overflow exception "problem"?

If it's any consolation, this seems to work:

code:
  

Function Exp2($Base, $Power)
;Returns a base value raised to the specified power
$ = iif($Power = 0, '$$Exp2 = 1', '$$Exp2 = Exp2($$Base, $$Power - 1) * $$Base')
$ = execute($)
EndFunction



LonkeroAdministrator
(KiX Master Guru)
2003-01-08 10:43 PM
Re: iif() stack overflow exception "problem"?

maciep, yes. it proves the concept.

but is it anymore worth it?
simple if-else-endif works properly...
and likely is faster.

I think the kix.doc should state something about this...


ShawnAdministrator
(KiX Supporter)
2003-01-08 11:13 PM
Re: iif() stack overflow exception "problem"?

Guys (especially Jooel) my apologies - i'm such a windbag peabrain - in all my ranting i totally lost sight of the fact that IIF is a FUNCTION - not a CONSTRUCT ... of course it would behave this way - just like any other function (builtin or custom) all parameters would be evaluated before the function was entered. It was hard for me to think of IIF as a function (for some reason) ...

Only came to this (obvious?) realization on the train ride home and re-reading jooels earlier comments - Jooel, you should have like threw a book at my head or something to wake me up.

My apologies to Microsoft and Ruud as well.

-Shawn

[ 09. January 2003, 02:26: Message edited by: Shawn ]


ShawnAdministrator
(KiX Supporter)
2003-01-08 11:19 PM
Re: iif() stack overflow exception "problem"?

So really all IIF really is is this:

code:
Break On

$x = IIF2(1=1,1+1,2+2)

Exit 1

Function IIF2($x,$y,$z)

If $x
$IIF2=$y
Else
$IIF2=$z
EndIf

EndFunction

And to my mind, IIF is only really usefull for quick one-shot conditional assignments - using throw-away expressions. Comments ?

[ 09. January 2003, 01:25: Message edited by: Shawn ]


Lee Wilmott
(Starting to like KiXtart)
2003-01-08 11:59 PM
Re: iif() stack overflow exception "problem"?

The If ... Else ... statement may well be quicker; I was just thinking (maybe that's the problem) that my exp() function would be a good test for the new iif() function.

You know what it is like, a new function is introduced to KiX - you've gotta have a look, haven't you?!?!?

Like you Shawn, I would only use iif() for the more simplistic task. However, the reason for posting my original post is that I thought that the returned result was incorrect and that it may have bigger, more important consequences.

I must admit, I'm not sure that after reading your comments that this is any clearer for me!!!

I agree with you Shawn, the iif() function is merely...

code:
Function IIF($x,$y,$z)
If $x
$IIF=$y
Else
$IIF=$z
EndIf
EndFunction

But seeing as this is all my exp() function contains is the if ... else ... statement, so why can't this statement be replaced with iif()?

Although, I believe you are correct; logically speaking this is exactly what iif() does, however programatically I would have to argue that it is different!

Am I missing something?

Lee


LonkeroAdministrator
(KiX Master Guru)
2003-01-09 12:11 AM
Re: iif() stack overflow exception "problem"?

you can replace.
but as you put a function into the parameter, it will be scanned before the iif is tested.

for shawns example:
code:
$x = iif(1=1,FuncOne(),FuncTwo())

function FuncOne()
?"FuncOne..."
endfunction

function FuncTwo()
?"FuncTwo..."
endfunction

it is translated to:
code:
$x = iif(1=1,?"FuncOne...",?"FuncTwo...")

and then executed.
say you have nested function which calls itself like you had.
I'm sure what it becomes.
it keeps adding itself to the parameters until the stack gets filled.

like you probably know, expressions are executed in bracket-style manner.

this is different with commands.
command does something and if is conditional command.

mmm...
to make iif-function work as "expected", ruud would need to override normal syntax rules for it.

making any sense?


Lee Wilmott
(Starting to like KiXtart)
2003-01-09 09:39 AM
Re: iif() stack overflow exception "problem"?

I'm with you!

Sorry...It was late last night when I posted my last message!

"Speak" soon,

Lee


**DONOTDELETE**
(Lurker)
2003-01-09 05:55 PM
Re: iif() stack overflow exception "problem"?

First of all, let me say that I was really excited to see the true community-power at work in this thread. The initial post was intriguing, and your combined responses have produced the exact cause and appropriate work arounds. Makes me feel proud to be part of this community!

And, as a result of your efforts, my response can be short: the phenomenon is indeed caused by the fact that all parameters of a function are always evaluated. Changing this behaviour would be non-trivial, and might break downward compatibility.

Basically, IIF() is just a bit of 'syntactical candy' which can make certain scripts shorter. If readability and performance are your main concern, good old IF is probably a better choice.

Thanks to all the participants, and keep scripting!

Ruud


Sealeopard
(KiX Master)
2003-01-09 06:11 PM
Re: iif() stack overflow exception "problem"?

So, basically
code:
$a=10
if $a<10
$b='a is smaller than 10'
else
$b='a is not smaller than 10'
endif

could be a candidate for the IIF as in
code:
$a=10
$b=iif($a<10,'a is smaller than 10','a is not smaller than 10')

but anything involving more complicated things like function evaluations would be off-limits.

You might need to update the Manual to make this clear.

[ 09. January 2003, 18:14: Message edited by: sealeopard ]


Richard H.Administrator
(KiX Supporter)
2003-01-10 10:16 AM
Re: iif() stack overflow exception "problem"?

Agreed, the manual should explicitly state the situations in which IIF() should be used, and the pitfalls of having the expressions always evaluated.

It caught me out at first as coming from a mainly 'C' background I am used to the ternary "?:" operator which appears to work in a similar way. The form is:
quote:
(condition) ? (True-expression) : (False-expression);
The difference is that this is a language construct, and only the expression which corresponds to the result of the condition expression is evaluated.

The fact that IIF() is a function implies that the parameters must be evaluated first, but it will save some headaches if it is spelled out explicitly in the documentation.


LonkeroAdministrator
(KiX Master Guru)
2003-01-11 12:34 AM
Re: iif() stack overflow exception "problem"?

can't say that I agree.
there is no place I've found that it's better to use iif.
mainly because I want to run stuff by speed.

there is no place where I would recommend it.

anyway, about adding some words to the manual to clarify that the parameters are eveluated will decrease the confusion.


Sealeopard
(KiX Master)
2003-01-10 04:24 PM
Re: iif() stack overflow exception "problem"?

The only place in my UDFs where I could see potential use of IIF is to simplify the following type of IF construct:
code:
; example
if @INWIN=1
$os='Windows NT/2000/XP'
else
$os='Windows 9x'
endif
; replaced example
$os=IIF(@INWIN=1,'Windows NT/2000/XP','Windows 9x')

and similar plain value-assigning IF constructs.


ShawnAdministrator
(KiX Supporter)
2003-01-10 04:28 PM
Re: iif() stack overflow exception "problem"?

I think IIF's are ok as long as one fully understands what one is doing - which I didn't - i thought of IIF more along the lines of the tenary IF that Richard outlined. Not the same beast at all.

Lee Wilmott
(Starting to like KiXtart)
2003-01-10 04:40 PM
Re: iif() stack overflow exception "problem"?

I totally agree with you shawn...
quote:
IIF's are ok as long as one fully understands what one is doing
Using iif() is fine...as long as you understand what it is doing and how it is doing it!

Lee