An earlier proposa=
l for special-casing `java.dyn.Dynamic`

provides a minimal s=
et of functionality to support interoperability with dynamically typed valu=
es, assuming those values are mostly produced and manipulated in other lang=
uages.

By assigning canonical invokedynamic calls to other uses (in Java) of dy= namic expressions, additional possibilities open up for integrating Java wi= th other languages. The extra steps include defining, for additional constr= ucts which involve dynamic subexpressions. Each such construct is transform= ed into one or more invokedynamic calls.

Here are the invokedynamic calls for each additional syntax that allows =
dynamic subexpressions. For each expression, the variables "x" and "y" are =
dynamic. Variables "a" and "b" are of arbitrary types "A" and "B", which ma=
y or may not be the type `Dynamic`

.

The unary arithmetic and bitwise operators ! ~ are transformed according= to this pattern:

!x Dynamic.<Dynamic>#"operator:!"(x)

The binary arithmetic and bitwise operators + - * / & | ^ % <<= >> >>> are transformed according to this pattern:

x+a Dynamic.<Dynamic>#"operator:+"(x, a) a+x Dynamic.<Dynamic>#"operator:+"(a, x)

The binary relational operators > < =3D=3D <=3D >=3D !=3D ar= e transformed according to this pattern:

x!=3Da Dynamic.<boolean>#"operator:!=3D"(x, a= ) a!=3Dx Dynamic.<boolean>#"operator:!=3D"(a, x)

Normal method calls are transformed as specified above; the name is not = augmented in any way, and is therefore distinct from any other invokedynami= c selectors generated by these transformations:

x.foo(a,b,...) Dynamic.<Dynamic>foo(a,b,...)

The field and array element selection syntaxes, when a Dynamic-typed val= ue appears to the left of the dot or array bracket, is transformed accordin= g to this pattern:

x.foo Dynamic.<Dynamic>#"field:foo"(x) x[a] Dynamic.<Dynamic>#"element:"(x,a)

As a result of the symmetry between the two syntaxes for invokedynamic e= xpressions, the previous transformations are more compactly expressed as fo= llows:

x.foo x.#"field:foo"() x[a] x.#"element:"(a)

A simple assignment of a selection expression, when a dynamic expression= appears to the left of the dot or array bracket, is transformed as follows= :

x.foo=3Da {t=3DDynamic.<Dynamic>#"set:field:foo"= (x,a); if(x!=3Dt)x=3Dt;} a x[a]=3Db {t=3DDynamic.<Dynamic>#"set:element:"(x,a,b= ); if(x!=3Dt)x=3Dt;} b

The transformed code contains three separate operations: First, an invok= edynamic expression processes the base reference and the incoming value (an= d the index value, if any). Second, the result of the invokedynamic is assu= med to return the original base reference, or perhaps an updated version of= it; it is in any case assigned to the original variable containing the ref= erence, if it has changed. Finally, the assigned value is produced as the v= alue of the whole expression.

If a dynamic expression appears as an element index, the transformation = is similar, except that the array variable is not reassigned:

a[x]=3Db {Dynamic.<void>#"set:element:"(a,x,b);= } b

Similarly, a method call may be the subject of an assignment, if its rec= eiver is dynamic. This produces a dynamic call by a transformation similar = to assignments to selection expressions:

x.foo(a,b,...)=3Dc {x=3DDynamic.<Dynamic>#"set:foo"(x,a,b= ,...,c);} c

The compound assignment operators ** +=3D -=3D *=3D /=3D &=
;=3D |=3D ^=3D %=3D <<=3D >>=3D >>>=3D**=
are transformed according to this pattern:

x+=3Da x =3D Dynamic.<Dynamic>#"operator:+=3D= "(x, a) a+=3Dx a =3D Dynamic.<A>#"operator:+=3D"(a, x)

If the left-hand operand of the compound assignment is itself a dynamic = selection expression, the simple assignment in the transformation of the co= mpound assignment is further transformed. Therefore, the final results are = as follows:

x.foo+=3Da {t=3Dx.#"field:foo"().#"operator:+=3D"(a); x= =3Dx.#"set:field:foo"(t)} t x[a]+=3Db {t=3Dx.#"element:"(a).#"operator:+=3D"(b); x=3Dx.= #"set:element:"(a,t)} t a[x]+=3Db {t=3DDynamic.#"element:"(a,x).#"operator:+=3D"(b)= ; Dynamic.#"set:element:"(a,x,t)} t

The unary assignment operators ** ++ --** are t=
ransformed according to this pattern:

++x x =3D Dynamic.<Dynamic>#"operator:++"(x) x++ {x =3D Dynamic.<Dynamic>#"operator:++"(x,null= );} x /*previous value*/

Uses of dynamic values in constructs requiring booleans is allowed. They= are converted to booleans as according to this pattern:

if (x) if (Dynamic.<boolean>#"as:"(x)) x ? a : b Dynamic.<boolean>#"as:"(x) ? a : b

This pattern holds for if, while, do/while, for, assert, and the first o=
perands of the boolean expressions `?: && ||`

.

A ternary expression is dynamic if and only if its second or third opera= nd is dynamic.

A sequential logical expression `&& ||`

is dynamic if and only if one of its two subexpressions is dynamic. In =
that case (and in any case), its meaning is defined by the following transf=
ormations:

a || b a ? a : b a && b a ? b : a

This treatment of operators scales easily to other, non-Java operators, = if an expression parser were able to parse them. There have been proposals = (such as Borneo) to allow disciplined extension the set of o= perators in Java-like languages. The conventions given here would adapt eas= ily, and allow a flexible (if statically untyped) way of supplying semantic= s to those operators.

If the expression of the for-each statement is `Dynamic`

, the=
statement transformed as follows:

for (A a : x) for (A a : Dynamic.<Iterable<A>>#"= for:"(A.class, x))

Note that the type parameter for `A`

is made explicit in the =
dynamic call.

In all these transformations, temporaries are generated as needed to pre= vent side effects from being doubled.

The operator names are rendered in invokedynamic call sites by prependin= g the string "operator:" and then adding the operator spelling, with the fo= llowing (arbitrarily fixed) translations of dangerous identifier characters= . Each translation of a dangerous character is a two-character pair which b= egins with a backslash character, as follows:

dangerous: / < > [ ] safe replacement: \| \^ \_ \{ \}

For example, the ** <<=3D** operator is s=
afely (if rudely) spelled as

`#"\^\^=3D"`

There is no special transformation for other statement types. The switch= , throw, synchronized, and try statements do not accept dynamic expressions= .

(A dynamic expression cannot be cast or converted to a parameterized typ= e instance. This is a problem; the erased information must be reified as an= extra argument to the MOP. Likewise, erasing argument types before calling= invokedynamic loses important information.)