Some parts of stdlib could be greatly ehanced by using Scala 3 specific features. One example is ChainingSyntax. Just consider:
extension [A](self: A):
inline def tap[U](inline f: A => U): A =
f(self)
self
inline def pipe[B](inline f: A => B): B = f(self)
Using inline here is not only more efficient, it also makes debugging more reliable (no lambdas), exception callstacks shorter and tidier and it e.g. makes return statemens from inside possible, as they are no longer non-local.
I am not sure what are binary compatibility concerns in cases like this and what strategy could be used to implement Scala 3 improvements to some carefully seleected parts of stdlib.
Interesting, thanks. I can see assert there, but not locally or implicitly, only summon.
Who and how chooses what will be added there? Is pipe / tap a good candidate?
How many functions can be added before the maintenance burden becomes too heavy? Will Scala 3 improvements in stdlib have to wait until Scala 2.13 dies, which may be practically never?
Oh that is interesting, I think before 3.0.0 this was the case, but we did some “cleanup” which probably decided it was not worth patching those methods - but at least assert exists in the 2.13 Predef also
I have seen several mentions on GitHub most of the stdlib will be compiled by Scala 3 compiler to allow improving it as needed, starting with 3.8 release, and its distribution will be changed a bit. I think this is great news. I guess it will be done carefully to avoid annoyance as much as possible, but still maybe this is quite a substantial change, which might deserve an announcement? Maybe next Scala Highlights could cover this?
In Scala 3.8, it will use the stdlib in source, other than the one from Scala 2.13, but I still don’t know which features were added, may be CC checked?
I’m not sure if it’s possible, but maybe we can use the @targetName annotation to make these kinds of changes while not breaking backward compatibility? I. e. rename the old pipe implementation to something else (legacyPipe or whatever) but annotate it with @targetName so it’s still called pipe in the binary, then add the new macro-based implementation under the name pipe. this would retain binary compatibility while providing the benefits of the macro based implementation to callers compiled against a newer version of the standard library.
Note that other ecosystems already do something similar, e. g. glibc’s symbol versioning feature.