the if statement in TCL - tcl

I have a question about if statement in tcl of the following code:
if {(($number == 1)&&($name == "hello")) || (($number == 0)&&($name == "yes"))} {
#do something here
}
The above code works, but if I wrote it down like this:
if {{$number == 1 && $name == "hello"} || {$number == 0&&$name == "yes"}} {
#do something here
}
It complains that the $number is expected to be a boolean, why? Is the second one not a valid expression? How to correct it?

Braces, {}, and parentheses, (), are not interchangeable in Tcl.
Formally, braces are (with one exception) a kind of quoting that indicates that no further substitutions are to be performed on the contents. In the first case above, this means that that argument is delivered to if without substitution, which evaluates it as an expression. The expression sub-language has a strongly-analogous brace interpretation scheme to general Tcl; they denote a literal value with no further substitutions to perform on it.
By contrast, parentheses are mostly not special in Tcl. The exceptions are in the names of elements of arrays (e.g., $foo(bar)), in the expression sublanguage (which uses them for grouping, as in mathematical expressions all over programming) and in the regular expression sublanguage (where they are a different type of grouping and a few other things). It is entirely legal to use parentheses — balanced or otherwise — as part of a command name in Tcl, but you might have your fellow programmers complaining at you anyway for writing confusing code.
The Specifics
In this specific case, the test expression of this if:
if {{$number == 1 && $name == "hello"} || {$number == 0&&$name == "yes"}} {...}
is parsed into:
blah#1 LOGICAL_OR blah#2
where each blah is a literal. Unfortunately, blah#1 (which is exactly equal to $number == 1 && $name == "hello") has no boolean interpretation. (Nor does blah#2 but we never bother to consider that.) Things are definitely going very wrong here!
The simplest fix is to change those bogus braces back to parentheses:
if {($number == 1 && $name == "hello") || ($number == 0&&$name == "yes")} {...}
I bet this is what you originally wanted.
Warning: Advanced Topic
However, the other fix is to add in a little extra:
if {[expr {$number == 1 && $name == "hello"}] || [expr {$number == 0&&$name == "yes"}]} {...}
This is normally not a good idea — extra bulk for no extra gain — but it makes sense where you're trying to use a dynamically-generated expression as a test condition. Do not do this unless you're really really certain you need to do this! I mean it. It's a very advanced technique that you hardly ever need, and there's often a better way to do your overall goal. If you think you might need it, for goodness' sake ask here on SO and we'll try to find a better way; there's almost always one available.

I think the error message you are getting does not mean that $number has to be a boolean (I got the message expected boolean value but got "$number == 1 && $name == "hello"").
It means that the string $number == 1 && $name == "hello" is not a boolean value - which is definitely true.
If you use curly braces in your if expression those strings are not evaluated but are simply interpreted as they are - as a string of characters.

In short: if uses a special "mini language" for its condition script — the same understood by the expr command. This is stated in the if manual page:
The if command evaluates expr1 as an expression (in the same way that expr evaluates its argument).
In contrast to Tcl itself, which is quite LISP-like and/or Unix shell-like, that "expr mini language" is way more "traditional" in the sense it feels like C.

In ($number == 1) number is assigned 1 and the comparison is made.Ex: 1==1 here output is Boolean.
But in {$number == 1 && $name == "hello"} $number is not assigned because of flower bracket $number is compared with 1 so output obtained is not Boolean.

Related

What is the technical term for a programming language's operator evaluation order?

Several procedures such as array destructuring in JavaScript or collection manipulation in Python have prompted me to evaluate an object's property or method to check if it even exists before proceeding, often resulting in the following pattern:
var value = collection.length
if value != null {
if value == targetValue {
/* do something */
}
}
In an attempt to make "cleaner" code I want to do something like:
if value != null && value == targetValue {
/* do something */
}
or with a ternary operator:
var value = collection.length != null ? collection.length : 0
However, I'm never sure if the compiler will stop evaluating as soon as it resolves the first comparison to null, or if it'll keep going and produce an error. I can of course do small unit tests to find out but I'd prefer if I knew the right term to look up in any language's documentation. What is this term, or is it perhaps the same in all languages?
This is known as Short Circuit Evaluation . It's quite consistent between languages.
In most languages, && will only evaluate the second argument if the first was true, and || will only evaluate its second if the first was false.

1084: Syntax error: expecting rightparen before and

I'm dying I just keep getting this error can someone help me.
and the second error is the same message but with this code.
for (idx=0;idx<childs.length;++idx) {
if (typeof(obj[childs[idx]]) == 'object' != childs[idx] != "$xml") {
out += this.dump( obj[childs[idx]], childs[idx], nLevels );
} else {
out += sPre + '\t' + childs[idx] + '="' + obj[childs[idx]].toString() + '"\n';
}
}
the error is at the row of the if statement.
You cannot use and as an operator. You must use &&. See below
if(node.nodeType == 1 && node.firstChild.nodeType <> 3)
However, note that <> is not an operator and cannot be used. I'm not sure whether you want greater than or less than so you'll have to fix that.
As for the second error, same issue. You cannot use and
if (typeof(obj[childs[idx]]) == 'object' && childs[idx] ne "$xml")
Also note again that ne is not a valid operator either and must be fixed
Your problem is here:
if (typeof(obj[childs[idx]]) == 'object' and childs[idx] ne "$xml") {
"and" is not an operator in as3. You're looking for &&.
"ne" is also not an operator in as3.
In pseudocode, what you're trying to do is:
"If my first variable is an 'object', and my second variable is not equal to "$xml", then do stuff."
You need to use the correct operators for those operations, not random names (from other languages, perhaps?).
Checking the documentation would be a good idea.

Perl if statement, If value = nothing do statement if value = something do statement

I am trying to insert a value from a text box into a SQL table. Although when I leave the text box blank it is adding a blank value which then causes the rest of the form functions to not work.
I want the if statement to check if $animal is blank do nothing. And if $animal has something in it, then to perform the insert into the table.
I am not quite sure what to put where I have put.
if ($animal = " ") {
}
else
if ($animal = "???") {
insertTable("INSERT INTO $table(name) VALUE ('".$animal."')");
Line 24 - 27 is this
sub insertTable {
$statement = shift (#_);
$dbh->do($statement);
} # sub
Perl uses scalar variables, which are quite versatile little things. One of the gotchas with them is that their 'truthiness' isn't always obvious.
If you test a scalar with a Boolean test it will be false if:
It's undefined.
It's an empty string.
It's the number 0.
It's the string "0".
(Arrays test as false if they're undefined or have no elements.)
So the correct answer would be - either used defined to check if the value is defined. Or use a regular expression to pattern match a 'valid' value.
E.g.
if ( $animal =~ m/\w+/ ) {
# Do something
}
\w+ is the Perl regular expression for saying 'one or more word characters' which is alphanumeric and underscore. So your empty string, whitespace only string, or undefined string will all not match this pattern.
Quite a few problems here. Addressing the worst of them:
You're using = which is for assignment, not comparison. Use == to compare numbers and eq to compare strings.
You're comparing your variable to a single space. It's very unlikely that you'll get a single space character in $animal. You'll want to do something either far simpler (if ($animal) { ... }) or more complex (perhaps if ($animal =~ /\w/) { ... }).
You are interpolating user input directly into SQL which you then run against your database. This leads to SQL injection attacks. Far better to use a bind point in your SQL.
In Perl there isn't a null value, only an undefined!
if (defined $value)
{
# Do that
}
else
{
# Do this
}

Using predicates in Alloy

I am trying to use two predicates (say, methodsWiThSameParameters and methodsWiThSameReturn) from another one (i.e. checkOverriding) but i receive the following error: "There are no commands to execute". Any clues?
I also tried to use functions but with no success, either due to syntax or to functions do not return boolean values.
They are part of a java metamodel specified in Alloy, as i commented in some earlier questions.
pred checkOverriding[]{
//check accessibility of methods involved in overriding
no c1, c2: Class {
c1=c2.^extend
some m1, m2:Method |
m1 in c1.methods && m2 in c2.methods && m1.id = m2.id
&& methodsWiThSameParameters[m1, m2] && methodsWiThSameReturn[m1, m2] &&
( (m1.acc = protected && (m2.acc = private_ || #(m2.acc) = 0 )) ||
(m1.acc = public && (m2.acc != public || #(m2.acc) = 0 )) ||
(#(m1.acc) = 0 && m2.acc != private_ )
)
}
}
pred methodsWiThSameParameters [first,second:Method]{
m1.param=m2.param || (#(m1.param)=0 && #(m2.param)=0)
}
pred methodsWiThSameReturn [first, second:Method]{
m1.return=m2.return || (#(m1.return)=0 && #(m2.return)=0)
}
Thank you for your response, mr C. M. Sperberg-McQueen, but i think i was not clear enough in my question.
My predicate, say checkOverriding, is being called from a fact like this:
fact chackJavaWellFormednessRules{
checkOverriding[]
}
Thus, i continue not understanding the error: "There are no commands to execute" .
You've defined predicates; they have a purely declarative semantics and they will be true in some subset of instances of the model and false in the complementary subset.
If you want the Analyzer to do anything, you need to give it an instruction; the instruction to search for an instance of a predicate is run. So you'll want to say something like
run methodsWithSameParameters for 3
or
run methodsWithSameParameters for 5
run methodsWithSameReturn for 5
Note that you can have more than one instruction in an Alloy model; the Analyzer lets you tell it which to execute.
[Addendum]
The Alloy Analyzer regards the keywords run and check (and only them) as 'commands'. From your description, it sounds very much as if you don't have any occurrences of those keywords in the model.
If all you want to do is to see some instances of the Alloy model (to verify that the model is not self-contradictory), then the simplest way is to add something like the following to the model:
pred show {}
run show for 3
Or, if you already have a named predicate, you could simply add a run command for that predicate:
run checkOverriding
But without a clause in the model that begins with either run or check, you do not have a 'command' in the model.
You say that you have defined a predicate (checkOverriding) and then specified in a fact that that predicate is always satisfied. This amounts to saying that the predicate checkOverriding is always true (and might just as well be done by making checkOverriding a fact instead of a predicate), but it has a purely declarative meaning, and it does not count as a "command". If you want Alloy to find instances of a predicate, you must use the run command; if you want Alloy to find counter-examples for an assertion, you must use the check command.

OR operator in JSONPath?

Using a single JSONPath expression alone, is it possible to do some kind of 'OR' or '||' operator. For example, these two JSONPath boolean expressions work to check the severity of a log JSON file:
$..log[?(#.severity == 'WARN')]
$..log[?(#.severity == 'Error')]
But I'd like to do something logically similar to:
$..log[?(#.severity == 'WARN' or #.severity == 'Error')] //this is not correct
Is there any way to do this?
If you are using Goessner's parser, you can use the || operator within your expression as follows:
$..log[?(#.severity == 'WARN' || #.severity == 'Error')]
From the JSONPath page:
[,] - Union operator in XPath results in a combination of node sets. JSONPath allows alternate names or array indices as a set.
Try
$..log[?(#.severity == 'WARN'), ?(#.severity == 'Error')]
Edit: Looks like there is an open issue for logical AND and OR operators in which they state that the operators are not yet supported by JSONPath.
Thank you for your answers. In my use case I got it working by combining the two answers from #sirugh and #elyas-bhy.
$..log[?(#.severity == 'WARN') || ?(#.severity == 'Error')]