summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Griesemer <gri@golang.org>2009-01-16 14:12:50 -0800
committerRobert Griesemer <gri@golang.org>2009-01-16 14:12:50 -0800
commitcea97fbfc985cf2cbd110c00d2e436b776b271f8 (patch)
treea7668a544aa635ac9093b003fd348d9f791c72c5
parent9813be7b9a1b3fa88c2f4c93ebd56c7bc3513355 (diff)
downloadgolang-cea97fbfc985cf2cbd110c00d2e436b776b271f8.tar.gz
- language for export via capitalized identifiers
- removed explicit "export" declarations and keyword - fixed a few glitches and adjusted examples (The details of what "export" mean should be clarified in the spec, this is just so we have a working doc for now.) R=r DELTA=131 (7 added, 63 deleted, 61 changed) OCL=22753 CL=22970
-rw-r--r--doc/go_spec.txt180
1 files changed, 62 insertions, 118 deletions
diff --git a/doc/go_spec.txt b/doc/go_spec.txt
index 812c3bbdc..b78d81c5c 100644
--- a/doc/go_spec.txt
+++ b/doc/go_spec.txt
@@ -3,7 +3,7 @@ The Go Programming Language Specification (DRAFT)
Robert Griesemer, Rob Pike, Ken Thompson
-(January 7, 2009)
+(January 16, 2009)
----
@@ -28,8 +28,6 @@ Timeline (9/5/08):
Missing:
-[ ] partial export of structs, methods
-[ ] packages of multiple files
[ ] Helper syntax for composite types: allow names/indices for maps/arrays,
remove need for type in elements of composites
@@ -92,6 +90,8 @@ Decisions in need of integration into the doc:
Closed:
+[x] packages of multiple files - we have a working approach
+[x] partial export of structs, methods
[x] new as it is now is weird - need to go back to previous semantics and introduce
literals for slices, maps, channels - done
[x] determine if really necessary to disallow array assignment - allow array assignment
@@ -155,12 +155,11 @@ Contents
Declarations and scope rules
Predeclared identifiers
- Exported declarations
+ Exported identifiers
Const declarations
Iota
Type declarations
Variable declarations
- Export declarations
Types
Basic types
@@ -284,17 +283,18 @@ A package is a collection of import, constant, type, variable, and function
declarations. Each declaration binds an ``identifier'' with a program entity
(such as a variable).
-In particular, all identifiers in a package are either declared explicitly
-within the package, arise from an import statement, or belong to a small set
-of predeclared identifiers (such as "string").
+In particular, all identifiers occurring in a package are either declared
+explicitly within the package, arise from an import declaration, or belong
+to a small set of predeclared identifiers (such as "string").
Scoping follows the usual rules: The scope of an identifier declared within
a ``block'' generally extends from the declaration of the identifier to the
end of the block. An identifier shadows identifiers with the same name declared
in outer scopes. Within a scope, an identifier can be declared at most once.
-A package may mark explicitly declared identifiers for ``export'' to make them
-visible to other source files in the same package, or to other packages.
+Identifiers may be ``internal'' or ``exported''. Internal identifiers are only
+accessible to files belonging to the package in which they are declared.
+External identifiers are accessible to other packages.
Typing, polymorphism, and object-orientation
@@ -342,11 +342,6 @@ they are no longer accessible. There is no pointer arithmetic in Go.
Values and references
----
-TODO
-- revisit this section
-- if we'd keep the * for maps and chans, all types would have value semantics
- again
-
Most data types have value semantics, but their contents may be accessed
through different pointers referring to the same object. However, some
data types have reference semantics to facilitate common usage patterns
@@ -423,32 +418,30 @@ Comments are // to end of line or /* */ without nesting and are treated as white
Some Unicode characters (e.g., the character U+00E4) may be representable in
two forms, as a single code point or as two code points. For simplicity of
-implementation, Go treats these as distinct characters.
+implementation, Go treats these as distinct characters: each Unicode code
+point is a single character in Go.
Characters
----
-In the grammar the term
-
- utf8_char
+The following terms are used to denote specific Unicode character classes:
-denotes an arbitrary Unicode code point encoded in UTF-8. Similarly,
+ unicode_char an arbitrary Unicode code point
+ unicode_letter a Unicode code point classified as "Letter"
+ capital_letter a Unicode code point classified as "Letter, uppercase"
- non_ascii
-
-denotes the subset of "utf8_char" code points with values >= 128.
+(The Unicode Standard, Section 4.5 General Category - Normative.)
Letters and digits
----
- letter = "A" ... "Z" | "a" ... "z" | "_" | non_ascii.
+ letter = unicode_letter | "_" .
decimal_digit = "0" ... "9" .
octal_digit = "0" ... "7" .
hex_digit = "0" ... "9" | "A" ... "F" | "a" ... "f" .
-All non-ASCII code points are considered letters; digits are always ASCII.
----
@@ -467,12 +460,14 @@ type, a function, etc.
identifier = letter { letter | decimal_digit } .
+Exported identifiers (§Exported identifiers) start with a capital_letter.
+
a
- _x
- ThisIsVariable9
+ _x9
+ ThisVariableIsExported
αβ
-Some identifiers are predeclared (§Declarations).
+Some identifiers are predeclared (§Predeclared identifiers).
Numeric literals
@@ -541,7 +536,7 @@ following differences:
The rules are:
char_lit = "'" ( unicode_value | byte_value ) "'" .
- unicode_value = utf8_char | little_u_value | big_u_value | escaped_char .
+ unicode_value = unicode_char | little_u_value | big_u_value | escaped_char .
byte_value = octal_byte_value | hex_byte_value .
octal_byte_value = "\" octal_digit octal_digit octal_digit .
hex_byte_value = "\" "x" hex_digit hex_digit .
@@ -598,7 +593,7 @@ Double-quoted strings have the usual properties; back-quoted strings
do not interpret backslashes at all.
string_lit = raw_string_lit | interpreted_string_lit .
- raw_string_lit = "`" { utf8_char } "`" .
+ raw_string_lit = "`" { unicode_char } "`" .
interpreted_string_lit = """ { unicode_value | byte_value } """ .
A string literal has type "string" (§Strings). Its value is constructed
@@ -669,7 +664,7 @@ The following words are reserved and must not be used as identifiers:
break default func interface select
case else go map struct
- chan export goto package switch
+ chan goto package switch
const fallthrough if range type
continue for import return var
@@ -683,9 +678,7 @@ A declaration ``binds'' an identifier to a language entity (such as
a package, constant, type, struct field, variable, parameter, result,
function, method) and specifies properties of that entity such as its type.
- Declaration =
- [ "export" | "package" ]
- ( ConstDecl | TypeDecl | VarDecl | FunctionDecl | MethodDecl ) .
+ Declaration = ConstDecl | TypeDecl | VarDecl | FunctionDecl | MethodDecl .
Every identifier in a program must be declared; some identifiers, such as "int"
and "true", are predeclared (§Predeclared identifiers).
@@ -726,9 +719,6 @@ same identifier declared in an outer block.
function and does not intersect with any non-label scope. Thus,
each function has its own private label scope.
-An entity is said to be ``local'' to its scope. Declarations in the package
-scope are ``global'' declarations.
-
Predeclared identifiers
----
@@ -753,36 +743,19 @@ The predeclared functions (note: this list is likely to change):
cap(), convert(), len(), make(), new(), panic(), panicln(), print(), println(), typeof(), ...
-Exported declarations
+Exported identifiers
----
-Global declarations optionally may be marked for ``export'', thus making the
-declared identifier accessible outside the current source file. Another source
-file may then import the package (§Packages) and access exported identifiers
-via qualified identifiers (§Qualified identifiers). Local declarations can
-never be marked for export.
-
-There are two kinds of exports: If a declaration in a package P is marked with
-the keyword "export", the declared identifier is accessible in any file
-importing P; this is called ``unrestricted export''. If a declaration is
-marked with the keyword "package", the declared identifier is only accessible
-in files belonging to the same package P; this is called ``package-restricted''
-export.
-
-If the identifier represents a type, it must be a complete type (§Types) and
-the type structure is exported as well. In particular, if the declaration
-defines a "struct" or "interface" type, all structure fields and all structure
-and interface methods are exported also.
-
- export const pi float = 3.14159265
- export func Parse(source string);
+Identifiers that start with a capital_letter (§Identifiers) are ``exported'',
+thus making the identifiers accessible outside the current package. A file
+belonging to another package may then import the package (§Packages) and access
+exported identifiers via qualified identifiers (§Qualified identifiers).
- package type Node *struct { val int; next *Node }
+All other identifiers are ``internal''; they are only visible in files
+belonging to the same package which declares them.
-TODO: Eventually we need to be able to restrict visibility of fields and methods.
-(gri) The default should be no struct fields and methods are automatically exported.
-Export should be identifier-based: an identifier is either exported or not, and thus
-visible or not in importing package.
+TODO: This should be made clearer. For instance, function-local identifiers
+are never exported, but non-global fields/methods may be exported.
Const declarations
@@ -808,8 +781,8 @@ the type of all constants is the type specified, and the types of all
expressions in ExpressionList must be assignment-compatible with the
constant type.
- const pi float64 = 3.14159265358979323846
- const e = 2.718281828
+ const Pi float64 = 3.14159265358979323846
+ const E = 2.718281828
const (
size int64 = 1024;
eof = -1;
@@ -836,6 +809,7 @@ ExpressionLists permit light-weight declaration of enumerated values (§Iota):
Thursday;
Friday;
Partyday;
+ numberOfDays; // this constant in not exported
)
The initializing expression for a numeric constant is evaluated
@@ -985,7 +959,7 @@ of the variable.
VarSpec = IdentifierList ( CompleteType [ "=" ExpressionList ] | "=" ExpressionList ) .
var i int
- var u, v, w float
+ var U, V, W float
var k = 0
var x, y float = -1.0, -2.0
var (
@@ -1014,7 +988,7 @@ The syntax
is shorthand for
- "var" ExpressionList = ExpressionList .
+ "var" IdentifierList = ExpressionList .
i, j := 0, 10;
f := func() int { return 7; }
@@ -1024,36 +998,6 @@ Also, in some contexts such as "if", "for", or "switch" statements,
this construct can be used to declare local temporary variables.
-Export declarations
-----
-
-TODO:
-1) rephrase this section (much of it covered by Exported declarations)
-2) rethink need for this kind of export
-
-Global identifiers may be exported, thus making the
-exported identifier visible outside the package. Another package may
-then import the identifier to use it.
-
-Export declarations must only appear at the global level of a
-source file and can name only globally-visible identifiers.
-That is, one can export global functions, types, and so on but not
-local variables or structure fields.
-
-Exporting an identifier makes the identifier visible externally to the
-package. If the identifier represents a type, it must be a complete
-type (§Types) and the type structure is
-exported as well. The exported identifiers may appear later in the
-source than the export directive itself, but it is an error to specify
-an identifier not declared anywhere in the source file containing the
-export directive.
-
- ExportDecl = [ "package" ] "export" ExportIdentifier { "," ExportIdentifier } .
- ExportIdentifier = QualifiedIdent .
-
- export sin, cos
- export math.abs
-
----
Types
@@ -1256,14 +1200,14 @@ types (§Types).
struct {
x, y int;
u float;
- a *[]int;
- f *();
+ A *[]int;
+ F *();
}
A struct may contain ``anonymous fields'', which are declared with a type
but no explicit field identifier. An anonymous field type must be specified as
a type name "T", or as a pointer to a type name ``*T'', and T itself may not be
-a pointer or interface type. The unqualified type acts as the field identifier.
+a pointer or interface type. The unqualified type name acts as the field identifier.
// A struct with four anonymous fields of type T1, *T2, P.T3 and *P.T4
struct {
@@ -1422,13 +1366,13 @@ In general, a type implements an arbitrary number of interfaces.
For instance, consider the interface
type Lock interface {
- lock, unlock ();
+ Lock, Unlock ();
}
If S1 and S2 also implement
- func (p T) lock() { ... }
- func (p T) unlock() { ... }
+ func (p T) Lock() { ... }
+ func (p T) Unlock() { ... }
they implement the Lock interface as well as the File interface.
@@ -3254,19 +3198,19 @@ The file must begin with a package clause.
package Math
-A package can gain access to exported items from another package
+A package can gain access to exported identifiers from another package
through an import declaration:
ImportDecl = "import" ( ImportSpec | "(" [ ImportSpecList ] ")" ) .
ImportSpecList = ImportSpec { ";" ImportSpec } [ ";" ] .
ImportSpec = [ "." | PackageName ] PackageFileName .
-An import statement makes the exported contents of the named
-package file accessible in this package.
+An import statement makes the exported top-level identifiers of the named
+package file accessible to this package.
In the following discussion, assume we have a package in the
-file "/lib/math", called package Math, which exports functions sin
-and cos.
+file "/lib/math", called package "math", which exports the identifiers
+"Sin" and "Cos" denoting the respective trigonometric functions.
In the general form, with an explicit package name, the import
statement declares that package name as an identifier whose
@@ -3276,7 +3220,7 @@ For instance, after
import M "/lib/math"
the contents of the package /lib/math can be accessed by
-M.cos, M.sin, etc.
+"M.Sin", "M.Cos", etc.
In its simplest form, with no package name, the import statement
implicitly uses the imported package name itself as the local
@@ -3284,7 +3228,7 @@ package name. After
import "/lib/math"
-the contents are accessible by Math.sin, Math.cos.
+the contents are accessible by "math.Sin", "math.Cos".
Finally, if instead of a package name the import statement uses
an explicit period, the contents of the imported package are added
@@ -3292,7 +3236,7 @@ to the current package. After
import . "/lib/math"
-the contents are accessible by sin and cos. In this instance, it is
+the contents are accessible by "Sin" and "Cos". In this instance, it is
an error if the import introduces name conflicts.
Here is a complete example Go package that implements a concurrent prime sieve:
@@ -3300,7 +3244,7 @@ Here is a complete example Go package that implements a concurrent prime sieve:
package main
// Send the sequence 2, 3, 4, ... to channel 'ch'.
- func Generate(ch chan <- int) {
+ func generate(ch chan <- int) {
for i := 2; ; i++ {
ch <- i // Send 'i' to channel 'ch'.
}
@@ -3308,7 +3252,7 @@ Here is a complete example Go package that implements a concurrent prime sieve:
// Copy the values from channel 'in' to channel 'out',
// removing those divisible by 'prime'.
- func Filter(in chan <- int, out *<-chan int, prime int) {
+ func filter(in chan <- int, out *<-chan int, prime int) {
for {
i := <-in; // Receive value of new variable 'i' from 'in'.
if i % prime != 0 {
@@ -3317,21 +3261,21 @@ Here is a complete example Go package that implements a concurrent prime sieve:
}
}
- // The prime sieve: Daisy-chain Filter processes together.
- func Sieve() {
+ // The prime sieve: Daisy-chain filter processes together.
+ func sieve() {
ch := make(chan int); // Create a new channel.
- go Generate(ch); // Start Generate() as a subprocess.
+ go generate(ch); // Start generate() as a subprocess.
for {
prime := <-ch;
print(prime, "\n");
ch1 := make(chan int);
- go Filter(ch, ch1, prime);
+ go filter(ch, ch1, prime);
ch = ch1
}
}
func main() {
- Sieve()
+ sieve()
}