(Beginner's question) After observing a few coding examples (from various sources) and syntax suggestions by Cargo Clippy, I'm still wondering whether the following blocks are just two alternatives for the same result, or actually do something different(ly) which I must be aware of.
fn main() {
let string_1 = "Hello!";
let string_2 = "See you!";
println!("{} {}", string_1, string_2);
}
Or...
fn main() {
let string_1 = "Hello!";
let string_2 = "See you!";
println!("{string_1} {string_2}");
}
If I use the first syntax, Cargo Clippy suggests me to use the second one instead. But, if I write println!("{} {}", &string_1, &string_2);, Clippy no longer complains, so I guess the difference between both coding blocks has to do with Rust's unique concept of "ownership".
So, am I missing something?
They are the same (but the second is newer, being stabilized in Rust 1.58.0, and more recommended for new code).
The reason Clippy does not suggest the second form anymore when you take reference is because it is invalid: only identifiers (bare variable names) can be used with inline captures.
I've recently decided to learn Elixir. Coming from a C++/Java/JavaScript background I've been having a lot of trouble grasping the basics. This might sound stupid but how would return statements work in Elixir? I've looked around and it seems as though it's just the last line of a function i.e.
def Hello do
"Hello World!"
end
Would this function return "Hello World!", is there another way to do a return? Also, how would you return early? in JavaScript we could write something like this to find if an array has a certain value in it:
function foo(a){
for(var i = 0;i<a.length;i++){
if(a[i] == "22"){
return true;
}
}
return false;
}
How would that work in Elixir?
Elixir has no 'break out' keyword that would be equivalent to the 'return' keyword in other languages.
Typically what you would do is re-structure your code so the last statement executed is the return value.
Below is an idiomatic way in elixir to perform the equivalent of your code test, assuming you meant 'a' as something that behaves kind of array like in your initial example:
def is_there_a_22(a) do
Enum.any?(a, fn(item) -> item == "22" end.)
end
What's actually going on here is we're restructuring our thinking a little bit. Instead of the procedural approach, where we'd search through the array and return early if we find what we were looking for, we're going to ask what you are really after in the code snippet:
"Does this array have a 22 anywhere?"
We are then going to use the elixir Enum library to run through the array for us, and provide the any? function with a test which will tell us if anything matches the criteria we cared about.
While this is a case that is easily solved with enumeration, I think it's possible the heart of your question applies more to things such as the 'bouncer pattern' used in procedural methods. For example, if I meet certain criteria in a method, return right away. A good example of this would be a method that returns false if the thing you're going to do work on is null:
function is_my_property_true(obj) {
if (obj == null) {
return false;
}
// .....lots of code....
return some_result_from_obj;
}
The only way to really accomplish this in elixir is to put the guard up front and factor out a method:
def test_property_val_from_obj(obj) do
# ...a bunch of code about to get the property
# want and see if it is true
end
def is_my_property_true(obj) do
case obj do
nil -> false
_ -> test_property_value_from_obj(obj)
end
end
tl;dr - No there isn't an equivalent - you need to structure your code accordingly. On the flip side, this tends to keep your methods small - and your intent clear.
You are correct in that last expression is always returned. Even more - there are no statements in the language - just expressions. Every construct has a value - if, case, etc. There is also no early return. This may seem limiting, but you quickly get used to it.
A normal way to solve your example with Elixir would be to use a higher order function:
def foo(list) do
Enum.any?(list, fn x -> x == "22" end)
end
I have scala REST service based on JSON and Play Framework. Some of the fields of the JSON are optional (e.g. middleName). I can mark it Option e.g.
middleName: Option[String]
and even don't expect it in JSON. But I would like to avoid possible app errors in the future and simplify life. I would like to mark it as expectable but empty if user don't want to provide this info and have no Option fields throughout entire application (JSON/DB overhead is minor).
Is it good idea to avoid Option fields throughout the application? If the String field is empty, it contains an empty string but manadatory present in JSON/DB. If the Int field is empty it contains 0 etc
Thanks in advance
I think you would regret avoiding Option because of the loss of type safety. If you go passing around potentially null object references, everyone who touches them has to remember to check for null because there is nothing that forces them to do so. Failure to remember is a NullPointerException waiting to happen. The use of Option forces code to deal with the possibility that there is no value to work with; forgetting to do so will cause a compilation error:
case class Foo(name: Option[String])
...
if (foo1.name startsWith "/") // ERROR: no startsWith on Option
I very occasionally do use nulls in a very localized bit of code where I think either performance is critical or I have many, many objects and don't want to have all of those Some and None objects taking up memory, but I would never leak the null out across a public API. Using nulls is a complicating optimization that should only be used where the extra vigilance required to avoid catastrophe is justified by the benefit. Such cases are rare.
I am not entirely sure I understand what your needs are with regard to JSON, but it sounds like you might like to have Option fields not disappear from JSON documents. In Spray-json there is a NullOptions trait specifically for this. You simply mix it into your protocol type and it affects all of the JsonFormats defined within (you can have other protocol types that do "not" mix it in if you like), e.g.
trait FooJsonProtocol extends DefaultJsonProtocol with NullOptions {
// your jsonFormats
}
Without NullOptions, Option members with value None are omitted altogether; with it, they appear with null values. I think that it is clearer for users if you show the optional fields with null values rather than having them disappear, but for transmission efficiency you might want them omitted. With Spray-json, at least, you can pick.
I don't know whether other JSON packages have a similar option, but perhaps that will help you look for it if for some reason you don't want to use Spray-json (which, by the way, is very fast now).
I think that would depend on your business logic and how you want to use these values.
In the case of the middleName I am assuming you are using it primarily to address the user in a personal manner and you just concatenate title, firstName, middleName and lastName. So you treat the value exactly the same whether the user has specified it or not. So I think using an empty String instead of None might be preferable.
In the case of values where 0 or the "" is a valid value in terms of your business logic I would go with the Option[String], also in cases where you have different behaviours depending on whether the value is specified or not.
x match {
case 0 => foo
case _ => bar(_)
}
is less descriptive than
x match {
case Some(i) => bar(i)
case None => foo
}
It's a bad idea, because normally you want to handle the absence of something differently. If you pass a value of "" or 0 around, this can very easily be confused with a real value; you might end up sending an email that starts "Dear Mr ," or wishing them Happy 35th Birthday because the timestamp 0 comes out as 1st January 1970. If you keep a distinction between a value and None in code and in the type system, this forces you to think about whether a value is actually set and what you want to do if it isn't.
Don't blindly just push Options everywhere though, either. If it's an error for a value to not be supplied, you should check that immediately and throw an error as soon as possible, not wait until much later in your application when it will be harder to debug where that None came from.
It won't make your "life easier". If anything, it will make it harder, and instead of avoiding app errors will make them more likely. Your app code will have to be infested with checks like if(middleName != "") { doSomething(middleName); } or if(age == 0) "Unknown age" else age.toString, and you will have to rely on the programmer remembering to handle those "kinda-optional" fields in a special way.
All of this you could get "for free" using the monadic properties of Option with middleName.foreach(doSomething) or age.map(_.toString).getOrElse("")
Is it possible o add custom behavior to copy function in case classes?
Something like this:
case class User (version: Integer) { //other fields are omitted
//something like this
override def copy (...) {
return copy(version = version + 1, ...)
}
}
So I do not want to rewrite copy function, just add increasing version field and copy others. How can I do that?
Adding behavior to fundamental functions such as copy is not a good idea. The functional approach is to let data be just data, and to have the behavior in the functions that operate on the data from outside.
But if you really want to do it, you will just have to re-implement the copy method, like this:
case class User(name:String, age:Int, version:Int = 0) {
def copy(name:String = this.name, age:Int = this.age) = User(name,age,version+1)
}
Usage:
scala> User("John Doe", 25).copy(age = 26)
res4: User = User(John Doe,26,1)
But note that you will probably have to re-implement some other methods as well for useful behavior. For example, you might not want people to be able to pass a version when constructing a user. So you need to make the constructor private and add an apply method.
You also might not want the version field to be considered for equality. So you have to redefine equals and hashCode to omit the version field. So since you have redefined almost everything that a case class gives you, you might as well make the class a normal non-case class.
In general, I think case classes should be used for pure data, while more object oriented classes that mix data and logic are best done as normal classes, even if it means a bit more typing.
This question is motivated by something I've lately started to see a bit too often, the if..else if..else structure. While it's simple and has its uses, something about it keeps telling me again and again that it could be substituted with something that's more fine-grained, elegant and just generally easier to keep up-to-date.
To be as specific as possible, this is what I mean:
if (i == 1) {
doOne();
} else if (i == 2) {
doTwo();
} else if (i == 3) {
doThree();
} else {
doNone();
}
I can think of two simple ways to rewrite that, either by ternary (which is just another way of writing the same structure):
(i == 1) ? doOne() :
(i == 2) ? doTwo() :
(i == 3) ? doThree() : doNone();
or using Map (in Java and I think in C# too) or Dictionary or any other K/V structure like this:
public interface IFunctor() {
void call();
}
public class OneFunctor implemets IFunctor() {
void call() {
ref.doOne();
}
}
/* etc. */
Map<Integer, IFunctor> methods = new HashMap<Integer, IFunctor>();
methods.put(1, new OneFunctor());
methods.put(2, new TwoFunctor());
methods.put(3, new ThreeFunctor());
/* .. */
(methods.get(i) != null) ? methods.get(i).call() : doNone();
In fact the Map method above is what I ended up doing last time but now I can't stop thinking that there has to be better alternatives in general for this exact issue.
So, which other -and most likely better- ways to replace the if..else if..else are out there and which one is your favorite?
Your thoughts below this line!
Okay, here are your thoughts:
First, most popular answer was switch statement, like so:
switch (i) {
case 1: doOne(); break;
case 2: doTwo(); break;
case 3: doThree(); break;
default: doNone(); break;
}
That only works for values which can be used in switches, which at least in Java is quite a limiting a factor. Acceptable for simple cases though, naturally.
The other and perhaps a bit fancier way you seem to sugges is to do it using polymorphism. The Youtube lecture linked by CMS is an excellent watch, go see it here: "The Clean Code Talks -- Inheritance, Polymorphism, & Testing" As far as I understood, this would translate to something like this:
public interface Doer {
void do();
}
public class OneDoer implements Doer {
public void do() {
doOne();
}
}
/* etc. */
/* some method of dependency injection like Factory: */
public class DoerFactory() {
public static Doer getDoer(int i) {
switch (i) {
case 1: return new OneDoer();
case 2: return new TwoDoer();
case 3: return new ThreeDoer();
default: return new NoneDoer();
}
}
}
/* in actual code */
Doer operation = DoerFactory.getDoer(i);
operation.do();
Two interesting points from the Google talk:
Use Null Objects instead of returning nulls (and please throw only Runtime Exceptions)
Try to write a small project without if:s.
Also in addition one post worth mentioning in my opinion is CDR who provided his perverse habits with us and while not recommended to use, it's just very interesting to look at.
Thank you all for the answers (so far), I think I might have learned something today!
These constructs can often be replaced by polymorphism. This will give you shorter and less brittle code.
In Object Oriented languages, it's common to use polymorphism to replace if's.
I liked this Google Clean Code Talk that covers the subject:
The Clean Code Talks -- Inheritance, Polymorphism, & Testing
ABSTRACT
Is your code full of if statements?
Switch statements? Do you have the
same switch statement in various
places? When you make changes do you
find yourself making the same change
to the same if/switch in several
places? Did you ever forget one?
This talk will discuss approaches to
using Object Oriented techniques to
remove many of those conditionals. The
result is cleaner, tighter, better
designed code that's easier to test,
understand and maintain.
A switch statement:
switch(i)
{
case 1:
doOne();
break;
case 2:
doTwo();
break;
case 3:
doThree();
break;
default:
doNone();
break;
}
Depending on the type of thing you are if..else'ing, consider creating a hierarchy of objects and using polymorphism. Like so:
class iBase
{
virtual void Foo() = 0;
};
class SpecialCase1 : public iBase
{
void Foo () {do your magic here}
};
class SpecialCase2 : public iBase
{
void Foo () {do other magic here}
};
Then in your code just call p->Foo() and the right thing will happen.
There's two parts to that question.
How to dispatch based on a value? Use a switch statement. It displays your intent most clearly.
When to dispatch based on a value? Only at one place per value: create a polymorphic object that knows how to provide the expected behavior for the value.
The switch statement of course, much prettier then all those if's and else's.
Outside of using a switch statement, which can be faster, none. If Else is clear and easy to read. having to look things up in a map obfuscates things. Why make code harder to read?
switch (i) {
case 1: doOne(); break;
case 2: doTwo(); break;
case 3: doThree(); break;
default: doNone(); break;
}
Having typed this, I must say that there is not that much wrong with your if statement. Like Einstein said: "Make it as simple as possible, but no simpler".
I use the following short hand just for fun! Don't try anyof these if code clearity concerns you more than the number of chars typed.
For cases where doX() always returns true.
i==1 && doOne() || i==2 && doTwo() || i==3 && doThree()
Ofcourse I try to ensure most void functions return 1 simply to ensure that these short hands are possible.
You can also provide assignments.
i==1 && (ret=1) || i==2 && (ret=2) || i==3 && (ret=3)
Like instad of writting
if(a==2 && b==3 && c==4){
doSomething();
else{
doOtherThings();
}
Write
a==2 && b==3 && c==4 && doSomething() || doOtherThings();
And in cases, where not sure what the function will return, add an ||1 :-)
a==2 && b==3 && c==4 && (doSomething()||1) || doOtherThings();
I still find it faster to type than using all those if-else and it sure scares all new noobs out. Imagine a full page of statement like this with 5 levels of indenting.
"if" is rare in some of my codes and I have given it the name "if-less programming" :-)
In this simple case you could use a switch.
Otherwise a table-based approach looks fine, it would be my second choice whenever the conditions are regular enough to make it applicable, especially when the number of cases is large.
Polymorphism would be an option if there are not too many cases, and conditions and behaviour are irregular.
The example given in the question is trivial enough to work with a simple switch. The problem comes when the if-elses are nested deeper and deeper. They are no longer "clear or easy to read," (as someone else argued) and adding new code or fixing bugs in them becomes more and more difficult and harder to be sure about because you might not end up where you expected if the logic is complex.
I've seen this happen lots of times (switches nested 4 levels deep and hundreds of lines long--impossible to maintain), especially inside of factory classes that are trying to do too much for too many different unrelated types.
If the values you're comparing against are not meaningless integers, but some kind of unique identifier (i.e. using enums as a poor man's polymorphism), then you want to use classes to solve the problem. If they really are just numeric values, then I would rather use separate functions to replace the contents of the if and else blocks, and not design some kind of artificial class hierarchy to represent them. In the end that can result in messier code than the original spaghetti.
Use a switch/case it's cleaner :p
switch statement or classes with virtual functions as fancy solution. Or array of pointers to functions. It's all depends on how complex conditions are, sometimes there's no way around those if's. And again, creating series of classes to avoid one switch statement is clearly wrong, code should be as simple as possible (but not simpler)
I would go so far as to say that no program should ever use else. If you do you are asking for trouble. You should never assume if it's not an X it must be a Y. Your tests should test for each individually and fail following such tests.
In OO paradigm you could do it using good old polymorphism. Too big if - else structures or switch constructs are sometimes considered a smell in the code.
The Map method is about the best there is. It lets you encapsulate the statements and breaks things up quite nicely. Polymorphism can complement it, but its goals are slightly different. It also introduces unnecessary class trees.
Switches have the drawback of missing break statements and fall through, and really encourage not breaking the problem into smaller pieces.
That being said: A small tree of if..else's is fine (in fact, i argued in favor for days about have 3 if..elses instead of using Map recently). Its when you start to put more complicated logic in them that it becomes a problem due to maintainability and readability.
In python, I would write your code as:
actions = {
1: doOne,
2: doTwo,
3: doThree,
}
actions[i]()
I regard these if-elseif-... constructs as "keyword noise". While it may be clear what it does, it is lacking in conciseness; I regard conciseness as an important part of readability. Most languages provide something like a switch statement. Building a map is a way to get something similar in languages that do not have such, but it certainly feels like a workaround, and there is a bit of overhead (a switch statement translates to some simple compare operations and conditional jumps, but a map first is built in memory, then queried and only then the compare and jump takes place).
In Common Lisp, there are two switch constructs built in, cond and case. cond allows arbitrary conditionals, while case only tests for equality, but is more concise.
(cond ((= i 1)
(do-one))
((= i 2)
(do-two))
((= i 3)
(do-three))
(t
(do-none)))
(case i
(1 (do-one))
(2 (do-two))
(3 (do-three))
(otherwise (do-none)))
Of course, you could make your own case-like macro for your needs.
In Perl, you can use the for statement, optionally with an arbitrary label (here: SWITCH):
SWITCH: for ($i) {
/1/ && do { do_one; last SWITCH; };
/2/ && do { do_two; last SWITCH; };
/3/ && do { do_three; last SWITCH; };
do_none; };
Use a Ternary Operator!
Ternary Operator(53Characters):
i===1?doOne():i===2?doTwo():i===3?doThree():doNone();
If(108Characters):
if (i === 1) {
doOne();
} else if (i === 2) {
doTwo();
} else if (i === 3) {
doThree();
} else {
doNone();
}
Switch((EVEN LONGER THAN IF!?!?)114Characters):
switch (i) {
case 1: doOne(); break;
case 2: doTwo(); break;
case 3: doThree(); break;
default: doNone(); break;
}
this is all you need! it is only one line and it is pretty neat, way shorter than switch and if!
Naturally, this question is language-dependent, but a switch statement might be a better option in many cases. A good C or C++ compiler will be able to generate a jump table, which will be significantly faster for large sets of cases.
If you really must have a bunch of if tests and want to do different things whenwver a test is true I would recommend a while loop with only ifs- no else. Each if does a test an calls a method then breaks out of the loop. No else there's nothing worse than a bunch of stacked if/else/if/else etc.