Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Nomenclature is important to a JVM MOP since the main programmable channel in invokedynamic is a name string. Based on the mangling convention described earlier, we will used colon delimiters to structure names into simple token sequences, and use those structured names to manage linkage across the JVM and across languages.

Top-level name syntax

Here are some key questions in designing such names.

...

3. What are the common notions that can be permanently imported? Anything that the JVM defines natively needs a name. This includes method: and field: and element: and perhaps class: (if a class or interface can be an operation--and if class:x then also just int, boolean). Certainly new:. Certainly the distinction between a static, a special, and a normal method name. Maybe array element getters and setters Maybe also set:field:.

...

6. Similarly, there are other modifiers that factor across some of the other constructs: Null handling notations foo?.bar, multiple-value notations foo*.bar or foo(*bar), complex get/set patterns foo[*bar] = baz }} or {{ foo() += bar. How are these extra conditions mixed into the basic selection of field/element/method? Are these extra notations mixed in as prefixes (}}nullable:method:foo}}) or suffixes method:foo:nullable? Probably prefix-only, to avoid ambiguity. Or is there a way to mix several syntactic aspects together on an equal footing? (Yes, something like XML attributes. See argument attributes below as an example.Yikes!)

7. How do we leave open spaces for reified generics, if the JVM gets them, or if a language chooses to simulate them? This is another (complex) case of name modification. Adding Keeping the prefix convention, but adding bracket tokens, maybe we have classof{:listint:(}:intclass:)list.

8. What other degrees of freedom are needed for structured names?9. What is the "polite" human readable form for such names? (E.g., replace colons by spaces, replace empty tokens by a fixed hole token (like _) and further adjust spacing for legibility.) This point assumes we fail to reach our goal at point #1 above.

Argument annotations

Since a call site is all about stacked arguments and return values, each call site is governed by a signature or descriptor which specifies exactly which JVM-level types are pushed and/or popped at a call site. These types are not language-level types. Even for Java, they are "erased" types which omit certain statically checked generic type information.

So there is a sizeable set of argument annotations which do not affect the way the arguments would be stacked but are syntactically present at the call site, and are significant to function linkage or runtime typing.

Here are some:

A. Whether a transmitted argument is spread or not (as with Lisp &REST or Groovy f(*x); affects calling sequence adaptation).

B. Whether a transmitted argument is a (reified) type parameter (as in Scala f[x] vs f(x); not sure when/if they are reified, though).

C. Whether a transmitted argument is keyword-modified (and by what keyword).

D. If it matters, whether a transmitted argument is an appended block (f(x){y}).

E. Any additional language specific type or constraint information not present in the JVM-level type. (Example: nullability, array length, generic type information, structural or advisory typing.)

F. Whether two or more transmitted arguments are to be grouped logically as one. (E.g, type complex(re,im:real).)

G. Whether a transmitted argument is to be hidden from the receiving method. (Perhaps it is an implicit argument to a parameterizable calling convention; can't think of an example. B above is a special case of this.)

Many of these annotations need to shake hands with corresponding definition-site parameter annotations.

Apparently we need some way of affixing such information to a method name, as method:foo:(:...:):. Parameter annotations would correspond positionally to stacked arguments.

No Format

call = myfunc(a1, a2, key: a3, otherkey: a4)
name = "method:myfunc:(:,:,:keyword=key:,:keyword=otherkey:):"

When presenting to polite human company, rely on ordinary (complex) conventions for presenting token-based expressions:

No Format
 
method function(_, _, keyword=key, keyword=otherkey)

Note that the latter friendly notation isn't necessarily accurate encoding, since a keyword might be an arbitrary string, including one containing a comma. (Probalby no language uses this particular degree of freedom, but it would be crazy to build symbol spelling restrictions into a new MOP.)

To transmit two attributes with one parameter, separate them by (say) a plus token:

...