3 ms·
You might be interested in my side project: https://github.com/lukechampine/ply https://github.com/lukechampine/ply IMO when people say they want generics in G
by nemo1618 10y ago
You might be interested in my side project: https://github.com/lukechampine/ply https://github.com/lukechampine/ply
IMO when people say they want generics in Go, they really just want a few functional-style methods and functions on slices (e.g. map, filter, reduce methods, and functions like sort, reverse, repeat). So I wrote a compile-to-Go language that allow you to write "Go code" that also has those things.
One of the things I've found, though, is that Go's first-class function syntax really harms the elegance of these sorts of constructions. For example, compare:
// square a slice of ints in Go
for x := range xs {
x *= x
}
// square a slice of ints in Ply (morph == map)
xs.morph(func(x int) int {
return x*x
})
When really, we want something like:
xs.map(x => x*x)
I think it's possible to achieve the latter without having to write a new lexer/parser/typechecker from scratch, but for now I'm avoiding adding any new syntax.
- woah 10y agoWouldn't xs.map((x int) int => x*x) be simple desugaring without messing with the type system?
- nemo1618 10y agoPerhaps, but you aren't saving a ton of typing if you still need to specify all the types. I think you can get away with xs.morph(x => x*x) because you know that xs is a slice of ints, so x must be an int, and that means x*x is an int, so the lambda has the right type signature. As far as I can see, there are two potential annoyances with this approach: you have to explicitly cast constants sometimes (e.g. uint64(3) instead of just 3), and you have to explicitly cast values if you want to return an interface (e.g. io.Writer(file) instead of just file). But these cases are rare enough that I think the tradeoff is worth it.