Archive for August, 2009

RQuery: refactored and simplified 2

I’ve gone back and knocked off a couple of big todos in rquery. Namely, removing the Symbol capability, and using instances of the new OperationCollector in place of the global class variable + mutex required by the Symbol alterations. Also, as a consequence, I was able to remove the Declarations methods ( .is, .is_not ) previously required for use with overloaded operators like ==.

No More Symbols

Previously there were two DSLs coexisting in the library. One opened up the Symbol class and added the declaration methods.

User.where { :age.is == 12 }

This, in my opinion, was an interesting hack and fun to implement but required both global storage for the results of the executing statements and the pollution of the Symbol class. The library’s better half used a block parameter that represented a collection of the attributes provided by ActiveRecord.

User.where { |user| user.age.is == 12 }

In removing support for the Symbol based syntax, the block based version became much cleaner both externally and internally. Externally there’s no longer a need for the .is and .is_not declarations while the from, between, in and contains methods remain the same.

User.where do |user|
  user.age == 12
  user.name.contains "George"
  user.weight.between 160..180
end

Though, because of Ruby’s restriction on overloading the != operator it now looks like:

User.where do |user|
  user.age.not = 12
end

Simple Internals

The internals have been simplified as well. At a glance, there is now a single class that handles the organization of the calls to the adapter for serialization, OperationCollector. In addition every time the where method is called, a new instance of this class is created so there’s no need to have the mutex to prevent race conditions. Please take a look at the newness for more details.

Unraverl: Partial Function Application 0

What is it?

Last weekend I hacked partial application into my parse transform for erlang, unraverl. The rules are very simple but the implications are interesting if nothing else.

In other functional languages, haskell as an example, there’s nothing inherently wrong with defining a function that requires two arguments but giving it one.

add x y = x + y
example = add 1
{- => \y -> 1 + y -}

The result is a lambda where the supplied argument is applied across the code in the function.

Unraverl’s implementation?

Using the initial example in Erlang

add(x, y) -> x + y.

example() -> add(1).

the parse transform sees that there are no local (only) functions named ‘add’ with an arity of 1. It then finds the next highest arity definition and changes the call to accommodate

%% roughly
example() -> fun(y) -> add(1, y) end.

So while haskell applies whatever arguments are available to the actual function (internally I’m not sure how its implemented), unraverl simply wraps a call to the actual function in a new fun requiring the remaining arguments.

To make use of this feature in your own applications simply add the compiler directive

-compile([{parse_transform, unraverl}]). 

and make sure the library is in the code path.

As yet, it doesn’t have a makefile or unit tests so use at your own peril.