Re: [CommonJS] Re: futures library

3 views
Skip to first unread message

AJ ONeal

unread,
Jul 28, 2010, 12:23:44 PM7/28/10
to comm...@googlegroups.com, futures-j...@googlegroups.com
I finally looked through the CommonJS proposals this morning. 

I plan to write my own proposal and toss it up for discussion in relation to FuturesJS, but here are my ideas as of right now.


Pre-emptive strikes / defense:
  • Assignment of literal objects (meaning data, values) is evil. 
    It leads to scope-creep and promotes disorganization. 
    If you're pulling data out of your object, you defeat layering. 

    My rules of thumb:
    • Parameters (arguments specifying "how") should be passed to functions, but not data.
    • Functions should be passed in rather than data being pulled out.
  • Literal strings are evil.
    In any scope of the program you can access "stringName", but you can only access .methodName() and .propertyName in the correct scope.
    Hence strings are inherently global.
    They make code more confusing because they take away the context. Such magic strings are the method/property equivalent of magic numbers.

    My rules of thumb:
    • methods and properties should be accessed only in their scope, not via accessors that accept strings.
    • If a string doesn't represent literal data or a parameter - from a database, from a user, a helpful user-facing error message - it shouldn't be a string
  • Asynchronous / Event-driven programming is better than good, it's great!
    Focus is placed on "what should happen if" rather than "when what should happen"
    Leads to cleaner, modularized design
    Is incompatible with assignment (excepting the case of continuations, but I don't like those)

    My rule of thumb:
    • Don't abstract away asynchronous programming, embrace it!
  • Optional arguments increase complexity. (a mistake a plan to correct in my API when I clean it up)
    consider func(callback, errback_opt, progress_opt, params_opt)
    What if I want to specify errback and params but not progress? or just progress?

    My rules of thumb:
    • Provide distinct functions for the best-defined use cases.
    • Always allow a params_opt as last argument which can be extended with the fluffy stuff.
    • Allow `null` (or `false`/`undefined` maybe)??? to require that an argument exists, but not require it to 

  • Most abbreviations are evil
    confusing, unintuitive, just saves a few keystrokes at the expense of readability

    My rules of thumb:
    • Sometimes shortcuts like rm, cp, mv, are nice, so provide both the intuitive remove(), copy(), move(), etc
      (or just provide the intuitive ones)

I would like to call to the stand two witnesses

The lazy programmers guide to secure computing: http://youtube.com/watch?v=eL5o4PFuxTY


Proposal A: Very straight forward, not very complete
  • "progressHandler" callback.
    • I like this, I plan to implement it.
  • var other_promise = p.get(str_name_of_property_on_result_object)
    • I don't really like this because of the whole using strings thing.
    • I would implement it as other_promise = p.nameOfProperty(), but I don't see much of a use-case for it

  • .then()
    • "then" in english implies a sequence of events and I use .then() for sequencing in Futures.
    • most libraries examples use .when(), I plan to continue with the defacto standard

  • always put callbacks on the queue vs immediate execution if immediately available
    • I say provide an option and allow the user to choose. 
      var p = Promise(callback, { allowSyncback: true });



Proposal B: More full-featured, but somewhat obfuscates the purpose of asynchronous programming
  • asap() - solves bullet point 4 above, but there are issues with optional arguments
    • asapWhen(), asapFail(), asapProgress()... maybe a bit much

  • funcName(object, args)
    very python way of passing the object to it's methods rather than having the methods be part of the object
    Personally, I don't like this style. I don't feel that JavaScript inherently caters to that style.

  • ref(object) - This is similar to Futures.asyncify() with Futures.promise(immediate). I like the idea.
    It needs an intuitive name. 
    I suggest .promisify(). My promisify() handles functions, but I will add the ability to handle promise objects and ready objects.

  • when() - this is used by other libraries I've encountered to mean what this proposal calls enqueue.

  • get(), post(), del(), put() - neat idea to have shortcuts for CRUD methods, but I don't like the idea of using strings nor micromanaging my data. And what if the object is a literal number? or string? or an array?

  • reject() - perhaps a more intuitive name than smash(). I'd be fine with using this.

Immediate thoughts on a proposal C:
  • Let the promise object be its own object and handle itself.
  • Let promises be duck-type detectable - if it has .when(), it's a promise.
  • Specify joins.
  • Allow arbitrary extension by using an optional params as the last argument to any function
    • params change the internal operation, but not the external outcomes
    • i.e. the difference between B's when() and asap() could be handled by a parameter
    • specifying or omitting these params will not break compatibility between implementations

I still have some work to do on FuturesJS and defining use cases before I submit my proposal, but my proposal will adhere to my rules of thumbs (with perhaps some exceptions)

The goal of FuturesJS is to *embrace* asynchronous and event-driven programming, not to "deal with it" or hide it.


All of that said, school me. Teach me where I'm being short sighted. I'm always open to understanding a better solution.

AJ ONeal

On Wed, Jul 21, 2010 at 9:20 AM, Nathan Stott <nrs...@gmail.com> wrote:
Hey it's great to hear that you want to get involved in the CommonJS standardization.  Welcome aboard.

Perhaps you could review http://wiki.commonjs.org/wiki/Promises/A and http://wiki.commonjs.org/wiki/Promises/B as a means of starting discussion.  Point out what you think should change and why.

On Wed, Jul 21, 2010 at 10:03 AM, CoolAJ86 <cool...@gmail.com> wrote:
On Jul 19, 2:51 pm, Nathan Stott <nrst...@gmail.com> wrote:
> Hey guys, what's your opinion on this library?http://github.com/coolaj86/futures/

I love it - but, hey, I'm building it.

> This came up on the node.js list earlier.  We really need a standard promise
> library, but this one seems to deviate from commonjs.  Do we have some
> equivalent that we could advertise as an implementation of the promise specs
> from CommonJS?

I'd prefer to conform rather than be shunned and shanked for not being
as cool as the other kids in the sandbox.
I hadn't heard of CommonJS until a few days ago (behind the times, I
know - forgive me).

From the proposals it doesn't apear that there's an actual standard
quite yet.
Let's chat, what can we do to get this converging rather than
deviating?

AJ ONeal

Tauren Mills

unread,
Jul 28, 2010, 3:56:12 PM7/28/10
to futures-j...@googlegroups.com
AJ,

It will take me some time to process all of this. As I haven't looked over proposals A and B yet, I don't yet have an opinion of them. But overall, your points seem strong and well thought out.

There is one point I would like to make about using strings as property accessors. In the past, I've also frowned on doing this. However, I'm finding that there are real use cases where doing it makes sense. I just created a post on my blog discussing these scenarios:

I realize much of what I went into there doesn't pertain to futures and promises, but the point I'm making is that sometimes using string-based property accessors is a good solution and you shouldn't discount it completely. 

However, if these proposals are simply using strings to access methods in a manner similar to jquery-ui, then I agree with you. I've never been thrilled with the way jquery-ui does this:

$(".tabs").tabs("remove",3);

Instead of this or something similar:

$(".tabs").tabs().remove(3);

I understand they are doing this to maintain the ability to chain, but I still don't like it.

Tauren

   

--
Please use prefixes: [Pony] Feature requests, [TestCase] Test cases, [Bug] if you're lazy. If you have contract work or position for FuturesJS devs, prefix [Bounty] or [Job].
-----
To post to this group, send email to futures-j...@googlegroups.com
To unsubscribe from this group, send email to
futures-javascr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/futures-javascript?hl=en

Tauren Mills

unread,
Jul 30, 2010, 4:27:54 PM7/30/10
to FuturesJS
AJ,

Now that you've had a chance to explore the different CommonJS
proposals, I was wondering if you had any thoughts on Twitter
@Anywhere, Dojo Deferreds, or the MSDN library implementation:

Twitter @Anywhere API
http://www.dustindiaz.com/async-method-queues/
http://platform.twitter.com/js-api.html

Dojo Deferreds
http://www.sitepen.com/blog/2010/05/03/robust-promises-with-dojo-deferred-1-5/
http://www.sitepen.com/blog/2010/01/19/commonjsjsgi-the-emerging-javascript-application-server-platform/
http://docs.dojocampus.org/dojo/Deferred

MSDN Library
http://blogs.msdn.com/b/rbuckton/archive/2010/01/29/promises-and-futures-in-javascript.aspx

I'm not looking for an elaborate analysis, just your general feelings
or thoughts on them. At the moment, I'm pretty happy with FuturesJS so
far, but there's always room for improvement and ideas borrowed from
other solutions.

Thanks!
Tauren

AJ ONeal

unread,
Jul 30, 2010, 4:39:46 PM7/30/10
to futures-j...@googlegroups.com
I've looked at that first blog and I plan to implement async method queues on top of sequence. I would have had that done already if this week hadn't been so busy. You can keep your fingers crossed for it tomorrow though.

I've already taken some pointers from the MSDN blog. I think that's where I first got the idea for join.
Do you understand the difference between their when() and whenOnly()? I didn't grasp that part.

I don't like the getValue(name), setValue(name, value)... maybe it will grow on me, but I don't see why it's more useful that simply providing a callback -- unless you're doing data-binding, but I'm not convinced that data-binding is a good solution. I like the idea of macro-managing. Take a chunk of data that is "small enough" rather than every single attribute.

Dojo deferred's I'm not familiar with, thanks for the link.

One of the CommonJS guys got back to me and I'm going to take a look at some of the stuff he sent me this weekend as well.

For 1.0 I'll probably keep things as I've set them forth. But for 1.5 I may switch over to the node.js style (or add convenience methods which look like theirs and wrap my existing methods with them).


AJ ONeal
(317) 426-6525


Tauren Mills

unread,
Jul 31, 2010, 4:07:44 AM7/31/10
to futures-j...@googlegroups.com
I've looked at that first blog and I plan to implement async method queues on top of sequence. I would have had that done already if this week hadn't been so busy. You can keep your fingers crossed for it tomorrow though.

Sounds cool! But don't  rush on my behalf... 
 
I've already taken some pointers from the MSDN blog. I think that's where I first got the idea for join.
Do you understand the difference between their when() and whenOnly()? I didn't grasp that part.

They certainly don't explain that very well. In my quick examination of the source, the comments mention this about whenOnly():

Sets a final action to be taken when the supplied promise has been fulfilled or broken

And this about when():

Returns a new promise who's value is based on how the supplied promise was fulfilled or broken

Of course, that doesn't help me grok it too much more.
 
I don't like the getValue(name), setValue(name, value)... maybe it will grow on me, but I don't see why it's more useful that simply providing a callback -- unless you're doing data-binding, but I'm not convinced that data-binding is a good solution. I like the idea of macro-managing. Take a chunk of data that is "small enough" rather than every single attribute.

I don't understand the internals of it enough yet to have an opinion. There is no example of when this would be used, it is just part of the API. So I'm not quite sure of their intent.

When you say "data-binding", what exactly do you mean? Our definition of this might be different. Are you referring to binding a text field value to an in-memory JS object value, or something else? I guess I'm not following your comment about macro-managing and "small enough".

My thoughts on data-binding are more elaborate. I want to have a component that manages a section of the DOM. It doesn't have to be a form element, it could be an entire table of data. That component has a backing data model. When the model changes, I want any component that references that model to be automatically updated. My goal is to simply modify the in-memory data structure, and the UI will automatically re-render the appropriate places in the DOM.

So for instance, if I update my name and profile photo, any place they are displayed on the page (possibly multiple places) would be automatically updated. I would just change values in the data model and these updates would happen. I don't want to have my update logic to have to know all the places these values are shown, just how to change the data model.
 
Dojo deferred's I'm not familiar with, thanks for the link.

One of the CommonJS guys got back to me and I'm going to take a look at some of the stuff he sent me this weekend as well.

I read his message and got nothing from it. He speaks of things I know nothing about. For instance,  E and Q? Obviously I've got some more learning to do... Hopefully you followed him better than I.
 
For 1.0 I'll probably keep things as I've set them forth. But for 1.5 I may switch over to the node.js style (or add convenience methods which look like theirs and wrap my existing methods with them).
 
Sounds good to me.

Tauren


Reply all
Reply to author
Forward
0 new messages