Meow Programming Language v0.21.1: A Top-Level Function Named Rather Than Called
Released 2026-08-20. v0.21.0 made a member readable as a value. A plain top-level function was still not one, and saying so leaked Go’s own complaint:
meow greet(who string) string { bring "hi " + who }
nya(greet)
cannot use greet (value of type func(who string) string) as meowrt.Value value
in argument to meow.Nya: func(who string) string does not implement meowrt.Value
Not a Hiss!, and not something a Meow program could act on. It was not only
nya — no top-level function could be used as a value at all, so the plainest
functional idiom did not work:
meow double(n int) int { bring n * 2 }
nya(lick([1, 2], double)) # the same Go error
nya(lick([1, 2], paw(n) { bring double(n) })) # what you had to write instead
A function named rather than called is the function
meow double(n int) int {
bring n * 2
}
meow join(a string, b string) string {
bring a + "-" + b
}
nyan f = double
nya(f(21)) # 42
nya(3 |=| double) # 6
nya(lick([1, 2, 3], double)) # [2, 4, 6]
nya(double) # <meow double>
nyan greet = join("hi") # already worked: a partial call
nya(greet("nyan")) # hi-nyan
A top-level function is a plain Go function, which nothing taking a Meow value can be handed, so it is wrapped into the value it has to be — the same wrapper a call with too few arguments already makes, with none of them supplied. Arity and currying therefore come out of the existing path rather than a new one.
Shadowing
A name a local has taken over is still the local’s. What says so is the type recorded for that very occurrence, resolved by the checker in the scope it was written in:
meow greet(who string) string { bring "hi " + who }
meow a() string { nyan greet = "shadowed" bring greet } # shadowed
meow b() litter { nyan greet = [1, 2] bring greet } # [1, 2]
nya(greet("nyan")) # hi nyan — still the top-level one
nyan g = greet
nya(g("again")) # hi again
A nested meow is already held as a value and needs no wrapping.
The playground’s interpreter had always answered this correctly — only the compiled path could not — so this release is where the two backends agree again, with a test pinning the agreement.
Upgrading
Purely additive: programs that wrapped a function in a paw to hand it to
lick or a pipe still work, and can now drop the wrapper.
brew upgrade meow
# or
go install github.com/135yshr/meow/cmd/meow@v0.21.1
One thing this release did not fix, found on the way: calling through a name a local has taken over still went to the top-level function. That is v0.21.2.