Nice TWiki > Dev > FeatureProposals > UnknownType TWiki webs:
Dev | Doc | Main | TWiki | Sandbox
Dev . { Changes | Index | Search | Go }

Unknown Type

I'd like to propose something that, at first glance, goes against the strongly typed phylosophy of Nice and Java. I'd like to have the ability to sometimes have a variable that does not have a known type, at compile time. This would mean that the compiler should make no assumptions on the variable's type. It would also mean that these variables would have to be resolved at runtime, for access to their fields and methods.

In Java or Nice today, we are forced to get by using an Object type, when we don't or can't know the type. The main problem with using Object is all of the type casting and instanceof operators that must be used with these variables or members.

Since Nice has MultiMethods?, meaning that methods are found dynamically, it only seem logical that this also be possible to accomplish at runtime, rather than compile time.


We would add unknown (and ?unknown) as a primitive (built-in) type. Here are some examples of the use of unknown:

    unknown depthSearch(Tree tree, unknown find);

    unknown entry = "This is a string";
    ?unknown first = null;
    unknown[] list1 = new unknown[50];
    var list2 = new ArrayList<unknown>();

    int len = entry.length();       // works because entry currently refers to a String and because
                                    //   String.length() returns an int
    file = new File(entry);         // works because File has a Sring constructor, and without typecasting
    int width = entry.width();      // would compile, but fail at runtime
    Set<int> set = entry.charAt(0); // seems silly, but would compile, then fail at runtime


Most scripting languages like Perl, Python, Ruby, and JavaScript never declare types for variables. Here are some of the advantages of unknown variables.


There are some problems with untyped variables, which is why many of us favor strongly typed languages for enterprise level projects. Because of these problems, the use of untyped variables should not be easy or encouraged, as they are in scripting languages. Here are a few of the problems.
    unknown found = list2[15];
    if (found instanceof Number) {
        /* Compiler knows 'found' is a Number here and can take advantage of that */

See also DynamicMembers for an idea of how to possibly implement runtime member lookup.

-- TroyHeninger - 25 Oct 2003

Thanks for your ideas. It is true that although strong typing is better when it is possible (and with Nice we try to make it possible more often), there will always be cases where it is not "clever" enough.

One aspect of Nice you might have missed is that, with type parameters, you can handle some of the situations you mention. For instance, instead of

  unknown `.`(row@Results, String column);
you can already write:

  <T> T `.`(row@Results, String column);

which says: the return type is T, for whatever value of T you choose (since T does not appear in the parameter list). This is already used in the standard library for serialization/deserialization without casts. You can also look at this forum thread about reflexion support.

This does not allow to have a local variable of any type, though, because T must be declared in a method type. But I believe this already covers many interesting cases.

-- DanielBonniot - 25 Oct 2003

That brings up several questions. 1) Does Nice currently support overriding the `.` operator, as you implied above? If so, then you've already answered my request for this in DynamicMembers. 2) With Nice's current type capabilities, is it possible to create an array or tuple of unknown types? I don't think it is. 3) How hard would it really be to add unknown to Nice? If you don't think it would be too hard, I'd be willing to look into adding it myself. I do have compiler writing experience, though I don't have tons of time.

-- TroyHeninger - 12 Nov 2003

1) You can put anything inside ``, so a method definition using `.` is valid. However, you would not be able to call it using the e1.e2 syntax, so that's not yet what you want (in the other discussion). My point here was about typing.

2) You're right, using <T> for unknown types does not carry on to arrays. What you can do currently is use Object for that purpose. You can convert any value to Object by using the method object(...). On the way back, you would use a cast or instanceof.

3) Basic support exists, using Object as described above. One could do better, by not requiring the use of object(...) (that is, make Object the top type). This should not be very difficult.

If you want to allow any operation on Object (or unknown) to succeed, and discover the operation at runtime, that would more work. Although maybe you could just rewrite f(e1, ..., eN) where at least one of e1...eN has the unknown type into dynamic_call("f", e1, ..., eN), and implement dynamic_call as a library function that uses reflexion and the class of its arguments to find what method to call. Is this what you are driving to?

It's interesting, although my bias is usually more towards static solutions. I'm not sure if you are awre that Nice is already quite clever about instanceof, so you don't need casts in addition:

Object f = operationReturningAnything();
if (f instanceof String) {
  // f has type String here, no cast required.
  int len = f.length(); // String operation, resolved at compile time.

This removes about half of the boilerplate needed in Java when using arbitrary types. If the removal of object(...) mentioned above was implemented, would not this provide quite a good support already, without loosing any type safety?

-- DanielBonniot

Topic UnknownType . { Edit | Attach | Ref-By | Printable | Diffs | r1.4 | > | r1.3 | > | r1.2 | More }
Revision r1.4 - 12 Nov 2003 - 14:01 GMT - DanielBonniot
Parents: WebHome > FeatureProposals
Copyright © 1999-2003 by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding TWiki? Send feedback.