Any plans to support "uses <namespace>.<classname>"?

After resolving my issue with FragmentPagerAdapter, I did a bit of digging to see if Java developers didn’t have similar issues with namespaces causing them problems in this area.

I noticed that in many/most/if not all cases, Java developers were importing only the specific FragmentPagerAdapter class from the android.support.v13.app namespace, rather than the entire namespace:

import android.support.v13.app.FragmentPagerAdapter;

This currently isn’t possible with Oxygene. Hence I was importing the entire v13.app namespace (and the v4.app namespace, for the ViewPager class) which is what ultimately seemed to be causing my problems with the resulting confusion of class references from different namespaces.

Are there any plans - or would you consider making plans :slight_smile: - to allow specific class references to be made in the uses list, to allow directly equivalence between Java imports and Oxygene uses ? e.g.

uses
   android.app,
   android.support.v13.app.FragmentPagerManager,
   etc...

It has just occured to me that one alternative approach would be to alias the desired class:

type
  FragmentPagerManager = android.support.v13.app.FragmentPagerManager;

Without adding the v13.app namespace to the uses list at all. But wouldn’t this then create yet another FragmentPagerManager identity in my application namespace which might cause even more confusion (unless this can be avoided somehow by making the aliased type restricted to the unit scope ? Is that even possible ?).

In any event, I haven’t tried this as yet, and even if it works it feels too much like a somewhat clunky workaround. Directly using specific classes would seem much cleaner, imho.

they’re not, though. equivalent. As i understand it, Java always imports classes, not namespaces, and mixing the two would cause a lot of confusion. (for one, while discouraged, you could have a class that has the same name as a namespace).

i think your example with the type alias is the proper solution. That, or using fully qualified names within the code.

—marc

Thanks Marc, but whilst Java can import classes it can also import entire namespaces:

import android.support.v13.app.*;

Which is directly equivalent to the Oxygene:

uses android.support.v13.app;

The difference is that in Java you can replace the ‘*’ with a specific class (and you have to, if you wish to import more selectively), where-as in Oxygene the ‘*’ is implicit and cannot be expressly overridden. It’s all or nothing.

The fact that you can have classes with the same name as a namespace then is already a problem that exists in Java. Oxygene developers would have to use the same techniques that Java developers have to employ in such circumstances.

Currently we don’t have all of those techniques available to us. i.e. the ability to selectively import only a specific class is missing from our toolkit. :wink:

And whilst problems might arise in those specific - and ideally rare - circumstances, the current situation causes problems with more mundane and common circumstances (as I spent over 2 hours finding out the other night! :().

uses
  android.support.v13.app,  

Which brings everything in that namespace into scope, including identifiers which potentially conflict with identifiers in other namespaces and introducing opaque sensitivities to the order in which namespaces are used (affecting how identifiers are resolved). It also seems to confuse the compiler under some circumstances, as evidenced by the inability to resolve and identify types when presenting errors/warnings (<unknown type> vs android.app.Fragment in my case).

Where-as:

uses
  android.support.v13.app.FragmentPagerAdapter,

Is entirely unambiguous. It would bring only the specific named class into scope, without all the baggage of everything else in that namespace.

Using a type alias works, but suspiciously looks to me like a more cumbersome way of approximating the same outcome. In my FragmentPagerAdapter case, I eliminate all references to the support namespaces in my uses list and replace them with two type aliases:

type
  FragmentPagerAdapter = android.support.v13.app.FragmentPagerAdapter;
  ViewPager            = android.support.v4.view.ViewPager;

// Could have been the less verbose:
uses
   ..
   android.support.v13.app.FragmentPagerAdapter,
   android.support.v4.view.ViewPager,
   ..

But it’s worse than just requiring more typing.

The type alias doesn’t just bring the required identifier into scope. In fact, it only does this as a side effect if my alias happens to have the same name as the original type. Using a different name would introduce only more confusion of a different, um, type :slight_smile: imho .

The real effect of the type alias approach is to create a FragmentPagerAdapter and a ViewPager into my project/application namespace, which is neither what I intend nor need. I just want my references in this unit to these identifiers to be appropriately resolved using the identified namespace in each case.

Indeed, if I have another unit where I have the same need, the situation becomes even more complicated by the fact that attempting to repeat the pattern of “importing” the desired class using a type alias fails because this obviously would create a duplicate FragmentPagerAdapter in my application namespace.

True, I don’t now need the alias in this second unit, thanks to the existing alias established by side-effect in the first unit, so I simply don’t have such an alias in that subsequent unit.

But now let’s say that original unit is refactored in the future and the new UI no longer needs the FragmentPagerAdapter. Or the unit is removed entirely. Now any other units that relied on the side effect of the original type alias will break.

So I need a specific unit dedicated to importing such types into my namespace to avoid that problem. I can only hope this won’t cause problems in other parts of my application involving these types/namespaces. I can’t think of any concrete examples of how that might arise right now, but I have a niggly feeling that they might exist. Even if they can be worked around with qualification etc if/when they do arise, it doesn’t strike me as desirable to have to keep piling up the work-arounds for what could be solved so much more easily and directly.

I am struggling to see how the status quo is less confusing and problematic than simply being able to express the intent “in a specific unit to state that it uses a specific class from a specific namespace”.

Oxygene already has a .* syntax for uses clauses as well, and it sans something else, so that too would conflict. I see your point and why you would like this, but i don’t think it’s necessary, given there are several ways around this (use a type alias, use the fully qualified name, use type inference to alleviate the need to type the name out as often as otherwise necessary).

What we really have here is a badly designed library; i’d prefer to not mess up and overcomplicate the language (and dilute what “uses” does) to accommodate one case of badly named classes/namespaces, when these can already be used with the current solutions, w/o much complication.

i hope that makes sense.

Yes, what we have is a badly designed library. But that library design is not going to change and the likelihood is that, Android being what it is, more such badly designed libraries will emerge in the future.

Currently the ability to learn Android techniques in Oxygene with reference to Java examples is severely compromised by this difference in import capabilities. Providing the same ability to import only specific classes in Oxygene would make Java examples more directly “portable”.

And I do not see where the perceived problems that adopting this would lead to. The Oxygene ‘*’ syntax is different to the Java ‘*’ syntax.

In Oxygene it means all classes in all descendant namespaces.
In Java it means all classes in the namespace.

// Oxygene
uses android.support.v4.*;

// Is equivalent to the Java:
import android.support.v4.app.*;
import android.support.v4.view.*;
import android.support.v4...etc.*;

The problem being that the Oxygene uses implementation is always more broad than the Java equivalent. But introducing the ability to import a specific class would not cause any problems, confusion or conflicts:

uses
  // import all classes from a namespace:
      android.app,           
  // import all classes from the named and descendant namespaces:
      android.support.v4.*   
  // import only a specified class:
      android.support.v13.app.FragmentPagerAdater;  

I am not suggesting to change anything at all, only to add the ability to import more selectively. i.e. in a manner directly equivalent to that in Java.

Some consideration might have to be given to how to handle imports that effectively form duplicates or overlapping imports. But the potential for this situation already exists:

uses
  android.support.v4.*,
  android.support.v4.app;

// is no more or less problematic than:
uses
  android.support.v13.*,
  android.support.v13.app.FragmentPagerAdapter;

So whatever strategy is currently already employed in the former case would simply need to be extended to the latter.

If you’re suggestion is to simply not use “uses” imports for problematic namespaces, the problem with that approach is that you do not necessarily know that a namespace is going to cause any such problems, and when it does, the problems it causes confuse the compiler which makes more difficult the task of diagnosing the problem and identifying the specific workaround needed to avoid it.

In my case I ended up spending time refactoring classes out into separate units that really didn’t warrant separate units, simply to simplify the imports. At which point the compiler was able to finally provide useful information that lead to the resolution, allowing me to then re-re-factor my code back into the single unit that I wanted (and which made most sense).

At the very least, is any effort going to be put into resolving the issues that cause the compiler difficulty in reporting the relevant types involved in errors and warnings (i.e. reporting the confusing and unhelpful “<unknown type>”), so that identifying the cause of such problems and thus the required workaround could at least be made less problematic ?

This at least must be a bug, no ?

Again, it would. you child have a class stat has the same name as a namespace

namepsace Foo.Bar;

...

namespace Foo

type
  Bar = public class

now, what does uses Foo.Bar do? does it import the Foo.Bar namespace, or the Bar class in the Foo namespace?

the compiler should definitely emit clear messages (“ambiguous class name Foo” or the like. If you can provide me with a clear test case that shows where it doesn’t, i’ll get that logged, thanx!

Ah, I see what you mean now w.r.t the class/namespace issue. One solution would be to choose to prioritise namespaces over classes (since that is the existing behaviour) and to emit a warning of some sort where any conflict arises:

Warning: namespace Foo.Bar hides the class Bar in namespace Foo.

In such cases the solution would exactly what is being suggested in the face of the inability to import a specific class. i.e. don’t import the class and/or namespace and use qualification or a type alias to resolve the ambiguity.

But is this a situation that exists now, or only a potential situation ? Surely it shouldn’t be permitted by any compiler (Java) since the Foo.Bar class would conflict with the Foo.Bar namespace ?

Indeed, I just tested it and got this from the javac compiler:

Bar.java:4: error: class Bar clashes with package of same name
public class Bar {
       ^
Wibble.java:2: error: package foo.Bar clashes with class of same name
package foo.Bar;
^
2 errors

So it cannot occur within any current libraries. Could it still be an issue as a result of the fact that Oxygene is more tolerant when it comes to case sensitivity:

namespace:  foo.bar
class    :  foo.Bar

In Java these are distinct. In Oxygene it could conceivably present a problem (but no more so than any such case-dependent ambiguity that may already exist).

But, as interesting as all that it, the entire problem could be rendered academic with a small further refinement in the uses list to completely remove the ambiguity:

Allowing (indeed, requiring) the deployment of the “class” keyword for an item in the uses clause where a specific class is being imported.

i.e. / e.g.

uses
  Foo.Bar,         // imports Foo.Bar namespace
  class Foo.Bar,   // imports the Bar class from Foo
  Other.Namespace.Etc;

This feels even more “right” :slight_smile: and strikes me as straightforward to implement. The uses clause now may contain namespace identifiers and class identifiers, but where an identifier is to resolve to a class it must be preceded by the “class” token (and must unambiguously identify a class - i.e. no use of wildcard(s)).

Code Completion in this scenario could then also offer the classes from the namespace, rather than ‘*’ and/or child namespaces.

Meanwhile I shall create a self contained example of the issue that led to this itch and my subsequent need to scratch it. :smile:

Thanx!

OK, well when I tried to re-create the <unknown type > warnings I couldn’t. Recreating the actual warnings/errors was simple enough, but the types referenced in those warnings and errors were all quite clear. Not a missing or unknown type to be found.

All I can think is that it may have been some particular ordering of the namespaces in my uses, or the inclusion (or not) of some other namespaces that caused the problem. But I’m afraid I cannot afford to spend even more time on this trying to chase down the particular permutation that cost me so much time in the first place.

FYI - I recently upgraded to the latest beta 1599. I thought I had done this before any of these problems but checking the timeline it may well have been just after. Could it be that the problems with identifying referenced types in these circumstances has been resolved in that beta ? (prior to upgrading I was using the immediately preceding beta).

Incidentally, I still think that supporting “uses class <namespace>.<classname>” has merit, quite aside from the issues it would address in this case. :wink:

Python in addition to import <namespace> . <classname> has the syntax form:-
from <namespace> import <classname> or with the overriding class alias from <namespace> import <classname> <aliasname>

which acts as flexible way of defining the precise class dependency.

I do agree with Jolyon that it is tedious to define a type alias in Oxygene or full qualify the class type in place every time a class member or variable is declared.

Has changed since Aug 14?