In October of 1979 I had a pre-processor, called Cpre, that added Simula-like classes to C running and in March of 1980 this pre-processor had been refined to the point where it supported one real project and several experiments. My records show the pre-processor in use on 16 systems by then. The first key C++ library, the task system supporting a co-routine style of programming, was crucial to the usefulness of "C with Classes," as the language accepted by the pre-processor was called, in these projects.



go generate

#!/usr/bin/env python from collections import namedtuple Person = namedtuple('Person', ['first_name', 'last_name', 'hair_color']) people = [ Person('Sideshow', 'Bob', 'red'), Person('Homer', 'Simpson', 'n/a'), Person('Lisa', 'Simpson', 'blonde'), Person('Marge', 'Simpson', 'blue'), Person('Mr', 'Burns', 'gray'), ] joined = '

'.join(repr(x) for x in people) print 'My favorite Simpsons Characters:

%s' % joined

'

'.join(repr(x) for x in people)

repr

join

My favorite Simpsons Characters: Person(first_name='Sideshow', last_name='Bob', hair_color='red') Person(first_name='Homer', last_name='Simpson', hair_color='n/a') Person(first_name='Lisa', last_name='Simpson', hair_color='blonde') Person(first_name='Marge', last_name='Simpson', hair_color='blue') Person(first_name='Mr', last_name='Burns', hair_color='gray')

fmt.Stringer

With

[]fmt.Stringer

Person

package main import ( "fmt" "strings" ) type Join []fmt.Stringer func (j Join) With(sep string) string { stred := make([]string, 0, len(j)) for _, s := range j { stred = append(stred, s.String()) } return strings.Join(stred, sep) } type Person struct { FirstName string LastName string HairColor string } func (s *Person) String() string { return fmt.Sprintf("%#v", s) } func main() { people := []Person{ Person{"Sideshow", "Bob", "red"}, Person{"Homer", "Simpson", "n/a"}, Person{"Lisa", "Simpson", "blonde"}, Person{"Marge", "Simpson", "blue"}, Person{"Mr", "Burns", "gray"}, } fmt.Printf("My favorite Simpsons Characters:%s

", Join(people).With("

")) }

./bad_example.go:40: cannot convert people (type []Person) to type Join

Join(people)

fmt.Stringer

Person

String

fmt.Stringer

type Joinable []fmt.Stringer func Join(in []fmt.Stringer) Joinable { out := make(Joinable, 0, len(in)) for _, x := range in { out = append(out, x) } return out } func (j Joinable) With(sep string) string { stred := make([]string, 0, len(j)) for _, s := range j { stred = append(stred, s.String()) } return strings.Join(stred, sep) }

./bad_example2.go:51: cannot use people (type []Person) as type []fmt.Stringer in argument to Join

fmt.Stringer

Person

[]Person

Person

[]fmt.Stringer

go generate

go generate

join

go generate

go run *.go

package main //go:generate joiner $GOFILE import ( "fmt" ) // @joiner type Person struct { FirstName string LastName string HairColor string } func main() { people := []Person{ Person{"Sideshow", "Bob", "red"}, Person{"Homer", "Simpson", "n/a"}, Person{"Lisa", "Simpson", "blonde"}, Person{"Marge", "Simpson", "blue"}, Person{"Mr", "Burns", "gray"}, } fmt.Printf("My favorite Simpsons Characters:

%s

", JoinPerson(people).With("

")) }

// @joiner

type

go install https://github.com/bslatkin/joiner

go generate

main_joiner.go

// generated by joiner -- DO NOT EDIT package main import ( "fmt" "strings" ) func (t Person) String() string { return fmt.Sprintf("%#v", t) } type JoinPerson []Person func (j JoinPerson) With(sep string) string { all := make([]string, 0, len(j)) for _, s := range j { all = append(all, s.String()) } return strings.Join(all, sep) }

go run *.go

My favorite Simpsons Characters: main.Person{FirstName:"Sideshow", LastName:"Bob", HairColor:"red"} main.Person{FirstName:"Homer", LastName:"Simpson", HairColor:"n/a"} main.Person{FirstName:"Lisa", LastName:"Simpson", HairColor:"blonde"} main.Person{FirstName:"Marge", LastName:"Simpson", HairColor:"blue"} main.Person{FirstName:"Mr", LastName:"Burns", HairColor:"gray"}

go generate

go generate