Overloading a function in go doesn't work - function

I have a function which currently doesn't receive a bool parameter, but then calls another function with a hardcoded bool. We need to remove the hardcoded call and allow a bool to be passed.
I first thought I could try some default parameter - my google searches resulted in that Go apparently doesn't support optional (resp. default) parameter.
So I thought I'd try function overloading.
I found this thread on reddit, which says that it works with a special directive since version 1.7.3:
https://www.reddit.com/r/golang/comments/5c57kg/when_did_function_overloading_get_slipped_in/
I am using 1.8, and still I couldn't get it to work.
I am not even sure I may be allowed to use that directive, but I was speculating that changing the function signature right away may be dangerous as I don't know who uses the function...
Anyway - even with //+overloaded it didn't work
Is there any "idiosyncratic" way or pattern to solve this problem in Go?
//some comment
//+overloaded
func (self *RemoteSystem) Apply(rpath, lpath string, dynamic bool) error {
result, err := anotherFunc(rpath, dynamic)
}
//some comment
//+overloaded
func (self *RemoteSystem) Apply(rpath, lpath string ) error {
//in this function anotherFunc was being called, and dynamic is hardcoded to true
//result, err := anotherFunc(rpath, true)
return self.Apply(rpath, lpath, true)
}
When I run my test, I get (forgive me for omitting part of the real path to file):
too many arguments in call to self.Apply
have (string, string, bool)
want (string, string)
../remotesystem.go:178: (*RemoteSystem).Apply redeclared in this block
previous declaration at ../remotesystem.go:185

Overloading isn't available in Go. Instead of writing functions with the same name that do different things, it is preferable to be more expressive with what the function does in the function name. In this instance, what would commonly be done is something like this:
func (self *RemoteSystem) Apply(rpath, lpath string, dynamic bool) error {
result, err := anotherFunc(rpath, dynamic)
}
func (self *RemoteSystem) ApplyDynamic(rpath, lpath string ) error {
//in this function anotherFunc was being called, and dynamic is hardcoded to true
return self.Apply(rpath, lpath, true)
}
Just by the name of the function, you can easily tell what is different and why.
Another example to provide some context (pun intended).
I write a lot of Google App Engine code in Go using go-endpoints. The way to log things is different depending on if you have a context or not. My logging functions ended up like this.
func LogViaContext(c context.Context, m string, v ...interface{}) {
if c != nil {
appenginelog.Debugf(c, m, v...)
}
}
func LogViaRequest(r *http.Request, m string, v ...interface{}) {
if r != nil {
c := appengine.NewContext(r)
LogViaContext(c, m, v...)
}
}

From the Reddit post:
Unicode. I can tell by the pixels.
Go doesn't support function overloading. But it does support using Unicode characters in function names, which allows you to write function names that look like other function names.
The first one is setValue, the second one is setV\u0430lue aka setV\xd0\xb0lue (with CYRILLIC SMALL LETTER A) and the third is setVal\U0001d69ee aka setVal\xf0\x9d\x9a\x9ee (with MATHEMATICAL MONOSPACE SMALL U).
See also:
Does the Go language have function/method overloading? (stackoverflow.com)
Why does Go not support overloading of methods and operators? (golang.org)
Alternative for function overloading in Go? (stackoverflow.com)

Related

What is the difference between *(*uintptr) and **(**uintptr)

In Go's runtime/proc.go, there is a piece of code showed below:
// funcPC returns the entry PC of the function f.
// It assumes that f is a func value. Otherwise the behavior is undefined.
// CAREFUL: In programs with plugins, funcPC can return different values
// for the same function (because there are actually multiple copies of
// the same function in the address space). To be safe, don't use the
// results of this function in any == expression. It is only safe to
// use the result as an address at which to start executing code.
//go:nosplit
func funcPC(f interface{}) uintptr {
return **(**uintptr)(add(unsafe.Pointer(&f), sys.PtrSize))
}
What I don't understand is why not use *(*uintptr) instead of **(**uintptr)?
So I write a test program below to figure out.
package main
import (
"fmt"
"unsafe"
)
func main(){
fmt.Println()
p := funcPC(test)
fmt.Println(p)
p1 := funcPC1(test)
fmt.Println(p1)
p2 := funcPC(test)
fmt.Println(p2)
}
func test(){
fmt.Println("hello")
}
func funcPC(f func()) uintptr {
return **(**uintptr)(unsafe.Pointer(&f))
}
func funcPC1(f func()) uintptr {
return *(*uintptr)(unsafe.Pointer(&f))
}
The result that p doesn't equal p1 makes me confused.
Why doesn't the value of p equal the value of p1 while their type is the same?
Introduction
A function value in Go denotes the funtion's code. From far, it is a pointer to the function's code. It acts like a pointer.
From a closer look, it's a struct something like this (taken from runtime/runtime2.go):
type funcval struct {
fn uintptr
// variable-size, fn-specific data here
}
So a function value holds a pointer to the function's code as its first field which we can dereference to get to the function's code.
Explaining your example
To get the address of a function('s code), you may use reflection:
fmt.Println("test() address:", reflect.ValueOf(test).Pointer())
To verify we get the right address, we may use runtime.FuncForPC().
This gives the same value as your funcPC() function. See this example:
fmt.Println("reflection test() address:", reflect.ValueOf(test).Pointer())
fmt.Println("funcPC(test):", funcPC(test))
fmt.Println("funcPC1(test):", funcPC1(test))
fmt.Println("func name for reflect ptr:",
runtime.FuncForPC(reflect.ValueOf(test).Pointer()).Name())
It outputs (try it on the Go Playground):
reflection test() address: 919136
funcPC(test): 919136
funcPC1(test): 1357256
func name for reflect ptr: main.test
Why? Because a function value itself is a pointer (it just has a different type than a pointer, but the value it stores is a pointer) that needs to be dereferenced to get the code address.
So what you would need to get this to uintptr (code address) inside funcPC() would be simply:
func funcPC(f func()) uintptr {
return *(*uintptr)(f) // Compiler error!
}
Of course it doesn't compile, conversion rules do not allow converting a function value to *uintptr.
Another attempt may be to convert it first to unsafe.Pointer, and then to *uintptr:
func funcPC(f func()) uintptr {
return *(*uintptr)(unsafe.Pointer(f)) // Compiler error!
}
Again: conversion rules do not allow converting function values to unsafe.Pointer. Any pointer type and uintptr values may be converted to unsafe.Pointer and vice versa, but not function values.
That's why we have to have a pointer value to start with. And what pointer value could we have? Yes, the address of f: &f. But this will not be the function value, this is the address of the f parameter (local variable). So &f schematically is not (just) a pointer, it's a pointer to pointer (that both need to be dereferenced). We can still convert it to unsafe.Pointer (because any pointer value qualifies for that), but it's not the function value (as a pointer), but a pointer to it.
And we need the code address from the function value, so we have to use **uintptr to convert the unsafe.Pointer value, and we have to use 2 dereferences to get the address (and not just the pointer in f).
This is exactly why funcPC1() gives a different, unexpected, incorrect result:
func funcPC1(f func()) uintptr {
return *(*uintptr)(unsafe.Pointer(&f))
}
It returns the pointer in f, not the actual code address.
It returns a different value because **(**uintptr) is not the same as *(*uintptr). The former is a double indirection, the later a simple indirection.
In the former case, the value is a pointer to a pointer to a pointer to a uint.

When to use function expression rather than function declaration in Go?

When to use functioneExpression rather than function declaration in Go?
I searched Function Expression vs Function Declaration (in JS), it's about hoisting. How about Golang?
There is one unique property to each:
A function declaration binds an identifier, the function name, to a function; so the function name will be an identifier which you can refer to.
A function literals represents an anonymous function. Function literals are closures, they capture the surrounding environment: they may refer to variables defined in a surrounding function. Those variables are then shared between the surrounding function and the function literal, and they survive as long as they are accessible.
Don't be deluded: syntactically whenever a function literal is used, a declared function could also be used. For example the following code is a valid and working Go code:
func do() {}
func main() {
go do()
defer do()
}
The answer to when to use one over the other lies in the unique properties listed above.
Use function declaration when you want to refer to the function, when you want to reuse it. This is also a good way to separate code, function declaration must be at the file level: you can't declare a function in another function. See Golang nested class inside function for details.
Use function literals when you want the function to have access to the local variables and other identifiers surrounding it. Since you can't declare a function in another function, to capture the local variables and identifiers, the only option here is a function literal (unless you want to pass everything as arguments to a declared function, which could quickly get dirty if the function needs to modify the values in which case they need to be "transformed" into pointers and addresses need to be passed). For an interesting related question, check out Define a recursive function within a function in Go.
When the function does not need to have a name, and the function does not need access to the local variables, you may choose which one to use, relying on your judgement, examples seen in other (quality) projects and prior experiences. If the function body is "small", easier / simpler to use a function literal. If the function body is "big", code will be easier to read and understand if you declare it as a separate function and provide sufficient documentation to it.
An interesting / related topic is a variable of function type, which you may initialize using either a function literal or with a declared function. It has the benefits that it is an identifier so you can refer to it, and that its value can be changed and a new function can be assigned to it.
For example:
func do() { fmt.Println("Doing...") }
var f = do
func main() {
f()
f = func() { fmt.Println("Not doing!") }
f()
}
Output of the above (try it on the Go Playground):
Doing...
Not doing!
Very useful for mocking functions in tests. For an example, see Testing os.Exit scenarios in Go with coverage information (coveralls.io/Goveralls).
Anonymous functions in Go are used in various situations:
- to start a goroutine
go func() {
// body
}()
- with a defer statement
defer func() {
// body
}()
- as an argument to another function
err := filepath.Walk(root, func(path string, info os.FileInfo, err error) error {
// todo
})
- as a closure (examples)
Function declarations are used when you want to refer to the function by name. Maybe to call it from multiple places in your own code, or to expose it to other packages.

What are the differences between functions and methods in Swift?

I always thought functions and methods were the same, until I was learning Swift through the "Swift Programming Language" eBook. I found out that I cannot use greet("John", "Tuesday") to call a function that I declared inside a class, as shown in the eBook in the screen shot below:
I received a error saying that "Missing argument label 'day:' in call" as per this screen shot:
Here is the code:-
import Foundation
import UIKit
class ViewController2: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
//var dailyStatement = greet("John", "Tuesday")
var dailyStatement = greet("John", day: "Tuesday")
println(dailyStatement)
}
func greet(name: String, day: String) -> String {
return "Hello \(name), today is \(day)."
}
}
After some research, I found this post: Difference between a method and a function, and it seems to me that the function that I declared inside a class is actually called a method. So, the syntax that I use to call the method is different compared to the syntax that I use to call a function.
I never realized this difference when I was programming in Objective-C.
What are the differences between functions and methods in Swift?
When do we use functions and when do we use methods in Swift?
After a few hours of reading and experimenting, here are the things that I found out:-
Functions in Swift
Functions are self-contained chunks of code that perform a specific
task. You give a function a name that identifies what it does, and
this name is used to “call” the function to perform its task when
needed.
Resource: Official Apple Documentation on Functions in Swift
Function Parameter Names
However, these parameter names are only used within the body of the
function itself, and cannot be used when calling the function. These
kinds of parameter names are known as local parameter names, because
they are only available for use within the function’s body.
It means that by default, all the parameters for Function are local parameters.
But, sometimes we want to indicate the purpose of each parameter. So, we can actually define an external parameter name for each parameter. Example Code:
func someFunction(externalParameterName localParameterName: Int) {
// function body goes here, and can use localParameterName
// to refer to the argument value for that parameter
}
Another way to make the external parameter name is using hash symbol (#) to shorten the name.
func someFunction(#localParameterName: Int) {
// function body goes here, and can use localParameterName
// to refer to the argument value for that parameter
}
To call the above functions with external parameter, you may use
someFunction(localParameterName:10)
Methods in Swift
Methods are functions that are associated with a particular type.
Classes, structures, and enumerations can all define instance methods,
which encapsulate specific tasks and functionality for working with an
instance of a given type.
Resource: Official Apple Documentation on Methods in Swift
However, the default behavior of local names and external names is
different for functions and methods.
Specifically, Swift gives the first parameter name in a method a local
parameter name by default, and gives the second and subsequent
parameter names both local and external parameter names by default.
Code below shows the differences for default and non-default parameters for method in Swift.
import Foundation
import UIKit
class ViewController2: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
//Default methods calling
var dailyStatement = greet("Rick", day: "Tuesday")
println(dailyStatement)
//First parameter is also an external parameter
var dailyStatement2 = greet2(name:"John", day: "Sunday")
println(dailyStatement2)
}
//Default: First Parameter is the local parameter, the rest are external parameters
func greet (name: String, day: String) -> String {
return "Hello \(name), today is \(day)."
}
//Use Hash symbol to make the First parameter as external parameter
func greet2 (#name: String, day: String) -> String {
return "Hello \(name), today is \(day)."
}
}
I might miss some important details. Hope someone can provide a better answer.
As you said yourself, methods are functions, but in a class. In objective-c you never realized this, because we were only coding in classes. Every function that we wrote was a method of a class (ViewController or some other class we created).
In Swift we have the ability to create functions that are not inside some class. The main reason for doing this is to write functions that are not tied to any class, and can be used wherever we need them. So if you have a function that is related to a class you write it inside the class and you can access is from every instance of the class:
class Square {
var length: Double
func area() -> Double {
return length * length
}
}
But if you need to access the function from everywhere, then you don't write it inside a class. For example:
func squared(number: Int) -> Int {
return number * number
}
About your syntax issues between functions and methods: You guessed it right, methods and functions are called a little bit differently. That is because in Objective-C we had long method names and we liked them because we could read what the methods were doing and what the parameters were for. So the first parameter in a method is in most cases described by the function name itself. And the other parameters shouldn't only be some numbers or strings or instances, they should be described as well, so Swift writes the name of the variable automatically. If you want to describe it by yourself you can do that as well:
class Something {
func desc(firstString string1: String, secondString string2:String) {...}
}
Well, #Ricky's answer says it pretty much. I was confused what exactly they are. So here is my thought:
Functions could be defined outside of classes or inside of classes/structs/enums, while Methods have to be defined inside of and part of classes/structs/enums.
We could define a Function outside of any Type's definition and could use it within Methods of any Type's definition.
Just my understanding and illustration here, hope this helps someone else or you may edit if you feel there is an improvement needed OR let me know if anything is wrong:
//This is a Function which prints a greeting message based on the category defined in an 'enum'
func greet(yourName name: String, category: GreetingsCategory) {
switch category {
case .Person:
print("Hello, " + name + " Today is Tuesday")
case .Vehicle:
print("Hello, " + name + " your Vehicle is a Car")
}
}
//This is an 'enum' for greetings categories
enum GreetingsCategory: String {
case Person
case Vehicle
}
//Type: Person
class Person {
//This is a method which acts only on Person type
func personGreeting() {
greet(yourName: "Santosh", category: .Person)
}
}
//Type: Vehicle
class Vehicle {
//This is a method which acts only on Vehicle type
func vehicleGreeting() {
greet(yourName: "Santosh", category: .Vehicle)
}
}
//Now making use of our Function defined above by calling methods of defferent types.
let aPerson = Person()
aPerson.personGreeting()
//prints : Hello, Santosh Today is Tuesday
let aVehicle = Vehicle()
aVehicle.vehicleGreeting()
//prints: Hello, Santosh your Vehicle is a Car
//We can also call the above function directly
greet(yourName: "Santosh", category: .Person)
Mainly the names are used interchangeably without people having a real intent of distinguishing them. But ultimately they do have a difference.
someFile.swift:
func someFunc{
//some code
}
class someClass{
func someMethod{
//some code
}
}
Note: someClass != someFile
someMethod works only on its associated type which is 'someClass'. However the same can't be said for someFunc. someFunc is only in the someClass.Swift because semantically it is better suited to be written in that file. It could have been written in any other class as long as it's marked with private
And obviously the method can access self. With functions, there is no self.. For more see: What's the difference between a method and a function?
Here is a simple answer on the difference between functions and methods:
Some folks use “function” and “method” interchangeably, but there’s a
small difference: both of them are reusable chunks of code, but
methods belong to classes, structs, and enums, whereas functions do
not.
So:
func thisIsAFunction() {
}
struct Person {
func thisIsAMethod() {
}
}
Because methods always belong to a data type, they have a concept of
self that functions do not.
source: https://www.hackingwithswift.com/example-code/language/whats-the-difference-between-a-function-and-a-method
Lots of great answers, but let me use Xcode to show something visually from the UIKit module:
That is a function because it's written at the global level. It's not a method. Methods are scoped to a class.
Screenshot to show that it's at the global level.
The following function is at the global level:
public func UIApplicationMain(_ argc: Int32, _ argv: UnsafeMutablePointer<UnsafeMutablePointer<Int8>>!,
_ principalClassName: String?, _ delegateClassName: String?) -> Int32
Icons for the different symbols. (Class, Method, Property, Protocol, Function, Extensions are all different symbols)
The function has an icon like 𝓯
The method has an icon of M
functional principle as a part of functional language
function is a first-class type (first-class citizen) in Swift. Higher order functions
assign to a variable
pass as an argument
return
Function
Function is a block of code that is created for executing some task. Function consists of name, optional parameters(name, type), optional return type, body.
func name(parameterName1: Int, parameterName2: String) -> Bool {
//statements
return true
}
Function type - function’s parameter type + return type[Java about]. For example it is used as function's parameter
//Function type for the sample above
(Int, String) -> Bool
Method
Method - is a function which is associated with a type - class, structure, enum [About]:
Instance method - method which belongs to instance
MyClass().foo()
Type method - method which belongs to type itself. class or static is used[About]
MyClass.foo()
Closure
As official doc says that Closure in Swift has three next forms:
global function(with name, without capturing) - is a function that is declared in a global scope(out of class scope). Usually it is defined as a first level of .swift file and does not have a big memory foot print
nested function(with name, with capturing enclosing function variables) - function inside other function
closure expression(without name, with capturing enclosing context)
Closure(closure expression) - anonymous function - is a block of code(functionality). Closure is a type of function without name. Closure is a function in terms of Functional programming. It can support capturing concept(if it doesn't capture it is lambda). It is similar to block in Objective-C.
[Closure vs Lambda]
They can be used for:
non-escaping closure - sync operations - click events, sort...
escaping closure - async operations - e.g.completion handler - it is a callback/notification which is called when task is done
class ClassA {
var variable = "Hello"
func fooA() {
print(variable)
let b = ClassB() //1
b.fooB(completionHandler: { [weak self] (input) -> String? in //2 pass closure //3 capture list or any calls from closure to outher scope
guard let self = self else { return nil }
self.variable = "World" //capturing self.variable
return String(input)
})
}
}
class ClassB {
var myCompletionHandler: ((Int) -> String?)? = nil //5
func fooB(completionHandler: #escaping (Int) -> String?) { //4
self.myCompletionHandler = completionHandler //6
let result = completionHandler(7)
}
func fooB2(completionHandler: #escaping (Int) -> String?) { //if you re-pass function to #escaping function you must mark it by #escaping too
self.fooB(completionHandler: completionHandler)
}
}
func testClosure() {
ClassA().fooA()
}
(Int) -> String? //Function type
//Closure Expression
{ [weak self] (input) -> String? in
//logic
}
[non-escaping vs escaping closure]
[#autoclosure]
[Init/customize stored property by closure]
[JVM Memory model]

Why the strong difference between closures and functions in Rust and how to work around it?

I just ran into a problem with how Rust handles closures.
Let's assume I'm a library author and have written this method
fn get(&mut self, handler: fn() -> &str){
//do something with handler
}
Now if a user wants to call this method like this
let foo = "str";
server.get(|| -> &str { foo });
It won't work because Rust, according to it's documentation makes a strong difference between regular functions and closures.
Do I as a library author always have to make such methods accept closures instead of regular functions to not restrict library users too much?
Also it seems to me as if closures are the only way to write anonymous functions or am I mistaken?
Currently, fn() types can be automatically "promoted" to || types. (A closure with an empty environment, I suppose.) For example, this works:
fn get(handler: || -> &str) -> &str {
handler()
}
fn main() {
fn handler_fn() -> &str { "handler_fn" }
let handler_cl = || -> &str "handler_cl";
println!("{}", get(handler_fn));
println!("{}", get(handler_cl));
}
So if your library function get doesn't care whether handler is a closure or not, then it seems reasonable to just accept closures for maximum flexibility. But this isn't always possible. For example, if you wanted to execute handler in another task, then I believe it must be a fn or a proc type. (I'm not 100% certain here---I may be missing a detail.)
With regard to anonymous functions, yes, a || or a proc closure are the only two ways to write anonymous functions.

How do you return non-copyable types?

I am trying to understand how you return non-primitives (i.e. types that do not implement Copy). If you return something like a i32, then the function creates a new value in memory with a copy of the return value, so it can be used outside the scope of the function. But if you return a type that doesn't implement Copy, it does not do this, and you get ownership errors.
I have tried using Box to create values on the heap so that the caller can take ownership of the return value, but this doesn't seem to work either.
Perhaps I am approaching this in the wrong manner by using the same coding style that I use in C# or other languages, where functions return values, rather than passing in an object reference as a parameter and mutating it, so that you can easily indicate ownership in Rust.
The following code examples fails compilation. I believe the issue is only within the iterator closure, but I have included the entire function just in case I am not seeing something.
pub fn get_files(path: &Path) -> Vec<&Path> {
let contents = fs::walk_dir(path);
match contents {
Ok(c) => c.filter_map(|i| { match i {
Ok(d) => {
let val = d.path();
let p = val.as_path();
Some(p)
},
Err(_) => None } })
.collect(),
Err(e) => panic!("An error occurred getting files from {:?}: {}", pa
th, e)
}
}
The compiler gives the following error (I have removed all the line numbers and extraneous text):
error: `val` does not live long enough
let p = val.as_path();
^~~
in expansion of closure expansion
expansion site
reference must be valid for the anonymous lifetime #1 defined on the block...
...but borrowed value is only valid for the block suffix following statement
let val = d.path();
let p = val.as_path();
Some(p)
},
You return a value by... well returning it. However, your signature shows that you are trying to return a reference to a value. You can't do that when the object will be dropped at the end of the block because the reference would become invalid.
In your case, I'd probably write something like
#![feature(fs_walk)]
use std::fs;
use std::path::{Path, PathBuf};
fn get_files(path: &Path) -> Vec<PathBuf> {
let contents = fs::walk_dir(path).unwrap();
contents.filter_map(|i| {
i.ok().map(|p| p.path())
}).collect()
}
fn main() {
for f in get_files(Path::new("/etc")) {
println!("{:?}", f);
}
}
The main thing is that the function returns a Vec<PathBuf> — a collection of a type that owns the path, and are more than just references into someone else's memory.
In your code, you do let p = val.as_path(). Here, val is a PathBuf. Then you call as_path, which is defined as: fn as_path(&self) -> &Path. This means that given a reference to a PathBuf, you can get a reference to a Path that will live as long as the PathBuf will. However, you are trying to keep that reference around longer than vec will exist, as it will be dropped at the end of the iteration.
How do you return non-copyable types?
By value.
fn make() -> String { "Hello, World!".into() }
There is a disconnect between:
the language semantics
the implementation details
Semantically, returning by value is moving the object, not copying it. In Rust, any object is movable and, optionally, may also be Clonable (implement Clone) and Copyable (implement Clone and Copy).
That the implementation of copying or moving uses a memcpy under the hood is a detail that does not affect the semantics, only performance. Furthermore, this being an implementation detail means that it can be optimized away without affecting the semantics, which the optimizer will try very hard to do.
As for your particular code, you have a lifetime issue. You cannot return a reference to a value if said reference may outlive the value (for then, what would it reference?).
The simple fix is to return the value itself: Vec<PathBuf>. As mentioned, it will move the paths, not copy them.