Coffeescript - referencing class methods in onclick - coffeescript

I'm just wondering how I can get this to work?
Trying to reference a method at an onclick
class C
#f: () ->
alert 'works'
null
constructor: () ->
console.log #f # why is this undefined?
document.onclick = #f
new C()

It's because #f compiles to this.f and this is constructor function itself.
To access class method f you have to write C.f:
class C
#f: () ->
alert 'works'
null
constructor: () ->
console.log C.f
document.onclick = C.f

I assume you wanted to bind an instance method and not a class method
class C
#this defines a class method
#f: () ->
alert 'works'
null
#this is an instance method
f: () ->
alert 'works'
null
constructor: () ->
console.log #f # why is this undefined?
document.onclick = #f
new C()

Related

swift Parameter is implicitly non-escaping

func test(f: () -> ()) {
let a = f
let b: () -> () = f // error
a()
b()
}
The only difference between a and b is whether the type is specified or not.
But what is the reason for the error to be printed only in b?
Please explain the clear difference between a and b.
The error is shown because 'b' and 'f' do have different signatures.
'b' is an escaping closure 'f' is not.
when doing:
let a = f
you are copying 'f'. The signature stays the same "nonescaping () -> ()".
Declaring a closure in function definition gives you implicit 'nonescaping' in body gives you implicit 'escaping'.
Decorating your closure in the header with #escaping will solve the problem.
func test(f: #escaping () -> ()) {
If you want to know more:
https://medium.com/swiftcommmunity/what-do-mean-escaping-and-nonescaping-closures-in-swift-d404d721f39d

Why does an instance method have this type in Swift?

Given this code:
struct Foo {
func f() {}
}
let f = Foo.f // (Foo) -> () -> ()
Why does f have the type (Foo) -> () -> () and not (Foo) -> ()? Wouldn’t it make sense for instance methods like Foo.f to be directly interchangeable with free functions of type (Foo) -> …?
Why does f have the type (Foo) -> () -> () and not (Foo) -> ()?
That's just currently how unapplied instance method references are implemented; they're curried functions that follow the model of "give me an instance, and I'll give you back a partially-applied instance method" (partially applied with that instance).
However this is problematic in some areas, firstly because it's generally more useful for them to be of the form (Self, Args...) -> Ret, but also more importantly because it because it leads to issues around mutating methods. These end up looking like (inout Self) -> (Args...) -> Ret with the current system, which is problematic because the window of mutation for inout only lasts for the duration of the call.
This means the following currently compiles, but is actually undefined behaviour:
struct S {
var i: Int
mutating func increment() {
i += 1
}
}
var s = S(i: 0)
let unappliedIncrement = S.increment
let increment = unappliedIncrement(&s)
increment() // undefined behaviour
These are the main motivations behind SE-0042, which will change unapplied instance method references from being of the form (Self) -> (Args...) -> Ret to being of the form (Self, Args...) -> Ret (and with inout, Self will be inout Self – allowing the mutation of the instance without UB).
This proposal is yet to be implemented, but once it is, assuming empty parameter lists get flattened out (so you don't end up with a trailing Void parameter), Foo.f will indeed be of type (Foo) -> Void.
It's because, by saying this:
let f = Foo.f
you've described f as a class method, Foo.f. But in your declaration of Foo, f is an instance method. You have thus accidentally discovered the deep dark secret that instance methods are class methods in disguise; you are seeing the signature of the secret class method.
If you had said
let f = Foo().f
you would have gotten the expected result.

Same name (and signature) closure & function: non-ambiguous for >0 arguments, giving closure precedence when calling

Precedence rules for same name and signature function & closure
When defining a closure and a function with same name (say, foo) and signature, it seems as if the closure takes precedence when calling said (seemingly ambiguous) foo.
// Int -> () function
func foo(num: Int) { print("function \(num)")}
// Int -> () closure
let foo: (Int) -> () = { print("closure \($0)")}
/* or...
let foo = { (num: Int) in print("closure \(num)")} */
foo(1) // closure 1
If I option-click the two declarations, they point at each other under the label Related declarations, differing in how they are referred to as:
Declaration: func foo(num: Int)
Related Declarations: foo
...
Declaration: let foo: (Int) -> ()
Related Declarations: foo(_:)
If we attempt to define the same double-foo definitions for a zero-argument function & closure, we get a compile time error prompting invalid redeclaration
// () -> () function
func foo() { print("function")}
// () -> () closure
let foo: () -> () = { print("closure")}
/* or...
let foo = { () in print("closure")} */
/* error: invalid redeclaration of 'foo' */
Question: Why is it that the first case above is considered non-ambiguous, and why does the closure take precedence over the function when calling foo(..) (i.e., in the overload resolution of foo(...)?
I haven't been able to find any official docs (or existing SO thread) explaining this.
Tested for Swift 2.2/Xcode 7.3 and Swift 3.0-dev/IBM Sandbox (with function signature modified to func foo(_ num: Int) { ... }).
In Swift, you cannot name a variable and a function or closure the same thing if no parameters are passed. Although we call them in different ways (foo for a variable and foo() for a function. we will get an invalid redeclaration of foo. The compiler treats the variable as if it has no parameters like the function does. Consider some of these cases:
class X {
var value : Int = 0
func value() -> Int { return 1 } // Invalid redeclaration of 'value()'
}
let x = X()
What is x.value in this case? Is it Int or is it () -> Int? It's legal and useful to treat the methods of classes as if they were closures.
What if we're even more tricky, and do this:
class X {
let value: () -> Int = { 2 }
func value() -> Int { return 1 } // Invalid redeclaration of 'value()'
}
let x = X()
let v = x.value() // ????
Should Swift use the property value and then call it? Or should it call the method value()? Closures are completely legal as properties.
However, using parameters, you can name a function and a variable/Closure the same thing, although I would advise you not to. In this case you should try to name the variable and the function something that describes what they are and/or what they do to make your code more readable by others. I would suggest naming the variable something like
class X {
// Int -> () function
func foo(number num: Int) { print("function \(num)")}
// Int -> () closure
let foo: (Int) -> () = { print("closure \($0)")}
}
because by naming the function it will allow user to know exactly which function your are calling when your method and variable names are same. user can know what parameter is for they are passing. by naming when you call the methods like below.
let x = X()
x.foo(number: 2)
x.foo(3)
and you CMD + click it will point you to the exact method or variable/closure you have written for.
consider previous example:
class X {
// Int -> () function
func foo(number num: Int) { print("function \(num)")}
// Int -> () closure
let foo: (Int) -> () = { print("closure \($0)")}
}
let x = X()
x.foo(2) // x.foo(num: Int)
x.foo(3) // x.foo
Despite you called the correct method or closure. by cmd + click it will point you to the closure only.

Passing generic type over functions in Swift

In order to avoid code repetition I'm trying to find a way to infer argument type Tor () -> T from a variable of type U.
I don't know if I'm clear enough so this is what I wan't to do:
func f<T>(closure: () -> T) -> String {
return "closure: () -> \(T.self)"
}
func f<T>(value: T) -> String {
return "value: \(T.self)"
}
f("test1") // -> "value: Swift.String"
f({ return "test2" }) // -> "closure: () -> Swift.String"
func foo<U>(bar: U) -> (String, String) {
return ("\(U.self)", f(bar))
}
foo("test3") // (.0 "Swift.String", .1 "value: Swift.String")
foo({ return "test4" }) // (.0 "() -> Swift.String", .1 "value: () -> Swift.String")
I expected foo({ return "test4" }) to call f<T>(closure: () -> T) function instead of f<T>(value: T). Why Swift can't infer that bar: U match with () -> T pattern ?
TL;DR: Type data is lost with foo() / U.
I suspect that you are coming from a C++ background.
This would work in C++ as C++ infers the type based on the call site. Swift is different though, in that the generic parameter is the only source of type data. In your case, you are providing no information about the type U, so the compiler does not know how it could convert it to the closure type. Your value override of f() works because you are not placing any conditions on T, whereas in your closure type override, you are specifying a specific form (a closure). Since all type data is lost by your call through foo that takes generic (think blank) type U, the compiler does not have enough information, and cannot deduce a conversion from (blank) to a closure.
This is the topic of "type reification", and there is a lengthy discussion on this on devforums.apple.com.

No trailing closures support for methods with default parameter values?

You can drop the code below into playgrounds.
import UIKit
class MyClass {
func foo(a: String, b: () -> ()) {
b()
}
func bar(a: String = "a", b: () -> ()) {
b()
}
}
let object = MyClass()
object.foo("x") { () -> () in
println("foo")
}
object.bar() { () -> () in
println("foo")
}
object.bar() call produces Missing argument for parameter 'b' in call
The question is: am I doing something wrong, or trailing closures are not supported in methods with default parameter values?
It does look like a problem with trailing closures - this code works:
object.bar(b: { () -> () in
println("foo")
})
However if the external name is removed:
func bar(a: String = "a", _ b: () -> ()) {
b()
}
this no longer works:
object.bar({ () -> () in
println("foo")
})
Moreover using a function having a string as the 2nd parameter:
func test( val1: String = "a", val2: String) {
}
the default parameter is correctly assigned, so this succeeds:
test("me")
which is a different behavior than using closures.
Conclusion: a method or function with parameter(s) having default value and a trailing closure does not work if at least one of the parameters with default value is not specified. Avoiding the trailing closure the function works only if the parameter has external name.