Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove given instance definitions in favor of given aliases #76

Open
julienrf opened this issue Nov 6, 2019 · 4 comments

Comments

@julienrf
Copy link

@julienrf julienrf commented Nov 6, 2019

Currently, it is possible to write a given instance definition without writing an = sign:

given intOrd: Ord[Int] {
  def compare(x: Int, y: Int) =
    if (x < y) -1 else if (x > y) +1 else 0
}

This is not consistent with the rest of the language, which requires all term definitions to have a left-hand side and a right-hand side separated by an = sign, or to use extends:

val foo = 42
def bar(x: Int): Unit = println(x * x)
object Baz extends Something

I think the main reason for allowing users to write given instance definitions without = sign is to remove the repetition with the given instance type, which is mandatory:

given intOrd: Ord[Int] = new Ord[Int] { ... }

However, Dotty can infer the name of an anonymously extended class:

given intOrd: Ord[Int] = new { ... } // Dotty infers “new Ord[Int] { ... }”

I think we could remove the special case of omitting the = sign when writing given instance definitions, in favor of a given instance alias that uses the new { ... } syntax.

Here is a comparison of a complete definition:

// Currently
given intOrd: Ord[Int] {
  def compare(x: Int, y: Int) =
    if (x < y) -1 else if (x > y) +1 else 0
}

// Proposal
given intOrd: Ord[Int] = new {
  def compare(x: Int, y: Int) =
    if (x < y) -1 else if (x > y) +1 else 0
}
@LPTK

This comment has been minimized.

Copy link

@LPTK LPTK commented Nov 6, 2019

I also find the current syntax very confusing, especially the shorthand syntax:

given Ord[Int] { ... }

which is to stand for:

given someName: Ord[Int] { ... }

Indeed, because of the expectation that this sets (you can ignore the 'someName:' part) I am left to wonder whether the example given in the doc:

given Position = enclosingTree.position

means this (consistent with the shorthand above):

given someName: Position = enclosingTree.position

or that (consistent with the rest of the language):

given Position: InferredType = enclosingTree.position

From what I understand, the new syntax was meant to (superficially) "look and feel" like a proper language feature, making type class instances more "first class", except that it's not actually a new feature — it's a syntactic twist to save a few characters. The problem is that it's so flexible and general that I don't think one can can fully understand it without understanding the underlying encoding anyways, which defeats its purpose.

So we have a strange syntax that's alien to experienced users and mind-boggling to beginners, and confusing to both groups.

I really hope the SIP committee see that this situation is untenable.

@neko-kai

This comment has been minimized.

Copy link

@neko-kai neko-kai commented Nov 6, 2019

@LPTK What about having a colon after given (without an underscore) ?

given: Position = enclosingTree.position
@LPTK

This comment has been minimized.

Copy link

@LPTK LPTK commented Nov 6, 2019

I would prefer just using an underscore, which is already the conventional way of saying "I don't care about the name of this thing."

given _: Position = enclosingTree.position
@neko-kai

This comment has been minimized.

Copy link

@neko-kai neko-kai commented Nov 6, 2019

That two character difference is annoying, though, I think inserting colon, but omitting the underscore has a better chance of being accepted since it's closer to the current syntax...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
3 participants
You can’t perform that action at this time.