Closed ezz-no closed 4 months ago
This proposal break the assumption that arguments names are not part of the API.
reflect.Type.In
only ever use indexes, in general within the rules of the language there are only positional arguments as far as signatures goes.
It's a backward compatible change, but I don't know if we want something like that.
As an example of why adding meaning to arguments of function looks weird to me: I think it would be weird if we didn't applied public / private rules on the argument names too. So:
otherPackage.Foo{b: 6}
shouldn't be allowed imo, for consistency with everything else that use named keys.
I think it's equally weird if we apply public / private rules to argument because what would this do:
// otherpackage.go
func Foo1(B int) {}
func Foo2(b int) {}
// package.go
var a func(b int) = otherPackage.Foo1 // this shouldn't probably fail
var b = a{b: 52}
var c func(B int) = otherPackage.Foo2 // should this fail ? it doesn't currently, and would be breaking change, but it takes a private argument and make it public
var d = c{B: 52} // should this fail ? should the `c =` assignement remember if the original function had public or private arguments, but that a runtime fail
We would also need a syntax like python's /, *
to indicate if arguments can be keyed or positional.
Adding argument names to the signature of the function looks like a big can of worms to me, and the value of your proposal is very limited (some syntax sugar), I think this proposal shouldn't be accepted without a more complete story for named arguments as part of the api (like foo(x, y, compare: func(x, y int) int { return cmp(abs(x), abs(y)) })
)
It's called currying, and it's a very important concept in functional programming, but I don't think the Go team would choose to introduce them.
previously #4633 was closed as a dup of #21498
In Elixir, there's a 'capture operator', &
, which lets you turn any expression into a function. It looks like &Example.function("example", &1)
. This returns a function that takes a single argument and, when called, evaluates that expression, passing in its single argument in place of &1
. More arguments can be given, i.e. &2
, &3
, etc. At least one must be given. Other expressions are allowed besides function calls, too, such as &(&1 + "example")
, but my guess is that that could be complicated in Go as it's statically typed.
I don't think it would make sense to overload the &
operator in Go, but something else could be used, such as $
. I think that's what Swift does.
I'm not necessarily advocating this, but this approach might be cleaner. It separates it from the argument names this way.
This amounts to syntactic sugar, since you can already use a function literal. f{v}
is equivalent to func(b int) int { return f(v, b) }
. So an important question is: how often would real code use this feature? Is it common enough to be worth introducing a new syntax? Especially bearing in mind that the new syntax is somewhat obscure. The difference between using {
and (
is subtle.
Based on the discussion above, and the emoji voting, this is a likely decline. Leaving open for four weeks for final comments.
No further comments.
Go Programming Experience
Intermediate
Other Languages Experience
No response
Related Idea
Has this idea, or one like it, been proposed before?
No
Does this affect error handling?
No
Is this about generics?
No
Proposal
Allow to construct function composite literal, inside or outside function, to provide a convenient way of constructing named function out of existing function in the case of the only difference is that some arguments differ
Language Spec Changes
Treat function name as type in the case of composite literal
Informal Change
Example:
Is this change backward compatible?
Yes
Orthogonality: How does this change interact or overlap with existing features?
No
Would this change make Go easier or harder to learn, and why?
Could understand easily, the concept is well known
Cost Description
Complicate the difficulty of distinguishing function as value or type
Changes to Go ToolChain
Not familiar
Performance Costs
No
Prototype
Types:treat function as type in the case of composite literal Noder/writer:write down base function object info and fixed arguments Noder/reader:construct the closure accordingly