Leaving .NET

I have been thinking about my programming past a little bit recently, and while I never really "left" .NET exactly, it did kind of start fading out of my day-to-day.

I started my first real programming job doing .NET apps for a company that was writing apps for dealing with medical record request and receipt. I got a lot of experience at that job, and when it came time to cut code for my first startup we used .NET becuase I knew it well.

Fast forward a bit and I took on some consulting work using Microsoft CRM. I wrote a whole blog about that, and it gets a lot of traffic even today.

However, as time wore on and I moved to Silicon Valley, it became apparent that I needed to do a lot more work learning things like Node.js and Clojure. Diving into JS even deeper than I did in my startup. I got to work on this stuff, and slowly the .NET bug started fading away.

I don't think that .NET is particularly bad, but occasionally I'm reminded of why it is a little awkward in this day of open source software. Check out this article for some good points on leaving .NET.

Thoughts on software complexity

I ran across a comment on Hacker News just now that kind of ties into some things I have considered in the past on my other blog in a post called "That pesky bug"

In that post I talk sort of obliquely about an experience that I had writing the HN Plonk project. While developing that project, I really tried to keep it as simple as possible, but things kept popping up that complicated it. Even though it was only a few hundred lines of code it started to get messy in some places.

I got called out for being a little bit vague in that post, so in the comments I went into some details on what I was really writing about:

The bug in the script that annoyed me was that when I hit the bottom of the list, the check for whether the end has been reached is not correct. If it was designed correctly it should be trivial to add the check without breaking anything else. But stupidly, the code for highlighting the items is part of that code, so I end up with another more annoying bug where the last item is ‘stuck on’ and highlighted until you move down to it.

 The  HN comment is from someone that is building an app from the ground up and hasn't had any deadline pressures or outside concerns to deal with. However, he writes the following about how it has affected the complexity of the code:

It's amazing to me how little any of this has helped with the fundamental problems. The code is better, the parts of the system that need to be optimized are optimized but the screaming at the code is still there. The "how did things reach this state is still there".

The idea is that complexity happens through the effects of many small unintended consequences. In other words, simplicity is a feature all on its own.

Rebinding variables and functions in Clojure

I'm working on writing some tests for some Clojure code, and I was wondering just what the TDD landscape looked like. I was trying to replace a few functions with stubs, and I figured I'd rewrite some things to do a kind of depenency injection.

It turns out that DI seems to be a dirty word in the Clojure community. However, I'm seeing some opportunities to do things like pass the implementation of something as a function like we would in Javascript or Ruby.

I started doing this, but later I found out that you can dynamically rebind a function using

 

(binding [old new] ... )

In theory this lets you call the enclosed code having replaced the method completely in the called code. In practice, since the target code was not marked as dynamic this doesn't work.

To explain what I'm talking about, let's go to the clojure REPL:

 

user=> (defn foo [] "bar")
#'user/foo
user=> (foo)
"bar"
user=> (binding [foo #(str "blaz")] (foo))
IllegalStateException Can't dynamically bind non-dynamic var: user/foo  clojure.lang.Var.pushThreadBindings (Var.java:339)

So this won't work as-is. As a side note, I'm not sure why I need the (str) function here, since we can ordinarily return a string from a function without anything special. For some reason, in an anonymous function like this we need some enclosing function to return a single string.

If you hadn't already guessed, the answer to our problem here is to use a compiler hint to mark the def as dynamic like this:

user=> (def ^:dynamic foo (fn [] "bar"))

Then the previous binding attempt will work:

user=> (binding [foo #(str "blaz")] (foo))
"blaz"

The Web browser as transitional technology

I recently came across a talk that espoused an opinion that I've been forming over the last year or two. That is, that the Web browser as we know it is just a stepping stone on our journey on the Web.

Ever since I got my Palm Pre back in 2009 I was totally enamored with the idea of HTML as a first class citizen of the OS, with system services implemented as web services.

REST is becoming the ubiquitous RPC mechanism of choice, and for ages, browsers' own UI has been implemented in itself essentially, like a Lisp implementation.

There is no question that these technologies are powerful enough to replace most of what we do using cumbersome native frameworks. The question is, how is this transition going to take place?

I think that the monolothic Web browser is going to have to break up into a set of service providers that can be incorporated as system-level services. I don't think we should go as far as Microsoft went with http.sys (this caused all sorts of issues, having http implemented at the kernel level). However, I think that by treating browsers as a set of components that can be used (see the Unix philosophy) and reused, we can take the Web experience and itegrate it more seamlessly into our devices and user experiences.

The idea that mobile, and by extension, the Web, is going to be more of an assistive, augmentative technology in the fugure is correct in my opinion. We are going to need more flexible tools to make this a reality. Currently native apps get us part of the way there by providing a more immediate interface to the desired content, but this again only takes us part of the way. Apps aren't reactive and dynamic the way the Web is. Apps must be downloaded, upgraded, and maintained by the device. Web apps are dynamic, ephemeral sometimes, and like the ether - transforming to the task at hand, updatable immediately by their mantainers by just tweaking some code on the server.

I'm rambling a little bit now, so I'll leave you for now with these ideas. There are some good things afoot I think.

Amazon AWS availability zones

I'm using EC2 for a few things these days, and I came across something that I didn't realize was an issue until now.

I tried to launch an EC2 instance of Ubuntu from the official ubuntu AMIs and I couldn't figure out why I wasn't seeing the image when I searched for it.

I was able to use the shortcut link on the Ubuntu Cloud site, but I couldn't find it by searching. When I launched the instance I didn't see any of the keypairs that I use for authentication listed. I had to create a new keypair. Once I launched, I didn't see any of my other instances running.

What is going on?

I fired up my other browser window and figured out that I was in a different region in the other console. I launched my new instance in region "US West" and my other instances were "US East".

I remember this being an issue with EBS volumes. You couldn't mount a volume in one region on a server running in another.

 

Exception logs for Clojure code running under Apache Tomcat

Despite the rather specific title of this post, the following information applies to just about anything running under a Tomcat server. Normally we'd like to use Log4j for any serious logging, but occasionally we just need to know what is going to the console.

Tomcat 6 logs the console out to

/usr/local/tomcat/logs/catalina.out

So when you are running Clojure code under something like ring you can see the console output. The catalina.out file will display this same information.

Beating RSI injuries

Every once in a while something comes up about RSI injuries in the programming community. There is an article on Hacker News right now about it.

I've suffered through some rough stretches with RSI and I've managed to treat it and avoid it so I thought I would write some of my thoughts on it here.

I'd like to say that there was one thing that worked for me, but in reality I think that it took a wholistic approach to things. I do use a combination of hand exercise props and ergonomic keyboards, but over time I have been able to go back to using my laptop keyboard for weeks at a stretch without any problems.

I think the key is body awareness, and perhaps mental awareness. When you start getting extremely tired, you are more likely to have bad posture and ignore warning signs that you need to take a break. Paying attention to warning sigs is crucuial I think. Even with good posture and ergonomics there are times when my hands just say "I'm getting tired." When I notice this I stop typing and stretch my hands a bit. Sometimes I use my Chinese iron (Baoding) balls (I love these by the way, they are my hand exerciser of choice).

I change up my work location often. I stand at a standing desk sometimes. Sometimes I sit on an excercise ball or on the floor. Mostly I'm typing on my laptop keyboard, which I used to swear was the cause of my issues to start with.

I pay attention to actions that I take repetitively that are especially straining. Sometimes in an app you notice yourself running a "mouse marathon". Some action requires a long series of mouse-intensive actions. The scroll wheel is especially nefarious I think. Taking some time to pay attention to how some action can be optimized can really pay off. Learn a keyboard shortcut for what you want to do. Write a little script maybe, or if you are not a programmer, maybe something like AutoHotKey could do the trick for you.

Lately I have been noticing that my left hand is getting tired before my right, even though I use my right hand on the Trackpoint device on my Thinkpad laptop. My suspicion is that the alt-tab key combination is causing my hand to make an awkward pinching motion where my thumb has to tuck underneath my hand slightly. I'm working on retraining myself to use two hands for this motion, with the right hand hitting the right alt key and the left hand hitting tab.

The aforementioned example illustrates part of what I'm talking about when I say "awareness", Just paying attention to how you work in a physical sense. It could be a matter of batching tasks also. For example, taking a programming task and sandwiching it between something that requires less typing. Maybe a research task. This is not always feasible, since you want to be productive in the time that you are working, but it's worth thinking about for a minute to see of you can schedule your activities to accommodate your physical being.

I see this article about the "Mindbody Prescription" mentioned a lot when the issue of RSI comes up. I think that this is kind of bunk as it is written (thinking away physical pain), but if you flip it around to be more about avoiding the pain in the first place by thinking about what causes it and unconsciously developing and testing hypotheses about what your pain points are, I think the idea of "mind over matter" starts to make a lot of sense.

I don't think any one thing will work for everyone. Just in my own life, observing the people that I know, I see lots of variations in the way people interact with computers. So, everyone is going to have their proverbial Achilles' heel when it comes to RSI. To find yours, I think you just need to pay attention.

Using sudo to run command as another user (not root)

I was wondering if it was possible to use sudo more generically to allow some otherwise unprivileged user to run a somewhat more privileged operation that doesn't require root. Maybe logging into a database administratively.

It turns out (unsurprisingly) that you can do just this. Check out this blog post.

 

Here is the example given:

Cmnd_Alias DBcmd=/usr/local/bin/dbstop.sh,/usr/local/bin/dbstart.sh
Runas_Alias  DBAUSER=dba 
monitor     ALL   = (DBAUSER) NOPASSWD: DBcmd

Enjoy!

Running Clojure code using Cake as an alternative to Lein

In the Clojure world, Leiningen is your main tool for managing projects. It handles the Java classpath, dependency management and resolution, running tests, and running the repl. Basically you are dead in the water with Clojure without Lein. You'd have to set up the classpath yourself and make sure that all of the dependencies were already downloaded from Clojars. While this is certainly possible to do manually, it's not advisable.

However, the main problem that I have with Lein is its speed. Well this is not really an issue with Lein so much as it is with the JVM itself. Any time we want to do something with Lein it requires us to spin up a JVM instance, which takes a little bit of time. When we want to iterate fast and run tests quickly this can become a drag. One of the nice things about using a dynamic language like Clojure is that it reduces the cycle time during development. Unfortunately you only realize that when you are coding mostly in the repl.

I started looking at Cake becase it lets you reuse a running JVM rather than spinning up a new one each time. Cake does most of what Lein does but in slightly different ways. One thing that I need to do often is run the main function of a project. In Lein there is a convention for the main function, which is to define the function like this:

(ns mynamespace)
(defn main- [] ())

In order to run this, in the project.clj file we'd specify the class that we'd like to run:

:main "mynamespace"

Then

$ lein run

Will run the main- function in the class specified in :main.

With Cake we can tell it to run any file by saying

$ cake run file.clj

However in order to run the main function we can say:

$ cake run -m file.clj

As far as I can tell, cake doesn't look at the :main in project.clj at all.