Introducing… ActionLinq

I am excited to release a pet project of mine that I have been developing for a few months.  ActionLinq is a complete LINQ-to-Objects implementation for ActionScript 3.0.  Including the same deferred execution behavior as LINQ, ActionLinq is a functional query library designed to process and manipulate data in ActionScript 3.0.  It is especially useful for processing data received from web services and manipulating it to fit into the view.

Let me illustrate what ActionLinq can do with an example of some basic data processing:

var transformed:Array =
        [-4, -3, -2, -1, 0, 1, 2, 3, 4]
        .where(isEven)
        .select(square)
        .distinct()
        .reverse()
        .toArray();

assertThat(transformed, array(0, 4, 16));

ActionLinq can query pretty much any collection type (Array, ArrayCollection, ArrayList, XMLList, Vector, etc) and it can output it just the same. 

Lets look at a slightly more real-world example.  Assume that the xml variable is data received from something like a REST service.  We want to create an ordered collection of distinct categories from the XML that was received:

var xml = <products>
              <product name="Beef"         category="Meat" />
              <product name="Hot Dog Buns" category="Bread" />
              <product name="Bran Flakes"  category="Cereal" />
              <product name="Chicken"      category="Meat" />
              <product name="White Bread"  category="Bread" />
              <product name="Pita Bread"   category="Bread" />
          </products>;

var categories:ArrayCollection =
        Enumerable.from(xml.product)
        .select(function(product):String { return product.@category })
        .distinct()
        .orderBy(identity)
        .toArrayCollection();

Running that query lets you bind the categories variable to a DropDownList with a very expressive, functional query on the data that was received.

These are just a few examples.  You can find a lot more documentation at the project site.

How do I Get ActionLinq?

I have made ActionLinq an open-source project on BitBucket.org under the Apache 2.0 license.  I chose that license because I want you to be able to use it for any use without charge as long as you maintain attribution.  In other words, fork it, modify it, re-distribute it, do whatever for any reason.  Just give me and/or SRT Solutions credit for the work that ActionLinq provides.

The BitBucket site includes a lot of documentation for ActionLinq in the Wiki.  There are also a lot of unit tests in the source which document everything that ActionLinq is meant to do.

If you use it, let me know!  I’d love to know who is using it.  If you find problems, also let me know in the “Issues” section of the project site.

Why Did I Create ActionLinq?

Overcome the Flex Collections Inconsistencies

When I first came to Flex, I was frustrated by the inconsistencies between the different collection types.  Some types, like Array, include useful functions like map and filter (select and where in ActionLinq) but other types like ArrayList do not.  Although an interface named IList exists, most of the collections do not implement it.  Some collections use a length property.  Others use a length() method.  The Vector class gives a useful typed data set but is difficult to go back and forth between it and other collection types.  Inconsistencies forced me to convert my data collections from one collection type to another just to get the functionality I needed. I found myself writing more code than I wanted to work my data. Still, I was missing many of the useful capabilities that I was used to from my Silverlight and .Net development.

I quickly realized that what I really wanted was LINQ.  I threw together a proof of concept by implementing select, where, and selectMany.  I found myself using these methods throughout my application.  As I found myself wanting another LINQ capability, I added it to my ActionLinq library.  The next thing I knew: I had a mostly complete LINQ-to-Objects implementation.  A bit more work and I had a complete clone of LINQ-to-Objects.

Aid .Net Developers in Flex Development

I have been preaching lately that Silverlight and Flex developers need to get together and learn from one another.  Where Silverlight has some great features (LINQ is one of them), Flex has some pretty great features as well.  I believe that a library like ActionLinq will facilitate the learning process from Silverlight to Flex by leveraging existing Silverlight knowledge.

Get to Know LINQ

There is no better way to fully understand the power and intricacies of LINQ in Silverlight and .Net than by implementing it on a different platform.  By implementing every function and every overload in the LINQ space, I was forced to understand what everything is used for because I had to write unit tests that gave examples of using the functionality.

Get to Know Flex and ActionScript 3

There is no better way to get to know a new environment than to implement a familiar set of functionality in it.  I was forced to learn about areas of Flex and ActionScript 3.0 that I would not have likely done on my own.  I learned all about functional programming and closures in AS3, unit testing in Flex, the dynamic capabilities of AS3, monkey patching and ASDoc to name a few.  I have come out of the ActionLinq project with a strong understanding of the ActionScript 3.0 language and the more esoteric but powerful features of the language.  I was also painfully made aware of the limitations of ActionScript that I miss from C#: Generics, method overloading, operator overloading, yielding and lambdas to name a few.

Go Use It!

Give it a try.  Let me know how it goes.  Have fun.  Enjoy!

Shout it

Tags: , , ,

13 Responses to “Introducing… ActionLinq”

  1. Introducing… ActionLinq…

    Thank you for submitting this cool story – Trackback from DotNetShoutout…

  2. [...] This post was mentioned on Twitter by billwagner and others. billwagner said: RT @BrianGenisio: Introducing: ActionLinq — A complete LINQ2Objects implementation for ActionScript 3.0. http://j.mp/fsqdy6 #flex #linq [...]

  1. Mike Ward says:

    Cool! Any thoughts about a JavaScript version?

  2. admin says:

    Mike: No, I don’t have any plans to port this to JavaScript. Mostly because there are already at least two implementations available for JavaScrilpt: jslinq and linqjs.

  3. This is great work I’ll let you know what I get up to with it – Thanks.

  4. Marty Pitt says:

    Wow — This is awesome. I’ve been hanging out for a decent LINQ port for a while. Congratulations!

  5. Roland Zwaga says:

    Very impressive work! Ever since I started working in actionscript did I feel the pain of not having LINQ at my disposal, I am very happy to see someone making the effort of porting it.
    Great job!

  6. Jade Freeman says:

    Just wanted to say thanks for the great work! I’m loving it and already using on a couple of projects. I’m also doing a presentation to the Michigan Flex Users Group tomorrow (Thursday 02/010) on what we’ve been able to do with ActionLinq. Thanks!

  7. makc says:

    How would deferred execution work, for example, with .orderBy query? Shouldn’t the whole data source be sorted before I can retrieve a single resulting element?

  8. Very interesting.
    I highly encourage you to create a GitHub respository of this; Git is the standard for open-source sharing and collaboration. Swiz, BabelFx, Flex-Extensions, and tons AS3 libraries are available there. It would be great for me to access yours there also.

    Thanks again,
    ThomasB

  9. admin says:

    @Thomas: The project is in BitBucket which is the same thing as GitHub but for Mercurial. You can create a fork from the bitbucket site: actionlinq.org

  10. admin says:

    @makc: That’s right. Kind of. Deferred execution really just means that the execution is deferred until you need it.

    When you call orderBy(), it doesn’t happen right away. The moment something asks for the first item, it needs to sort the entire chain. This is not usually the case. select() and where() for instance, happen one-by-one and stream through the levels. Since orderBy() requires the entire collection to sort (like you suggested), it will pull everything in through the linq chain and process them. Anything after that continues to be deferred.

    In other words, orderBy() returns an IEnumerable. This means that once the IEnumerable has been returned, the sorting has not happened yet. If you were to call first() on that IEnumerable, it would need to execute everything in order to sort. The execution is still deferred but it needs to know about the entire collection to proceed.

    This is how Linq2Objects in .Net works as well.

    In contrast, toArrayCollection() returns a populated ArrayCollection. This means that the moment this gets called, all of the data is processed. Calls like this (that do not return IEnumerable) are not deferred.

    Does this help?
    Brian

  11. Hi

    I found out of your Class form The Flex Show radio
    Thanks for your great work. I am going to use this from now on my projects.

Leave a Reply