SwiftUI ViewBuilder: is it guaranteed that in `if/ese` statement `else` clause isn't executed when condition is true? - ios

I ask this because I suddenly realized today that, since the if/else statement we use to build View in SwiftUI is interpreted by ViewBuilder, it may behave differently than the plain old if/else statement in Swift language. Could it be that, for some (e.g. performance) reason, SwiftUI pre-execute both clauses and cache the result? Does anyone know it for sure?
I remember I observed some confusing behavior in the past, which might be explained by this hypothesis. But unfortunately I can't recall an example.

The way a result builder transforms your code is spelled out in SE-0289: Result builders. Section “Selection statements” describes how if/else statements are transformed. It gives the following example:
Consider the following code:
if i == 0 {
"0"
} else if i == 1 {
"1"
} else {
generateFibTree(i)
}
Under this pattern, the example code becomes something like the
following:
let vMerged: PartialResult
if i == 0 {
var firstVar = "0"
var firstBlock = BuilderType.buildBlock(firstVar)
vMerged = BuilderType.buildEither(first: firstBlock)
} else if i == 1 {
var secondVar = "1"
var secondBlock = BuilderType.buildBlock(secondVar)
vMerged = BuilderType.buildEither(second:
BuilderType.buildEither(first: secondBlock))
} else {
var elseVar = generateFibTree(i)
var elseBlock = BuilderType.buildBlock(elseVar)
vMerged = BuilderType.buildEither(second:
BuilderType.buildEither(second: elseBlock))
}
You can also read a detailed description of the transformation algorithm, but I think the example makes it clear enough that it will only execute one branch of an if/else statement.

Related

stumped by simple groovy variable comparison

I have a groovy script (a Jenkins pipeline) and a simple variable comparison is not working like I expect. I have a class defined to hold some constants, like this:
class email_when {
static final int ON_FAILURE = 0
static final int ALWAYS = 1
}
At a certain point in the script I set an environment variable to one of these states, like this:
env.EMAIL_WHEN = email_when.ALWAYS
Then later, I check the value. This check is always failing and I don't understand why.
echo ("email when = "+env.EMAIL_WHEN+ " always = "+email_when.ALWAYS);
if (env.EMAIL_WHEN == email_when.ALWAYS)
{
echo ("Send email.")
}
else
{
echo ("NO EMAIL")
}
So this always prints
email when = 1 always = 1
NO EMAIL
I don't understand why?
I thought maybe it was some sort of object/value comparison thing? Although I am directly setting env.EMAIL_WHEN to email_when.ALWAYS.
I tried this and it still did the same thing:
if (env.EMAIL_WHEN.equals(email_when.ALWAYS))
Can anyone explain what I am missing?
Thanks!
Everything in env map automatically converted to String
so 1 != '1'

Lua, local variables in a table

Sorry in advance if this is an incorrect question. I'm fairly new to Lua and I'm not sure how to go about this. I want to access a variable stored in a table from a function variable.
As far as I know there is no self-referencing tables before constructed.
An example would be this:
local bigTable = {
a = {
foo = 0,
bar = function(y)
print(foo) --Incorrect
end
}
}
What would be the best approach for this situation?
What you want to do is to create a table first, and append the keys to it:
local a = {}
a.foo = 0
a.bar = function()
print(a.foo)
end
local bigTable = {
a = a
}
bigTable.a.bar() -- prints 0
local bigTable = {
a = {
foo = 0,
bar = function(self, ...)
print(self.foo)
end,
}
}
-- Somewhere else in the code...
bigTable.a.bar(bigTable.a) --> 0
-- or the shorter but (almost) equivalent form:
bigTable.a:bar() --> prints 0
I anticipate your next question will be "What does the : do?", and for that there's lots of answers on SO already :)
Note that there's potential for a performance improvement here: if the above code gets called a lot, the bar method will be created again and again, so it could make sense to cache it; but that's pointless unless the surrounding code is already fast enough that this one allocation would have a noticeable impact on its runtime.

Is it possible to define your own operators in Rascal?

I'm writing some test helper functions to make the output more sensible:
bool tstEq(first, second) {
if(first == second)
return true;
else {
println("<first> was not equal to <second>");
return false;
}
}
Is it possible to do something like this?
bool ===(first, second) = tstEq(first, second);
usage:
test bool myTest() = 1 === 2
Which would result in something like:
rascal>:test
1 was not equal to 2
bool: false
A short answer: no. I fully agree that this can be convenient (but may also lead to less readable code).
Given the large list of topics we want to address first, it is unlike that such a feature will come to Rascal in the near future.

How to mute jslint error on do{}while(false)

In this simple code:
do {
console.log('o');
} while (false);
jslint produces a warning on the last line saying Unexpected 'false'
I understand why, but I still want to mute it because in these cases that's how I want to have the control flow.
Let's look at what jslint expects in the while statement. From the source:
labeled_stmt('while', function () {
one_space();
var paren = next_token;
funct.loopage += 1;
advance('(');
step_in('control');
no_space();
edge();
this.arity = 'statement';
this.first = expected_relation(expression(0));
if (this.first.id !== 'true') {
expected_condition(this.first, 'unexpected_a');
}
no_space();
step_out(')', paren);
one_space();
this.block = block('while');
if (this.block.disrupt) {
prev_token.warn('strange_loop');
}
funct.loopage -= 1;
return this;
});
It mostly reads like English. 'while', one space, (, no space, expected expression, no space, ).
So let's look at what an expression(0) is. You can read through the source if you're really interested, but to be honest I can't really wrap my head around it either. Sorry. https://github.com/douglascrockford/JSLint/blob/master/jslint.js
As far as I can tell, though, expression(0) traverses the tree of operators and operands, and looks for values with a Right Binding Power greater than 0? And false has a binding power of 0? But variables and comparisons are okay here. I have no clue how that even works. Ask Crockford.
As for shutting up jslint, here is my suggestion:
/*jslint devel: true, continue: true */
var i = 0;
var forever = false;
do {
i = i + 1;
if (i < 5) {
continue;
}
console.log('o');
} while (forever);

Formatting lua table for a parse $in query that is also a table

I am using corona (lua) with parse.com and I have hit a problem constructing an $in query using values from another table / array.
My code is a little like this:
local usersToFetch = {}
table.insert( usersToFetch, "KnVvDiV2Cj")
table.insert( usersToFetch, "Paf6LDmykp")
and the working query I want to perform is the following lua table (which will get encoded before heading to parse). As I said, this works when I am hard coding the values as shown
local queryTable = {
["where"] = {
["objectId"] = { ["$in"] = {"KnVvDiV2Cj","Paf6LDmykp" }}
},
["limit"] = 1000
}
My problem is how do I incorporate my 'usersToFetch' table in the above table so that it will work the same as hard coding the values?
I swore I tried that but clearly I did not.. I think that I placed it inside the braces whereas they are not needed which is where I went wrong.
Thanks, hjpotte92 - what you put worked fine but this is my final solution in a single declaration:
Where I was going wrong before was because I had too many braces ["objectId"] = { ["$in"] = { usersToFetch } }
local queryTable = {
["where"] = {
["objectId"] = { ["$in"] = usersToFetch}
},
["limit"] = 1000
}

Resources