This seems like a clean approach in general, but it needs some refinement to
deal with languages with type inference.   As a simple example, a bit of
Scala code can say

class SomeScalaClass {
   def foo(x : SomeNonScalaClass) = x.something()
}

The return type of foo depends on the return type of
SomeNonScalaClass#something.  If that's the only dependency then compiling
in order solves the problem.  But if SomeNonScalaClass is written in a type
inferring language and it has a another method that depends on the return
type of SomeScalaClass#foo then neither side can figure things out in one
pass over the whole .class.  The dependency chain is only breakable by being
able to ask for typing of individual methods.

Which brings me to a pathological case.  It's entirely possible to have

class SomeScalaClass {
   def something(x : SomeNonScalaClass, n : Int) = if (n == 0) 48 else
x.something(this, n - 1)
}

// this is a class written in a hypothetical non-Scala, but type-inferring
language
class SomeNonScalaClasss
   define something[x : SomeScalaClass]
      if (n ==0)
         return 900
     else
        return x.something(this, n - 1)

Obviously a silly example, but does illustrate that mutual recursion needs
to be dealt with, perhaps by punting and insisting that one side or the
other annotate a type.


On Sun, Dec 20, 2009 at 5:16 PM, Per Bothner <[email protected]> wrote:

> On 12/17/2009 09:02 AM, Charles Oliver Nutter wrote:
> > I may be naive, but what we really want here is simply a set of common
> > protocols for doing the following:
> >
> > * Requesting from a language what types and methods are provided by a
> > set of source files
> > * Providing to a language services to look up types from other languages
>
> If there are no dependency cycles, and the dependencies are known, then
> it is easy: If files in language A depend on files in language B, but
> not vice versa, just compile the files in language B before those in
> language A, and then have language A's compiler read the B .class files.
> We all do this, at least in the case that B==Java.
>
> To handle dependency cycles or unknown dependies one can use a "compile
> for export" option.  This just generates a stub .class file, that
> contains no code, or private fields, or anything else that is not
> part of the "public contract" of the module.  The key is that it
> should be possible to generate this without reading any other
> class files, and so cycles or other dependencies aren't a problem.
>
> Generating the stub for Java is in theory easy:  You can generate
> stub method bodies by replacing all method bodies by "return null"
> or whatever is appropriate for the method's return type, and
> otherwise not checking for type compatibility and so.  The import
> statements allow replacing class names by the full-qualified names.
>
> There are some complications: one is that import-on-depend does need
> to search for other classes.  So you need one extra step, as below.
>
> So the multi-language compiler-driver does:
> (1) Figure out the set of source files to (possibly) compile.
> (2) For each source file, figure out the compiler to use, presumably
> using extensions, though it could also use mime-types or looking at
> the source file itself or some property datebase.
> (3) For each source file, ask its compiler the set of class names
> it might generate, using some to-be-specified simple protocol.
> (4) For each source file, compile it "for export".  I.e. generate
> the stub .classes mentioned above, leaving them in some temporary
> location (ideally a "MemoryFileSystem").
> (5) For each source file, compile it for real, setting up the class
> path to search the above temporary location first.  When it needs to
> import definitions from another file or class, it just reads the
> sub class in "the normal way".  The compiler should have access to
> the map generated in (3), and should have a mechanism to invoke
> the corresponding compiler "out of order".  For example, a Scheme
> library may want to execute a macro at compile time, and that
> macro may depend on methods in some other class; thus it would
> be nice to have a "compile this file first" mechanism.
>
> This approach still means an API invoking compilers with various
> options, but we don't need to invent a protocol for representing
> types and modules - we just use the .class files.
> --
>        --Per Bothner
> [email protected]   http://per.bothner.com/
>
> --
>
> You received this message because you are subscribed to the Google Groups
> "JVM Languages" group.
> To post to this group, send email to [email protected].
> To unsubscribe from this group, send email to
> [email protected]<jvm-languages%[email protected]>
> .
> For more options, visit this group at
> http://groups.google.com/group/jvm-languages?hl=en.
>
>
>

--

You received this message because you are subscribed to the Google Groups "JVM 
Languages" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/jvm-languages?hl=en.


Reply via email to