Replies: 1 comment
-
|
https://hal.science/hal-00310317/file/cmsv-long.pdf is probably a good starting point for the implementation of mixins in a CBV language. Looks pretty complicated though, but maybe we don't need the full generality. I think it would be good to do a bit of a literature survey to see what the state of the art is. That paper is fairly old, and just a starting point. |
Beta Was this translation helpful? Give feedback.
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
This describes an idea I had with @crusso about building a mixin system from
actorfragments of fractional typeThis is a writedown of a few ideas we tossed around earlier today about incorporating incomplete actors into the type system and allowing such mixins to be combined.
Motivation
Imagine a system where actors are simply non-negative natural numbers. They can receive messages — that are primes —, but only when they have that prime as a factor.
According to the fundamental theorem of arithmetic the actors have a unique decomposition into primes, so
1will reject every message and6will accept2and3but reject others.If we want to combine abilities of actors (i.e. their message vocabulary) we multiply them: the
6we have encountered formerly combined with5will give an actor30which understands three separate messages.For technical reasons we only allow prime exponents (≤ 1) in the factorisations, the reason for which will become clear later.
Now let's observe that an actor can send messages to any other, as well as itself, but such a send is only valid if the receiver can understand it. Also we'd like to check if the sends are valid beforehand.
Fragments
Imagine we want to build actors from pieces (a preferable methodology!), like the
30actor we built above. The5fragment eventually can send message3to itself, but there is a problem: Checking5sending itself a3is invalid, and thus rejected.Is this the end of the modularisation idea? Is
5(as building block of30) unable to send a3to its eventual self?Let's entertain the idea of fractional actors:
5/3is not a natural number but a rational one, so it cannot be an actor. But it can be a building block of one with the crucial property that it can (eventually) understand the message3to self. So the send can be validated by considering the fragment in isolation.Building
So, how do we combine actors from fragments? We still use the multiplication rule with the extra condition that
p * q/pgivesp * q, i.e. the exponent 1 on the prime in the product is dominant. This way6 * 5/3becomes30as before, and we obtain the same actor.If the other building block is not having 3 as a prime factor, then the resulting actor is still fractional and thus second class. It still tracks the demand for a building block that can understand the message
3.How can we extend such an idea to Motoko?
In the motivation above the types and inhabited values coincide, i.e. the fractional actor
7 * 5/3has this rational number as type (as needed for validation). In Motoko we have a different system for typing actors than the actors themselves.Extending
actortypes with demandIn Motoko types like
actor { beep : () -> async () }are product types withactor { }as the neutral element under theandoperation (greatest lower bound, glb).To obtain fractional actor types we add fields that indicate demand:
Such fractional
actortypes can be made properactors(i.e. installable canisters) by combining them using theandtype operator. This is creating a product type, which motivates the "fractional" lingo. As with other named fields,importfields can only appear once in any actor type.Consider
which results in
Fractional actors are not
sharedtypes, and can't be projected out. They can, however, be passed as arguments, saved as values and returned as results.actorValuesWhen building the eventual
actor, the type system checks that allimportmethods are counterbalanced with manifest methods, i.e. the result is not fractional.One can build (fractional) actors from building blocks with the
actor { … } (and <actor>)*syntax where the<actor>part can be an expression ofactor { … }type. All fragments will have the same actor as the self reference.Non-
publicvisceraThe definition of an
actor(i.e.Syntax.ActorU) also containsdec_fields which don't show up in the actor type, but need to be desugared in a centralised fashion. These include e.g.privateutility functions andstablebindings as well assystemfunctions and upgrade hooks. When the builtactorgets lowered to IR these must be joined to a coherent whole from the mixin fragments.We could allow more labels in fractional actor types to track
private,system,stablesignatures too. These would represent positive information, but wouldn't participate in sub typing relations. They would, however, be propagated byand.Discussion
Some meta-thoughts here...
How is this related to open recursion?
This is the recursion part of it. Open means that in an inheritance setting always the most derived method is called (think calls via a vtable). But here we have no inheritance, the vocabularies of the mixins are disjoint.
Is this novel?
Probably not. Amr Sabry et al. had a few papers [1] about negative (travelling backwards in time) and fractional types more than a decade ago. I'll have to dig them out.
Is this worth a paper?
Maybe. I am not sure if there are actual type systems out there that run with the fractional idea...
Is it worth extending to
moduleandobject?Possibly. But for these the self reference seems much less prominent.
References
[1]
Fractional Types
Roshan P. James, Zachary Sparks, Jacques Carette and Amr Sabry
https://www.cas.mcmaster.ca/~carette/PiFractional/frac.pdf
Beta Was this translation helpful? Give feedback.
All reactions