Variable And Function Calls On Lines By Themselves In Swift - swift

I'm reading the iBook The Swift Programming Language and seeing a convention that I don't understand and hasn't been explained in the book: variable and functions followed by a single line with the variable or function name by itself.
For example:
var n = 2
while n < 100 {
n = n * 2
}
n
var m = 2
do {
m = m * 2
} while m < 100
m
And:
func returnFifteen() -> Int {
var y = 10
func add() {
y += 5
}
add()
return y
}
returnFifteen()
What is the purpose of these lines where the variable or function name are on a line by themselves?
TIA

The purpose is for "Playground" Demonstrations. For example, if you put that code into playground. The window on the right will show result of the execution of the function.
If you were in a traditional project, you would likely do:
func returnFifteen() -> Int {
var y = 10
func add() {
y += 5
}
add()
return y
}
var someInt = returnFifteen()
println(someInt)
However, this is unnecessary in Playground:
Notice the right side.

When you are using Swift in the playground, the output display on the right hand side is not actually a console output more so just an output of whatever variable is on that line, or the number of times a loop runs.
So they are placing the variable/function on it's own line so that when you paste that into Playground you will see what the result is.

Related

Make variable immutable after initial assignment

Is there a way to make a variable immutable after initializing/assigning it, so that it can change at one point, but later become immutable? I know that I could create a new let variable, but is there a way to do so without creating a new variable?
If not, what is best practice to safely ensure a variable isn't changed after it needs to be?
Example of what I'm trying to accomplish:
var x = 0 //VARIABLE DECLARATION
while x < 100 { //VARIABLE IS CHANGED AT SOME POINT
x += 1
}
x = let x //MAKE VARIABLE IMMUTABLE AFTER SOME FUNCTION IS PERFORMED
x += 5 //what I'm going for: ERROR - CANNOT ASSIGN TO IMMUTABLE VARIABLE
You can initialize a variable with an inline closure:
let x: Int = {
var x = 0
while x < 100 {
x += 1
}
return x
}()
There's no way I know of that lets you change a var variable into a let constant later on. But you could declare your constant as let to begin with and not immediately give it a value.
let x: Int /// No initial value
x = 100 /// This works.
x += 5 /// Mutating operator '+=' may not be used on immutable value 'x'
As long as you assign a value to your constant sometime before you use it, you're fine, since the compiler can figure out that it will eventually be populated. For example if else works, since one of the conditional branches is guaranteed to get called.
let x: Int
if 5 < 10 {
x = 0 /// This also works.
} else {
x = 1 /// Either the first block or the `else` will be called.
}
x += 5 /// Mutating operator '+=' may not be used on immutable value 'x'

Difference between functions with / without return Swift

What is the fundamental difference between these 2 functions ?
func sqr(number: Int) {
print (number * number)
}
func sqr1(number: Int) -> Int {
return number * number
}
This is why I basically never teach print to new programmers. People conflate returning values with printing values, because ultimately they all get printed, so there's not much of an evident difference.
Suppose your goal was to evaluate a quadratic equation: a*x^2 + b*x + c.
How would you multiply the x^2 term by a if it doesn't return a value?
func sqr1(number: Int) -> Int {
return number * number
}
let a = 5
let b = 4
let c = 3
let x = 2
let y = 1
let result = a*sqr1(number: x) + b*x + c
print(result)
Trying doing this with sqr(number:), and you'll quickly see that it's impossible.
The first 1 is a void - return function that prints square of a number
The Second 1 is a Int - return function for a square number that returns it to caller
As an illustration sometimes in coding you need to print a value for e.x debugging purposes for beginners sometimes they think it's useless but when you be an experienced you'll know reason of it unlike the 1 that returns the value to callers which makes more sense for all levels

Why does a horizontal line appear in Xcode Playground extension when viewing "Show result"?

I am learning about Swift extensions, and wrote a simple extension to Double in a Playground. Code is below.
extension Double {
func round(to places: Int) -> Double {
let precisionNumber = pow(10, Double(places))
var n = self //self contains the value of the myDouble variable
n = n * precisionNumber
n.round()
n = n / precisionNumber
return n
}
}
var myDouble = 3.14159
myDouble.round(to: 1)
The extension works as planned, however when I press "show result" (the eye icon) in the right column for any line of code in the extension, I see a horizontal line.
Anyone know what this line is supposed to signify? Using Xcode 11.2.1 and Swift 5.
The trouble here is that you have not revealed all of your playground. My guess is that there is more code, where you call your extension again. Perhaps your real code looks something like this:
extension Double {
func round(to places: Int) -> Double {
let precisionNumber = pow(10, Double(places))
var n = self //self contains the value of the myDouble variable
n = n * precisionNumber
n.round()
n = n / precisionNumber
return n
}
}
var myDouble = 3.14159
myDouble.round(to: 1) // once
print(myDouble)
myDouble = myDouble.round(to: 1) // twice; in your case it's probably another value
print(myDouble)
That is a very poor way to write your playground, if your goal is to write and debug your extension, for the very reason you have shown. You have called the extension two times, so what meaningful value can be shown as the "result" of each line of the extension? The playground has to try to show you both "results" from both calls. The only way it can think of to do that is to graph the two results.
That is a downright useful representation, though, when you are deliberately looping or repeating code, because you get at least a sense, through the graph, of how the value changes each time thru the loop.

I seem to have an infinite while loop in my Swift code and I can't figure out why

var array: [Int] = []
//Here I make an array to try to dictate when to perform an IBaction.
func random() -> Int {
let rand = arc4random_uniform(52)*10+10
return Int(rand)
}
//this function makes a random integer for me
func finalRand() -> Int {
var num = random()
while (array.contains(num) == true){
if (num == 520){
num = 10
}else {
num += 10
}
}
array.append(num)
return num
}
The logic in the while statement is somewhat confusing, but you could try this:
var array:Array<Int> = []
func finalRand() -> Int {
var num = Int(arc4random_uniform(52)*10+10)
while array.contains(num) {
num = Int(arc4random_uniform(52)*10+10)
}
array.append(num)
return num
}
This way there will never be a repeat, and you have less boiler code.
There is probably a better method involving Sets, but I'm sorry I do not know much about that.
A few things:
Once your array has all 52 values, an attempt to add the 53rd number will end up in an infinite loop because all 52 values are already in your array.
In contemporary Swift versions, you can simplify your random routine to
func random() -> Int {
return Int.random(in: 1...52) * 10
}
It seems like you might want a shuffled array of your 52 different values, which you can reduce to:
let array = Array(1...52).map { $0 * 10 }
.shuffled()
Just iterate through that shuffled array of values.
If you really need to continue generating numbers when you’re done going through all of the values, you could, for example, reshuffle the array and start from the beginning of the newly shuffled array.
As an aside, your routine will not generate truly random sequence. For example, let’s imagine that your code just happened to populate the values 10 through 500, with only 510 and 520 being the final possible remaining values: Your routine is 51 times as likely to generate 510 over 520 for the next value. You want to do a Fisher-Yates shuffle, like the built-in shuffled routine does, to generate a truly evenly distributed series of values. Just generate array of possible values and shuffle it.

what does ++ exactly mean in Swift?

i am learning Swift with a book aimed for people with little experience. One thing bothering me is the ++ syntax. The following is taken from the book:
var counter = 0
let incrementCounter = {
counter++
}
incrementCounter()
incrementCounter()
incrementCounter()
incrementCounter()
incrementCounter()
the book said counter is 5.
but i typed these codes in an Xcode playground. It is 4!
i am confused.
The post-increment and post-decrement operators increase (or decrease) the value of their operand by 1, but the value of the expression is the operand's original value prior to the increment (or decrement) operation
So when you see playground, current value of counter is being printed.
But after evaluation of function, the value of counter changes and you can see updated value on the next line.
x++ operator is an operator that is used in multiple languages - C, C++, Java (see the C answer for the same question)
It is called post-increment. It increments the given variable by one but after the current expression is evaluated. For example:
var x = 1
var y = 2 + x++
// the value of x is now 2 (has been incremented)
// the value of y is now 3 (2 + 1, x has been evaluated before increment)
This differs from the ++x (pre-increment) operator:
var x = 1
var y = 2 + ++x
// the value of x is now 2 (has been incremented)
// the value of y is now 4 (2 + 4, x has been evaluated after increment)
Note the operator is getting removed in the next version of Swift, so you shouldn't use it anymore.
It's always better to just write x += 1 instead of complex expressions with side effects.
The value of counter after your five calls to the incrementCounter closure will be 5, but the return of each call to incrementCounter will seemingly "lag" one step behind. As Sulthan writes in his answer, this is due to x++ being a post-increment operator: the result of the expression will be returned prior to incrementation
var x = 0
print(x++) // 0
print(x) // 1
Also, as I've written in my comment above, you shouldn't use the ++ and -- operators as they will be deprecated in Swift 2.2 and removed in Swift 3. However, if you're interested in the details of post- vs pre-increment operator, you can find good answers here on SO tagged to other languages, but covering the same subject, e.g.
What is the difference between ++i and i++?
It's worth mentioning, however, a point that is relevant to Swift > 2.1 however, and that don't really relate to the ++ operator specifically.
When you initiate the closure incrementCounter as
var someOne : Int = 0
let incrementCounter = {
someInt
}
The closure is implictly inferred to be of type () -> Int: a closure taking zero arguments but with a single return of type Int.
let incrementCounter: () -> Int = {
return someInt
}
Hence, what you seemingly "see" in you playground is the unused (non-assigned) return value of the call to incrementCounter closure; i.e., the result of the expression incrementCounter().
Whereas the value of counter is never really printed in the right block of your playground (unless you write a line where the result of that line:s expression is counter).
++ and -- before the identifier add/subtract one, and then return its value.
++ and -- after the identifier return its value, and then add/subtract 1.
They were removed in Swift 3.0, but you can add them back:
prefix operator --
prefix operator ++
postfix operator --
postfix operator ++
prefix func ++(_ a : inout Int) -> Int {
a += 1
return a
}
prefix func --(_ a : inout Int) -> Int {
a -= 1
return a
}
postfix func ++(_ a: inout Int) -> Int {
defer { a += 1 }
return a
}
postfix func --(_ a: inout Int) -> Int {
defer { a -= 1 }
return a
}
var a = 11
print(a++) // 11
print(a) // 12
var b = 5
print(--b) // 4
print(b) // 4
even though there are a lot of answers and all of them are clear i added this snippet to show you how to replace your code with 'new' syntax, where ++ and or -- are deprecated. at first your own code
var counter = 0
let incrementCounter = {
counter++
}
let i0 = incrementCounter() // 0
let i1 = incrementCounter() // 1
// .....
how to rewrite it in future Swift's syntax? lets try the recommended replacement ...
var counter = 0
let ic = {
counter += 1
}
let i0 = ic() // () aka Void !!!
let i1 = ic() // ()
but now the result of ic() is Void! Hm ... OK, the next attempt could looks like
var counter = 0
let ic = {
counter += 1
return counter
}
but now the code doesn't compile with error: unable to infer closure return type in current context :-), so we have to declare it (it was not necessary in our original version)
var counter = 0
let ic:()->Int = {
counter += 1
return counter
}
let i0 = ic() // 1
let i1 = ic() // 2
// .....
it works, but the results are not the same. that is because in original code ++ operator was used as post-increment operator. so, we need another adjustment of our 'new' version
var counter = 0
let ic:()->Int = {
let ret = counter
counter += 1
return ret
}
let i0 = ic() // 0
let i1 = ic() // 1
// .....
yes, i would like to see my familiar unary ++ and / or -- will be also in the future versions of Swift
The thing which you are doing is post increment.
First Learn the difference between Pre & Post Increment
In Post Increment, the value counter after increment contains incremented value (i.e 5)
but if we return, then it will contain old value (i.e 4).
In Pre Increment, both the value and return value is incremented.
Lets look into your code now,
counter++ makes a copy, increases counter, and returns the copy (old value).
so if you print counter it will have incremented value (i.e 5) but, if you return counter (i.e your doing so with incrementCounter) it contains the old value (i.e 4).
because of which incrementCounter only showing upto 4.
CHECK OUTPUT
Solution :
change counter++ to ++counter
CHECK OUTPUT