I've been attempting to follow some iOS Swift tutorials for connecting to Parse.com
codementor.io tutorial:
loginViewController.fields = .UsernameAndPassword | .LogInButton | .PasswordForgotten | .SignUpButton | .Facebook | .Twitter
makeschool tutorial
loginViewController.fields = [.UsernameAndPassword, .LogInButton, .SignUpButton, .PasswordForgotten, .Facebook]
I assume the former is Switch 1.x, and thelatter is Swift 2. From context they appear to be doing the same thing, but I haven't yet found the language references for the change in syntax. Awfully hard to search for dots, pipes and commas... can someone explain the syntax in each snippet? (I'm working on reading through the language specification, but would be fun to actually get an app to work!)
The old Swift 1 syntax is based on the way you deal with option sets in C and Objective-C: you store an option set in an integer type and use bitwise operators (| and & and ~) to manipulate them. So .UsernameAndPassword | .LogInButton means an option set in which both the .UsernameAndPassword and the .LogInButton options are included. In the old syntax, you use nil to represent an empty option set (in which no options are included), which is not obvious based on the syntax for a non-empty set.
Chris Lattner described the changed syntax in WWDC 2015 Session 106: What's New in Swift. First he describes the problems with the old syntax:
The problem is, when you get to the other syntaxes you end up using, it is a bit less nice. You create an empty-option set with nil -- it doesn't make sense because option sets and optionals are completely different concepts and they're conflated together. You extract them with bitwise operations, which is a pain and super error-prone, and you can get it wrong easily.
Then he describes the new approach:
But Swift 2 solves this. It makes option sets set-like. That means option sets and sets are now formed with square brackets. That means you get empty sets with an empty set of square brackets, and you get the full set of standard set API to work with option sets.
The reason the new syntax works is because OptionSetType conforms to the ArrayLiteralConvertible protocol (indirectly, by conforming to SetAlgebraType). This protocol allows a conforming object to be initialized using an array literal, by having an init that takes a list of elements.
In the new Swift 2 syntax, [ .UsernameAndPassword, .LogInButton ] represents an option set containing both the .UsernameAndPassword and the .LogInButton options. Note that it looks just like the syntax by which you can initialize a plain old Set: let intSet: Set<Int> = [ 17, 45 ]. The new syntax makes it obvious that you specify an empty option set as [].
Swift no longer supports the vertical bar operator used your first line. The second is taking the different cases of an enumeration and describing them as an option set. Here's an example from the Swift docs:
enum CompassPoint {
case North
case South
case East
case West
}
directionToHead = .South
switch directionToHead {
case .North:
print("Lots of planets have a north")
case .South:
print("Watch out for penguins")
case .East:
print("Where the sun rises")
case .West:
print("Where the skies are blue")
}
// prints "Watch out for penguins"
Related
I know that we can use
/// index variable
var i = 0
as a documentation comment for a single variable.
How can we do the same for a loop variable?
The following does not work:
var array = [0]
/// index variable
for i in array.indices {
// ...
}
or
var array = [0]
for /** index variable */ i in array.indices {
// ...
}
Background:
The reason why I don’t use "good" variable names is that I’m implementing a numerical algorithm which is derived using mathematical notation. It has in this case only single letter variable names. In order to better see the connection between the derivation and the implementation I use the same variable names.
Now I want to comment on the variables in code.
The use of /// is primarily intended for use of documenting the API of of a class, struct, etc. in Swift.
So if used before a class, func, a var/let in a class/struct, etc. you are attaching documentation to that code aspect that Xcode understands how to show inline. It doesn’t know how to pickup that information for things inside of function since at this time that is not the intention of /// (it may work for simple var/let but not likely fully on purpose).
Instead use a simple // code comment for the benefit of any those working in the code however avoid over documenting the code since good code is likely fairly self explaining to anyone versed in the language and adding unneeded documentations can get in the way of just reading the code.
This is a good reference for code documentation in Swift at this time Swift Documentation
I woud strongly push back on something like this if I saw it in a PR. i is a massively well adopted "term of art" for loop indices. Generally, if your variable declaration name needs to be commented, you need a better variable name. There are some exceptions, such as when it stores data with complicated uses/invariants that can't be captured in a better way in a type system.
I think commenting is one area that beginners get wrong, mainly from being misled by teachers or by not yet fully understanding the purpose of comments. Comments don't exist to create an english based, psuedo-programming language in which your entire app will be duplicated. Understanding the programming language is a minimal expectation out of contributors to a project. Absolutely no comments should be explaining programming language features. E.g. var x: Int = 0 // declares a new mutable variable called x, to the Int value 0, with the exception of tutorials for learning Swift.
Commenting in this manner might seem like it's helpful, because you could argue it explains things for beginners. That may be the case, but it's suffocating for all other readers. Imagine if novel had to define all the English words they used.
Instead, the goal of documentation to explain the purpose and the use of things. To answer such questions as:
Why did you implement something this way, and not another way?
What purpose does this method serve?
When will this method of my delegate be called?
Case Study: Equatable
For a good example, take a look at the documentation of Equatable
Some things to notice:
It's written for an audience of Swift developers. It uses many things, which it does not explain such as, arrays, strings, constants, variable declaration, assignment, if statements, method calls (such as Array.contains(_:)), string interpolation, the print function.
It explains the general purpose of this protocol.
It explains how to use this protocol
It explains how you can adopt this protocol for your own use
It documents contractual requirements that cannot be enforced by the type system.
Since equality between instances of Equatable types is an equivalence relation, any of your custom types that conform to Equatable must satisfy three conditions, for any values a, b, and c:
a == a is always true (Reflexivity)
a == b implies b == a (Symmetry)
a == b and b == c implies a == c (Transitivity)
It explains possible misconceptions about the protocol ("Equality is Separate From Identity")
In Swift 2.1, I am trying to use reflection in order to add cases generated from a text file to an enum at compile time.
Here is the enum wrapper:
enum Kind : Int {
}
Using C/++ I could just use this macro:
#define X(value, left, right) \
value##Left = left, value##Right = right,
How can I get similar result in Swift?
Preprocessor directives are deliberately cut down to a very bare minimum in Swift. Even if technically possible, your particular case would go quite against Swift philosophy in respect of enums, as this philosopy requires that switch statements on enumerations are exhaustive, that is, cover all possible cases.
Now, if you would be able to dynamically fill up the enum's cases from some file, then how would compiler be able to ensure exhaustiveness? Opting out to use default: cases all over the program would basically throw the whole Swift's idea of enum safety right into the window.
If you stick with Swift then you are probably better off with dictionary as #RMenke suggests.
What's the difference between these 3:
struct A {
let myVal: Array<Char>
let myVal2: [char]
let myVal3: Array<CChar>
}
Which one is more common or recommended to be used?
There is no difference between Array<Thing> and [Thing]; the latter is syntactic sugar for the former.
Hence the only difference between your three declarations is the difference between the three element types: Char (whatever that is), char (whatever that is - a type name starting with a small letter is really bad practice in Swift, though), and CChar (that's the only one I've ever heard of). The recommended one of those three is: whatever it is you want an array of.
CChar is Swift equivalent of C Primitive type - It is recommended to use Swift data type where it is possibl.- Apple Documentation
The recommended usage as per this style guide is the shortcut version
myValue: [CChar]
Hope this helps
I'm beginning to teach myself swift and I'm going through examples of games at the moment. I've run across a line of code that I thought was peculiar
scene.scaleMode = .ResizeFill
In languages I'm used to (C / Java) the "." notation is used to reference some sort of structure/ object but I'm not exactly sure what this line of code does as there is no specified object explicitly before the "."
Information regarding clarification of this non-specified "." reference, or when/ how it can be used, would be great
P.S. I'm using sprite kit in Xcode
In Swift, as in the other languages you mentioned, '.' is a member access operator. The syntax you are referring to is a piece of shorthand that Swift allows because it is a type-safe language.
The compiler recognises that the property you are assigning to is of type SKSceneScaleMode and so the value you are assigning must be one of that type's enumerated values - so the enumeration name can be omitted.
To add to PaulW11's answer, what's happening here is only valid syntax for enums, and won't work with any other type (class, struct, method, function). Swift knows the type of the property that you are assigning to is an enum of type SKSceneScaleMode, so lets you refer to the enum member without having to explicitly give the type of the enum (ie SKSceneScaleMode.ResizeFill).
There are some situations where there will be ambiguity, and you will have to give the full name, this will be dependant on the context. For example, you may have two different enum types in scope, that both have a matching member name.
EDIT
Updating this answers as I incorrectly specified this was only applicable to enums, which is not true. There is a good blog post here which explains in more detail
http://ericasadun.com/2015/04/21/swift-occams-code-razor/
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.