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

repl :kind command is misleading and underdocumented #8529

Closed
scabug opened this issue Apr 23, 2014 · 4 comments
Closed

repl :kind command is misleading and underdocumented #8529

scabug opened this issue Apr 23, 2014 · 4 comments

Comments

@scabug
Copy link

scabug commented Apr 23, 2014

Some of the results from :kind are difficult to justify. The sum total of the documentation I can find is "display the kind of expression's type" so if there is some non-standard notion of kind (and/or expression) being applied here it would be nice to document it. The one line of documentation is already on shaky ground - all expressions (as the word is normally used) have the same kind.

There is more confusion as to whether :kind is providing the kind of an "expression" or of a "type". As the kind of an expression is uninteresting, it should interpret the input as describing an unapplied type whenever possible. But in the following example it prefers the expression meaning over the type-constructor meaning, which leads to absurdity.

// Apparently treating this as the value expression Predef.Pair
scala> :kind -v Predef.Pair
scala.Predef.Pair's kind is A
*
This is a proper type.

// Same treatment for the type expression describing that value
scala> :kind -v Predef.Pair.type
scala.Predef.Pair's kind is A
*
This is a proper type.

// Now it figures out we meant the type constructor.
// Why would anyone ask for the kind of Predef.Pair the value?
// And the kind of Pair[Int, Int] is * - it's not a type constructor.
scala> :kind -v Predef.Pair[Int, Int]
scala.Tuple2's kind is F[+A1,+A2]
* -(+)-> * -(+)-> *
This is a type constructor: a 1st-order-kinded type.

Here are some more anomalies noted in brief experimentation.

// I don't know what is the benefit of 'kind A' over 'kind *',
// and with no explanation offered in the brief documentation.
scala> :kind 5
scala.Int's kind is A

// an applied type should have kind *
scala> :k -v List[Int]
scala.collection.immutable.List's kind is F[+A]
* -(+)-> *
This is a type constructor: a 1st-order-kinded type.

// So List[Int] gets one answer and List[Int]() another
// Furthermore, it appears to be telling me the kind of List's 
// companion object, which is irrelevant to the given expression
// and most likely only correct by accident since all expressions
// (should) have this kind.
scala> :k -v List[Int]()
scala.collection.immutable.List's kind is A
*
This is a proper type.

// no, that's a value of type Function1[Int, Int] with kind *
scala> :k -v (x: Int) => x + 1
scala.Function1's kind is F[-A1,+A2]
* -(-)-> * -(+)-> *
This is a type constructor: a 1st-order-kinded type.

// no response - crash?
scala> :kind def f[A](x: A) = x

scala>
@scabug
Copy link
Author

scabug commented Apr 23, 2014

Imported From: https://issues.scala-lang.org/browse/SI-8529?orig=1
Reporter: @paulp
Affected Versions: 2.11.0

@scabug
Copy link
Author

scabug commented Apr 24, 2014

@som-snytt said:
One fix is to rename the command to :kinda.

scala> :kind def f[A](x: A) = x
A little more than kin, and less than kind.

Happy Shakespeare's birthday.

@scabug
Copy link
Author

scabug commented Sep 6, 2016

@SethTisue said:
personally I'd welcome a PR that simply removed :kind (not sure how the other scala/scala committers feel)

@scabug scabug added this to the Backlog milestone Apr 7, 2017
dwijnand added a commit to dwijnand/scala that referenced this issue May 19, 2017
dwijnand added a commit to dwijnand/scala that referenced this issue May 19, 2017
eed3si9n added a commit to eed3si9n/scala that referenced this issue May 20, 2017
Fixes scala/bug#8529

The :kind implementation added in scala#2340 was buggy and misleading in part because we could not find a robust way to turning type expression strings into Type. See also http://stackoverflow.com/questions/15678616/getting-type-information-inside-scala-repl-via-imain/15694003#15694003. The problem was that we didn't know how to pick up types defined in the REPL, so scala#2340 faked it by treating the expression as a term.

That's the major source of problems reported in scala/bug#8529. This change improves the String to type symbol conversion by using `exprTyper.typeOfTypeString` repeatedly with `[Nothing]`. It's hacky, but a whole class of "expression" can now be called out as not being a type.

Before:

    scala> :kind 5
    scala.Int's kind is A

After:

    scala> :kind 5
    <console>:1: error: identifier expected but integer literal found.
    def $ires23: 5 = ???
                 ^

More importantly, it will no longer mix up companion objects with actual types.

Before:

    scala> :kind -v Predef.Pair
    scala.Predef.Pair's kind is A
    *
    This is a proper type.

After:

    scala> :kind -v Predef.Pair
    scala.Tuple2's kind is F[+A1,+A2]
    * -(+)-> * -(+)-> *
    This is a type constructor: a 1st-order-kinded type.
eed3si9n added a commit to eed3si9n/scala that referenced this issue May 20, 2017
Fixes scala/bug#8529

The :kind implementation added in scala#2340 was buggy and misleading in part because we could not find a robust way to turn a type expression string into a Type. See also [Getting type information inside scala repl via IMain](http://stackoverflow.com/questions/15678616/getting-type-information-inside-scala-repl-via-imain/15694003#15694003). The problem was that we didn't know how to pick up types defined or imported in the REPL, so scala#2340 faked it by treating the given type expression as a term.

That's the major source of problems reported in scala/bug#8529. This commit improves the String to type symbol conversion by using `exprTyper.typeOfTypeString` repeatedly with `[Nothing]`. It's hacky, but a whole class of "expression" can now be called out as not being a type.

Before:

    scala> :kind 5
    scala.Int's kind is A

After:

    scala> :kind 5
    <console>:1: error: identifier expected but integer literal found.
    def $ires23: 5 = ???
                 ^

More importantly, it will no longer mix up companion objects with actual types.

Before:

    scala> :kind -v Predef.Pair
    scala.Predef.Pair's kind is A
    *
    This is a proper type.

After:

    scala> :kind -v Predef.Pair
    scala.Tuple2's kind is F[+A1,+A2]
    * -(+)-> * -(+)-> *
    This is a type constructor: a 1st-order-kinded type.
eed3si9n added a commit to eed3si9n/scala that referenced this issue May 20, 2017
Fixes scala/bug#8529

The :kind implementation added in scala#2340 was buggy and misleading in part because we could not find a robust way to turn a type expression string into a Type. See also [Getting type information inside scala repl via IMain](http://stackoverflow.com/questions/15678616/getting-type-information-inside-scala-repl-via-imain/15694003#15694003). The problem was that we didn't know how to pick up types defined or imported in the REPL, so scala#2340 faked it by treating the given type expression as a term.

That's the major source of problems reported in scala/bug#8529. This commit improves the String to type symbol conversion by using `exprTyper.typeOfTypeString` repeatedly with `[Nothing]`. It's hacky, but a whole class of "expression" can now be called out as not being a type.

Before:

    scala> :kind 5
    scala.Int's kind is A

After:

    scala> :kind 5
    <console>:1: error: identifier expected but integer literal found.
    def $ires23: 5 = ???
                 ^

More importantly, it will no longer mix up companion objects with actual types.

Before:

    scala> :kind -v Predef.Pair
    scala.Predef.Pair's kind is A
    *
    This is a proper type.

After:

    scala> :kind -v Predef.Pair
    scala.Tuple2's kind is F[+A1,+A2]
    * -(+)-> * -(+)-> *
    This is a type constructor: a 1st-order-kinded type.
eed3si9n added a commit to eed3si9n/scala that referenced this issue May 21, 2017
Fixes scala/bug#8529

The :kind implementation added in scala#2340 was buggy and misleading in part because we could not find a robust way to turn a type expression string into a Type. See also [Getting type information inside scala repl via IMain](http://stackoverflow.com/questions/15678616/getting-type-information-inside-scala-repl-via-imain/15694003#15694003). The problem was that we didn't know how to pick up types defined or imported in the REPL, so scala#2340 faked it by treating the given type expression as a term.

That's the major source of problems reported in scala/bug#8529. This commit improves the String to type symbol conversion by using `exprTyper.typeOfTypeString` repeatedly with `[Nothing]`. It's hacky, but a whole class of "expression" can now be called out as not being a type.

Before:

    scala> :kind 5
    scala.Int's kind is A

After:

    scala> :kind 5
    <console>:1: error: identifier expected but integer literal found.
    def $ires23: 5 = ???
                 ^

More importantly, it will no longer mix up companion objects with actual types.

Before:

    scala> :kind -v Predef.Pair
    scala.Predef.Pair's kind is A
    *
    This is a proper type.

After:

    scala> :kind -v Predef.Pair
    scala.Tuple2's kind is F[+A1,+A2]
    * -(+)-> * -(+)-> *
    This is a type constructor: a 1st-order-kinded type.
eed3si9n added a commit to eed3si9n/scala that referenced this issue May 21, 2017
Fixes scala/bug#8529

The :kind implementation added in scala#2340 was buggy and misleading in part because we could not find a robust way to turn a type expression string into a Type. See also [Getting type information inside scala repl via IMain](http://stackoverflow.com/questions/15678616/getting-type-information-inside-scala-repl-via-imain/15694003#15694003). The problem was that we didn't know how to pick up types defined or imported in the REPL, so scala#2340 faked it by treating the given type expression as a term.

That's the major source of problems reported in scala/bug#8529. This commit improves the String to type symbol conversion by using `exprTyper.typeOfTypeString` repeatedly with `[Nothing]`. It's hacky, but a whole class of "expression" can now be called out as not being a type.

Before:

    scala> :kind 5
    scala.Int's kind is A

After:

    scala> :kind 5
    <console>:1: error: identifier expected but integer literal found.
    def $ires23: 5 = ???
                 ^

More importantly, it will no longer mix up companion objects with actual types.

Before:

    scala> :kind -v Predef.Pair
    scala.Predef.Pair's kind is A
    *
    This is a proper type.

After:

    scala> :kind -v Predef.Pair
    scala.Tuple2's kind is F[+A1,+A2]
    * -(+)-> * -(+)-> *
    This is a type constructor: a 1st-order-kinded type.
@eed3si9n
Copy link
Member

eed3si9n commented May 21, 2017

The sum total of the documentation I can find is "display the kind of expression's type" so if there is some non-standard notion of kind (and/or expression) being applied here it would be nice to document it.

I corrected the broken behaviors in scala/scala#5916, so it should now align with the standard notion of kind. :kind should require types, and types only. :help kind will now display fuller explanation of what the command does (scala/scala@74850c8).

There is more confusion as to whether :kind is providing the kind of an "expression" or of a "type".

Yea. scala/scala#5916 will reject term expressions like 5.

As the kind of an expression is uninteresting, it should interpret the input as describing an unapplied type whenever possible. But in the following example it prefers the expression meaning over the type-constructor meaning, which leads to absurdity.

I figured out a way to get to the type constructor without going through terms, so Predef.Pair will be interpreted as the unapplied type, not its companion object.

// And the kind of Pair[Int, Int] is * - it's not a type constructor.

Yes fully applied type should be *. This will be fixed in scala/scala#5916 as well.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants