|
Mon, May 05, 2008
![[Link]](http://geekblog.oneandoneis2.org/img/chain_link.gif)
In reply to some posts recently, questions have been asked such as "Why learn C instead of going straight to Python?" and "Why implement manually something that's in the standard library anyway?"
Rather than just shunt it into a rather long comment, I'm writing a post on the subject. Here it is.
So.. what difference does the language make? Well, let's take the most recent example I've been working on: A calculator.
If you wanted to do addition in assembly, say 6 + 7, you'd have a laborious bit of work to do. You'd have to write code to load the value of the first number, 6, into one memory register; load the value of the second number, 7, into another memory register; and then tell the computer to add the value of the first memory register to the value of the second register and put the new value into a register so you could do something with it later.
In C, which is rather more abstracted from how the computer 'thinks' you can just tell it to create two variables, and print their combined values: int i = 6; int j = 7; printf("%d plus %d equals %d\n" i, j, (i + j)); will do what you want.
In Python? Well, you run the python executable, and type "6 + 7":
Python 2.5.2 (r252:60911, Feb 21 2008, 13:11:45) [MSC v.1310 32 bit (Intel)] on win32 Type "help", "copyright", "credits" or "license" for more information. >>> 6 + 7 13 >>>
Doesn't get much easier, does it?
Thing is.. when I tried to learn Python a while ago, I was hamstrung because there was too much basic knowledge I didn't have. I could understand what the code said, but I couldn't have written it myself because I didn't know enough.
Sticking with the calculator example: I've known about reverse Polish notation for a long time. Erwin talked like Yoda for a while because of its 'backward' way of entering the two numbers and THEN telling the calculator what to do with them.
I couldn't imagine, years ago, what possible reason there could be for something as daft as this.
In a normal calculator, to find out six plus seven, you type '6' '+' '7' '=' and get the answer. In this thing, you'd have to do '6' 'enter' '7' 'enter' '+' 'enter'
How inefficient! Why would anybody set it up like this??
Because it's how computers work. They take two numbers and perform a function on them. A normal calculator has to remember the numbers and what function you want it to perform. Reverse Polish notation only remembers the numbers, and just performs the function.
It's much quicker and easier to do the sum in Python. But it doesn't give you any idea what the computer's actually DOING when it does that sum. It just does it. All cleverly automated and simple.
The trouble with automation is, it only works when it works. When it doesn't, you need to be able to do it yourself.
The other day, I was struck by something printf does: It turns a number into an ASCII string for you. How, I wondered, did it do that? The number 182, for instance, is stored as the binary number.. just a second... 10110110
Yes, I just worked that out in my head. I like binary. It's a sickness.
So.. how does 10110110 get turned into a '1', an '8', and a '2'? How does it work it out?
It tells you, in K&R. Take your number, use the modulus operator to find the remainder when you divide it by the base you want. That gets you the last digit of the number. Add that to the char '0' and you've got your first character. Then divide the number by your base. Repeat.
This gets you the number, the wrong way round. So reverse it, and you've done your conversion:
182 % 10 = 2
2 + '0' = '2'
182 / 10 = 18
18 % 10 = 8
8 + '0' = '8'
18 / 10 = 1
1 % 10 = 1
1 + '0' = '1'
1 / 10 = 0
Reverse '2' '8' '1' = '1' '8' '2'
Why does it matter? you might ask. printf() does it all for you. There's no value in doing it that way round.
And you're quite right. A %d in printf() will turn 10110110 into "182". Quick and easy.
But.. what if you don't want the decimal value? Or the oct or hex.. what if you've been told to print the answer it base 7? Base 18? Base 3?
If you know how the number is converted into a string, this is no problem. Just a slightly tedious bit of coding. If you rely totally on printf doing it for you.. Well, you're stuffed. Basically.
Before I started learning C, I couldn't understand why reverse Polish notation had ever existed. Upon having to write a calculator, I've discovered that it's the easiest way to write a calculator program.
Yeah, maybe I could get by without the knowledge. The world is FULL of people that can write all kinds of software without knowing the nuts & bolts of it.
But the world is also full of people that can't use a language that doesn't do garbage collection for them. It's full of people who can only write code where 9/10s of the work has been done for them by somebody else.
The parallels between writing code and using software are fairly blatant. Take Linux: How successful it's becoming recently, with Ubuntu and PCLinuxOS and Suse etc. The numbers of users are going up all the time.
Because a while ago, people were saying "We've got this really good powerful system, but it takes time and effort for people to be able to use it." And they 'fixed' this problem by automating things, stopping people being obliged to do them.
There was a time when you had to compile a custom kernel to get Linux working properly on your system. There was a time when you were unable to use it unless you knew how to use the CLI. There was a time when virtually every Linux user had an opinion on the "vi or emacs?" question.
Trawl through the Ubuntu forums. See just how many users today have to be hand-held through every step of using the CLI when they have a problem. There are people out there using Linux every day who have no idea how to even get to the CLI, let alone how to use it. They don't NEED to know, and they're HAPPY not to.
Good for them.
I'm not.
For me, a Linux computer without a CLI is worse than Windows. I can cope without Firefox, without Pidgin, without VLC.. but not without bash.
Because whilst things being done automatically by a clever bit of software may work 99 times out of 100... that 1 in 100 time can be a killer.
I once lost my grub config file. I booted up to nothing but a grub prompt. It was a 10-second inconvenience, because I know how to use grub, and I told it where to find the kernel and what partition to make the root, and in less than a minute I was back into my fully-functional Linux OS. The average 'new' Ubuntu user? Wouldn't stand a chance.
XMMS wouldn't start once. No error message, it showed up in a 'ps', I just didn't get anything on my screen. Ever. No message telling me why. It just didn't work. Even re-installing it didn't fix it. I launched it from the CLI via the strace command and discovered it was trying to access a /tmp file. Deleting that file fixed the problem. Solving that problem without the CLI? As far as I know, it couldn't be done.
My computer locked up every time I booted once. It got as far as starting the X prompt, and then froze. So I told grub to pass it the "Don't start X" command, scanned the X error messages with less, discovered that it was crashing because it couldn't find /dev/mouse, edited udev's conf file to create a symlink /dev/mouse to /dev/psaux, and then started X manually. Problem solved.
Solved, not by helpful forums or a nearby Linux guru. Solved by me, because I know how to use Linux without all the GUIs and helpful wizards. Because where some people have only ever used Ubuntu, I started with Slackware, moved onto LinuxFromScratch, spent a long time on Gentoo, and only THEN came to try out Ubuntu.
Yes, most of the time, it's pointless knowing what's going on under the hood. The majority of people spend the majority of time not knowing or caring.
I'm not the majority of people.
I don't like helpful software. I don't like having config files I don't know how to edit by hand. I don't want to just shrug and let the standard library do things without having a clue how it does them. I don't like the attitude of "If a language doesn't fix my mistakes, it's a crap language" which is what most "C is rubbish because it doesn't do garbage collection" arguments boil down to.
C isn't a bad language, and it doesn't have memory management problems. The only problem it has is the age-old PEBKAC one. YOU have to use it properly. Languages like Python are a lot more forgiving, but if all you know is Python, then you're going to have the same problems that a user who only knows Ubuntu has: Sometimes, it WON'T do it for you, and you won't know how to do it yourself.
As the old saying goes: Linux is user-friendly. It's just very selective about who its friends are.
I hope that answers the questions about why I'm learning C, and why I'm learning it in the way I am :o)
![[Link]](http://geekblog.oneandoneis2.org/img/chain_link.gif)
It's a Bank Holiday. May day.
The world has gone wrong: It's warm and sunny. Has been all weekend.
When I went out jogging, I actually wore my short-sleeved top and shorts. And was too hot. And finished my bottle of water before I got back.
Even after a fairly long shower, I was still sweating enough that my shaving foam kept being washed off my face. Once I'd finally managed to shave, I almost wanted another shower to rinse off the sweat that had accumulated since getting out of the shower the first time.
I'm not hugely fond of living in a hot climate. And here I am, planning on heading south for an extended period. Let's hope it'll be easier to cope with when it's not such a rarity :o)
| Mon | Tue | Wed | Thu | Fri | Sat | Sun |
|---|---|---|---|---|---|---|
| << < | > >> | |||||
| 1 | 2 | 3 | 4 | |||
| 5 | 6 | 7 | 8 | 9 | 10 | 11 |
| 12 | 13 | 14 | 15 | 16 | 17 | 18 |
| 19 | 20 | 21 | 22 | 23 | 24 | 25 |
| 26 | 27 | 28 | 29 | 30 | 31 | |