Jason in a Nutshell

Jason in a Nutshell

Jason Baker  //  Just another random geek. Visit my homepage at http://jason-baker.com

Follow me on twitter: http://twitter.com/jasonsupdates

Sep 1 / 11:34pm

Choosing sides

Because you don’t need to own the universe. Just see it.  To have the privilege of seeing the whole of time and space… that’s ownership enough. -The 10th doctor

Very few quotes have summarized the fundamental differences between the left brain and the right brain as succinctly as the above quote. And yet, even though the difference can be summarized pretty nicely in a few sentences, there are a lot of misconceptions about the differences between the left brain and the right brain. The thing that makes these misconceptions so hard to break is that they’re just like most other forms of pop psychology: just accurate enough to be tricky.

Google would be jealous

Before I can get into those misconceptions (and what reality is), there’s something you need to understand about the brain. We tend to think of the brain as a biological microprocessor, but that’s not quite accurate. You see, a microprocessor has pre-defined subsystems with very well-defined tasks. The brain is much more sophisticated than that. A better analogy is to think of the brain as a biological cluster of computers (or probably more accurately, a biological cloud). Although you do have subclusters that handle specific segments of functionality, there’s no reason why they have to be dedicated to that task.

As it turns out, the brain is amazingly adaptable. In fact, your brain can and does spread tasks out to parts that we don’t generally associate with handling those tasks.

If it sounds like your brain is chaotic, it’s because it is. The different parts can even work at odds with each other some times. To deal with this, your ego tends to favor certain parts of the brain more than others. Generally, you favor a specific hemisphere over the other. In fact, you even favor a specific portion of a specific hemisphere. But that’s the subject of another blog post.

The left brain is logical, the right brain is creative

As it turns out, the information that I gave in the last section was quite a revelation to neurologists within the last couple of decades. Up until that point in time, they thought that the brain had a strict division of labor. It was thought that the left part of the brain handled logic while the right part of the brain was creative. If you wanted to be more creative, you needed to develop the right brain. If you want to be more logical, you need to develop the left brain. As a right-brained thinker, I’m living proof that the right brain is every bit as capable of logic as the left brain. It just tends to be a different kind of logic.

As it turns out, the two hemispheres can do mostly the same things. In fact, what we refer to as the “left brain” might not physically even be the left hemisphere (if you’re a lefty, there’s about a 70% chance of this!). The point is, there isn’t any reason why the left brain can’t do the things the right brain does and vice versa. However, these two hemispheres do tend to “specialize”. See, the brain is capable of rewiring itself. This is part of the process of learning. As one hemisphere does one task, it rewires itself so it can do that task better in the future. Thus, you do see differences emerge between the two hemispheres. These differences are developmental rather than biological though.

So what IS the difference?

If you’ve ever taken a personality test, you got back a four-letter code ending in J (for judging) or P (for perceiving). Most of the ideas that these tests are based on come from CG Jung. Jung said that judgers like to plan ahead of time and perceivers dislike to have their future mapped out ahead of time. The technology didn’t exist at the time for Jung to realize this, but he was essentially describing the difference between the left brain and the right brain (albeit with a somewhat primitive understanding).

Let’s go back to the Doctor Who quote I presented at the beginning of this post. In this scene, the Doctor (a perceiver) was talking to the Master (a judger). You see, the Master had a goal: complete domination of the universe. The Doctor never really has any explicit goals that he sets ahead of time. He sort of just bumbles around the universe until he runs into trouble. This illustrates the major differences between the left and right brain, but there are still others.

The forest or the trees?

Left-brained thinkers think very linearly. They tend to divide the topics up into individual parts and consider them one by one before considering the big picture. They may be seen as “not being able to see the forest for the trees”, but that isn’t strictly true. It’s more that they just haven’t moved from considering the parts to considering the whole.

Right-brainers might be seen as being “big-picture” oriented, but this isn’t necessarily true either. Distinguishing parts from the whole is a distinctly left-brained way of thinking. The right brain is probably better thought of as being “whole-picture” oriented. While right-brained people might start from the standpoint of the overall picture, you’ll notice that there are certain details that they just won’t let go of.

Experience vs instruction

Left-brained thinkers tend to do very well in school as our educational model is very much aligned with how they think. The model of listening to a lecture and reading an assignment fits very well into their mode of thinking. Left-brainers don’t really need experience to go about their tasks. But they do need instruction. They can follow instructions very well, but they don’t do very well when instructions are poorly defined or when the situation changes in such a way those instructions didn’t anticipate.

Right-brained thinkers do need experience. Until they’ve actually tried something once or twice, they have no frame of reference no matter how much instruction they get. In fact, they will usually feel as though instructions are boxing them in and limiting their options. However, (much to the chagrin of their left-brained counterparts) they are good at improvisation. They’re good at reacting quickly when plans become inadequate.

Conclusion

There’s a lot more to be said on this subject, but hopefully this should be a good outline of the differences between the left brain and the right brain.

Filed under  //  psychology  

Comments (0)

Jul 17 / 6:52pm

Python metaclasses in depth

Metaclasses have a reputation for being among the blackest of Python’s black magic. As it turns out, they’re actually pretty simple, but they require you to understand some concepts. There are two ways to learn metaclasses in Python:

  1. Skip the details and get straight to a useful implementation of a metaclass.
  2. Understand the core concepts behind metaclasses.

Number 1 is useful, but will only get you so far. If you really want to understand metaclasses, you need to take approach number 2.

With that in mind, I’m going to start with the basics of how classes are constructed in Python. Let’s consider the following class:

class SomeClass(object):
     x = 1
     y = 2

If you’re ready to learn about metaclasses, the above statement shouldn’t require much thought to understand. But let’s stop to think about it a bit anyway. In Python, everything is an object. Therefore, classes are also objects. But if SomeClass is an object, it must be an instance of some class. Let’s find out what that class is:

>>> type(SomeClass)
<type 'type'>

So apparently, it’s an instance of type. We just saw the most common usage of type: to query an object’s type. But have you ever read the help on that function?

>>> help(type)

Help on class type in module __builtin__:

class type(object)
 |  type(object) -> the object's type
 |  type(name, bases, dict) -> a new type
 ...

So it turns out that type is not only a builtin function, it’s also a class! How do we instantiate an instance of type? You’ve already seen the most obvious way: using a class statement. But did you know that you can create a class using type?

SomeClass = type('SomeClass', (object,), {'x' : 1, 'y' : 2})

For all intents and purposes, the above statement is equivalent to the prior definition of SomeClass. But this way is ugly and isn’t used very commonly. That said, we’ve demonstrated something: type isn’t just any class. It’s the class of classes. It’s a metaclass.

Let’s go a step further though. How does the compiler generate the dictionary that’s the third argument to type? As it turns out, classes have something in common with functions: they have local namespaces. You might have seen the locals function used like this:

def some_func():
    x = 1
    y = 2
    print locals()

If you execute this, the output is this:

>>> some_func()
{'y': 2, 'x': 1}

If classes have their own namespaces, then they must also be able to use the locals function as well:

>>> class SomeClass(object):
...     x = 1
...     y = 2
...     print locals()
...
{'y': 2, 'x': 1, '__module__': '__main__'}

The only difference here is that the namespace is generated at import time and passed into the type function.

So this is all interesting, but we haven’t really seen anything terribly useful yet. Let’s go further. We’ve seen that type is the class of classes. But if type is a class, then we must be able to subclass it. There are a number of reasons you might want to do this. For instance, you may sometimes want to attach a property to a class rather than to an instance. Let’s do just that:

class SomeMetaClass(type):
    @property
    def z(self):
        print 'In class property z'
        return self.x + self.y

>>> SomeClass = SomeMetaClass('SomeClass', (object,), {'x' : 1, 'y' : 2})
>>> SomeClass.z
In class property z
3

But we don’t want to use this same ugly notation for creating SomeClass. Python provides syntactic sugar for this. We can instead define SomeClass like this:

class SomeClass(object):
    __metaclass__ = SomeMetaClass
    x = 1
    y = 2

A more common use of metaclasses is to create a class constructor. Let’s attach z to the class directly rather than defining a property:

>>> class SomeMetaClass(type):
...         def __init__(self, name, bases, dict):
...             self.z = self.x + self.y
...
>>> class SomeClass(object):
...         __metaclass__ = SomeMetaClass
...         x = 1
...         y = 2
...
>>> SomeClass.z
3

As we can see, we’ve defined a constructor for SomeClass. Now let’s go a bit further. What if we want to change the base class of SomeClass? That can be done, but we have to use a __new__ method. I’m going to presume that you know a bit about __new__ methods. If you don’t, you might want to read up on them.

>>> class SomeMetaClass(type):
...     def __new__(cls, name, bases, cls_dict):
...         new_cls = type.__new__(cls, name, (dict,), cls_dict)
...         return new_cls
...
>>> class SomeClass(object):
...     __metaclass__ = SomeMetaClass
...     x = 1
...     y = 2
...
>>> x = SomeClass()
>>> x['foo'] = 'bar'
>>> x
{'foo': 'bar'}

That should hopefully give you an idea of what metaclasses are and how to use them. If you’re even more lost than you were before, don’t worry. This is just one of those things that requires an “aha!” moment. You might also want to check out Michael Foord’s great Meta-classes Made Easy for a different perspective.

Filed under  //  metaclass   object oriented programming   programming   python  

Comments (1)

Jul 15 / 8:17am

How Celery, Carrot, and your messaging stack work

If you’re just starting with Celery right now, you’re probably a bit confused. That’s not because celery is doing anything wrong. In fact, celery does a very good job of abstracting out the lower-level stuff so you can focus just on writing tasks. You don’t need to know very much about how any of the messaging systems you’re using will work. However, to truly understand celery, you need to know a bit about how it uses messaging and where it fits in your technology stack. This is my attempt to teach you the things you need to know about the subject to be able to make everything work.

Messaging

At the very bottom of celery’s technology stack is your messaging system, or Message Oriented Middleware in enterprise-speak. As of this writing, there are a couple of standards out there in this market:

  • AMQP – A binary protocol that focuses on performance and features.
  • STOMP – A text-based format that focuses on simplicity and ease of use.

Of course, there are a lot more players out there than just this. But these are the two protocols that are the most important to celery.

Now, a protocol is totally useless without software that actually implements it. In the case of AMQP, the most popular implementation seems to be RabbitMQ. The popular implementation of STOMP seems to be Apache ActiveMQ.

Carrot

A good analogy that I think most people can wrap their heads around is the SQL database. STOMP and AMQP are like SQL, while RabbitMQ and ActiveMQ are like Oracle and SQL Server. Any one who has had to write software that works with more than one type of database knows how challenging this can be. Sure, it’s easy to issue SQL commands directly when you just support one type of database, but what happens when you need to support another? One possible solution is to use an ORM. By abstracting out the lower-level stuff, you make your code more portable.

The first thing most ORMs do is provide an abstraction to write SQL queries. For instance, if I want to write a LIMIT query for SQL Server, I would do something like this:

SELECT TOP (10) x FROM some_table

Oracle’s query would look something like this:

SELECT x FROM some_table WHERE row_num < 10

These are different queries, but they are both doing the same basic thing. That’s why SQLAlchemy allows you to write the query like this:

select([some_table.x], limit=10)

This is the functionality that carrot provides. Although most messaging systems are fundamentally different in a lot of ways, there are certain operations that every platform has some version of. For example, sending a message in STOMP would look like this:

SEND
destination:/queue/a

hello
^@

AMQP’s version is binary, but would look something like this in text format:

basic.publish "hello" some_exchange a

Since we don’t want to worry too much about these protocols at a low level, carrot creates a Publisher class with a “send” message.

Celery

Carrot makes it so that we can forget about a lot of the lower-level stuff, but it doesn’t save us from the fact that we’re still working with a messaging protocol (albeit a higher-level one). Going back to the ORM analogy, we can see the same thing happening: we need a layer of abstraction to make dealing with different implementations of SQL easier, but we don’t want to write SQL. We want to write Python (or whatever your language of choice is).

Thus, ORMs will add another layer of abstraction. Wouldn’t it be nice if we could just treat a database row as a Python object? Or, in the case of task execution, wouldn’t it be nice if we could just treat a task as a Python function? This is where celery comes in. See, we could run tasks like this:

  1. Process A wants to run task “foo.bar”
  2. Process A puts a message in queue saying “run foo.bar”
  3. Process B sees this message and starts on it
  4. When done, Process B replies to Process A with the status.
  5. Process A acknowledges this message and uses the return result.

Rather than having to code all the details of the messaging process, celery allows us to just create a Python function “foo.bar” that will do the above for us. Thus, we can execute tasks asynchronously without requiring that people reading our code know everything about our messaging backend.

Hopefully, this gives you a high-level overview of how celery is working behind the scenes. There are a lot of details that I’ve left out, but hopefully this provides you with enough knowledge that you can figure the rest out.

Filed under  //  amqp   carrot   celery   messaging   programming   python   rabbitmq  

Comments (0)

Jul 8 / 8:08am

Embrace quirks when working with others

For me, learning to work with people was a two-step process:

  1. Realize that other people are different from me. And I don’t just mean that other people just act differently. I mean they are completely different with different motivations.
  2. Realize that this is actually a good thing.

It seems to me that Derek Sivers has learned the first lesson, but I’m not sure that he’s learned the second. When we realize the first lesson, most of us try to avoid the issue. If people are different, the goal must be to suppress those differences. Unfortunately, people just don’t work that way. David Keirsey would describe this as a Pygmalion Project.

For those of you who aren’t familiar with Roman Mythology, Pygmalion was a sculptor who could not find the perfect woman. Solution? He sculpted one. Venus was touched by this story, so she turned the statue into a real woman.

This is a cute story, but it parallels reality more than we realize. Like Pygmalion, when we encounter someone who’s different our first instinct is to shape them into something that’s the same. Keirsey talks about this as the downfall of many relationships: we go to great lengths to find somebody who is different from us, but then we try to make them into ourselves. Of course Derek shows that one can have a Pygmalion project on themself. If we view ourselves as abnormal, the solution is to be more normal.

This tends to have the effect of lowering one’s self esteem. No matter how hard you try, you can’t make yourself be something you’re not. If you try to suppress your quirks, you will either fail or become a mediocre version of what you perceive as “normal”.

I would argue that not only is it not feasible change peoples' personalities, it’s not preferable. Your quirks are what make you unique, and they are the reason your coworkers need you. Quirks are different ways of looking at things. Rather than suppress them, learn to appreciate them. Most importantly, become proud of your quirks. Other people may not understand them, and that’s the point.

The only time quirks become problematic is when you turn them into Pygmalion projects. If you expect others to share your quirks, you will quickly run out of friends. However, when you learn to appreciate quirks in yourself and others, you become a better person. You begin to appreciate peoples' strengths and weaknesses. If you pay attention, you might even discover that the person you thought was incompetent is really just different from you.

The moral of this story: Embrace quirks, but don’t enforce them.

Filed under  //  advice   career   derek sivers   quirks  

Comments (0)

Jul 4 / 4:42pm

The Rumsfeld Hazard

There are known knowns. These are things we know that we know. There are known unknowns. That is to say, there are things that we now know we don’t know. But there are also unknown unknowns. These are things we do not know we don’t know. —Donald Rumsfeld

(I should note something here: although this blog post is named after a political figure, I generally prefer to avoid political references here. So don’t construe this as being a political message.)

I seem to recall Rumsfeld being very much criticized for the above quote. Now, I’m not saying that the above quote was the appropriate response to the question he was asked. However, there is some truth to what he said. Too often, we think in terms of knowns and unknowns. We treat planning a software project as if it were an obstacle course: overcome this and this obstacle and you’re done!

If this were the case, software development would be a much easier practice. It’s not so much that comparing software development to an obstacle course isn’t an apt analogy. But the obstacle course is more insidious than we think it is. Almost always, the obstacle course looks easy. The problem is that it’s built upon a minefield and you weren’t told about it. Unless you get really lucky, you’re in for a huge surprise.

And don’t think that you can beat this by bringing a mine detector through the second time around. By then, they’ll have replaced the mines with pits of spikes or some other twisted but hidden trap. A software developer has the unenviable job of traversing this obstacle course.

A lot of us will carefully map our plans out, only to have a single mine invalidate the entire plan. That mine is the Rumsfeld Hazard: a problem you didn’t know about, couldn’t have predicted, and thus couldn’t plan for. If there’s one thing that agile development methods help with, it’s dealing with the Rumsfeld hazard. Sure you won’t be any less surprised when the mine goes off, but you won’t have spent so much time making plans that are shattered by one unseen event. It’s a beautiful thing when a software team can roll with the punches this way and plan enough in advance to have a general direction.

Comments (0)

Jun 16 / 1:23pm

How to come up with good abstractions

The effective exploitation of his powers of abstraction must be regarded as one of the most vital activities of a competent programmer. -Dijkstra

Abstraction is something that every programmer uses, but few appreciate. In fact, there’s an architecture antipattern that discusses this. You can agree or disagree with the idea that 1 in 5 programmers understand abstraction, but it is my experience that few developers truly appreciate abstraction and can make good use of it. This is somewhat sad. While abstraction comes naturally to few programmers, it is something that every programmer can learn with some amount of effort.

So with that said, here are my (sometimes conflicting) guidelines for coming up with good abstractions.

  1. Trust your gut. Abstraction is more of an art than a science. If there were an objective, scientific method of coming up with good abstractions, programming would be a lot easier. Therefore, you need to forget everything your professors told you about not trusting your intuition. The goal of any abstraction is to make something easier to understand. Guess what abstractions are easiest to understand? The ones that are the most intuitive. Of these guidelines, this is the most important. When you’re in a situation where two guidelines conflict go with your first instinct.

  2. All abstractions leak. It’s worth reading Joel’s piece on leaky abstractions. This is an important thing to keep in mind. The most beautiful abstractions are the ones that are successful in spite of this. Unix is full of good examples. For instance, is anyone really naive enough to be convinced that everything really can be treated exactly the same as an honest-to-god file that resides on the hard disk? Sure, everything has the same interface as a file. But in all but the most trivial of cases, you’re going to need to know what the underlying thing you’re interfacing with is. For instance, with a socket, you may need to worry about if the socket is half-closed, totally closed, or open. If it’s a pipe, you need to realize that something on the other end might close the connection. And yet in spite of the leakiness, the “everything is a file” abstraction is probably the most important thing Unix ever did.

  3. Don’t trust black boxes. Whether it’s your abstraction or someone else’s, there’s a real danger of thinking of something as a magical black box that doesn’t need to be understood. This is dangerous because of guideline #2. When something doesn’t work right, you want to be prepared.

  4. …but don’t be too transparent. Of course, there’s a danger of going too far in the opposite direction. A completely transparent abstraction is useless; it’s not really an abstraction. A good abstraction should be translucent. You shouldn’t have to know all of the details all the time, but you should be able to figure them out easily.

  5. Elegance before comprehensiveness. Since we’ve already established in #2 that no abstraction works in all circumstances, you should abandon the idea of an all-encompassing abstraction. It’s better to have a small set of abstractions upon which higher-level abstractions can be built than to try and come up with one all-encompassing layer of abstraction.

  6. Abstraction doesn’t make your code simpler. Many peoples' complaint against abstraction is that it makes your code more complex. In fact, they’re often correct. When you have the choice between abstraction and simplicity, always choose simplicity. Unfortunately simplicity isn’t always an option. Think of it this way: if you become sick, would you rather take medication that will cure the disease or treat the symptoms? Obviously, we’d rather make the disease go away if at all possible. But not all diseases are curable. In this case, the only thing you can do is treat the symptoms. This is essentially what abstractions do. They don’t make complex code simple. They do make complex code easier to wrap your head around though.

In the end, I can come up with nifty guidelines like this all day. But in the end, it’s most important to remember rule #1: trust your gut. Chances are that you’ll be better off than if you followed a checklist of guidelines.

What are some good abstractions that follow these guidelines? What are some that break them?

Filed under  //  abstractions   architecture  

Comments (0)

May 5 / 9:15pm

Exceptional programmers

One thing that seems to be a perennial favorite on Hacker News is discussion of the characteristics of a good programmer. Inevitably, people disagree on this subject. I think this is a difficult question to answer not because it's difficult to recognize good programmers, but because it's the wrong question.

Human talent cannot be reduced to a simple boolean proposition. People have different talents in different areas. People often have problems recognizing good programmers because they try to fit people into a box. They try to say that good programmers have characteristics x, y, and z, but that characteristics a, b, and c are never qualities of good programmers.

It turns out that for every good programmer you do recognize, there are probably several other people you wouldn't have guessed in a million years would be any good. So here's my attempt to help people understand good programmers better. Oftentimes, good programmers will fall under more than one or even all of these categories. But usually, they're most talented in one area.

I should also point out that I'm probably just scratching the surface here. There are probably more types of good programmer than this.

The machine

The machine is probably the first person you think of when the words "good programmer" hit your ear. The machine is someone who has the job you asked for finished yesterday. Sometimes the most challenging task is simply finding things for them to do.

Machines are the easiest to recognize simply because their talent is more measurable: they get their tasks done way ahead of schedule. However, they're not without their tragic flaws. Although machines are good at writing code, they rarely see code as anything but a means to an end. Left unchecked, machines can turn your code into a steaming pile of crap. Fortunately, that's where the other types of good programmers come in.

The method man (or woman)

The method man is the one who brings discipline to the team. Their greatest strength is attention to detail. Usually, they're the ones to poke holes in the architects' brilliant ideas or to get the machine to slow down, take a breath, and think before coding.

It's a bit more difficult to recognize a method man than it is a machine. The key thing to watch for is process. They're the ones who describe everything they do in excruciating detail. This is also their Achilles heel. They're good at applying rules and processes, but they freeze the instant they are faced with a situation that falls outside them.

The architect

The architect is the crazy guy (or gal) who rambles on and on about design patterns. Get him involved in a conversation and he'll be delighted to tell you his latest theory about whatever random thing he's thinking about at the time. While their ideas may come off as crazy, there is almost always a method to their madness.

They're the people who make sure machines don't have to care about their code. They're also the ones to offer guidance to the method men when the rules don't apply. They're the ones who look out for the big picture while everyone else is distracted by details.

The hallmark of the architect is inconsistency. They're the ones you come to when you have a really difficult problem. But assign them the most mundane task and a two-hour project just turned into a two-day project. Ask them to explain Goedel's Incompleteness theorem, and you'll get the most brilliant description you've ever heard. Ask them what a database is and you'll probably get the most obtuse and technically dense answer you've ever heard.

So what other types of brilliant programmers have you come across?

Filed under  //  career   functional-programming   hiring   programmers  

Comments (0)

Feb 12 / 7:01am

Building a Common Lisp webapp using Python's envbuilder

One of my goals in starting envbuilder was to make it not totally wedded to Python. My main use-case for envbuilder is to build Python apps, but I think it's important to make sure envbuilder can be flexible and simple enough to get the job done. I think that the best way to do that is to try using it to build something other than Python.

Shaneal Manek's excellent guide to setting up a simple Lisp webapp seemed like the perfect project to try this out with. I'll start off by telling you how to try it out. The first step is to actually get envbuilder. I recommend using the version that's in master as of this writing. Although this example can probably be made to work with envbuilder 0.2.1 (the current stable release), it is just much easier to understand if you use some of 0.3.0's features.

So, to get envbuilder, you just need to use the following command:

 
git clone git@github.com:jasonbaker/envbuilder.git 

This example is already set up in examples/lisp-webapp. To get up and running, you just need to do the following commands:

 
envb checkout # get the files you need to start 
export INSTALL_ROOT=`pwd` # tell sbcl to install to the current directory 
envb setup # create a local build of SBCL 
export SBCL_HOME=`pwd`/lib/sbcl # tell sbcl where it is installed 
envb start # start the webserver 

Alright, so here is the .env file in all its glory:

 
# It seems that there's a bug in configobj where a section name can 
# conflict in interpolation, so name this differently 
sbcl_ = '$CWD/bin/sbcl'	 
[project] 
 parcels = 'sbcl', 'webapp' 
 [[sbcl]] 
 checkout = 'git clone git://git.boinkor.net/sbcl' 
 setup = 'cp $CWD/customize-target-features.lisp $dir', 'sh make.sh', 'sh install.sh' 
 [[webapp]] 
 dir = 'trivial-lisp-webapp' 
 checkout = 'git clone git://github.com/smanek/trivial-lisp-webapp.git' 
 start = '$sbcl_ --no-sysinit --no-userinit --load $CWD/$dir/src/init.lisp', 
[commands] 
 [[start]] 
 working_dir = '%dir/scripts' 
 required = False 
 help = 'Start the server' 

The first thing to understand about envbuilder is the concept of a "parcel". A parcel is simply a piece of software that's usually checked out from version control (although it doesn't have to be). The commands that are run when you do "envb checkout" are defined using the checkout option. Similarly, the command that is run when you do "envb setup" is defined by the setup option. You'll notice that the webapp parcel doesn't have a setup command. This is because we don't really need to do anything to set it up other than checking it out from git. There is one important thing to note here though. The sbcl section uses a $CWD variable to run itself. There is a difference between $CWD and simply using a dot ("."). The difference being that the setup command is run from inside the parcel's directory. Using dot is relative to that directory while $CWD is the directory that envb was run from.

The last feature to note is the custom command (start). Just as with checkout and setup, the start command is to be placed in a start option in a parcel. In this case, the start command only runs on the webapp parcel. I won't go into detail about each option on the start command as that's covered in the envbuilder documentation.

So, the purpose of this blog post isn't really to teach you how to set up a lisp web application with envbuilder. It's to show you that envbuilder is much more than a tool to create a Python virtualenv. If you'd like to contribute to envbuilder, the best way to do so at present is to submit other examples of how you've gotten envbuilder to work in a neat or creative way. After all, the real fun in creating an extensible application is finding out that it can do things you didn't realize it could do.

Comments (0)

Jan 30 / 9:58am

YA "Lifecycle of a Programmer" post

Yes, I'm going to make the obligatory post talking about the lifecycle that programmers go through. I should note that this is a bit of an oversimplification. The reality is that some people may skip stages, stop at some stages, or go through these in a different order.

Here are the steps:

Infant - This is where we take our first steps. We write our first programs (which are hideously terrible by the way), and we just get excited because we wrote something that didn't crash. There's really not a lot more to this stage.

Child - Child programmers are a handful. To some, they may seem arrogant and hard-headed. The reality is that they just don't know any better. Child programmers do as real children do. They test boundaries to see what they can and can't get away with. They throw tantrums when they don't get their way. It may not always be apparent, but their intentions are usually benign. For the record, I don't trust a programmer that never had a Child stage.

Teenager - Teenagers are at the stage where they're trying to be adults. And they go out of their way to prove it to everyone. They're often condescending to children and rebellious to the "establishment". Most teenagers do things they'll later regret in adulthood, but this is usually a programmer at their most creative stage. Their ideas are usually either totally brilliant or absolutely stupid. The difficulty is in recognizing which is which.

Adult - At some point, the teenager will wake up and realize that they've become the authority figure they used to despise. They're the workhorse programmers. Their old idealism at the expense of practicality is gone. And if they're not careful, their desire to try out new things may go with it.

Old timer - This is the stereotypical "greybeard". The elderly programmer is wiser than all of the other programmers combined. This is both their greatest asset and their greatest weakness. They're usually not willing to try new things simply because they've probably already solved the problem many times before and found a way that works. Old timers usually say things like "Frameworks? Back in my day, we didn't need frameworks! We just wrote our CGI scripts in Perl. And we liked it too!" Sometimes old timers can be comical in this manner, but you should always listen to them. No matter what, they've probably been where you're at before.

What use is anyone else?

Programmers in all life stages tend to conflict with programmers in other stages, some more than others. But reality is that they're all necessary. Teenagers and children are needed to bring a fresh perspective. Adults are needed to make sure that work actually gets done. Old timers are needed to keep the younguns in line.

Comments (0)

Jan 6 / 6:34pm

How to have a side project

If there's one part of a programmer's professional development that is harder than it seems, it's starting a side project. I, for instance, love to program. The funny thing is, that programming is the easiest part of programming (those of you who are true programmers will know what I mean). The hardest part is starting to program and finishing your work.

That said, I do have a few bits of advice for programmers who want to start a side project. If you follow my advice, you probably won't write the next big thing, nor will you have a side project that will stand out particularly well on your resume. But you'll probably write something that will make you a better programmer, and that's the point, isn't it?

Here's what I've learned about starting a side project:

#1 - Have a good time

This is the first point on here for a reason. And I should hope it's self explanatory. However, note that there are good reasons for making tradeoffs here. I'll note them below, but there are some things that shouldn't be tradeoffs. For instance, don't make tradeoffs based on how it will look on your resume or what the latest and greatest technology is (not that either of these can't be fun).

#2 - Learn something

I've known some programmers who live by the mantra "I'll learn it later". Here's the problem: later never comes. You're just going to have to accept the fact that you as a professional need to have some responsibility for your own development. Fortunately, a side project is just the way to take on that learning.

#3 - Make it timeless

Here's where you may have to make tradeoffs in terms of fun. The most fun things are usually a hassle to maintain. For instance, suppose you write a new twitter client. I can guarantee you that at some point in time, the twitter people will change their API in such a way that will break your code. Granted, this isn't a big deal if you put a lot of time into it. But that's the problem: no matter what you do, there's going to come a point in time in your life that you have something else to spend your time on or otherwise just won't want to deal with your side project. That's normal. What you want is something that you can come back to after that time is up.

This is part of the reason why I chose pysistence for my project. Aside from keeping up with language changes, it's doubtful that functional data structures are ever going to change such that my code will break.

#4 - It doesn't have to be code

I'd probably say that the blog you're reading right now is my most rewarding side project. Don't underestimate the value of doing things that aren't coding. It's fashionable to talk about how bad it is to be "all talk and no game", but the fact of the matter is that reading and writing about programming helps you to solidify some of the ideas that may be forming in your head.

#5 - Make it something you'll use

This is the last point, but that doesn't mean it's not important. If you write something fun, you'll abandon it as soon as it stops being fun. If you write something useful, you'll have a reason to keep coming back!

Filed under  //  programming   side projects  

Comments (2)