Showing posts with label javascript. Show all posts
Showing posts with label javascript. Show all posts

4/22/2007

What makes a DSL a DSL?

I recently released Flexjson to the world, and I've been thrilled by the response I've gotten. But, someone asked why I called Flexjson a Domain Specific Language. It's a good question so I thought I'd write down some ideas around what makes me say something is a DSL vs. when it's just an API.

DSL does get thrown around a lot, and it's hard to always pick out what's a DSL and what's just an API. Hibernate's HQL is definitely a DSL, SQL is a DSL, Phong Shader languages are DSLs, but it gets fuzzier when people say Rails is a DSL or something in LISP. LISP and Ruby are general purpose languages just like Java so how can a library written for a general purpose language be a language too. Isn't that just a well written API? I struggled to answer this question when I first encountered examples of these DSLs.

Martin Fowler wrote some thoughts of this subject and he divided DSLs into two types: external DSL and internal DSL. External DSLs examples are SQL, Hibernate's HQL, ant scripts, or phong shader languages. Internal DSLs would be certain aspects of Rails, or Javascript's Event.Behavior.

External DSLs are glaring examples of DSL. They're easy to spot. Internal DSLs are harder to spot as such. I've decided that Internal DSLs read like a sentence where an API is reads like an algorithm. It's a fuzzy definition, but no less fuzzy than spotting design patterns in code. Said another way DSL should feel more high level, like you're able to produce results in a very simple way.

So what makes an API an API? Well I guess API is not high level. Terrible definition I know, but I think it's pretty accurate. An example of a definite API is JDBC. There's no way to get things done in a simplified way. It's verbose as hell and low level as the day is long. Sorry I get that way about JDBC. ;-) But seriously, it makes me handle all the details. It just gives me access to the database, but I have to manage the connections, the statements, and results sets sure signs I'm dealing with an API.

Flexjson is an internal DSL. It's very simple DSL. There are really only three statements in this language: include, exclude, and serialize. However, while these are just simple methods include and exclude accept strings formatted in dot notation. Dot notation is a simple way of specifying the fields within the object graph. This is probably the part that is most language like. The overall style of Flexjson feels more high level almost language like. So we get something like:


new JSONSerializer().include("bids", "winner.winningBids").serialize(auction);


Let's say I had designed Flexjson like following:


JSONSerializer serializer = new JSONSerializer();
serializer.include( auction.getClass().getField("bids") );
serializer.include( auction.getClass().getField("winner") );
serializer.include( auction.getClass().getField("winner").getDeclaringClass().getField() );
serializer.serialize( auction );


I would say this is starting to look more like an API than a DSL. It doesn't really help me in specifying what I want to happen. It just does the serialization to JSON process. And not as easy to work with which means it's not fun either.

So while Flexjson purpose is to serialize Java objects to JSON. It also tackles the effort of walking the graph for you. Walking the graph is not central to it's purpose, but it's something you have to do as a client. So, Flexjson has a little language that let's you just say in a high-level way what you want to happen. This is what makes your job easier.

The difference between DSL and API sometimes boils down to just style. Java has had a tradition in writing APIs. Some better than others. However, there are a lot of good programmers out there doing things differently, and I think that's a very good thing. I've heard Rubynauts say that you can't create DSLs with Java because it doesn't support all the cool stuff Ruby has. And all that stuff is important to writing DSLs. I happen to disagree with that very much. Java is just as suitable for writing DSLs as any other general purpose language. You just have to work with what you got. I hope to add more on this subject later. DSL vs. API is root in a change in style, but it allows us to do things we couldn't do with our APIs.

It's really about reaching consensus if something is a DSL or not because these things are fuzzy. We're using these APIs to write mini-languages, and exposing our language as APIs so it can be confusing. But, just because it takes the form of an API doesn't mean it's an API. There are lot of benefits to this my favorite is code completion and use of our existing tools. Flexjson I think qualifies as a DSL, albeit a simple one.

4/18/2007

Annoucing: Flexjson for Java 1.5

I recently created a new library for sending Java objects over JSON. It's called Flexjson. Flexjson allows you to control the depth to which you serialize your objects. If you're using libraries like Hibernate for your objects you'll know that many libraries will try to serialize the entire object graph as JSON. This is be a serious performance bottle neck when your object form a connected graph as Hibernate requires. Other libraries force you to manually copy over fields into a seperate object thus creating lots of boiler plate code. Flexjson tries to give you a simple DSL implemented as a normal Java API in order to control with a minimal amount of code what gets translated to JSON.

Check it out: http://flexjson.sourceforge.net

3/28/2007

Stopping the memory leaks with Prototype

Lately, I've been trying to fix the memory leaks in my application. I found this cool little tool for Firefox: Leak Monitor. It's pretty nice at showing you when you have a leak, but it could be improved a lot more by showing you more details about the leaks. Right now it only tells you the creation point of the object that was leaked. Which if you're using a javascript library like Prototype then you get a lot of references to code you didn't write. It would be more helpful if it could print out the complete stack trace that caused the construction. And it would be nice if you could turn the plugin on and off for given pages. Right now it alerts you to every leak which is interesting to see what pages you visit the most cause your browser to leak *cough* Digg, gmail. But, ultimately it's annoying as all hell after a few visits. Bottom line it's still a nice tool.

What I found in my code was lots of problems using bind() and bindAsEventListener(). Massive amounts of memory being wasted by yours truly because I didn't clean up my event handlers. But, I thought Prototype handled this for me judge! Honest! I started reading the new prototypejs.org site for any hint of documenation mentioning cleaning up references. Prototype will install a listener on the unload event and cleanup all listeners registered through Event.observe(). But, reading the fine print it only does this if you're in IE! But, I'm seeing tons of memory leaked in Firefox. Why not do it for Firefox as well? It's all the same javascript, and if I have to go around and manage all of the listeners myself what's the point of having IE then do it for me? Only the Prototype developers know why. But, here is what I did to fix my problems:


Event.observe( document, 'unload', Event.unloadCache );


Put that in my javascript and viola I went from over 70-80 leaked objects down to 2. I'm so smart...hey wait a minute two! So I checked my leak monitor tool, and it's coming from the bind() method in prototype. Well I'm a heavy user of the bind() method so it could be anywhere. At first I thought maybe it was Behaviour so I removed Behaviour, but nope still 2 being leaked.

Fingers drumming, mouth frowning, what in the heck could it be?! I played around and noticed sometimes I leaked 1 object. Other times I leaked 4. Hmmm. Then I remembered something that I read on Jack Slocum's blog 3 Easy steps to avoid javascript memory leaks. Number 3 relates to using Ajax calls. So I commented out my Ajax call I was doing on page load and viola no leaks! Looks like my use of bind() method there was causing trouble. So now I know what it is, but what's is Prototype not doing?

After hunting through the Prototype source I see where it's setting the onreadystatechange to null. I've been working on it for a couple of days, and I still can't figure out why it's leaking. This is where it's unclear why my object is being leaked. Comparing this with how you look for leaks in Java this is a real pain. In order to implement garbage collection you have to have what's called a root set. This is a set of objects that is considered always live like global variables live forever, or the client side dom. The garbage collection algorithm starts recursively walking object references from the root set marking the objects as reachable. Once it's finished visiting all the reachable objects it can throw away the objects that aren't reachable. So essentially anything that is reachable from the root set will survive garbage collection. To clean up objects simply cut all the references from the live set. That means for a given object we ought to be able to see what objects have references to it, and what objects have reference to those, etc. Now I know that because IE uses ref counting it can leak objects not reachable from the root set, but every other browser out there implements a real GC algorithm. And remember I'm talking about tools that run in Firefox mainly.

Leak monitor just tells you if you're leaking memory, it doesn't tell you why. What we need is a tool that traces the objects back to the root set so it can show us where it's being referenced accidentally. Then we can cut that reference and move on. A good tool like this would make leak removal makes this process easy for anyone to do. Right now it's much more of a hunt and guess that takes forever.

Well I guess it's back to hunting.