Aug 31, 2008

Afraid of the CLI?

I found myself wondering recently (I wonder how many blogs I've started with a sentence similar to that) about programmers that don't use the command line. I know that outside of the geek world, people really like the point-and-click interface, and don't really know or want to know how to use the command line.

However, then I come to the question at hand. How many programmers are afraid of the command line? It is something that is fairly technical, but as programming itself is something that is also fairly technical, I don't see why a programmer should be afraid of it. Yet I do find programmers who don't know how to use it.

In Rails, I think that the command line is essential. The number of tasks that are done through rake mean that the most efficient way to sort through them all is through command line: just type the command you want rake to do and it does it. No having to dig through GUI screens and all that to find the one you want to do.
Same goes for the generators, by using the command line arguments you can save yourself a bit of typing later on by passing the right things to script/generate.

For web programming in general (I say programming to assert that you are actually programming and not just making HTML/CSS pages) command line is also important for productivity. When dealing with a server, you'll have to check log messages. While you can do this through fancy web interfaces, or by downloading the log files via FTP, the easiest way to do it IMO is through SSH. It's simple:
ssh username@domain.com
cd /path/to/log/file
tail -n 1000 logfile.log (add a -f in there if you want real-time updates)
You can do more magic using grep to find things more specifically what you're looking for.

So why would programmers be afraid of it? My answer is that it has a higher learning curve. You need to know things in order to use it. You need to know what commands to type, and what parameters to send to them. Not knowing how to use things like tail or grep or nano (not that nano is terribly difficult to use, but I can imagine some developers not liking it) can remove the efficiency boost that the command-line provides. Even worse, not knowing about --help/-h conventions or man pages make it even more difficult to figure things out.

I'd say this is another one of those things where taking the time to actually learn it will pay off in the end, but requires you to actually take the time to learn it. And it seems that in the modern computing world, taking time to learn how to use things is a no-no.

Aug 26, 2008

The Illusion of Community

Responding to this article. If you choose to read it, try to read between the lines of the troll-speak. The guy makes a really good point, he just seems to feel the need to say it in a rather immature way.

I'll agree with him that Linux users should stop complaining when other people do things that don't support them (like the Democrats/Olympics using Silverlight). One of the drawbacks of Linux is that there is no support for certain things. If you didn't know this when you chose Linux, you do now. So shut up and accept the fact that Linux is not perfect. Or maybe even try doing something constructive instead of just complaining.

Now to my main point. He says that Linux is not a democracy, it is an anarchy. That is what I think really hits the nail right on the head. Linux is not a united community under the banner of Linux, rather it is a divided battlefield of users flocking under various banners labelled "KDE" or "Emacs" or the like, all of whom will go to great lengths to point out how the others under the same banner of Linux are wrong. And even then, people under the same banner are willing to turn on the group when they decide they don't like where the group is going (this is called "forking"), and then divide the community even further.

Some examples:
I use Ubuntu. I'd probably get called a n00b if I went to a Linux conference.
I use Vim. I'd get shunned by some Emacs users.
I use GVim. I'd probably get shunned by some Vim users. It's graphical, it must be for wussies.
I use NVidia's drivers. I'd get shunned for using proprietary software on my machine.
Yet people like the LinuxHaters author would probably dump me into the category of "Linux user" or "luser" as many of them so eloquently put it. Do I feel like I'm in a community?

Sometimes. There are plenty of great people who are under the banner of Linux. I'd guess they are the majority of people who make up the "Linux community". Yet their voices are all drowned out by the more militant types. I've had plenty of great experiences using Ubuntu forums to get things working, but have seen enough "RTFM" or "winblows/proprietary is teh ghey" to hesitate posting things in there.

One time I mentioned "Ubuntu forums" at the Montreal Linux Users' Group which stemmed a huge rant about how nobody on there knows about what they are talking about (I believe it was called "the blind leading the blind"). I didn't go back to the MLUG. It was not a community, but a group of elitists. That has been my perception of the Linux community.

So if you choose to go with Linux, remember that there are a lot of people out there worth ignoring. Linux itself is a good thing, and the community has it's moments, but I wouldn't list the community as a benefit of using the OS.

Aug 25, 2008

JRuby

Today I've been messing around with JRuby. I meant to check it out a while back, but have been procrastinating, and finally have gotten to it.
For those of you who don't know, JRuby is an implementation of Ruby in the Java Virtual Machine. It can access all the Java core library classes, which is pretty damn sweet.

Here's my setup:
Ubuntu 8.04 64-bit
Athlon X2 6400+
Ruby 1.8.6
JRuby 1.1.4
OpenJDK 6b11

So you may think, "oh, it has access to the Java libraries. So what? Ruby has tons of libraries." Well, Java has more, so it's always beneficial to have access to that.

Here is my main reason though. I made a little script that looks like this:
require 'benchmark'

def pythag(n)
result = []
(2..n).each do |c|
(1..c).each do |b|
a = Math.sqrt(c*c - b*b)
result << [a.to_i, b, c] if a.to_i == a
end
end
result
end

puts Benchmark.measure { pythag(5000); pythag(5000) }
Actually I didn't write it, I stole it off a comment from this article here. But anyway, check this out:
rob@alien:~/Programming/jruby$ ruby benchmark.rb 
40.750000 2.550000 43.300000 ( 43.440552)
rob@alien:~/Programming/jruby$ jruby benchmark.rb
14.920000 0.000000 14.920000 ( 14.919958)
I almost fell out of my chair. JRuby is over twice as fast! I was expecting that they'd be about the same, or JRuby might be a bit faster, but no. Over twice as fast. Damn.

You may notice I called pythag twice. I did this to see if it would make a difference because of JIT-compiling, and it doesn't seem to. Here's the output if I just call it once:
rob@alien:~/Programming/jruby$ ruby benchmark.rb 
19.560000 1.170000 20.730000 ( 20.934664)
rob@alien:~/Programming/jruby$ jruby benchmark.rb
7.999000 0.000000 7.999000 ( 7.998930)
Pretty much half as long.

I'm hoping to start running some other benchmarks. Here's another one I tried:
require 'benchmark'

def load(file)
words = {}
File.open(file, "r") do |f|
f.each_line do |l|
l = l.split(/[\s,\.!\?\"\';:]+/)
l.each do |w|
w = w.downcase
words[w] = (words[w] ? words[w] + 1 : 1)
end
end
end
words
end

puts Benchmark.measure {
words = load("kingJamesBible.txt")

words = words.to_a.sort { |a, b| b[1] <=> a[1] }

for i in 0..10
#puts "%s: %d" % [ words[i][0], words[i][1] ]
end
}
And the results:
rob@alien:~/Programming/jruby$ ruby benchmark2.rb 
2.370000 0.120000 2.490000 ( 2.487271)
rob@alien:~/Programming/jruby$ jruby benchmark2.rb
2.570000 0.000000 2.570000 ( 2.570358)
This time JRuby took longer. Not sure what to think here! Maybe it's fast in certain situations but not so fast in others.

Did you know the words "shall" and "unto" appear more often than "for" or "I"? Weird.

Aug 23, 2008

Installing OGRE on Ubuntu

I've been messing around with this C++ library called Ogre, which is a fancy 3D rendering library. It's great for building cross-platform 3D applications where you don't want to have to worry about a lot of the lower level details of 3D programming.

I found that it was a bit of a pain to install on Ubuntu. You can get the packages in Synaptic, but sometimes they are out of date, or there are a few libraries that work together but different versions are incompatible, etc. So I decided the best option was to roll up my sleeves and compile it on my own.

Here's what you have to do: get CEGUI, Cg and OIS. CEGUI is a widget library designed for 3D applications. It's not required for OGRE, but I think it is definitely a good thing to have. OIS is an input system, you use it to interact with the keyboard/mouse/joystick/etc. You can also use SDL for this, but SDL comes with a whole lot of other stuff that you may or may not need. Cg is Nvidia's shader language, from what I've gathered the Ogre guys highly recommend it.
You'll have to compile these guys from source, using the old ./configure + make + make install routine. No big deal. If there is no configure file, then use ./bootstrap first.
One problem with using CEGUI from the Ubuntu repositories is that it is set to use the Xerces XML parsing library. Unfortunately for some reason there are some issues with this, so you have to compile CEGUI yourself and tell it not to use Xerces. It'll probably default to Expat (another XML parsing library) which works well. Use this line instead of the normal ./configure:
./configure --disable-xerces-c
and off you go. OIS should install without any problems, as should Ogre. Cg doesn't even need to compile, you just copy the tarball to the root directory and extract it.

Once you've got everything installed, you might have some issues getting things to compile. Type this:
pkg-config --cflags OGRE OIS CEGUI
It should output something like this:
-DOGRE_GUI_gtk -DOGRE_CONFIG_LITTLE_ENDIAN -I/usr/local/include
-I/usr/local/include/OGRE -I/usr/local/include/OIS
-I/usr/local/include/CEGUI
These are the include paths to the libraries you just installed, and you'll need to use those flags when you compile your OGRE program. So when you create your makefile, put
CXXFLAGS = `pkg-config --cflags OGRE OIS CEGUI`
LFLAGS = `pkg-config --libs OGRE OIS CEGUI` -lCEGUIOgreRenderer
You have to put the -lCEGUIOgreRenderer if you're using CEGUI, it's the way Ogre and CEGUI communicate with one another.

One final hiccup is that Ubuntu doesn't know where to look for the shared object (.so) files once you've gotten your program to compile. They are in /usr/local/lib, but Ubuntu normally puts things in /usr/lib. So you have to edit /etc/ld.so.conf file and add the line:
/usr/local/lib
at the end. You only need to do this if you have issues with your Ogre app loading the shared objects.

And finally, you need to tell Ogre where to find the plugins. In your plugins.cfg file in the folder where your Ogre app is, make sure that the PluginFolder value is set to /usr/local/lib/OGRE.

Once you have all this going, there are some very well-written tutorials on the Ogre wiki. You should have some good stuff up and running in no time!

Aug 21, 2008

How C-61 Affects You

For those of you who don't already know, Bill C-61 is a bill proposed by the Conservative government in June. It hasn't yet passed since Parliament is on their summer getaway, but they'll be talking about it once everything resumes in September. Essentially it is a reform to Canada's copyright laws, which as it stands are fairly relaxed when compared to other nations like the USA. The Conservatives want to "improve" the copyright laws here to reflect the vast changes in technology since the last copyright bill was passed in the mid-90's.

I believe this bill reflects the Conservative party's desire to restrict consumer rights, promote big-business and stifle innovation and freedom of choice.

How will it affect you? Well, the bill states that you can do things like format-shift (which means things like copy music from a CD to an iPod) and time-shift (which means save to watch later, like recording the hockey game or something), provided there are no digital locks (ie. DRM) on the media. This has some far-reaching consequences, basically it gives power to the producers of the media to remove the rights of the consumer simply by putting digital locks on things. Use, creation and distribution of programs that circumvent these kinds of locks will be illegal. Furthermore, the producers are not required to specify whether the media they are producing has locks or not. So consumers have no idea if they can legally "format-shift" from a CD to their iPod.
This leads to the discussion of how C-61 stifles innovation. Take an innovative product like the MP3 player (I won't restrict this just to iPods). If you go out and buy a CD that is DRM'd, then you can't use that CD on anything except a CD player that supports the DRM. No ripping it to your iPod, no copying it to your computer (last I checked Windows Media Player automatically ripped music CDs when you put them into your computer, so you could be screwed just by putting the CD in!), no freedom in how to use the media you legally bought. What are the consequences? Well, it may just destroy the CD market. How often do you see people with CD players vs. MP3 players nowadays? Every time I get on the bus, I see people with the white and grey iPod buds in their ears. These people won't be able to put music on their iPods if they can't rip music from their CDs, so they might just stop buying CDs and go with online music stores like iTunes.
One risk of this is that people may buy music from an online reseller for their specific hardware, but that music is encrypted to only work with that hardware. So the next time something nice and shiny comes out, none of the music you already have can be put onto that shiny new thing unless it also supports the DRM scheme that the older hardware uses. But it'd be illegal for the people creating the new hardware to reverse-engineer the old hardware to see how it works, so they'd have to get permission from the people who made the old hardware. Let's give three cheers for barriers to entry!

You won't be able to make backups of CDs/DVDs. You won't be able to make a mix of your music for driving in the car, unless you destroy the CD after you listen to it (also any CDs you ripped to get the music can't have any locks).

A random note, not sure if this is entirely true but I think that the fine for ripping music off a copy-protected CD is higher than the fine for downloading music from a P2P network. So why not just download the music? Oh yeah, and on the topic of P2P networks, if you so much as open a program like Limewire and have something shared, or use BitTorrent at all, then you could be subject to a fine of up to $20k.

The time-shifting thing is pretty nice, you can record a TV show for later viewing. Problem? After you watch it, you have to destroy any copies! Darn! Oh yeah, and only you can view it, you can't give it to your friend. So taping a show for your friend who is at work when the show is playing is illegal. Hopefully they don't lock down the hockey games, that'd cause a riot here in Montreal! Not that anybody misses the hockey games here.

Another random use of media: I want to build a media PC (you can get some nice looking mATX cases that would fit really well under your TV) that sits in my living room. I would use it for watching videos, but I would like to be able to copy movies to it in order to watch them without having to look for my DVD. Can I do that? Nope! Well, if the DVD isn't copy-protected I can't, but I think a lot of the DVDs out there are (let's not even start with Blu-Ray). Want to convert your now-obsolete HD DVDs to Blu-ray? Nope! Against the law.
I also would like to watch copy-protected DVDs under Ubuntu. However, I believe that you need to crack the DRM in order to watch the DVDs. Can I do that under C-61? Nope! On a side note, does Windows XP need you to crack the DRM too? That would also screw those people who are "downgrading" to XP from Vista, or all the people still using XP. So I'd have to buy a copy of Vista for my media PC. But then Vista could say, "your hardware is not authorized" and shut you down. So much for my media PC idea (this would work fine if you can use XP legally to view videos).

This is not just confined to music and movies. Suppose you're a student, and you want to cite a passage in a copy-protected PDF. In order to do this, you need to get permission from the writer. For students who are on deadlines and have to write papers with at least 15 (arbitrary number) citations, this gets a little unmanageable. Contacting the individual could be difficult to impossible, and they could just flat-out refuse. It'd be just great to fail your thesis because the key authors you're citing decide they don't want to give your permission to cite them. And think of those poor authors, they'd spend so much time answering student emails/phone calls that they'd never have time to do anything else!

So yeah, apparently it is necessary to reform our copyright law. The people who are selling copyrighted works for profit (don't get me started on the recording industries. They make tons of money off of other people's works) are being unfair and probably should be cracked down on. However I believe that C-61 will harm the average citizen much more than these other people, considering pretty much everyone I went to school with downloads music/movies. Damn those educated ones!

If you are a Canadian and would like to preserve your rights as a consumer, then I suggest you get up and start doing something about this. There is a fair copyright for Montreal group that meets every 2-3 weeks (site), and most other cities in the country have something similar (to the best of my knowledge). There are Facebook groups (for Canada, for Montreal), blogs, you could write a letter to your MP (especially if they are Conservative or Bloc Quebecois - make sure you're French for BQ, or they probably won't listen to you - I believe that the Liberals and NDP are against the bill but you may as well send it to them too), there are many things you can do.

EDIT: Here's one Conservative who gets it.

Aug 20, 2008

100 Posts

Many bloggers who get to 100 posts like to give some sort of celebration, and I am no exception. This is the 100th post I will be publishing. It's not the 100th one I've written, since there are a bunch that haven't been finished, or didn't really meet my quality standards for me to actually want to post them.

I would have to give thanks to Jeff Atwood and his talk at CUSEC 2008 about blogging, which basically inspired me to write more and not really care what people think. I do find it somewhat ironic that I'm thanking him, since I have criticized him before.

His argument is this: there is a certain number of people who will potentially be affected by your contributions to the Linux kernel, or open-source world. There is a certain number of people who will potentially be affected by your blogging. What do you think is bigger?

Essentially, you have the power to impact more people with your writing than with your code. Not to mention it is a fair bit easier to write blog entries than it is to write programs. Finally, writing a lot will make you a better writer. No doubts about that. So what are you waiting for? Hop on it and start blogging!

Aug 13, 2008

Dynamic Typing in...C++?

This may be old news to the C++ folks, but to users of dynamic languages like Ruby or PHP who tend to look down on C++/Java for their static nature, this is definitely a welcome aspect.

One of the more prominent extension libraries to C++ is the Boost library (or I should say libraries, as it is more of a collection libraries). If you're not familiar with this and you work with C++ at all, you should definitely take a look at this guy. Or if you're someone who tends to bash static languages, you should educate yourself a little on what they are capable of.

The boost::any class is a class that can hold a value of any type. For example:
any x = 5;
// .. do some stuff with x
x = string("awesome");
Of course, it is not always so easy. There are a few problems. One, if you want to use the value anywhere, you need to cast to the needed type:
any x = 5;

cout << any_cast<int>(x) << endl;
You can't put arrays in. Doesn't stop you from putting a pointer to the first element, but it is a little annoying:
int y[] = {1, 2, 3, 4};
any x = &y[0];

cout << any_cast<int *>(x)[0] << endl;
Despite it being annoying, it gives you a whole heck of a lot of flexibility compared to pure static types, and more security over void pointers. The any_cast function throws an exception if you try to cast to something that isn't compatible.

This isn't the same as an actual dynamic language, but it is a nice little trick to have in your toolbox when programming in C++.

Aug 12, 2008

Experience, experience, experience

One thing that I've learned about the software industry is this: in order to get experience, you need experience.

From a business perspective, this makes sense. You want the employees working for you to know what they're doing, before they start working for you. Come on, paying people to learn? Blasphemy. They have to spend enough time learning the new software.

Unfortunately it seems like a lot of the time the people in charge of hiring don't know what they're talking about. Even if it's programmers in charge of hiring. Imagine some senior programmer interviewing somebody and they go "psh, this guy doesn't know about advanced function X in the standard library, he sucks." Of course, it takes like 2 minutes to learn about function X, but that detail might be ignored.
It's even worse when you're dealing with business-people. Things like "we require 5 years of Ruby on Rails experience" or "10 years experience maintaining Ubuntu systems."

This was a problem when I first started looking for a job. I did have experience, although nothing professional. Which meant that it didn't count as experience. I was amazed at how often I would say "I just graduated from university" and people would go "oh, sorry we want somebody with more experience." I mentioned on both my cover letter and on my resume that I had just graduated. You'd think they'd notice that kind of detail.
Now I'm looking for something else. I applied for a Rails job the other day, and was told I didn't have enough experience. You'd think after making this site1 I'd have enough experience making pretty much 99% of the sites out there, but apparently not.

It's even worse if I want to move out of any web job. I've got loads of C++ experience from academic and personal projects, yet if I apply to a C++ job they want to see who I've worked for. That's annoying. It seems nobody wants to hire university graduates who have no professional experience. But my question is: how are we supposed to get professional experience if nobody will hire us because we have no professional experience?

Fortunately one way you can judge the value of a job to you is by what the interviewers look at when they talk to you. For me, one great aspect of a job is that you're always learning. If they test you on things that are not easily learned like problem solving ability2, then you know that they are people who know what programming is all about and that you will probably be learning, and getting challenged often. But if they ask about API-specific tricks that only a grizzled veteran would know, chances are they just want you to come in, do your day job ASAP, and get the heck out of there. Learning is to be done on your own time.
Of course, don't think that this is the only way to judge the value of a job, but keep it in mind.

1 Ok, it wasn't just me working on this site, there were a couple others too. I did a lot of the work on the framework (more details) and the front-end logic (as opposed to the front-end display, aka the HTML/CSS bits...*shudder*).
2 Stuff that is good to ask here are language-agnostic things like Fizzbuzz, or maybe a trick question like "how would you make an AI always win at Go?" (I'm just kidding with that one). Basically something that tests their basic coding skills. However, I am surprised at how many people can't write code that swaps the value of a variable.

Aug 11, 2008

Idiots on Both Sides

Normally, I try to ignore flame wars between Linux advocates and Windows advocates. Today however, I did stumble across some sites like this one (which links to Linux advocate sites) that take a side and argue it vehemently (in my opinion half the stuff they say is just to get a rise out of Linux geeks).

Both sides have things in common. They see the flaws on their own side as minor, and the flaws on the other side as major. I want to talk about some of these flaws and I'm going to try to take an objective approach to it.
A little description about my history: I used to be on the Windows advocate side. Many of the arguments that the Windows advocates make are ones that I used to make as well. And some of them I still make. Now, I use Ubuntu at home, and Windows at work - although I would prefer to use Ubuntu at work.
On a side note, I'll point out one difference between the two groups. People on the Linux side love Linux and hate Windows. People on the Windows side just hate Linux, they don't seem to show a great love for Windows other than "it does what I want it to do".

Why is Windows better than Linux? Here are some of the reasons given by the Windows side.
  • Easier to use - I won't entirely agree with this one. I do think that there are a lot more things in Linux that have a steep learning curve, but for general use I don't think either is easier to use. My girlfriend uses Ubuntu (of her own volition believe it or not, she asked me to install it) and now has trouble when using Windows because it is unfamiliar. I feel the same way when using a Mac.
  • Better hardware support - This one is true for newer hardware, since many hardware manufacturers don't really have Linux as a priority. Getting my Logitech webcam to work with both the camera and the microphone was a huge pain, and it still doesn't work in a lot of programs. If Linux gains more market share on the desktop this may change, but for now it is a problem.
    When I look back though to when XP came out, it didn't really work too well either. My hardware gave it a blue screen on install - I had to take all of my hardware out except for the essentials in order to install the OS (this was back before everything was onboard, so it was a fair few pieces). Then after I installed the OS, I had to reinstall the hardware - which was not detected of course - and get all that working.
    Windows has better hardware management. The device manager is wonderful. While you can do the same things in Ubuntu with modprobe/lsmod/lsusb/etc. there is nothing that really parallels for it. What gives Windows its edge is that the device manager not only sorts things into human-readable categories (Ubuntu gives a lot of extra information that is useless to me), it also points out what hardware was detected, what isn't working, and a brief description as to why it isn't working. This means that I can spend less time figuring out why it isn't working and focus on getting it working.
    I do have to say that Linux has Windows beat in that once you have a driver, you don't have to restart the damn computer after you install the driver - you might have to restart X in the case of video drivers, but logging in and out is faster than a restart.
  • Better media support - Windows has built-in support for MP3s and encoded DVDs. Windows Explorer detects the type of media that is in your folder (even XP does this) and gives you different columns, etc. to better manage the media. Windows easily has Linux beat here. However, Linux has Windows beat on a few things. If Windows doesn't support a codec out of the box, you have to find the codec and install it - Windows Media Player shows that little "searching for codec...error downloading codec" thing that always seems to fail. With Linux (or at least Ubuntu), it actually gets the right codec you want and installs it. Also a neat thing is in Ubuntu when you mouse over a music file in Nautilus (the file browser) it starts playing the song until you move the mouse away. I could see that being cool for when you have LAN parties and are browsing a friend's computer for stuff to yank.
  • App Consistency/Interactivity - Applications in Windows play better together and act more similarly than ones under Linux. Yup, it's true. Especially when the programs you like are a mix between KDE and GNOME programs. One annoying thing in GNOME is that if I use single click to activate instead of double click, it doesn't propagate everywhere. In file browsers for programs I'm still required to double click. Not a huge issue, but inconsistent.
These are all the ones that I can think of off the bat and it's quite a few.

Why do people choose Linux over Windows?
  • Malware - Windows has viruses. Linux does too, but not as many and they're much less dangerous. Of course, you could say it's because Windows has so many more users, but I've written about this before and I don't think it is simply a matter of market share, there are several other factors. Speculation aside though, the fact is that when running Windows there is a problem with viruses, with Linux there is much less of one.
  • Freedom - You don't have to pay for Linux (at least not with money). You don't have to pay for updates, or new versions. Furthermore, you don't have to pay for a lot of the software for Linux. Even further, a lot of the time you don't even have to pay for support, as there are plenty of helpful, articulate people on places like Ubuntu forums that are more than willing to help you out (I will talk about this one more later in the article). Finally, you don't have to worry about being locked out from stuff you paid for because the damn pirates are draining the cash coffers of the makers - mainly because the makers couldn't care less if people pirate the software (is it even possible to pirate open-source software?).
    It's not just about money though. The limit that you can go with Linux is the limit of your knowledge, and the time you're willing to invest. You can dig deep into the code and change pretty much any functionality you want - proprietary drivers aside. Not only that, but you can tell all your friends about it, and give them your change. Or you can publish it on the Internet, and have other people use your change. Of course, if you're writing drivers then you might have to worry about getting sued, but that's not really OS-specific.
  • Software Repositories - Mmm. I really do love package managers. You have a nice secure location that handles both the installing of software, and the updating of it. When I use Windows, I now find it a bit annoying when I actually have to go to someone's website to download their software and install it. Like come on, that's so last decade. Or earlier this decade.
    There are some downsides to package managers, mainly that they aren't completely able to keep up with the updates done in software, but for the most part it's alright.
There is still another huge issue that I've glossed over until now: the Linux community. Linux users will say that their community is a good thing, that it helps people learn and is a much better approach to software than the producer-consumer model of the non-open-source world. But then Windows advocates will go and say that the Linux community is one thing that is holding Linux back. They are immature, don't understand economics, not very helpful, etc. etc. etc.

Both sides are right. However they are both wrong in that they seem to see the community as a monolithic stereotype of geeks. There are plenty of people in the Linux world that are nice, helpful and actually competent at telling people how to do things properly. The advocates of Linux will then point to these people saying why the Linux community is so awesome.
But then on the other hand, you have your open-source zealots. The people who love Linux and don't just stop with loving it, but trying to stuff it down everyone else's throats. They lose sight of the fact that Linux is about choice, including the choice not to use it. And they give the rest of us a bad name. Or there are other people who are great coders, but aren't so great at explaining things in non-technical language. Or the people who will code a program, release it as open-source, and then are expected to provide support for their program from the masses of people who seem to think that the programmer owes them something. These are the people that the Windows advocates will point to and say, "Linux community bad!"

Looking at my list of reasons, it seems like the list to not use Linux is longer than the list to use it. So why do I use it? I've answered this before, but what it really comes down to is that when I'm using it, I like it better. I know how to use both OSes fairly well, so usability issues don't get in the way anywhere. I find that I get 95% of things done faster or with less effort under Linux than under Windows. This is not a scientific observation, nor do I have much proof of it, it is just more of a feeling that I get while I'm using either OS. There are the 5% of times that Linux is slightly more annoying, and I've written about those times in past (although looking back some of them aren't really that justified, just me being a whiner). However I'm not going to let that 5% make the other 95% suck.

In the end when criticizing Linux, remember what you had to pay to use it: nothing. You might have had to spend time with it, but it's not like time is that vital (what else would you do, watch TV?) So yeah, the developers don't really owe you anything. Don't act like they do.
At the same time though, I wish so many Linux people would stop hyping it up to be better than it actually is. I like Linux and all, but that doesn't mean there aren't times when I want to throw my computer out the window. It is not a silver bullet and there will always be things that Windows does better.

Aug 5, 2008

Pricing and Downloaded Music

I was reading Slashdot the other day and inevitably there was an article regarding the RIAA. I remember some commenters saying how prices of music have to rise in order to make up lost money to the record companies and artists.

This is completely preposterous. The people making statements like this are either trying to start a flame war, or have no understanding of basic economics. I have two points to make here.

First, on demand. Suppose there are x albums out there that have had songs downloaded. According to these commenters (and also it seems, the record companies say the same), that means that there is a total of px dollars lost. This is completely false. Let's look at x, which is a number of albums. If these people had acquired the albums by paying for them, there would not have been x albums bought, since by the law of demand there would be someone, somewhere who wouldn't have thought the album was worth p. Some twelve year old whose parents refuse to buy them rap music, or somebody who did legitimately buy a bunch of CDs but decided to download some other ones they wanted.
On top of this, we can take into account the elasticity of demand. Albums are not necessary to survival. In fact, they can even be considered a luxury good. Therefore their price is elastic, which means that a change in price results in a much higher change in quantity demanded1, so x albums acquired for free is actually much higher than the amount of albums that would be demanded at price p. In short, a lot of people who downloaded the music wouldn't have bought it anyway, so there isn't as much revenue lost as people say there is.

Now for the second point. These people are saying that record companies have to increase prices in order to make up for lost profits. Let's see why this is silly.
Ignore for the moment the people who downloaded the music, and think only of the legitimate buyers. Suppose you are a legitimate buyer. If the record company is raising the price of CDs, would you want to buy as many CDs? Probably not. You have other things to spend your money on. So therefore, the quantity demanded (and consequently, sold) q falls with an increase in price p.
Looking at this mathematically, revenue r is equal to the price of the good, times the number of the good sold, so pq. However, q is a function of p, so we can write q(p) = b - ap which is the general form of a linear demand curve (not all demand curves are linear, but all demand curves do slope downward and the result is the same regardless of whether it is linear or not). Now:
r = pq = p(b - ap) = pb - ap2
This resulting revenue function is a parabola opening downward, and it doesn't take a genius to know that there is a maximum value for revenue here. So increases in price actually cause revenue to fall!
Then take profits, which are equal to revenue minus cost. However, the cost for producing an additional CD is negligible compared to the price, so we can ignore it in terms of the function2. So profits are essentially a reflection of revenue, and therefore we can say that the company, before we take into account the music downloading, will already be at the optimal point for gathering revenue. If they raise their prices, this will cause profits to fall due to the resulting loss of demand for higher priced items. We'll call this point the optimal production point.

Why do the record companies then sue people for downloading music? Why would they care? The reason being that file sharing online has negatively affected demand. What this does is reduces both the price at the optimal production point, and the quantity demanded. So both p and q drop, and revenue and profit drop accordingly. People no longer demand the good in the traditional sense, as they can just get it online for free. Suing people is an attempt to counteract this drop in demand to bring it back to what it was before.

In my opinion, the media companies will never stop music piracy. They should just bite the bullet and stick with their new optimal pricing point that the free market has given them.


1 For those interested, the formula for the elasticity of a function is f' * x / f where f' is the derivative of f with respect to x, and both are functions of x. It's basically a ratio of percentage changes.
2 A wise reader would note that there is a large fixed cost involved with making a CD, but in this case the company would want to make a large enough revenue to offset these costs. This doesn't affect the function, but rather limits the domain of p to be between two values. Also, we can assume that marginal cost for a CD (aka the cost to make a new CD) is more or less constant.

Aug 1, 2008

RegExs and Finite State Automata

In my regular browses through the Internet, I stumble across comments, flame wars, etc. Through doing this, I've realized two things: lots of computer-y people don't know about regular expressions (a highly useful tool) and a lot of them don't seem to know what computer science is (having taken comp sci in school, it slightly bothers me when people call something comp sci when it isn't actually comp sci). So I'm going to write about an actual comp sci topic in hopes that at some point I may help educate people. Also I'm writing this because I like automata theory and want to talk about it.

Regular expressions (regexps) are a part of computer science, in the sub-discipline of automata theory. You can probably put them into other sub-disciplines, but this is one where they are used a lot.
So what is a regexp? Many of us use them, or have heard of them. Well, let's compare to math. An arithmetic expression is a list of primitives (like numbers or variables) and possibly operators (possibly, since "5" is technically an expression) including + and *. They are given an input (usually a set of values that correspond to any variables used in the expression) and evaluate to a certain value.
A regexp is similar to an arithmetic expression. The difference is that a regexp doesn't really evaluate to a value as an arithmetic expression does, rather the regexp accepts or rejects the input (you could say it evaluates to true or false).
So what does a regexp consist of? There is an alphabet Σ (alphabets are usually referred to by the Greek letter Σ, pronounced "sig-ma") over which the regexp works. This can be as simple as {a, b}, or more complicated, like Unicode. For simplicity, we will use small alphabets like {a, b}.
Then there are operations. There are three operations with regexps:

Concatenation: /ab/ (I will use / / to represent a regexp). The input is accepted if it is an a, followed by a b.
Alternation: /a|b/ The input is accepted if it is an a or a b.
Kleene Star: /a*/ The input is accepted if it is zero or more as.

We also need to introduce ε (Greek letter epsilon) which means "nothing".

Those familiar with Perl may say, "Hey, there are lots more operators than that!" True. There are lots more than that1. However, these are the fundamental base operators. Like in arithmetic, there are the fundamental operations of * and + from which all other operations can be created2 (like subtraction, exponentiation). All other operations can be made from combinations of these three, and none of these three can be made up from combinations of the other two (I'm pretty darn certain - you can say the Kleene Star is a combination of concatenation and alternation, but regexps have to be finite and Kleene Star is the only way to represent infinite inputs using a finite regexp).
Let's take a look at some others:
+ (one or more): /a+/ is the same as /aa*/
? (zero or one): /a?/ is the same as /(ε|a)/
and you can figure out others.

So these are pretty cool, but we still only have them at a theoretical level. How would we put these into practice? First, we need a bit more knowledge.

Now we move onto the finite state automaton or FSA (also known as a finite state machine, I just think "automaton" sounds so much cooler). These are "machines" that work over an input, and either accept or reject it.
What are these made up of? Well, we still have our alphabet Σ. We also have a finite set of states, Q. Then a start state s which is in Q, and a set of final states F which is a subset of Q. Finally, there is a transition function δ (Greek letter delta - us comp sci kids seem to love the Greeks) which is a function that takes two inputs: a state and a character, and outputs a state3.
The FSA works by starting in the first state s, and then going in steps over the input, consuming one as it goes, and doing a state transition for each one. The FSA moves to a different state depending on what δ outputs. Then once the input is all consumed, it is rejected if the state we are in is not in the set of final states F, otherwise it is accepted.
It's really easy to write a program to simulate a FSA. Here is a simple algorithm:
function doFSA(input, s, d, F)
set q = s

while input is not empty
a = pop first element from input
set q = d(a, q) // this is the state transition

if q is in F
accept
else
reject
Pretty simple eh?

So, how does this relate to regexps? Well, in automata theory there is a proof (that I don't feel like writing out here) that any regular expression can be converted to a finite automaton, and any finite automaton can be converted to a regular expression. That gives us a pretty easy way to simulate our regular expressions!

I've skipped a lot of details here. One that I want to talk about a little bit is non-deterministic FSAs.
A non-deterministic FSA allows two new things. The first is a ε-transition, where the FSA can move from one state to another without consuming an input. This means it can also move back. So you can look at this in different ways: the FSA is in both states; or the FSA's state is indeterminate, ie. you don't know which state it is in.
The second new thing is that FSA's allow for you to end up in different states for the same input from one state. If you're in q2, you could consume an a and end up in q3 or in q4 since the transition relation (in non-deterministic FSAs it is a relation rather than a function) can allow multiple outputs for a specific set of inputs.
It doesn't take much to realize this makes simulating a FSA much harder. Fortunately for us, there is an algorithm on how to convert from a non-deterministic FSA to a deterministic FSA.

The proof that any regexp can be expressed as a FSA involves showing that you can have an FSA that accepts a one-character regexp, and then showing that you can combine these FSAs into larger FSAs that represent the three basic operations of regexps. This creates a non-deterministic FSA, that then can be converted into a deterministic one.

So how is this useful? How does this relate to programming or Ubuntu? It doesn't really. But I think it's good to know how things work, or where our tools come from.

1 Perl regexps are not true regexps in that they let you use forward matching and that's not something that regexps can do. Second, if you know Perl regexps, I use an implicit ^ and $ in my regexps.
2 See here for some info on why multiplication is not just repeated addition.
3 This is the case for deterministic FSAs, non-deterministic FSAs use a transition relation Δ over Q x (Σ U ε) x Q (that's a Cartesian product).