I have been playing with a new language feature I haven’t seen anywhere and I wanted to share it with you. I am currently implementing a prototype for my own language but it would be absolutely gorgeous to have it in Scala as well. I call it Literal Abstraction
because it does just that, it abstracts over a variable in a term using a literal supplied at compile time:
def foreach[A, B](literal x, seq: Seq[A])(f[x]: A => B) = seq.foreach(f)
In the above definition, the literal parameter comes first in the parameter list. More importantly though, f[x]
means “when applying an argument for f, make sure to abstract over the variable bound to x” This means that all parameters that are concerned with literal abstractions (i.e. the literal parameter itself and terms binding the variable) have to be filled in at once. Sadly, this would somewhat restrict currying, even preventing it entirely in cases where the first and last parameter “know about something regarding literals”. Anyway, an example invocation of the function declared above could like this:
foreach(x, List(1,2,3)) {
println(x * x)
}
This is a simple case where the literal abstraction basically replaces the need to introduce a named parameter for the lambda. A slightly more interesting case would be custom syntax for lambda expressions such as
// using the new extension method syntax of dotty <3
def [A, B](literal x) ~> (f[x]: A => B) = f
val lambda = a ~> println(a)
Something that might require some tinkering is literal parameters with varying arity. After all, how could one define multi-param lambdas this way?
type VarTypeArg = ??? // As far as I know, this isn't possible
def [VarTypeArg, B](literal ...xs) ~> (f[xs]: VarTypeArg => B) = f
val lambda = (a, b) ~> println(a * b)
The Scala community seems to be incredibly creative so I am pretty sure that people will find very practical usecases and I don’t think it would be too hard to implement either. With literal
as soft keyword, the core language would not change much, while adding a significant amount of flexibility to API designers. I think the symbol lookup would have to be changed slightly because it would also need to consider symbols introduced by literal arguments. It’s worth noting that this feature might not have as much of an impact as it would in certain other languages, I still felt like proposing it though.