refractproject / minim

A library for interacting with Refract elements
MIT License
21 stars 9 forks source link

Support MSON inheritance #26

Open danielgtaylor opened 9 years ago

danielgtaylor commented 9 years ago

Right now this won't behave as expected. Think of the MSON which defines one type which is an object, then another which inherits from it:

Without expansion/preprocessing it's likely it will get expanded to something like this:

['object', {name: 'Data types'}, {}, [
  ['object', {name: 'A'}, {}, []],
  ['A', {name: 'B'}, {}, [
    ['string', {name: 'C'}, {}, 'test']
  ]]
]

In the above example we'll get an ElementType for B instead of ObjectType because there is no registered type for A. That means that B.content will be the raw content above instead of proper element instances. The solution may be to create some kind of lookup tree for the base type or some kind of preprocessing loop. Ideas?

zdne commented 9 years ago

I think refract implementations should provide this lookup – expansion – at least we are going to implement it in the C++ counterpart (cc @klokane)

smizell commented 9 years ago

@zdne @danielgtaylor This is something we need to decide. How does an MSON structure get converted into a normal Refract structure? I don't think Minim should handle that explicitly, though I think we can make some things that derive element definitions from a structure (which is essentially what MSON does).

First, let me change up the example above to match the MSON.

MSON:

Refract

["object", { "title": "Data types" }, {}, [
  ["object", { "id": "A", "name": "A" }, {}, {}],
  ["A", { "id": "B", "name": "B" }, {}, [
    ["string", { "name": "C" }, {}, "test"]
  ]]
]]

At this point, this is all Refract should do. MSON structures have their own way of representing the data. If you ran through something to convert to use MSON inheritance there are several steps we could take. First, convert

["object", { "title": "Data types" }, {}, [
  ["object", { "id": "A", "name": "A" }, {}, {}],
  ["extend", { "id": "B", "name": "B" }, {}, [
    ["ref", {}, {}, "A"],
    ["object", {}, {}, [
      ["string", { "name": "C" }, {}, "test"]
    ]]
  ]]
]]

Then dereference the A reference.

["object", { "title": "Data types" }, {}, [
  ["object", { "id": "A", "name": "A" }, {}, {}],
  ["extend", { "id": "B", "name": "B" }, {}, [
    ["object", { "ref": "A" }, {}, {}],
    ["object", {}, {}, [
      ["string", { "name": "C" }, {}, "test"]
    ]]
  ]]
]]

Finally compute extend:

["object", { "title": "Data types" }, {}, [
  ["object", { "id": "A", "name": "A" }, {}, {}],
  ["object", { "id": "B", "name": "B", "ref": "A" }, {}, [
    ["string", { "name": "C" }, {}, "test"]
  ]]
]]

Is this correct? Thoughts? I think we can make the jump straight to the end, but wanted to show some intermediate steps.

smizell commented 9 years ago

The solution may be to create some kind of lookup tree for the base type or some kind of preprocessing loop. Ideas?

I'm not sure the best way to do this. I'd be interested to see what the C++ say above doing this. I'm wondering if we will have to make two passes on the document.

klokane commented 9 years ago

I still have no completed expansion. But way how i will to complete it

How I understand to refract, expansion should provide complete resolution of every any type up to primitives w/o any linking.

I hope we will discuss it today with @zdne

smizell commented 9 years ago

I still have no completed expansion. But way how i will to complete it

I like it. Seems correct.

How I understand to refract, expansion should provide complete resolution of every any type up to primitives w/o any linking.

I think you're correct, but there are some cases around this to discuss. For example, Refract inheritance by default is simply inheriting the definition of the element, but does not inherit the actual data. In MSON, though, elements will actually inherit data from their respective parents. I think we need to discuss how to convey this, because I think by default Refract will act differently than MSON.

Hope that makes sense.

klokane commented 9 years ago

Refract inheritance by default is simply inheriting the definition of the element, but does not inherit the actual data.

Good to know, I miss it :)

smizell commented 9 years ago

@klokane See https://github.com/refractproject/refract-spec/blob/master/namespaces/mson-namespace.md#expanded-element