New slides about Go
bearophile
bearophileHUGS at lycos.com
Thu Oct 14 15:06:50 PDT 2010
Found through Reddit, talk slides by Rob Pike, "The Expressiveness of Go":
http://go.googlecode.com/hg/doc/ExpressivenessOfGo.pdf
http://www.reddit.com/r/programming/comments/dr6r4/talk_by_rob_pike_the_expressiveness_of_go_pdf/
This time I think I have understood most of the contents of the slides :-)
Few interesting quotations:
>From Page 18:
There are pointers but no pointer arithmetic
- pointers are important to performance, pointer arithmetic not.
- although it's OK to point inside a struct.
- important to control layout of memory, avoid allocation
Increment/decrement (p++) are statements, not expressions.
- no confusion about order of evaluation
Addresses last as long as they are needed.
- take the address of a local variable, the implementation
guarantees the memory survives while it's referenced.
No implicit numerical conversions (float to int, etc.).
- C's "usual arithmetic conversions" are a minefield.
>From page 19 and 20:
Constants are "ideal numbers": no size or sign, hence no L
or U or UL endings.
Arithmetic with constants is high precision. Only when
assigned to a variable are they rounded or truncated to fit.
A typed element in the expression sets the true type of the constant.
>From page 40:
Goroutines have "segmented stacks":
go f()
starts f() executing concurrently on a new (small) stack.
Stack grows and shrinks as needed.
No programmer concern about stack size.
No possibility for stack overflow.
A couple of instructions of overhead on each function call, a
huge improvement in simplicity and expressiveness.
>From page 46:
The surprises you discover will be pleasant ones.
--------------------
Some comments:
- In my D programs I sometimes use pointers, but pointer arithmetic is indeed uncommon.
- Turning x++; into statements seems harsh, but indeed it solves some problems. In practice in my D programs the ++ is often used as a statement, to avoid bugs.
- I think that "take the address of a local variable, the implementation guarantees the memory survives while it's referenced." means that it gets copied on the heap.
- Constants management in Go: seems cute.
- Segmented stack: allows to avoid some stack overflows at the price of a bit of delay at calling functions.
- The comment from 46 refers to a language that is orthogonal, and I think it is probably very correct. It's one of the main advantages of an orthogonal design, you are free to create many combinations.
--------------------
On the Go site there is a "playground", similar to what Ideone and Codepad sites offer for D2/D1. It contains some small programs, and you may modify them and compile almost arbitrary Go code.
A little Go example in the playground shows closures and the comma/tuple syntax similar to Python one:
package main
// fib returns a function that returns
// successive Fibonacci numbers.
func fib() func() int {
a, b := 0, 1
return func() int {
a, b = b, a+b
return b
}
}
func main() {
f := fib()
// Function calls are evaluated left-to-right.
println(f(), f(), f(), f(), f())
}
Something similar in D2, D lacks a handy unpacking syntax, and I think currently it doesn't guarantee that functions get evaluated left-to-right:
import std.stdio: writeln;
int delegate() fib() {
int a = 0;
int b = 1;
return {
auto a_old = a;
a = b;
b = a_old + b;
return b;
};
}
void main() {
auto f = fib();
// function calls are not surely evaluated left-to-right
writeln(f(), " ", f(), " ", f(), " ", f(), " ", f());
}
Another example on the Go site, that shows the segmented stacks at work:
// Peano integers are represented by a linked list
// whose nodes contain no data (the nodes are the data).
// See: http://en.wikipedia.org/wiki/Peano_axioms
// This program demonstrates the power of Go's
// segmented stacks when doing massively recursive
// computations.
package main
// Number is a pointer to a Number
type Number *Number
// The arithmetic value of a Number is the count of
// the nodes comprising the list.
// (See the count function below.)
// -------------------------------------
// Peano primitives
func zero() *Number {
return nil
}
func isZero(x *Number) bool {
return x == nil
}
func add1(x *Number) *Number {
e := new(Number)
*e = x
return e
}
func sub1(x *Number) *Number {
return *x
}
func add(x, y *Number) *Number {
if isZero(y) {
return x
}
return add(add1(x), sub1(y))
}
func mul(x, y *Number) *Number {
if isZero(x) || isZero(y) {
return zero()
}
return add(mul(x, sub1(y)), x)
}
func fact(n *Number) *Number {
if isZero(n) {
return add1(zero())
}
return mul(fact(sub1(n)), n)
}
// -------------------------------------
// Helpers to generate/count Peano integers
func gen(n int) *Number {
if n > 0 {
return add1(gen(n - 1))
}
return zero()
}
func count(x *Number) int {
if isZero(x) {
return 0
}
return count(sub1(x)) + 1
}
// -------------------------------------
// Print i! for i in [0,9]
func main() {
for i := 0; i <= 9; i++ {
f := count(fact(gen(i)))
println(i, "! =", f)
}
}
It's easy to translate it to D:
import std.stdio: writeln;
struct Number {
Number* next;
this(Number* ptr) { next = ptr; }
}
// -------------------------------------
// Peano primitives
Number* zero() {
return null;
}
bool isZero(Number* x) {
return x == null;
}
Number* add1(Number* x) {
return new Number(x);
}
Number* sub1(Number* x) {
return x.next;
}
Number* add(Number* x, Number* y) {
if (isZero(y))
return x;
return add(add1(x), sub1(y));
}
Number* mul(Number* x, Number* y) {
if (isZero(x) || isZero(y))
return zero();
return add(mul(x, sub1(y)), x);
}
Number* fact(Number* n) {
if (isZero(n))
return add1(zero());
return mul(fact(sub1(n)), n);
}
// -------------------------------------
// Helpers to generate/count Peano integers
Number* gen(int n) {
if (n <= 0)
return zero();
return add1(gen(n - 1));
}
int count(Number* x) {
if (isZero(x)) {
return 0;
}
return count(sub1(x)) + 1;
}
// -------------------------------------
void main() {
foreach (i; 0 .. 11) {
int f = count(fact(gen(i)));
writeln(i, "! = ", f);
}
}
But compiled normally on Windows leads to a stack overflow, you need to add a -L/STACK:10000000
Bye,
bearophile
More information about the Digitalmars-d
mailing list