Observable Properties

250 views
Skip to first unread message

Azer Koçulu

unread,
Oct 29, 2012, 8:11:08 PM10/29/12
to nod...@googlegroups.com

Hi All,

I've created a new JS library for defining properties that can be subscribed for updates and can interact with eachother.

Check it here;

https://github.com/azer/ak47

Readme contains many examples. Here is another one:

var user = ak47({ name: 'joe', 'birthdate': 21 });

> user.name()
"joe"
> user.name.subscribe(console.log);
> user.name("mike")
"mike"
"mike" "joe"

Defining a new property that observes another(s):

> var greeting = ak47(joe.name, function(name){
return 'Hello ' + name;
});
> greeting()
"Hello mike"
> joe.name("joe")
> greeting()
"Hello joe"

What do you think?

Azer

Rick Waldron

unread,
Oct 29, 2012, 8:42:23 PM10/29/12
to nod...@googlegroups.com
Related... v8 just landed support for Object.observe()

-Rick

--
Job Board: http://jobs.nodejs.org/
Posting guidelines: https://github.com/joyent/node/wiki/Mailing-List-Posting-Guidelines
You received this message because you are subscribed to the Google
Groups "nodejs" group.
To post to this group, send email to nod...@googlegroups.com
To unsubscribe from this group, send email to
nodejs+un...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/nodejs?hl=en?hl=en

Jake Verbaten

unread,
Oct 29, 2012, 10:43:03 PM10/29/12
to nod...@googlegroups.com
Is that the original non-optimized prototype or more optimized iteration of it?

Vyacheslav Egorov

unread,
Oct 30, 2012, 12:19:52 PM10/30/12
to nod...@googlegroups.com
Implementation is still in progress. CLs that were landed introduce
the skeleton of the system but there are no notifications coming in
from the runtime yet.

I don't know what the actual plan is but I would expect that
implementation would degrade only performance of the observed objects
not the system as whole like prototype did (similar to Object.freeze).

--
Vyacheslav Egorov

Rick Waldron

unread,
Oct 30, 2012, 12:47:32 PM10/30/12
to nod...@googlegroups.com
On Tue, Oct 30, 2012 at 12:19 PM, Vyacheslav Egorov <veg...@chromium.org> wrote:
Implementation is still in progress. CLs that were landed introduce
the skeleton of the system but there are no notifications coming in
from the runtime yet.

I don't know what the actual plan is but I would expect that
implementation would degrade only performance of the observed objects
not the system as whole like prototype did (similar to Object.freeze).

--
Vyacheslav Egorov

Thanks for filling in the blanks—I accidentally deleted Jake's response, so never saw until now

Rick

Azer Koçulu

unread,
Oct 30, 2012, 1:37:28 PM10/30/12
to nod...@googlegroups.com
It was non-optimized. After reading your response, I spent couple of
hours on optimizing it. Here are the numbers:

Before optimization:

ak47-accessors: 7495ms
ak47-sub: 6963ms
ak47-subAll: 7785ms
ak47-pubsub: 6780ms

After optimization (v0.0.5)

ak47-accessors: 851ms
ak47-sub: 873ms
ak47-subAll: 1277ms
ak47-pubsub: 1868ms

And here how I measure it:
https://github.com/azer/ak47/blob/master/benchmarks/index.js

Azer Koçulu

unread,
Oct 30, 2012, 2:00:03 PM10/30/12
to nod...@googlegroups.com
By the way, I would prefer using Ak47 over Object.observe for some
cases (if there isn't a significant performance issue). ak47 is not
only for object properties, it's also for observing variables;

> var birthdate = ak47(new Date("1.1.1990")),
age = ak47(birthdate, today, function(bd, td){
return parseInt( (td - bd) / 31536000000 );
});

> age()
22

It ensures all data structures are observable. And it's fairly simpler
than JavaScript's new accessor and observation APIs.

Here is a use case, assume we have a module like below:

// a.js

var foo = "hello",
bar = hello + " world";

module.exports = {
foo: foo,
bar: bar
};

// b.js
var a = require('./a');

a.foo = "What's up?"

console.log(a.foo); // what's up?
console.log(a.bar); // hello world

When we ignore using classes (or another way to create properties) in
CommonJS modules, we may have two copies of what we export from a
module. One is internal, the other one is external when a client
module overrides the property.

To solve this issue, I was creating properties like below:

var foo = (function(){

var value = undefined;

return function foo(newValue){
if(arguments.length){
value = newValue;
}

return value;
};

}());

And after using this pattern for long time, I came up to the the idea of ak47.

On Mon, Oct 29, 2012 at 5:42 PM, Rick Waldron <waldro...@gmail.com> wrote:

Rick Waldron

unread,
Oct 30, 2012, 2:04:49 PM10/30/12
to nod...@googlegroups.com
On Tue, Oct 30, 2012 at 1:37 PM, Azer Koçulu <az...@kodfabrik.com> wrote:
It was non-optimized. After reading your response, I spent couple of
hours on optimizing it. Here are the numbers:

Just a heads up... The "thing" you're calling "accessors" are not actually accessors.


Rick

Azer Koçulu

unread,
Oct 30, 2012, 2:21:20 PM10/30/12
to nod...@googlegroups.com
You mean that benchmark doesn't contain any accessor or ak47 misses accessors?

Here is how I define a property with getters and setters using ak47:

function getter(d){ return Number(d); }
function setter(d){ return new Date(d); }

var date = a.property(new Date('1.1.1990'), getter, setter);

And that benchmark case uses default accessors unlike the example above.

Rick Waldron

unread,
Oct 30, 2012, 2:36:17 PM10/30/12
to nod...@googlegroups.com
On Tue, Oct 30, 2012 at 2:21 PM, Azer Koçulu <az...@kodfabrik.com> wrote:
You mean that benchmark doesn't contain any accessor or ak47 misses accessors?

Here is how I define a property with getters and setters using ak47:

function getter(d){ return Number(d); }
function setter(d){ return new Date(d); }

var date = a.property(new Date('1.1.1990'), getter, setter);

And that benchmark case uses default accessors unlike the example above.

A little misleading, because what you're illustrating is actually just "a function". JavaScript accessors are created by defining get/set property descriptors or named get/set accessors.

Rick

Azer Koçulu

unread,
Oct 30, 2012, 2:40:00 PM10/30/12
to nod...@googlegroups.com
On Tue, Oct 30, 2012 at 11:36 AM, Rick Waldron <waldro...@gmail.com> wrote:
>
> A little misleading, because what you're illustrating is actually just "a
> function". JavaScript accessors are created by defining get/set property
> descriptors or named get/set accessors.

That's why ak47 exists! It introduces a new way of defining
properties. I don't think prefixing accessors as get/set is essential
to fill the definition of "accessor" in a dynamic language.

Rick Waldron

unread,
Oct 30, 2012, 3:12:59 PM10/30/12
to nod...@googlegroups.com
On Tue, Oct 30, 2012 at 2:40 PM, Azer Koçulu <az...@kodfabrik.com> wrote:
On Tue, Oct 30, 2012 at 11:36 AM, Rick Waldron <waldro...@gmail.com> wrote:
>
> A little misleading, because what you're illustrating is actually just "a
> function". JavaScript accessors are created by defining get/set property
> descriptors or named get/set accessors.

That's why ak47 exists! It introduces a new way of defining
properties. I don't think prefixing accessors as get/set is essential
to fill the definition of "accessor" in a dynamic language.

I never said anything about prefixing... Prefixing is also not really an "accessor".


Rick

Azer Koçulu

unread,
Oct 30, 2012, 3:38:08 PM10/30/12
to nod...@googlegroups.com
Thanks for the example. As I mentioned before, I prefer not using
JavaScript's getter and setter API. And by saying prefixing, I meant
creating two different functions to access a private variable like
getFoo and setFoo.
Reply all
Reply to author
Forward
0 new messages