Author Topic: 'Inline If' Statement  (Read 5729 times)

0 Members and 1 Guest are viewing this topic.

Offline gumby

'Inline If' Statement
« on: January 18, 2011, 08:15:20 AM »
Any ideas how to implement something like this?  I've checked the SCI Studio help file, but came up with nothing. 

So instead of code like this (which I had to implement a temporary variable for holding the result of the first if)
Code: [Select]
  (var tempResult)

  (if (<condition>)
     = tempResult <true>
  ) else (
     = tempResult <false>
  )

  (if (== TRUE tempResult)
      Print("Hello")
  )

I'd like to do something like this: (the '?' and ':' are one of the ways I've seen other languages handle this)
Code: [Select]
   (if (== TRUE (<condition> ? <true> : <false>))
       Print("Hello")
   )



In the Great Underground Empire (Zork port in development)
Winter Break 2012 Rope Prop Competition

Offline lance.ewing

Re: 'Inline If' Statement
« Reply #1 on: January 18, 2011, 02:57:56 PM »
I've never written any SCI code, but from what I've deduced regarding the original language, I doubt that such syntax existed. One reason for this is that it has an expression as the first item after the opening ( character. My understanding is that the first item would have been one of: keyword, operator, kernel function, procedure or an object. An expression that resolves to a boolean does not align with this. I guess what you could do though is define a reusable public procedure that gives you something like this behaviour.

Offline MusicallyInspired

Re: 'Inline If' Statement
« Reply #2 on: January 18, 2011, 06:42:31 PM »
There's the 'and' and 'not' characters that should work. I also recall something with "&&" and "|" that I've used in the past.
« Last Edit: January 18, 2011, 06:49:54 PM by MusicallyInspired »
Brass Lantern Prop Competition

Offline troflip

Re: 'Inline If' Statement
« Reply #3 on: January 18, 2011, 08:55:13 PM »
Err why don't you just do this?
Code: [Select]
  (if (<condition>)
     Print("Hello");
  )

Or am I misunderstanding something?
Check out my website: http://icefallgames.com
Groundhog Day Competition

Offline gumby

Re: 'Inline If' Statement
« Reply #4 on: January 18, 2011, 09:41:01 PM »

My problem stems from porting code (programatically) that supports inline if's to SCI.  A more reasonable example is:
Code: [Select]
   (if ( > 5 ( a > 10 ? b : c ) )
        ...
   )
     
So, it's mostly a problem of 'nested' if's.  Some of the source code uses multiple inline-if's in the same statement, which aggravates the problem.

I would attempt a public procedure that could take care of the in-lines, but I don't think I can make it work when it comes to evaluation time - SCI doesn't seem to have an 'eval()' function (or similar).

My fallback is to re-write the if's to remove the nesting, like this:
Code: [Select]
   (var temp)
   (if (a > 10)
       = temp b
   ) else (
       = temp c
   )
     
   (if (> 5 temp)
       ...
   )
In the Great Underground Empire (Zork port in development)
Winter Break 2012 Rope Prop Competition

Offline lance.ewing

Re: 'Inline If' Statement
« Reply #5 on: January 19, 2011, 01:55:21 AM »
I don't think it would need an eval() function. The evaluation of the condition would happen before the procedure is called. So in effect what you get is a TRUE or FALSE being passed to the procedure as the first parameter. I am making an assumption that boolean parameters are possible. Likewise the second and third parameters would be evaluated before passing their results to the procedure. The code in the procedure would be very trivial. All the hard word of the evaluation would be done prior to the procedure being called.

Thinking about it, the "if" keyword is almost what you need.

(if (<condition>) (<first-value>) else (<second-value>))

All the procedure would be doing is turning that into a short cut of:

(proc (<condition>) (<first-value>) (<second-value>))

The big difference though would be that the procedure returns the value it picks. I doubt that the if keyword returns a value (but then again I don't know, so perhaps that is worth testing out. It would be weird and cryptic if it does return a value though).

Offline lance.ewing

Re: 'Inline If' Statement
« Reply #6 on: January 19, 2011, 07:34:41 AM »
The more I think about it, the more I am wondering whether using the "if" keyword as is might not be such a silly idea:

(if (<condition>) (<first-value>) else (<second-value>))

What if it does return a value? Now that I think it through, it seems to make sense that most things have a value. Whether it makes sense or not is the point I guess.

The real question though is whether the compiler will let you put an "if" into this context, e.g. the compiler would have to allow this kind of code:

(= someVar (if (<condition>) (<first-value>) else (<second-value>)))

Offline gumby

Re: 'Inline If' Statement
« Reply #7 on: January 19, 2011, 07:59:08 AM »
Yep, tried that and the compiler wouldn't buy it.  It seems that an 'if' statement cannot result in just a 'primitive' (the <first-value> or <second-value>).  It makes sense to me syntactically as well.  I guess this means that an 'if' statement has no return value.

Which brings us around full-circle to your suggestion, Lance.  I suppose I need a procedure that is an expression evaluator that returns a value (an 'if'/'then'/'else' replacement procedure).

I'm not up for building that (I think there are only a dozen or so in-line in references in the source code), I'll just bite the bullet and implement temporary holding variables instead.
In the Great Underground Empire (Zork port in development)
Winter Break 2012 Rope Prop Competition

Offline gumby

Re: 'Inline If' Statement
« Reply #8 on: January 19, 2011, 10:52:23 AM »
I don't think it would need an eval() function. The evaluation of the condition would happen before the procedure is called. So in effect what you get is a TRUE or FALSE being passed to the procedure as the first parameter. I am making an assumption that boolean parameters are possible. Likewise the second and third parameters would be evaluated before passing their results to the procedure. The code in the procedure would be very trivial. All the hard word of the evaluation would be done prior to the procedure being called.

Thinking about it, the "if" keyword is almost what you need.

(if (<condition>) (<first-value>) else (<second-value>))

All the procedure would be doing is turning that into a short cut of:

(proc (<condition>) (<first-value>) (<second-value>))

The big difference though would be that the procedure returns the value it picks. I doubt that the if keyword returns a value (but then again I don't know, so perhaps that is worth testing out. It would be weird and cryptic if it does return a value though).

I missed this post...  The reason I think I would need an eval() is that I'd like the procedure to be generic (accepting any sort of conditional statements) - returning the result would probably work just fine ('then' or 'else'), but I'd need some way to parse the conditional statement & evaluate it.
In the Great Underground Empire (Zork port in development)
Winter Break 2012 Rope Prop Competition

Offline lance.ewing

Re: 'Inline If' Statement
« Reply #9 on: January 19, 2011, 03:22:33 PM »
But I think that would be the beauty of it. You wouldn't need to pass in the condition. The condition is essentially self evaluating. e.g.

(proc (> var 5) (+ temp 7) (- bob 2))

The procedure doesn't see the condition expression or the calculation expressions. It sees the result. For example, if var is greater than 5 then the first argument to the procedure is a value of true. The condition expression could be as complex as you want it to be, including nested ands and ors and all that sort of thing. The procedure only ever sees a value of true or false for that first parameter. You would be using the power of the language to perfom the condition evaluation.

Offline troflip

Re: 'Inline If' Statement
« Reply #10 on: January 19, 2011, 04:18:01 PM »
Keep in mind that is slightly different than an if/else, because in your case both expressions are always evaluated. (However in the example you gave it wouldn't matter, because neither expression modifies any state).
Check out my website: http://icefallgames.com
Groundhog Day Competition

Offline gumby

Re: 'Inline If' Statement
« Reply #11 on: January 19, 2011, 09:34:17 PM »
Brilliant Lance!  It works perfectly.  Here is a full working example:
Code: [Select]
(procedure public (iif pTrue pFalse pCondition)
   (if (pCondition)
     return pTrue
   )(else
     return pFalse
   )
)

...

  (if (== "blue" iif("blue" "green" > 1 2))
      Print("It's blue")
  )(else
      Print("It's green")
  )

The procedure accepts any conditional expression (at least on the surface).  It will evaluate it and return either the true part (passed in with the 1st param) or the false part (passed in with the 2nd).  The only hitch was I needed to put the true & false parameters first, so that the final parameter (the condition) would gobble up all the rest of the supplied values in the procedure call.

In the above example, the expression evaluates to false, so the value returned is "green", and we get the message "It's green".

We've already got a built-in expression evaluator!  When the expression is passed into the procedure below, it's evaluated.
Code: [Select]
(procedure public (eval pExpression)
   return pExpression
)

...

FormatPrint("%d" eval(+ 1 2))     // Will print '3'


I never would have thought that an approach like this would have worked.  Thank you so much for the push in the right direction.
In the Great Underground Empire (Zork port in development)
Winter Break 2012 Rope Prop Competition

Offline troflip

Re: 'Inline If' Statement
« Reply #12 on: January 19, 2011, 10:53:24 PM »
We've already got a built-in expression evaluator!  When the expression is passed into the procedure below, it's evaluated.
Code: [Select]
(procedure public (eval pExpression)
   return pExpression
)

...

FormatPrint("%d" eval(+ 1 2))     // Will print '3'


Actually, it's evaluated before its passed into the function. All that's doing is evaluating it to 3, then passing 3 to eval, which just returns it.

The same thing is happening with your iif procedure. iif doesn't receive the expression (> 1 2), it just receives the result of it.

I've looked at the SCIStudio compiler, and I wrote the SCICompanion compiler, so I'm sure of it :-).
That being said, it certainly seems like it would be possible to modify the compiler to allow for something like this (i.e. passing lambda functions to procedures).
« Last Edit: January 19, 2011, 11:24:15 PM by troflip »
Check out my website: http://icefallgames.com
Groundhog Day Competition

Offline lance.ewing

Re: 'Inline If' Statement
« Reply #13 on: January 20, 2011, 02:05:08 AM »
I agree with troflip. The eval procedure is not required. The same thing would work if you did this:

FormatPrint("%d" (+ 1 2))     // Will print '3'

In the above example, it is actually the + that acts as a procedure. The 1 and 2 are in effect passed to it and it adds them together.

I'm surprised that you had to put the true and false parameters first. There should be no reason I can see why this would be required. What happens if you wrap the condition in () characters as in the following?

iif((> 1 2) "blue" "green")

Maybe the problem is that without the () the compiler is assuming that it is wrapped in () when it appears at the end of the parameter list. Maybe it can't assume that if the condition appears at the start of the parameter list, unless it is wrapped in () as in the above example. Yeah, thinking it through, if you were to write this:

iif(> 1 2 "blue" "green")

then the compiler would probably think that the 1, 2, "blue" and "green" are all parameters for the > operator.

Offline lance.ewing

Re: 'Inline If' Statement
« Reply #14 on: January 20, 2011, 02:08:55 AM »
Keep in mind that is slightly different than an if/else, because in your case both expressions are always evaluated. (However in the example you gave it wouldn't matter, because neither expression modifies any state).

Yes, this is a good point. It will always evaluate both, which might have side effects if the expression alters something in the process of evaluating the value. I guess there is extra work being done needlessly as well.


SMF 2.0.14 | SMF © 2017, Simple Machines
Simple Audio Video Embedder

Page created in 0.118 seconds with 23 queries.