SIP-42: Literal-based Singleton types

551 views
Skip to first unread message

George Leontiev

unread,
Jun 23, 2014, 12:03:18 PM6/23/14
to scala...@googlegroups.com
Hello folks,

We've had a very productive discussion of use-cases for this feature on scala-language mailing list some time ago. I've combined a document:
Possible interactions with the feature are covered in this test (and also described in the document): https://github.com/folone/scala/blob/topic/42.type/test/files/run/dottype.scala

Your feedback is very welcome!

Cheers.

Miles Sabin

unread,
Jun 23, 2014, 2:53:11 PM6/23/14
to scala...@googlegroups.com
You seem to have completely ignored the part of the discussion that
revolved around https://issues.scala-lang.org/browse/SI-5103. Aside
from providing a better resolution of almost all of the issues which
motivate this SIP (ie. who really wants to write foo[23.type] when
they can write foo(23) and have Int(23) inferred), it's plausibly a
bug fix, so no SIP required at all.

You can find a first cut at a fix by Jason here,

https://github.com/retronym/scala/compare/ticket/5103

I kicked the tires, and it solves all my singleton type problems in shapeless.

Like I've said, I don't object to this SIP per se, however it isn't
the best solution for the problems it purports to address.

Cheers,


Miles
> --
> You received this message because you are subscribed to the Google Groups
> "scala-sips" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to scala-sips+...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.



--
Miles Sabin
tel: +44 7813 944 528
skype: milessabin
gtalk: mi...@milessabin.com
g+: http://www.milessabin.com
http://twitter.com/milessabin

George Leontiev

unread,
Jun 23, 2014, 3:54:36 PM6/23/14
to scala...@googlegroups.com
Hello Miles,

I've added the ticket to the corresponding session of the document. I indeed forgot about it, sorry for that.

Do you agree that there is an inconsistency though? You can use some values in type position.

George Leontiev

unread,
Jun 23, 2014, 5:03:27 PM6/23/14
to scala...@googlegroups.com
Another thing that bugs me – it seems a bit strange to have a possibility to infer some type, but no possibility to manually specify it. Specifying the expected type of an expression is pretty much the enabler of the "follow the types" approach, which I personally find quite useful.

Miles Sabin

unread,
Jun 23, 2014, 5:22:12 PM6/23/14
to scala...@googlegroups.com
On Mon, Jun 23, 2014 at 11:03 PM, George Leontiev <fol...@gmail.com> wrote:
> Another thing that bugs me – it seems a bit strange to have a possibility to
> infer some type, but no possibility to manually specify it. Specifying the
> expected type of an expression is pretty much the enabler of the "follow the
> types" approach, which I personally find quite useful.

As I said, I'm not opposed to being able to specify literal singleton
types explicitly. However, we almost always want these types inferred
from values: I believe the exceptions to this are extremely rare.

When it comes down to it, I think ".type" is ugly and unnecessary
syntax. What we're groping towards in the ability to index types by
values. That being the case, why don't we just do exactly that. Let's
drop the ".type" suffix altogether and allow any stable value (I can't
remember whether literals are currently classified as stable, but
there's no reason why they shouldn't be) in a position expecting a
type to be automatically promoted to the corresponding singleton type.
This would make the few scenarios where explicit literal singleton
types are useful a great deal more pleasant (ie. Matrix[Double, 3, 3]
rather than Matrix[Double, 3.type, 3.type]).

Cheers,


Miles

George Leontiev

unread,
Jun 23, 2014, 5:31:47 PM6/23/14
to scala...@googlegroups.com
Agreed! I've played with this just today, and believe this can be done in a relatively straightforward way. There were some remarks by Denys on how this functionality could be problematic for quasiquotes though.

Denys Shabalin

unread,
Jun 24, 2014, 1:55:01 PM6/24/14
to scala...@googlegroups.com
Hi George, 

We’ve found a way to fix this. Currently lifting works through a following type class:

    trait Liftable[T] { def apply(value: T): Tree }

Here we can’t have any way to lift an Int differently based on term vs type context. But in .meta:

    trait Lift[From, To <: Tree] { def apply(value: From): To }

We encode syntactical context in types (i.e. strongly typed Term, Type, Pat, Stmt etc) and can dispatch based on it. This way there can be separate instances like meta.Lift[Int, meta.Term] and meta.Lift[Int, meta.Type] etc.

So syntax without “.type” isn’t a problem for us any longer.

Cheers, 
Denys
--

George Leontiev

unread,
Jun 24, 2014, 2:42:49 PM6/24/14
to scala...@googlegroups.com
Hey Denys,

Good news, I'll go ahead and start working on dropping the .type part, as well as changing the document.

Thanks!

Adriaan Moors

unread,
Jun 25, 2014, 3:10:10 AM6/25/14
to scala-sips
Thanks for writing this up!

Sorry, I'm a bit late to the party. I'm concerned about dropping the `.type` suffix for a singleton type of a value. I'd like to fully understand the plan here. Will we make `.type` optional, and if so, what happens to the example below? Are we not going to support it at all? I know a lot of you (including Martin) are in favor of a simpler (but ambiguous) syntax. Consider this (hypothetical):

type T = Int
final val T = 1

val x: T = 2 // Should this type check or not? Since the value T is effectively a constant, should it be promoted to T.type?
val one: T.type = 1 // will this be allowed?

Concretely, by not requiring .type, we'll lose the property that we are always either in type-parsing or term-parsing mode. If I understood correctly, we'd now have to use a fallback mechanism: whenever something doesn't parse as a type in a type position, parse as term and add `.type`. I think the feature should be sufficiently exotic that the extra .type doesn't matter -- in fact, it serves as a good reminder you're doing type wizardry, and avoids unsuspecting programmers using it by accident.

cheers
adriaan

George Leontiev

unread,
Jun 25, 2014, 4:02:00 AM6/25/14
to scala...@googlegroups.com
Hi Adriaan,

I was thinking about making `.type` optional for actual literals (42, "PANDA!"), but make it mandatory for references to literals (vals). For example:

scala> final val T = 1
T: 1.type = 1

scala> val t: 3 = 3
t: 3.type = 3

scala> val s: T = 2
<console>:7: error: not found: type T
       val s: T = 2
              ^

scala> val s: T.type = 2
<console>:8: error: type mismatch;
 found   : 2.type (with underlying type Int)
 required: 1.type
       val s: T.type = 2
                       ^

scala> val s: T.type = 1
s: 1.type = 1

scala> val k: 42.type = 42
k: 42.type = 42

Here's the fix in parser that would allow something like that: https://gist.github.com/folone/e6d7250570a839e591b8. Would that make sense?

Cheers.

martin odersky

unread,
Jun 25, 2014, 4:14:12 AM6/25/14
to scala...@googlegroups.com
I would hate to give up the term/type parsing property. So I think we need to continue to require ".type" for a singleton type that starts with an identifier. Precisely because "x" can be a term and a type. But it could be redundant for literals because there no ambiguity can arise. 

Cheers

 - Martin



cheers
adriaan

--
You received this message because you are subscribed to the Google Groups "scala-sips" group.
To unsubscribe from this group and stop receiving emails from it, send an email to scala-sips+...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.



--
Martin Odersky
EPFL

Adriaan Moors

unread,
Jun 25, 2014, 4:38:44 AM6/25/14
to scala-sips
Ok, makes sense! In short, I agree with making ".type" optional after parsing a literal where a type is expected.

Grzegorz Kossakowski

unread,
Jun 25, 2014, 10:18:32 AM6/25/14
to scala...@googlegroups.com
As an outside lurker I wanted to say that I like the latest iteration of this proposal.
Grzegorz Kossakowski
Scalac hacker at Typesafe
twitter: @gkossakowski

Jason Zaugg

unread,
Jun 25, 2014, 10:51:40 AM6/25/14
to scala...@googlegroups.com
On Wed, Jun 25, 2014 at 4:18 PM, Grzegorz Kossakowski <grzegorz.k...@gmail.com> wrote:
As an outside lurker I wanted to say that I like the latest iteration of this proposal.

I'm a bit worried that ConstantTypes themselves are not (directly) specified. Only constant value definitions and constant expressions are described.

For example, by what rules is this allowed?
scala> "": Singleton
res0: Singleton = ""
Here's an an IntelliJ bug that results from the interaction between constant types and numeric literal narrowing:
object Test {
  final val x = 0
  x: Byte // good code red
}


-jason
Reply all
Reply to author
Forward
0 new messages