Pre-SIP: a syntax for aggregate literals

Hey @sjrd,

Thank you for your encouraging comment. I was talking to @lihaoyi on Discord earlier who also encouraged me to prosecute this further and gave some very valuable advice.

It seems that the “placeholder for companion object” idea is considered too easy to abuse by too large a faction of the Scala community to be viable. I find this unfortunate because it is extremely versatile: it can be used to construct collections, construct case classes, construct objects using factory methods like of or fill, plays nicely with explicit type parameters, multiple parameter lists and using clauses, can be used for collection conversions (e. g. (1 to 10).to(#)) or even enum constructors and it does all of that with a single new expression, #, whose meaning is determined from the context in a way that largely re-uses the rules that are already in place for _ lambda expressions. I think that’s a pretty high power-to-weight ratio, which I thought would be appealing to people, but alas, many people seem to have concerns about it.

I also feel a bit misunderstood since @odersky used the phrase “the original proposal to have special forms for collection literals” – but it was never intended to be limited to collections. It was always meant to work for collections and objects, which is why I called it aggregate literals, not collection literals.

But at the end of the day, the bait needs to taste good to the fish, not to the angler, so it doesn’t really matter how much I like it. I need to think about this a bit more and see if I can come up with a proposal that is more palatable to the community. I haven’t completely given up yet.

1 Like

Yes sorry it wasn’t clear. I meant any mechanism based on expected types is brittle and bound to fail in many cases:

  1. When methods are overloaded : then there is simply no such thing as an expected type
  2. When for some type T the expected type is not T but something T can be brought to, like Option[T], as was already pointed

So, more often than not we are forced to make the type explicit as in val a: T = thing instead of val a = T(thing) whereas a big part of the language is dedicated to type inference. And I personally always try to hide types as much as possible.

This also impacts implicit conversions, but at least these can chain, which addresses point 2). Point 1) regularly causes implicit conversion to fail, as implicit and overloading resolution seem difficult to coordinate.

This might also explain the difficulties of the generic number literals proposal which is nice on the paper but fails in too many cases for it to be really viable, due to the above.

1 Like

By “chaining”, do you mean that when there’s an implicit conversion from A to B and from B to C, then these can be used together as an implicit conversion from A to C? Because Scala doesn’t actually do that.

You are right, you have to arrange one of them accordingly, as in:

But in practice this is not a problem (I use it regularly).

The other use case is simpler output in REPL, where people often ask for less name verbosity.

Is anyone here volunteering to get IntelliJ up to speed on all of the Scala 3 features until this one?

I don’t think it’s a good idea to divorce the language more and more from what at least I think is the only really good IDE. And while it’s appreciated that Jetbrains, despite maintaining the only close competitor to Scala, pays people to work on the Scala plugin, I feel like if we keep making their job harder, what if at some point they feel like it just isn’t worth it? What if they decide that the only way to make the plugin usable (perhaps for a future release of Scala) is well beyond whatever budget they feel Scala support justifies?

4 Likes