implicit-import (export) pre-sip

365 views
Skip to first unread message

Ruslan Shevchenko

unread,
Sep 9, 2012, 5:58:53 AM9/9/12
to scala-...@googlegroups.com

Good day, colleagues.

It's about possible 'implicit import' feature: here is 'pre-sip:' https://docs.google.com/document/d/1dlT6NgB9610jqLscCJW2LRB7TapDh3q4d2S3YA_q5zs/edit 

I think to submit one as SIP after release of scala-2.10,  on absence of big concerns against.

Note, that future is implemented [ https://github.com/rssh/scala/tree/implicit-import ]  but current implementation is just an experiment to estimate value of changes.
Currently it's not optimal and has code duplication -- so I want to discuss the main implementation points in scala-internals after 2.10 release,  if  this pre-sip is go on.


Eugene Burmako

unread,
Sep 9, 2012, 6:20:29 AM9/9/12
to Ruslan Shevchenko, scala-...@googlegroups.com
My comments:
1) I'd call the new feature "export", because: a) hard to understand what "implicit import" means (import all implicits? import only implicits?), b) export is used for similar purpose in Lisp
2) I think we need just an additional field in ClassSymbol instead of a designated ImportSymbol
3) Also I'd prefer if we had a new AST node for "implicit import" or "export" in order not to break already existing usages of Import(_, _)

Ruslan Shevchenko

unread,
Sep 9, 2012, 10:02:48 AM9/9/12
to scala-...@googlegroups.com, Ruslan Shevchenko


On Sunday, September 9, 2012 1:20:34 PM UTC+3, Eugene Burmako wrote:
My comments:
1) I'd call the new feature "export", because: a) hard to understand what "implicit import" means (import all implicits? import only implicits?), b) export is used for similar purpose in Lisp

Problem that export  is not a keyword now,  so  we must or add export as new keyword (which would break existing code) or think about context-depended 'export' keyword  [which add complexity to grammar]
implicit import may be is not such intuitive as export, but it does not break existing code and does not require new keywords. From other side -- it's not contr-intuitive:  implicit imports are introduced into scopes exactly as implicit vars and defs.

From yet other (third ?)  side -- it's not very important for me here.  I.e.  if  trade-off of  new keyword introduction is less, than I think,  and community will strictly prefer new keyword - than let's add new keyword.  I. e. need some feedback on this theme.
For now - stay with implicit import and note about export as alternative.
 
2) I think we need just an additional field in ClassSymbol instead of a designated ImportSymbol

Thanks, will look
 
3) Also I'd prefer if we had a new AST node for "implicit import" or "export" in order not to break already existing usages of Import(_, _)


Depends from (1)

Paul Phillips

unread,
Sep 9, 2012, 10:07:14 AM9/9/12
to Ruslan Shevchenko, scala-...@googlegroups.com


On Sun, Sep 9, 2012 at 7:02 AM, Ruslan Shevchenko <ruslan.s....@gmail.com> wrote:
Problem that export  is not a keyword now,  so  we must or add export as new keyword (which would break existing code) or think about context-depended 'export' keyword  [which add complexity to grammar]
implicit import may be is not such intuitive as export, but it does not break existing code and does not require new keywords. From other side -- it's not contr-intuitive:  implicit imports are introduced into scopes exactly as implicit vars and defs.

An idea I had a while ago is to label the object, not the imports.  This would require no new keywords and makes a certain kind of sense:

  import object foo {
    // foo is an "import object", analogous in name to a "package object"
    // import foo._ imports the imports in foo
  }

I don't think "implicit import" will fly.

Ruslan Shevchenko

unread,
Sep 9, 2012, 11:33:37 AM9/9/12
to scala-...@googlegroups.com, Ruslan Shevchenko

Hmm, really  -- why bound to modifiers (?)

So, import object must have the same name as package  (or in generalized way --- corresponded  TemplateDef)  and  contains only import clauses.

something like:

package object foo {
   ....
}

import object foo {
    import x._
}


Look's good, but a little verbose.

Yet one idea -- may be use signs.   And => import will denote export.
i.e.  

package object foo {
    =>  import x._
}


And yet one variant  about export: it can-be be keyword only if  language.export included ?
i,e, if we have import  language.export   than export is keyword, otherwise -- normal identifier.

in such case 

import language.export

package object foo {
   export x._
}

In such case introducing new keyword  would broke only compiler units with   'import language._'  programs.

From other side,  as I understand - currently  we have no 'enabled/disabled'  keywords in scala, and macro is keyword even if language.macros is not enabled ?
Or I mistaking ?

Ok, so 3 possibilty instead implicit imports:

1)  import object
2)  => import
3)  export  enabled only by language.exports


What you think ?
Any other ideas ?

Alexander Kuklev

unread,
Sep 9, 2012, 12:31:26 PM9/9/12
to scala-...@googlegroups.com, Ruslan Shevchenko
I like the idea with import objects very much. The verbosity you mentioned is a non-issue if you allow one object to be import object and package object at the same time. What's the problem with "package import object foo"?

Alexander Kuklev

unread,
Sep 9, 2012, 4:17:49 PM9/9/12
to scala-...@googlegroups.com, Ruslan Shevchenko
On Sun, Sep 9, 2012 at 9:51 PM, Ruslan Shevchenko wrote:
> And how many package object with imports will be non-import ?

At least the ones that are already there.

> May be just change  the meaning of import in direct scope of package object and does not > touch syntax at all ?
> (i.e. imports in package objects are imported into scope of clients who imported appropriated package)
> This will be, in some sense, minimal solution.

Unfortunately, not backwards compatible. To remain backwards compatible, you have to add one more modifier. "import package object" is a good choice.
The exporting imports will be just "import com.mycompany.mypackage", for the non-exporting we could introduce "import[this] com.mycompany.mypackage" akin to protected and protected[this].

Paul Phillips

unread,
Sep 9, 2012, 7:37:31 PM9/9/12
to Ruslan Shevchenko, scala-...@googlegroups.com


On Sun, Sep 9, 2012 at 8:33 AM, Ruslan Shevchenko <ruslan.s....@gmail.com> wrote:
And yet one variant  about export: it can-be be keyword only if  language.export included ?
i,e, if we have import  language.export   than export is keyword, otherwise -- normal identifier.

I think this is an excellent idea; even if we don't use it here, it seems like the smooth route to syntax changes.  (I've always dreamed of being able to import user-defined lexically scoped syntax; this would be a sort of super-restricted, extremely impoverished man's version of that.)

Alec Zorab

unread,
Sep 9, 2012, 9:37:34 PM9/9/12
to Paul Phillips, Ruslan Shevchenko, scala-debate

And could even be used as a way to shoehorn whitespace sensitive syntax into the language! This would give everybody what they want: I'd have cleaner code and the haters would have yet another thing to complain about the complexity of.

On a serious note though, this would be an excellent way to introduce changes like sip-12, whilst also providing a convenient way to allow old code to compile after it or similar changes became part of the spec.

Som Snytt

unread,
Sep 9, 2012, 11:15:36 PM9/9/12
to Alec Zorab, Paul Phillips, Ruslan Shevchenko, scala-debate
Then I'll offer another plug for import language.comments

https://groups.google.com/forum/#!msg/scala-language/CfFVCu1P0Bc/_Gz2_c7ajfUJ

Is this a case of history repeating itself first as farce, then as complexity?

Eugene Burmako

unread,
Sep 10, 2012, 9:40:24 AM9/10/12
to scala-debate
Another interesting idea: public imports from D: http://dlang.org/module.html.

On Sep 10, 5:15 am, Som Snytt <som.sn...@gmail.com> wrote:
> Then I'll offer another plug for import language.comments
>
> https://groups.google.com/forum/#!msg/scala-language/CfFVCu1P0Bc/_Gz2...

Paul Phillips

unread,
Sep 10, 2012, 9:45:59 AM9/10/12
to Eugene Burmako, scala-debate


On Mon, Sep 10, 2012 at 6:40 AM, Eugene Burmako <eugene....@epfl.ch> wrote:
Another interesting idea: public imports from D: http://dlang.org/module.html.

That looks like a good find.  Are there enough D programmers that we can also derive some meaningful opinion about how it has worked out in practice?

Ruslan Shevchenko

unread,
Sep 10, 2012, 12:39:58 PM9/10/12
to scala-...@googlegroups.com, Eugene Burmako
btw -- semantics of the public import in D is explicitly the same as implemented in current pre-SIP

Russ P.

unread,
Sep 10, 2012, 2:53:02 PM9/10/12
to scala-...@googlegroups.com, Eugene Burmako
My concern about "public import" is that it uses the word "public" in a way that is not quite consistent with the way it is used currently. The current usage grants access, but the proposes new usage only involves the way a value is referred to.

I personally prefer "export", but backwards compatibility is not an issue for me here because I've never used that word as an identifier. If "import" is a keyword, it seems reasonable to me that "export" should be one too.

--Russ P.

Naftoli Gugenheim

unread,
Sep 10, 2012, 7:58:59 PM9/10/12
to Paul Phillips, Ruslan Shevchenko, scala-...@googlegroups.com
That gave me a different idea, which would result in larger class files, but a less fundamental change to scalac, I assume.

object X {
  val _ = scala.util._  // syntactic sugar instead of aliasing all the terms manually
  val _ = scala.slick.session.{Database, Session}

Ruslan Shevchenko

unread,
Sep 11, 2012, 12:10:25 AM9/11/12
to scala-...@googlegroups.com, Paul Phillips, Ruslan Shevchenko

  Yet one idea  --  special static annotation before import.

@exported import  x._

Russ P.

unread,
Sep 11, 2012, 3:11:08 AM9/11/12
to scala-...@googlegroups.com
Interesting idea, but not nearly as clean as "export x._".

I believe that long-term language aesthetics should trump any short-term concern for breaking code that uses "export" as an identifier. Renaming an identifier is not a huge job, particularly consider that the compiler will tell you exactly where to do it. An IDE can make the job even easier. People have been working around "import," and I don't see why then can't work around "export" as well.

Let's keep it as simple as possible, please.

--Russ P.

Jan Vanek

unread,
Sep 11, 2012, 4:41:19 AM9/11/12
to scala-...@googlegroups.com
If you say "export x._" you are not saying that you actually also import the x._ into the scope, which is the primary goal. So it doesn't describe the reality, unless of course, export is only export and you also need import x._ to have x._ available in the scope, which I don't think is a good idea. Also, given that this kind of visible import will likely not be very frequent, I think the somehow-annotated import is more balanced, like the:  "@exported import", or:

import @export x._

Regards,
Jan

Russ P.

unread,
Sep 11, 2012, 2:40:57 PM9/11/12
to scala-...@googlegroups.com
I had assumed that "export" implies "import" as well. I have a hard imagining a situation where you want export without import, but perhaps I'm missing something.

--Russ P.

Jan Vanek

unread,
Sep 11, 2012, 3:07:20 PM9/11/12
to scala-...@googlegroups.com
My objection was that the english word "export" doesn't imply "import".

Eugene Burmako

unread,
Sep 11, 2012, 3:18:30 PM9/11/12
to Jan Vanek, scala-...@googlegroups.com
Also, from what I know about Lisp, "export" there means "export a function declared by a module to be seen by the outside world". To be honest I like "public import" a bit better.


Russ Paielli

unread,
Sep 11, 2012, 3:31:51 PM9/11/12
to Jan Vanek, scala-...@googlegroups.com
On 9/11/12, Jan Vanek <j3v...@gmail.com> wrote:
> My objection was that the english word "export" doesn't imply "import".

That's true. However, export without import is saying, "I want users
of this object or module to have shorthand access to all those names,
but I don't want the same access myself." If there is a significant
use case for that, then keep import and export separate, but otherwise
it seems to me that export should just imply import. As far as I am
concerned, either way is an improvement over the current situation in
which exporting is essentially impossible.

--Russ P.

--
http://RussP.us

Rex Kerr

unread,
Sep 11, 2012, 3:52:17 PM9/11/12
to Eugene Burmako, scala-...@googlegroups.com
I also like public import, because this is exactly what it is: an import that can be seen by everyone, as opposed to just you (private import).

However, public is not a reserved word.  I can't think of a case where parsing it even as a non-reserved word would be a problem, though.

  --Rex

Jan Vanek

unread,
Sep 11, 2012, 3:56:53 PM9/11/12
to Eugene Burmako, scala-...@googlegroups.com
"public import" is not bad, but I have similar concerns as Russ here. I'm not sure how it fits into Scala's philosophy that things are public by default and you have to explicitly restrain the accessibility. "public" is not a keyword in Scala, but every Scala programer understands the word "public" in the "java"-sense, but in "public import" it is a different sense. So to summarize in "public import":
1. "public" used in different sense
2. "public" used at all, i.e. public is not default

How about:
@visible import
import @pass

With regards,
Jan

Rex Kerr

unread,
Sep 11, 2012, 4:14:53 PM9/11/12
to Jan Vanek, Eugene Burmako, scala-...@googlegroups.com
On Tue, Sep 11, 2012 at 3:56 PM, Jan Vanek <j3v...@gmail.com> wrote:
"public import" is not bad, but I have similar concerns as Russ here. I'm not sure how it fits into Scala's philosophy that things are public by default and you have to explicitly restrain the accessibility. "public" is not a keyword in Scala, but every Scala programer understands the word "public" in the "java"-sense, but in "public import" it is a different sense. So to summarize in "public import":
1. "public" used in different sense

I think it is the same sense.  Private variables are ones you don't access externally.  Private imports are ones you don't access internally.  Public variables are ones you can see externally.  Public imports are ones you can see externally.  How is it a different sense?
 
2. "public" used at all, i.e. public is not default

That is true.
 

How about:
@visible import
import @pass

I don't like using annotation syntax to control basic language features that change the interface of the class.  It is okay to parse random words before "import" since import cannot occur in very many places in the language.

So,

  broadcast import
  forwards import
  export import
  import and export

should all work.  It's a little tricky in that "import" is used as a verb, so we need an adverb like "exportingly".

  --Rex

Jan Vanek

unread,
Sep 11, 2012, 5:53:17 PM9/11/12
to Rex Kerr, Eugene Burmako, scala-...@googlegroups.com
On 11.09.2012 22:14, Rex Kerr wrote:
On Tue, Sep 11, 2012 at 3:56 PM, Jan Vanek <j3v...@gmail.com> wrote:
"public import" is not bad, but I have similar concerns as Russ here. I'm not sure how it fits into Scala's philosophy that things are public by default and you have to explicitly restrain the accessibility. "public" is not a keyword in Scala, but every Scala programer understands the word "public" in the "java"-sense, but in "public import" it is a different sense. So to summarize in "public import":
1. "public" used in different sense

I think it is the same sense.  Private variables are ones you don't access externally.  Private imports are ones you don't access internally.  Public variables are ones you can see externally.  Public imports are ones you can see externally.  How is it a different sense?

public/protected/private controls the accessibility of members, of something what is "physically" there. "import" puts a name in the scope, where the name is not "physical" as members are. With "public import" you don't control the accessibility of the name, rather you make the name importable. So, right, I am basing the distinction of the two "public"s on the distinction between their subjects (member vs. name). But in my opinion Java/Scala programmers understand "public" in relation with the access to the members, and public/protected/private sort of belong together, whereas in "public import" it is about materializing the name for subsequent importation, and protected/private import doesn't make sense. On higher level of course one can unify those two "public"s, and can say imports are by default private, and sort of unify members and names. I'd personally prefer not to, and use another word for it, like you say e.g. forward or export or pass.


 
2. "public" used at all, i.e. public is not default

That is true.
 

How about:
@visible import
import @pass

I don't like using annotation syntax to control basic language features that change the interface of the class.  It is okay to parse random words before "import" since

I was not aware of it - that the interface of the class would be changed. I thought it was strictly about visibility of names. Still, even if that was true, I agree that annotation would be on the edge.


import cannot occur in very many places in the language.

So,

  broadcast import
  forwards import
  export import
  import and export

should all work.  It's a little tricky in that "import" is used as a verb, so we need an adverb like "exportingly".

  --Rex

Regards,
Jan


Rex Kerr

unread,
Sep 11, 2012, 7:21:09 PM9/11/12
to Jan Vanek, Eugene Burmako, scala-...@googlegroups.com
On Tue, Sep 11, 2012 at 5:53 PM, Jan Vanek <j3v...@gmail.com> wrote:
On 11.09.2012 22:14, Rex Kerr wrote:
On Tue, Sep 11, 2012 at 3:56 PM, Jan Vanek <j3v...@gmail.com> wrote:
"public import" is not bad, but I have similar concerns as Russ here. I'm not sure how it fits into Scala's philosophy that things are public by default and you have to explicitly restrain the accessibility. "public" is not a keyword in Scala, but every Scala programer understands the word "public" in the "java"-sense, but in "public import" it is a different sense. So to summarize in "public import":
1. "public" used in different sense

I think it is the same sense.  Private variables are ones you don't access externally.  Private imports are ones you don't access internally.  Public variables are ones you can see externally.  Public imports are ones you can see externally.  How is it a different sense?

public/protected/private controls the accessibility of members, of something what is "physically" there. "import" puts a name in the scope, where the name is not "physical" as members are. With "public import" you don't control the accessibility of the name, rather you make the name importable.

I guess you care more about the implementation details and I care more about the use cases.  The point of having something private is so that you can't get at it; the point of having something public is so that you can.

In this more general sense, the two uses are identical.  (Protected makes sense too--if you inherit from a class with a protected import, you get the same imports.)


I don't like using annotation syntax to control basic language features that change the interface of the class.  It is okay to parse random words before "import" since

I was not aware of it - that the interface of the class would be changed. I thought it was strictly about visibility of names. Still, even if that was true, I agree that annotation would be on the edge.

Well, visibility affects the _apparent_ interface even if it doesn't affect the interface-as-seen-as-from-Java's-invokeInterface command.

For example, it would make apparently transparent wrappers easier to achieve:

    class WrapString(val s: String) {
      import and export s._
      def half = substring(length/2)
    }

Now if you imported a WrapString, you'd (presumably) get all the (unqualified) methods-on-s in scope as well as the new half method.

Maybe this goes beyond what was envisioned, but I think the link between visibility and interfaces is tighter than you suggest.  That you can even see a private method is kind of odd--it aids with debugging in some cases, but arguably if it's an implementation detail you needn't be able to generate different compile-time errors by trying to get at it vs. trying to get at something that isn't there at all.  You're still not allowed to have it, whatever it is (or is not).

  --Rex

Russ P.

unread,
Sep 12, 2012, 3:38:27 PM9/12/12
to scala-...@googlegroups.com, Jan Vanek, Eugene Burmako
That's an interesting example, Rex.

Until someone provides a counterexample where it causes a significant problem, I still lean toward simply letting "export" imply "import". However, if they must be kept independent, then I would suggest a slightly cleaner syntax such as "import/export" or even "import-export" rather than "import and export". (Ever heard of the Import-Export Bank?)

--Russ P.

Erik Osheim

unread,
Sep 15, 2012, 6:52:11 PM9/15/12
to Ruslan Shevchenko, scala-...@googlegroups.com
On Sun, Sep 09, 2012 at 02:58:53AM -0700, Ruslan Shevchenko wrote:
> Note, that future is implemented [
> https://github.com/rssh/scala/tree/implicit-import ] but current
> implementation is just an experiment to estimate value of changes.
> Currently it's not optimal and has code duplication -- so I want to discuss
> the main implementation points in scala-internals after 2.10 release, if
> this pre-sip is go on.

So, I should preface this by saying that I think a SIP and formal
scalac support is the right path for implicit import/bulk
import/exports. That said, I have just finished a nifty little compiler
plugin that enables this feature for 2.9.2:

https://github.com/non/bulk-importer

It's a bit of a hack, in that you have to build the "exports" into the
plugin's jar file, but it seems to work well in my tests. I don't know
if the pain of boiler-plate imports is enough to justify using a
compiler plugin, but I figured I'd put it out there.

-- Erik

P.S. I had hoped to make something a bit more like Ruslan's spec (an
annotated object containing imports) but I couldn't see a way to do
that without hacking a bunch of existing compiler code (as he has done)
or requiring the "exports.scala" file containing the object to be
included in all compilation runs (probably a non-starter).
Reply all
Reply to author
Forward
0 new messages