Which stdlib functions and types should be marked as `infix`?

This is where your argument falls down. New users will not add @infix in front of everything.

  • They will not be able to add infix in front of every standard library method,

  • nor will they be able to add infix in front of any third party libraries.

  • PRs to add infix to the standard library for random methods like Iterable#map will probably be argued over and rejected.

  • PRs to add infix to third party libraries will be met with confusion (“Why would you can to call .toFooBar(qux: Qux) infix???”). PRs to add infix to the Java standard library are impossible.

  • They will not know to add infix in front of the methods they define themselves. It’s not like there’s a wealth of blog posts and books talking about using that keyword

What will end up happening is that the new users will just not call any methods infix unless the library author explicitly wanted to be called infix, and would just not define any of their own methods that can be called infix until they become more advanced users and learn about the feature from more advanced sources

To me that is the intended outcome. Not no infix methods, but only infix methods that the definition author intended to be infix, where the definition author knows what they are doing

Well that just tells me you don’t use ranges. When you want to use something a lot, you call it P or T or somesuch. I think it’s a great insight that it’s fine to make the critical common stuff super-easy to use.

If one uses a lot of ranges, one knows what to and until mean, and one doesn’t want it longer. (It could be different, but not longer.)

If you’re using them a lot, it’s fine to add your own helper methods. I myself have several such helper libraries, including os-lib and requests-scala, that are simply wrappers around parts of the standard library that I use a lot and want to be shorter.

If such helper libs became popular, that would be convincing to me that is resonates broadly with the community. Otherwise, “one person does things that way and likes it” doesn’t really help make a judgement of a feature’s net pros/cons across the language community


Forcing infix is an explicit choice that restricts what people do. Obviously the people who enjoy the thing being restricted won’t like it. The bet is that there is a large pool of people who would appreciate the limits, or would appreciate the additional uniformity that the restrictions enforce.

It’s fundamentally a bet between Ruby-like or Python-like syntax. It’s a bet on Javascript v.s. Coffeescript. There are plenty of people who like Ruby (and liked Coffeescript! Remember when it was the default for Ruby on Rails???) but I think the market has spoken which one is more adoptable, and Scala is clearly trying to move in the Python-like direction for its surface syntax

2 Likes

Why would they know anything about what the library author wants?

They simply won’t call anything infix at all.

Knowing what a library author wants, knowing how to annotate your own stuff, and knowing how to turn off the warning are all of roughly comparable complexity.

Remembering everything every library owner wants is of much greater complexity–the solutions there are “never use infix” or “turn the warning off”. This goes for experts and new users alike.

4 Likes

Is it really so hard? We already need to know what the library author wants their method to be named, how many parameter lists the method should be called with, what the library method’s parameters typed are, what the parameter names are if you want to use named params. You have to know whether library authors want their types to be covariant, rather than specifying the variance of a generic at every use site. Newly in Scala 3, you also need to know how many empty parens lists a method is defined with to call it, and can’t just randomly leave them out anymore

In general, “you need to know how a library is meant to be used to use a library” is a non issue for me, and I think most engineers. Of course the person defining something specified how it is used! Of course the caller needs to know things about the method they are calling in order to call it! Are we also going to complain that needing to know a method name to call that method is a huge hardship?

Obviously the ruby folks think differently - they also allow method calls with and without parens - and some people here do too. But I don’t think anyone here is going to be convinced by any of this discussion. But I hope people can understand the problem space and solution space and discuss it in that context, rather than harping on and on about the minutiae of this specific feature

2 Likes

Add to that how in the future you will have to know which parameter can undergo implicit conversion, marked by into. So fully agree.

Yes, and good libraries choose good names to help as much as possible with this because it takes attention. length or size or len or count or dim or dims or…? Furthermore, autocomplete and “did you mean X” messages are all there to help you out with this task because it’s harder than we want it to be.

In any case, one has little choice but to name things since types are not enough most of the time to figure out what is going to happen. (e.g. (Int, Int) => Int is rather underspecified).

These are also hard, but the first actually helps with the second because you can use grouping to aid the task. But, anyway, IDEs tell you this stuff incessantly because it’s harder than we want it to be.

In any case, we can’t get away from knowing what order to put parameters and which parameters to put, because the set of parameters is often not enough to determine function. (E.g. (Int, Int) => Boolean might be antisymmetric.)

This is a pain point. a? x? element? Most people–especially newbies–do not use named parameters ubiquitously for exactly this reason. It’s harder than we want it to be.

This is mostly because it’s hard to code so that use-site variance is correct. This is a safety issue, primarily.

Yes, and that’s a pain point too. next or next()? hasNext()? And we can still elide them or not, as we please, for Java.

I think it’s an open question as to whether this was worth it. The exception for Java is especially questionable.

Again, I am not convinced that this is wise. Again it’s more to remember for dubious benefit. How do you know what I need to get into that argument slot?

Of course! And it’s a lot. It’s one of the things that makes programming hard. So don’t make it gratuitiously harder by adding extra superfluous stuff to remember! We put so much effort into making this easier:

  • Types help by catching you if you forget
  • IDEs help by offering you the most important info
  • Immutable by default means we don’t have to worry about which library author thinks it’s cool to mutate internals so we don’t even need to think about it

And so on.

4 Likes

(inb4 @alvae comes to remind us our vals are not as safe as they could be :stuck_out_tongue: )

More seriously, I agree with everything you said

1 Like