neighbour-hoods / rep_lang

a language for Cultural Articulation
Other
20 stars 4 forks source link

Implement API interface for DSL runtime #5

Closed pospi closed 2 years ago

pospi commented 3 years ago

Proposed toplevel crate API interfaces from conversations between @mhuesch & @pospi -

Compiler

Language parsing and AST introspection

Interpreter

Runtime execution of interpreted reputation language expressions against some set of input data

where

  struct ReputationCalculationResult  {
      calculation: poly_rs::Expr,
      type: poly_rs::Type,
      value: poly_rs::Value,
  }

Internal operation:

At each stage in the computation (each unwinding of poly_rs::Expr)—

At every step in evaluation the runtime by its nature should have awareness of poly_rs::Type and poly_rs::Value, which enables it to infer compatibility of arithmetic operations between different poly_rs::Type with compatible underlying poly_rs::Value types. (eg. metres / seconds = valid m/s because both inputs are doubles / decimals)

mhuesch commented 3 years ago

I have made some decent progress on this over on this branch.

the type signatures are a little different:

pub fn parse_calculation(dsl_document: String) -> Result<syntax::Program, String>

pub fn get_calculation_type(program: syntax::Program) -> Result<types::Scheme, String>

pub fn reduce_calculation(
    prog: syntax::Program,
    input_data: &mut dyn Iterator<Item = eval::Value>,
) -> Result<ReputationCalculationOutput, ReputationCalculationError>

pub struct ReputationCalculationOutput {
    pub rcr_calculation: syntax::Expr,
    pub scheme: types::Scheme,
    pub value: eval::Value,
}

pub enum ReputationCalculationError {
    ArityMismatch(usize, usize),
    ProgramTypeInferenceError(TypeError),
    ProgramValuesUnificationError(TypeError),
}

// I opted to create a single function `get_calculation_type` above, onto whose output these functions can be applied.
// it returns a `Scheme`, which is `Type` along with any free `TVar`s in the type. so it's slightly different but these functions can be made to line up with each other.
pub fn type_arguments(ty: &Type) -> Vec<Type>
pub fn type_return(ty: &Type) -> Type

it seems to be going fairly well, and I have mostly filled in the body of reduce_calculation. it has some bugs which I've already identified / left as TODOs as I went along.

I have not seen any significant issues with the approach thus far - seems like it will work, and may be all wrapped up in a few more days of work.

I have not yet tackled poly_rs::Type::TRelated(op, Type, Type).

pospi commented 3 years ago

Looking great!

Clarification- do type_arguments and type_return deal with types::Scheme, rather than Type as indicated?

I have been thinking about ReputationCalculationOutput a bit more. What it really craves is some datum held as an indicator of the source information which yielded the given result.

Maybe a sum would be a good way to carry this information forward in aggregate? So we could include an additional source: eval::Value that can be used in combination with type_arguments to determine what kind of information was passed in, and how many records?

mhuesch commented 3 years ago

Looking great!

Clarification- do type_arguments and type_return deal with types::Scheme, rather than Type as indicated?

Right now they force the user to unpack the Scheme, get out the enclosed Type, and pass that in. I suppose I could make a trait method so that the functions work with both Scheme & Type.

I have been thinking about ReputationCalculationOutput a bit more. What it really craves is some datum held as an indicator of the source information which yielded the given result.

Maybe a sum would be a good way to carry this information forward in aggregate? So we could include an additional source: eval::Value that can be used in combination with type_arguments to determine what kind of information was passed in, and how many records?

Hmm, I think I lack context to understand this & the motivation. Would source be a single element or an iterator/vector of multiple, for the arguments provided to reduce_calculation?

Maybe it would help me to understand the constraints on the “caller” (which is the Vault?) - what it needs and is looking to do.

There’s a lot of data being plumbed around which I could easily imagine being useful “to the outside” and perhaps I can be more systematic in persisting it / making it available.

mhuesch commented 3 years ago

@pospi would it be a good use of time for you to run me through some of the vault so I can understand the constraints? then we can have two brains guiding the structuring of the API.

I see https://github.com/sacredcapital/ReputationVault as empty, maybe code is somewhere else.

mhuesch commented 3 years ago

I think the guts of this are mostly done on the branch. I have not implemented type inference for closures, which means they cannot be provided via the values iterator. I am pretty sure I know how to support them, but figure it is less likely that people will want to send in values?

So, I think we might be able to wire the top level API up to other things (the vault?) now and see what works / breaks.

pospi commented 3 years ago

Noting work to do following today's sync call:

pospi commented 3 years ago

RE total langauges-

So, unbounded computation is not an issue until we need such features.

pospi commented 3 years ago
mhuesch commented 2 years ago

I am favoring a more "organic" approach to developing this top-level API, starting with https://github.com/sacredcapital/rep_interchange/issues/8 as "first contact between Holochain and rep_lang".

there are good things in this issue to revisit when designing the successor "directed experiments" which will follow https://github.com/sacredcapital/rep_interchange/issues/8.