extension methods should not pollute global scope #17660
Replies: 14 comments 1 reply
-
you can define your extension method in a non global scope such as a standalone object (i.e. not a companion) |
Beta Was this translation helpful? Give feedback.
-
But then I have to import it to use it? Importing translated function(s) as well. I'd like to have globally visible extension but without globally visible translated function. Implicit conversions half-solve this problem as implicit conversion function can be arbitrarily named and there is only one implicit function for entire StringOps. |
Beta Was this translation helpful? Give feedback.
-
I'm not really sure what is a new concern here?, all the extension methods added by |
Beta Was this translation helpful? Give feedback.
-
New concern is dotty extension methods are kind of flawed for providing extensions from libraries. Example: If StringOps are to be reimplemented as extension methods, it will add a lot of functions like |
Beta Was this translation helpful? Give feedback.
-
as I said, those methods are already visible without an import, so what is new? why does it matter which scope it is defined in, surely use-site is more important |
Beta Was this translation helpful? Give feedback.
-
if the concern is about documentation, I believe scaladoc has a grouping mechanism to organise definitions |
Beta Was this translation helpful? Give feedback.
-
that is not true: https://scastie.scala-lang.org/R1Y6wnHlQZuYeQjDMEFgBw |
Beta Was this translation helpful? Give feedback.
-
ok, I see what you mean now - its not about members added to objects, but about what values exist to choose from as you start typing anywhere demo here: https://scastie.scala-lang.org/Kg4wsf6VSdWa1o0fD9XBiA |
Beta Was this translation helpful? Give feedback.
-
Indeed. I'm not sure why it was decided to make extensions available as functions as well but I don't think that is desirable in most cases. Surely I can stick to implicit anyval classes buuut why can't it be better than that. |
Beta Was this translation helpful? Give feedback.
-
Related discussion https://contributors.scala-lang.org/t/change-shadowing-mechanism-of-extension-methods-for-on-par-implicit-class-behavior/5831/24 It also took me a while to understand the objection here: "pollute global scope" means "whenever the extension is in lexical scope, the 'ordinary method name' is also in scope." I still don't understand why implicit scope seems under-leveraged, but the inclination is to prefer imports. |
Beta Was this translation helpful? Give feedback.
-
@som-snytt Yep. Imagine a library with API of some traits and lots of extension methods, Kotlin uses this style extensively for collections, for example. With current extension methods implementation, that API will consists of traits, extension methods and public functions with names derived from extension methods. They are unwanted since a) they bloat the API b) it is highly unlikely any client will use them directly instead of extension syntax c) they make keeping backward compatibility harder d) they can lead to overload resolution conflicts. Honestly I don't understand why it is not obvious. |
Beta Was this translation helpful? Give feedback.
-
relevant SIP: scala/improvement-proposals#60 |
Beta Was this translation helpful? Give feedback.
-
As a workaround: extension methods do not have to be imported, the compiler will also search if any implicit in scope has an extension method. This allows you to do something like: object MyPredef:
implicit object syntax:
extension (s: String) def cap = s.capitalize
import MyPredef.*
"hello".cap // compiles
cap("hello") // does not compile https://scastie.scala-lang.org/sV2iQLBKRReWeoJzkE3YvQ That also allows you to have multiple extension methods with the same name on different types, which is otherwise ambiguous: object MyPredef:
implicit object syntax:
extension (s: String) def cap = s.capitalize
object MyPredef2:
implicit object syntax:
extension (s: Int) def cap = s.toString.capitalize
import MyPredef.*
import MyPredef2.*
"hello".cap
5.cap |
Beta Was this translation helpful? Give feedback.
-
Is there an expected scala release when SIP-54 is expected to land? |
Beta Was this translation helpful? Give feedback.
-
Right now extension methods are translated to ordinary functions and can be called as such:
Which limits its usage in libraries - for example, re-implementing
scala.collectionStringOps
as extension functions will add tenths of useless functions to visible scope causing confusion and potential problems with overload resolution and compatibility.Beta Was this translation helpful? Give feedback.
All reactions