Why do I get stuck in a compile loop - Lambda - swift

Why do I get stuck in a compile loop in Playground when trying to run the following?
func makeIncrementer(byHowMuch: Int) -> ((Int) -> Int) {
func addArg(number: Int) -> Int {
return 2 + number
}
return addArg
}
var twoTimesIncrementer = makeIncrementer(2)
twoTimesIncrementer(7)
Also, how do you call a function returning a function in a non-functional language? Lambda still?

Firstly I do not get stuck in a compile loop, it returns 9 as expected. And Playground has its fair amount of bugs, if something does not work in playground, stick it into an actual project, try to run it and there you will see wether or not it actually works.
Secondly a function returning a function is simply still a function, its naming does not change with its return type. The only thing to note is that in Swift you can have functions as First-Class Objects, your twoTimesIncrementer is a variable as any other.
Other than that my recommendation is not trying to get over-obsessed with the naming of certain patterns or features. Do you have an example of a non-functional language where you can define functions that return functions?

Related

How come I can create a variable with same name as a function parameter?

In a function, if I'm being passed an int (which is immutable type, i.e let n), how come if I pass this into a function, I can create a var variable of this? Just wondering why swift works this way, and the reason for it .
func checkNum(_ n: Int) -> Bool {
var n = n
}
In this, it let's me do this.
This is called "shadowing" and is allowed in a variety of places because it's convenient for the programmer because it avoids having two similarly named variables in scope. Without this feature, this code would be:
func checkNum(_ n: Int) -> Bool {
var writableN = n
...
}
This raises the possibility of modifying writableN, and then using n again later in the function unintentionally. It also can make the function a bit harder to understand because of the extra variable. (Of course shadowing can also make code more difficult to understand as well, if it's used without care.)
This is very similar to the if let shadowing, such as:
var x: Int? = ...
if let x = x { ... }
This allows you to use x inside the if let as a non-Optional rather than having to come up with some other name for it.
This is a fairly general feature. Whenever there is a new scope, variables can shadow. For example, you can declare variables inside a function that have the same name as properties or globals. You can create scopes inside a function as well
func checkNum(_ n: Int) -> Bool {
var n = n // Shadows previous `let`
do {
let n = 4 // Shadows previous `var`
print(n)
}
return true
}
Used with care, this is helpful. Used too often (as this last example definitely does), it can make the code very confusing.
Your specific case touches on another important aspect of Swift, which is that it tries to control shared mutable state. The n that the function receives is a copy of the integer that was passed. Modifying n would never directly modify the caller's variable. (There's inout to allow this, but it's subtle. It does't share state. It copies the value in, and on return, copies the value back out.)
Since n isn't shared with the caller, Swift makes this very explicit by making it immutable. If you want to modify it, you need to explicitly make another copy, and var n = n does that.
'var' as a parameter attribute has been deprecated in Swift 3 so that is no longer possible. You can get a similar behaviour by using an inout parameter
func checkNum(_ n: inout Int) -> Bool {
n + 1
}
Remember to call the function by passing the parameter like this: checkNum(&n)

Swift - Ambiguous reference to member '==' error

I've done some searching and can't seem to find a solution for my below issue. I'm fairly new to swift so working through some issues. I have the below function which is just a stub containing the signature of the function and a return value just to get it to compile.
The test code is what I've been given, I did not write this and unfortunately cannot alter it.
My issues is that when I run it, it says that the test that calls this function has an "Ambiguous call to member '=='". I cannot alter the test code. Whatever the issue is must be in my function signature i'm assuming but could use some help.
Function That I am writing (That I assume contains the issue):
func contains(target: StringOrInt, compare: Character ) -> Bool {
return false
} // contains
Test that calls the function (I'm not allowed to edit this and did not write it):
func test_contains_cons_2_strings_3() {
let list1 = MyList.cons("foo", MyList.cons("bar", MyList.empty))
assertEquals(testName: "test_contains_cons_2_strings_3",
expected: true,
received: list1.contains(target: "bar", compare: ==))//Error is on this line '=='
} // test_contains_cons_2_strings_3
Error:
main.swift:807:67: error: ambiguous reference to member '=='
received: list1.contains(target: "foo", compare: ==))
Also note that "StringOrInt" is a protocol that I've defined that acts as an extension on both Int and String. This is done because the test code (Which i did not write and cannot edit) passes both strings and ints to this same variable and function.
Thanks advance for any help, I really appreciate it!
I think you want to compare two strings by passing "==" operator and return a Boolean value.If so you can use the below method,
func myList(_ compare:((String, String) -> Bool)) -> Bool {
return compare("foo","bar")
}
myList(==)
I was able to figure this out using the below. I implemented an enum of generic type and the nan extension on that enum. I then used this generic type within the contains function to represent multiple types instead of StringOrInt. Thanks everyone for the comments and the help.
enum implemented:
indirect enum my_list<A> {
case cons(A, my_list<A>)
case empty
}
I then implemented in extension for this enum "extension my_list" and placed the contains function within the extension.
contains function signature/stub:
func contains(target: A, compare:((A, A) -> Bool))
-> Bool {
return true
}// contains

How does a function that returns a function work?

I'm reading Apple's book about Swift and stumbled upon this piece of code, which I after many tries couldn't understand. As far as I understand, this function returns a function. The two last lines of code, as well as all the code, though, are totally bewildering. And how we can assign a function to a variable (the seventh line)? Thank you.
I've typed it myself into the Playground but still don't get it.
func makeIncrement () -> ((Int) -> Int){
func addOne (number: Int) -> Int{
return 1 + number
}
return addOne
}
var increment = makeIncrement()
increment(7)
Functions can be considered objects in Swift (or as first class functions - worth researching).
Therefore may be assigned to variables and to object properties.
So in your code makeIncrement simply returns the function addOne as a variable.
var increment = makeIncrement() can just be seen as assigning the returned function from makeIncrement as a variable (or function object) increment.
We can then freely call the increment function as we would call addOneor any other function really.
A function is something with optional input and a return type. If you alt-click on the var increment you will see that increment is of type ((Int) -> Int). This means that you can input an Int and will return an Int. This is then done in the last line by calling this function.
If you know object-oriented programming, you will know that you can always pass objects around, which also have functions. In this way, in your code, it is doing the same but now we are omitting the object.

What is the purpose to make a function which return a function?

I was reading Apple doc about swift .
it has an example in which it made a function which returns a function
func makeIncrementer() -> ((Int) -> Int) {
func addOne(number: Int) -> Int {
return 1 + number
}
return addOne
}
var increment = makeIncrementer()
increment(7)
So here my concern is what are advantages of this practice and when to use it?
and if some one can also help me with concept of "A function can take another function as one of its arguments." than that will be so kind
Thanks in advance
Here's a really common case of this that you use all the time, probably without even realizing it.
Instance methods are really just class methods that return closures.
Take String.hasPrefix for example, which has type (String) -> (String) -> Bool.
So String.hasPrefix takes String argument, which is the instance the instance method will act upon, and returns a closure of type (String) -> Bool.
We would usually get this closure by using a form like "The quick brown fox".hasPrefix, but we can also use String.hasPrefix("The quick brown fox"), which is equivalent.
The result of these expressions is the hasPrefix function, bound to the specific instance (the String "The quick brown fox") that it will act upon.
We can then invoke this closure with another String argument, which tells it what prefix to look for.
Here's what you might typically write:
let result = "The quick brown fox".hasPrefix("The") // => True
Let's break that down into steps (with type annotations added for emphasis on the types at play):
import Foundation
let instance: String = "The quick brown fox"
let desiredPrefx: String = "The"
let staticMethod: (String) -> (String) -> Bool = String.hasPrefix
let boundInstanceMethod: (String) -> Bool = staticMethod(instance)
let result: Bool = boundInstanceMethod(desiredPrefx) // => true
equivalent:
import Foundation
let instance: String = "The quick brown fox"
let desiredPrefx: String = "The"
let boundInstanceMethod: (String) -> (String) -> Bool = instance.hasPrefix
let result: Bool = boundInstanceMethod(desiredPrefx) // => true
The benefit of creating a function that returns a function is that the inner function remembers the environment that it was created in. Typically, when you call a function, the variables within that function end when the function finishes. By returning a function, however, you create what is called a closure, and this allows you to hold on to the environment that the closure was created in, so you can use it over and over again.
There are many benefits to being able to accept a function as a parameter to another function. For example, you could create a filter function that accepts an array as its first argument and another function as its second. Then, you could call your filter function and pass it a function that would check each element of the array to see if it was even, and return a new array that only contains even values. You could also call the same filter function with a function that checks each element of an array to see if it is odd, and return a new array containing only odd numbers. This makes the filter function far more flexible than it would otherwise be, and allows you to get away with writing less code. Instead of writing a new, complex function every time you want to filter the elements of an array, and having to maintain a potential multitude of filter functions, you only have to write one.
I hope this helps.
makeIncrementer() have a function addOne(number: Int)
That is only eccessable with in makeIncrementer()
Out side of makeIncrementer() we can not access addOne(number: Int).

Swift: A function as an another functions argument

EDIT: I'm aware that I was using the wrong Xcode version for Swift 2, now. Problem solved.
I'm following the Swift 2 book from Apple. At a point there's the following example:
import Foundation
func hasAnyMatches(list: [Int], condition: Int -> Bool) -> Bool {
for item in list {
if condition(item) {
return true
}
}
return false
}
func lessThanTen(number: Int) -> Bool {
return number < 10
}
var numbers = [20, 19, 7, 12]
hasAnyMatches(numbers, condition: lessThanTen)
What I think is weird is the last line. Why does it say condition: lessThanTen and not just lessThanTen? My compiler (Xcode) also gives me an error doing it the way it's shown in the book.
Also: why does it only say list: [Int] in the third line but condition: Int -> Bool? Why not something like list: [Int] -> Int?
Swift functions and methods can define their parameters to either have external names or not.
By default, the first parameter omits its external name, and the
second and subsequent parameters use their local name as their
external name.
Excerpt From: Apple Inc. “The Swift Programming Language (Swift 2 Prerelease).” iBooks. https://itun.es/us/k5SW7.l
The the tag condition: is the external name for the closure that you are passing to your hasAnyMatches function.
That code should compile and run.
My compiler (Xcode) also gives me an error doing it the way it's shown in the book.
Because the language has changed! In Swift 2, which you are reading about, the function has condition: so your call must have condition:. But you are testing in Swift 1.2, a very different language, where the rules are not the same.
In Swift 1.2, a top-level function declared with condition: means that your call should not have condition:. In Swift 1.2, to require the call to have condition:, the function declaration would have to say # condition:.
You are confusing yourself. Update Xcode so that the language you are using is the same as the language you are reading about.
It says condition: lessThanTen because in Swift you can define "labels", that is, descriptions for the data that a function call requires. It gives you an error because the call would be correct if the function declaration was func hasAnyMatches(list: [Int], #condition: Int -> Bool) -> Bool (at least this would be the case with Swift 1.2). The number sign produces, inside every call to the function, a label identical to the name of the function argument. Said label must not be deleted from the call, since it's there to clarify the purpose of that parameter to whoever invokes the function.
list: [Int] means that the first function argument takes name "list" and is of type [Int]. condition: Int -> Bool means that the second function argument takes name "condition" and is of type "Int to Bool", that is, condition is a function that takes a single argument of type Int and returns a value of type Bool. In fact, if you read the last line, in the call to the function hasAnyMatches the following are passed: i) an array of Ints and ii) a function that takes an Int and returns a Bool (note that when passing functions as parameters we only write their name - no parentheses).