accordproject / template-archive

Smart Legal Contracts & Templating System
https://accordproject.org/projects/cicero/
Apache License 2.0
282 stars 119 forks source link

Support for multiple return types #37

Closed mttrbrts closed 6 years ago

mttrbrts commented 6 years ago

Context

Currently, clause logic can only specify a single return type. e.g. https://github.com/accordproject/cicero-template-library/blob/master/fragile-goods/lib/logic.js#L25

 * @param {io.clause.demo.fragileGoods.PayOut} context.response - the response

Expected Behavior

As a template author, I want my logic to be able to specify multiple CTO types without building a wrapper CTO type. This could be in the form of an array, or integer indexed object.

 * @param {Object[]} context.response - the response

or

 * @param {io.clause.demo.fragileGoods.PayOut} context.response.0 - the response
 * @param {io.clause.demo.fragileGoods.Message} context.response.1 - the response

Possible Fix

Need to look at this code: https://github.com/accordproject/cicero/blob/master/packages/cicero-engine/lib/engine.js#L167

                let type${n} = '${ele.getParameterTypes()[2]}';

Existing issues

None.

jeromesimeon commented 6 years ago

This is something that should be discussed. With Object[] you lose the type information. In JavaScript you might get away with it because it's mostly dynamic, but if you want a type checker (as I think we should get in Jura), you need to be able to describe the signature for the clause.

A traditional way to handle multiple return values is with a tuple. See e.g., http://www.codingexplorer.com/tuples-in-swift-create-read-and-return/

Sadly there is no tuple type (that I know of?) in CTO, so this means an extension to the Jura type system.

In Jura this could look as follows:

clause getPayout(request DeliveryUpdate) : (Payout, Message) { // code goes here }

It could be implemented as an 'on the fly record' so as a kind of syntactic sugar for a record (or JS side a JSON object) with the following structure:

{ '0' : PayoutValue, '1' : MessageValue }

or

{ 'payout' : PayoutValue, 'message' : MessageValue }

JavaScript side you could access it as:

const payout = response['0'];
const message = response['1'];

Do you think that might work?

jeromesimeon commented 6 years ago

A couple of following up notes:

jeromesimeon commented 6 years ago

@mttrbrts What's the reason for closing this?

mttrbrts commented 6 years ago

Reading this again, this should be an Ergo issue, so deferring to your issue https://github.com/accordproject/ergo/issues/20

jeromesimeon commented 6 years ago

👍 I thought it was! Sounds good.