Is it too rough to use a version to conrol Go features?

118 views
Skip to first unread message

tapi...@gmail.com

unread,
Mar 2, 2021, 6:14:23 AM3/2/21
to golang-nuts
Would be better to use compile flags to control each language features individually?

tapi...@gmail.com

unread,
Mar 2, 2021, 6:21:25 AM3/2/21
to golang-nuts
BTW, I think the embedding functionality introduced in Go 1.16 should not be viewed as a feature.
It should be viewed as an API change instead.
Now Go projects using embedding and setting go directive verison as v1.15 in go.mod fail to compile with Go toolchain 1.16.
IMO, this is unnecessary, for the "//go:embed" directive always requires importing the "embed" package.

Axel Wagner

unread,
Mar 2, 2021, 7:43:37 AM3/2/21
to tapi...@gmail.com, golang-nuts
There would be no advantage to that - all features are either available, or not available, depending on which version you use. There is no "go 1.16 without `embed`". It also needs to be set in `go.mod`, because you might compile modules written for different go versions into one binary - so which language version to use is part of the module description.
So, no. Putting a language version into `go.mod` seems to be exactly the right way to do this.

On Tue, Mar 2, 2021 at 12:21 PM tapi...@gmail.com <tapi...@gmail.com> wrote:
BTW, I think the embedding functionality introduced in Go 1.16 should not be viewed as a feature.
It should be viewed as an API change instead.

I don't understand what you mean by this. There is no intrinsic difference between the two. In this particular case, the `embed` package adds an API to support a new feature "embedding static files in go binaries".
 
Now Go projects using embedding and setting go directive verison as v1.15 in go.mod fail to compile with Go toolchain 1.16.

They shouldn't do that. If they use `embed`, they require at least go 1.16, so they set that.
I can't reproduce your claim that setting `go 1.15` and using embed will fail to compile with a Go 1.16 toolchain. It works fine for me.

IMO, this is unnecessary, for the "//go:embed" directive always requires importing the "embed" package.

On Tuesday, March 2, 2021 at 6:14:23 AM UTC-5 tapi...@gmail.com wrote:
Would be better to use compile flags to control each language features individually?

--
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...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/c8e1bd96-78e2-434a-a0cc-4356382e49fcn%40googlegroups.com.

Axel Wagner

unread,
Mar 2, 2021, 7:47:19 AM3/2/21
to tapi...@gmail.com, golang-nuts
Sorry, I have to walk that back - my test code was wrong, you are correct, compilation fails.
The point still stands - they require 1.16, so they set that, not 1.15. Either way - compilation will fail, why does it matter if it fails because `embed` doesn't exist before 1.16, or whether it fails because `//go:embed` is not supported before 1.16?

Axel Wagner

unread,
Mar 2, 2021, 7:50:15 AM3/2/21
to tapi...@gmail.com, golang-nuts
Okay, sorry for the multiple, quick mails, but:
I would even say it *has* to be done the way it is. Because otherwise compilation will *not* fail, if you declare a wrong go version to use. That is, if you use `//go:embed`, declare your used version as go 1.15 and test it yourself using go 1.16, your module is broken. Users of your module that only have go 1.15 will break and get a crypting error message about `embed` being missing, instead of a reasonable message that their go version is not fresh enough.
I don't understand why you'd want a broken module to compile.

tapi...@gmail.com

unread,
Mar 2, 2021, 8:18:48 AM3/2/21
to golang-nuts
What is the difference between "embed" and "io/fs"?
A Go project with version declared as 1.15 in go.mod and using "io/fs" compiles okay with Go toolchain 1.16.

Axel Wagner

unread,
Mar 2, 2021, 8:25:53 AM3/2/21
to tapi...@gmail.com, golang-nuts
Maybe it shouldn't.

FWIW, there is one significant difference, which is that `//go:embed` needs support from the go tool and compiler to work. That is, the files need to be read and we need to emit initialization code for the variables holding the embedded files. So, a go toolchain that is not aware of embedding can't possibly compile the code (correctly).

tapi...@gmail.com

unread,
Mar 2, 2021, 8:38:05 AM3/2/21
to golang-nuts
> Maybe it shouldn't.

By my knowledge, the version specified in go.mod doesn't prevent APIs newer than the version to be used. This is design.

=====

OK. It looks a Go project with version declared as 1.15 in go.mod and importing "embed" also compiles okay with Go toolchain 1.16
So the key distinction is whether there are "//go:embed" directives are used.
Here, I tested four setups (all with version declared as 1.15 in go.mod and compile with Go toolechain 1.16:
1. a source file importing "io/fs". It compiles okay.
2. a source file importing "embed" but not using "//go:embed". It also compiles okay.
3. a source file importing "embed" and using "//go:embed". It fails to compile with an error "go:embed requires go1.16 or later (-lang was set to go1.15; check go.mod)"
4. a source file importing using "//go:embed" and not importing 1.16 new packages. It fails to compile with an error "usage: //go:embed pattern...".

I don't know whether or not it is intended to let the latter two cases report different errors.

tapi...@gmail.com

unread,
Mar 2, 2021, 8:41:29 AM3/2/21
to golang-nuts
sorry, the 4th setup reports "//go:embed only allowed in Go files that import "embed"".
Reply all
Reply to author
Forward
0 new messages