How to pass a function as an optional parameter Swift - swift

New to Swift and I am currently getting around passing a function as an optional parameter in the following way:
import Foundation
func foo()
{
print("Foo")
}
func bar()
{
print("Bar")
}
func dummy()
{
return
}
func myFunc()
{
myFunc(callBack: dummy())
}
func myFunc(callBack: (Void))
{
foo()
callBack
}
myFunc()
myFunc(callBack: bar())
i.e. exploiting polymorphism
This seems like an inelegant way to do this, is there a better way,
Thanks,
Tom
edit:
I am aware I could shorten this by doing:
import Foundation
func foo()
{
print("Foo")
}
func bar()
{
print("Bar")
}
func dummy()
{
return
}
func myFunc(callBack: (Void) = dummy())
{
foo()
callBack
}
myFunc()
myFunc(callBack: bar())
But I would still say this is an inelegant solution

You can easily define a default value for a function as parameter:
func foo(completion: () -> Void = { }) {
completion()
}
You could also have it be nil by default:
func foo(completion: (() -> Void)? = nil) {
When it's an optional closure, you'll have to call it like this:
completion?()

Your are referring to default arguments:
You can define a default value for any parameter in a function by assigning a value to the parameter after that parameter’s type. If a default value is defined, you can omit that parameter when calling the function.
So you need something like:
func myfunc (callback: ()->void = dummy) {
LinusGeffarth notes that callbacks in Swift are called completion, or closure as avismara notes.

Full code with answer applied:
import Foundation
func foo()
{
print("Foo")
}
func bar()
{
print("Bar")
}
func myFunc(completion: () -> Void = { })
{
foo()
completion()
}
myFunc()
myFunc(completion: bar)

Umm, are you passing function as an optional parameter, though? It looks like you have written a method that accepts Void, you have a function that accepts Void and you are just calling that method. I don't see any trace of polymorphism here except probably that the myFunc has multiple signatures. This method is an inelegant solution not because it is inelegant, but because it isn't a solution.
Here is a correct example of polymorphism in functional systems:
func printA() {
print("A")
}
func printB() {
print("B")
}
//This method accepts a function as a parameter
func higherOrderPrinter(with print: () -> Void ) {
print() //Can be anything, depends on the method you send here. Polymorphism much? :)
}
higherOrderPrinter(with: printA) //Prints A. See carefully how I am NOT doing printA()
higherOrderPrinter(with: printB) //Prints B
//In fact...
higherOrderPrinter {
print("C")
} //Prints C

Related

How to use a protocol function as block definition?

Here a function b calls a and passes a completion block:
func a(completion: (_ succeeded: Bool)) {
completion(true)
}
func b() {
a() { succeeded in
...
}
}
Can I use a protocol function definition to define the block?
Something like this (which does not work):
protocol P {
func c(succeeded: Bool)
}
func a(completion: P) {
completion.c(succeeded: true)
}
func b() {
a() { c(succeeded) in
...
}
}
Note: I am not looking for the protocol/delegate concept.
The issue with using a protocol here is that functions cannot conform to a protocol, only classes, enums and structs can conform to a protocol. So you either need one of these types or an instance of one of these types, but then the instance seems superfluous. If you really want to do it the protocol way here is an example with static conformance on an enum:
import UIKit
protocol Callable {
static func call(someString: String, someInt: Int)
}
enum MyCallable: Callable {
static func call(someString: String, someInt: Int) {
print(someString, someInt)
}
}
func someFunction<T: Callable>(callable: T.Type) {
callable.call(someString: "a",someInt: 1)
}
someFunction(callable: MyCallable.self)
You can use a labeled tuple to give yourself argument labels if that is what you are after. Here is a playground example:
import UIKit
typealias MyArguements = (someInt: Int, someString: String)
func someFunction( completion: #escaping (MyArguements) -> Void) {
completion((someInt: 1, someString: "a"))
}
someFunction { tuple in
let (someInt, someString) = tuple
print(someInt, someString)
}

how can i use `#function` symbol in a `inline` function?

I'd like to use the name of function to resolve some problems, but #function seems not to work well with #inline(__always), here is my codes:
#inline(__always) func log() {
print(#function)
}
func a() { log() } // want 'a()', but got 'log()'
func b() { log() }
func c() { log() }
//...
Can anybody explain? or that's just a stupid idea.
If your intention is to print the name of the function which calls
log(), then you should pass it as default argument (which is evaluated
in the context of the caller), as demonstrated
in Building assert() in Swift, Part 2: __FILE__ and __LINE__ in the Swift blog.
Example:
#inline(__always) func log(_ message: String, callingFunction: String = #function) {
print("\(callingFunction): \(message)")
}
func a() { log("Hello world") }
func b() { log("Foo") }
func c() { log("Bar") }
a() // a(): Hello world
b() // b(): Foo
c() // c(): Bar
This works regardless of whether the log function is inlined or not.
(Inlining does not change the semantics of a program. In particular,
it does not mean that the source code of func log is included from
the source code of func a() and compiled as a single function.)

How to use an Swift object method as a closure?

I'd like to use an object method as a closure because I need to reuse the same closure multiple times in different places in an object. Let's say I have the following:
class A {
func launch(code: Int) -> Bool { return false }
}
And I need a closure that is of type Int -> Bool in the same object. How would I be able to use the launch method as the closure? I'd rather not do something like { self.launch($0) } if I can just directly reference the method.
Instance methods are curried functions which take the instance
as the first argument. Therefore
class A {
func launch(code: Int) -> Bool { return false }
func foo() {
let cl = A.launch(self)
// Alternatively:
let cl = self.dynamicType.launch(self)
// ...
}
}
gives you a closure of the type Int -> Bool.

Overriding a function outside its class

I came across a strange behaviour. The following code produces a compile error where I call bar() with the message: "Missing argument for parameter #1 call"
func bar() {
println("bar with no argument")
}
class ClassA {
func bar(varOfAnyType: String) {
println("bar with argument")
}
func foo() {
bar()
}
}
If I change bar() function's name then I get no errors:
func barNameChanged() {
println("bar with no argument")
}
class ClassA {
func bar(varOfAnyType: String) {
println("bar with argument")
}
func foo() {
barNameChanged()
}
}
What's the reason for the compiler not allowing to override the function outside the class?
Cheers, Daniel
At the moment, the Swift compiler cannot distinguish between a method and a global function with the same name, regardless of overloading.
The solution is to prefix the global function with its module name, e.g.,
func bar() { }
class ClassA {
func bar(anything: String) {}
func foo() { Module.bar() }
}

How to create empty closure properly?

I have a class with a closure as a property:
class MyClass{
var onChange = {}
func foo(){
onChange()
}
}
A behaviour implemented in closure is used in method foo:
var c = MyClass()
c.onChange = {
println("something is changed");
}
c.foo() // prints 'something is changed'
It's easy to make closures with an argument like {(n: Int) -> Void in println(n); } but how to create a closure without input arguments?
I tried to use {}, {in}, etc., but it gave a compilation error.
How to create empty closure properly?
If I understood your question correctly, you could use:
var closure = {() -> () in
return
}