--- layout: developer-doc title: Typing the Polyglot Bindings category: polyglot tags: [polyglot, types] order: 2 --- # Typing the Polyglot Bindings The polyglot bindings inherently provide a problem for the Enso type system. When many of the languages with which we can interoperate are highly dynamic and flexible, or have significant mismatches between their type system and Enso's, we can only make a best effort attempt to maintain type safety across this boundary. <!-- MarkdownTOC levels="2,3" autolink="true" --> - [Enso Values](#enso-values) - [Polyglot Values](#polyglot-values) - [Dynamic](#dynamic) - [The Enso Boundary](#the-enso-boundary) <!-- /MarkdownTOC --> ## Enso Values The underlying nature of our runtime allows us to pass Enso values across the polyglot boundary while ensuring that they aren't modified. This means that the typing information known about a value `v` _before_ it is passed to a polyglot call is valid after the polyglot call, as long as the following properties hold: - The polyglot call does not modify the entity passed in. - The polyglot call returns an entity of the same type. However, there are sometimes cases where we _want_ to let an Enso value be used freely by the polyglot language. To that end, we have to have some way of distinguishing _safe_ usages of Enso values from _unsafe_ ones. In the latter case, the value needs to be treated as `Dynamic` after its use. > The actionables for this section are: > > - Think much more on this. ## Polyglot Values In the presence of a polyglot value, however, there is very little that we can determine about a value with which we are working. This means that we need to have a principled way to assert properties on a polyglot object that can then be reflected in the Enso type system. This mechanism needs to deal with: - Concurrent access to polyglot objects. - Mutation and modification of polyglot objects. - Potentially taking _ownership_ of polyglot objects. > The actionables for this section are: > > - Reflect more on this problem and think about what principled approaches we > could take to it. ## Dynamic As Enso can seamlessly interoperate with other programming languages, we need a principled way of handling dynamic types that we don't really know anything about. This mechanism needs: - A way to record what properties we _expect_ from the dynamic. - A way to turn a dynamic into a well-principled type-system member without having the dynamics pollute the whole type system. This may involve a 'trust me' function, and potentially dynamicness-polymorphic types. - A way to understand as much as possible about what a dynamic _does_ provide. - A way to try and refine information about dynamics where possible. ```ruby obj.model = { atom : Text , dict : Map Text Any , info : { doc : Text , name : Text , code : Text , loc : Location } , arg : # used only when calling like a function { doc : Text , default : Maybe Any } } ``` > The actionables for this section are: > > - Work out how to do dynamic properly, keeping in mind that in a dynamic value > could self-modify underneath us. ### The Enso Boundary Fortunately, we can at least avoid foreign languages modifying memory owned by the Enso interpreter. As part of the interop library, Graal lets us mark memory as read-only. This means that the majority of data passed out (from a functional language like Enso) is not at risk. However, if we _do_ allow data to be worked with mutably, when control is returned to Enso it needs to be treated as a dynamic as it may have been modified.