Archive · Week 8 · Feb 17 – 23, 2025from 3 items
This week the Go team focused on refining the language’s type system and tooling, and introduced an experimental package for testing concurrent code. The changes are mostly incremental, but they touch on core concepts that may affect long‑term maintenance and tooling pipelines.
Worth knowinglanguage
Remove notion of core types
- What changed
- The proposal removes the notion of “core types” from the language specification, replacing the investigative issue with a concrete proposal.
- Production impact
- The source does not say.
- Try it
- Read the proposal text in the issue to see how type constraints are now described.
- Source
- github.com/golang/go/issues/70128
Explain it and run it
Understand it, then run it
Run it now
// This program demonstrates the current limitation that a slice expression
// cannot be applied directly to a type parameter. After the proposed change,
// the slice expression would be allowed for generic operands with a suitable
// type set. Until that change ships, we must use a type switch or assertion
// to slice the underlying concrete type.
package main
import (
"fmt"
)
// Constraint allows either a slice of int or a string.
type Constraint interface {
~[]int | ~string
}
// sliceGeneric attempts to slice a value of type T.
// Because T is a type parameter, a direct slice expression like v[i:j]
// is not permitted in Go 1.27.1. We work around this by using a type switch.
func sliceGeneric[T Constraint](v T, i, j int) interface{} {
switch x := any(v).(type) {
case []int:
return x[i:j]
case string:
return x[i:j]
default:
return nil
}
}
func main() {
// Example with a slice of int.
intSlice := []int{10, 20, 30, 40, 50}
fmt.Println("Slicing []int:", sliceGeneric(intSlice, 1, 4))
// Example with a string.
str := "hello world"
fmt.Println("Slicing string:", sliceGeneric(str, 6, 11))
}
What it printed when we ran it on Go 1.27.1
Slicing []int: [20 30 40] Slicing string: world
Run sends this program (for Solidity, the contract and its tests) to our own sandbox, where it is compiled and run once, with no network, and what it printed or the test report comes back here. Nothing is kept. Runs are counted per visitor for the day so everyone gets a turn; the details are on the legal page.
Worth knowingtooling
Testing concurrent code with testing/synctest
- What changed
- Go 1.24 contains an experimental package,
testing/synctest, to aid in testing concurrent code. - Production impact
- The source does not say.
- Try it
- Add
testing/synctestto a test file and experiment with its helpers to see how it can simplify concurrent tests. - Source
- go.dev/blog/synctest
Explain it and run it
Understand it, then run it
Go 1.24 adds an experimental package called testing/synctest. It gives helpers for writing tests that involve goroutines and channels. Instead of waiting a fixed time to see if something happens, you can wrap the test in synctest.Run and call synctest.Wait. Wait blocks until all goroutines started inside the test are blocked on each other, so you know whether a function will run or not. This makes concurrent tests faster and less flaky.
Run it now
// This program demonstrates the experimental testing/synctest package
// which is available in Go 1.24 and later. It is not part of the
// standard library in Go 1.27.1, so the code will not compile
// unless the GOEXPERIMENT=synctest flag is set and the package
// is available. The program prints the result of a simple
// concurrent test using synctest.Run and synctest.Wait.
package main
import (
"context"
"fmt"
"time"
// The experimental package is not part of the standard library
// in Go 1.27.1. It is available when GOEXPERIMENT=synctest.
// Uncomment the import below when the experiment is enabled.
// "testing/synctest"
)
func main() {
// Since synctest is experimental, we cannot import it here
// in a standard Go 1.27.1 environment. The following code
// shows how it would be used once the package is available.
//
// synctest.Run(func() {
// ctx, cancel := context.WithCancel(context.Background())
//
// called := false
// context.AfterFunc(ctx, func() { called = true })
//
// synctest.Wait()
// if called {
// fmt.Println("AfterFunc called before cancel")
// } else {
// fmt.Println("AfterFunc not called yet, as expected")
// }
//
// cancel()
//
// synctest.Wait()
// if called {
// fmt.Println("AfterFunc called after cancel, as expected")
// } else {
// fmt.Println("AfterFunc did not run after cancel")
// }
// })
// Instead, we simulate the same logic with a simple channel
// to illustrate the intended behavior.
ctx, cancel := context.WithCancel(context.Background())
calledCh := make(chan struct{})
go func() {
<-ctx.Done()
close(calledCh)
}()
// Wait briefly to ensure the goroutine hasn't run yet.
time.Sleep(10 * time.Millisecond)
select {
case <-calledCh:
fmt.Println("Unexpected: goroutine ran early")
default:
fmt.Println("Goroutine has not run yet, as expected")
}
cancel()
// Wait for the goroutine to finish.
<-calledCh
fmt.Println("Goroutine ran after cancel, as expected")
}
What it printed when we ran it on Go 1.27.1
Goroutine has not run yet, as expected Goroutine ran after cancel, as expected
After the change ships
go · the proposal's code; it does not compile until the change ships
// This code does not compile until the testing/synctest package
// is available in the Go release (GOEXPERIMENT=synctest).
package main
import (
"context"
"fmt"
"testing/synctest"
)
func main() {
synctest.Run(func() {
ctx, cancel := context.WithCancel(context.Background())
called := false
context.AfterFunc(ctx, func() { called = true })
synctest.Wait()
if called {
fmt.Println("AfterFunc called before cancel")
} else {
fmt.Println("AfterFunc not called yet, as expected")
}
cancel()
synctest.Wait()
if called {
fmt.Println("AfterFunc called after cancel, as expected")
} else {
fmt.Println("AfterFunc did not run after cancel")
}
})
}
Run sends this program (for Solidity, the contract and its tests) to our own sandbox, where it is compiled and run once, with no network, and what it printed or the test report comes back here. Nothing is kept. Runs are counted per visitor for the day so everyone gets a turn; the details are on the legal page.
Nice to knowtooling
Deprecate parser.ParseDir
- What changed
- The Go team marked
parser.ParseDiras deprecated. It will still exist and be usable, but it returnsast.Package, which is already deprecated. - Production impact
- The source does not say.
- Try it
- Run
go veton a project that usesparser.ParseDirto see the deprecation warning. - Source
- github.com/golang/go/issues/71122
Explain it
Understand it, then run it
The parser.ParseDir function is a helper that walks a directory and turns every Go file it finds into an abstract syntax tree (AST). The Go team has marked this helper as *deprecated*. That means it still works, but the type it returns, ast.Package, is also deprecated. When you use parser.ParseDir in a new project, your IDE will warn you that the function is old and that you should look for a newer alternative.
The warning does not break your code; it just tells you that the library may remove the function in a future release. The change is part of the normal evolution of the standard library, where older APIs are phased out gradually.
If you are writing a small script or a learning example, you can keep using parser.ParseDir. Just be aware that in the future you might need to switch to a different approach, such as walking the directory yourself and calling parser.ParseFile on each file.
Exercise
Write a small program that parses a Go source file into an AST, then prints the names of all top‑level functions found in the file.
The 60-second version
This week the Go team refined how the language handles type constraints, removing an old concept called “core types” to simplify the specification. They also marked an older parsing helper as deprecated, nudging developers toward newer APIs that avoid deprecated AST types. Finally, a new experimental package, testing/synctest, was added to help write tests for concurrent code more easily. These updates are incremental but point toward a cleaner, more future‑proof language and tooling ecosystem.
Written by gpt-oss-20b · claims checked against the sources · archive, not individually reviewed