Swift for in loop with parentheses - swift

I normally use the for in loop in swift without parentheses, but today I put them on just for kicks thinking they were just optional and it did not worked as expected.
This code works:
if let tasks = getAllTasksWithManagedObjectContext(appDelegate.managedObjectContext){
for task in tasks{
appDelegate.managedObjectContext.deleteObject(task)
}
}
This one does not:
if let tasks = getAllTasksWithManagedObjectContext(appDelegate.managedObjectContext){
for (task in tasks){
appDelegate.managedObjectContext.deleteObject(task)
}
}
I get this errors:
Whats going on here?

You are simply not allowed to use parentheses here.
Take a look at the Language Reference -> Statements and compare the C-style for-loop against the swift for-in
for-statement → for­ for-init­;­expression­;­expression­ ­code-block
for-statement → for­ (for-init­;­expression­;­expression­) ­code-block
vs.
for-in-statement → for ­case(opt) ­pattern ­in ­expression ­where-clause­(opt­) code-block
The first one can be used with or without parentheses - your choice as the developer.
However the later one, the one you are actually asking about does not have a version with ( and ), only the one version without them. That means that it is not allowed to use them parentheses around the "argument" of the loop.
Screenshots from the docs linked above for better readability:
vs.

Related

Is there any technical benefit in adding semicolons in Swift?

I wrote couple of programs in Objective-C.
I've seen that Swift syntax does not require use of semicolons.
My question is - is there any technical point in using them anyway?
The short answer is: No.
Swift does not require a semicolon after each statement in your code. They are only required if you wish to combine multiple statements on a single line.
Do not write multiple statements on a single line separated with semicolons.
Preferred:
var swift = "not a scripting language"
Not Preferred:
var swift = "not a scripting language";
For more informations, please refer to this page:
https://github.com/raywenderlich/swift-style-guide#semicolons
There are (or used to be) situations where two separate statements on two different lines would taken by the compiler as a single statement. The typical locus is return followed by another statement that you don't want executed. In that situation, and in that situation alone, the semicolon is crucial.
override func viewDidLoad() {
super.viewDidLoad()
return // need semicolon here
print(1) // oops
}
However, in modern Swift the compiler warns and compensates. Adding a semicolon (return;) quiets the warning (though it then causes a different warning).
Otherwise, a semicolon never has any technical benefit.
Yes there is, you can write multiple statements in one line. For example you could write statements more compact when needed, for example:
var progress: Progress {
get { _progress.value }
set { _progress.value = newValue; parent?.update() }
}
Use sparingly though. But in this specific case I prefer it instead of expanding everything to a separate line since its still quite readable and only 2 statements.

Swift - how to create custom operators to use in other modules?

I created a sample project and a framework next to it. The framework is called "SampleFramework". Then I created a custom operator in SampleFramework. Here is what it looks like:
infix operator >>= {associativity left}
public func >>=<A, B>(a: A?, f: A -> B?) -> B? {
if let a = a { return f(a) }
else { return .None }
}
Then I wanted to use it my main application. I imported the SampleFramework to my source file and then I wrote this code to test it:
NSURL(string: "www.google.com") >>= { println("\($0)") }
It didn't compile. Here is Xcode's error message:
Ambiguous operator declarations found for operator. Operator is not a
known binary operator
I can confirm that that what you are seeing is what really happens. I just tried it myself and I've seen the same result.
My opinion is that >>= is somehow conflicting with some other operator (probably the bite shift operator: >>) or is being declared somewhere else too (you can see why I think that here). I did successfully declared custom operators in a framework and used those in the main app code before (you can see that here for example).
What I would suggest is rename your custom operator to something else. When I did that (renamed the custom operator to >>>=) the compiler stopped complaining and my app compiled just fine.
Later edit
Ok. So this might help a bit more. Basically when an operator is already declared and you want to add extra functionality to that operator (for example doing things like 3 * "Hello" like Johan Kool said he wanted to) all you have to do is overload that operator's method.
Basically, in your specific case I am now 100% that >>= is an already declared operator and you can go ahead and just add these lines in your framework:
public func >>=<A, B>(a: A?, f: A -> B?) -> B? {
if let a = a { return f(a) }
else { return .None }
}
This will make your operator work. BUT it will inherit the precedence and associativity of the original operator thus giving you less control over how it's supposed to behave.
I figured it out. I think declaration of operator (infix operator >>= {associativity left}) is module specific. You can't apply access control to it. But the operator function can be accessed in other modules. So in order to make this work I had to copy operator declaration and paste it to main project.
It seems to be sufficient to just add the
infix operator + : Additive
in each source where you want to apply your framework-defined operator, assuming that your framework has some
public func + (lhs: ...
declared.
Anyhow, it's nasty to have the need for adding this if you use a framework and I'd like to see some way to have some global approach where importing a framework also makes available the operators automatically.
Edit After fiddling around for hours, the problem went away. I have not figured out what's the cause. I had lots of infix declarations in my basic framework (for historic reason). Once I got rid of them, everything went to normal. So now that I have only infix for the new operators, it's fine. But obviously re-declaring existing ones (like *, +, etc.) Swift seems to get hick-ups.

Purpose of (^) sign in iOS

I have seen in many iOS header's that (^) is utilized, and I have never come across the reasoning as of why that sign is being used. Would anyone might like to enlighten into this?
Thanks.
Those often indicate "blocks". See the Blocks Programming Topics.
Alternatively, if you watch the beginning of WWDC 2012 session 712, they also walk you through blocks with a touch of historical context.
It signifies a block. A block is a syntax that allows you to create a callback function, and pass it into a method as a parameter. In other languages this is similar to a closure, a lambda, or an anonymous class.
For example a parameter that lists:
void(^)(NSString *myStr)
is expecting you to pass in a block/function that returns void, and takes in an NSString pointer.
You can create a block, based on the expected parameters declared in the method, with this syntax:
^(<Parameters>) { <Body> }
For example, a method that is expecting a block parameter might look like this:
-(void)doSomething:(void(^)(NSString *myStr))theBlock;
...and could be called like this:
[self doSomething:^(NSString *myStr) { NSLog(#"The String is: %#", myStr); }];
Your block will be called back from doSomething: just like a function, using the parameter name:
-(void)doSomething:(void(^)(NSString *myStr))theBlock {
theBlock(#"Hello!");
}
...which would display:
The String is: Hello!
The ^ character is used for blocks, in particular, block parameters.
If you're asking why the character '^' for use in blocks, it's because there's relatively few characters left that:
Are available on all typical keyboards.
Could be used at all - i.e. aren't already significant in the language and would conflict.
Don't look stupid.
That actually narrows it down to only two or three, and of those '^' was chosen because, well, because.
There's probably a record of this on the llvm.org mailing lists and so forth, if you want to pore over the discussion in detail.
You could also look at the minutes from the C++11 committee meetings on lambdas, which went through basically the same process.

Methods of simplifying ugly nested if-else trees in C#

Sometimes I'm writing ugly if-else statements in C# 3.5; I'm aware of some different approaches to simplifying that with table-driven development, class hierarchy, anonimous methods and some more.
The problem is that alternatives are still less wide-spread than writing traditional ugly if-else statements because there is no convention for that.
What depth of nested if-else is normal for C# 3.5? What methods do you expect to see instead of nested if-else the first? the second?
if i have ten input parameters with 3 states in each, i should map functions to combination of each state of each parameter (really less, because not all the states are valid, but sometimes still a lot). I can express these states as a hashtable key and a handler (lambda) which will be called if key matches.
It is still mix of table-driven, data-driven dev. ideas and pattern matching.
what i'm looking for is extending for C# such approaches as this for scripting (C# 3.5 is rather like scripting)
http://blogs.msdn.com/ericlippert/archive/2004/02/24/79292.aspx
Good question. "Conditional Complexity" is a code smell. Polymorphism is your friend.
Conditional logic is innocent in its infancy, when it’s simple to understand and contained within a
few lines of code. Unfortunately, it rarely ages well. You implement several new features and
suddenly your conditional logic becomes complicated and expansive. [Joshua Kerevsky: Refactoring to Patterns]
One of the simplest things you can do to avoid nested if blocks is to learn to use Guard Clauses.
double getPayAmount() {
if (_isDead) return deadAmount();
if (_isSeparated) return separatedAmount();
if (_isRetired) return retiredAmount();
return normalPayAmount();
};
The other thing I have found simplifies things pretty well, and which makes your code self-documenting, is Consolidating conditionals.
double disabilityAmount() {
if (isNotEligableForDisability()) return 0;
// compute the disability amount
Other valuable refactoring techniques associated with conditional expressions include Decompose Conditional, Replace Conditional with Visitor, Specification Pattern, and Reverse Conditional.
There are very old "formalisms" for trying to encapsulate extremely complex expressions that evaluate many possibly independent variables, for example, "decision tables" :
http://en.wikipedia.org/wiki/Decision_table
But, I'll join in the choir here to second the ideas mentioned of judicious use of the ternary operator if possible, identifying the most unlikely conditions which if met allow you to terminate the rest of the evaluation by excluding them first, and add ... the reverse of that ... trying to factor out the most probable conditions and states that can allow you to proceed without testing of the "fringe" cases.
The suggestion by Miriam (above) is fascinating, even elegant, as "conceptual art;" and I am actually going to try it out, trying to "bracket" my suspicion that it will lead to code that is harder to maintain.
My pragmatic side says there is no "one size fits all" answer here in the absence of a pretty specific code example, and complete description of the conditions and their interactions.
I'm a fan of "flag setting" : meaning anytime my application goes into some less common "mode" or "state" I set a boolean flag (which might even be static for the class) : for me that simplifies writing complex if/then else evaluations later on.
best, Bill
Simple. Take the body of the if and make a method out of it.
This works because most if statements are of the form:
if (condition):
action()
In other cases, more specifically :
if (condition1):
if (condition2):
action()
simplify to:
if (condition1 && condition2):
action()
I'm a big fan of the ternary operator which get's overlooked by a lot of people. It's great for assigning values to variables based on conditions. like this
foobarString = (foo == bar) ? "foo equals bar" : "foo does not equal bar";
Try this article for more info.
It wont solve all your problems, but it is very economical.
I know that this is not the answer you are looking for, but without context your questions is very hard to answer. The problem is that the way to refactor such a thing really depends on your code, what it is doing, and what you are trying to accomplish. If you had said that you were checking the type of an object in these conditionals we could throw out an answer like 'use polymorphism', but sometimes you actually do just need some if statements, and sometimes those statements can be refactored into something more simple. Without a code sample it is hard to say which category you are in.
I was told years ago by an instructor that 3 is a magic number. And as he applied it it-else statements he suggested that if I needed more that 3 if's then I should probably use a case statement instead.
switch (testValue)
{
case = 1:
// do something
break;
case = 2:
// do something else
break;
case = 3:
// do something more
break;
case = 4
// do what?
break;
default:
throw new Exception("I didn't do anything");
}
If you're nesting if statements more than 3 deep then you should probably take that as a sign that there is a better way. Probably like Avirdlg suggested, separating the nested if statements into 1 or more methods. If you feel you are absolutely stuck with multiple if-else statements then I would wrap all the if-else statements into a single method so it didn't ugly up other code.
If the entire purpose is to assign a different value to some variable based upon the state of various conditionals, I use a ternery operator.
If the If Else clauses are performing separate chunks of functionality. and the conditions are complex, simplify by creating temporary boolean variables to hold the true/false value of the complex boolean expressions. These variables should be suitably named to represent the business sense of what the complex expression is calculating. Then use the boolean variables in the If else synatx instead of the complex boolean expressions.
One thing I find myself doing at times is inverting the condition followed by return; several such tests in a row can help reduce nesting of if and else.
Not a C# answer, but you probably would like pattern matching. With pattern matching, you can take several inputs, and do simultaneous matches on all of them. For example (F#):
let x=
match cond1, cond2, name with
| _, _, "Bob" -> 9000 // Bob gets 9000, regardless of cond1 or 2
| false, false, _ -> 0
| true, false, _ -> 1
| false, true, _ -> 2
| true, true, "" -> 0 // Both conds but no name gets 0
| true, true, _ -> 3 // Cond1&2 give 3
You can express any combination to create a match (this just scratches the surface). However, C# doesn't support this, and I doubt it will any time soon. Meanwhile, there are some attempts to try this in C#, such as here: http://codebetter.com/blogs/matthew.podwysocki/archive/2008/09/16/functional-c-pattern-matching.aspx. Google can turn up many more; perhaps one will suit you.
try to use patterns like strategy or command
In simple cases you should be able to get around with basic functional decomposition. For more complex scenarios I used Specification Pattern with great success.

What'S the difference between these two initialization snippets? Which one is correct?

While looking through some code, I found two different code snippets for initialization. I don't mean the method names, but the round brackets.
This one has just two of them:
if (self = [super initWithFrame:frame]) {
That's the way I do it all the time, and it seems to work. Now in an Apple example I found this:
if ((self = [super init])) {
Do I have to put it twice into round brackets here? Or is it just fine to put it in one pair of brackets, like the first example?
One pair of brackets is just fine
I call them "paranoia brackets" :)
EDIT: some C/C++ compilers will issue a warning because of the use of the assignment operator (it will say something like "did you mean ==" ?). Using extra parentheses prevents this warning. But XCode doesn't show this kind of warning, so there's no need to do that.
In some languages, if( foo = bar ) implies that the assignment was correctly applied. So the calls:
if( ( foo = bar ) )
would evaluate the assignment and return the result as the outer () act as a LHS, ie,
blah = foo = bar
the outer () act sort of like blah.
In ANSI C and it's children C++ and Objective-C this isn't strictly necessary. However as has been mentioned some compilers will issue a warning since the "=" / "==" type-o can be a nasty one. That type-o led to the idiom of putting the invariant or constant at the left hand side to cause compile time catching of the problem:
if( nil == foo )
if both sides are variables though it's still possibly a mistake.
There is a good reason for doing this even though gcc isn't warning you or evaluating things differently.
If you are writing code in a team environment your peers may not be sure you meant "=" or just mistyped "==", causing them to peer more closely at what you're doing even though there's no need to. In the style of "write once to be read 1000 times" you put in clues to prevent people from having to waste time when reading your code. For instance, use clear and spelled out variable names (no economy on bytes these days!). Don't use obtuse and overly optimized constructs in areas that aren't drags on performance - write your code cleanly.
In this case, use (( )) to indicate you knew it was "=" not "==".
Don't forget, Apple is writing their examples for not just a dozen people to read, but potentially every man, woman, and child on earth to read now and in the future. Clarity is of upmost importance.
Looks like a cut and paste error to me! (Or a lover of Lisp.) There is no good reason to have the second pair of brackets but, as you note, it's not actually harmful.
If I've got this right the first one checks that the assignment self = [super initWithFrame:frame] happens and the second one checks that the result of that assignment is true
But this could just be a lack of tea speaking...