I’m skeptical that the
A ?=> B syntax is a good idea, for two reasons, which I think have kind of been stated, but I want to state them directly:
(using A) => B perfectly mirrors the method declaration, while
A ?=> B adds an extra nonstandard symbol to learn.
?=> intuitively makes more sense as
PartialFunction (meaning “maybe I can A => B”) than it does as a context function type (“I’ll produce B, just let me know A from context”).
If we wanted to do it symbolically,
?=> would be for
PartialFunction (and the other wouldn’t be used, to avoid confusion), and some other weird arrow would be used for context functions, like
~~>. (Tilde suggests a wiggly indirect path, which is kinda true if it’s context-dependent.)
But I’m not sure that we ought to do it symbolically.
(using A) => B is really clear.
Of course we then have the problem of
def foo(using A => B) being confusing (because it looks like
(using A) => B, even though it’s not valid to just stick a type as an argument with nothing else). If we want this, we can warn on
using A => B and require
using (A => B).
Anyway, although I normally adore symbolic methods, I think
?=> is not a great choice here.
Edit: some IMO better choices include
~> “indirect arrow”: upside – looks like a not-utterly-straight path to get the result; downside – already used in Akka (edges), Graph for Scala (directed edges), Cats (mapping), etc.
~~> “long indirect arrow” upside – same as
~> and it doesn’t conflict with much; downside – long! Why so long?!
*=> “take all stuff and map”: upside –
* is used as a kind of gathering option already; downside –
* only falls in the middle in some fonts, making it look arrowlike
!=> “wow! then map”: upside –
! indicates something extraordinary is going on (in this case, using givens); downside – doesn’t look that much like an arrow because
! is both wide and asymmetric; also suggests “not” as well as “wow”