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

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.

Loading mentions Retweet

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.

Loading mentions Retweet

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!

Loading mentions Retweet
Filed under  //  programming   side projects  

Comments (2)

Jan 3 / 7:32am

Are you an Engineer or a Scientist?

I just got done reading an excellent article by Roman Snitko. I agree almost 100% with everything he says. However, I felt that the idea could have been developed and executed better. I'm not writing this because I feel that his original piece sucked. Rather I'm writing this because I like the idea he comes up with and want to see it have an impact. So here's my shot.

(I should say that some of what I say might disagree with what Roman says. I did say almost 100%.)

The engineer

People tend to associate "engineers" with people who get things done and solve real-world problems. Thus, I feel that Roman's "dudes" can be thought of as the engineers of the programming community. Engineers are the ones who want to make something and get it in peoples' hands as quickly as possible. It just so happens that that product is a piece of software.

You can recognize an engineer because they're usually saying things like "So what if it's not perfect? It works!" or "That sounds like a great idea, but I don't think we have time for it."

The engineer's biggest weakness is that they seem to not think about much past their current deadlines. Yes, it's important to meet those deadlines. But you do plan on writing software after meeting those deadlines, don't you? To make up for this, they must call upon the expertise of the scientist.

The scientist

The interesting thing is that almost every field of engineering has a corresponding field of science. Scientists are people who find better ways of doing things without necessarily considering their practicality. It's fashionable to talk about how disconnected these types of people are from reality, but the truth of the matter is that engineers can't do the things they can without scientists. Scientists are the ones who want to build great software. It just so happens that that software is also a product people will use.

You can recognize scientists because they're usually saying things like "So what if it works? It's an ugly hack!" or "Software schedules should reflect what needs to get done, not the other way around."

You might have already guessed the scientist's weakness: they tend to not get along with deadlines very well. To make up for this, they must call upon the abilities of an engineer who can transform their great ideas into reality.

So who's right?

This way of looking at things is a bit of an oversimplification though. It's really not that engineers don't want to make a great piece of software or that scientists don't want to make a great product. It's really a matter of priority. Scientists would rather write a great piece of software than a product. Engineers would rather make a product than a great piece of software.

Unfortunately, both sides are a bit disconnected from reality. In the software world, a great product usually is a great piece of software. It's also unfortunate that someone who can make both things happen is extremely rare if not nonexistent.

Thus, it is ideal for these two sides to be in a state of healthy conflict. They need to recognize that the other side has a point sometimes (as hard as that can be).

So which one are you? And how do you work with the other side?

Loading mentions Retweet

Comments (2)

Jan 1 / 8:38am

Myths about code comments

It seems to me getting good at writing comments is an under-appreciated part of a Programmer's development. However, I feel that this is a part of programming that's almost as important as writing code itself. So, here are some of the biggest misconception about comments:

Comments are free

This is an assumption that most of us make at one time or another. Comments aren't actually executable code, therefore they aren't maintenance costs, right? As it turns out, this isn't true. When you update the code that the comment references, you usually have to update the comment as well.

Unfortunately, this myth is actually true most of the time. After enough time staring at a comment, it typically becomes "noise" that you tune out. Thus, comments have a nasty habit of not being up-to-date.

Comments make code more readable

This is by far the most pervasive myth that I've encountered. If anything, comments make code less readable. Nine times out of ten, I ignore comments unless I'm stumped. In fact, I'm tempted to make emacs hide all comments unless I explicitly expand them.

Comments don't make code more readable. They are ways to compensate for code not being readable.

You should comment every function, method, class, and module

How many times have you seen docstrings like this?

 
def get_x(self): 
 """ 
 This method gets x. 
 """ 

This is about as close to being a canonical "bad comment" as you can get, and yet people who should know better still do it. Why? Because they feel that they should document every function or class. The reality is that documenting something that needs no documentation is universally a bad idea.

Code must always be "self documenting"

Most of the myths thus far have been of the "comments are a wholesome, healthy thing variety". Don't take this to mean that I feel that comments are bad. The reality of the situation is that the decision of whether to comment is just like most other decisions in programming: it's about tradeoffs.

In most cases, comments should be viewed as code smells. But remember that code smells aren't necessarily bad. They're just hints that something might be bad. And sometimes, removing one code smell adds another one which may or may not be worse.

For instance, would you rather use a one-liner that requires a 3-line comment, or a 10-liner that requires no comments? In most cases, code's readability suffers more when it's overly verbose than when it has a high comment to code ratio. Thus, I would choose to write the comment in most cases.

Loading mentions Retweet

Comments (43)

Dec 12 / 3:01pm

Syntax vs semantics: what's the difference?

This is a subject that many programmers get confused about.  The difference isn't really a difficult concept, it's just that it's not explained to programmers very frequently.  Let's consider a snippet of a poem by Jeff Harrison:

know-bodies, devoted we to under-do for you
every Sunday-day of dressy morning, black pond,
sky's germs, chairs' ponds - prove it, stain!
us, rain-free & orphaned, we're living laboratories

This is from Dart Mummy & The Squashed Sphinx.  If you haven't figured it out, this text is generated by a computer.  And it uses the same techniques that a lot of spammers use.  What's most interesting about this is that it's grammatically correct.  For instance, "prove it, stain!" is a perfectly valid English sentence.  The problem is just that it's meaningless.  Thus, we can say that the above poem is syntactically correct but has no meaning semantically.

Programming languages are similar in concept.  Consider the following Python snippet:

The above code is obviously incorrect.  It uses variables that haven't been declared yet.  Therefore, it is semantically incorrect.  But it is a syntactically valid Python program.

In the same manner, we can say that these two snippets of code are identical semantically although they definitely have very different syntax:

python

ocaml

Therefore, we can define these terms like this:

 * syntax - A set of rules for specifying a program
 * semantics - The meaning behind that program

 

Loading mentions Retweet
Filed under  //  ocaml   programming languages   python   semantics   syntax  

Comments (0)

Nov 29 / 9:07am

My five rules for writing good code

I just came across a blog post that outlines 5 rules for writing good code.  I agree with them for the most part.  But this subject is extremely subjective and will vary from person to person.  Therefore, I'd like to write up my own rules for writing good code.

Keep it simple

This is the YAGNI rule.

There are often times when we want to try to solve problems we don't have.  You must resist this urge.  It's far easier to make simple code more complex than the other way around.  This is usually more of a challenge than it looks.  It's a sign of good code that you constantly find yourself saying "any idiot could have put this together".  Reality is that idiots only write simple code when the problem is easy or when they get lucky.

...but not simplistic

You can call this the SYDNI rule.

Albert Einstein said it best when he said "Everything should be made as simple as possible, but not simpler."  I've seen too many "simple" hacks that ended up causing more of a maintenance problem than it would have been just to write something more complex.  As good a thing as simplicity is, you need to be realistic.  Don't try to make a simple solution match a complex problem.

Abstraction is your friend

So what do you do in those situations where you need to use a complex solution?  Do you give up all hope and just write some horrible piece of crap?  No, you find a way to make that complexity easier to manage.  This is where abstraction comes in handy.  

For instance, Lisp introduced the concept that "it's all data". This makes it easier to understand things.  If you want to know what something is, you already know that it's data of some kind.  What is a function?  Data.  What is a list?  Data.  What is code?  Data.  This has a profound effect upon your ability to understand things.

Follow guidelines

Jeff Atwood would call this following the instructions on the paint can.  We tend to sneer at the idea of "best practices", but reality is that they're necessary.  There are a lot of problems out there that people have already dealt with and solved.  Why waste time not learning from others' mistakes.

...but don't worship them

As the old cliche tells us, rules were made to be broken.  Some of the most well known design patterns break the guidelines and have some of the worst code smells.  In fact, sometimes the guidelines conflict with each other.  Thus, don't blindly follow guidelines without knowing their purpose.  Instead, understand the rules, know when to follow them and when following them is the greater of two evils.
Loading mentions Retweet
Filed under  //  guidelines   programming  

Comments (0)

Nov 21 / 11:39am

The understanding dilemma

Remember the first time you heard about object-oriented programming?  What was your first response?  If you're like me (and most other people), your response was probably something along the lines of "What the heck is this?"

Yet, at one point, a lightbulb probably clicked in your head.  All of a sudden, it made sense.  Nowadays, I know objects like the back of my hand.  It's just such a simple concept, is it not?

How many times has something similar happened to you?  I'm willing to bet it's more common than you think.  The thing about it is that we as humans have a tendency to assume something we don't understand is complex.  And oftentimes that's true.  But sometimes it isn't.

I think I've determined the root cause of this problem.  You see, we programmers have to be masters of filtering out unnecessary data.  There's simply too much of it.  So how do we approach learning new things?  We try to learn the bare minimum.  Most of the time, this is necessary.

Here comes the bad news.  This doesn't always work.  You were expecting me to say this, weren't you?  You see, there are times where we as programmers have to understand things.  And by understand, I don't just mean extracting just the parts you feel are necessary.  I mean you have to understand general concepts.

After all, only an idiot would claim that the only part of C you need to know to write a calculator are the +, -. /, and * operators.  And yet, this is what we as programmers find ourselves doing on a daily basis.  We momentarily ignore the fact that we need to know how to write a function and how to do I/O.

The point is this:  just make sure you understand things before you pass judgement.  And try to make sure that you spend time understanding general concepts and not just specific ones.
Loading mentions Retweet

Comments (0)

Nov 5 / 10:44am

How programming language webpages should be designed

A while back, I asked a question on Stackoverflow that taught me something (other than what programming languages are fun to work with). A lot of programming language authors just aren't very good at marketing their languages.

There are a lot of programming languages out there that I wanted to try out, but couldn't figure out an excuse to spend my time on them. And that's pretty sad considering how much I like trying new languages out.

Therefore, I'd like to present to the world my ideal website for programming languages: the Ruby webpage. In fact, I have to admit that if I were trying to decide between Python (my favorite programming language) and Ruby today, I'd easily choose Ruby just based on their website. And that would be sad considering how much I love Python.

Let's take a look at why this is.

Show me the code!

I still don't understand why this is such a difficult concept for some programming languages. The first thing I want to know is how my code
will look if I write it in your language. With Ruby, it's right there on the first page.  Now try doing the same thing on the Python webpage.  Not as easy is it?

Even if you don't want to put it on the first page, it should at least be reachable using one click on the first page.  See the Scala webpage for an example of this.

Feature lists are useless, documentation is priceless

Hey, your language is cross-platform, has object-oriented and/or functional and/or concatenative and/or [insert language buzzword here] features. Good for you! Since you've taken a whole lot of time to provide me with great features, show them to me.

Again, I hold up Ruby as a prime example of how to do this. Right on the front page is Ruby in Twenty Minutes. This shows me all of the great features in brief code examples. And if that doesn't work for me, I can even try Ruby out in my browser.

As an example of how not to do this, I present the Unicon webpage. From the front page, I can gather that Unicon is a "very high level, goal-directed, object-oriented, general purpose applications language", but that's about it.

But we just met!

And one other thing, don't try to sell me a book. Yes, you should make it easy to find books on your programming language. No, you shouldn't remind me of it every chance you get. I view suggestions to buy a book as being somewhat like asking me to move in with you on the first date. Yeah, I find you interesting. I'm just not ready for the commitment.

Loading mentions Retweet

Comments (5)

Nov 3 / 1:41pm

7 tools for working with Python in Emacs (and Ubuntu)

I've been meaning to blog about this for some time, so I suppose now
is as good an opportunity as any. This is going to be a very "stream
of consciousness"-esque posting, so bear with me. Some of these are
things that have radically changed the way I use emacs. Others are
minor changes that I like. Feel free to pick and choose from them.

I'll assume you're running Ubuntu. Also, not all of these are Python
specific. But I feel that they will be useful to most Python
programmers who use emacs.

I should also note that (like most emacs users), most of these things
are tricks that I've picked up from various sources along the way. If
you wrote something that I put in here, thanks!

Ropemacs

Ropemacs is among the tools I love the most and hate the most. When
it works, it opens up a new world of automated refactorings for you.
But it seems to be a bit buggy at times. That said, setting it up is
really easy. Firstly, you need to have ropemacs installed. This is
pretty easy:

 
sudo apt-get install python-ropemacs 

After that, just a couple of lines of elisp in your .emacs file and
you're good to go!

 
(require 'pymacs) 
(pymacs-load "ropemacs" "rope-") 
(setq ropemacs-enable-autoimport t) 

Anything

Anything is almost like Quicksilver for emacs. To begin, you need to
download anything.el and anything-config. I also use 
anything-match-plugin. Then you just need the following lines of elisp:

 
(require 'anything-config) 
(require 'anything-match-plugin) 
(global-set-key "\C-ca" 'anything) 
(global-set-key "\C-ce" 'anything-for-files) 

Then, prepare to spend a lot less time searching for files!

Line number mode

When you're pair programming, nothing is more helpful than being able
to direct people to a certain line of code. This lets you spend less
time saying "hey, see that over there? It's about 3 lines up. No,
too far! go down another two lines." Installing this is really easy.
You just need linum.el and two lines of elisp:

 
(require 'linum) 
(global-linum-mode 1) 

Flymake through pyflakes

In case you miss the automatic error highlighting of the Visual Studio
world, you should realize that emacs has a similar system built-in.
It's called flymake. And you can make it work with Python as well. I
personally prefer to use pyflakes for this. All that's needed is
pyflakes:

 
sudo apt-get install pyflakes 

...and some elisp:

 
(when (load "flymake" t) 
 (defun flymake-pyflakes-init () 
 (let* ((temp-file (flymake-init-create-temp-buffer-copy 
 'flymake-create-temp-inplace)) 
 (local-file (file-relative-name 
 temp-file 
 (file-name-directory buffer-file-name)))) 
 (list "pyflakes" (list local-file)))) 
 
 (add-to-list 'flymake-allowed-file-name-masks 
 '("\\.py\\'" flymake-pyflakes-init))) 

Uniquify

How many __init__.py buffers do you have open at this moment? If
you're using emacs for Python programming, probably a lot. This is
where emacs's uniquify functionality is useful. It gives you a more
useful name for your buffers other than just appending a number at the
end. I have mine use the reverse of the directory. For instance, if
I have foo/__init__.py and bar/__init__.py open, they will be named
__init__.py/foo and __init__.py/bar respectively.

You just need this in your .emacs:

 
(setq uniquify-buffer-name-style 'reverse) 
(setq uniquify-separator "/") 
(setq uniquify-after-kill-buffer-p t) ; rename after killing uniquified 
 
(setq uniquify-ignore-buffers-re "^\\*") ; don't muck with special 
buffers (or Gnus mail buffers) 

python-mode

To be totally honest with you, I haven't used the built-in emacs mode
for python. I just installed python-mode because I was told it was
better. What I can tell you is that there is an occasional plugin
that requires python-mode. Installing it is easy. Just install
python-mode:

 
sudo apt-get install python-mode 

And add some elisp:

 
(autoload 'python-mode "python-mode" "Python Mode." t) 
(add-to-list 'auto-mode-alist '("\\.py\\'" . python-mode)) 
(add-to-list 'interpreter-mode-alist '("python" . python-mode)) 

Pylookup

Pylookup is useful for those moments when you find yourself asking
something like "Is join in os or os.path?" Unfortunately, the setup
can be complex, but well worth it. There are instructions here.

     
Click here to download:
7_tools_for_working_with_Pytho.zip (49 KB)

Loading mentions Retweet
Filed under  //  emacs   python   ubuntu  

Comments (3)