"if <struct> then" oddity
-
Right, not sure if this qualifies as a bug. Consider this function:
function tertiumNonDatur(v) ret = false if v then ret = true else ret = true endif return ret
In every other environment I know, such a function would either return 'true' or trigger an error of some sort, because in the absence of an error, one of the two branches of the if statement has to execute.
In Fuze, that's only the case if 'v' is an integer of float. If you pass it any string (empty or not), array (empty or not), struct or vector, it returns 'false'.
Using '(ref v)' instead of '(v)' does not change anything.Is this a bug or are we free to exploit it?
It's potentially useful for more compact linked lists. For example, the structures in this other thread have a 'next' element with the actual next list element and then a 'hasNext' flag indicating whether 'next' is set. With the above function, one could make the 'hasNext' element redundant; have 'next = 0' indicate that there is no next element and just set 'next' to the next element (almost necessarily a struct), and use the above trick to distinguish the two. Like so:
struct listElement listElement next = 0 // if that becomes illegal, use 'var next' endStruct function listHasNext(ref element) ret = true if element.next then ret = false else ret = false endIf return ret // count the elements in a list function listCount(ref element) count = 1 if listHasNext(element) then count += listCount(element.next) endif return count
(The above does not have a valid representation for the empty list; it's written for clarity, not usefulness.)
-
I'm still trying to get past this:
function tertiumNonDatur(v) ret = false if v then ret = true else ret = true endif return ret
How does that ever return anything other than true? You have an if statement that say "if this then true else true". That's always going to set 'ret' to true. Same in your lower example, except with false. How does that one ever return anything other than false? What am I missing?
-
You're hitting the nail on the head :) Under any normal logic, the (first) function should always return true. But
print(tertiumNonDatur([0]), "\n") print(tertiumNonDatur([.thisIsAStruct = 0]), "\n") print(tertiumNonDatur("string"), "\n") print(tertiumNonDatur({0,0,0}), "\n")
prints four zeroes. It just does. Maybe the implementation of the 'if' statement simply gives up silently? After all, '!v' is considered an illegal expression for all those values.
-
OK, I'm with you!
Yeah, on the face of it, that looks a lot like a bug to me. As you say, applying boolean logic directly to anything other than an int should really be an invalid expression so I would guess that it should really be bombing out with "illegal expression" for all of those cases.
-
I've filed a bug report / issue.
-
You are 100% correct: The implementation of
if
does indeed silently give up if the input is not an int (bool) or a float. Neither path of the if/else statement will be executed in this case. We'll likely have this produce an error in a future patch.Edit: A fix for this is coming in the next patch, to be exact.