-
-
Notifications
You must be signed in to change notification settings - Fork 117
Concepts, Assets, Participants, Transactions and Events (v1)
concerto.Concept
is the root of the type hierarchy: everything ultimately extends concerto.Concept
.
All namespaces implicitly import all the types in the concerto
namespace. I.e. import concerto.*
A concept does not have to have an identifier
. Identifiers are simple String
fields used as the natural idenfifier for types. Concerto does not support compound identifiers.
A Concept may include collections of other concepts (belongings, or contained/inline instances):
concept Person {
o Concept[] myStuff
}
Relationships
are used to define typed pointers to external identified
instances.
A concept may not include references to Concept
- as the base concerto.Concept
is not identified by a field.
concept Person {
--> Concept[] otherStuff // invalid
}
A concept may have an implicit (system) identifier:
namespace test
concept Person identified { // creates the system $identifier field
o String name
}
Serialized as:
{
"$class" : "test.Person",
"$identifier" : "DAN",
"name" : "Dan Selman"
}
A concept may alternatively have an explicit (named) identifier:
concept Person identified by ssn {
o String ssn
}
Serialized as:
{
"$class" : "test.Person",
"name" : "Dan Selman",
"ssn" : "xx-xxxx-xx"
}
A concept may include references to any identified types:
concept Employee {
o String name
--> Person manager // this is valid
}
To determine whether a type has an identifying field Concerto walks up the type hierarchy until it finds a type with an identifying field (either named or system), until it reaches concerto.Concept
.
Within a hierarchy of identified types, a given type may redefine its identifying field.
Do we want to support ^^^^? It may make the code more complex, as to determine whether a field is identifying for a type you need to look at not just at the type declaration, but at the type of the instance.
namespace test
concept Stuff identifier {
o String name
}
concept Vehicle identified by vin extends Stuff {
o String vin
o String make
o String model
}
/**
* Truck may override the identifying field defined by a super type ...
*/
concept Truck identified by truckId extends Vehicle {
o String truckId // note that Trucks must still have a vin, however it is no longer identifying
}
concept Tollbooth {
--> Vehicle[] vehicles // could be a relationship to either Vehicle or Truck
}
Serialization of relationships persist both the type of the relationship as well as the identifier:
{
"$class" : "test.Tollbooth",
"vehicles" : [
"test.Vehicle#123",
"test.Truck#ABC"
]
}
Assets are used within models to denote identifiable Things (nouns), while Partipants are identifiable people/organizations/parties.
Both concerto.Asset
and concerto.Participant
extend concerto.Concept
.
namespace concerto
abstract concept Concept {}
abstract concept Asset identified extends Concept {
}
abstract concept Participant identified extends Concept {
}
The keyword asset
is semantic sugar to denote that a type extends concerto.Asset
:
asset Truck identified by vin {
o String vin
o String make
o String model
}
Is equivalent to:
concept Truck extends concerto.Asset identified by vin {
o String vin
o String make
o String model
}
The keyword participant
is semantic sugar to denote that a type extends concerto.Participant
:
participant Party identified by email {
o String email
}
Concerto enforces that types that are declared as asset
or participant
must ultimately extend concerto.Asset
or concerto.Participant
respectively. This ensures that the modeller can denote the role of a type when declaring it, and document/enforce its ultimate super type.
Not clear that we want to enforce this ^^^^ restriction?
E.g.
asset Vehicle {
o String make
}
participant Truck extends Vehicle { // this is invalid, cannot redeclare an asset as a participant
}
Transactions are used within models to denote that an action should be performed. For example, UpdateAddressDetails
.
Events are used within models to denote that something has happened. For example, AddressModified
.
E.g. in Hyperledger Fabric there is a very different mechanism for handling incoming transactions (and responses to transactions), to the enqueue of events onto the Fabric event bus. Similarly Cicero supports a syncronous request/response programming model based on transactions, while also supporting async emission of events.
Both Transaction and Event must have a timestamp
fields that captures a DateTime
of occurrence.
Both concerto.Transaction
and concerto.Event
extend concerto.Concept
.
The keyword transaction
is semantic sugar to denote that a type extends concerto.Transaction
:
The type concerto.Transaction
is defined as:
abstract concept Transaction {
o DateTime timestamp
}
The keyword event
is semantic sugar to denote that a type extends concerto.Event
:
The type concerto.Event
is defined as:
abstract concept Event {
o DateTime timestamp
}