weekly.2011-11-18

219 views
Skip to first unread message

Andrew Gerrand

unread,
Nov 18, 2011, 3:39:36 PM11/18/11
to golang-nuts
We've just tagged a new Go weekly, weekly.2011-11-18. As usual, you
can update by running:
hg pull
hg update weekly

This release includes some language changes.

Map and function value comparisons are now disallowed (except for comparison
with nil) as per the Go 1 plan. Function equality was problematic in some
contexts and map equality compares pointers, not the maps' content.

As an experiment, structs are now allowed to be copied even if they contain
unexported fields. This gives packages the ability to return opaque values in
their APIs.

Other changes:
* 6a, 8a: allow $(-1) for consistency with $1, $(1), $-1.
* 6l: code generation fixes (thanks Michał Derkacz).
* build: fix check for selinux allow_execstack on Fedora (thanks Bobby Powers).
* builtin: document delete.
* cgo: don't panic on undeclared enums/structs (thanks Rémy Oudompheng),
fix g0 stack guard.
* crypto/tls: fix handshake message test.
* crypto: update incorrect references to Cipher interface; should be Block.
* doc: clean ups, additions, and fixes to several documents.
* doc/install: add openbsd (thanks Joel Sing!).
* doc: link to Chinese translation of A Tour of Go.
* encoding/json: add marshal/unmarshal benchmark,
decode [] as empty slice, not nil slice,
make BenchmarkSkipValue more consistent.
* env.bash: check for presence of make/gmake (thanks Scott Lawrence).
* exp/sql: NumInput() allow -1 to ignore checking (thanks Yasuhiro Matsumoto),
add DB.Close, fix bugs, remove Execer on Driver (only Conn),
document that for drivers, io.EOF means no more rows,
add client side support for publickey auth (thanks Dave Cheney),
add direct-tcpip client support (thanks Dave Cheney),
change test listen address, also exit test if fails,
other fixes and improvements (thanks Dave Cheney).
* exp/terminal: rename shell to terminal and add SetSize.
* fcgi: fix server capability discovery.
* fmt: distinguish empty vs nil slice/map in %#v.
* gc: better error, type checks, and many fixes,
remove m[k] = x, false syntax (use delete(m, k) instead),
support for building with Plan 9 yacc (thanks Anthony Martin).
* go/printer: make //line formatting idempotent.
* godefs: delete, replaced by cgo -godefs.
* godoc: document -templates flag, fix remote search,
provide mode for flat (non-indented) directory listings.
* gofmt: leave nil nodes of the AST unchanged (thanks Rémy Oudompheng).
* html/template: indirect top-level values before printing.
* html: more parser improvements (thanks Andrew Balholm).
* http: fix serving from CWD with http.ServeFile,
make Dir("") equivalent to Dir(".").
* ld: fix .bss for ldpe (thanks Wei Guangjing).
* math/big: replace nat{} -> nat(nil).
* math: faster Lgamma (thanks Charles L. Dorian).
* mime: implement TypeByExtension for windows.
* misc/bbedit: error and rune support (thanks Anthony Starks).
* misc/benchcmp: benchmark comparison script.
* misc/emacs: add delete builtin (thanks Bobby Powers).
* misc/kate: add error and rune (thanks Evan Shaw).
* misc/notepadplus: error and rune support (thanks Anthony Starks).
* misc/windows: Windows installer in MSI format (thanks Joe Poirier).
* net, io/ioutil: remove use of os.Time (thanks Anthony Martin).
* net/http: fix EOF handling on response body (thanks Gustavo Niemeyer),
fix sniffing when using ReadFrom,
use t.Errorf from alternate goroutine in test.
* os: remove undocumented Envs (use os.Environ instead).
* reflect: empty slice/map is not DeepEqual to nil,
make Value an opaque struct.
* runtime, syscall: convert from godefs to cgo.
* runtime: add nanotime for Plan 9 (thanks Anthony Martin),
add timer support, use for package time,
avoid allocation for make([]T, 0).
* strconv: add Ftoa benchmarks, make Ftoa faster.
* syscall: delete syscall.Sleep, take over env implementation, use error.
* testing: add file:line stamps to messages, print results to standard output.
* text/template: refactor set parsing.
* time: add ISOWeek method to Time (thanks Volker Dobler).
* various: avoid func compare, reduce overuse of os.EINVAL + others.

Apologies if we missed anyone in the list above. We appreciate all your help.

To see a full list of changes between this and the previous weekly,
after updating, run:
hg log -r weekly.2011-11-09:weekly.2011-11-18

Enjoy.

Andrew

Steven Blenkinsop

unread,
Nov 19, 2011, 12:02:12 AM11/19/11
to Andrew Gerrand, golang-nuts
On Fri, Nov 18, 2011 at 3:39 PM, Andrew Gerrand <a...@golang.org> wrote:
As an experiment, structs are now allowed to be copied even if they contain
unexported fields.

Torn on this. While I dislike assignability being tied to visibility of fields, it's unfortunate not to have any method of preventing unsafe copying. Just in the past couple of weeks, I've seen a couple posts where people ran into the struct copying restriction where they truly were unwittingly doing something unsafe. Had they not run into it, debugging would have changed from explaining a rather simple compile-time error to figuring out wonky behaviour, or else hopefully noticing the mistake somewhere in somebody's code after they hopefully have noticed the incorrect behaviour and asked for help.

Ian Lance Taylor

unread,
Nov 19, 2011, 1:34:29 AM11/19/11
to Steven Blenkinsop, Andrew Gerrand, golang-nuts
Steven Blenkinsop <stev...@gmail.com> writes:

Note that a package can still prevent copying a struct in all cases by
returning an interface containing a pointer to a struct.

The question is what you can do with a struct with some unexported
fields. I see two possible uses for such a struct. 1) Perhaps the
struct value can not be casually copied for some reason. 2) Perhaps
some invariants need to be maintained for the struct fields.

Either or both of those goals can be achieved by returning an interface
containing the struct value or a pointer to the struct value. The
question is which goals the language supports when using a plain struct
value rather than an interface value. Before this change the language
supported goal 1 (with an exception: the value was copied when calling a
method with a value receiver). This change is an experiment in having
the language instead support goal 2.

Ian

Archos

unread,
Nov 19, 2011, 3:06:04 AM11/19/11
to golang-nuts

On Nov 18, 8:39 pm, Andrew Gerrand <a...@golang.org> wrote:
> As an experiment, structs are now allowed to be copied even if they contain
> unexported fields. This gives packages the ability to return opaque values in
> their APIs.
Before of this change, when I wanted to copy the struct of exec.Cmd
(function copyCmd in my code), I had a error at compile-time. Perfect.

But now, with this change, I can compile it without errors of
compiling *although it doesn't works* since I cann't run a command --
cmd.Wait()-- after of copy its struct. So this change could be source
of problems.


[1]: https://github.com/kless/GoStart/blob/master/gostart/gostart.go#L43

Mark Summerfield

unread,
Nov 19, 2011, 3:34:01 AM11/19/11
to Andrew Gerrand, golang-nuts
Hi Andrew,

On Sat, 19 Nov 2011 07:39:36 +1100
Andrew Gerrand <a...@golang.org> wrote:
> We've just tagged a new Go weekly, weekly.2011-11-18. As usual, you
> can update by running:
> hg pull
> hg update weekly

[snip]

(1) The first time I did ./all.bash the httputil test failed (error
output at the end of this email). The second time all tests passed.

(2) The %#v output for reflect Values has changed (I don't care but it
wasn't mentioned):

word := "Thing"
fmt.Printf("'%#v'\n", reflect.ValueOf(word))

weekly 2011-11-09:
'reflect.Value{Internal:"Thing", InternalMethod:0}'
weekly 2011-11-18 (newline added):
'reflect.Value{typ:(*reflect.commonType)(0x45a408),
val:(unsafe.Pointer)(0xf8400023c0), flag:0x182}'

(3) Now when I run hg identify I get moaned at because I'm using 1.6.4
(which is standard on Debian 6), rather than "1.9 or newer".

$ hg identify
... annoying moans elided...
b4a91b693374 weekly/weekly.2011-11-18
I'm using 64-bit Debian 6.

------------------------------------------------------------
test net/http/httputil
TEST FAIL net/http/httputil
make[1]: Entering directory `/home/mark/opt/go/src/pkg/net/http/httputil'
gotest -test.short -test.timeout=120
rm -f _test/net/http/httputil.a
6g -p net/http/httputil -o _gotest_.6 chunked.go dump.go persist.go reverseproxy.go chunked_test.go dump_test.go reverseproxy_test.go
rm -f _test/net/http/httputil.a
gopack grc _test/net/http/httputil.a _gotest_.6
2011/11/19 08:14:44 Unsolicited response received on idle HTTP channel starting with "H"; err=<nil>
panic: test timed out

goroutine 6 [running]:
testing.alarm()
/home/mark/opt/go/src/pkg/testing/testing.go:337 +0x47
created by time.goFunc
/home/mark/opt/go/src/pkg/time/sleep.go:86 +0x4a

goroutine 1 [chan receive]:
testing.RunTests(0x400c00, 0x696e88, 0x300000003, 0x2ba1d77d0f01, 0x1, ...)
/home/mark/opt/go/src/pkg/testing/testing.go:254 +0x6e7
testing.Main(0x400c00, 0x696e88, 0x300000003, 0x6a76f0, 0x0, ...)
/home/mark/opt/go/src/pkg/testing/testing.go:201 +0x62
main.main()
/home/mark/opt/go/src/pkg/net/http/httputil/_testmain.go:31 +0x91

goroutine 2 [timer goroutine (idle)]:
created by addtimer
/home/mark/opt/go/src/pkg/runtime/time.c:74

goroutine 4 [chan receive]:
net/http.(*persistConn).roundTrip(0xf8400560c0, 0xf840022880, 0x0, 0x0, 0x0, ...)
/home/mark/opt/go/src/pkg/net/http/transport.go:647 +0x284
net/http.(*Transport).RoundTrip(0xf840027640, 0xf84003c0e0, 0xf840026370, 0x0, 0x0, ...)
/home/mark/opt/go/src/pkg/net/http/transport.go:158 +0x1ef
net/http/httputil.DumpRequestOut(0xf84003c0e0, 0x41c801, 0x0, 0x0, 0x0, ...)
/home/mark/opt/go/src/pkg/net/http/httputil/dump.go:75 +0x195
net/http/httputil.TestDumpRequest(0xf840027f00, 0x410add)
/home/mark/opt/go/src/pkg/net/http/httputil/dump_test.go:109 +0x356
testing.tRunner(0xf840027f00, 0x696ea0, 0x0, 0x0)
/home/mark/opt/go/src/pkg/testing/testing.go:188 +0x38
created by testing.RunTests
/home/mark/opt/go/src/pkg/testing/testing.go:253 +0x6c7
gotest: "./6.out -test.short=true -test.timeout=120" failed: exit status 2
make[1]: *** [testshort] Error 2
make[1]: Leaving directory `/home/mark/opt/go/src/pkg/net/http/httputil'
make: *** [net/http/httputil.testshort] Error 1
------------------------------------------------------------


--
Mark Summerfield, Qtrac Ltd, www.qtrac.eu
C++, Python, Qt, PyQt - training and consultancy
"Programming in Go" - ISBN 0321774639
http://www.qtrac.eu/gobook.html

Florian Weimer

unread,
Nov 19, 2011, 5:34:07 AM11/19/11
to golan...@googlegroups.com
* Steven Blenkinsop:

> Torn on this. While I dislike assignability being tied to visibility of
> fields, it's unfortunate not to have any method of preventing unsafe
> copying. Just in the past couple of weeks, I've seen a couple posts where
> people ran into the struct copying restriction where they truly were
> unwittingly doing something unsafe.

It's also break encapsulation. Now that copying structs always works,
client code will rely on it. This means that you no longer can add a
private field which is not safe to copy to a struct where copying has
not yet been prohibited in the documentation.

Jan Mercl

unread,
Nov 19, 2011, 6:19:31 AM11/19/11
to golan...@googlegroups.com
I'm also -1 on this change.

Discussed here: http://groups.google.com/d/topic/golang-dev/5u-qhRtya8Y/discussion

John Asmuth

unread,
Nov 19, 2011, 7:41:09 AM11/19/11
to golan...@googlegroups.com
-1 from me too.

It may be surprising to a newbie, but it's a really safe restriction in practice.

Jonathan Amsterdam

unread,
Nov 19, 2011, 8:49:59 AM11/19/11
to golang-nuts
> It's also break encapsulation. Now that copying structs always works,
> client code will rely on it.  This means that you no longer can add a
> private field which is not safe to copy to a struct where copying has
> not yet been prohibited in the documentation.

The original rule also broke encapsulation: you couldn't add a private
field at all to a public struct which had only public fields.

Anyway, most of the time instead of this:

struct {
noncopyable T
}

you can write this:

struct {
noncopyable *T
}

The pointee cannot be copied by code outside the package if it is not
otherwise exposed. See the new implementation of os.File for an
example.

+1 for me. It enables immutable value types, which I find more and
more important in my life. It also simplifies generics.

Florian Weimer

unread,
Nov 20, 2011, 4:31:28 AM11/20/11
to golan...@googlegroups.com
* Jonathan Amsterdam:

>> It's also break encapsulation. Now that copying structs always works,
>> client code will rely on it.  This means that you no longer can add a
>> private field which is not safe to copy to a struct where copying has
>> not yet been prohibited in the documentation.
>
> The original rule also broke encapsulation: you couldn't add a private
> field at all to a public struct which had only public fields.

At least this results in a compile-time error. I guess it's also a
bad idea to mix exported and non-exported fields in the same struct.

> Anyway, most of the time instead of this:
>
> struct {
> noncopyable T
> }
>
> you can write this:
>
> struct {
> noncopyable *T
> }
>
> The pointee cannot be copied by code outside the package if it is not
> otherwise exposed. See the new implementation of os.File for an
> example.

Why does os.Open return a *os.File, and not an os.File? The former
approach achieves abstraction only through indirection, something Go
was set out to avoid. In contrast, returning an os.File (with the
inaccessible pointer embedded in it) seems quite appealing to me. If
programming interfaces are adjusted accordingly, the struct copying
change isn't so bad after all.

Jonathan Amsterdam

unread,
Nov 20, 2011, 8:29:29 AM11/20/11
to golang-nuts
> Why does os.Open return a *os.File, and not an os.File?

I suspect Russ didn't want to break the world for an experiment. That
is the natural next step.

Andrew Gerrand

unread,
Nov 20, 2011, 5:29:36 PM11/20/11
to golan...@googlegroups.com, Andrew Gerrand


On Saturday, November 19, 2011 7:34:01 PM UTC+11, Mark wrote:
Hi Andrew,

On Sat, 19 Nov 2011 07:39:36 +1100
Andrew Gerrand <a...@golang.org> wrote:
> We've just tagged a new Go weekly, weekly.2011-11-18. As usual, you
> can update by running:
>  hg pull
>  hg update weekly
[snip]

(1) The first time I did ./all.bash the httputil test failed (error
    output at the end of this email). The second time all tests passed.


It hpapens.
 

(2) The %#v output for reflect Values has changed (I don't care but it
    wasn't mentioned):

    word := "Thing"
    fmt.Printf("'%#v'\n", reflect.ValueOf(word))

    weekly 2011-11-09:
'reflect.Value{Internal:"Thing", InternalMethod:0}'
    weekly 2011-11-18 (newline added):
'reflect.Value{typ:(*reflect.commonType)(0x45a408),
val:(unsafe.Pointer)(0xf8400023c0), flag:0x182}'


The internal structure of reflect.Value changed, not "%#v". This change is listed in the notes:
  "reflect: make Value an opaque struct."
 

(3) Now when I run hg identify I get moaned at because I'm using 1.6.4
    (which is standard on Debian 6), rather than "1.9 or newer".

$ hg identify
... annoying moans elided...
b4a91b693374 weekly/weekly.2011-11-18
I'm using 64-bit Debian 6.


This is only for people using the codereview.py hg extension, that is no longer compatible with hg versions <1.9. If you disable codereview the warning will go away.

Andrew 
Reply all
Reply to author
Forward
0 new messages