Proposal to add Extension Methods to the language

#22

While I agree that parsing might be problematic (high priority concern), I confess at the same time that I found myself actually wanting to be able to define this kind of DSL-syntax more than once in the past.

#23

I want that kind of DSL too, but I think the cleaner way to get it is probably to introduce ephemeral types. An ephemeral type cannot be stored or discarded; the only thing you are allowed to do with it is immediately call a method on it. Then you could build things up a piece at a time using more or less normal parsing rules.

(In a sense, every mutable operation could be viewed as changing an ephemeral type, but here we make explicit the type and the operation converting it to another type.)

1 Like
#24

This reminds me a bit of similar Smalltalk syntax which I loved. Why limit it to extension methods? I would prefer that we were able to write all methods in this syntax as it leads to far more comprehension of coder readers, at least for the left-to-right natural languages. Right-to-left languages could simply reverse the argument order, if desired.

2 Likes
#25

In effect I do this now, as I have case classes and opaque types, and everything else is put in with extension methods.

#26

This works due to Translation of Calls to Extension Methods. But new rules seem be ad-hoc and lacking some groundwork. While encoding of type classes looks great we are not restricted to use the feature only this way. In general I can extend the scope with a bunch of functions using implied parameters with extension methods. I can imagine someone will definitely find it useful while implementing DSL or just trying to cut some boilerplate.

trait Connection {
  def (st: Statement) execute: Unit
}
def withConnection(f: given Connection => Unit) = f given new Connection {
  def (st: Statement) execute = println(s"Executed $st")
}

withConnection {
  "SELECT 1".execute
}

Why not go further and introduce scope manipulation as a separate feature so that all other use cases would be covered? For the reference the thread where this feature was discussed.

#27

I guess what is at-hoc is in the eye of the beholder. I find scope injection the way you describe it pretty abhorrent. It’s a hack that brings back the worst memories of dynamic scoping.

#28

The code snippet above demonstrates how scope injection can be achieved with extension methods (the current implementation). It doesn’t look like a feature abuse or a hack but rather a direct usage of the feature. Extension methods are special in a sense that they are visible in the scope of implied object they belong to. But what makes them special? Even though they allow syntactically different invocation mechanism in essence they are just methods, members of an object. I guess they were made special because of the need for a nicer typeclass encoding. But there is no direct support for typeclasses in the language, typeclasses are plain traits. In the end of the day we two types of methods with different scoping rules. That’s why it seems to me that the proposed solution is incomplete. There are a two directions we may take to be consistent:

  1. Special scoping rules for typeclasses. This requires direct typeclass support in the laguage.
  2. Scope management support