bloggo ergo sum

Lambdas in data-binding expressions

For a recent project, I wrote a templated web part (similar to the Smart Part) to do a search on a custom list and display the results (all using AJAX updates made available by the UpdatePanel), and I found myself unable to accomplish what I needed to accomplish in data-binding expressions inline in the user control loaded by my web part. I needed to be able to do multiple steps to condition the bound data before rendering it (for example, splitting a single field into multiple distinct fields that should be rendered differently).

For example, one of the bound fields I needed to render was a string formatted like this:

"http://www.website.com/page.aspx, Name of the Website"

I needed to render this as a link. Obviously, it won’t directly render properly. It needed to be split, so it could be rendered something like this:

Name of the Website

For this simple example, you can do it all inline without lambdas by taking advantage of the ability to pass an array as a params parameter:

String.Format("{1}",
             1

However, for a more complex case in which the bound data needs conditioning that can’t be done inline, typically you would do your conditioning and rendering in server side code2.

The problem with that is that you then have to write a bunch of methods that kind of pollute your other classes, and your logic is divided (some in the user control, some in a class). Enter lambdas.

Data-binding expressions are somewhat restrctive in that they can only evaluate DataBinder.Eval and DataBinder.Bind. DataBinder is the context of the expression. However, you can create a new context by writing an inline lambda, like this:

() =>
{
  string url =3.  Somehow, we have to cause this method to be invoked.

My suggestion is to write a server-side method for invoking the lambda.

public delegate string DbExprDelegate();

public static string DbExpr(DbExprDelegate lambda)
{
  var obj = lambda.Invoke();
  return obj;
}

To get the type system to go along, you have to define a delegate type for the lambda. In my case, I knew I would be taking no arguments and returning no strings. For more complex cases you may be able to make good use of generics and type inference to write a more useful generalization. Since lambdas are implicitly convertible to compatible delegates, you can then use the static method DbExpr in your data binding expression to invoke the lambda. I defined DbExpr in my web part class, but I could have put it just it just about anywhere because my user control has no reference to the web part object that loads it, which requires my DbExpr to be static. In other contexts where data binding expressions are used, you may have references to instance objects in your context and may not need to make your DbExpr static.

Finally, we now have the plumbing we need to make the data binding expression work:

<%@ Assembly Name="MyAssembly, etc, etc." %>
<%@ Import Assembly="MyAssembly" Namespace="MyNamespace" %>
 
<%#
MyWebPartControl.DbExpr(() =>
  {
    string url = ((SPListItem)Container.DataItem)["WebPage"].ToString();
    string toks[] = url.Split(new string[] {", "},
                              StringSplitOptions.RemoveEmptyEntries);
    return String.Format("{1}", toks[0], toks[1]);
  })
%>

  1. SPListItem)Container.DataItem)["WebPage"] .ToString().Split(new string[] { ", " }, StringSplitOptions.RemoveEmptyEntries []
  2. Of course, the term “server-side” here doesn’t imply that inline expressions are executed on the client – they aren’t. It’s just a way to distinguish between code organized into class libraries and inline expressions embedded into ASP.NET files, like user controls. []
  3. SPListItem)Container.DataItem)["WebPage"].ToString(); string toks[] = url.Split(new string[] {", "}, StringSplitOptions.RemoveEmptyEntries); return String.Format("{1}", toks[0], toks[1]); }

Now you can see more clearly what it is you’re doing, and as an added bonus, you can actually set breakpoints on each individual statement and inspect local variables (an option that’s unavailable with chained expressions).

There’s a problem, though. The result of this expression is a lambda, not a string. When the page is hit and the server tries to compile this, it may fail. Even if it didn’t, the rendered result would not be desirable ((the lambda’s .ToString() method would be called, and the result would be what the end-user would seee []

Chrome OS: Much Ado About Nothing

Folks, let’s don’t get too excited about Google’s announcement of a “Chrome” operating system. They’ve already said that it’s oriented toward netbooks and other entry-level PC devices, and that most of the interactivity will be web-based.

In other words – it’s not a desktop operating system as you understand the term. It’s not going to compete with windows. It’s going to be a glorified browser than doesn’t need Windows to run.

Is that significant? Yes. But it’s not a Windows (or Linux)-killer.

Sololance

I’ve got a full-time job with benefits, and it’s a blessing to me and my family because it allows me to provide for them in full. We want for nothing, really.

However, I do someday want to start my own business. I have some ideas, but it will take time and even if I bootstrap and patiently build something worthwhile, it will still take money. I’ve been looking for small but worth-it side jobs to do to generate a little cash for a new business (e.g., purchase a license for basic developer tools, pay for basic hosting, etc). I’ve registered at a few of these “freelancer” work websites, thinking that if I fish around, I shouldn’t have much trouble picking up a job a month and netting an extra $100 or so to put away for a startup. Seems like a reasonable way to start bootstrapping something, no?

You know the sites: sologig.com, elance.com, guru.com, and most recently, werkadoo.com.

I’m entirely frustrated. Werkadoo looked promising, but since it launched it looks like a huge flop – I can only ever find one job listing, and it’s a very generic “send us your resume and we’ll be in touch” kind of listing. Not only that, but a full membership on Werkadoo costs $20/month. Sorry. Cash flow is the whole reason to do it in the first place, and when I really only envison doing 1 job per month, a cost of $20/month just to be there is not doable. Sologig.com? Just a feeding ground for employment companies and recruiters – which I’m entirely uninterested in. Sologig is a waste of time.

Don’t even get me started on rent-a-coder and get-a-freelancer and the like. Most of the projects are junk, and the employers that post non-junk projects are swarmed by bidders who can’t communicate, have no idea how to bid a project, or both.

Elance.com and guru.com are probably the best remaining options. Both have free membership options, but they limit your ability to bid and communicate with clients. They aren’t as bad as the other sites, but they still have their share of junk projects (you know the kind: “I need a complete clone of eBay for $500″). Those two sites don’t seem too bad, but bidding on a free membership plan is difficult because you’re not allowed to ask questions, and the projects posted are rarely detailed enough to elicit a complete bid. I’m basically structurally unable to compete because I’m not a paid member, but it’s not economical for me to shell out for a paid membership.

The other problem I have is that most of the software development projects are web applications. I’m not incapable of doing those projects (web applications are what I do for a living now), but the ideal project is one for which I can draw on my experience, and most of my experience is in distributed systems, clusters, backend server applications, systems programming, and embedded systems. Those projects are few and far between (and only on guru.com, as far as I can tell).

*Sigh*. Does anyone else have this problem? I want to find small, discrete chunks of work to do to make a little extra cash on the side, and in principle, the freelancing sites seem like a good avenue for finding such work, but in practice, they aren’t working well.

What is a freelancer with minimal availability to do?

A simple weblocks application

Introduction

I’ve been following the Weblocks web framework for about a year now, and it’s my opinion that Weblocks is the best Common Lisp web framework available. One of the difficulties with Weblocks right now is a lack of documentation and example code. This will be a contribution to that need. I have created a simple blog application based on Weblocks. I started with the blog that Evan Monroig put together as a simple tutorial, but wanted to go a little further with it. This will be a multi-part screencast tutorial, but rather than spreading it across multiple posts, I”ll just update this one as I have new material to post. I apologize in advance if there are very dry moments in these videos; I’m new to screencasting and am using free tools. You get what you pay for :-)

So let’s start…

Setup

I use the Linux-Emacs-Slime-SBCL stack for the screencasts.  Slime, Emacs, and SBCL are functional on Windows, but I don’t know that Weblocks (or, more importantly, it’s dependencies) will.  I haven’t tried.  I prefer Franz’ Allegro Common Lisp, but Weblocks is targeted specifically at the Hunchentoot webserver. There is a very good Lisp environment screencast by Marco Berringer, and an accompanying reference by Peter Christensen.  I highly recommend them for learning more about how to get your Lisp environment set up. There are many other references on the web that will help you with getting Lisp set up on your machine.  I use the Gentoo distribution of Linux.  Gentoo has a very good package management system called “Portage”, which works something like the FreeBSD/OpenBSD ports system, but better (there are also drop-in replacement systems that improve on Portage in different ways, but I haven’t had a need for them; Portage works just fine for me).  One of the more recently developed features of Portage is the concept of “overlays”, which provide the ability to more easily customize the set of packages available at a particular location or over a particular subset of categories.  There is a Common Lisp overlay that provides fairly up-to-date releases of most of the useful Common Lisp libraries available (the overlay contains 200+ ebuilds), and I’ve found that to be adequate for my needs.  Thus I avoid all the teeth-gnashing over Lisp library management and installation. For me, I just needed to install Emacs, Slime, paredit, SBCL and finally Weblocks (which pulls in a lot of other libraries as dependencies) through the portage system.  The only thing I needed to do to make things work was to edit my .emacs and .swank.lisp files.   My .emacs file needed this:

(load "/usr/share/emacs/site-lisp/site-gentoo" nil t)

and my .swank.lisp (the user lisp initialization file for swank, the Slime backend).

(defun project-setup ()
  (mapcar #'(lambda (path)
              (push path asdf:*central-registry*))
          '(
            #p"/home/bc/proj/weblocks-dev-aggieben/"
            #p"/home/bc/proj/simple-blog/"
            )))
(project-setup)

As you can tell (hopefully), the PROJECT-SETUP function merely adds my local project directories to the ASDF path so I can simply use (require :simple-blog) to load my application (SBCL’s REQUIRE function uses ASDF to find packages). The two directories I’m adding to the ASDF path are key to this tutorial:  I am a Weblocks contributor (barely), so I run a local development version of Weblocks in my project directory.  Most users can just install Weblocks however is best supported by their Linux distribution, through ASDF-INSTALL, or manually.  This tutorial was created and tested on the latest development version.  It may or may not work on the last stable (0.8, I think).  Also, I added the ‘simple-blog’ directory to the list because that’s where we will create our application.

Creating a Weblocks Application

After making sure my Lisp environment is set up, I can start everything up:

At this point, we have the skeleton of a Weblocks application. It only writes a little text on the site, but all the plumbing is in place. Since we’re building a blog, we need to design a simple object model to represent it:

Now we have our object model in place and have shown how to use gridedits and default views for viewing and data entry, as well as the limits of the default views. In order to successfully input data, we need to customize the form views:

Now that we have data entry working, we need to build more interesting pieces of our blog. Firstly, how do we display a post to a user? We can write a custom widget to do that:

We’d like to be able to show more than one post to a user. We’ll construct a custom widget to represent the blog itself:

Check back for updates….when I get time, I’ll post screencasts to demonstrate further improvements to the blog, including graphical styling, navigation, author login, and tags.

Client Perspectives

I’ve been trying to write a web application in my free time. It’s been going on at varying degrees of intensity for months now, and I’ve got virtually nothing to show for it. Part of that is due to a lack of time to devote to it; at best, I can add 2 hours to the top of my day by getting up early.

But the point of the post is really the other compounding factors that the various technologies impose on me, and how that relates to the client perspective in typical contracted software work.

My day job involves almost exclusively Microsoft technology; .NET in particular. We use Sharepoint to build client intranet applications, do custom C# development, etc.

In my hobby projects, I tend to play on a Linux platform with Lisp or C++ (although I certainly am no stranger to the Windows platform or other languages). The webapp I’m working on has been based on Weblocks, a continuations-based web framework for Common Lisp. I have an idea of what I want it to be and do, but Weblocks isn’t well documented and I’m not very experienced with it yet, so I come to it asking this question:

what can I do?

The framework is also pretty liberal, so even once I know what it provides, I still have the same question because the possibilities are limitless. In a way, this expanse is paralyzing: I have to spend a lot of cognitive energy figuring out among the zillion design choices at each step, in addition to learning a technology I’m inexperienced with. Consequently, it takes a really long time to get something working. However, once it starts to roll, it can roll fast because once I’ve made my design decisions and worked out my requirements (informal as they may be), I understand where I’m going and generally how to get there.

I have another hobby project, a Git client for Windows built in WPF and C#. With that project, I ask a different question:

How do I do that?

This is because of the nature of the platform. True of closed, proprietary platforms in general, but in particular of comprehensive frameworks like .NET, most of the design decisions have already been made. I don’t have to choose among the zillion ways to render a components in HTML/CSS/Javascript and process user activity – there’s already a mechanism just for that in ASP.NET called “web parts”. I don’t have to make a hundred design decisions about the desktop GUI framework to use and how to use it or roll my own or extend one, etc, because the Visual Studio and Blend designers support WPF. With this platform stack, the tradeoffs are reversed: I can get rolling on a project almost immediately, but at some point, things get really hard because of the box you find yourself in down the road (and at least part of the box is hidden from you because of the proprietary nature of the stack – the Sharepoint object model is a perfect example because it sucks). I once worked on a system that had it’s own threadpool because the .NET threadpool didn’t perform well enough, for example. That was not a quick project.

What struck me about this contrast was that I found myself empathizing with the position of a client.

As in the first case, the possibilities are endless – unmanageable – at first, and I didn’t know what I wanted, and nobody was there to tell me – but later on, the freedom in those design choices was favorable.

In the other case, I had some very concrete ideas about what I wanted because the technology limited my choices, but those limitations created pain points later on because they became very confining.

Conclusion? I don’t know, really. Each position has it’s advantages and drawbacks. I tend toward the former as a craftsman, but toward the latter as a consultant for a variety of reasons, including market inertia.

Continuations

By training and experience, I’m largely an object-oriented programmer. I was a freshman comp. sci. student when the Java wave hit my university, so that’s what I was fed. I didn’t learn anything else but Java until the summer after my sophomore year; then, I was involved in a summer research program for which I used C++. Between then and the end of my undergraduate tenure, I had picked up more C++ and learned C (I should add here that my department was and is a very good c.s. department – they just didn’t use functional languages as teaching tools).

Where did that leave me? I knew how to write nice object hierarchies, tight structural/procedural code. However, Boost wasn’t a big deal yet, and I had only barely dabbled in anything else, so I was missing a huge piece of the puzzle: functional programming. I used lisp for a couple of programming assignments in graduate school because I wanted to learn the language – and I did learn the basics, but what I didn’t learn was important functional concepts.

Now, as a working professional programmer, I’m still trying to learn functional concepts. Some are pretty easy: immutability and recursive computation. These are very basic – even recursive functions were taught in Java programming classes.

But the most interesting element of functional programming is higher order functions, which are the basis for some very powerful forms of abstraction. This is what I was really missing in my repertoire.

So now, the point: I’ve been trying to learn a web framework called Weblocks. It’s freaking cool – but it makes heavy use of continuations for control flow (one of its major features). I had never learned about continuations before, so this was (and still is, to some degree) making it hard to learn the framework. So I was reading about continuations online (here ,here, and here) and came across a reference to Paul Graham’s book, On Lisp. I have a copy that I printed for myself, so I looked up the chapter on Continuations to gain some insight, and found the best explanation I’ve seen so far:

A continuation is a function representing the future of a computation. Whenever an expression is evaluated, something is waiting for the value it will return. For example, in

(/ (- x 1) 2)

when (- x 1) is evaluated, the outer / expression is waiting for the value, and something else is waiting for its value, and so on and so on, all the way back to the toplevel…

We can think of the continuation at any given time as a function of one argument. If the previous expression were typed into the toplevel, then when the subexpression (- x 1) was evaluated, the continuation would be:

(lambda (val) (/ val 2))

That is, the remainder of the computation could be duplicated by calling this function on the return value.

I found the little example shown here to be the best way try to explain continuations. Trying to understand the applications of continuations is a beast, and without this basic understanding it’s very easy to get lost.

Now…back to Weblocks…

Visual Studio is a Pretender!

Can I just rant at you for a minute, gentle reader?

The editor in Visual Studio is from the stone ages. Really – it’s retarded (I don’t mean that in a derogatory sense – it really is retarded).

Sure, it does syntax highlighting, but really….so do the little code-paste tools like pastebin, and those little tools highlight for dozens of languages, so color me unimpressed.

Intellisense? Yup – very nifty, very advanced – oh, wait! Lisp environments have been doing “intellisense” for years decades.

What else….let’s see….feature or failure?

Visual Studio characteristic Feature/Failure Notes
consistency of indentation FAIL ever tried to use another editor to open files authored in Visual Studio?
efficient keyboard shortcuts FAIL the most often used shortcuts (navigation in text, for example) require me to move my hand off the home row
automatic indentation FAIL Are you kidding? Only if you happen to be typing in a magical combination of keystrokes that Microsoft decided was the one true way to type will auto-indentation be convenient.

These are just some very basic, fundamental things, and this list could go on – indeed, I might come back and add to it as I become more proficient with Visual Studio. As an experienced Emacs user, it’s quite painful. I tried to use the Emacs keyboard mode, but it was even more maddening than the other modes – they get the keystrokes wrong, and even when they get them right, they don’t work correctly! C-k is supposed to kill a line, but you have to type ‘k’ twice for the kill to happen, and if you try to yank it back in using C-y, you get the killed line twice! M-q doesn’t work, you don’t get registers, typing on top of a highlighted region doesn’t replace, it appends, and ‘C-x b’ doesn’t switch tabs in the editor.

For all the wonders of a modern IDE, can we just please, please have an editor that’s advanced past 1985?

Crack in the ‘Golden Spike’

I love the description Marty Manly uses over at ‘Jam Side Down’:

So you have Google with all the software needed to replace Outlook in every respect except syncing contact and calendars to an iPhone or a Blackberry and you have Apple with a great device and an opportunity to wean thousands of small and mid size companies off of Exchange offering an inadequate alternative to Exchange. Neither company has built a solution for real users. It’s as if the railroads had decided to end their tracks about a 100 yards from each other rather than meeting at Promontory Point and driving the golden spike. Dumb.

He’s soooooo right. Why can’t Apple support all the Google APIs that correspond to the functionality in Exchange server? It’s all there and free to build against, and for a small business, Google Apps + iPhone (with Google support) would be absolutely killer. I switched from a Blackberry (Pearl) to the iPhone 3G, and I’ll never look back, but having calendar, contacts, and mail all synced to my phone is just huge.

However…

I just got bombed in the way Marty says isn’t possible: Nuevasync stopped working correctly for me. It fails to synchronize my contacts, reporting that my google account has corrupt data. They advised me to export all my contacts, delete them, and re-import them. I followed the instructions and didn’t read the fine print: Google contact export doesn’t retain grouping metadata, so if you do what I did and just export ‘All Contacts’, you lose group metadata. Losing track of your groups is bad enough, but also: all your ‘Suggested Contacts’ also become ungrouped, so I had 500+ contacts, more than half of which were junk.

Anyway, after I re-imported my 500+ contact list (with no groups), Nuevasync still doesn’t work. I emailed their support address, and I got a form reply (which is typical, no problem there), but after several days, I didn’t get any further response from a staff member, so I emailed back again, and I still have yet to hear from them. In the meantime, I have zero contact data on my phone because all my contacts were previously synchronized (which was fabulous!).

I really just don’t know what to do at this point. I don’t want to switch to GooSync because a) it isn’t free, and b) there’s no way to try before you buy, and it looks like you have to download a special iPhone app for syncing. Does that integrate well with the Apple Contacts and Calendar apps? It doesn’t look like it from what I can tell, but….I can’t really tell unless I fork over $15 for the iPhone app and £20 for the SyncML service.

I really just want Nuevasync to help me, because their service worked like a charm up until this point.

Update: Through a comment on their blog, David indicated that there will be some kind of support in the status pages to help pinpoint exactly what data isn’t parsing correctly in the sync.

Lisping in Bed

I happen to have an ssh client on my iPhone 3G, and while I was in bed the other night I thought to try and log in to a box, fire up emacs and get a slime repl. It worked great, as you might expect, but it was still amusing.

My Hiatus

Dear readers (all none of you), I’ve been away from my blog for a while now because of life circumstances that required my attention to be invested elsewhere. Hopefully, I will now be able to post something on a semi-regular basis. To explain somewhat:

I worked at a rather large defense contractor as a software engineer. I shan’t mention the name for a number of reasons; one being for my own protection; another being to make at least a nominal effort to not burn bridges.

The work was mostly rewarding. The technology there is quite interesting; in it is an intersection between technology that the commercial sector left behind, technology they’ll never have (with a few exceptions, like some of the more interesting telecoms). Even when compared to the telecoms, there is a segment of the tech there that will never see the light of day. As you might expect, there are both frustrations and excitement involved. For the second half of my tenure there, I began to be seriously frustrated with the corporate culture there; part of it was simply the reality of working for a giant company, and part of it was simply the reality of working for a defense contractor (which makes it like working for two giant companies simultaneously). But there was a third major part of it that was really starting to bother me: I was never going to be deeply involved in the essential business there, and thus my ability to do things I want to do in my career would be artificially limited. That company was a systems integrator, not a software company. To be sure, there were lots of interesting software projects, but that wasn’t the company’s essential business; more like a value-added service that went along with the main business.

There were other secondary issues as well. Most of that didn’t have to do with other people, except as it related to the environment and corporate culture. There were financial incentives to leave as well.

So I stuck to my work, and didn’t talk about leaving and kept it a secret that I was looking. I wasn’t looking hard, though. I was passively observing the local tech market, looking for a landing pad. I interviewed a couple of times, including once with a premier Valley firm. Ultimately though, I decided I didn’t want to become a Californicator. There were a couple of potential openings that I found through personal contacts, including one with my brother at his trading firm in New York. I pursued that option for a couple months and had it all settled out, and the credit market problems ended up closing that door for me. I went back to my contacts again, and it turned out that the timing was just right for me to join up with a small .NET/SharePoint consulting firm in Dallas, called Cogent, with whom I now work.

One of the benefits of working for Cogent is that they encourage the developers to write blogs and articles, because it increases their exposure, so I hope to be able to post at least a few times a month on topics of interest to me.