REPL and scalac compilation differences ?

66 views
Skip to first unread message

Francois

unread,
Mar 7, 2011, 2:01:52 PM3/7/11
to scala-user
Hello,

I'm wondering what are the main differences between the REPL and scalac.
What I'm aware of, but I can't find if that's due to my imagination, or
if I read that somewhere (and so, where ?)

- I believe the REPL defines an object for the session, and that all the
session is a big compilation unit. Is that true ?

- each command in REPL is compiled with the REPL session past compiled
commands as environment, and the result is added to the environment. Is
that true, too ?

- scopes in REPL have to be dealt with care (but I can't find back any
good example of that);

- Does the REPL load some special environment over scalac that may
influence compilation or evaluation ? (I don't think so).

- I also know that in the past, REPL "print" part was a little to
agressive for lazy vals and structures, and that it was considered as a
bug. Is there any other difference of that kind which are expected (not
bugs, but genuine difference between REPL and scalac) ?

- finally, does the Scala "script" mode is exactly the same as REPL, or
does it have some other specificities ?

Thanks !

--
Francois ARMAND
http://fanf42.blogspot.com
http://www.normation.com

Kevin Wright

unread,
Mar 7, 2011, 2:18:49 PM3/7/11
to Francois, scala-user
Josh has written a lot of good stuff about this in his book, Chapter 2... http://www.manning.com/suereth/

--
Kevin Wright

gtalk / msn : kev.lee...@gmail.com
mail: kevin....@scalatechnology.com
vibe / skype: kev.lee.wright
quora: http://www.quora.com/Kevin-Wright
twitter: @thecoda

"My point today is that, if we wish to count lines of code, we should not regard them as "lines produced" but as "lines spent": the current conventional wisdom is so foolish as to book that count on the wrong side of the ledger" ~ Dijkstra

Paul Phillips

unread,
Mar 7, 2011, 2:44:54 PM3/7/11
to Francois, scala-user
On 3/7/11 8:01 PM, Francois wrote:
> - I believe the REPL defines an object for the session, and that all the
> session is a big compilation unit. Is that true ?

Nope.

> - each command in REPL is compiled with the REPL session past compiled
> commands as environment, and the result is added to the environment. Is
> that true, too ?

Sort of. To compile any given "line" of code (in quotes because a
"line" is arbitrarily long) all the identifiers are imported from the
previous lines. These used to be in objects with pretty ungodly names
but now I have every line in its own package to pave the way for future
improvements.

scala> [paulp@stem ~]$ scala29 -Dscala.repl.power
Welcome to Scala version 2.9.0.r24393-b20110306225200 (Java HotSpot(TM)
64-Bit Server VM, Java 1.6.0_22).
Type in expressions to have them evaluated.
Type :help for more information.
Starting in power mode, one moment...

** Power User mode enabled - BEEP BOOP WHIR **
** scala.tools.nsc._ has been imported **
** global._ and definitions._ also imported **
** New vals! Try repl, intp, global, power **
** New cmds! :help to discover them **
** New defs! Type power.<tab> to reveal **

scala> def bippy = 55
bippy: Int

scala> RootClass.tpe.members
res0: List[global.Symbol] = List(package $line22, package $line21,
package $line17, package $line18, package $line19, package $line20,
package $line16, package $line15, ...

scala> getModule("$line21").tpe.members
res1: List[global.Symbol] = List(object $eval, object $read)

scala> getModule("$line21").tpe.member("$eval").tpe.member("$result")
res3: global.Symbol = lazy value $result

scala> getModule("$line21").tpe.member("$eval").tpe.member("$result").tpe
res4: global.Type = ()Int

scala> $line21.$eval.$result
res6: Int = 55

> - Does the REPL load some special environment over scalac that may
> influence compilation or evaluation ? (I don't think so).

I wouldn't put it that way, but there's enough stuff going on that I
wouldn't ever be too surprised at differences poking out.

> - I also know that in the past, REPL "print" part was a little to
> agressive for lazy vals and structures, and that it was considered as a
> bug. Is there any other difference of that kind which are expected (not
> bugs, but genuine difference between REPL and scalac) ?

Expected differences should mostly be in the category of the scalac way
being impractical to mimic in an interactive session. That means things
like hitting enter meaning "I'm done" even if when compiling the next
line would have been considered.

> - finally, does the Scala "script" mode is exactly the same as REPL, or
> does it have some other specificities ?

It is not exactly the same, but close enough for the purposes of the
amount of time I have for this answer.

Francois Armand

unread,
Mar 7, 2011, 4:49:46 PM3/7/11
to scala-user
Le 07/03/2011 20:44, Paul Phillips a écrit :
> On 3/7/11 8:01 PM, Francois wrote:
>> [...]

> Sort of. To compile any given "line" of code (in quotes because a "line"
> is arbitrarily long) all the identifiers are imported from the previous
> lines. These used to be in objects with pretty ungodly names but now I
> have every line in its own package to pave the way for future improvements.
>
> [...]

>
> scala> getModule("$line21").tpe.member("$eval").tpe.member("$result").tpe
> res4: global.Type = ()Int
>
> scala> $line21.$eval.$result
> res6: Int = 55


Wow, I'm happy to have asked :)


>[...]


>
> It is not exactly the same, but close enough for the purposes of the
> amount of time I have for this answer.


Thanks a lot for the insightful answer.

--
Francois Armand
http://fanf42.blogspot.com

Francois

unread,
Mar 11, 2011, 11:28:26 AM3/11/11
to scala-user
On 07/03/2011 20:44, Paul Phillips wrote:
> On 3/7/11 8:01 PM, Francois wrote:
>> - I believe the REPL defines an object for the session, and that all the
>> session is a big compilation unit. Is that true ?
>
> Nope.
>
>> - each command in REPL is compiled with the REPL session past compiled
>> commands as environment, and the result is added to the environment. Is
>> that true, too ?
>
> Sort of. To compile any given "line" of code (in quotes because a "line"
> is arbitrarily long) all the identifiers are imported from the previous
> lines. These used to be in objects with pretty ungodly names but now I
> have every line in its own package to pave the way for future improvements.


Something I don't understand here. OK for the one object (or package) by
line (and it's really clever).

But if a REPL session is not a compilation unit and considered as one
source file, why can I extends a sealed class defined on one line on an
other one ? Is sealed even more magic than I thought ?

8<--------------------------------------------------------------------
Welcome to Scala version 2.8.1.final (Java HotSpot(TM) Server VM, Java
1.6.0_23).


Type in expressions to have them evaluated.
Type :help for more information.

scala> sealed class A
defined class A

scala> class B extends A
defined class B

scala>
8<--------------------------------------------------------------------

Paul Phillips

unread,
Mar 11, 2011, 1:53:33 PM3/11/11
to Francois, scala-user
On 3/11/11 8:28 AM, Francois wrote:
> But if a REPL session is not a compilation unit and considered as one
> source file, why can I extends a sealed class defined on one line on an
> other one ? Is sealed even more magic than I thought ?

I said it's not one big compilation unit, but I didn't say anything
about source files. Sealed only requires they have the same source, and
they do (they are both null.)

Francois

unread,
Mar 11, 2011, 4:38:50 PM3/11/11
to scala-user
On 11/03/2011 19:53, Paul Phillips wrote:
> I said it's not one big compilation unit, but I didn't say anything
> about source files. Sealed only requires they have the same source, and
> they do (they are both null.)

Ah, clever, too :)

Thanks again,

Peter C. Chapin

unread,
Mar 13, 2011, 10:15:06 AM3/13/11
to Scala User

A general question... is sealed the only Scala feature that is specific to
source file "scoping?"

My understanding has been that for the most part the source file layout is,
in theory anyway, indpendent of the logical constructs of the language...
except for sealed. Perhaps my understanding is flawed.

Peter

Paul Phillips

unread,
Mar 13, 2011, 10:49:42 AM3/13/11
to Peter C. Chapin, Scala User
On 3/13/11 7:15 AM, Peter C. Chapin wrote:
> A general question... is sealed the only Scala feature that is specific
> to source file "scoping?"

There is at least one much more important one: companions.

Peter C. Chapin

unread,
Mar 13, 2011, 12:59:08 PM3/13/11
to Scala User

Ah yes, of course. Thanks for reminding me.

So then here is a follow up question. If it is possible to extend a sealed
class in the REPL, why isn't it possible to define a class and it's
companion in the REPL? For example:

Welcome to Scala version 2.8.1.final (Java HotSpot(TM) 64-Bit Server VM,

Java 1.6.0_23).
Type in expressions to have them evaluated.
Type :help for more information.

scala> object X {
| private val a = 1
| }
defined module X

scala> class X {
| def a_value = X.a
| }
<console>:7: error: value a cannot be accessed in object X
def a_value = X.a
^

Peter

Peter C. Chapin

unread,
Mar 13, 2011, 1:04:51 PM3/13/11
to Scala User
On Sun, 13 Mar 2011, Peter C. Chapin wrote:

> So then here is a follow up question. If it is possible to extend a sealed
> class in the REPL, why isn't it possible to define a class and it's
> companion in the REPL? For example:
>
> Welcome to Scala version 2.8.1.final (Java HotSpot(TM) 64-Bit Server VM,
> Java 1.6.0_23).
> Type in expressions to have them evaluated.
> Type :help for more information.
>
> scala> object X {
> | private val a = 1
> | }
> defined module X
>
> scala> class X {
> | def a_value = X.a
> | }
> <console>:7: error: value a cannot be accessed in object X
> def a_value = X.a
> ^

Never mind, I answered my own question. If each REPL line is its own package
than clearly the object X and the class X above can't be companions. On the
other hand the following file does compile quite happily with scalac

package p1 {
sealed class A;
}

package p2 {
import p1.A
class B extends A;
}

Peter

Jim Balter

unread,
Mar 13, 2011, 3:25:02 PM3/13/11
to Peter C. Chapin, Scala User

This is a common question and the common answer is to put them
together in an object:

object GroupTheseInREPL { object X { ... } class X { ... } }

-- Jim

Paul Phillips

unread,
Mar 13, 2011, 5:42:13 PM3/13/11
to Peter C. Chapin, Scala User
On 3/13/11 9:59 AM, Peter C. Chapin wrote:
> So then here is a follow up question. If it is possible to extend a
> sealed class in the REPL, why isn't it possible to define a class and
> it's companion in the REPL?

Although I see you answered your question, the answer did not really
capture the meaningful difference. The same-file restriction on sealed
is a way of limiting the universe of possible subclasses for
exhaustiveness checking: without such a limitation it is impossible to
say a match is exhaustive. That it works in the repl is purely an
artifact of the implementation (the check is as simple as "are these
source files the same" and since they're both null the answer is "yes".)
It is not a design choice that it works in the repl.

The same-file restriction on companions is a technical limitation
because it would make the implementation way harder if we never knew
whether a companion was lurking in the wings. In a magical world where
the implementations fall from the sky fully debugged, cycles do not
exist, and you can always backtrack if your initial impression was
wrong, there's no reason I can see to require companions in the same file.

Reply all
Reply to author
Forward
0 new messages