2008-07-30:
[0:00] <daniel__> is it possible to override HopObject methods like get() without touching helma's source? i've managed to do it by extending the source but i'd appreciate a pure js alternative.[0:02] <daniel__> by override i mean still being able to call the original get() method from within the overridden method[0:13] <phil_s> im having trouble getting helma to connect to mysql. it says Wrapped java.lang.RuntimeException: Error retrieving NodeIDs... any tips?[0:16] <daniel__> set logSQL=true in your app.properties, this will output all sql queries to a sql log file[0:17] <phil_s> thanks[0:17] <daniel__> then simply lookup the last query and it should be ovious whats wrong[0:18] <daniel__> the log file is called log/helma.appname.sql.log[0:19] <phil_s> says Function onStart not defined in global scope[0:19] <daniel__> this is the event log not the sql log[0:20] <phil_s> oh, yeah.. that one has an error about the driver[0:21] <daniel__> the sql log? what does it say?[0:21] <phil_s> i dont see an sql.log[0:21] <daniel__> you need to restart your application[0:21] <phil_s> i see helma.logSQL.event.log[0:22] <daniel__> oh! you've added the logSQL=true to your apps.properties[0:22] <phil_s> yes, in helma/app.properties[0:22] <daniel__> you need to add it to your app.properties, this one is the app specific properties file and needs to be placed in your top level coe directory[0:22] <phil_s> i dont have one[0:23] <phil_s> maybe thats a problem?[0:23] <daniel__> coe=code[0:23] <daniel__> simply create it in your top level code directory[0:24] <phil_s> i was following a tutorial here... http://helma.org/docs/tutorial/skins/[0:24] <daniel__> it is mostly intended for your own app specific settings. you can access all the settings from within your application by using the global getProperty() function[0:25] <phil_s> and i got that far[0:26] <daniel__> did you try to create the app.properties file and check if an sql log file is created?[0:28] <phil_s> i created an app.properties in helma/apps/addressbook, with logSQL = true in it[0:29] <daniel__> thats correct, now you should have a sql log file[0:29] <phil_s> in helma/log i still dont see it. only event.log[0:30] <daniel__> did you restart your application?[0:30] <phil_s> i restarted the helma server, and reloaded the page[0:31] <daniel__> what does the event log say in detail about your error?[0:32] <phil_s> Datasource not defined or unable to load driver: myDataSource.[0:32] <phil_s> and lots more[0:32] <daniel__> ah ok[0:32] <phil_s> but that looked important[0:32] <daniel__> i see the tutorial does not say anthing about database drivers[0:33] <phil_s> im using windows and i have mysql running[0:33] <daniel__> did you place your needed (mysql, ...) jdbc database driver in the lib/ext directors?[0:33] <phil_s> i use it with php a lot[0:33] <phil_s> no[0:33] <daniel__> ok thats the problem[0:33] <daniel__> download the mysql connector/j from mysql.com[0:33] <phil_s> cool thanks for the help![0:34] <daniel__> there will be a *.jar file in the archive you download, place it in lib/ext[0:34] <daniel__> if lib/ext does not exist yet, create it[0:34] <daniel__> lib is for core libraries whereas lib/ext is for any additional java libraries you want to use[0:37] <phil_s> ok got it there[0:37] <phil_s> will it just auto load anything in there?[0:38] <phil_s> cool![0:38] <daniel__> yes (-:[0:38] <phil_s> OH YEAH!!![0:38] <phil_s> this is awesome, thanks[0:45] <phil_s> so i guess main.hac is the default application entry point[0:47] <daniel__> its the default action on the object specified by the path in your browser[0:48] <daniel__> the path selects an object from helma's object tree, the last path element is the action to call on it, if you did not specify it, helma will fall back to main.hac[0:49] <phil_s> so you can nest objects in the file structure?[0:50] <daniel__> not in the file structure but per definitions in your type.properties[0:50] <daniel__> see http://helma.org/docs/guide/mapping/collections/[0:52] <phil_s> so type.properties is the data model?[0:52] <daniel__> yes[0:53] <phil_s> and main.hac is like a base controller[0:53] <daniel__> it is the default controller yes[0:54] <phil_s> and data objects like person are global to main.hac[0:55] <phil_s> it says root.get()[0:55] <phil_s> yeah, i'll docs, i still dont quite get it.. thanks for the help[0:56] <daniel__> root is the root object of the object tree[0:56] <daniel__> it is predefined and does not load anything from the database[0:57] <phil_s> in the tutorial they use it to get all the records from the person table[0:57] <daniel__> you attach leaves or children to it by specifying in in Root's type.properties[0:57] <phil_s> yeah, it says _children = collection(Person)[0:57] <phil_s> so thats adding it to the root object[0:58] <daniel__> yes[0:58] <daniel__> now you already have an object tree[0:58] <daniel__> if you want to access one of your person objects[0:59] <phil_s> looks like very well organized way to do things[0:59] <daniel__> you don't need to have root.get() in Root/main.hac[0:59] <daniel__> you can already access the person object by specifiying the correct path in your browser[0:59] <daniel__> .../id/main[1:00] <daniel__> whereas id is an id of one of your person objects[1:00] <daniel__> most important, its an extremely fast way to do things (-;[1:01] <phil_s> says object not found[1:02] <daniel__> did you write it like i wrote it? with main? you probably do not have a main.hac for Person yet[1:03] <phil_s> no, just the addressbook itself[1:03] <phil_s> addressbook/root/main.hac[1:03] <daniel__> create a main.hac in addressbook/Person/[1:04] <daniel__> put something in there to test... like res.writeln(this.firstname);[1:04] <phil_s> oh now it works[1:05] <phil_s> i added that file, a copy of the original[1:05] <phil_s> yes, that works[1:05] <phil_s> id/controller[1:05] <phil_s> is that why main is there?[1:06] <phil_s> in the url[1:06] <daniel__> yes[1:06] <phil_s> this keeps getting better![1:06] <daniel__> however if it would not be the last element in the url, helma would assume the controller you want to call is main[1:06] <phil_s> good[1:07] <daniel__> you would now change the copied main.hac of ourse[1:07] <daniel__> course...[1:07] <phil_s> yes, i just made it show first name[1:07] <daniel__> because i guess you still have root.get()s in there[1:07] <phil_s> this = root?[1:08] <daniel__> this always is the object specified in the url[1:08] <daniel__> so for id/main it is the Person object[1:09] <phil_s> and that works because i have the type.properties data model in there[1:09] <daniel__> yes[1:09] <daniel__> to give you an idea, this is an url of one of my applications http://www2.dowee.com/Europe/Greece/Santorini/main[1:10] <daniel__> root -> Continent -> Country -> Location -> main[1:10] <daniel__> the object tree specified in the type.properties can be as big and complex as you like (-:[1:11] <phil_s> can it inherit data members from other objects?[1:11] <daniel__> please give an example of what you mean in detail![1:11] <daniel__> or what do you mean by data member?[1:12] <phil_s> like maybe i want the same data model, but with different views, and different urls[1:12] <daniel__> yes thats possible[1:12] <phil_s> can person get its data from somewhere else, instead of being set in that directory's type.properties[1:12] <phil_s> ok[1:13] <daniel__> from somewhere else... no...[1:13] <daniel__> but there can be a lot of places in the object tree where you can access the Person[1:13] <daniel__> so a lot of different urls, like[1:13] <daniel__> id/[1:13] <daniel__> or[1:13] <daniel__> id/friends/id might be the same object[1:14] <daniel__> where do you want to get data from?[1:14] <phil_s> so the file structure seems to match the raw object tree[1:15] <daniel__> the file structure defines the type of objects in the object tree[1:15] <phil_s> anyway, im just thinking about it, compared to other frameworks i know[1:15] <daniel__> the object tree is defined by the type.properties files only[1:16] <daniel__> well in reality, your database already defines how the object tree looks like or should look like[1:17] <daniel__> expect for n:m relations, usually each table is on helma prototype and the object tree looks like you defined your keys and indexes in the database[1:18] <phil_s> i like your site. good panos[1:19] <daniel__> thanks[1:26] <phil_s> now i just need to find a host that will run this![1:26] <phil_s> someday i want to go with a vps[1:29] <daniel__> where are you from?[1:30] <daniel__> you can get root servers in germany starting at 2020ac (see www.netdirekt.de)[1:35] <phil_s> canada, but soon moving to usa..vps starts at $20 per month, so ill start there[1:36] <phil_s> its root access, which is what i need[1:37] <daniel__> btw, its possible to start helma inside tomcat (though not recommended)[1:38] <phil_s> no thanks, jetty is great[1:38] <phil_s> so nice that helma buldes it and rhino too[1:38] <phil_s> bundles*[1:39] <phil_s> i found this page, and either host looks great http://dev.helma.org/wiki/Workspace/philmaker/Helma+Hosting/[1:40] <daniel__> i didn't find the time yet, but since years i am thinking about adding php as scripting alternative to helma[1:40] <daniel__> (-;[1:41] <phil_s> what about ruby, python, or even lisp[1:42] <phil_s> i heard lisp is making a comeback as a web server scripting language[1:42] <daniel__> if there is a java to whatever bridge, or a java implementation of whatever it is theoretically possible as helma uses a plugin system for selecting the scripting engine[1:43] <daniel__> rhino is the only plugin available right one, but who knows ... (-:[1:43] <phil_s> i think scheme would be cool. its so small, but its powerful. you can write other languages in it[1:43] <phil_s> http://sisc-scheme.org/[1:44] <phil_s> theres already a java interpreter![1:44] <phil_s> go for it man![1:45] <daniel__> lets see (-:[1:53] <phil_s> i would love to help with that if i could[1:58] <phil_s> ive been trying to use plt scheme web server, but its not working out so well for me.. using helma and jetty with that would be perfect[2:03] <daniel__> too bad i don't know anything about scheme yet[2:08] <phil_s> if you like javascript you'll like scheme[2:09] <phil_s> its based on lisp. its a functional programming language, dynamically typed, uses late binding[2:09] <phil_s> fully bracketed syntax[2:09] <phil_s> heres a great way to get to know it... http://plt-scheme.org/[2:10] <phil_s> thats a full ide for it, and theres lots of support on the site[2:11] <phil_s> lisp is one of the oldest programming languages, and is mainly used for ai research[2:14] <daniel__> i had a look at the quick introduction, defining new syntax really looks interesting[2:15] <phil_s> lisp is starting to get used for server side scripting for web frameworks. the main variants are Common Lisp, which is much larger and incorporates a lot of libraries, and Scheme, which is extremely small but has external libraries[2:15] <phil_s> there is a Common Lisp web framework called Uncommon Web. but i have not heard of any framework yet for scheme...[2:19] <phil_s> and ive tried to get UCW to run and it's not easy... its nowhere near as complete as Helma[2:19] <daniel__> thanks for the information! i will leave now, its already past 4am here in Austria (-;[2:19] <phil_s> ok later[13:17] <midnightmonster> *looking at logs*, fwiw, I've been using slicehost with no problems[13:31] <midnightmonster> ?emailing a designer I happen to be working with about the client's logo. almost said, "too bad they didn't let you design a new one". but then... well, I'm 95% sure that this WordArt monstrosity was their existing logo...[13:34] <zumbrunn_> ?[13:34] <midnightmonster> there was just that 5% chance that I'd be saying too bad they didn't let you design a new one about the one she actually did design[13:35] <zumbrunn> oh, right :-)[13:36] <midnightmonster> murphy's law of demos struck me yesterday[13:37] <midnightmonster> ?demoing new features for the client, and the script that redirects the forms to AJAX doesn't work. works on my local version of the site (almost identical config), doesn't work for them or me on the web version. never had this problem before.[13:37] <midnightmonster> ?later, start editing the relevant js file directly over SSH[13:37] <midnightmonster> ?add a few logging things in, and the logging all comes back as expected[13:37] <midnightmonster> ?wait--it's working?[13:37] <midnightmonster> ?yes, it's working. no errors.[13:38] <midnightmonster> ?remove the logging stuff--it's still working[13:38] <midnightmonster> file is byte-for-byte identical with what it was during the demo[13:40] <midnightmonster> of course the thing that did change is the timestamp (which would have been several days old), and we're talking about client-side js, so there must ?(?) have been some kind of caching issue, though afaik one of the three computers we were using probably had never visited the site before, let alone recently[13:41] <midnightmonster> this is my second for-client helma app, first using the relational DB, but i've got apache serving the static files, so it wasn't possibly anything to do with helma[13:47] <midnightmonster> zumbrunn, on topic, I think I've heard rumblings of being more rails-like in helma 2. do you know in what way? 'cause I've done a little rails now, and mostly I like helma 1.x better[13:49] <midnightmonster> (in particular, every other framework does "routes", and I actually love Helma's object tree approach)[13:50] * zumbrunn kickbans murphy and his law[13:50] <zumbrunn> helma 2/ng is more flexible than 1.x[13:50] <zumbrunn> it *allows* to do things more rails like[13:50] <zumbrunn> doesn't force you to[13:51] <zumbrunn> aida is rails like[13:51] <midnightmonster> aida?[13:51] <zumbrunn> http://helma.org/pipermail/helma-ng/2008-June/000085.html[13:54] <zumbrunn> it's in the sandbox[13:54] <zumbrunn> https://dev.helma.org/trac/helma/browser/sandbox/aida[13:56] <midnightmonster> trying to read that email.... really coming in in the middle[13:59] <midnightmonster> I care a lot about helma ng, but I'm short on time and I don't know where to jump in[14:01] <zumbrunn> yeah, anyway... point is, developing rails-like becomes easier/possible[14:02] <zumbrunn> but that's just a side-effect of helma-ng being more flexible[14:02] <zumbrunn> so, no need to move in that direction if one doesn't have to[14:03] <zumbrunn> basically, in helma-ng requests are handled by an applications handleRequest function[14:04] <zumbrunn> depending on how you handle the requests there, you get something more rails-like or more helma-like[14:05] <zumbrunn> and helma-ng is more flexible mainly because it implements less framework capabilities as part of its java core[14:06] <zumbrunn> and leaves more to be done by the modules[14:07] <zumbrunn> in a sense, the helma-ng core itself is more of a platform for frameworks than being a framework itself[14:07] <zumbrunn> when compared with helma 1.x, anyway[14:08] <midnightmonster> I see[14:21] <daniel> btw, what is the main motivation of making helma-ng more flexible in js instead of making it more flexible in java?[14:22] <midnightmonster> java suxors, js roxors[14:23] <midnightmonster> ;-)[14:24] <midnightmonster> seriously, if we thought java was adequately flexible, powerful, and expressive for web dev, we wouldn't need a JS framework[14:26] <midnightmonster> SQL vs. functional JS for cleaning up after an app screw-up:[14:27] <zumbrunn> daniel: because javascript's strength is its "flexibility" while java's strength is more its "stability"?[14:27] <midnightmonster> ?delete from distributions where prodid not in (select prodid from products);[14:28] <daniel> for the core framework i prefer stability[14:28] <midnightmonster> ?this.list().filter(function(d){ return !d.product; }).forEach(function(d){ this.remove(); })[14:28] <midnightmonster> daniel, arguably you still have that--just as zumbrunn was saying earlier, the core is smaller and you can build different framework styles atop it[14:28] <daniel> and for me core is everything i need to do web development. i dont want to do framework development (-;[14:29] <midnightmonster> daniel, as much as I like absolute power, I'm feeling a little torn about that, too with helma ng[14:29] <midnightmonster> if aida is where people go, I either have to implement my own helma 1-style framework or live with I-wish-I-was-rails[14:32] <daniel> what is aida?[14:33] <zumbrunn> matthias' experimental framework on top of the helma-ng core[14:33] <zumbrunn> the rails-like approach isn't my preferred one either[14:34] <zumbrunn> for most of my apps I like the helma 1 style approach[14:34] <zumbrunn> and the object db flavor of that on top of it[14:34] <midnightmonster> is there a helma 1-style framework?[14:34] <midnightmonster> (We should look at integrating support for 10gen's object db)[14:34] <zumbrunn> there is a helma1 module in helma ng[14:34] <daniel> sorry for asking newbie like questions but I've not done any helma developments in the last couple of years, now I started again and am trying to catch up with all I missed since then (-:[14:35] <midnightmonster> daniel, are you daniel ruthardt?[14:35] <daniel> yep[14:35] <midnightmonster> I'm joshua paine on the mailing list[14:35] <daniel> ah, good to know.[14:35] <midnightmonster> (And in real life, for that matter)[14:36] <zumbrunn> lol[14:36] <daniel> btw, JSAdapter works fine for generic getters / setters[14:36] <midnightmonster> good deal[14:36] <midnightmonster> I don;t know how to use it with helma 1.6[14:37] <midnightmonster> I hear it's much more integrated by default in helma ng[14:37] <midnightmonster> sample code?[14:37] <zumbrunn> sample code for what?[14:38] <zumbrunn> http://github.com/zumbrunn/helma-ng/tree/master/modules/helma/helma1.js[14:38] <midnightmonster> using jsadapter with (I assumed) hopobjects[14:38] <midnightmonster> (was talking to daniel)[14:38] <zumbrunn> the helma1 module is just a basic start for how the backwards compatibility could be implemented[14:39] <daniel> http://helma.pastebin.com/m11d7a4ba[14:39] <midnightmonster> how does it work for HopObjects that already exist?[14:40] <zumbrunn> JSAdapter works just as fine in helma 1.x as it does in helma-ng[14:41] <midnightmonster> there's somthing wrong witht that syntax. not to be picky, just so I understand how to actually do it[14:41] <daniel> for exsiting HopObjects you need to make sure[14:41] <daniel> that the get wrapped as soon as the are "created"[14:41] <daniel> existing HopObjects always come from some get()[14:41] <daniel> so i implemented the wrapping in my overridden get() method[14:42] <daniel> http://helma.pastebin.com/m11f6bf37[14:42] <daniel> i am using your suggestion for the overriding[14:42] <daniel> HopObject -> MetaObject -> all others[14:42] <midnightmonster> cool[14:42] <midnightmonster> (and you know you can say which type Root inherits from, too)[14:43] <daniel> works fine and as even Root extends MetaObject and has my custom get() all HopObjects are JSAdapter wrapped[14:43] <midnightmonster> so am I missing something or does JSAdapter add its own syntax?[14:44] <daniel> JSAdapter is a Java object that you can wrap araound any other object[14:44] <daniel> as a default, all getting and setting is forwarded to the wrapped object[14:44] <midnightmonster> 'cause I would expect the {...} after new thing(thing) to be an error[14:44] <midnightmonster> syntax-wise[14:45] <daniel> the {...} specifiy the methods that override the default behaviour of simply forwarding everything to the wrapped object[14:45] <midnightmonster> right. but is that valid syntax for anything else?[14:45] <daniel> yes[14:45] <daniel> new HopObject() {...} works fine too[14:45] <midnightmonster> where does the {..} object go?[14:45] <midnightmonster> !! what does that do?[14:46] <daniel> the instance is extended with the properties and methods defined in {...}[14:46] <daniel> this syntax is called anonymous class[14:47] <midnightmonster> but it's not standard?[14:47] <midnightmonster> 'cause it doesn't work in spidermonkey[14:48] <daniel> at least its standard in java (-;[14:48] <daniel> might be that it only works in rhino[14:49] <daniel> have a look at http://blogs.sun.com/sundararajan/entry/self_javascript_and_jsadapter to see the standard way of doing it[14:50] <zumbrunn> http://blogs.sun.com/sundararajan/entry/self_javascript_and_jsadapter[14:50] <zumbrunn> lol[14:50] <daniel> (-:[14:50] <daniel> standard... this is one argument why i don't like to shift framework functionality to js[14:51] <daniel> which standard? rhino standard? js standard? ecma standard?[14:51] <midnightmonster> (new Object() { spork:'hi' }).spork[14:51] <daniel> there is too much js out there (-:[14:51] <midnightmonster> ^ works in Rhino[14:51] <midnightmonster> (new Date() { spork:'hi' }).spork[14:51] <midnightmonster> ^ no love[14:52] <daniel> the syntax doesn't do any real magic[14:52] <daniel> if var d = new Date(); d.spork = "hi";[14:52] <daniel> does not work, the anonymous class syntax won't either[14:53] <midnightmonster> but that normal syntax *does*[14:53] <midnightmonster> only the anonymous class syntax doesn't[14:53] * zumbrunn yells: THERE ARE NO CLASSES IN JS[14:54] <midnightmonster> zumbrunn, no kidding? seriously--that's add-on syntax, Rhino-only, and it's called anonymous class syntax[14:54] <midnightmonster> at least according to Sundararajan[14:54] <zumbrunn> yeah well, it shouldn't be ;-)[14:55] <daniel> agreed, there are no classes in js, its called that way anyhow.[14:55] <midnightmonster> ok, now I've read that blog post for the many-th time, though, I see that it is some add-on syntax, which is fine now that I know[14:55] <zumbrunn> everybody that calls this or that a class in js now, will just make things more confusing when classes come around in ES$[14:56] <zumbrunn> ES4[14:56] <daniel> so lets call it anonymous object initializer (-;[14:56] <zumbrunn> +1[14:56] <midnightmonster> w00t[14:57] <daniel> var a = function() {}; new a();[14:57] <daniel> looks like we need to name a named object initializer accordingly (-:[14:57] <midnightmonster> that's a constructor[14:57] <daniel> as there are no classes, there are no constructors[14:57] <midnightmonster> it's still a constructor[14:57] <daniel> (-;[14:58] <midnightmonster> just like it's still an object[14:59] <daniel> well, agreed. so new Object() {...} is the "anonymous constructor syntax"[14:59] <midnightmonster> excellent[14:59] <midnightmonster> ?looks like there's no pretty way to make a JS adapter of an existing object and simultaneously add the magic jsadapter stuff without using an anonymous constructor[15:01] <daniel> yes, there is no pretty way, as HopObjects do not have a prototype which can be extended from within js[15:01] <midnightmonster> um, sure they do[15:01] <zumbrunn> huh?[15:02] <zumbrunn> HopObject.prototype can be fiddled with just fine[15:02] <midnightmonster> I'm not sure what we're talking about exactly, but you can definitely do HopObject.prototype.foo = bar;[15:02] <zumbrunn> define "extended", I guess[15:02] <midnightmonster> and you can mess with the HopObject constructor if you like, though in HElma you have to restart the app[15:04] <daniel> is that true also for HopObjects which are not created by using the constructor i.e. HopObjects created by Helma?[15:04] <zumbrunn> yes[15:05] <midnightmonster> so you might be able to do the JSadapter wrapping in the constructor instead of get[15:05] <midnightmonster> not sure[15:05] <daniel> the constructor however is not called for these HopObjects, thats what i am sure of[15:06] <midnightmonster> which hopobjects?[15:06] <midnightmonster> 'cause in my experience it is[15:06] <midnightmonster> but you have to restart the app for changes to constructor to take effect[15:06] <daniel> the ones created by helma which are retrieved via gets()[15:06] <daniel> lets give it another try...[15:06] <midnightmonster> hmmm...[15:08] <midnightmonster> nah, daniel[15:08] <midnightmonster> 's right[15:09] <midnightmonster> when they're retrieved from the db, they're not being constructed[15:09] <midnightmonster> just retrieved[15:09] <daniel> tried it and yes[15:09] <midnightmonster> HopObject.prototype.whatever definitely works, though[15:10] <daniel> tried it too and yes, this definitely works[15:11] <daniel> regarding JSAdapter and what i want to do, there is one issue left[15:11] <daniel> JSAdapter enables generic getters and setters but hides all functions )-:[15:11] <midnightmonster> ?[15:13] <daniel> new JSAdapter(new HopObject() {this.lala = "lala"}).lala works[15:13] <daniel> but new JSAdapter(new HopObject()).size() does not work anymore[15:13] <daniel> or any other method[15:14] <midnightmonster> just tried[15:14] <midnightmonster> wow, that's crappy[15:14] <midnightmonster> it doesn't hide pre-existing properties, either[15:14] <midnightmonster> only functions[15:14] <daniel> yes[15:15] <daniel> but the really funny thing about it is[15:15] <daniel> that readding the functions does not help either[15:15] <daniel> new JSAdapter(new HopObject() {a: function(){}}).a()[15:15] <midnightmonster> it wouldn't[15:15] <daniel> sorry it should be[15:16] <daniel> new JSAdapter(new HopObject()) {a: function() {}} of course[15:19] <daniel> the only thing working is adding the functions afterwards[15:19] <daniel> var test=new JSAdapter(new HopObject());[15:19] <daniel> test.lala = function() {}[15:20] <daniel> i guess this works because this causes the setter to work and set them on the wrapped hopobject[15:21] <daniel> overwriting the hopobject's functions however does not help to access them (-:[15:27] <midnightmonster> here it is:[15:27] <midnightmonster> HopObject.prototype.__get__ = function(name){ if(name=='foo') return 'bar'; return this[name]; }[15:27] <midnightmonster> new JSAdapter(myHop).foo == 'bar'[15:28] <midnightmonster> new JSAdapter(myHop).size() == 12 (or whatever)[15:28] <midnightmonster> the anonymous bs syntax doesn't work right[15:29] <midnightmonster> (note that href() won't work on a JSAdapter--you'll have to special-case that one)[15:34] <daniel> that makes functions accessible again, but not callable[15:34] <midnightmonster> yeah they are[15:34] <midnightmonster> working for me[15:35] <daniel> working? returning the right thing?[15:35] <midnightmonster> (how can they be accessible but not callable? that's not possible in js)[15:35] <daniel> not only: TypeError: Method "size" called on incompatible object.[15:35] <midnightmonster> right... some (most?) of the built-ins won't work on an JSAdapter. hang on[15:35] <daniel> this is possible as they are java methods and not js functions[15:35] <midnightmonster> right. it's fixable though[15:37] <daniel> i didn't try it but i guess all of them don't work[15:38] <daniel> how do you want to fix it?[15:38] <daniel> well, jsAdapter.size.apply(new HopObject()) works, but...[15:38] <midnightmonster> http://helma.pastebin.com/m4f524572[15:42] <midnightmonster> I left out passing on the arguments[15:42] <daniel> mh that one really works.[15:42] <daniel> i saw it[15:43] <phil_s> hi daniel thanks again for the help yesterday. i ended up talking to cky at #sisc about a helma / scheme bridge and he said it looked pretty easy to do[15:44] <midnightmonster> complete version: http://helma.pastebin.com/d779c69fb[15:44] <daniel> from what i saw in the scheme api docs it looks easy to do, thats the advantage of a minimalistic language[15:46] <phil_s> cky told me that sisc uses jsr223, and sun has an engine for it. he said all that remained is to make helma talk to the jsr223 engine, and drop in the sisc interpreter[15:47] <daniel> thanks joshua, i will try to improve it a little bit, creating a new function object for each function call is quite an overhead - but at least it works and seems like the right way to go[15:50] <daniel> btw, do i have to implement different scripting engines in helma ng in js or is this still considered core framework and worth to be in java? (-;[15:51] <daniel> rhetorical question...[15:51] <daniel> phil, where can i find this engine?[15:52] <phil_s> jsr223 looks really good. theres a lot of scripting engines supported already. https://scripting.dev.java.net/[15:52] <phil_s> it will be included in java 6[15:52] <midnightmonster> daniel, that's the beauty and pain of closure. I don't think you'll find a way around the extra function object, though you could work on restricting it to just the built-in methods that need it.[15:53] <midnightmonster> and for what's it's worth I throw around anonymous functions all the time as my basic way of working in JS, and my performance issues always come from somewhere else[15:55] <daniel> per caller/callee caching would be possible[15:55] <midnightmonster> huh?[15:56] <midnightmonster> oh, you mean when I call hop.size, keep the anonymous function for size in a hash table somewhere[15:56] <daniel> before i answer your huh with an implementation, i will first do a quick benchmark to see if its worth it[15:56] <midnightmonster> I'm almost sure you'll find that's worse[15:56] <daniel> yep but only for hop of course[15:57] <daniel> i don't want hop2.size to be called on hop[15:57] <daniel> thats what i meant with per caller/calle[15:57] <midnightmonster> right[15:57] <daniel> +e[15:58] <daniel> might be worth it[15:59] <daniel> took me 153ms to execute took me 1193ms to execute[15:59] <midnightmonster> caching keeping a function and its closed scope in memory for each distinct function call until the object is destroyed, whereas in my no-caching impl, the anonymous function and its scope can go away as soon as you're done[15:59] <midnightmonster> ?[15:59] <daniel> 100000 times accessing size()[15:59] <daniel> 153ms with a plain hopobject, 10 times more with the jsadapter[16:00] <midnightmonster> try with the trivial __get__ impl (without the closure trick) and a method you define yourself that doesn't require a real Hop[16:01] <midnightmonster> (i.e., test whether the problem is the extra closure or just using jsadapter at all)[16:02] <daniel> mh ok i will try it[16:02] <daniel> btw, implementing caching makes it 20 times slower (-:[16:03] <midnightmonster> lol[16:03] <daniel> cache lookup is more expensive than function creation[16:04] <daniel> sort of both[16:04] <daniel> accessing a non-existing property[16:04] <daniel> took me 142ms to execute took me 635ms to execute[16:04] <daniel> 5 times more with jsadapter[16:06] <daniel> still had the typeof() in there...[16:06] <daniel> emptying the getter reduces the time to 400ms[16:16] <decke> i found an interesting high performance java cache (similar to memcached) http://ehcache.sourceforge.net/[16:22] <midnightmonster> daniel, I think your caching impl may have been the problem. with caching I'm actually able to get about a 14% speedup[16:23] <midnightmonster> not huge and very possibly not worth the extra memory load, but it's there[16:23] <daniel> i tried some other caching mechamnism in between, but i didn't get more than 10%[16:23] <daniel> how does your caching look like?[16:24] <midnightmonster> calling size 100000 times on plain hop I get ~113 ms, with my original JSadapter code ~732 ms, with caching ~636 ms[16:26] <midnightmonster> it uses closure to establish the per-obj context, so you'd have to do it just before you jsadapt the object in your overriden get instead of in the prototype[16:26] <daniel> understood[16:28] <midnightmonster> http://helma.pastebin.com/m4ae0d401[16:33] <midnightmonster> another way you could do is pay the cost up front--when you get() the obj, loop through and stick functions for all its methods in var cache. then the __get__ function is down to return cache[name] || this[name];[16:34] <midnightmonster> uses more memory, and the cache lookup might be slightly slower, but it should be faster overall[16:50] <daniel> thats the way to go[16:50] <daniel> 226ms[16:53] <daniel> ah sorry need to evaluate again, thats not the correct time[17:03] <daniel> 145ms / 610ms[17:04] <daniel> better, but still not it. i will have a look in JSAdapter.java and see what can be improved there[17:50] <midnightmonster> daniel, is 610 with the upfront full cache or my updated on the fly cache? and what # did you get for the other?[17:53] <daniel> 610 is for the upfront full cache[17:54] <daniel> for the updated on the fly cache i had ~670ms[17:54] <midnightmonster> if jsadapter can be conformantly improved, that's an obvious win[17:55] <midnightmonster> but my guess is even the 5-6x slowdown of using jsadapter isn't really going to matter in most cases[17:56] <daniel> might be true, but all together a lot of things that don't matter start to matter (-:[17:56] <daniel> don't forget, i am doing this to implement a per object / property access layer[17:57] <daniel> this will cost a lot of time, so i need to find that lot of time somewhere else[19:19] <Helma4> mm: i've no idea why (yet), but with my modified JSAdapter i am not at 103ms vs. 152ms of the plain HopObject[19:20] <midnightmonster> how have you modified jsadapter?[19:20] <midnightmonster> (and you're saying access is actually faster than directly?)[19:20] <daniel> yes thats what i am saying[19:20] <midnightmonster> sorta seems like that shouldn't be possible, right?[19:21] <daniel> well what did i modify[19:22] <daniel> do know who rhino works?[19:22] <midnightmonster> some[19:22] <daniel> tje JSAdapter is a Function[19:22] <daniel> a Function actually is a FunctionObject[19:22] <daniel> so you can call it and get and set properties on it[19:23] <daniel> when the hopobject function[19:23] <daniel> lets say size()[19:23] <daniel> gets called on the JSAdapter, i first returned the FunctionObject() of size()[19:24] <daniel> in js the () calls it which resulted in the error whe already had[19:24] <daniel> called on wrong object[19:25] <daniel> because you can only call it on hopobjects, so i modified my JSAdapter more ore less like we did it in js[19:25] <daniel> i prepared a BaseFunction (which is a very simple function) which when called forwards the call to the real size Function[19:25] <daniel> called on the right HopObject[19:26] <daniel> and it seems that as in JS, the preparing makes it faster then the original[19:28] <midnightmonster> the problem with this approach, I imagine, is that if the method (not size, perhaps, but a user-created method) accesses any properties/variables of the object, it accesses them directly, not through the rules of the adapter?[19:28] <midnightmonster> which is a problem with mine, too[19:29] <midnightmonster> but doing it in JS, at least you have the possibility to give the bypass only to certain functions[19:29] <daniel> this is true[19:29] <daniel> right now i only bypass the built-in hopobject functions[19:30] <midnightmonster> how can that be?[19:30] <midnightmonster> unless you're working helma-specific code into it[19:30] <daniel> you can still not call the others at all (-;[19:30] <midnightmonster> does it only do the framework-built-in ones, or any defined on the prototype?[19:30] <daniel> but thats exactly what i did as i called my modified version HopObjectAdapter (-:[19:31] <daniel> only the framework built-ins for now[19:32] <daniel> still the difference in performance is quite interesting[19:34] <daniel> i forgot to mention that out js approach still works, so one can use the js approach for the non builtin functions on let the others be handeled directly[19:35] <daniel> i will continue to work on it, lets see where i end up[19:37] <midnightmonster> any functions written in JS should run fine on a JSAdapter, so the simple __get__:function(name){ return this[name]; } is all that[19:37] <midnightmonster> 's needed[19:38] <midnightmonster> (plus whatever access restrictions you want)[19:38] <daniel> well its true[19:39] <daniel> i forgot that the only reason for having the JSAdapter is the generig getter / setter[19:39] <midnightmonster> heh[19:40] <daniel> enforcing security restrictions for builtin functions did already work before JSAdapter by using your approach from the mailing list[19:41] <midnightmonster> right. only remains issue was property access[19:41] <midnightmonster> remaining[19:41] <daniel> yep and property access with the original JSAdapter made everything else more complex[19:41] <daniel> and this is not true anymore for my modified JSAdapter[19:45] <midnightmonster> I learned about e4x about the same time I was getting started in Helma, and (esp. in the tutorial but even with more recent improvements) skins didn't feel right, so I haven't been using them at all. what is it macros do that you're trying to change?[19:54] <daniel> there are aonly a handful of predefined macros, i do not worry about them. i do worry about my own macros as i have a lot of generic macros.[19:55] <daniel> macros for printing properties, printin lists, macros that can crawl through the whole object tree and so on[19:57] <phil_s> midnightmonster: what do you use instead of skins?[19:59] <midnightmonster> E4X lets me use XML as native objects with their own (XML) syntax right in the middle of JavaScript. I still keep my view functions separate, but they just have XHTML right in them instead of separate skins[19:59] <phil_s> does that work cross browser? like IE6?[19:59] <midnightmonster> when it gets to the browser, it's just text like anything else[19:59] <phil_s> ok[19:59] <midnightmonster> on the client side it only works in FF[20:00] <midnightmonster> but I'm using it in Helma on the server[20:00] <daniel> i want to make sure that the macros don't need to take security into account and that macros inserted into skins by someone else than the developer can not access data or do thinks which they shouldn't do[20:00] <phil_s> right, i thought you meant e4x on the client.. i didn't understand you could also use it on the server[20:00] <midnightmonster> daniel, ok.[20:01] <midnightmonster> Rhino supports it, too. works pretty well. there are a couple bugs[20:01] <midnightmonster> but nothing too problematic[20:03] <midnightmonster> helma encourages you to break up your views into pieces associated with object involved. e.g., a product is still responsible its part of the HTML (perhaps a row of a table) of the manufacturer's page that lists products. this is Right and Good as far as I'm concerned[20:04] <midnightmonster> but what it means is that we're already completely out of the zone of things that "designers" can do directly unless they really know their HTML & CSS without a WYSIWYG and can handle some level of abstraction and indirection[20:05] <midnightmonster> and if they can handle that, XML in (view-specific) JavaScript isn't really any harder than JavaScript interspersed in XML[20:06] <phil_s> midnightmonster: in what file do you put your e4x view code? in the .hac? or do you make some other file to store all the view stuff for each object?[20:07] <phil_s> in each hac might make sense for me[20:07] <midnightmonster> I don't use the .hac's actually--main.hac is just a shortcut for function main_action(){} in any .js file in the prototype dir[20:08] <phil_s> O_O[20:09] <midnightmonster> I have files like Product.action.js (which has all my actions) Product.model.js (which has functions to do with the lower level data model) Product.view.js (which has all the view functions)[20:09] <midnightmonster> all in the Product folder[20:09] <midnightmonster> and I wouldn't put view code in a .hac--it would mean you couldn't access it from any other action, so you'd end up repeating yourself[20:09] <phil_s> so i the js files are there, they get called automatically?[20:10] <midnightmonster> right[20:10] <midnightmonster> any functions defined are added to the prototype[20:11] <midnightmonster> and if you have a function named whatever_action, it gets called to handle the request when someone accesses /yourObj/whatever[20:11] <daniel> functions ending in _action get called automatically[20:11] <phil_s> how do i know which one it calls first? if i define a function in one, and then call it in another for example[20:11] <midnightmonster> don't put code in .js files except in functions[20:11] <phil_s> ic[20:12] <midnightmonster> (you can do it, and there are probably use cases, but it gets evaluated every time the file changes, which leads to weird results)[20:13] <midnightmonster> you put the code "loose" in whatever.hac, but behind the scenes everything in whatever.hac is automatically wrapped in function whatever_action(){ ... }[20:13] <phil_s> ok, i just have to try some things, and i'm sure i'll start to figure it out...[20:13] <midnightmonster> the reason for the .hac thing is some people like to be able to read down their directory tree and see all their actions[20:14] <midnightmonster> I prefer to have them all in one file[20:14] <midnightmonster> (per type)[20:14] <daniel> i even have an actions directory for all my hac files (-:[20:14] <midnightmonster> that'd work[20:15] <daniel> a function.js, macros.js and a skins dir[20:15] <midnightmonster> it's annoying when they're not listed together b/c of alphabetical sorting[20:15] <daniel> i totally agree[20:15] <midnightmonster> I've started doing the file names like I mentioned b/c when they're tabs in Eclipse, Customer/functions.js and Product/functions.js both would show as functions.js[20:16] <daniel> i am using eclipse too and yes this is annoying[20:16] <phil_s> daniel: as you mentioned before, helma could support other scripting engines.. but isn't this stuff pretty much exclusive to javascript?[20:16] <midnightmonster> relatively recently it was made so you can do NameOfType.properties, too, instead of just type.properties[20:16] <midnightmonster> what part?[20:17] <daniel> phil: not at all, helma can use any language accessible from java[20:17] <midnightmonster> daniel, in theory--I don't know that anyone has practically done it[20:17] <phil_s> so i would follow the same rules for hac, skins, function, etc..[20:18] <midnightmonster> afaik the potential to use other languages is theoretical.[20:19] <midnightmonster> like, there's nothing about the architecture that would make it impossible for someone to modify helma to work with some other language kind of theoretical[20:19] <phil_s> but now that java supports so many scripting language engines, i think it could be done pretty easily[20:19] <midnightmonster> and of course you could instantiate helma classes from any JVM language[20:19] <daniel> well but for other scripting engines, its not needed to change helma in any way[20:19] <midnightmonster> daniel, news to me, but I'm not very interested in it so I wouldn't know[20:19] <daniel> helma is right now implemented with a pluggable scripting engine design[20:20] <daniel> long time ago, there were at least two different scripting engines one could choose from[20:20] <midnightmonster> they were both JS engines, though[20:20] <midnightmonster> no?[20:20] <daniel> the pre-rhino js engine (whatever that was, cant remember) and the rhino one[20:21] <phil_s> i think its a great idea to use a standardized java stuff, and then let the developer script in their language of choice[20:21] <daniel> well but you were able to switch on off and the other on by changing a flag[20:22] <daniel> so yes of course as with any other plugin system, there is an overhead of making the scripting engine accessible to helma[20:22] <midnightmonster> I'm using Helma b/c I like JS. I can't really think why else you would.[20:22] <daniel> but i can be done quite easily and what is most important without changing helma in any way[20:22] <daniel> php[20:22] <daniel> what about it?[20:22] <daniel> real classes (-;[20:22] <phil_s> i like javascript too, but there are a lot of scripting languages out there besides js[20:22] <midnightmonster> I left PHP for this[20:23] <daniel> you didn't leave it because of the classes did you?[20:23] <phil_s> and i think its just great to give people the choice[20:23] <midnightmonster> "real classes" but no useful dynamic features[20:23] <midnightmonster> and I don't miss classes at all[20:23] <phil_s> so a tcl guy can still use tcl... a lisp guy can still use lisp[20:23] <midnightmonster> (and yes, I used them and have at least a fair understanding of how they work)[20:24] <daniel> i don't miss classes too but i think most people that left php in the pre php5 times left php because of lack of data model abstraction[20:24] <phil_s> and the framework core is no longer a concern for them, they can all depend on a standard helma to take care of that stuff[20:24] <daniel> so it would be nice to have helma provide the data model and let php developers continue in the scripting language they are used to[20:25] <midnightmonster> phil_s, realistically, Helma's a niche platform and if someone figures out how to get Lisp running on it, I'd be shocked if real-world users passed 1 digit[20:25] <phil_s> people are already using these languages on the web[20:25] <phil_s> and each time they have to build a separate framework to power them[20:26] <daniel> btw, i reimplemented helma some time ago in php (-:[20:26] <phil_s> they should be doing in in a jvm, and since helma is here, they should not reinvent the wheel[20:26] <midnightmonster> daniel, I've been thinking about doing that, too, whenever I think about having to write more PHP[20:26] <daniel> to have a helma like framework for developers who are used to develop in php[20:27] <midnightmonster> ?PHP wins b/c it can be run everywhere. "you need a virtual private server" is maybe even a bigger obstacle than switching languages (since most PHP devs have to have at least a passing familiarity with JS)[20:27] <daniel> its even in user... www.tronic.cc uses it for his projects... i am not sure if it has been updated but its available at phpop.sf.net[20:28] <midnightmonster> the *other* reason PHP wins is that just adding a little functionality to an otherwise static site is easy. running PHP on Helma breaks both advantages[20:31] <phil_s> i like javascript because i like functional programming. but thats also why i like lisp and scheme. php is not really the same...[20:31] <midnightmonster> really PHP is not at all the same.[20:32] <phil_s> right, and also you can already run it everywhere, so why implement a jvm for it?[20:32] <midnightmonster> I think that[20:32] <daniel> if you really use the object orientation offered in php5 and try to use nothing else than oop than it is most similar to java[20:33] <midnightmonster> right. which is not a language I want to work in[20:33] <daniel> but still you want java back whenever you hit at php's oop limits (-:[20:33] <phil_s> and java is great for what it does.. but i want to work in a language that promotes functional programming[20:34] <midnightmonster> huh? I have never once in my life thought, this PHP sucks--if only I were working in Java[20:34] <midnightmonster> phil_s <-- yeah, that[20:35] <midnightmonster> over and over I think, this PHP sucks--if only I were working in JS[20:35] <phil_s> like you need java for the serious stuff, the foundation... and they you want to give people the more expressive language to work with on top[20:35] <phil_s> *they=then[20:36] <daniel> agreed. but what i really want more than anything else is a helma ide (-;[20:36] <phil_s> thats why i think helma is brilliant, it does that so well[20:36] <daniel> now. anyone willing making one for me *g*?[20:36] <midnightmonster> phil_s, IMO, the principle advantage of having a Java base is that you get access to the gazillion java libs[20:36] <phil_s> midnightmonster: agreed, its there for you when you need it, and its part of the core foundation[20:37] <phil_s> but to layer php on top? kind of not much difference[20:37] <phil_s> make it something really expressive like javascript, now thats impressive[20:37] <phil_s> go further with supporting lisp type languages, and thats just incredible[20:37] <midnightmonster> I'm told some LISPs can be in the neighborhood of C speed-wise. if I were into LISP, I would do that all the time except for the library issue[20:38] <phil_s> scheme would be best[20:38] <phil_s> minimal lisp[20:38] <midnightmonster> (i.e., I'd be happy with a framework written 100% in JS if it were fast enough and had all the libs I needed)[20:38] <phil_s> similar to javascript in a lot of ways[20:39] <midnightmonster> yeah, I know (in a vague, general way)[20:39] <phil_s> but it just finally trumps the argument of typed vs dynamic... have both at the same time[20:40] <phil_s> use each when needed for its strengths[20:40] <midnightmonster> well, but you're not really getting both at the same time you have to write in a whole other language with a completely different design to switch between[20:40] <phil_s> cant you call one from the other?[20:40] <midnightmonster> yes[20:41] <phil_s> like if i needed to add some core functionality, i would choose to update the java part of the framework[20:41] <midnightmonster> (sorta depends on what you mean by core)[20:42] <daniel> i am quite happy with what is core in helma 1.x[20:43] <midnightmonster> wow... it's been fun, and digging into jsadapter was definitely fun/educational, but I've written so little paid code today I'm going to cry. so I'll see y'all later[20:43] <daniel> although there could be more pluggable components[20:43] <daniel> see ya (-:[20:44] <phil_s> dont get me wrong, javascript is great, and i like helma just the way it is[20:46] <daniel> as said, i see a need to make the existing core more flexible, but i dont see a need or improvement in doing it in js
In the channel now:
Logs by date: