Haha, I can’t blame you because we’ve explored many different paths from where we started. I think that’s actually really good and it has certainly provided me with new insights.
Going through your list in order, here’s how I think about the various options:
- That is the original idea. I don’t think of it as “conversion” though, rather it’s a kind of syntactic sugar that’ll fill in the correct companion object in front of a parameter list. So you can go from
[1,2,3]
toList(1,2,3)
, but also from[x=1, y=2]
toPoint(x = 1, y = 2)
. - (tuple conversion) I don’t like this idea for a variety of reasons. It’s less flexible because there are things that just aren’t possible with tuples, like multiple parameter lists or
using
clauses or having some parameters named and others unnamed. It will also lead to terrible error messages and bad tooling, unless the tools grow specific support for these conversions. Moreover I don’t think it can be made to work for the case where such expressions are nested. I don’t think a good solution can be achieved this way. - (scope injection) The original scope injection thread is here. At one point I thought it was a good idea to merge the two, but I’m no longer convinced because I think the issues are sufficiently distinct that more than one language feature is going to be required to solve them (sorry @soronpo, I’m still convinced that relative scoping of some form is required due to the reasons I’ve laid out in another comment, but I think it’s a largely separate issue, and I’m still prepared to help out with writing a proposal)
- (placeholder for companion object) That is quite similar to number 1 which proposes a syntax for companion object apply calls. It has the added benefit of also allowing things like
#.of(1958, 9, 5)
to create aLocalDate
object (assuming that#
means companion object). I think that’s a good solution.
Now that you brought up that last one again, I had some more thoughts about it. At one point I thought it would be nice to have a syntax to select members from the companion object, e. g. #of
would select the of
member of the companion object (or static method for Java classes). That would allow us to get rid of that ugly little dot in #.of(1958, 9, 5)
. But then I realized that maybe you don’t always want to select anything from the companion but rather just refer to the companion object itself. Notably, that is the case for collection conversions:
val foo = List("bar" -> 42)
def baz(m: Map[String, Int]) = ()
baz(foo.to(Map)) // using companion object here
baz(foo.to(#)) // but could use a placeholder too!
So maybe that ugly little .
in #.of(1958, 9, 5)
is the price to pay to enable this use too.
Now that I’ve thought about it again and that @lihaoyi has demolished the []
idea, I think that this “companion object placeholder” idea is probably the best solution.
Absolutely, that is what I was trying to express with many more words before. Let’s make the language simple and orthogonal and have linters deal with “readability” for those that deem that necessary.