func sum (_ x:Int, _ y:Int) -> Int {
    let result = x + y
    return result
}



func sum                      // 1.
    (_ x:Int, _ y:Int)        // 2. i 3.
    -> Int {                  // 4. i 5.
        let result = x + y    // 6.
        return result         // 7.
}



func echoString(_ s:String, times:Int) -> String {
    var result = ""
    for _ in 1...times { result += s }
    return result
}



func echo(string s:String, times n:Int) -> String {
    var result = ""
    for _ in 1...n { result += s }
    return result
}



func say() -> String {
    return "jeden"
}
func say() -> Int {
    return 1
}



class Dog {
    func say(_ s:String, times:Int = 1) {
        for _ in 1...times {
            print(s)
        }
    }
}



func say(_ s:String, times:Int, loudly:Bool) {
    var loudly = loudly
    loudly = true // Nie ma problemu.
}



func removeCharacter(_ c:Character, from s:String) -> Int {
    var s = s
    var howMany = 0
    while let ix = s.firstIndex(of:c) {
        s.remove(at:ix)
        howMany += 1
    }
    return howMany
}



func removeCharacter(_ c:Character, from s: inout String) -> Int {
    var howMany = 0
    while let ix = s.firstIndex(of:c) {
        s.remove(at:ix)
        howMany += 1
    }
    return howMany
}



func getRed(_ red: UnsafeMutablePointer<CGFloat>,
    green: UnsafeMutablePointer<CGFloat>,
    blue: UnsafeMutablePointer<CGFloat>,
    alpha: UnsafeMutablePointer<CGFloat>) -> Bool



let c = UIColor.purple
var r : CGFloat = 0
var g : CGFloat = 0
var b : CGFloat = 0
var a : CGFloat = 0
c.getRed(&r, green: &g, blue: &b, alpha: &a)
// Teraz wartościami zmiennych r, g, b, a są odpowiednio 0.5, 0.0, 0.5, 1.0.



func popoverPresentationController(
    _ popoverPresentationController: UIPopoverPresentationController,
    willRepositionPopoverTo rect: UnsafeMutablePointer<CGRect>,
    in view: AutoreleasingUnsafeMutablePointer<UIView>) {
        view.pointee = self.button2
        rect.pointee = self.button2.bounds
}



let d = Dog()
d.name = "Fido"
print(d.name) // Dane wyjściowe: "Fido".
changeName(of:d, to:"Rover")
print(d.name) // Dane wyjściowe: "Rover".



func checkPair(_ p1:Piece, and p2:Piece) -> Path? {
    // …
    func addPathIfValid(_ midpt1:Point, _ midpt2:Point) {
        // …
    }
    for y in -1..._yct {
        addPathIfValid((pt1.x,y),(pt2.x,y))
    }
    for x in -1..._xct {
        addPathIfValid((x,pt1.y),(x,pt2.y))
    }
    // …
}



func checkPair(_ p1:Piece, and p2:Piece) -> Path? {
    // …
    if arr.count > 0 {
        func distance(_ pt1:Point, _ pt2:Point) -> Double {
            // Funkcja narzędziowa pozwalająca na określenie odległości między dwoma punktami.
            let deltax = pt1.0 - pt2.0
            let deltay = pt1.1 - pt2.1
            return Double(deltax * deltax + deltay * deltay).squareRoot()
        }
        for thisPath in arr {
            var thisLength = 0.0
            for ix in thisPath.indices.dropLast() {
                thisLength += distance(thisPath[ix],thisPath[ix+1])
            }
            // …
        }
    }
    // …
}



func countDownFrom(_ ix:Int) {
    print(ix)
    if ix > 0 { // Warunek zatrzymujący pracę funkcji.
        countDownFrom(ix-1) // Rekurencja!
    }
}
countDownFrom(5) // Dane wyjściowe: 5, 4, 3, 2, 1, 0.



func doThis(_ f:() -> ()) {
    f()
}
func whatToDo() { // 1.
    print("Zrobiłem to.")
}
doThis(whatToDo) // 2.



let size = CGSize(width:45, height:20)
UIGraphicsBeginImageContextWithOptions(size, false, 0) // 1.
let p = UIBezierPath(
    roundedRect: CGRect(x:0, y:0, width:45, height:20), cornerRadius: 8)
p.stroke() // 2.
let result = UIGraphicsGetImageFromCurrentImageContext()! // 3.
UIGraphicsEndImageContext() // 4.



func imageOfSize(_ size:CGSize, _ whatToDraw:() -> ()) -> UIImage {
    UIGraphicsBeginImageContextWithOptions(size, false, 0)
    whatToDraw()
    let result = UIGraphicsGetImageFromCurrentImageContext()!
    UIGraphicsEndImageContext()
    return result
}



func drawing() {
    let p = UIBezierPath(
        roundedRect: CGRect(x:0, y:0, width:45, height:20), cornerRadius: 8)
    p.stroke()
}
let image = imageOfSize(CGSize(width:45, height:20), drawing)



func whatToAnimate() { // W interfejsie użytkownika self.myButton przedstawia przycisk.
    self.myButton.frame.origin.y += 20
}
func whatToDoLater(finished:Bool) {
    print("Koniec animacji: \(finished)")
}
UIView.animate(withDuration:0.4,
    animations: whatToAnimate, completion: whatToDoLater)



func whatToAnimate() { // W interfejsie użytkownika self.myButton przedstawia przycisk.
    self.myButton.frame.origin.y += 20
}
func whatToDoLater(finished:Bool) {
    print("Koniec animacji: \(finished)")
}
UIView.animate(withDuration:0.4,
    animations: whatToAnimate, completion: whatToDoLater)



typealias VoidVoidFunction = () -> ()
func dothis(_ f:VoidVoidFunction) {
    f()
}



UIView.animate(withDuration:0.4,
    animations: {
        () -> () in
        self.myButton.frame.origin.y += 20
    },
    completion: {
        (finished:Bool) -> () in
        print("Koniec animacji: \(finished)")
    }
)



func drawing() {
    let p = UIBezierPath(
        roundedRect: CGRect(x:0, y:0, width:45, height:20), cornerRadius: 8)
    p.stroke()
}
let image = imageOfSize(CGSize(width:45, height:20), drawing)



let image = imageOfSize(CGSize(width:45, height:20), {
    () -> () in
    let p = UIBezierPath(
        roundedRect: CGRect(x:0, y:0, width:45, height:20), cornerRadius: 8)
    p.stroke()
})



UIView.animate(withDuration:0.4,
    animations: {
        () in // *
        self.myButton.frame.origin.y += 20
    }, completion: {
        (finished:Bool) in // *
        print("Koniec animacji: \(finished)")
})



UIView.animate(withDuration:0.4,
    animations: { // *
        self.myButton.frame.origin.y += 20
    }, completion: {
        (finished:Bool) in
        print("Koniec animacji: \(finished)")
})



UIView.animate(withDuration:0.4,
    animations: {
        self.myButton.frame.origin.y += 20
    }, completion: {
        (finished) in // *
        print("Koniec animacji: \(finished)")
})



UIView.animate(withDuration:0.4,
    animations: {
        self.myButton.frame.origin.y += 20
    }, completion: {
        finished in // *
        print("Koniec animacji: \(finished)")
})



UIView.animate(withDuration:0.4,
    animations: {
        self.myButton.frame.origin.y += 20
    }, completion: {
        print("Koniec animacji: \($0)") // *
})



UIView.animate(withDuration:0.4,
    animations: {
        self.myButton.frame.origin.y += 20
    }, completion: {
        _ in // *
        print("Koniec animacji!")
})



UIView.animate(withDuration:0.4,
    animations: {
        self.myButton.frame.origin.y += 20
    }) { // *
        _ in
        print("Koniec animacji!")
}



func doThis(_ f:() -> ()) {
    f()
}
doThis { // Brak nawiasu!
    print("Cześć")
}



func greeting() -> String {
    return "Cześć"
}
func performAndPrint(_ f:()->String) {
    let s = f()
    print(s)
}
performAndPrint {
    greeting() // To jest odpowiednik polecenia return greeting().
}



let arr = [2, 4, 6, 8]
func doubleMe(i:Int) -> Int {
    return i*2
}
let arr2 = arr.map(doubleMe) // Dane wyjściowe: [4, 8, 12, 16].



let arr = [2, 4, 6, 8]
let arr2 = arr.map ({
    (i:Int) -> Int in
    return i*2
})



let para = NSMutableParagraphStyle()
para.headIndent = 10
para.firstLineHeadIndent = 10
// Dalsza konfiguracja egzemplarza para…
content.addAttribute( // Zawartością jest NSMutableAttributedString.
    .paragraphStyle,
    value:para,
    range:NSRange(location:0, length:1))



content.addAttribute(
    .paragraphStyle,
    value: {
        let para = NSMutableParagraphStyle()
        para.headIndent = 10
        para.firstLineHeadIndent = 10
        // Dalsza konfiguracja egzemplarza para…
        return para
    }(),
    range:NSRange(location:0, length:1))



class Dog {
    var whatThisDogSays = "hau"
    func bark() {
        print(self.whatThisDogSays)
    }
}



func doThis(_ f : () -> ()) {
    f()
}
let d = Dog()
d.whatThisDogSays = "arf"
let barkFunction = d.bark
doThis(barkFunction) // Dane wyjściowe: arf.



func doThis(_ f : () -> ()) {
    f()
}
let d = Dog()
let barkFunction = d.bark
d.whatThisDogSays = "arf" // *
doThis(barkFunction) // Dane wyjściowe: arf.



func imageOfSize(_ size:CGSize, _ whatToDraw:() -> ()) -> UIImage {
    UIGraphicsBeginImageContextWithOptions(size, false, 0)
    whatToDraw()
    let result = UIGraphicsGetImageFromCurrentImageContext()!
    UIGraphicsEndImageContext()
    return result
}



let image = imageOfSize(CGSize(width:45, height:20)) {
    let p = UIBezierPath(
        roundedRect: CGRect(x:0, y:0, width:45, height:20), cornerRadius: 8)
    p.stroke()
}



let sz = CGSize(width:45, height:20)
let image = imageOfSize(sz) {
    let p = UIBezierPath(
        roundedRect: CGRect(origin:CGPoint.zero, size:sz), cornerRadius: 8)
    p.stroke()
}



func makeRoundedRectangle(_ sz:CGSize) -> UIImage {
    let image = imageOfSize(sz) {
        let p = UIBezierPath(
            roundedRect: CGRect(origin:CGPoint.zero, size:sz), cornerRadius: 8)
        p.stroke()
    }
    return image
}



func makeRoundedRectangleMaker(_ sz:CGSize) -> () -> UIImage { // 1.
    func f () -> UIImage { // 2.
        let im = imageOfSize(sz) {
            let p = UIBezierPath(
                roundedRect: CGRect(origin:CGPoint.zero, size:sz), cornerRadius: 8)
            p.stroke()
        }
        return im
    }
    return f // 3.
}



func makeRoundedRectangleMaker(_ sz:CGSize) -> () -> UIImage {
    func f () -> UIImage {
        let im = imageOfSize(sz) { // *
            let p = UIBezierPath(
                roundedRect: CGRect(origin:CGPoint.zero, size:sz), cornerRadius: 8) // *
            p.stroke()
        }
        return im
    }
    return f
}



func makeRoundedRectangleMaker(_ sz:CGSize) -> () -> UIImage {
    func f () -> UIImage {
        return imageOfSize(sz) {
            let p = UIBezierPath(
                roundedRect: CGRect(origin:CGPoint.zero, size:sz), cornerRadius: 8)
            p.stroke()
        }
    }
    return f
}



func makeRoundedRectangleMaker(_ sz:CGSize) -> () -> UIImage {
    return {
        return imageOfSize(sz) {
            let p = UIBezierPath(
                roundedRect: CGRect(origin:CGPoint.zero, size:sz), cornerRadius: 8)
            p.stroke()
        }
    }
}



func makeRoundedRectangleMaker(_ sz:CGSize) -> () -> UIImage {
    return {
        imageOfSize(sz) {
            let p = UIBezierPath(
                roundedRect: CGRect(origin:CGPoint.zero, size:sz), cornerRadius: 8)
            p.stroke()
        }
    }
}



var x = 0
print(x)
func setX(newX:Int) {
    x = newX
}
pass100(setX)
print(x)



func countAdder(_ f: @escaping () -> ()) -> () -> () {
    var ct = 0
    return {
        ct = ct + 1
        print("Wartość licznika to \(ct)")
        f()
    }
}



func greet () {
    print("Cześć")
}
let countedGreet = countAdder(greet)
countedGreet()
countedGreet()
countedGreet()



func makeRoundedRectangleMaker(_ sz:CGSize) -> () -> UIImage {
    return {
        imageOfSize(sz) {
            let p = UIBezierPath(
                roundedRect: CGRect(origin:CGPoint.zero, size:sz), cornerRadius: 8)
            p.stroke()
        }
    }
}



func makeRoundedRectangleMaker(_ sz:CGSize, _ r:CGFloat) -> () -> UIImage {
    return {
        imageOfSize(sz) {
            let p = UIBezierPath(
                roundedRect: CGRect(origin:CGPoint.zero, size:sz), cornerRadius: r)
            p.stroke()
        }
    }
}



func makeRoundedRectangleMaker(_ sz:CGSize) -> (CGFloat) -> UIImage {
    return { r in
        imageOfSize(sz) {
            let p = UIBezierPath(
                roundedRect: CGRect(origin:CGPoint.zero, size:sz), cornerRadius: r)
            p.stroke()
        }
    }
}



func whatToAnimate() { // W interfejsie użytkownika self.myButton przedstawia przycisk.
    self.myButton.frame.origin.y += 20
}
func whatToDoLater(finished:Bool) {
    print("Zakończono: \(finished)")
}
UIView.animate(withDuration:0.4,
    animations: whatToAnimate, completion: whatToDoLater) // *



class Dog {
    func bark() {
        print("hau")
    }
    func bark(_ loudly:Bool) {
        if loudly {
            print("HAU")
        } else {
            self.bark()
        }
    }
    func test() {
        let barkFunction = bark // Błąd w trakcie kompilacji.
        // …
    }
}



class Dog {
    func bark() {
        // Podobnie jak wcześniej.
    }
    func bark(loudly:Bool) {
        // Podobnie jak wcześniej.
    }
    func test() {
        let barkFunction = bark(_:) // Świetnie.
    }
}



class Dog {
    func bark() {
        // Podobnie jak wcześniej.
    }
    func bark(loudly:Bool) {
        // Podobnie jak wcześniej.
    }
    func test() {
        let barkFunction = bark as () -> () // Świetnie.
    }
}



class Dog{
    func bark() {
    }
    func bark(_ loudly:Bool) {
    }
    func bark(_ times:Int) {
    }
    func test() {
        let barkFunction = bark(_:) // Błąd w trakcie kompilacji.
    }
}



class Dog {
    func bark() {
    }
    func bark(_ loudly:Bool) {
    }
    func test() {
        let f = {
            return self.bark(_:) // W tym poleceniu konieczne jest użycie self.
        }
    }
}



class Cat {
    func purr() {
    }
}
class Dog {
    let cat = Cat()
    func test() {
        let purrFunction = cat.purr
    }
}



class Cat {
    func purr() {
    }
}
class Dog {
    func bark() {
    }
    func test() {
        let barkFunction = Dog.bark // Podejście dozwolone, choć niepotrzebne.
        let purrFunction = Cat.purr
    }
}



class ViewController : UIViewController {
    @IBOutlet var button : UIButton!
    func viewDidLoad() {
        super.viewDidLoad()
        self.button.addTarget( // Przygotowanie do awarii!
            self, action: "buttonPressed", for: .touchUpInside)
    }
    @objc func buttonPressed(_ sender: Any) {
        // …
    }
}



class ViewController : UIViewController {
    @IBOutlet var button : UIButton!
    func viewDidLoad() {
        super.viewDidLoad()
        self.button.addTarget(
            self, action: #selector(buttonPressed), for: .touchUpInside)
    }
    @objc func buttonPressed(_ sender: Any) {
        // …
    }
}



