Skip to content

Instantly share code, notes, and snippets.

@okram
Created November 7, 2020 12:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save okram/29f3f09830aeb43c5d6679201965eb38 to your computer and use it in GitHub Desktop.
Save okram/29f3f09830aeb43c5d6679201965eb38 to your computer and use it in GitHub Desktop.
mmlang> 5 => int+2-<(nat;nat+10)=(vertex;vertex)=>edge
==>edge:('outV'->vertex:('id'->nat:7),'inV'->vertex:('id'->nat:17))
mmlang> int => int+2-<(nat;nat+10)=(vertex;vertex)=>edge
==>edge<=int[plus,2]
[split,(nat{?}<=int[is,bool<=int[gt,0]];nat{?}<=int[is,bool<=int[gt,0]][plus,10])]
[combine,(vertex;vertex)]
[as,edge<=(vertex;vertex)
[split,('outV'->vertex<=(vertex;vertex)[get,0,_],
'inV'->vertex<=(vertex;vertex)[get,1,_])]]
@okram
Copy link
Author

okram commented Nov 7, 2020

I've been working on a concept I'm calling cascading coercion (or chained implicts). The general idea is that your API (a model in mm-ADT) is a bunch of types that are linked together in a graph by instruction paths that will yield one type from another type. If you are at a string and want to make that string a person, you simply do 'marko' => person ... the most efficient way of generating a person from a string is searched and computed.

This graph is called the obj graph and it is of fundamental importance to nearly every process in mm-ADT.
https://www.mm-adt.org/vm/


Here is a simple property graph model. An mm-ADT model is a collection of types. Types are of the form range<=domain[inst]. Given a domain type, if you evaluate the sequence of instructions, then an obj of the range type is returned.

NOTE: The model format below is just to help for human organization. It could just be a flat list. Ultimately, a model is a graph and a "flat list" is equivalent to an edge list.

pg:(
'import' -> (num -> ()),
'type'   -> (
  int    -> (int<=vertex.id),
  vertex -> (vertex:('id'->nat),
             vertex<=nat-<('id'->nat)),
  edge   -> (edge:('outV'->vertex,'inV'->vertex),
             edge<=(vertex;vertex)-<('outV'->.0,'inV'->.1))
))

A obj graph is constructed that links all these types by their domain and range. It also decomposes (bi-)products and links up the individual components.

Now, to say: "morph 5 into an int" you express that as below.

mmlang> 5 => int
==>5

SYNONYMS: morph, coerce, map, translate, ...

How about a nat (realize we imported the num package in the pg model above)?

mmlang> 5 => nat
==>nat:5
mmlang> -15 => nat
language error: -15 is not a nat

What does it look like compiled?

mmlang> int => nat
==>nat<=int[as,nat<=int[is,bool<=int[gt,0]]]

Let's create a (bi-)product.

mmlang> 5 => int+2-<(nat;nat+10)
==>(nat:7;nat:17)

Now lets have each component morph accordingly.

mmlang> 5 => int+2-<(nat;nat+10)=(nat;vertex)
==>(nat:7;vertex:('id'->nat:17))

An edge is a reference to a 2-component product. There is a path from (nat;vertex) to edge. It's:

mmlang> (nat;vertex)=>edge
==>edge<=(nat;vertex)[combine,(vertex<=int[is,bool<=int[gt,0]][as,vertex<=nat[split,('id'->nat)]];vertex)<=(nat;vertex)]
                     [as,edge<=(vertex<=int[is,bool<=int[gt,0]][split,('id'->nat)];vertex)
                               [split,('outV'->vertex<=(vertex:('id'->nat);vertex)[get,0,_],
                                        'inV'->vertex<=(vertex:('id'->nat);vertex)[get,1,_])]]

Thus:

mmlang> 5 => int+2-<(nat;nat+10)=(nat;vertex)=>edge
==>edge:('outV'->vertex:('id'->nat:7),'inV'->vertex:('id'->nat:17))

...or let the compiler do the work for you -- an obj graph search from source to sink.

mmlang> (5;17) => edge
==>edge:('outV'->vertex:('id'->nat:5),'inV'->vertex:('id'->nat:17))

@okram
Copy link
Author

okram commented Nov 7, 2020

The [explain] instruction provides a human readable breakdown of your types (which, if they are not base types, are composed of yet more types).

mmlang> (int;int) => edge => [explain]
==>'
edge<=(int;int)[combine,(vertex<=int[as,nat<=int[is,bool<=int[gt,0]]][as,vertex<=nat[split,('id'->nat)]];vertex<=int[as,nat<=int[is,bool<=int[gt,0]]][as,vertex<=nat[split,('id'->nat)]])<=(int;int)][as,edge<=(vertex<=int[is,bool<=int[gt,0]][split,('id'->nat)];vertex<=int[is,bool<=int[gt,0]][split,('id'->nat)])[split,('outV'->vertex<=(vertex:('id'->nat);vertex:('id'->nat))[get,0,_],'inV'->vertex<=(vertex:('id'->nat);vertex:('id'->nat))[get,1,_])]]

inst                                           domain                                              range                                         state
-------------------------------------------------------------------------------------------------------------------------------------------------------
[combine,(vertex<=int[as,nat<=int[is,boo...    (int;int)                                      =>   (vertex<=int[is,bool<=int[gt,0]][split,(...
 [as,nat<=int[is,bool<=int[gt,0]]]              int                                           =>    nat{?}
  [is,bool<=int[gt,0]]                           int                                          =>     int{?}
   [gt,0]                                         int                                         =>      bool
 [as,vertex<=nat[split,('id'->nat)]]            nat                                           =>    vertex:('id'->nat)
  [split,('id'->nat)]                            nat                                          =>     ('id'->nat)
 [as,nat<=int[is,bool<=int[gt,0]]]              int                                           =>    nat{?}
  [is,bool<=int[gt,0]]                           int                                          =>     int{?}
   [gt,0]                                         int                                         =>      bool
 [as,vertex<=nat[split,('id'->nat)]]            nat                                           =>    vertex:('id'->nat)
  [split,('id'->nat)]                            nat                                          =>     ('id'->nat)
[as,edge<=(vertex<=int[is,bool<=int[gt,0...    (vertex<=int[is,bool<=int[gt,0]][split,(...    =>   edge:('outV'->vertex<=(vertex:('id'->nat...
 [split,('outV'->vertex<=(vertex:('id'->n...    (vertex<=int[is,bool<=int[gt,0]][split,(...   =>    ('outV'->vertex<=(vertex:('id'->nat);ver...
  ->[get,0,_]                                      (vertex:('id'->nat);vertex:('id'->nat))      =>     vertex:('id'->nat)
  ->[get,1,_]                                      (vertex:('id'->nat);vertex:('id'->nat))      =>     vertex:('id'->nat)
'
mmlang>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment