val _ = binds nothingWhen it fires. A declaration has _ as its only name and a value:
val _ = expr, var _ = expr, the same with a type (val _ T = expr), or
_ := expr. _ binds nothing, so the declaration only evaluates expr —
which is what the expression does on its own, written as a statement.
Minimal repro.
package main
func save(name string) bool {
Println(s"saved $name")
return true
}
func main() {
val _ = save("report")
}
Error output.
error[GALA-E0060]: `val _ = ...` binds nothing
--> main.gala:9:5
|
9 | val _ = save("report")
| ^^^^^ write the expression as a bare statement
|
= hint: write the expression as a bare statement; if the value matters, bind it to a name and use it
Inside a lambda the hint also names FromError, because in a lambda with no
result a call that returns only an error cannot be a bare statement:
package main
import (
"os"
. "martianoff/gala/collection_immutable"
)
func main() {
ArrayOf("a.tmp", "b.tmp").ForEach((p) => {
val _ = os.Remove(p)
})
}
error[GALA-E0060]: `val _ = ...` binds nothing
--> main.gala:10:9
|
10 | val _ = os.Remove(p)
| ^^^^^ write the expression as a bare statement
|
= hint: write the expression as a bare statement; in a lambda with no result, a call that returns only an `error` becomes `FromError(call())`; if the value matters, bind it to a name and use it
At package level there are no statements, so the hint points at func init():
package main
func register(name string) bool {
Println(s"registered $name")
return true
}
var _ = register("report")
func main() {}
error[GALA-E0060]: `var _ = ...` binds nothing
--> main.gala:8:1
|
8 | var _ = register("report")
| ^^^^^ to run it for its effect, call it from `func init()`
|
= hint: to run it for its effect, call it from `func init()`; if the value matters, bind it to a name and use it
Fix. Write the expression as a statement:
package main
func save(name string) bool {
Println(s"saved $name")
return true
}
func main() {
save("report")
}
If the value matters, give it a name and use it:
package main
func save(name string) bool {
Println(s"saved $name")
return true
}
func main() {
val saved = save("report")
Println(s"saved: $saved")
}
In a lambda with no result, a call that returns only an error cannot be a
bare statement — GALA refuses to drop the error silently there. Wrap it in
FromError, which turns the error into a Try[Void] you can inspect or
ignore:
package main
import (
"os"
. "martianoff/gala/collection_immutable"
)
func main() {
ArrayOf("a.tmp", "b.tmp").ForEach((p) => {
FromError(os.Remove(p))
})
}
At package level, move the call into func init():
package main
func register(name string) bool {
Println(s"registered $name")
return true
}
func init() {
register("report")
}
func main() {}
What still works. _ keeps every other meaning it has:
val n, _ = strconv.Atoi(s), n, _ := strconv.Atoi(s),
val (_, b) = pair, var (_, d) = pair;(_ int) => 0), a match pattern (case _ =>) or a
for range variable (for _, x := range xs);var _ T with no value.A typed val _ Shape = Circle(1.0) is rejected too. It needs no replacement as
a conformance check: GALA already checks that a Circle is a Shape wherever
one is used as the other.
Rationale. val _ = reads as if something were kept, but nothing is.
Writing the expression on its own says exactly what happens: it runs for its
effect and its value is dropped. The one place a bare statement is refused —
an error in a lambda with no result — is refused on purpose, and val _ =
(with or without a type) was a way around that check; FromError keeps the
error visible instead.