www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 2179] New: import inside class works but is not in spec

reply d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=2179

           Summary: import inside class works but is not in spec
           Product: D
           Version: 1.028
          Platform: PC
        OS/Version: Windows
            Status: NEW
          Keywords: spec
          Severity: normal
          Priority: P2
         Component: DMD
        AssignedTo: bugzilla digitalmars.com
        ReportedBy: wbaxter gmail.com


DMD accepts imports placed inside of class scopes. This is useful for template
mixins because it means you can put the imports needed by the mixin into the
template itself.

However it doesn't seem to be allowed by the grammar in the spec.  It is
useful, and it works, and therefore I think the grammar should be updated to
reflect this.

Here's the test case:
----
module miximport;
import std.stdio;

class Foo {
    import miximport_imp;
    this() {
        writefln("Hi there from Inner - magic value: %s", magic_value);
    }
}

void main() { new Foo; }
----

Running dmd -v gives this, which includes miximport_imp in the list of imports:
----
F:\bax\Code\d\play>dmd -v miximport.d
parse     miximport
semantic  miximport
import    object        (f:\usr\pkg\d\dmd\bin\..\import\tango\object.di)
import    std.stdio     (f:\usr\pkg\d\dmd\bin\..\import\tangobos\std\stdio.d)
import    std.compat    (f:\usr\pkg\d\dmd\bin\..\import\tangobos\std\compat.d)
import    tango.stdc.stdio     
(f:\usr\pkg\d\dmd\bin\..\import\tango\tango\stdc\stdio.d)
import    tango.stdc.stdarg    
(f:\usr\pkg\d\dmd\bin\..\import\tango\tango\stdc\stdarg.d)
import    tango.stdc.stddef    
(f:\usr\pkg\d\dmd\bin\..\import\tango\tango\stdc\stddef.d)
import    tango.stdc.config    
(f:\usr\pkg\d\dmd\bin\..\import\tango\tango\stdc\config.d)
import    std.c.stdio   (f:\usr\pkg\d\dmd\bin\..\import\tangobos\std\c\stdio.d)
import    std.format    (f:\usr\pkg\d\dmd\bin\..\import\tangobos\std\format.d)
import    std.stdarg    (f:\usr\pkg\d\dmd\bin\..\import\tangobos\std\stdarg.d)
import    tango.core.Vararg    
(f:\usr\pkg\d\dmd\bin\..\import\tango\tango\core\Vararg.d)
import    std.c.stdarg 
(f:\usr\pkg\d\dmd\bin\..\import\tangobos\std\c\stdarg.d)
import    std.utf       (f:\usr\pkg\d\dmd\bin\..\import\tangobos\std\utf.d)
import    std.c.stdlib 
(f:\usr\pkg\d\dmd\bin\..\import\tangobos\std\c\stdlib.d)
import    std.stdint    (f:\usr\pkg\d\dmd\bin\..\import\tangobos\std\stdint.d)
import    std.c.stddef 
(f:\usr\pkg\d\dmd\bin\..\import\tangobos\std\c\stddef.d)
import    tango.stdc.errno     
(f:\usr\pkg\d\dmd\bin\..\import\tango\tango\stdc\errno.d)
import    std.c.string 
(f:\usr\pkg\d\dmd\bin\..\import\tangobos\std\c\string.d)
import    std.string    (f:\usr\pkg\d\dmd\bin\..\import\tangobos\std\string.d)
import    std.uni       (f:\usr\pkg\d\dmd\bin\..\import\tangobos\std\uni.d)
import    std.array     (f:\usr\pkg\d\dmd\bin\..\import\tangobos\std\array.d)
import    tango.core.Exception 
(f:\usr\pkg\d\dmd\bin\..\import\tango\tango\core\Exception.di)
import    std.ctype     (f:\usr\pkg\d\dmd\bin\..\import\tangobos\std\ctype.d)
import    std.gc        (f:\usr\pkg\d\dmd\bin\..\import\tangobos\std\gc.d)
import    tango.core.Memory    
(f:\usr\pkg\d\dmd\bin\..\import\tango\tango\core\Memory.di)
import    miximport_imp (miximport_imp.d)
semantic2 miximport
semantic3 miximport
code      miximport
function  this
function  main
----

The spec could be fixed, by for instance sticking ImportDeclaration under
ClassBodyDeclaration.

A similar issue may pertain to structs, but I haven't tried that.

Relevant discussions of this elsewhere include:
* http://www.dsource.org/projects/dsss/ticket/193
* http://www.dsource.org/forums/viewtopic.php?p=20054#20054

If it is decided that the spec is correct, and this is not legal, then it
should be made an error.  But I will note that there are libraries in existence
that depend on this behavior (namely doost,
http://www.dsource.org/projects/doost).  There maybe be others, but that's the
one where I ran across it.


-- 
Jun 26 2008
next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=2179





------- Comment #1 from clugdbug yahoo.com.au  2008-07-14 04:04 -------
Wow! That's a fantastic feature.


-- 
Jul 14 2008
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=2179





------- Comment #2 from andrei metalanguage.com  2008-07-14 08:49 -------
(In reply to comment #1)
 Wow! That's a fantastic feature.

It is pretty interesting, but it would be vastly more so if import would work inside a template and were parameterized with the parameters of the template, or in general if the import could be somehow parameterized. As it is, I'm not seeing many good applications. For example, say I want to define a module "cloneable" so I can say: class A { import cloneable; } class B : A { import cloneable; } auto x = new A; auto y = x.clone; and so on. But in the definition of clone (inside the cloneable module) we'd need the type of the class under construction. Guess that's where typeof(this) would come in handy :o). --
Jul 14 2008
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=2179





------- Comment #3 from aarti interia.pl  2008-07-14 10:16 -------
(In reply to comment #2)

 It is pretty interesting, but it would be vastly more so if import would work
 inside a template 

It works right now, but as Bill noticed is not in specs. See: http://www.dsource.org/projects/doost/browser/trunk/doost/util/serializer/archive/JsonArchive.d
 and were parameterized with the parameters of the template,
 or in general if the import could be somehow parameterized. 

AFAIK according spec template alias parameter can be import also. And maybe mixin("import std.stdio;") will work also... Though I did not test it.
 As it is, I'm not
 seeing many good applications.

With imports in templates it is possible to separate specific implementation from general code. So I would not say that it is not useful :-)
 For example, say I want to define a module "cloneable" so I can say:

 class A { import cloneable; }
 class B : A { import cloneable; }
 auto x = new A;
 auto y = x.clone;

Although below already works: class A { mixin cloneable; } class B : A { mixin cloneable; } I used it in serializer, which is parametrized with archive class, and then proper class body is imported into base class. See: http://www.dsource.org/projects/doost/browser/trunk/doost/util/serializer/Serializer.d It works nice, but there is still a lot of rough edges and developing serializer was sometimes really painful. E.g. I can not remove now (in 1.0 branch) spurious parameter to template archive. Program compiles with this argument, but not without it, although template argument (ARCHIVE) is not used anywhere.
 and so on. But in the definition of clone (inside the cloneable module) we'd
 need the type of the class under construction. Guess that's where typeof(this)
 would come in handy :o).

I don't get this part. For me some clarifications would be helpful, but maybe its just me :-) --
Jul 14 2008
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=2179





------- Comment #4 from wbaxter gmail.com  2008-07-14 15:35 -------
(In reply to comment #2)
 (In reply to comment #1)

 As it is, I'm not seeing many good applications.

It solves the classic problem of how to ensure that you have access to all the symbols that a mixin depends upon. If in mix.d you have a simple mixin: import std.stdio; template() Mix { void blarf() { writefln("blarf"); } } and then you mixin that in a class in another file, that other file also needs to be sure to have writefln accessible. You could make std.stdio a public import of Mix (ick) or selectively make public aliases of all the symbols you use in Mix (easy to forget to update). But both those are foiled if the user decides to use selective import of just Mix. So what putting the import inside the mixin (and thereby inside the class where it gets mixed in) does is allow you to make sure the dependencies of the mixin always get carried around with the mixin. I suppose it would also be possible to make aliases to all needed symbols inside the template, but again it's easy to forget one and the list could get quite long. Much easier to just import the modules the mixin needs inside the mixin. --
Jul 14 2008
prev sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=2179


Leandro Lucarella <llucax gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |llucax gmail.com
            Summary|import inside class works   |[module] import inside
                   |but is not in spec          |class works but is not in
                   |                            |spec


--- Comment #5 from Leandro Lucarella <llucax gmail.com> 2009-11-13 16:38:43
PST ---
See bug 3506 (a feature request for allowing import at any scope).

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Nov 13 2009