Skip to content
This repository has been archived by the owner on Apr 13, 2023. It is now read-only.

Backend-specific dependencies #3605

Closed
CeylonMigrationBot opened this issue Dec 10, 2012 · 19 comments
Closed

Backend-specific dependencies #3605

CeylonMigrationBot opened this issue Dec 10, 2012 · 19 comments

Comments

@CeylonMigrationBot
Copy link

[@FroMage] We need a way to say that backend JVM depends on those modules, but backend JS on those.

[Migrated from ceylon/ceylon-spec#499]
[Closed at 2015-08-17 17:22:06]

@CeylonMigrationBot
Copy link
Author

[@tombentley] Once we have a way to specify that a compilation unit is only for a particular back end (#3606), this could be done by allowing the dependencies of a module to be declared 'outside' the module descriptor some how. For example using the source-java suggestion I made in #3606, if the source directory contained the module.ceylon (which would contain the common dependencies) then the source-java directory could contain some compilation unit which added to those dependencies. This other compilation unit would only be allowed to add dependencies, not specify the module name or version.

Would you be allowed to export such backend specific dependencies?

@CeylonMigrationBot
Copy link
Author

[@FroMage] I think with the implementation of #3606 we could define annotations for backend-specific imports and keep them all in the single module.ceylon file:

module foo '1' {
 import bla '1';
 jvm import bli '2';
 js import foo '1';
}

@CeylonMigrationBot
Copy link
Author

[@FroMage] BTW, this would be trivial to implement.

@CeylonMigrationBot
Copy link
Author

[@gavinking] I think this makes sense. Of course, it's only 1/2 of the problem. We still need to be able to define a module which has different underlying implementations for different backends. This feature, on its own, is almost useless. The hard bit is how to define a platform-independent module that makes use of platform-specific code.

@CeylonMigrationBot
Copy link
Author

[@FroMage] Well, go and tell us to go ahead on #3606 then ;)

@CeylonMigrationBot
Copy link
Author

[@gavinking] We will solve this and #3606 for Ceylon 1.1. Not for Ceylon 1.0. Sorry.

@CeylonMigrationBot
Copy link
Author

[@gavinking] I'm closing this issue. AFAICT, it doesn't propose anything that is not already provided by optional. If the functionality of optional should be enhanced in some way, please submit a new issue for that, with a proper definition of what needs doing.

@CeylonMigrationBot
Copy link
Author

[@FroMage] What? This is not about optional, unless you define what its semantics are to retrofit this issue. We discussed situations where for example the JVM backend would require module X (jvm-only) and Y (cross-backend) while the JS backend would require module Z (JS-only).

Also optional would never produce an error if the module is missing, and in the case of multi-backends we surely want to make sure the dependencies exist.

@CeylonMigrationBot
Copy link
Author

[@gavinking]

What? This is not about optional, unless you define what its semantics are to retrofit this issue. We discussed situations where for example the JVM backend would require module X (jvm-only) and Y (cross-backend) while the JS backend would require module Z (JS-only).

All of which cases are already handled by judicious application of optional.

Also optional would never produce an error if the module is missing, and in the case of multi-backends we surely want to make sure the dependencies exist.

Ok, fine, so let's enhance optional to specify that a dependency is required for a certain platform. Sounds easy enough to do.

@CeylonMigrationBot
Copy link
Author

[@quintesse] Can't we reuse the platform annotation you just suggested in #3606 ?

@CeylonMigrationBot
Copy link
Author

[@FroMage]

All of which cases are already handled by judicious application of optional.

No, because optional ATM makes the module visible to every unit if it happens to be resolvable, and not just to certain backends.

Ok, fine, so let's enhance optional to specify that a dependency is required for a certain platform. Sounds easy enough to do.

Well, perhaps, even though I have a feeling this will end up meaning not required for backend X which is a negative I don't quite like.

But if you agree optional as it is is not enough, let's reopen this issue.

@CeylonMigrationBot
Copy link
Author

[@FroMage] platform would work, but that's essentially the original proposal, no?

@CeylonMigrationBot
Copy link
Author

[@gavinking] Moving to 1.2.

@CeylonMigrationBot
Copy link
Author

[@quintesse] I've just pushed some proof of concept code as a solution for the following two issues:

I say proof of concept but the code is completely working and could be merged as-is.

I've also created a small project with some test code to look at: https://github.com/quintesse/spec500proposal

So with this code you can now add @backend:"xxx" annotations to certain source elements in your code and only the associated compiler will handle that part and it will be ignored by the others.

Currently 3 different backends are recognized: jvm, js and doc

So for example:

@backend:"jvm"
shared void test() { print("A test for the JVM"; }

will only generate this method when compiled with the Java backend compiler.
Of course the above is not interesting, this is:

shared void test() { testImpl(); }

@backend:"jvm"
void testImpl() { print("A test for the JVM"; }

@backend:"js"
void testImpl() { print("A test for JS"; }

Calling `test()`` will now result in a different result on the JVM backend than on the JS backend.

You are even able to do this in module.ceylon files and with imports in source files:

module mymod "1.0" {
    @backend:"jvm" import ceylon.file "1.1.1";
    @backend:"js" import com.nodejs.fileaccess "3.18";
 }

and then in your source file you could have:

import ceylon.file { @backend:jvm home }
import  com.nodejs.fileaccess { @backend:js getHomeDir }

@backend:"jvm"
String homeDir => home;

@backend:"js"
String homeDir => getHomeDir();

You can even mark entire files as being just for one backend or the other:

@backend:"jvm";    // <-- see the semi-colon!

import ceylon.file { home }

String homeDir => home;

(Didn't anyone besides @gavinking even know you could put annotations on the file itself? I found it by accident looking at the grammar)

And finally an element can also have multiple annotations, this might be useful in the case of documentation for example, where you can do this:

@backend:"jvm" @backend:"doc"
"A very long explanation here documenting the exact behavior of this method"
String homeDir => home;

@backend:"js"
// No docs here
String homeDir => getHomeDir();

I think this work pretty well to be honest. It goes a very long way to make everything we wanted for backend-dependent code and dependencies possible. The only thing I'm not too fond of is the longish name "backend", "for" is unfortunately not possible (of course), other suggestions are welcome.

So WDYT?

@CeylonMigrationBot
Copy link
Author

[@luolong] Sort of elegant, but I was under impression that compiler annotations were not meant to be surfaced to anyone but compiler developers.

I would wait for Gavin's opinion on this one.

@CeylonMigrationBot
Copy link
Author

[@quintesse] Sure, but they are far easier to use when making a PoC :)
They've already been changed to native("xxx")

@CeylonMigrationBot
Copy link
Author

[@luolong] I do not actually mind using compiler annotations for this at all. It kind of fits the bill :)

@CeylonMigrationBot
Copy link
Author

[@quintesse] In a way it does yes, marking some code in a class file in a .car with native("jvm") seems a bit superfluous ;)
But as long as I can implement the required functionality I don't mind.

@CeylonMigrationBot
Copy link
Author

[@quintesse] I think this can be closed now. Any remaining problems can be put in their own issues.

quintesse added a commit that referenced this issue Nov 14, 2015
quintesse added a commit that referenced this issue Nov 14, 2015
quintesse added a commit that referenced this issue Nov 14, 2015
quintesse added a commit that referenced this issue Nov 14, 2015
quintesse added a commit that referenced this issue Nov 14, 2015
quintesse added a commit that referenced this issue Nov 14, 2015
quintesse added a commit that referenced this issue Nov 14, 2015
quintesse added a commit that referenced this issue Nov 14, 2015
… so we can ask it what backends it can do lookups for (#3605 and #3606)
quintesse added a commit that referenced this issue Nov 14, 2015
…aration` and we initialize it from any `native` annotations it might have (#3605)
quintesse added a commit that referenced this issue Nov 14, 2015
quintesse added a commit that referenced this issue Nov 14, 2015
…and the native attribute of the imported module itself (#3605)
@quintesse quintesse modified the milestones: 1.2, 1.5 Nov 16, 2016
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants