Wednesday, December 28, 2011

On permissive and copyleft licenses

As you probably know, FOSS licenses are a touchy subject - I've seen some people who won't use or contribute to a project if the project uses a license they do not like. In my humble opinion, licenses aren't a major issue (except for projects you lead) and I'll attempt to explain why below.

Let's start with the (A)GPL. This is probably the most loved/hated license of all time, for 2 major reasons:

  • The GPL is a strong copyleft license: Any derivative product must also be covered under the GPL.

  • Even if you leave the GPL code alone and build your own code on top of it - even with dynamic linking - your code must also be covered under the GPL.

For those of us who primarily develop GPL'ed code, this isn't really an issue (in such a case, you'd license your derivative product under the GPL anyway), but using the GPL prevents your code from being used in a non-GPL FOSS project, which may or may not be what you intended.

This is the biggest argument against the GPL in the license debate by far, and for obvious reasons. However, unlike permissive licenses, GPL'ed code cannot be used in a proprietary product, no matter how many times it is derived from, which is the point brought up by those who do like/use the GPL.

So if you don't want your code to be used in a proprietary product, or you only want your code to be used in other Free software projects, the GPL is the way to go. Otherwise, you might want to read on.

Now, let's take a look at permissive licenses. There are quite a few of these, most notably:

  • 3-clause BSD

  • 2-clause BSD

  • MIT/X

  • Apache

All of them differ in subtle ways (the Apache license includes a patent indemnification clause, for example), but they all have the same basic premise: Use, modify and redistribute this code however you like, but:

  1. Don't change the license on the original code

  2. Distribute a copy of this code's license along with your product

  3. State unambiguously (none of the licenses specify where) that your product uses my code

Quite a bit more permissive (hence the name) than the GPL, don't you agree? These sort of licenses are used primarily by those who aren't concerned about possibly proprietary derivative products. As far as I've seen, the permissive licenses receive the most flak for not ensuring that derivative products are FOSS as well, something the GPL ensures. In my opinion, whether or not this is a problem is something that has to be decided by the author of the code in question: Am I fine with people making a proprietary (and most likely commercial) derivative of my project? The way I normally go about deciding between using the (A)GPL or a permissive license in a new project - yes, I use both :) - boils down to four questions:

  1. Is the code I am going to license constitute a product that others could make a proprietary (and most likely commercial), standalone derivative of by copying verbatim?

  2. How much time have I spent on the code I'm licensing?

  3. Am I trying to use this code to advance the cause of FOSS, i.e, I'm making a FOSS application in a problem domain where no other FOSS application currently exists?

  4. Are there already currently better FOSS applications in the problem domain for my new project?

Questions 1 and 3 are probably the most significant: If the answer to either question is "yes", unless the answer to Question 4 is "no", the code for the new project will almost certainly be under the GPL - if my project is the only FOSS application in its problem domain, I want to make sure that everything that touches it stays FOSS, for obvious reasons. Question 2 and 4 are somewhat less important, but still bear some weight: If the answer to Question 4 is "yes", I'm probably going to use a permissive license - there wouldn't be much point to someone ripping off my project with there being better FOSS applications in its problem domain anyway.

Besides, as long as I'm the sole copyright holder (or have all contributors sign a CLA assigning copyright to me), I can change the license in the future if my FOSS project becomes the best in its problem domain or other FOSS projects in my project's problem domain become defunct.

You've probably noticed by this point at least three of the four questions have to deal with whether someone will come along and make a proprietary, commercial spinoff of my project. I notice quite a few people in the FOSS community stating that since I wrote my code for "free", i.e, without any monetary fees being incurred from development of the code in question - which often isn't true anyway, otherwise so many projects wouldn't have a "Donate" button displayed conspicuously on their home page - I shouldn't care whether someone else makes money off of my code.

And that's where Question 2 comes into play: At the very least, whenever you write code, you spend time. Time isn't free - as a matter of fact, it can be considered more precious than money; time spent doing anything is part of your life you'll never get back, ever. And if you've spent a significant amount of time working on your FOSS project (or you're about to start a new one, and are pretty sure you're going to spend a lot of time on it), you probably want to think about whether you're fine with someone spending perhaps an hour re-branding your product and making a profit with it.

Enough theory. How do you license a FOSS project in practice? I have one major FOSS project that I lead at the moment - OpenBlox - so I'll go through how I came up with a licensing scheme for that project.

How does OpenBlox do with those four questions we talked about earlier?

  1. Is the code I am going to license constitute a product that others could make a proprietary (and most likely commercial), standalone derivative of by copying verbatim? In its current state, no, but very soon (most likely in 6-8 months), yes.

  2. How much time have I spent on the code I'm licensing? Quite a bit - I estimate I've spent around 5,500 hours on OpenBlox so far (and it's only existed for around 2 and a half years)

  3. Am I trying to use this code to advance the cause of FOSS, i.e, I'm making a FOSS application in a problem domain where no other FOSS application currently exists? Yes, definitely. There is not a single other FOSS project in OpenBlox's problem domain, although there are at least two proprietary products sharing OpenBlox's problem domain.

  4. Are there already currently better FOSS applications in the problem domain for my new project? Because of the answer to Question 3, the answer to this question is of course "no."

Due to how I answered each of the four questions, the GPL looks like a pretty good choice for OpenBlox, and due to its nature as a relatively extensible and unique game engine, a permissive license works great for bundled extensions/plugins. And that's exactly what I use for it now: GPL for the main engine, with plugins and support scripts (save for core plugins that handle things like rendering) under the Apache license.

Quick note before I sign off: The LGPL is a great compromise between a strong copyleft like the GPL and a permissive license like the BSD license: People can use your code without having to change the license of their code (just like a permissive license), but all their modifications to your code must fall under the LGPL, which is pretty neat.

Sunday, December 4, 2011

What is programming?

What is programming? I get that question a lot from my non-programmer friends. The interesting thing is, I had never really asked myself that question - and if my Google-fu hasn't failed me, no-one else has really answered this question, either (at least in a way a beginning programmer or non-technical person can understand ). So I'll do my best to do answer that now, and I'll voice my thoughts about the answer a little too :)

First off, what are programmers trying to accomplish when they write a program?  They're trying to solve some problem. Even when you're writing a small one-page script for fun, you've set some problem up for yourself to solve. For example, I wrote an RSS reader in Python a while ago, that notified me of new news items via libnotify - a program/framework that lets you make pop-up alerts on Linux.

Even with such a small utility (it was under 300 lines of code, if I recall correctly), there was a problem for it to solve: Check a list of site's RSS feeds every so often, and if there are any new items, set up a libnotify alert. Yes, it's a small problem, but it is a problem to solve nonetheless.

So, now we know what programmers are trying to accomplish when they write a program, how do they write the program itself? This is another question I get often - how in the world do you write a program?

Well, now the programmer knows the problem he/she is trying to solve, the programmer must now come up with a solution to that problem. Going back to my RSS reader example, my solution was for my reader script to be called via cron (a UNIX/Linux program that runs other programs every so often), and save the etag (basically a hash of a RSS feed's contents) of each feed, and check them against the current etag of the feed we're trying to update. If the etags are different, that means there is new content, so fetch the new content and make a libnotify alert.

Note that the solution to our problem is not code, and it's not UML or anything. It's just a simple, step-by-step, human-readable solution. That's how solutions to the problems your program is trying to solve should be - simple sentences, nothing more. UML and code snippets are useful, but if your solution cannot be explained in plain English (or your native language, if that's not English), you most certainly will not be able to implement it in code. I like the way the Zen of Python puts it:

If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.

So, now we know what we're trying to solve, and how we're going to solve it, we have to convey our solution to the computer in a way it can understand and run - in other words, actually implement our solution in some programming language. This is the most complicated part of programming, and the most error-prone - most software bugs are created during this step, so programmers must use extra caution while performing this task.

Unfortunately, Murphy's Law often hits hard during this step.

No matter how careful you are while actually writing your solution in some programming language, you will make mistakes. When this happens, you'll have to find where the bug occurs, figure out why the bug occurs in the first place, and then devise a way to fix the bug. Again, going back to our RSS reader example, I made a mistake that caused the RSS reader to make a pop-up notification for every news item, even for old items. My solution was fine, but I made an error implementing my solution, so I had to fix it.

Now we've answered the question of what programmers are trying to accomplish when they write a program, and then how they convey that solution to the computer in a way it can understand, we can answer our original question: What is programming?

It is the act of finding a solution for a problem, and then implementing that solution in a way a computer can understand - nothing more, nothing less. Whenever you sit down to write code, you're trying to solve some problem. This is practically identical to what mechanical and electrical engineers do for a living, which is quite interesting: Are programmers "software engineers"? Should they treat every line of code they write with the same amount of professionalism and excellence a mechanical engineer treats the design of a suspension bridge he's made that some construction workers are going to build? Those questions have been the subject of much debate in the software industry for more than a decade.

If you're not a programmer, now you see there's no "black magic" in programming. All that a programmer does while he programs is solve problems. Who knows, now you know programming isn't as complicated as most non-programmers make it out to be (it's still not a breeze by any means :)), you just might want to try programming out for yourself. :)

If you're a programmer, the next time you sit down to write some code, think about the answers to the above questions, and remember what you're doing when you're writing code - you're solving a problem. You just might be surprised how much more carefully you write code. :)