Commit 7231ceb7 authored by Robert Griesemer's avatar Robert Griesemer

Proposal for new function type syntax as suggested by ken:

- removed "func" from function type
- make it work by changing composite literal syntax to use {} instead of ()

FunctionType is now more in line with the rest of the declarations, as the
keyword "func" is now really part of the declaration and not part of the type.

R=r,ken
DELTA=49  (14 added, 12 deleted, 23 changed)
OCL=14864
CL=14955
parent 47809085
...@@ -4,7 +4,7 @@ The Go Programming Language Specification (DRAFT) ...@@ -4,7 +4,7 @@ The Go Programming Language Specification (DRAFT)
Robert Griesemer, Rob Pike, Ken Thompson Robert Griesemer, Rob Pike, Ken Thompson
---- ----
(September 4, 2008) (September 8, 2008)
This document is a semi-formal specification of the Go systems This document is a semi-formal specification of the Go systems
...@@ -992,22 +992,23 @@ particular to dereference a channel pointer. ...@@ -992,22 +992,23 @@ particular to dereference a channel pointer.
Function types Function types
---- ----
A function type denotes the set of all functions with the same signature. A function type denotes the set of all functions with the same parameter
list and result.
Functions can return multiple values simultaneously. FunctionType = "(" [ ParameterList ] ")" [ Result ] .
FunctionType = "func" Signature .
Signature = Parameters [ Result ] .
Parameters = "(" [ ParameterList ] ")" .
ParameterList = ParameterSection { "," ParameterSection } . ParameterList = ParameterSection { "," ParameterSection } .
ParameterSection = IdentifierList Type . ParameterSection = IdentifierList Type .
Result = Type | "(" ParameterList ")" . Result = Type | "(" ParameterList ")" .
Functions can return multiple values simultaneously.
// Function types // Function types
func () ()
func (a, b int, z float) bool () int
func (a, b int, z float) (success bool) (s string)
func (a, b int, z float) (success bool, result float) (a, b int, z float) bool
(a, b int, z float) (success bool)
(a, b int, z float) (success bool, result float)
A variable can hold only a pointer to a function, not a function value. A variable can hold only a pointer to a function, not a function value.
In particular, v := func() {} creates a variable of type *func(). To call the In particular, v := func() {} creates a variable of type *func(). To call the
...@@ -1025,7 +1026,7 @@ An interface type denotes a set of methods. ...@@ -1025,7 +1026,7 @@ An interface type denotes a set of methods.
InterfaceType = "interface" "{" [ MethodDeclList [ ";" ] ] "}" . InterfaceType = "interface" "{" [ MethodDeclList [ ";" ] ] "}" .
MethodDeclList = MethodDecl { ";" MethodDecl } . MethodDeclList = MethodDecl { ";" MethodDecl } .
MethodDecl = identifier Signature . MethodDecl = identifier FunctionType .
// A basic file interface. // A basic file interface.
type File interface { type File interface {
...@@ -1125,7 +1126,7 @@ Literals for composite data structures consist of the type of the value ...@@ -1125,7 +1126,7 @@ Literals for composite data structures consist of the type of the value
followed by a parenthesized expression list for array and structure literals, followed by a parenthesized expression list for array and structure literals,
or a list of expression pairs for map literals. or a list of expression pairs for map literals.
CompositeLit = LiteralType "(" [ ( ExpressionList | ExprPairList ) [ "," ] ] ")" . CompositeLit = LiteralType "{" [ ( ExpressionList | ExprPairList ) [ "," ] ] "}" .
LiteralType = TypeName | ArrayType | MapType | StructType . LiteralType = TypeName | ArrayType | MapType | StructType .
ExprPairList = ExprPair { "," ExprPair } . ExprPairList = ExprPair { "," ExprPair } .
ExprPair = Expression ":" Expression . ExprPair = Expression ":" Expression .
...@@ -1141,7 +1142,7 @@ Given ...@@ -1141,7 +1142,7 @@ Given
we can write we can write
pi := Num(Rat(22,7), 3.14159, "pi") pi := Num{Rat{22, 7}, 3.14159, "pi"};
For array literals, if the length is present the constructed array has that many For array literals, if the length is present the constructed array has that many
elements; trailing elements are given the approprate zero value for that type. elements; trailing elements are given the approprate zero value for that type.
...@@ -1150,39 +1151,40 @@ if the specified length is less than the number of elements in the expression li ...@@ -1150,39 +1151,40 @@ if the specified length is less than the number of elements in the expression li
In either case, the length is known at compile type and thus the type of an In either case, the length is known at compile type and thus the type of an
array literal is always a fixed array type. array literal is always a fixed array type.
primes := [6]int(2, 3, 5, 7, 9, 11) primes := [6]int{2, 3, 5, 7, 9, 11};
weekdays := []string("mon", "tue", "wed", "thu", "fri", "sat", "sun") weekdays := []string{"mon", "tue", "wed", "thu", "fri", "sat", "sun"};
Map literals are similar except the elements of the expression list are Map literals are similar except the elements of the expression list are
key-value pairs separated by a colon: key-value pairs separated by a colon:
m := map[string]int("good": 0, "bad": 1, "indifferent": 7) m := map[string]int{"good": 0, "bad": 1, "indifferent": 7};
TODO: Consider adding helper syntax for nested composites TODO: Consider adding helper syntax for nested composites
(avoids repeating types but complicates the spec needlessly.) (avoids repeating types but complicates the spec needlessly.)
TODO(gri): These are not conversions and we could use {} instead of () in
the syntax. This will make literals such as Foo(1, 2, 3) clearly stand
out from function calls. TBD.
Function Literals Function Literals
---- ----
Function literals represent anonymous functions. Function literals represent anonymous functions.
FunctionLit = FunctionType Block . FunctionLit = "func" FunctionType Block .
Block = "{" [ StatementList [ ";" ] ] "}" . Block = "{" [ StatementList [ ";" ] ] "}" .
A function literal can be invoked The type of a function literal is a pointer to the function type.
or assigned to a variable of the corresponding function pointer type.
For now, a function literal can reference only its parameters, global
variables, and variables declared within the function literal.
// Function literal
func (a, b int, z float) bool { return a*b < int(z); } func (a, b int, z float) bool { return a*b < int(z); }
A function literal can be assigned to a variable of the
corresponding function pointer type, or invoked directly.
f := func(x, y int) int { return x + y; }
func(ch *chan int) { ch -< ACK; } (reply_chan)
Implementation restriction: A function literal can reference only
its parameters, global variables, and variables declared within the
function literal.
Primary expressions Primary expressions
---- ----
...@@ -1367,7 +1369,7 @@ Strings and arrays can be concatenated using the "+" operator ...@@ -1367,7 +1369,7 @@ Strings and arrays can be concatenated using the "+" operator
String and array addition creates a new array or string by copying the String and array addition creates a new array or string by copying the
elements. elements.
For integer values, / and % satisfy the following relationship: For integer values, "/" and "%" satisfy the following relationship:
(a / b) * b + a % b == a (a / b) * b + a % b == a
...@@ -2016,7 +2018,7 @@ literals in expressions. ...@@ -2016,7 +2018,7 @@ literals in expressions.
A function declaration declares an identifier of type function. A function declaration declares an identifier of type function.
FunctionDecl = "func" identifier Signature ( ";" | Block ) . FunctionDecl = "func" identifier FunctionType ( ";" | Block ) .
func min(x int, y int) int { func min(x int, y int) int {
if x < y { if x < y {
...@@ -2038,7 +2040,7 @@ Methods ...@@ -2038,7 +2040,7 @@ Methods
A method declaration declares a function with a receiver. A method declaration declares a function with a receiver.
MethodDecl = "func" Receiver identifier Signature ( ";" | Block ) . MethodDecl = "func" Receiver identifier FunctionType ( ";" | Block ) .
Receiver = "(" identifier Type ")" . Receiver = "(" identifier Type ")" .
A method is bound to the type of its receiver. A method is bound to the type of its receiver.
...@@ -2618,8 +2620,8 @@ where "F" is declared as "func (a *[30 + 2] float, b, c int) (ok bool)". ...@@ -2618,8 +2620,8 @@ where "F" is declared as "func (a *[30 + 2] float, b, c int) (ok bool)".
Finally, two interface types are equivalent if they both declare the same set of Finally, two interface types are equivalent if they both declare the same set of
methods: For each method in the first interface type there is a method in the methods: For each method in the first interface type there is a method in the
second interface type with the same method name and equivalent signature, and second interface type with the same method name and equivalent function type,
vice versa. Note that the declaration order of the methods is not relevant. and vice versa. Note that the declaration order of the methods is not relevant.
[OLD [OLD
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment