I thought closures and functions are same thing. But when referencing to a property inside local function compiler doesn't require self. But inside closure it requires to write self. What i mean is why this two things are different?
The sample code for clarity:
class Foo {
let bar = "bar"
func baz() {
func localBaz() {
println(bar) // No complain from compiler.
}
let bazClosure = {
println(self.bar) // Here if I write just println(bar), compiler complains.
}
}
}
You expectation is wrong - functions and closures in Swift are not the same thing. A func essentially sets up a lazy var binding with a [unowned self] declaration. Thus, if you want to get rid of func you could transform the following:
class Foo {
let bar = "bar"
// this is not your 'baz'; just an example
func baz () { println (bar) }
}
}
as
class Foo {
let bar = "bar"
lazy var baz = { [unowned self] in println (self.bar) }
}
You can see that func is doing more than just a closure.
Furthermore, and importantly, func sets up a recursive binding environment which allows the body of func bar to reference bar. Thus you can write:
1> class Foo {
2. func fact (x:Int) -> Int {
3. if 1 == x { return x }
4. else { return x * fact (x - 1) }}
5. }
6> Foo().fact(5)
$R0: (Int) = 120
but not
7> class Foo {
8. lazy var fact = { (x:Int) -> Int in
9. if 1 == x { return x }
10. else { return x * fact (x - 1) }}}
repl.swift:10:27: error: variable used within its own initial value
else { return x * fact (x - 1) }}}
^
Indeed, I do not know why closure need self in swift to access instance properties but let's think about it.
Your baz() is a class function, I mean it belongs to the class Foo and the closure like a external function. In Objective-C all class function actually need a self argument to invoke that function.
Therefore a closure need a self pointer (or something named self reference the instance of Foo) to access its property.
Related
Is it possible to do something like this in Golang?
package main
import "fmt"
type myFunType func(x int) int
var myFun myFunType = myFunType { return x } // (1)
func doSomething(f myFunType) {
fmt.Println(f(10))
}
func main() {
doSomething(myFun)
}
In other words, is it possible to declare a function type variable using a function type alias, without repeating the signature?
Or, alternatively, is there a way not to always retype the whole function-signature, whenever creating a variable of a function-type?
The above code sample, which I would expect to be equivalent to the one below (replace line (1) with line (2)), results in the compilation error syntax error: unexpected return, expecting expression.
package main
import "fmt"
type myFunType func(x int) int
var myFun myFunType = func(x int) int { return 2 * x } // (2)
func doSomething(f myFunType) {
fmt.Println(f(10))
}
func main() {
doSomething(myFun)
}
From Spec: Function literals:
FunctionLit = "func" Signature FunctionBody .
A function literal must contain the func keyword and the Signature. Using a function type is not allowed by the syntax.
Same goes for Function declarations:
FunctionDecl = "func" FunctionName Signature [ FunctionBody ] .
Using a function type (instead of the signature) is not allowed.
So no, what you want is not possible. And the reason for it is because the signature (the function type) does not include the parameter names (just their order and types), but when you are actually "creating" a function value, you need a way to refer to them, and having just the function type you don't have names for the parameters.
See related questions for more details:
Getting method parameter names in Golang
Is unnamed arguments a thing in Go?
No, but in golang you can define methods with a name and use them.
As an example. Sometimes at the top of a file or even in a whole package there is a common way of defining errors like this:
ErrFileNotFound := func(file string) error { return errors.New(fmt.Sprintf("file not found %v", file)) }
And this function can then be used multiple times in the file like
file, err := os.Open(filenameRequestedToOpen) // For read access.
if err != nil {
log.Fatal(ErrFileNotFound(filenameRequestedToOpen))
}
or see https://play.golang.org/p/CvBGGc3YeX4
var myFun myFunType = func(x int) int { return 2 * x } // (2)
this is ok, myFun must contains func keyword,means it's a func type of myFunType, and parameters and return type must same with myFunType declared.
How do I take a vector of function argument AST variants, extract the values, and use them to instantiate a function call?
I am writing an interpreter that evaluates certain expressions. Some of the expressions are function calls. I am having a hard time figuring out how to translate the function calls AST to the actual call. The AST gives me the function name and a vector of arguments. I can lookup the function pointer to call from the name using a map, but passing the arguments to the function pointer is problem.
Rust does not have a splat operator (argument expansion). I could pass them as a tuple and use destructuring of the arguments, but I can't figure out how to convert the vector of AST argument enum variants to a tuple of the concrete types.
I can't simply map or loop over the AST arguments to extract the values and produce a tuple.
I can use nested tuples to build a heterogenous list incrementally:
fn prepend<I,T>(i: I, t: T) -> (I,T) { (i, t) }
fn foo() {
let x = ();
let x = prepend(1, x);
let x = prepend(2.0, x);
let x = prepend(true, x);
}
But that only works because x gets shadowed and the new binding has a different type. This won't work:
fn foo() {
let mut x = ();
x = prepend(1, x);
x = prepend(2.0, x);
x = prepend(true, x);
}
Any ideas?
You don't. Rust is a statically typed language and you are attempting to do non-statically-determinable actions.
Instead, all of your functions need to take in a collection of arguments, verify that there is the right number of arguments (and type, if appropriate to your interpreter), then call the appropriate Rust function with a fixed number of arguments:
// All of the panicking can be replaced by proper error handling.
enum Arg {
Bool(bool),
Int(i32),
}
impl Arg {
fn into_bool(self) -> bool {
match self {
Arg::Bool(b) => b,
_ => panic!("Not a bool"),
}
}
fn into_int(self) -> i32 {
match self {
Arg::Int(i) => i,
_ => panic!("Not an int"),
}
}
}
fn some_fn_wrapper(mut args: Vec<Arg>) {
assert_eq!(args.len(), 3);
let c = args.pop().unwrap();
let b = args.pop().unwrap();
let a = args.pop().unwrap();
some_fn(a.into_bool(), b.into_int(), c.into_bool())
}
fn some_fn(_a: bool, _b: i32, _c: bool) {}
All of this will happen at runtime, as you want to create a highly dynamic language.
See also:
How do I pass each element of a slice as a separate argument to a variadic C function?
How to pass a dynamic amount of typed arguments to a function?
Calling a function only known at runtime
How can I create a function with a variable number of arguments?
Is Reflection possible in Rust, and if so how can I invoke an unknown function with some arguments?
Given this short program:
package main
import "fmt"
type Foo struct {
doer func()
}
func (f Foo) SetDoer(doer func()) {
f.doer = doer
}
func main() {
foo := Foo{func() { fmt.Println("original") }}
foo.doer()
foo.SetDoer(func() { fmt.Println("replacement") })
foo.doer()
}
The output is:
original
original
I had expected it to be:
original
replacement
Why isn't it? Note that the output is as expected if I set foo.doer directly in main(). Just not if I use the SetDoer method.
In Go, the item on the left of the function name is the receiving type. This is the type from which a function can be called. However, receiver can be both pointers or value types. In this case, it is a value. The receiver is purely for the purpose of organization, under the covers, it is passed to the function like any other argument. You're passing by value so a copy of foo is passed into SetDoer, the value is modified, then the setter returns, the value goes out of scope and in the calling scope you're working with the original.
Try this;
// make the receiver a pointer
func (f *Foo) SetDoer(doer func()) {
f.doer = doer
}
// instantiate as pointer
foo := &Foo{func() { fmt.Println("original") }}
foo.SetDoer(func() { fmt.Println("replacement") })
// now the version of doer on foo has been updated.
playground example; https://play.golang.org/p/ZQlvKiluu3
I'm trying to write some helper functions and am getting an 'Invalid Redeclaration' error of some similar methods. If anyone can explain why these methods collide I would be very thankful.
func CGRectModify(rect: CGRect, x: CGFloat) -> CGRect {
return CGRectMake(x, rect.origin.y, rect.size.width, rect.size.height)
}
func CGRectModify(rect: CGRect, y: CGFloat) -> CGRect {
return CGRectMake(rect.origin.x, y, rect.size.width, rect.size.height)
}
func CGRectModify(rect: CGRect, width: CGFloat) -> CGRect {
return CGRectMake(rect.origin.x, rect.origin.y, width, rect.size.height)
}
func CGRectModify(rect: CGRect, height: CGFloat) -> CGRect {
return CGRectMake(rect.origin.x, rect.origin.y, rect.size.width, height)
}
I would think that because the second parameter has a different external name, the method would be understood to have a different signature. It seems that is not the case.
I've been using Apple's doc for reference, but in the section of Local and External Parameter Names for Methods I could not find my answer. Any input is much appreciated.
The rule of "automatic external parameter names" for functions are different from methods.
Swift applies different rules depends on the type of callables.
Functions/Closures → document
No "automatic external parameter names" are performed.
func f(x:Int, y:Int) { /* ... */ }
let c = { (x:Int, y:Int) -> Void in /* ... */ }
f(1, 2)
c(1, 2)
Initializers → document
"automatic external parameter names" are the default for every parameters.
class Foo {
init(x:Int, y:Int) { /* ... */ }
}
let foo = Foo(x: 1, y: 2)
Methods → document
"automatic external parameter names" except for the first parameter.
extension Foo {
func bar(x:Int, y:Int) { /* ... */ }
}
foo.bar(1, y:2)
Subscript → document missing?
No "automatic external parameter names" are performed.
extension Foo {
subscript(x:Int, y:Int) -> Void {
get { /* ... */ }
}
}
foo[1, 2]
And a special rule for ...
Default Values
func fz(x:Int, y:Int, z:Int = 1) { /* ... */ }
fz(1, 1, z: 1)
Of course you can override these default behaviors using:
_ name:Type: disable "automatic external parameter names"
#name:Type: force "automatic external parameter names"
externalName internalName:Type: explicit external name
This actually looks like a bug in the documentation. In the section I originally linked to, Local and External Parameter Names for Methods the follow explanation is written.
This default behavior effectively treats the method as if you had written a hash symbol (#) before the numberOfTimes parameter:
func incrementBy(amount: Int, #numberOfTimes: Int) {
count += amount * numberOfTimes
}
This is not the case. When I do add the hash symbol (#) to my second parameter, the compiler error does not occur.
func CGRectModify(rect: CGRect, #height: CGFloat) -> CGRect {
return CGRectMake(rect.origin.x, rect.origin.y, rect.size.width, height)
}
I'm trying to create 2 protocols ArithmeticType and MathematicType that will be used in where clauses of generic operator functions
protocol ArithmeticType {
func +(lhs: Self, rhs: Self) -> Self
func -(lhs: Self, rhs: Self) -> Self
func *(lhs: Self, rhs: Self) -> Self
func /(lhs: Self, rhs: Self) -> Self
}
extension Int : ArithmeticType {
}
extension Double : ArithmeticType {
}
extension Float : ArithmeticType {
}
ArithmeticType works as expected and either Int, Float and Double conform to it. However the following fails
import Darwin
protocol MathematicType {
func sin(x: Self) -> Self
}
extension Double : MathematicType {
}
extension Float : MathematicType {
}
on console output of the playground I read:
Playground execution failed: <EXPR>:35:1: error: type 'Double' does not conform to protocol 'MathematicType'
extension Double : MathematicType {
^
<EXPR>:32:10: note: protocol requires function 'sin' with type 'Double -> Self'
func sin(x: Self) -> Self
^
<EXPR>:39:1: error: type 'Float' does not conform to protocol 'MathematicType'
extension Float : MathematicType {
^
<EXPR>:32:10: note: protocol requires function 'sin' with type 'Float -> Self'
func sin(x: Self) -> Self
^
I would like that math functions behave like the operators above. Is there any way?
== EDIT:
Now I realize that trying to simplify my question was a bad idea. the context is this class (vector of optional values)
class Vector<T> {
var data=[T?]()
init(fromArray: Array<T>) {
for i in fromArray {
data.append(i)
}
}
init() {
}
init(count: Int){
for i in 0..<count {
data.append(nil)
}
}
init(count: Int, repeatedValue: T) {
for i in 0..<count {
data.append(repeatedValue)
}
}
func count() -> Int {
return data.count
}
func append(newElement: T?) {
data.append(newElement)
}
subscript(index: Int) -> T? {
let i = index>0 ? index % count() : -index % count()
return data[i]
}
}
outside of it I defined a generic function for the + operator
func +<T where T: ArithmeticType>(left: Vector<T>, right: Vector<T>) -> Vector<T> {
let resultCount = max(left.count(),right.count())
var result = Vector<T>()
for i in 0..<resultCount {
if left[i] != nil && right[i] != nil {
result.append(left[i]!+right[i]!)
}
else {
result.append(nil)
}
}
return result
}
that works as expected, however when I tried to define a generic sin function as
func sin<T where T : FloatingPointType>(x: Vector<T>) -> Vector<T>{
var result = Vector<T>()
for i in 0..<x.count() {
if let o = x[i] {
result.append(sin(o))
}
else {
result.append(nil)
}
}
return result
}
I got "could not find an overload of sin that accepts the supplied arguments"
then my attempt with MathemticType trying to mimic what I already done for + operator
(ArithmeticType was inspired from IntegerAritmeticType source found by command clicking on import swift more than my knowledge of what I was doing)
== UPDATE
If I write a specialized function only for Double
func sin(x: Vector<Double>) -> Vector<Double>{
var result = Vector<Double>()
for i in 0..<x.count() {
if let o = x[i] {
result.append(Darwin.sin(o))
}
else {
result.append(nil)
}
}
return result
}
it works as expected.
So the question may become "How can I generalize this to either Double and Float" ?
The compiler error is because you declared sin() as a method of the MathematicType protocol, and then declared that Double implements MathematicType, but didn't actually write the sin() method.
extension Double {
func sin(x: Double) -> Double {
return Darwin.sin(x)
}
}
I don't think that's what you want, though, is it? You want to be able to write this:
let myAngle = 3.14159
let sineValue = myAngle.sin()
If that's the case, your protocol and extension would need to look like this:
protocol MathematicType {
func sin() -> Self
}
extension Double : MathematicType {
func sin() -> Double {
return Darwin.sin(self)
}
}
Your MathematicType protocol, and your declarations of conformance to it in Float and Double extensions, say that Float and Double should provide sin as an instance method. That is, you're saying one should be able to write code like:
let zero = 0.0 // inferred type Double
zero.sin(1.5707963268) // returns about 1.0
Notice that invocation of sin isn't actually related to the value of zero, so this probably isn't the behavior you want.
You're probably looking to have sin be a free function, so you can just write:
sin(1.5707963268)
Right?
In that case, your work is already done... the standard library defines both:
func sin(x: Double) -> Double
func sin(x: Float) -> Float
If what you actually want is for your MathematicType to be usable as a generic parameter, meaning "a type you can take the sine of", you'll need a generic sin function. Something like this (quick kludgy solution, there's probably better):
func sine<T: FloatingPointType>(x: T) -> T {
if let v = x as? Double {
return sin(v) as T
}
if let v = x as? Float {
return sin(v) as T
}
fatalError("unknown FloatingPointType")
}
(Notice also that there's already a protocol that both Float and Double conform to, so I've used that in the example.)
I think the issue is that operator requirements and instance method requirements are different, even though they syntactically look similar. Operators are always defined at the global level, so an operator requirement is a requirement on an operator at the global level. On the other hand, instance method requirements are requirements on instance methods. There is no way to specify a global function requirement.