Robert Griesemer, Rob Pike, Ken Thompson
----
-(September 19, 2008)
+(September 26, 2008)
This document is a semi-formal specification of the Go systems
<!--
Open issues according to gri:
[ ] clarification on interface types, rules
-[ ] methods for all types
-[x] remove "any"
[ ] convert should not be used for composite literals anymore,
in fact, convert() should go away
[ ] syntax for var args
[ ] new(arraytype, n1, n2): spec only talks about length, not capacity
(should only use new(arraytype, n) - this will allow later
extension to multi-dim arrays w/o breaking the language)
-[x] & needed to get a function pointer from a function? (NO - there is the "func" keyword - 9/19/08)
[ ] comparison operators: can we compare interfaces?
[ ] optional semicolons: too complicated and unclear
[ ] like to have assert() in the language, w/ option to disable code gen for it
[ ] composite types should uniformly create an instance instead of a pointer
-[x] func literal like a composite type - should probably require the '&' to get
- address
[ ] meaning of nil
[ ] clarify slice rules
[ ] something on tuples?
[ ] iant suggests to use abstract/precise int for len(), cap() - good idea
(issue: what happens in len() + const - what is the type?)
[ ] Do composite literals create a new literal each time (gri thinks yes)
-[x] should binary <- be at lowest precedence level? when is a send/receive non-blocking? (NO - 9/19/08)
[ ] consider syntactic notation for composite literals to make them parseable w/o type information
+[ ] nil and interfaces - can we test for nil, what does it mean, etc.
Decisions in need of integration into the doc:
[ ] pair assignment is required to get map, and receive ok.
+
+
+Closed issues:
+[x] remove "any"
+[x] methods for all types
+[x] should binary <- be at lowest precedence level? when is a send/receive non-blocking? (NO - 9/19/08)
+[x] func literal like a composite type - should probably require the '&' to get address (NO)
+[x] & needed to get a function pointer from a function? (NO - there is the "func" keyword - 9/19/08)
+
-->
Contents
----
A function type denotes the set of all functions with the same parameter
-list and result.
+and result types.
FunctionType = "(" [ ParameterList ] ")" [ Result ] .
ParameterList = ParameterSection { "," ParameterSection } .
- ParameterSection = IdentifierList Type .
+ ParameterSection = [ IdentifierList ] Type .
Result = Type | "(" ParameterList ")" .
-Functions can return multiple values simultaneously.
+In ParameterList, the parameter names (IdentifierList) either must all be
+present, or all be absent. If the parameters are named, each name stands
+for one parameter of the specified type. If the parameters are unnamed, each
+type stands for one parameter of that type.
- // Function types
()
+ (x int)
() int
- (s string)
+ (string)
(a, b int, z float) bool
+ (a, b int, z float) (bool)
(a, b int, z float) (success bool)
- (a, b int, z float) (success bool, result float)
+ (int, int, float) (float, *[]int)
A variable can hold only a pointer to a function, not a function value.
In particular, v := func() {} creates a variable of type *(). To call the
function referenced by v, one writes v(). It is illegal to dereference a
function pointer.
-TODO: For consistency, we should require the use of & to get the pointer to
-a function: &func() {}.
+Type equality: Two function types are equal if both have the same number
+of parameters and result values and if corresponding parameter and result
+types are equal. In particular, the parameter and result names are ignored
+for the purpose of type equivalence.
+
+Assignment compatibility: A function pointer can be assigned to a function
+(pointer) variable only if both function types are equal.
Interface types
If statements
----
-If statements have the traditional form except that the
-condition need not be parenthesized and the "then" statement
-must be in brace brackets. The condition may be omitted, in which
-case it is assumed to have the value "true".
+If statements specify the conditional execution of two branches; the "if"
+and the "else" branch. If Expression evaluates to true,
+the "if" branch is executed. Otherwise the "else" branch is executed if present.
+If Condition is omitted, it is equivalent to true.
- IfStat = "if" [ [ Simplestat ] ";" ] [ Condition ] Block [ "else" Statement ] .
+ IfStat = "if" [ [ Simplestat ] ";" ] [ Expression ] Block [ "else" Statement ] .
if x > 0 {
return true;
}
-TODO: We should fix this and move to:
+<!--
+TODO: gri thinks that Statement needs to be changed as follows:
IfStat =
- "if" [ [ Simplestat ] ";" ] [ Condition ] Block
- { "else" "if" Condition Block }
- [ "else" Block ] .
+ "if" [ [ Simplestat ] ";" ] [ Expression ] Block
+ [ "else" ( IfStat | Block ) ] .
+
+To facilitate the "if else if" code pattern, if the "else" branch is
+simply another "if" statement, that "if" statement may be written
+without the surrounding Block:
+ if x > 0 {
+ return 0;
+ } else if x > 10 {
+ return 1;
+ } else {
+ return 2;
+ }
+
+-->
Switch statements
----