Related
What are the benefits and drawbacks of the ?: operator as opposed to the standard if-else statement. The obvious ones being:
Conditional ?: Operator
Shorter and more concise when dealing with direct value comparisons and assignments
Doesn't seem to be as flexible as the if/else construct
Standard If/Else
Can be applied to more situations (such as function calls)
Often are unnecessarily long
Readability seems to vary for each depending on the statement. For a little while after first being exposed to the ?: operator, it took me some time to digest exactly how it worked. Would you recommend using it wherever possible, or sticking to if/else given that I work with many non-programmers?
I would basically recommend using it only when the resulting statement is extremely short and represents a significant increase in conciseness over the if/else equivalent without sacrificing readability.
Good example:
int result = Check() ? 1 : 0;
Bad example:
int result = FirstCheck() ? 1 : SecondCheck() ? 1 : ThirdCheck() ? 1 : 0;
This is pretty much covered by the other answers, but "it's an expression" doesn't really explain why that is so useful...
In languages like C++ and C#, you can define local readonly fields (within a method body) using them. This is not possible with a conventional if/then statement because the value of a readonly field has to be assigned within that single statement:
readonly int speed = (shiftKeyDown) ? 10 : 1;
is not the same as:
readonly int speed;
if (shifKeyDown)
speed = 10; // error - can't assign to a readonly
else
speed = 1; // error
In a similar way you can embed a tertiary expression in other code. As well as making the source code more compact (and in some cases more readable as a result) it can also make the generated machine code more compact and efficient:
MoveCar((shiftKeyDown) ? 10 : 1);
...may generate less code than having to call the same method twice:
if (shiftKeyDown)
MoveCar(10);
else
MoveCar(1);
Of course, it's also a more convenient and concise form (less typing, less repetition, and can reduce the chance of errors if you have to duplicate chunks of code in an if/else). In clean "common pattern" cases like this:
object thing = (reference == null) ? null : reference.Thing;
... it is simply faster to read/parse/understand (once you're used to it) than the long-winded if/else equivalent, so it can help you to 'grok' code faster.
Of course, just because it is useful does not mean it is the best thing to use in every case. I'd advise only using it for short bits of code where the meaning is clear (or made more clear) by using ?: - if you use it in more complex code, or nest ternary operators within each other it can make code horribly difficult to read.
I usually choose a ternary operator when I'd have a lot of duplicate code otherwise.
if (a > 0)
answer = compute(a, b, c, d, e);
else
answer = compute(-a, b, c, d, e);
With a ternary operator, this could be accomplished with the following.
answer = compute(a > 0 ? a : -a, b, c, d, e);
I find it particularly helpful when doing web development if I want to set a variable to a value sent in the request if it is defined or to some default value if it is not.
A really cool usage is:
x = foo ? 1 :
bar ? 2 :
baz ? 3 :
4;
Sometimes it can make the assignment of a bool value easier to read at first glance:
// With
button.IsEnabled = someControl.HasError ? false : true;
// Without
button.IsEnabled = !someControl.HasError;
I'd recommend limiting the use of the ternary(?:) operator to simple single line assignment if/else logic. Something resembling this pattern:
if(<boolCondition>) {
<variable> = <value>;
}
else {
<variable> = <anotherValue>;
}
Could be easily converted to:
<variable> = <boolCondition> ? <value> : <anotherValue>;
I would avoid using the ternary operator in situations that require if/else if/else, nested if/else, or if/else branch logic that results in the evaluation of multiple lines. Applying the ternary operator in these situations would likely result in unreadable, confusing, and unmanageable code. Hope this helps.
The conditional operator is great for short conditions, like this:
varA = boolB ? valC : valD;
I use it occasionally because it takes less time to write something that way... unfortunately, this branching can sometimes be missed by another developer browsing over your code. Plus, code isn't usually that short, so I usually help readability by putting the ? and : on separate lines, like this:
doSomeStuffToSomething(shouldSomethingBeDone()
? getTheThingThatNeedsStuffDone()
: getTheOtherThingThatNeedsStuffDone());
However, the big advantage to using if/else blocks (and why I prefer them) is that it's easier to come in later and add some additional logic to the branch,
if (shouldSomethingBeDone()) {
doSomeStuffToSomething(getTheThingThatNeedsStuffDone());
doSomeAdditionalStuff();
} else {
doSomeStuffToSomething(getTheOtherThingThatNeedsStuffDone());
}
or add another condition:
if (shouldSomethingBeDone()) {
doSomeStuffToSomething(getTheThingThatNeedsStuffDone());
doSomeAdditionalStuff();
} else if (shouldThisOtherThingBeDone()){
doSomeStuffToSomething(getTheOtherThingThatNeedsStuffDone());
}
So, in the end, it's about convenience for you now (shorter to use :?) vs. convenience for you (and others) later. It's a judgment call... but like all other code-formatting issues, the only real rule is to be consistent, and be visually courteous to those who have to maintain (or grade!) your code.
(all code eye-compiled)
One thing to recognize when using the ternary operator that it is an expression not a statement.
In functional languages like scheme the distinction doesn't exists:
(if (> a b) a b)
Conditional ?: Operator
"Doesn't seem to be as flexible as the if/else construct"
In functional languages it is.
When programming in imperative languages I apply the ternary operator in situations where I typically would use expressions (assignment, conditional statements, etc).
While the above answers are valid, and I agree with readability being important, there are 2 further points to consider:
In C#6, you can have expression-bodied methods.
This makes it particularly concise to use the ternary:
string GetDrink(DayOfWeek day)
=> day == DayOfWeek.Friday
? "Beer" : "Tea";
Behaviour differs when it comes to implicit type conversion.
If you have types T1 and T2 that can both be implicitly converted to T, then the below does not work:
T GetT() => true ? new T1() : new T2();
(because the compiler tries to determine the type of the ternary expression, and there is no conversion between T1 and T2.)
On the other hand, the if/else version below does work:
T GetT()
{
if (true) return new T1();
return new T2();
}
because T1 is converted to T and so is T2
If I'm setting a value and I know it will always be one line of code to do so, I typically use the ternary (conditional) operator. If there's a chance my code and logic will change in the future, I use an if/else as it's more clear to other programmers.
Of further interest to you may be the ?? operator.
The advantage of the conditional operator is that it is an operator. In other words, it returns a value. Since if is a statement, it cannot return a value.
There is some performance benefit of using the the ? operator in eg. MS Visual C++, but this is a really a compiler specific thing. The compiler can actually optimize out the conditional branch in some cases.
The scenario I most find myself using it is for defaulting values and especially in returns
return someIndex < maxIndex ? someIndex : maxIndex;
Those are really the only places I find it nice, but for them I do.
Though if you're looking for a boolean this might sometimes look like an appropriate thing to do:
bool hey = whatever < whatever_else ? true : false;
Because it's so easy to read and understand, but that idea should always be tossed for the more obvious:
bool hey = (whatever < whatever_else);
If you need multiple branches on the same condition, use an if:
if (A == 6)
f(1, 2, 3);
else
f(4, 5, 6);
If you need multiple branches with different conditions, then if statement count would snowball, you'll want to use the ternary:
f( (A == 6)? 1: 4, (B == 6)? 2: 5, (C == 6)? 3: 6 );
Also, you can use the ternary operator in initialization.
const int i = (A == 6)? 1 : 4;
Doing that with if is very messy:
int i_temp;
if (A == 6)
i_temp = 1;
else
i_temp = 4;
const int i = i_temp;
You can't put the initialization inside the if/else, because it changes the scope. But references and const variables can only be bound at initialization.
The ternary operator can be included within an rvalue, whereas an if-then-else cannot; on the other hand, an if-then-else can execute loops and other statements, whereas the ternary operator can only execute (possibly void) rvalues.
On a related note, the && and || operators allow some execution patterns which are harder to implement with if-then-else. For example, if one has several functions to call and wishes to execute a piece of code if any of them fail, it can be done nicely using the && operator. Doing it without that operator will either require redundant code, a goto, or an extra flag variable.
With C# 7, you can use the new ref locals feature to simplify the conditional assignment of ref-compatible variables. So now, not only can you do:
int i = 0;
T b = default(T), c = default(T);
// initialization of C#7 'ref-local' variable using a conditional r-value⁽¹⁾
ref T a = ref (i == 0 ? ref b : ref c);
...but also the extremely wonderful:
// assignment of l-value⁽²⁾ conditioned by C#7 'ref-locals'
(i == 0 ? ref b : ref c) = a;
That line of code assigns the value of a to either b or c, depending on the value of i.
Notes
1. r-value is the right-hand side of an assignment, the value that gets assigned.
2. l-value is the left-hand side of an assignment, the variable that receives the assigned value.
I've read other questions in stackoverflow very similar to what I'm asking but I still do not understand. I understand the basic idea behind a stack and how it works but I still do not understand why you have to go to the trouble of saving the value that the $s register have before calling the function.
Like for example, consider this c code.
int main()
{
int a = 5, b = 5, c = 0;
int c = addNumbers(a,b);
}
in that example, I'm don't care about the value that c has initially, so why would care to save it? I'm only concern with the return value it gets from the function.
One example off the top of my head that could apply to why you would save $s registers into the stack is to save the value of the variables in main so that when you send those variables into a function, the value of those variables in main remain the same.
This make sense because that variable on one hand could be use as an argument in a function and then used in an if statement after returning from the function.
So in that situation you would want to preserve that value.
If some one could provide a better example, that would be great.
For example, if I want to read the middle value from magic(5), I can do so like this:
M = magic(5);
value = M(3,3);
to get value == 13. I'd like to be able to do something like one of these:
value = magic(5)(3,3);
value = (magic(5))(3,3);
to dispense with the intermediate variable. However, MATLAB complains about Unbalanced or unexpected parenthesis or bracket on the first parenthesis before the 3.
Is it possible to read values from an array/matrix without first assigning it to a variable?
It actually is possible to do what you want, but you have to use the functional form of the indexing operator. When you perform an indexing operation using (), you are actually making a call to the subsref function. So, even though you can't do this:
value = magic(5)(3, 3);
You can do this:
value = subsref(magic(5), struct('type', '()', 'subs', {{3, 3}}));
Ugly, but possible. ;)
In general, you just have to change the indexing step to a function call so you don't have two sets of parentheses immediately following one another. Another way to do this would be to define your own anonymous function to do the subscripted indexing. For example:
subindex = #(A, r, c) A(r, c); % An anonymous function for 2-D indexing
value = subindex(magic(5), 3, 3); % Use the function to index the matrix
However, when all is said and done the temporary local variable solution is much more readable, and definitely what I would suggest.
There was just good blog post on Loren on the Art of Matlab a couple days ago with a couple gems that might help. In particular, using helper functions like:
paren = #(x, varargin) x(varargin{:});
curly = #(x, varargin) x{varargin{:}};
where paren() can be used like
paren(magic(5), 3, 3);
would return
ans = 16
I would also surmise that this will be faster than gnovice's answer, but I haven't checked (Use the profiler!!!). That being said, you also have to include these function definitions somewhere. I personally have made them independent functions in my path, because they are super useful.
These functions and others are now available in the Functional Programming Constructs add-on which is available through the MATLAB Add-On Explorer or on the File Exchange.
How do you feel about using undocumented features:
>> builtin('_paren', magic(5), 3, 3) %# M(3,3)
ans =
13
or for cell arrays:
>> builtin('_brace', num2cell(magic(5)), 3, 3) %# C{3,3}
ans =
13
Just like magic :)
UPDATE:
Bad news, the above hack doesn't work anymore in R2015b! That's fine, it was undocumented functionality and we cannot rely on it as a supported feature :)
For those wondering where to find this type of thing, look in the folder fullfile(matlabroot,'bin','registry'). There's a bunch of XML files there that list all kinds of goodies. Be warned that calling some of these functions directly can easily crash your MATLAB session.
At least in MATLAB 2013a you can use getfield like:
a=rand(5);
getfield(a,{1,2}) % etc
to get the element at (1,2)
unfortunately syntax like magic(5)(3,3) is not supported by matlab. you need to use temporary intermediate variables. you can free up the memory after use, e.g.
tmp = magic(3);
myVar = tmp(3,3);
clear tmp
Note that if you compare running times with the standard way (asign the result and then access entries), they are exactly the same.
subs=#(M,i,j) M(i,j);
>> for nit=1:10;tic;subs(magic(100),1:10,1:10);tlap(nit)=toc;end;mean(tlap)
ans =
0.0103
>> for nit=1:10,tic;M=magic(100); M(1:10,1:10);tlap(nit)=toc;end;mean(tlap)
ans =
0.0101
To my opinion, the bottom line is : MATLAB does not have pointers, you have to live with it.
It could be more simple if you make a new function:
function [ element ] = getElem( matrix, index1, index2 )
element = matrix(index1, index2);
end
and then use it:
value = getElem(magic(5), 3, 3);
Your initial notation is the most concise way to do this:
M = magic(5); %create
value = M(3,3); % extract useful data
clear M; %free memory
If you are doing this in a loop you can just reassign M every time and ignore the clear statement as well.
To complement Amro's answer, you can use feval instead of builtin. There is no difference, really, unless you try to overload the operator function:
BUILTIN(...) is the same as FEVAL(...) except that it will call the
original built-in version of the function even if an overloaded one
exists (for this to work, you must never overload
BUILTIN).
>> feval('_paren', magic(5), 3, 3) % M(3,3)
ans =
13
>> feval('_brace', num2cell(magic(5)), 3, 3) % C{3,3}
ans =
13
What's interesting is that feval seems to be just a tiny bit quicker than builtin (by ~3.5%), at least in Matlab 2013b, which is weird given that feval needs to check if the function is overloaded, unlike builtin:
>> tic; for i=1:1e6, feval('_paren', magic(5), 3, 3); end; toc;
Elapsed time is 49.904117 seconds.
>> tic; for i=1:1e6, builtin('_paren', magic(5), 3, 3); end; toc;
Elapsed time is 51.485339 seconds.
Here's my code, I confuse the local variable 'count' in the return function(c1,c2) with memory strack and where does they store in?
function make_counter()
local count = 0
return function()
count = count + 1
return count
end
end
c1 = make_counter()
c2 = make_counter()
print(c1())--print->1
print(c1())--print->2
print(c1())--print->3
print(c2())--print->1
print(c2())--print->2
in the return function(c1,c2) with memory strack and where does they store in?
It's stored in the closure!
c1 is not a closure, it is the function returned by make_counter(). The closure is not explicitly declared anywhere. It is the combination of the function returned by make_counter() and the "free variables" of that function. See closures # Wikipedia, specifically the implementation:
Closures are typically implemented with a special data structure that contains a pointer to the function code, plus a representation of the function's lexical environment (e.g., the set of available variables and their values) at the time when the closure was created.
I'm not quite sure what you're asking exactly, but I'll try to explain how closures work.
When you do this in Lua:
function() <some Lua code> end
You are creating a value. Values are things like the number 1, the string "string", and so forth.
Values are immutable. For example, the number 1 is always the number 1. It can never be the number two. You can add 1 to 2, but that will give you a new number 3. The same goes for strings. The string "string" is a string and will always be that particular string. You can use Lua functions to take away all 'g' characters in the string, but this will create a new string "strin".
Functions are values, just like the number 1 and the string "string". Values can be stored in variables. You can store the number 1 in multiple variables. You can store the string "string" in multiple variables. And the same goes for all other kinds of values, including functions.
Functions are values, and therefore they are immutable. However, functions can contain values; these values are not immutable. It's much like tables.
The {} syntax creates a Lua table, which is a value. This table is different from every other table, even other empty tables. However, you can put different stuff in tables. This doesn't change the unique value of the table, but it does change what is stored within that table. Each time you execute {}, you get a new, unique table. So if you have the following function:
function CreateTable()
return {}
end
The following will be true:
tableA = CreateTable()
tableB = CreateTable()
if(tableA == tableB) then
print("You will never see this")
else
print("Always printed")
end
Even though both tableA and tableB are empty tables (contain the same thing), they are different tables. They may contain the same stuff, but they are different values.
The same goes for functions. Functions in Lua are often called "closures", particularly if the function has contents. Functions are given contents based on how they use variables. If a function references a local variable that is in scope at the location where that function is created (remember: the syntax function() end creates a function every time you call it), then the function will contain a reference to that local variable.
But local variables go out of scope, while the value of the function may live on (in your case, you return it). Therefore, the function's object, the closure, must contain a reference to that local variable that will cause it to continue existing until the closure itself is discarded.
Where do the values get stored? It doesn't matter; only the closure can access them (though there is a way through the C Lua API, or through the Lua Debug API). So unlike tables, where you can get at anything you want, closures can truly hide data.
Lua Closures can also be used to implement prototype-based classes and objects. Closure classes and objects behave slightly differently than normal Lua classes and their method of invocation is somewhat different:
-- closure class definition
StarShip = {}
function StarShip.new(x,y,z)
self = {}
local dx, dy, dz
local curx, cury, curz
local engine_warpnew
cur_x = x; cur_y = y; cur_z = z
function setDest(x,y,z)
dx = x; dy=y; dz=z;
end
function setSpeed(warp)
engine_warpnew = warp
end
function self.warp(x,y,z,speed)
print("warping to ",x,y,x," at warp ",speed)
setDest(x,y,z)
setSpeed(speed)
end
function self.currlocation()
return {x=cur_x, y=cur_y, z=cur_z}
end
return self
end
enterprise = StarShip.new(1,3,9)
enterprise.warp(0,0,0,10)
loc = enterprise.currlocation()
print(loc.x, loc.y, loc.z)
Produces the following output:
warping to 0 0 0 at warp 10
1 3 9
Here we define a prototype object "StarShip" as an empty table.
Then we create a constructor for the StarShip in the "new" method. The first thing it does is create a closure table called self that contains the object's methods. All methods in the closure (those defined as 'function self.') are "closed" or defined for all values accessible by the constructor. This is why it's called a closure. When the constructor is done it returns the closure object "return self".
A lot more information on closure-based objects is available here:
http://lua-users.org/wiki/ObjectOrientationClosureApproach
We (two people) are doing a project using Lua as an embedded language.
My teammate uses argument type checks almost everywhere:
function someFunction( a, b,c )
if a == nil then return end
--Some stuff here
if type( b ) ~= "function" then
Error( "blah" )
end
--More here
if someTable[ c ] == nil then someTable[ c ] = {}
end
I don't really like that as I think that most of those checks are unneccessary.. it kind of takes the "spirit" of using Lua. It also makes the code longer, slower and less readable in my opinion.
In general I would do it this way:
function someFunction( a, b,c )
--More here
if someTable[ c ] == nil then someTable[ c ] = {}
end
I leave out almost all type/argument checks and only do those who have a high chance of actually happening.
Now we are unsure of what solution is better and decided to ask you: Security checks in Lua - yes or no?
I'm not familiar with Lua, but Wikipedia seems to think it is duck-typed. I'm going to draw an analogy with Python, so forgive me if it's not appropriate.
In Python, functions are designed with the principle that they need an object that meets certain criteria. If you pass in a different object than what the original author intended, as long as it meets the criteria of the function, it should work. The idea being, "if it looks like a duck, walks like a duck, and quacks like a duck, it is a duck." (Hence the name.) That said, there are a few rare instances where you need an object of a specific type, but this is not the general case.
At any rate, you appear to be "fighting the language", which is a code smell in my book. Most languages are designed and intended to be used in certain ways - figure out what principles and design/coding guidelines the Lua community uses, and follow those.
I type check public functions in my api. But do not for only internally used functions.
Good type checking:
function ( a , b )
assert ( type ( a ) == "number" , "Invalid a" )
b = b or {}
assert ( type ( b ) == "table" , "B must be a table" )
c = assert ( type ( c ) == "string" ) and c or "default"
end
Keep in mind though, lua also has a bit of "duck" typing: if all that is required in an object is callable, then a table with a __call method should be allowable. Same for an indexable object: a table and a userdata can both be indexed (not to mention the other types).
I don't know Lua either, and it's a little unclear whether you're asking only about checking the argument types [type(b)~="function"] or do you want to check their values too [a==nil], but here's what I do:
If the function can only ever be called by some other functions of your own, and those other functions have already checked the argument, then there's no need to check it again. On the other hand, if your design doesn't guarantee the safety of your arguments then you do need to check it yourself.
Basically, what can go wrong will go wrong, but it will wait until after you've finished testing and have shipped. You can't take chances - you do need a cast-iron guarantee. The key to choosing your guarantee is to inspect your design and see what you really need.
(Even if the function is only called by your own other functions, you might still want to include checks if you think you might later forget about all this and call it from somewhere else without checking.)
I guess it depends on what you plan to do next: if other people should actually write Lua code to work with your code, it would be useful to check arguments (or make it possible by having something like enableDebug). Something useful I came along yesterday is DecoratorsAndDocstrings which makes it possible to document/typecheck functions without altering the implementation.
Another idiom used for this purpose is :
argument = argument or default -- or
argument = type(argument)=="number" and argument or error'I should get a number'
Now we are unsure of what solution is better and decided to ask you: Security checks in Lua - yes or no?
It depends on the type of the project. If your project is small - i.e. only you and your teammate are going to manage it - it is OK to skip the checks, because you should know that you are passing to functions, and it will make the code small and readable. The downside is that when error occurs - and it may happen somewhere totally unexpected - you'll have to spend time debugging and tracing your functions.
On the other hand, if you are creating an library/API to be used by others, it is very appropriate to do type checking. For the user of your library who doesn't know of the internals, it is very helpful to know when he is passing the wrong arguments.
You need to check types where it is important (and should not check where it is not important). Usually I type-check most of the public function arguments plus I add a check anywhere I encounter a type error when debugging.
To shorten the type checks, I use a small arguments() helper function:
https://github.com/lua-nucleo/lua-nucleo/blob/master/lua-nucleo/args.lua
Example:
https://github.com/lua-aplicado/lua-aplicado/blob/master/lua-aplicado/filesystem.lua#L63-66
local write_file = function(filename, new_data)
arguments(
"string", filename,
"string", new_data
)
local file, err = io.open(filename, "w")
if not file then
return nil, err
end
file:write(new_data)
file:close()
file = nil
return true
end