Giter VIP home page Giter VIP logo

flowerflip's People

Contributors

bergie avatar cbchouinard avatar d4tocchini avatar greenkeeperio-bot avatar jemgold avatar jonnor avatar paulyoung avatar royalts avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

flowerflip's Issues

Cannot subtree without external onSubtree

When trying to create a promise chain within a branch like this:

it 'should resolve', (done) ->
      multiply = (multiplier, c, data) ->
        tree = c.tree 'a'
        tree.deliver data
        tree.then "#{multiplier}", (c, d) ->
          c.branch 'doubled', (b, data) ->
            data * 2
          c.branch 'tripled', (b, data) ->
            btree = b.continue
            btree.deliver data
            btree.then 'btree-then', (c, d) ->
              d * 3
      t = Root()
      t.deliver 5
      .contest "contest-multiply", [
        multiply.bind @, 2
        multiply.bind @, 3
      ], (c, results) ->
        results[1]
      .finally 'end',   (c, res) ->
        chai.expect(res).to.eql [15]
        done()

I get the error : Cannot subtree without external onSubtree

Contest resolve callback

Can you give me a use case for the resolve callback of Thenable.contest()? Since resolve is called after score, I'm not sure when I wouldn't want to accept a solution that I choose during scoring (unless default scoring is used).

Choice name duplicated in path

In the following spec the name of the .all promise name is duplicated in the path:

it 'should generate good path', (done) ->
      treeComposition = (c, d) ->
        sub = c.continue 'subtree_c'
        sub.deliver d
        sub.then 'subthen0', (c, d) ->
          d
        .then 'subthen1', (c, d) ->
          d
      t = Root()
      t.deliver 10
      .then 'then0', (c, d) ->
        d
      .all 'allin', [
        treeComposition.bind @
        treeComposition.bind @
      ]
      .then 'then1', (c, d) ->
        d
      .finally (c, d) ->
        exp = {
          path: [
             'then0',
             'allin',
             'subtree_c',
             'subthen0',
             'subthen1',
             'then1']
          children: []
        }
        chai.expect(c.toSong()).to.eql exp
        done()

Eating items in .all

No eating of items should be done in .all() promise method since they all run in parallel we could easily get in the situation where we eat the same item twice.

Similar to #26. I think we should make this error out too.

optionalContent

For example, if the author component ate an author from the array of authors, you can run that same component multiple times until all authors are eaten. This would allow components that eat one thing to be easily reused to eat n things.

new abort / kill API

wants:

  • n.killPath() kill current path, same thing as else passing down error, stops at nearest continue or tree
  • n.killTree(), kills up to nearest tree, through any continue
  • n.killContestant() kill execution up to nearest contest, same thing as making contestant lose

By far most useful would be n.killPath.

Not sure about usefulness of killing up to nearest composite, but for that another method name maybe?

Another option would be

n.kill( type )

type in ['path', 'tree', 'composite', 'contest', 'root']

Branch root choice has empty attributes.items list

When branching, I think the function Choice.toJSON, used in the branch function, should copy the items by calling the function Choice.availableItems because right now the branch root choice will have an empty list of available items.

Following spec currently fails:

it 'the available items should be copied to the root choice of the branch', (done) ->
      multiply = (multiplier, c, data) ->
        tree = c.tree 'a'
        tree.deliver data
        tree.then "#{multiplier}", (c, d) ->
          c.branch 'tripled', (b, data) ->
            data is b.attributes.items.length
      t = Root()
      t.deliver
        config:
          name: 'test'
          type: 'test'
        items: [
          'item1'
          'item2'
          ]
      .then (c, d) ->
        c.source.attributes.items.length
      .contest "contest-multiply", [
        multiply.bind @, 2
      ], (c, results) ->
        results[0]
      .finally 'enfin-fini', (c, res) ->
        chai.expect(res[0]).to.be.true
        done()

How does branching works?

Answer from @bergie:
When you call choice.branch, the original choice is aborted and a new choice is created alongside it. Here is how it looks when a choice was branched twice (branches named left and right). After this the tree execution continues independently in both branches, meaning that this tree would produce two complete executions (leaf choices).

Contest nodes treat each branch as another possible task in the promises array, meaning that out of a single promise task you may get multiple choices to score and choose from.

localElseCallabck

.then( callback, localElseCallabck )

a local catch callback, similar to those used in that html5rocks article

.then 'step1', (n,d)->
    throw "hello"
  ,  (n,d) ->
    d is "hello"
    "goodbye"
.else (n,d) ->
  # doesnt catch step1's throw!
.then 'step2' (n,d) ->
  d is "goodbye"

.finally called twice when .maybe rejects all promise followed by else

 it 'should resolve', (done) ->
      multiply = (multiplier, orig, data) ->
        tree = orig.tree 'a'
        tree.deliver data
        tree.then (c, d) ->
          c.abort "I would've returned #{d*multiplier}, but chose not to"
      t = Root()
      t.deliver 5
      .maybe [
        multiply.bind @, 2
        multiply.bind @, 3
      ]
      .else (c, res) ->
        chai.expect(res).to.eql 5
        res * 2
      .finally (c, res) ->
        console.log 'finally called'
        console.log res
        done()

with .else followed by .finally, .finally gets called twice. If I replace .finally by then, the later is only called once. It seems to be related to the fact that .maybe as two negative result destination. Finally is called once with res = 10 from .else and another time with res = 5 from .maybe

Tree abortion problem with sub branching

When sub-branching, if somewhere in promise chain we do a choice.abort() then the whole contest seems to "fullfills" without any winner (in fact the solver callback of the contest is not even called).

choice.id gets indexed when subbranching

When subbranching, there a index that's added to the branch name so left right becomes left_0, left_1, right_0, right_1. Since we use those branch name to match css & gss selectors is it possible to remove the index?

I push a temp fix that just adds to the path the choice.id so in the path we have both left left_0.

isSubtypeOf "textual"

I would have expected these to return true:

isSubtypeOf "textual", "headline"
isSubtypeOf "textual", "h1"

Is there a reason why they don't?


(Previously asked in the-grid/poly/issues/13)

What’s the role of Poly with FlowerFlip?

Answer from @bergie :

Poly loads the right version of a design system, and runs the page through it, and then persists the solution and publishes the page. So, Poly is the way we integrate Flowerflip-based design systems into the Grid APIs environment. Flowerflip is run through Poly's ExternalSolver.

We're still keeping the old Poly solvers also around until Taylor is complete enough to produce both D4's site and The Grid site.

Promise chain added to a branch doesn't return value

I'm not sure how this should be handle but adding a promise chain on a branch doesn't return the value from the final promise of that chain to the contest. The contest receives the value from the first branch promise itself only.

describe 'promise chain after branching', ->
    it 'should walk the promise chain of the branch', (done) ->
      multiply = (multiplier, c, data) ->
        tree = c.tree 'a'
        tree.deliver data
        tree.then "#{multiplier}", (c, d) ->
          c.branch 'doubled', (b, data) ->
            data * 2
          c.branch 'tripled', (b, data) ->
            data
          .then 'bthen0', (c, data) ->
            data
          .then 'bthen1', (c, data) ->
            data * 3
      t = Root()
      t.deliver 5
      .contest "contest-multiply", [
        multiply.bind @, 2
        multiply.bind @, 3
      ], (c, results) ->
        paths = results.map (r) -> r.path
        idx = paths.indexOf 'root-tripled-bthen0-bthen1'
        results[idx]
      .finally 'end',   (c, res) ->
        chai.expect(res).to.eql [15]
        done()

.finally and subtrees

.finally should not be called on a subtree since the subtree is part of the parent decision tree. Calling .finally on the subtree would prevent further promise to be called.

I think we should make this error out if not already.

When branching within contest, the path of the solution doesn't contain the name of the subLeaf

I think we should add the name of the subLeaf that resolved in the path of the solution. With this spec:

it 'should resolve', (done) ->
      multiply = (multiplier, c, data) ->
        tree = c.tree 'a'
        tree.deliver data
        tree.then "#{multiplier}", (c, d) ->
          c.branch 'doubled', (b, data) ->
            data * 2
          c.branch 'tripled', (b, data) ->
            data * 3
      t = Root()
      t.deliver 5
      .contest "contest-multiply", [
        multiply.bind @, 2
        multiply.bind @, 3
      ], (c, results) ->
        results[1]
      .finally 'end',   (c, res) ->
        console.log 'fini'
        console.log c
        chai.expect(res).to.eql [15]
        done()

I get the path: [ 'root', 'contest_multiply', 'end' ]

Shouldn't it be: [ 'root', 'contest_multiply', 'tripled', 'end' ]

Mutability

The data parameter of promises is the only mutable object in decision trees.

How are other objects made immutable? e.g. choice

Asset registration / Tree walking API + Choice subclassing

Totally makes sense that if we want to add a global asset registration mechanism for design systems like;

node.addAsset [
    "my-gss.gss"
    "my-css.css"
    "text-fit.js"
  ]

Then we should subclass Choice. But... because of branches... we need a way to attach things to each choice node, and at then end, walk all choices and gather the assets. @bergie can you provide example on how we could do this?

This would be immediately beneficial in Taylor. I'm already hardcoding GOM transforms, stylesheets, etc...

How do we order posts using FlowerFlips

Question:
How does information flow is taken into consideration with design system? For example, if as a user I post item A and then item B and I absolutely want item A to appear before item B. I’m not sure to see how that can work right now.

Answer from @bergie :
The ordering of items is for the Poly solver to handle. In the "unordered" scenario, the order of items doesn't matter, only the rhythms, and hence you can get() until you receive an item you can work with.

In ordered scenario you will eventually only get the first uneaten item with choice.get(), not any of the following ones. This will make sure that items are shown in the order provided.

However, you may want to mark the paths of sections that ate a starred item with "starred" so we can utilize these in the rhythm.

Should we clone the data passed in when executing a tree?

I think this could lead to weird bugs in design system:

When executing the decision tree this is called:

if typeof data is 'object' and toString.call(data) isnt '[object Array]'
      for key, val of data
        choice.set key, val

but Choice.set doesn't clone val.

The data deliver to the tree will be passed to the next promise, what if that promise changes the value of data? Didn't test it yet but from what I see this would change the values of the source choice. Worst case would be to change the Items I think :)

Debugging sanity

Not sure about the ideal debugging convention, but we do need something. Lack of visibility on where & in what parent-child level things broke is by far the biggest time sink I've experienced with Taylor.

Maybe start off with a debug mode that prints the paths and/or failed paths in a tree-like, nested manner?

By addressing issue #5, we will have much better visibility on what the root cause of failures are. Like why a subTree killed one of it's parentTrees, which is a bitch to figure out. There are still failures in Taylor that I can't quite identify the source of, and the decision tree is only going to get bigger & more nested!

Hawaii Wishlist

Eaten content of subtrees in contest

n.get API

n.get 'prop'          # looks locally for prop
n.get 'prop', true  # looks for prop up trees
n.get 'prop', 'start-root'  # looks for prop at path

array of paths in thenables

t.tree ['section','simple'], ->

.then ['foo','bar'], ->

.then([component1,component2])

Chain an array of thenables by then...

until thenable

.some & .all accepts empty array

DEBUG=tree, show tree name in path

Would be useful to see tree name in path from console output using DEBUG=tree, right now all trees are labeled root, so hard to tell which tree was run

screen shot 2015-03-02 at 2 49 20 pm

Thenable::none

This would be the opposite of Thenable::all in that it rejects if any of the items fulfill and succeeds if any item rejects.

Branching directly from a contest node don't work

This is a nice to be consider enhancement suggestion. Since branching abort the original choice (in this case the contest itself) I think it's ok for the following example to break. This syntax feels good though but I understand that we would miss the information regarding continuing the path of creating a child path. Maybe we could default it to create a child path:

it 'should resolve', (done) ->
      multiply = (multiplier, c, data) ->
        c.branch 'doubled', (b, data) ->
          data
        c.branch 'tripled', (b, data) ->
          data
      t = Root()
      t.deliver 5
      .contest "contest-multiply", [
        multiply.bind @, 2
        multiply.bind @, 3
      ], (c, results) ->
        results[1]
      .finally 'end',   (c, res) ->
        console.log 'fini'
        console.log c
        chai.expect(res).to.eql [15]
        done()

The branch is executed but I get the error: Chosen solution doesn't contain a choice node.
Furthermore, problems could arise in the contest subCallback since only the last branch is considered a task of the contest.

safe way to do then(component)

Would be helpful to run a component (aka subtree thingy) in a .then(). Right now we have to wrap it in a composite because aborts bubble up to composites, thus a subtree cannot safely exit execution unless loaded in a some, all, contest, etc. If we tackle issue #5, this should be a non-issue.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.