Juliusz, Thank you. That's very interesting.
Code should be correct, maintainable, robust, readable, and reasonably efficient. Readablity is a prerequisite for the other properties. I glanced at babelweb2 (https://github.com/Vivena/babelweb2/). A code review would be useful. For example, from parser/parser.go: func nextWord(s *Scanner) (string, error) { more := s.Scan() if more { if s.Text() == "\n" { return "", errEOL } else { return s.Text(), nil } } err := s.Err() if err == nil { return "", io.EOF } return "", err } This is more complicated than it needs to be: more := s.Scan() if more { // . . . } Simplifying: if s.Scan() { // . . . } This is more complicated than it needs to be (Indent Error Flow: https://github.com/golang/go/wiki/CodeReviewComments#indent-error-flow): if s.Text() == "\n" { return "", errEOL } else { return s.Text(), nil } Simplifying: if s.Text() == "\n" { return "", errEOL } return s.Text(), nil It's now obvious that s.Text() is executed twice for each word and once for EOL. s.Text() is an allocation and a copy (string(bufio.s·2.token)). "Text returns the most recent token generated by a call to Scan as a newly allocated string holding its bytes." https://golang.org/pkg/bufio/#Scanner.Text Factoring out word: word := s.Text() if word == "\n" { return "", errEOL } return word, nil The err test is backwards (Indent Error Flow: https://github.com/golang/go/wiki/CodeReviewComments#indent-error-flow): err := s.Err() if err == nil { return "", io.EOF } return "", err Reorganizing: err := s.Err() if err != nil { return "", err } return "", io.EOF Or, (If statements: https://golang.org/ref/spec#If_statements): if err := s.Err(); err != nil { return "", err } return "", io.EOF To summarize: func nextWord(s *Scanner) (string, error) { if s.Scan() { word := s.Text() if word == "\n" { return "", errEOL } return word, nil } if err := s.Err(); err != nil { return "", err } return "", io.EOF } Peter On Saturday, July 29, 2017 at 12:51:48 PM UTC-4, Juliusz Chroboczek wrote: > > Dear all, > > I've just finished supervising three fourth year students doing > a month-long summer project in Go. I thought some of you might be > interested in my conclusions. > > The students were decent C programmers but had more experience with Java > (and I am not an experienced Go programmer myself). After a few days of > frustration, they had accepted that one does not build complex class > hierarchies in Go, and that one should just start writing code straight > away. They did attempt to write complex frameworks for channel > communication, I blame Java. > > Surprisingly enough, they had no issue at all with = vs. :=. > > They did find slices difficult to grasp. In particular, they thought > that slices alleviated the need for circular buffers, which obviously > caused massive memory leaks. Half an hour drawing boxes on a blackboard > solved this particular problem. > > They did find the behavious of defer confusing -- they expected it to be > lexically scoped. They initially wrote code such as the following: > > for .... { > conn, err = net.Dial(...) > defer conn.Close() > ... > } > > and were surprised that it caused a descriptor leak -- they were > expecting the defer to execute at the end of the enclosing block. > > They did find it surprising that multiple goroutines could write to the > same channel at the same time. In order to implement a fan-in, they > initially built a slice of channels and did a reflect.Select in the > reader. They were delighted to learn that they could use a single > channel and no select was necessary. > > One of them started using closures straight away, and even stored > closures in dictionaries. (They had had some exposure to Caml.) > > To my surprise, they wrote a fair amount of weakly-typed code (using > interface{}). Some of it was simulating generics, so I asked them to > write it monomorphically (the collection structure they implemented is > only used at one type in this particular program). Much of it, however, > was for good reasons, so perhaps this is a consequence of the problem > being solved here. > > Oh -- and I never managed to convince them that a Makefile is not needed. > > In case you're interested, the code is at > > https://github.com/Vivena/babelweb2 > > and an online demo (somewhat boring right now) is running at > > http://babelweb.wifi.pps.univ-paris-diderot.fr:8080/ > > -- Juliusz > > -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.