Skip to content

Opaque types are not definable at top level of REPL #9879

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

Closed
mpilquist opened this issue Sep 25, 2020 · 12 comments · Fixed by #21753
Closed

Opaque types are not definable at top level of REPL #9879

mpilquist opened this issue Sep 25, 2020 · 12 comments · Fixed by #21753

Comments

@mpilquist
Copy link
Contributor

Minimized code

  dotr -version
Starting dotty REPL...
Dotty compiler version 0.27.0-RC1 -- Copyright 2002-2020, LAMP/EPFL
scala> opaque type T = Int
1 |opaque type T = Int
  |^^^^^^
  |Illegal start of statement: no modifiers allowed here

scala> object Foo { opaque type T = Int }
// defined object Foo
@abgruszecki
Copy link
Contributor

@mpilquist what semantics would you expect from top-level opaque types in the REPL?

@som-snytt
Copy link
Contributor

I would expect scoped to the line:

scala> opaque type T = String ; def f: T = "hi"

similar to

scala> def f(s: String): Int = s.toInt ; def f(i: Int): Int = i+1   // ok, not local statements

I may not know whether or how a given line is wrapped.

@mpilquist
Copy link
Contributor Author

I wanted to enter both an opaque type and a companion, which is currently prohibited, even if wrapping with an outer { /* put type and companion here */ }

@abgruszecki
Copy link
Contributor

Yeah, I guess that makes sense. One may also want to copy top-level code from a file into a REPL, and we can define top-level opaque types in files.

In principle I think this should work, in practice it may boil down to how REPL encodes lines. I think right now every input corresponds to a class' body, which would imply we'd somehow need to add extra support for opaque types in class bodies.

@tgodzik
Copy link
Contributor

tgodzik commented Jun 8, 2021

How does REPL encode opaque type T = Int ?

Just wrap it in class REPL{ } or something like that? That seems to be fine for opaque types.

@bishabosha
Copy link
Member

bishabosha commented Jun 8, 2021

How does REPL encode opaque type T = Int ?

Just wrap it in class REPL{ } or something like that? That seems to be fine for opaque types.

it should be fine I think

scala> /*opaque*/ type T = Int
     | object T:
     |   def apply(i: Int): T = i
     | 
result of rs$line$1 after typer:
package repl$ {
  final lazy module val rs$line$1: repl$.rs$line$1$ = new repl$.rs$line$1$()
  final module class rs$line$1$() extends Object() { 
    this: repl$.rs$line$1.type =>
    type T = Int
    final lazy module val T: T$ = new T$()
    final module class T$() extends Object() { this: T.type =>
      def apply(i: Int): T = i
    }
  }
}

@dwijnand
Copy link
Member

dwijnand commented Jun 8, 2021

Yeah, I guess that makes sense. One may also want to copy top-level code from a file into a REPL, and we can define top-level opaque types in files.

In principle I think this should work, in practice it may boil down to how REPL encodes lines. I think right now every input corresponds to a class' body, which would imply we'd somehow need to add extra support for opaque types in class bodies.

Btw, this works correctly in the Scala 2 REPL, and what I mean by that is when you paste a multi-line block of code it doesn't get processed as line-prompt-line-... but as a single snippet. So bringing forward that support would deal with that use case.

[edit: actually looks like the Scala 3 REPL already does support that.]

@SethTisue
Copy link
Member

SethTisue commented Jun 8, 2021

Note that in both Scala 2 and Scala 3, the REPL allows you (because JLine 3 allows you) to press option-Return to continue the current input. (Rendering Scala 2's :paste unneeded, unless you need :paste -raw.)

@nrinaudo
Copy link

nrinaudo commented Aug 9, 2021

Just to add my two cents, I have an admittedly weird use case for the REPL supporting opaque types.

I maintain a tut-like tool: a tool that runs a REPL session, passes Scala blocks it finds in a markdown file, and pastes the result in an output markdown file. I use this to generate slides, articles, ... and be fully confident that my code samples are valid.

The REPL not supporting opaque types means I can't use my tools to use or explain opaque types to Scala beginners.

This is a weird, very niche use case that nobody else might have. Just thought it might be interesting to share.

@SethTisue
Copy link
Member

Perhaps mdoc (the standard "tut-like" tool these days, now that tut is deprecated) is affected as well?

@nrinaudo
Copy link

nrinaudo commented Aug 9, 2021

I don't think so - it's my understanding that mdoc doesn't run a REPL session, but generates classes and runs a normal compiler.

@Gedochao
Copy link
Contributor

Gedochao commented Jul 4, 2024

Still valid.

scala repl -S 3.nightly                            
# Welcome to Scala 3.6.0-RC1-bin-20240703-75a15c2-NIGHTLY-git-75a15c2 (17, Java OpenJDK 64-Bit Server VM).
# Type in expressions for evaluation. Or try :help.
#                                                                                                                  
# scala> opaque type T = Int
# -- [E103] Syntax Error: --------------------------------------------------------
# 1 |opaque type T = Int
#   |^^^^^^
#   |Illegal start of statement: this modifier is not allowed here
#   |
#   | longer explanation available when compiling with `-explain`
#                                                                                                                  
# scala> 

While of course:

scala compile --scala-snippet 'opaque type T = Int' -S 3.nightly
# Compiling project (Scala 3.6.0-RC1-bin-20240703-75a15c2-NIGHTLY, JVM (17))
# Compiled project (Scala 3.6.0-RC1-bin-20240703-75a15c2-NIGHTLY, JVM (17))

@WojciechMazur WojciechMazur added this to the 3.6.3 milestone Dec 9, 2024
tgodzik added a commit to scala/scala3-lts that referenced this issue Feb 14, 2025
Backport "Fix scala#9879: allow top-level opaque type definitions in REPL" to 3.3 LTS
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.