Go 1.9 Beta 1 release notes
tip.golang.org
tip.golang.org
- net.Resolver.Dial allows doing all DNS resolution myself, right in the same process (via a localhost port). And nice it can do both UDP and TCP.
- SyscallConn providing access to the underlying file descriptor is super useful too.
- monotonic time is very useful in network protocols.
- concurrent.Map is nice too.
Good stuff.
Check the discussion, as usual things aren't as simple as they seem: https://github.com/golang/go/issues/18616
On Unix systems the environment variables SSL_CERT_FILE and SSL_CERT_DIR can now be used to override the system default locations for the SSL certificate file and SSL certificate files directory, respectively.
The os/exec package now prevents child processes from being created with any duplicate environment variables. If Cmd.Env contains duplicate environment keys, only the last value in the slice for each duplicate key is used.
We went with the bash behavior (latest one wins), which also means all the code previously using:
cmd.Env = append(os.Environ(), "KEY=newvalue")
... now actually works reliably. Previously, if KEY=oldvalue was already defined, what you got depended on your luck with the child program. Either old, new, or random.
File a bug if you see a regression.
If you really want to do something nasty and intentionally confuse your child processes, the lower-level os.StartProcess and syscall packages are there for you. :)
This will fix so much pain that my team is having right now. I am glad that it finally is available.
type T1 = T2
I'm currently writing a pretty large project in Haskell and am thoroughly enjoying it -- as everyone and their mother says, the type system is superb, and even simple aliases like: type UserID = Int
Make it so much easier to read and understand functions. type Celsius int
that in theory prevent you from passing a bare int and mixing up Celsius/Fahrenheit.In go this almost works. If you define
type Celsius int
func isBoiling(t Celsius) bool {
return t >= 100
}
then You need to call it by doing something like t := Celsius(100)
isBoiling(t)
and just t := 212
isBoiling(t)
will not compile with cannot use t (type int) as type Celsius in argument to isBoiling
But unfortunately you can get away with isBoiling(212)
However, If you just used a type alias then you'd be able to do either.This would define a new, non-interchangeable type, even though it's just an int behind the scenes. The new type alias on the other hand define a new name for an existing type; you still have just one type. In the user ID example above that's not what you want, it would allow using an int where a UserID is required.
It is not due to some unkind turn of fortune that the Go type system drops the ball here and there.
> However, If you just used a type alias then you'd be able to do either.
The important distinction between a type and an alias is that you can define methods for a type and you can not do the same for an alias.
I don't know that I would build the same kind of type machinery though (I might only use the alias, not the actual type), since a call like
isBoiling(212)
would fall apart.In particular, I think the type aliasing will make function signatures a lot clearer -- if I to write a `Celsius` type class, I would likely just make a small, hopefully simple `Temperature` type. Unfortunately last time I wrote any Go code, I wasn't anywhere near that careful/purposeful with the types (I mostly left things as `int`s, etc)
You can't get away with:
isBoiling(Fahrenheight(212))
cannot use 212 (type Fahrenheight) as type Celsius in argument to isBoiling func Fahrenheight(f int) Celsius {
return Celsius(5*(f-32)/9)
} type (
Celsius float64
Fahrenheit float64
)This then avoids the patch of 40k lines changed as you can gradually go to different teams and get a checkmark that the changes you made to the teams code is still going to work as expected. This is usually better coordination-wise than a 40k line patch everyone has to sign off on.
I presume that those environment variables override the defaults at runtime, but it would be good to call that out explicitly since we are talking about a compiler release and there are compilers that can evaluate environment variables at compile time to allow for more flexible constant runtime values.
I haven't seen anything about it, which I absolutely love (based on fear of a Python 3 situation).
I think even major (=with source-level breaking changes) version bumps are feasible specifically with compiled languages. This is because you can still continue to support the both versions of the language in the compiler, and if you are careful with semantic changes, you can support linking packages of two different versions together.
Additionally, if you start designing breaking changes from the start with the mentality that an automatic tool should be able to upgrade the code base, that eases up the migration a lot. (There is 2to3 with Python, but that didn't always work, which to me means that the language changes weren't exiplicitly designed to be automatically upgradable.)
Btw. I wrote this thinking that a major version bump means source-level incompatibilities – but it's possible, although challenging, to introduce major new features even without.
If/when it happens, it won't be scary.
Go's debugging story, for things using cgo, has been a bit of a rude shock (to me). As of yesterday's toolchain updates (Gogland, Delve), single stepping on Linux is now working reliably (eg not randomly hanging).
It still needs to be improved so instructions execute in the order they're written (eg more disabling of compiler optimisations when debugging), but that's less important than fixing the "ugh, it's just hung again!" bug was.
Hopefully OSX debugging gets to a similar (working ok) state soon too. :)
Only sorta kidding... Personally, I think sync.Map is a dangerous addition to the standard library, and hope that the Go team does not encourage using the empty interface{}'s like this. I can only imagine how bad it'll feel when someone reads an int64 as an int.
Personally I would already be happy with what CLU allowed for in 1975, no need for anything more expressive.
In fact, if I could get a) a type safe concurrent map b) a promise/future construct and c) a fast concurrent queue for single writer multi-reader, I'd probably be ok with the set of generic data structures provided in the language.
If they fixed their variance rules along the way as well, I'd probably lose any actual arguments against the type system when it comes to the systems I build.
The question is of course, are those the only ones that fall into that category? Who knows but those are the ones I run into the most pain for.
Unlike C void-pointer, interface{} is the tuple (type, value) and you need a type assertion for the right tipe to get the value.
As for time, on Linux it got 70 ns slower. Tolerable. (It went from 70 ns to 140 ns on my GCE VM)
On Windows, it actually got faster on 64-bit with the addition of:
https://github.com/golang/go/commit/e4371fb179ad69cbd057f243...
And on macOS, where nobody runs servers, it's basically unchanged speed-wise.
Before she releases it, both Bob and Cathy ask for it.
So it goes to Cathy when it's released.
Before Cathy releases it, David requests it.
If the lock goes to David (and then possibly Emma, Fred, and Gary, and so on forever) before Bob finally gets to continue executing, then the lock is not fair.