I'm dealing with a collection of VBScript code (Microsoft Deployment Toolkit) and I frequently see the follow idiom when comparing a string to see if it has a given value:
If (oEnvironment.Item("IsOSUpgrade") <> "" and oEnvironment.Item("IsOSUpgrade") = "1") then
oEnvironment.Item is a property that I imagine could return null/nothing/empty (haven't wrapped my head fully around the subtle differences).
Does the first comparison serve any purpose? I'm guessing it does but don't understand what it would be. For surely if the the equality comparison returns True then the inequality comparison would as well, right? What am I missing? Something with null/nothing/empty?
You're right: if the second condition is true, the first will always be true. I think the first condition is there just for completeness and makes sure that "IsOSUpgrade" isn't empty/null.
Don't worry, you're not missing anything ;-)
Related
I am trying to write a function longer(S1,S2) which should be true if S1 is longer than S2, otherwise false. What I have so far is the following:
longer(A,nil).
longer(nil,B) :- false.
longer([A,AS],[B,BS]) :- longer(AS,BS).
But for some reason I cannot seem to get it to parse correctly when I provide for instance the input: longer([1,2],[1]).
But when I run the above through swi-prolog it return false.
Another example is running the: longer([1],nil) which also return false, even though it should be true by matching with list(cons(A,As)) where As = nil, finally matching the end clause.
What am I missing? Can someone point me in the right direction here, as I cannot see how this is not evaluating to true.
Edit: it should be noted that I am still fairly new to prolog at this point.
Update I have had some misunderstanding in relation to what is common prolog semantic. Including trying to force the program to yield a false value (probably being steered by my understanding of non-declarative language semantics). I have updated my answer with the inputs from #tiffi.
That is a solution that is pretty close to the thinking behind what you have come up with:
longer([_|_],[]).
longer([_|As], [_|Bs]):- longer(As,Bs).
Your idea with regard to the first clause (before your edit) could be expressed like this:
longer(A,[]):- is_list(A). %is_list/1 is inbuilt
However, that doesn't give you the right result, since the empty list is also a list. Thus you need to make sure that the first argument is a non-empty list.
h = {a: "foo"}
h.fetch(:a, h.fetch(:b))
yields key not found: :b
It seems strange that Ruby evaluates the default value even when the key is found? Is there a way around this?
Edit: Apparently this behavior falls under the paradigm of lazy vs eager evaluation. Nearly all imperative languages use eager evaluation, while many functional languages use lazy evaluation. However some languages, such as Python (which was before last week the only language I knew), have lazy evaluation capabilities for some operations.
It seems strange that Ruby evaluates the default value even when the key is found? Is there a way around this?
The overwhelming majority of mainstream programming languages is strict, i.e. arguments are fully evaluated before being passed. The only exception is Haskell, and calling it mainstream is a bit of a stretch.
So, no, it is not really "strange", it is how (almost) every language works, and it is also how every single other method in Ruby works. Every method in Ruby always fully evaluates all its arguments. That is, why, for example defined? and alias cannot be methods but must be builtin language constructs.
However, there is a way to delay evaluation, so to speak, using blocks: the content of a block is only evaluated each time it is called. Thankfully, Hash#fetch does take a block, so you can just use
h.fetch(:a) { h.fetch(:b) }
If you want the computation to only run if the key is not found, you can use the alternate form of fetch which accepts a block:
h.fetch(a) { h.fetch b }
I didn't actually know this was the case but I had a hunch and tried it and it worked. The reason I thought to try this was that something similar can be done in other methods such as gsub, i.e.
"123".gsub(/[0-9]/) { |i| i.to_i + 1 } == "234"
You could use the || operator instead, since it's lazy evaluated by design.
For example the following code where Nope is not defined does not throw an error.
{ a: "foo" }[:a] || Nope
However the fetch version will throw an error.
{ a: "foo" }.fetch(:a, Nope)
Personally I prefer how fetch is designed because it wont hide a bug in the default value.
However, in cases where I would rather not evaluate a default statement, then I would definitely reach for the || operator before doing something in a block or a lambda/proc.
I have the following logic:
if something
some_variable = true if another_variable
your_variable = true if that_other_variable
elsif thatthing
my_variable = true if another_variable
her_variable = true if that_other variable
else
puts "nothing found"
end
This is extremely simplified logic. Please forgive in advance for the names of the vars.
Coming from another language, I have conditioned my mind to think that nested inline if conditions are bad for readability reasons. I also have biases towards truthiness type tests. I tried to avoid negation if possible, but some times its unavoidable.
That being said, I have a couple of common possibilities of what I could use to replace the inline ifs, and one that is more uncommon that I put together to avoid negation. I am looking for feedback, and some things that you are doing to address this. Here it goes:
Possibility 1:
ternary:
if something
some_variable = defined?(another_variable) ? true : false
Possibility 2:
negation:
if something
some_variable = !defined?(another_variable)
# There are some variations to this, but this helps to address the negation I am trying to avoid.
Possibility 3 (I am favoring this one, but it seems a little uncommon):
if something
some_variable = (defined?(another_variable) && another_variable.length > 0) # Two truth based tests (does the var exist, and is it greater than 0 in length) This returns true/false.
Please let me know if anyone has any other solutions, and also which they feel is the most idiomatic.
Thank you!
Okay, instead of trying to stuff my answers in comments, I'll just give an answer, even though it's not quite an "answer".
All of your alternatives are not equivalent, they all do different things. What are you actually trying to do?
some_variable = true if another_variable
Will set some_variable = true only if another_variable has a truthy value. In ruby, any value but nil or false is evaluated as true in a boolean test. another_variable has to already exist, otherwise you'll get an exception raised.
So if another_variable exists, and is anything but nil or false, you'll set some_variable to true.
If another_variable exists and is nil or false, you won't change the value of some_variable at all, it will remain unchanged. It will not be set to false. (if some_variable didn't already exist, it will be brought into existence with a nil value. Otherwise it's previous value will be unchanged).
If another_variable didn't exist at all, the statement will raise an exception.
Is that what you intend? (And incidentally, using these meaningless variable names makes it a lot more confusing to talk about your example).
If that's really what you intend (and I'm doubting that it is), then there's probably no shorter or clearer way to do it than the way you've done: some_variable = true if another_variable.
There's nothing un-idiomatic with a one-line trailing if in ruby, it's perfectly idiomatic, people do it all the time, when it makes the code more clear. In your example -- and again it's hard to tell from your fake example -- I don't think it's the one-line if that makes it hard to tell what's going on, it is the weird structure of the top-level conditions, the overall structure of the code itself, it's very difficult to tell what the heck it's supposed to be doing. But you say you don't want to refactor that, so okay. And maybe that's just an artifact of you trying to produce a simple hypothetical and coming up with an awfully confusing one, maybe the original code isn't as confusing.
Your other alternative examples do something else, they are not equivalent. For instance:
some_variable = defined?(another_variable) ? true : false
This has different semantics than your first example.
if another_variable exists at all, then some_variable will be set to true. Even if another_variable exists with the value nil or false. So long as another_variable exists, some_variable will be set to true.
If another_variable does not exist at all some_variable will be set to false.
There is no case where some_variable will be untouched.
If that's really what you intend to do, then there certainly is a more concise alternative. defined? returns nil if the variable is not defined, otherwise a string explaining the nature of the defined variable. If you want to turn that into strictly boolean true or false, you can use a double boolean negation: some_variable = !! defined?(another_variable). Recall that in ruby anything but false or nil is evaluated as truthy in a boolean context, so !! foo will turn into false if foo was nil or false, and true if foo was anything else.
People also just commonly do some_variable = defined?(another_variable) and figure that's good enough to capture "did another_variable exist", since some_variable will still be evaluated the same in a boolean test. Although really, in idiomatic ruby you only occasionally need defined? at all, mostly you are working with variables you already know exist, and you don't need to test to see if they do, and even more seldom do you need to store the results of that test in a variable.
Your additional examples all have yet different semantics again, none of them are actually equivalent. Hopefully I've given you the tools here to see what they all actually do. You can also try them all out in a little test script, or in the irb REPL.
I suspect neither of these are what you actually want to do. It depends on the actual semantics you want, which you haven't told us. If your first version you start out with actually does represent the semantics you want, then I think there's no shorter way to do it.
You say you are refactoring existing code -- Based on this example you give us, I think the existing code may likely be a mess, with lots of bugs in it, written strangely, and with lack of certainty about what it's even supposed to do, since you aren't the original developer. I'm guessing it doesn't have any tests either. In this situation, I'd start by writing some tests establishing what the code is supposed to do, and then you can try refactoring and make sure it still performs as expected. Without that, and with such messy code, and especially with being newish to ruby, your refactoring is highly likely to change the semantics of the program when you weren't intending to, likely introducing new and even stranger bugs.
You don't need that true if <var> part and can use !!instead:
if something
some_variable = !!another_variable
your_variable = !!that_other_variable
elsif thatthing
my_variable = !!another_variable
her_variable = !!that_other variable
else
puts "nothing found"
end
new to TCL and running into a short circuit issue it seems. Coming from vbscript, I'm able to perform this properly, but trying to convert to a TCL script I'm having issues with the short circuit side effect and have been trying to find the proper way of doing this.
In the following snippet, I want to execute "do something" only if BOTH sides are true, but because of short circuiting, it will only evaluate the second argument if the first fails to determine the value of the expression.
if {$basehour != 23 && $hours != 0} {
do something
}
Maybe I'm not searching for the right things, but so far I've been unable to find the solution. Any tips would be appreciated.
The && operator always does short-circuiting in Tcl (as it does in C and Java and a number of other languages too). If you want the other version and can guarantee that both sub-expressions yield booleans (e.g., they come from equality tests such as you're doing) then you can use the & operator instead, which does bit-wise AND and will do what you want when working on bools. If you're doing this, it's wise to put parentheses around the sub-expressions for clarity; while everyone remember the precedence of == with respect to &&, the order w.r.t. & is often forgotten. (The parentheses are free in terms of execution cost.)
if {($basehour != 23) & ($hours != 0)} {
do something
}
However, it's usually not necessary to do this. If you're wanting an AND that you're feeding into a boolean test (e.g., the if command's expression) then there's no reason to not short-circuit, as in your original code; if the first clause gives false, the second one won't change what value the overall expression produces.
Related Questions: Benefits of using short-circuit evaluation, Why would a language NOT use Short-circuit evaluation?, Can someone explain this line of code please? (Logic & Assignment operators)
There are questions about the benefits of a language using short-circuit code, but I'm wondering what are the benefits for a programmer? Is it just that it can make code a little more concise? Or are there performance reasons?
I'm not asking about situations where two entities need to be evaluated anyway, for example:
if($user->auth() AND $model->valid()){
$model->save();
}
To me the reasoning there is clear - since both need to be true, you can skip the more costly model validation if the user can't save the data.
This also has a (to me) obvious purpose:
if(is_string($userid) AND strlen($userid) > 10){
//do something
};
Because it wouldn't be wise to call strlen() with a non-string value.
What I'm wondering about is the use of short-circuit code when it doesn't effect any other statements. For example, from the Zend Application default index page:
defined('APPLICATION_PATH')
|| define('APPLICATION_PATH', realpath(dirname(__FILE__) . '/../application'));
This could have been:
if(!defined('APPLICATION_PATH')){
define('APPLICATION_PATH', realpath(dirname(__FILE__) . '/../application'));
}
Or even as a single statement:
if(!defined('APPLICATION_PATH'))
define('APPLICATION_PATH', realpath(dirname(__FILE__) . '/../application'));
So why use the short-circuit code? Just for the 'coolness' factor of using logic operators in place of control structures? To consolidate nested if statements? Because it's faster?
For programmers, the benefit of a less verbose syntax over another more verbose syntax can be:
less to type, therefore higher coding efficiency
less to read, therefore better maintainability.
Now I'm only talking about when the less verbose syntax is not tricky or clever in any way, just the same recognized way of doing, but in fewer characters.
It's often when you see specific constructs in one language that you wish the language you use could have, but didn't even necessarily realize it before. Some examples off the top of my head:
anonymous inner classes in Java instead of passing a pointer to a function (way more lines of code).
in Ruby, the ||= operator, to evaluate an expression and assign to it if it evaluates to false or is null. Sure, you can achieve the same thing by 3 lines of code, but why?
and many more...
Use it to confuse people!
I don't know PHP and I've never seen short-circuiting used outside an if or while condition in the C family of languages, but in Perl it's very idiomatic to say:
open my $filehandle, '<', 'filename' or die "Couldn't open file: $!";
One advantage of having it all in one statement is the variable declaration. Otherwise you'd have to say:
my $filehandle;
unless (open $filehandle, '<', 'filename') {
die "Couldn't open file: $!";
}
Hard to claim the second one is cleaner in that case. And it'd be wordier still in a language that doesn't have unless
I think your example is for the coolness factor. There's no reason to write code like that.
EDIT: I have no problem with doing it for idiomatic reasons. If everyone else who uses a language uses short-circuit evaluation to make statement-like entities that everyone understands, then you should too. However, my experience is that code of that sort is rarely written in C-family languages; proper form is just to use the "if" statement as normal, which separates the conditional (which presumably has no side effects) from the function call that the conditional controls (which presumably has many side effects).
Short circuit operators can be useful in two important circumstances which haven't yet been mentioned:
Case 1. Suppose you had a pointer which may or may not be NULL and you wanted to check that it wasn't NULL, and that the thing it pointed to wasn't 0. However, you must not dereference the pointer if it's NULL. Without short-circuit operators, you would have to do this:
if (a != NULL) {
if (*a != 0) {
⋮
}
}
However, short-circuit operators allow you to write this more compactly:
if (a != NULL && *a != 0) {
⋮
}
in the certain knowledge that *a will not be evaluated if a is NULL.
Case 2. If you want to set a variable to a non-false value returned from one of a series of functions, you can simply do:
my $file = $user_filename ||
find_file_in_user_path() ||
find_file_in_system_path() ||
$default_filename;
This sets the value of $file to $user_filename if it's present, or the result of find_file_in_user_path(), if it's true, or … so on. This is seen perhaps more often in Perl than C, but I have seen it in C.
There are other uses, including the rather contrived examples which you cite above. But they are a useful tool, and one which I have missed when programming in less complex languages.
Related to what Dan said, I'd think it all depends on the conventions of each programming language. I can't see any difference, so do whatever is idiomatic in each programming language. One thing that could make a difference that comes to mind is if you had to do a series of checks, in that case the short-circuiting style would be much clearer than the alternative if style.
What if you had a expensive to call (performance wise) function that returned a boolean on the right hand side that you only wanted called if another condition was true (or false)? In this case Short circuiting saves you many CPU cycles. It does make the code more concise because of fewer nested if statements. So, for all the reasons you listed at the end of your question.
The truth is actually performance. Short circuiting is used in compilers to eliminate dead code saving on file size and execution speed. At run-time short-circuiting does not execute the remaining clause in the logical expression if their outcome does not affect the answer, speeding up the evaluation of the formula. I am struggling to remember an example. e.g
a AND b AND c
There are two terms in this formula evaluated left to right.
if a AND b evaluates to FALSE then the next expression AND c can either be FALSE AND TRUE or FALSE AND FALSE. Both evaluate to FALSE no matter what the value of c is. Therefore the compiler does not include AND c in the compiled format hence short-circuiting the code.
To answer the question there are special cases when the compiler cannot determine whether the logical expression has a constant output and hence would not short-circuit the code.
Think of it this way, if you have a statement like
if( A AND B )
chances are if A returns FALSE you'll only ever want to evaluate B in rare special cases. For this reason NOT using short ciruit evaluation is confusing.
Short circuit evaluation also makes your code more readable by preventing another bracketed indentation and brackets have a tendency to add up.