kaboom icon indicating copy to clipboard operation
kaboom copied to clipboard

[RFC] Allow passing components directly as arguments, and support composition

Open masad-frost opened this issue 4 years ago • 7 comments

There's two folds for this RFC. Firstly, I think it would be good for beginners to not have to think about passing arrays to add. It should accept add(body(), pos(), area()). Secondly, as a side-effect of trying to be backwards incompatible, you can now compose components and use them in objects without having to learn array spread syntax. To fully support this form of composition, we can allow infinitely nested arrays.

Before

const playerComponents = [
       sprite('player'),
       body(),
       area(),
       pos(),
       "player",
];

const evilPlayerComponents = [
  ...playerComponents, // or spreading later when calling add([...playerComponents, ...evilPlayerComponents])
  color(0, 0, 0),
  origin("left"),
];

add(evilPlayerComponents);

After

const playerComponents = [
       sprite('player'),
       body(),
       area(),
       pos(),
       "player",
];

const evilPlayerComponents = [
  playerComponents, // or later when calling add(playerComponents, evilPlayerComponents)
  color(0, 0, 0),
  origin("left"),
];

add(evilPlayerComponents);

You can do add([[[[[body()]]]], pos()]) or any form of nesting, it should still work!

The RFC is fully implemented and typescript supports it.

masad-frost avatar Sep 21 '21 22:09 masad-frost

I like this. Do you think we should generally advocate array-less add()? One thing is in addLevel() it uses array to define what each symbol means and calls add() later, wonder if we advocate array-less add() by default will it create more confusion when they're using addLevel()

slmjkdbtl avatar Sep 21 '21 22:09 slmjkdbtl

Yeah I saw that. Not sure to be honest. I can see people doing '=': () => (sprit("poop"), solid()) which doesn't work.

My first thought for this was to have compose or join function and ditch arrays altogether i.e. '=': () => compose(sprit("poop"), solid()). But not sure how beginners would respond to it. It'd be good to do some user research here.

masad-frost avatar Sep 21 '21 23:09 masad-frost

Another concern is if we should reserve the nested comps syntax. Kaboom (kinda) plans to moves to a node-tree structure from flat list where characters can have children who inherits transform attributes (position, scale, rotation), it'll be nice to use arrays to express this:

// the parent
add([
    sprite("hero"),
    pos(100, 100),
    area(),
    // a child
    [
        sprite("sword"),
        pos(-10, 0),
    ],
    // another child
    [
        sprite("pet"),
        float(),
    ],
]);

but not sure yet.

(btw "solid poop" is a 👍 )

slmjkdbtl avatar Sep 21 '21 23:09 slmjkdbtl

:hankey:

Interesting, haven't thought about that, would position be origined on the parent? I think mixing composition and inheritance API can be a trap and confusing. Feels like an API similar to follow makes more sense to me. Alternatively, nested add calls, like so


add([
    sprite("hero"),
    pos(100, 100),
    area(),
    // a child
    add([
        sprite("sword"),
        pos(-10, 0),
    ]),
    // another child
    add([
        sprite("pet"),
        float(),
    ]),
]);

We can have an opaque Symbol on Characters to identify nested children added via add

masad-frost avatar Sep 22 '21 00:09 masad-frost

Also thinking about

hero = add([
    sprite("hero"),
    pos(100, 100),
    area(),
    parent(), // gives addChild capabilities
]);

hero.addChild([ // same API as `add`
    sprite("sword"),
    pos(-10, 0),
]);

This gets rid of nesting altogether, which feels like it'll make the mental model easier.

masad-frost avatar Sep 22 '21 00:09 masad-frost

Yep, or maybe

const sword = add(...);
const pet = add(...);

add([
    sprite("hero",
    children(sword, pet), 
]);

I'll merge this to allow the syntax, but will think more if we want to start advocating this syntax over the existing one 🤔 .

slmjkdbtl avatar Sep 22 '21 01:09 slmjkdbtl

also i think the blockly version of kaboom (which targets more beginners) will be hiding the array syntax for add() anyway

slmjkdbtl avatar Sep 22 '21 02:09 slmjkdbtl