Example App - flippycard

52 views
Skip to first unread message

Mike Frawley

unread,
Oct 20, 2009, 2:38:38 PM10/20/09
to jQuery Concrete
Greetings,

I'm loving concrete, great job Hamish and thanks for releasing it!

I started last night implementing a simple memory game in a concrete
style last night. You can find the repo here:

http://github.com/ratbeard/flippycard

There is also a 'classic' implementation of it I made several years
ago in the repo as well. Its pre-jQuery and is pretty obtrusive and
janky, so maybe when I get further on the concrete version I will
update it to make it a better comparison.

I'm already learning some interesting techniques and found that it
feels like programming a state machine. It seems like it would be
possible to move all state in to the concrete selectors themselves,
then override the correct behavior for a given state. Css can style
the states as well. Not sure how well this type of development scales
up, but it sure is fun to experiment with!

I'll be posting back on what I discover in general with concrete
programming and with the concrete library specifically.

˙∆˚ Mike !

Sam Minnee

unread,
Oct 20, 2009, 5:41:20 PM10/20/09
to jQuery Concrete
Looks like a nicely sized demo app - small enough to be intelligible
to newcomers, large enough to be interesting.

If you branch the whole thing to gh-pages then github will host a
running demo of it at http://ratbeard.github.com/flippycard/concrete/

Sam Minnee

unread,
Oct 20, 2009, 5:43:55 PM10/20/09
to jQuery Concrete
> I'm already learning some interesting techniques and found that it
> feels like programming a state machine.  It seems like it would be
> possible to move all state in to the concrete selectors themselves,
> then override the correct behavior for a given state.  Css can style
> the states as well.  Not sure how well this type of development scales
> up, but it sure is fun to experiment with!

I like the use of CSS classes for representing state, because it
means:

* your presentation can change in response to state as well as your
behaviour
* server-side code could initialise objects with a state more easily
* state is a sufficiently simple piece of data to be contained
naturally within a CSS class.

Mike Frawley

unread,
Oct 21, 2009, 4:09:36 PM10/21/09
to jQuery Concrete

> I like the use of CSS classes for representing state, because it
> means:
>
>  * your presentation can change in response to state as well as your
> behaviour
> * server-side code could initialise objects with a state more easily
> * state is a sufficiently simple piece of data to be contained
> naturally within a CSS class.

Exactly! It allows you to 'hook' in styling (user feedback), just
like hooking in behavior.

I thought about using $().data to hold state, but then there's two
representations of application state - the contents of $.data, and the
UI. So $.data becomes the canonical representation while the UI
becomes a second class citizen, requiring you to bridge through the JS
engine to edit a representation, and only giving you feedback on the
state of the system based on what the original programmer thought was
necessary.

Instead I'm trying to make all application state explicit, so behavior
and UI can be hooked in as easily by myself as someone else (unlike w/
OO, which invariably is never generic enough or has enough hooks). I
think this makes it an exciting model to explore for web
applications. Presumably, the classes you use becomes your public
api, like with microdata.

> If you branch the whole thing to gh-pages then github will host a
> running demo of it at http://ratbeard.github.com/flippycard/concrete/

I will do that soon.

Thanks for the feedback :)

hamish

unread,
Oct 21, 2009, 4:22:48 PM10/21/09
to jQuery Concrete
Hi Mike,

> I started last night implementing a simple memory game in a concrete
> style last night.  You can find the repo here:
>
> http://github.com/ratbeard/flippycard

This is awesome. I've created a "Where's Concrete Used" wiki page on
github and added this to it - let me know if you don't want it there
and I'll remove it.

I notice you're using _ to mark private functions. What's your feeling
about this? The '_ is private' rule is fairly well known, but it sure
looks ugly.

I've been thinking about adding the ability to limit a function to
namespace-block internal usage only (which provides the most desirable
feature of private functions - having functions available to internal
code without polluting the exposed API) but I haven't been able to
come up with a nice syntax.

Hamish Friedlander

Michael Frawley

unread,
Oct 22, 2009, 2:48:34 PM10/22/09
to jquery-...@googlegroups.com

This is awesome. I've created a "Where's Concrete Used" wiki page on
github and added this to it - let me know if you don't want it there
and I'll remove it.


Glad you liked it - feel free to link to it.

I notice you're using _ to mark private functions. What's your feeling
about this? The '_ is private' rule is fairly well known, but it sure
looks ugly.


Agreed, `_` is ugly.  I usually do private stuff in nested functions, though this is more for code readability than information hiding.  For private functions that I want to use in several public functions, I probably would just prepend '_'  rather than wrap the whole declaration in a closure with private functions. 

I've been thinking about adding the ability to limit a function to
namespace-block internal usage only (which provides the most desirable
feature of private functions - having functions available to internal
code without polluting the exposed API) but I haven't been able to
come up with a nice syntax.


Is that a syntax for declaring them or calling them?  
 

hamish

unread,
Oct 23, 2009, 11:08:15 PM10/23/09
to jQuery Concrete
> > I've been thinking about adding the ability to limit a function to
> > namespace-block internal usage only (which provides the most desirable
> > feature of private functions - having functions available to internal
> > code without polluting the exposed API) but I haven't been able to
> > come up with a nice syntax.
>
> Is that a syntax for declaring them or calling them?

Declaring them. I've been think of something like:

https://gist.github.com/217337/ca96ee292758564a31d27a0defde68a321400d14

Private isn't really the right word, because it's not fully private -
you could still access it by doing

$.concrete('namespace', function($){ $(this).foo(); })

and you could still override it in subclasses. It's more like internal
function verses exposed api function. So maybe internal is better than
private:

http://gist.github.com/217337/567de648e34f637589667b9d1652d1d43b4f0121

Hamish Friedlander

Sam Minnée

unread,
Oct 24, 2009, 5:46:51 PM10/24/09
to jquery-...@googlegroups.com
> Declaring them. I've been think of something like:
>
> https://gist.github.com/217337/
> ca96ee292758564a31d27a0defde68a321400d14

I'm a little concerned about the amount of scaffold that you start
getting in a Concrete app with this addition. IMO, underscores are
less ugly. ;-)

One slightly more philosophical question is relevant here: are you
trying to nail down a new syntax that people should follow - a
Concrete DSL - or are you trying to provide a toolkit for people to
mix and match as they see fit - a Concrete API?

If you're going for an API, then $.concrete.internal makes sense,
because you could potentially mix and match these $.concrete.internal
closures/lambas in other ways.

However, I suspect that you're actually going for DSL, mostly because
the internals of Concrete appear to be designed to be
indistinguishable from magic to most of the people that use it. ;-)
In that case, it would seem best to optimise the API design towards
allowing for a nice easy to read syntax that Concrete users can write
their code in.

I don't really know what that would be, but one option is this:

$.concrete('namespace', function($){
$('.selector').concrete({
'foo.private': function(){
},
bar: function(){
this.foo(); // Allowed
}
})
});

From a DSL perspective, it seems better than "$.concrete.private()".

You could even hijack the underscores and automatically attach as
private any method that starts with an underscore. It's the closest
thing to a convention that JavaScript has in this area - why not adopt
it?

> Private isn't really the right word, because it's not fully private -
> you could still access it by doing
>
> $.concrete('namespace', function($){ $(this).foo(); })


Maybe "protected", then? Since protected methods can be broken into
in a similar way. Here's a little PHP simile:

class MyClass extends ClassWithProtectedMethod {
public function publicMethod() {
return $this->protectedMethod();
}
}

> and you could still override it in subclasses. It's more like internal
> function verses exposed api function. So maybe internal is better than
> private:
>
> http://gist.github.com/217337/567de648e34f637589667b9d1652d1d43b4f0121

The advantage of "protected" rather than "internal" is that people
have heard it 100 times before.

Michael Frawley

unread,
Oct 25, 2009, 3:20:29 PM10/25/09
to jquery-...@googlegroups.com
One slightly more philosophical question is relevant here: are you trying to nail down a new syntax that people should follow - a Concrete DSL - or are you trying to provide a toolkit for people to mix and match as they see fit - a Concrete API?

If you're going for an API, then $.concrete.internal makes sense, because you could potentially mix and match these $.concrete.internal closures/lambas in other ways.

However, I suspect that you're actually going for DSL, mostly because the internals of Concrete appear to be designed to be indistinguishable from magic to most of the people that use it. ;-)  In that case, it would seem best to optimise the API design towards allowing for a nice easy to read syntax that Concrete users can write their code in.


Concrete API vs DSL is a good point.  The best approach would be to make a lower level, magic-free API, and provide a DSL and some magic conversions on top that will satisfy most users.  Having many hooks in the core code is a good thing as people can experiment with different DSL's and degrees of magic, and maybe pull some cool ones that help a lot back in to the 'official' concrete dsl.  As Sam says, having that API will provide a lot of reuse.


I don't really know what that would be, but one option is this:

$.concrete('namespace', function($){
 $('.selector').concrete({
   'foo.private': function(){
   },
   bar: function(){
     this.foo(); // Allowed
   }
 })
});

From a DSL perspective, it seems better than "$.concrete.private()".

You could even hijack the underscores and automatically attach as private any method that starts with an underscore.  It's the closest thing to a convention that JavaScript has in this area - why not adopt it?


When this discussion came up my first thought was to auto-convert leading underscored methods to private, since its such a common convention and fits in with the auto getters/setters and on* handlers conversion already done.  There is no reason you would ^_ a non private method. 

I think  _ beats 'foo.private', but the second option allows for generalized method annotations.  I can think of '.init' and a few other possible annotations that _might_ be useful, but I'd much prefer a few static rules like like init.  However, annotation based on AOP or events could be interesting:

  edit: function () …

  'validate| :after(edit)': function …

  'recalc| :on(change)': function …


Another option for annotation is calling toString on the function and read in any metadata in comments on the first line.  I'm using a trick like this on a project:

score: function () { // +private

},


There's lots of ways to take it.  Long term, I think the best approach would be to have a hookable 'object creation' library that handles the infrastructure of taking in an object, applying some specified hooks, and spitting out the final object.  Rules could look like:

{
  'fn.name.startsWith("_"))': function (obj, matched) {  $.concrete.internal(matched.fn) }
}

This could be separate, but used by the core $.concrete library, and would be useful for me in a lot of projects :)  I'd love to get javascript closer to being declarative and easier to meta-program like my ruby.


The advantage of "protected" rather than "internal" is that people have heard it 100 times before.

That would be advantages if it carried the same semantics as protected, however since it doesn't  I think it would be a disadvantage.  Concrete's system is different enough in general from OO, that we should be careful about reusing the same terms.  I think 'internal' is clear, and is actually a modifier In dotnet, mthods marked with it are callable by any object in the same namespace, matching our semantics here.  This should make the transition for those C# programmers to concrete style javascript much easier ;)

Mike

Mike Frawley

unread,
Oct 25, 2009, 3:44:21 PM10/25/09
to jQuery Concrete
Instead of finishing my game up, I was playing around with an idea of
declaritive binding. Although jquery makes it easy to listen to
events and update something else, why not declare it and have concrete
do the work? Examples:

Update turn count text when `ol.turns li`.length changes:

$('.turn-count').sync('text').to('ol.turns li').length();


Update text when keyup on input box detected (default event is change,
but overrode it to keyup):

$('.greeting .name').sync('text').to('#players_name').val().on
('keyup');


http://github.com/ratbeard/flippycard/blob/master/concrete/flippy.js#L162

the table has fn's to get and set values, and determine which event to
listen to

MutantWatcher.prototype is a DSL to declare the binding and uses the
table for actions and concrete to actually do the listening.

Pretty neat :)

hamish

unread,
Oct 27, 2009, 4:55:01 PM10/27/09
to jQuery Concrete

I definitely see it as a DSL. There is an internal API that can be
used to add DSL components, but I don't want to guarantee it's
stability, so it's mostly a 'look at the source' thing. Additionally,
I'm a little worried everyone would come up with their own little DSL
bits, and concrete would fragment into a hundred incompatible
versions.

When adding new features to the DSL we have a few options

- Mark the key somehow (_foo, 'foo.internal', 'internal:foo')
- Mark the value somehow ($.concrete.private(function(){}))
- Add something outside the concrete definition block

Marking the keys: The event part of concrete hooks in when the key
starts with 'on'. You have to be careful that all the rules are clear,
and none of them clash. Otherwise it starts getting too magic

Example (Ok, a little ugly, the .internal bit looks like a selector
which is confusing, a bunch of internal functions together would look
bad):

$('.selector').concrete({
'foo.internal': function(){}
bar: function(){}
})

Another example (Why is internal special? What if you wanted to
introduce more internal functions later in the block?)

$('.selector').concrete({
internal: {
foo: function(){}
}
bar: function(){}
})

Marking the value: The property part of concrete hooks in when the
value is anything except a function. Marking the value reads worse,
but has less chance of clash

Example (Kind of ugly. We could make the 'internal' function global,
but give a hoot, don't pollute):

$('.selector').concrete({
'foo': $.concrete.internal( function(){} )
bar: function(){}
})

Adding something outside the concrete definition block: Has the least
change of clash, but the separation of related functions into
different blocks makes reading worst

Example (Internal functions separate from external functions mean it's
hard to track what functions belong to what selector in larger files)

$('.selector').concrete.internal({
foo: function(){}
})

$('.selector').concrete({
bar: function(){}
})

Consistency is an important thing. While watching others internally
learning to use concrete, it was obvious that having too many special
cases or magic meant people just got frustrated. Good documentation
helps here, but having simple always-true rules without special cases
or exceptions helps too.

Since none of these are obviously best, and there's no real call for
internal support ( _ works fine) I've avoided making a decision thus
far.

Hamish Friedlander



Reply all
Reply to author
Forward
0 new messages