On Mon, Apr 24, 2017 at 1:26 PM, Gustavo Sverzut Barbieri
<barbi...@gmail.com> wrote:
> On Mon, Apr 24, 2017 at 12:38 PM, Cedric BAIL <cedric.b...@free.fr> wrote:
>> On Apr 24, 2017 07:03, "Gustavo Sverzut Barbieri" <barbi...@gmail.com>
>> wrote:
>>
>> On Mon, Apr 24, 2017 at 12:17 AM, Carsten Haitzler <ras...@rasterman.com>
>> wrote:
>>> On Mon, 10 Apr 2017 23:46:43 -0300 Gustavo Sverzut Barbieri
>>> <barbi...@gmail.com> said:
>> [...]
>>>> Clear example with edc is to do chained animations, a series of
>>>> "after" must be chained, but if you need to cancel that you can't call
>>>> it a 'chain', you need to cancel all the program{} blocks... Also the
>>>> rel1/rel2 are very close to our internals, don't get into must
>>>> people's head that expect what the new "anchor" patchset is adding.
>>>>
>>>>
>>>> [...]
>>>> > We have been iterating over a MVC design for more than a year now. I
>>>> > think we are nearing a design that start to look good. The funny part
>>>> > is when I was trying to find some presentation to explain people about
>>>> > MVC and the difference with what we were doing, I stumble on Microsoft
>>>> > MVVM design pattern which is pretty close to the design we have
>>>> > selected. So we will rename the work we have done from ProxyModel to
>>>> > ViewModel to use the same naming convention as everyone else.
>>>> >
>>>> > The main difference between MVC and MVVM is that it allow the
>>>> > definition of a clean interface between View and Model. There isn't
>>>> > really a ProxyModel or ViewModel interface, as they really are just a
>>>> > Model that get data from another Model and interpret them into what
>>>> > the View will actually display. This means you can easily reuse Model
>>>> > and that you can test your Proxy/ViewModel without connecting it to an
>>>> > actual View.
>>>> >
>>>> > And last very nice benefit, I think, is that you are defining a
>>>> > "connection" for each parameter of your widget. So to connect a View
>>>> > with a Model, you are only setting the model and indicating which
>>>> > property to fetch on the model. No need to deal with callback in many
>>>> > case ! For an example (which is broken at the moment) of the idea you
>>>> > can look at layout_model_connect.c in efl elementary example.
>>>> >
>>>> > The most complex work will now be in writing this Proxy or View Model.
>>>> > This is something we have to work on to make it easier.
>>>>
>>>> I've talked to you and felipe at IRC, I still think that the current
>>>> Model is trying to address too much of "performance and async" at the
>>>> level that it will suck for developers.
>>>>
>>>> to address the correct goal of "never block", what the current
>>>> implementation does is make all property-get async, resulting in a
>>>> promise... callback, etc. Whenever you need a simple:
>>>>
>>>>   if (model.a + model.b < model.c) do_bla(model);
>>>>
>>>> then you're screwed... you need to store these elsewhere, wait on 3
>>>> callbacks, then execute what you want. Okay, helpers to accumulate and
>>>> wait on all futures... then dispatch an array of values will be there,
>>>> but still.
>>>>
>>>> caching is also left to outside. But to cache properly you need to
>>>> know your information, access pattern, load coast, evict cost... Okay,
>>>> applications may know better which information they are going to use,
>>>> but they can hint that to model if needed (we could add a way to
>>>> declare "hot properties").
>>>
>>> i personally prefer the idea of caching. have the item object and list
>> which
>>> properties you want fetched, and some thread fetches in the background.
>> when
>>> it's done your promise or callback is triggered. once it is you can be
>> certain
>>> the properties are already fetched and live in memory. it's not a promise
>> per
>>> property to fetch. it's "get me all of this in a blob" and should be
>> simpler to
>>> deal with. this is where i dislike promises for this. i prefer some
>> "updated"
>>> callback... as below, it'd work better with live updates. if an object
>> changed
>>> at the source - the model can be listening and it already knows what
>> properties
>>> you want... and it can auto re-fetch them and then call the "updated"
>> callback.
>>> you only have to register that cb on that object once to handle all cases.
>>>
>>> child objects in a tree that you haven't instantiated yet of source you
>> don't
>>> get these cb's on... but parent objects could tell you if a child changed
>> etc.
>>
>> yes, that's my view as well, much simpler and people need a single
>> "updated" (or "changed") callback.
>>
>> as for the model itself, I started to experiment with Facebook's
>> GraphQL, looks quite nice...
>>
>> http://graphql.org/ (salesman bullshit)
>>
>> https://facebook.github.io/relay/docs/thinking-in-graphql.html (good
>> reasoning)
>>
>> https://facebook.github.io/relay/docs/thinking-in-relay.html (how
>> their JS implementation works)
>>
>> They have it easily linked with their UI framework (React) thus if you
>> use React + Relay you get automatic updates for all views given a
>> model property change, even if it was detected in an indirect query
>> (ie: you have a view with list of stories, another with the story
>> details... when the story details is updated, such as "like count",
>> then the list is automatically updated as well).
>>
>>
>> We have been looking with Felipe about using graphql for more than remote
>> call (still having support for a graphql data model would be useful). One
>> of our idea was to use it for type checking data model. When you write your
>> proxy model, you have to check the type of everything you access if you
>> want to be able to reuse that proxy with a different source. The idea would
>> be to have a proxy model that take a graphql and a data model to
>> automatically generate error when the type don't match your proxy model
>> expectation. This would simplify writing proxy data model a bit. Of course
>> error are automatically forwarded to the view and the view has a value to
>> display in case of error.
>>
>>
>> with caching and paging in the platform, given you conform to some
>> extra protocol (some properties/interfaces)... also great way they
>> handle "opportunistic updates"... and their "GraphQL" language to
>> describe queries, with fragments and all... is very Edc/Eo-like
>> syntax, they use that to generate JS, we could use that to generate C.
>>
>>
>> I don't understand what you have in mind that could be generated from
>> graphql, could you explain what you have in mind ?
>
> https://facebook.github.io/relay/docs/relay-compiler.html
> https://facebook.github.io/relay/docs/babel-plugin-relay.html
>
> basically you provide textual graphql files (like our ".eo"):
>
> schema {
>   query: Root
> }
>
> type Root {
>   dictionary: [Word]
> }
>
> type Word {
>   id: String!
>   definition: WordDefinition
> }
>
> type WordDefinition {
>   text: String
>   image: Url
> }
>
> These are used as reference, usually is what the server (provider
> role, it can be local and even in process) supports.
>
> Then use these in fragments from code in an "easy way" (that is not
> performance friendly):
>
> const DictionaryWordFragment = graphql`
>   fragment DictionaryComponent_word on Word {
>     id
>     definition {
>       ...DictionaryComponent_definition
>     }
>   }
> `
>
> const DictionaryDefinitionFragment = graphql`
>   fragment DictionaryComponent_definition on WordDefinition {
>     text
>     image
>   }
> `
[...]
>  - input fragment.graphql files, like
> Dictionary_Word_Fragment.graphql, one fragment per file
>
>  - reads fragment, validates against schema and generates
> Dictionary_Word_Fragment.eo + implementation in
> Dictionary_Word_Fragment.c that will handle caching, query, etc...
>
>
> This would expose a model "Dictionary_Word_Fragment" with properties
> "id" (non-null String), then child model "definition" which is a
> "Dictionary_Definition_Fragment" with properties "text" (string) and
> "image" (url).

NOTE: for those that never saw graphql and were lazy enough to read
the links (most people?) the term "fragment" and its use is the key
difference from traditional REST.

In REST you usually have one endpoint (URL) for each model, it's
pre-defined and usually done like in DB, where you avoid exposing
replica in one endpoint, so for a "story list", the endpoint that
returns the list of stories only returns the ID, then you use
*ANOTHER* endpoint to fetch each ID... resulting in N+1 URL access...
This is often unusable in real products, then people create
YET-ANOTHER endpoint to return more information, such as
"/list-with-name-and-author" which returns not only the ID, but the
most used fields like name and author of the story. IOW the queries
are pre-defined in the SERVER/provider.

With GraphQL you define your QUERIES in the user side, closer to where
they are used (ie: views). It's like the UI sent a SQL query to the
backend... of course due this constrain the whole set of capabilities
and limits are enforced to avoid exposing too much, injections, etc...
this is the GraphQL Domain-Specific-Language (DSL).

Then these queries are based on fields to be sent and received. While
one can describe fields manually:

query X {
   id,
   name,
   complexfield {
       other_bla
   }
}

It's usually done with fragments, that operates conditionally and on
one type. It's syntax is like "...FragmentName":

fragment MyComplexFields on ComplexField {
   other_bla
}

fragment MyFields on X {
   id,
   name,
   .. MyComplexFields
}

(which is equivalent to the former).

This usage allows for easier composition of queries, particularly
useful when creating automated queries, since you just concatenate the
multiple fragments you want.

Also, fragments can be applied on other types and they won't match,
thus will be ignored, thus you can write something like:

query Y {
   ... StoryFragments
   ... UserFragments
}

this would make query Y to return story fields if applied on a story,
while return user fields if used on user...

That's a TL;DR of GraphQL for those not willing to dig further into it.




-- 
Gustavo Sverzut Barbieri
--------------------------------------
Mobile: +55 (16) 99354-9890

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
enlightenment-devel mailing list
enlightenment-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/enlightenment-devel

Reply via email to