[1+1=2]
OneAndOneIs2

Mon, May 05, 2008

[Link][Icon]Why bother?

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)

Comments:

Comment from: hari [Member] Email · http://hari.literaryforums.org
I'm not the majority of people.

You didn't get my point at all. Neither am I the "majority" of people.

Even I don't mind going down and dirty with code when I really need it. The key point is "really need it".

The point is I've been more productive with Linux in the last 7 to 8 years purely because I've been able to "work" with it, rather than knowing "how" it works.

Sure, it's great to know "how" sometimes. But unless you wish to become a system programmer, there's usually an easier way to solve a problem and so learning the hard way doesn't make much sense unless you have loads of time and the intellectual curiosity to pursue it.

Sure, I was one of those who looked down on "Interpreted" languages at one time and thought C and C++ were the ultimate, but nowadays with computers become super fast I realize that optimization is not usually worth the effort and it's much better to use a Very High level language to express and idea and code it faster (and produce more maintainable code) than waste time reinventing things like garbage collection or re-implementing a (usually buggy) version of a stack or a linked list in pure C.
PermalinkPermalink 05/05/08 @ 17:21
Comment from: hari [Member] Email · http://hari.literaryforums.org
And don't under-estimate Python before learning it. It's a deceptively powerful programming language.

It's an amazingly simple, yet expressive language which lets you do so much with so little code, yet is flexible enough to let you design your ideas your own way. ;)
PermalinkPermalink 05/05/08 @ 17:30
Comment from: Citronella [Visitor] Email · http://unsubstantialbubbles.blogspot.com
Python is just both more simple and more powerful for me.

More simple because it's high-level. No, I do not want to allocate memory when the language can do it for me (I've spent the most awful months of my coding education fighting with the erratic behavior of a professor's code, until I understood that one of the vectors was one spot too short, and then had an even less happy time trying to get her to believe me). No, I do not want to allocate fixed memory when someone has found a way to implement lists, which size increases each time I append items to them and decreases if I remove items from them. I know that sometimes you cannot avoid the dirty underlying stuff, but the rest of the time, I am quite fine without it. (But it's because I've been struggling with C that I understand bits and pieces of the dirty layers; but it's also because I started with Caml that I learned to like computer science.) In a way, C (or any low-level language) is about programming, while Python (or any high-level language) is about algorithmic. And I like writing algorithms more than merely coding. Which goes back to the difference Hari makes between "working with" and "knowing how it works".

Python is also simpler to use because it is interpreted. No pre-compiling means fixing mistakes more quickly, as far as I concerned. And Python tells you what kind of error the error is and where it encounters it rather than throwing Segfaults at your face that require a debugger.

Python is more powerful as far as I am concerned because it is object oriented. But that would also be why I wouldn't advise to start programming with Python or Java or C++...

And one of the strength of python is to be based on C and interface quite easily with C. Because it's so much slower... so it's quite a good idea to know C to use all the power of python.
PermalinkPermalink 06/05/08 @ 01:13
Comment from: Vincent Povirk [Visitor] Email
No, C isn't a bad language. It has its uses, and it's nice to have that in your toolkit.

Yes, if all you know is Python, you will be stuck when Python is not an option for what you want to do (probably at least 50% of the time when you account for the fact that different projects you might want to work on might not be written in Python). The same thing applies to C.

So by all means, learn C, but make sure you can use other languages too.
PermalinkPermalink 06/05/08 @ 04:47
Comment from: hari [Member] Email · http://hari.literaryforums.org
Yes, I agree completely with the comments above. Citronella makes a wonderful point about algorithmic expressiveness of Python versus the micromanagement of code in C.

Also C is great at a systems level because, after all, it is the language of the base system (in most OSes). But by no means is C a universal language. It's as much universal as C++, Java, Python or other programming languages.

The other advantage of interpreted languages is their portability to different platforms and architectures. Porting C code to different platforms involve using cross-compilation tools and a lot of testing.

PermalinkPermalink 06/05/08 @ 06:22
Comment from: herd [Visitor] Email · http://erduman.de
After you got all this bashing from [pune]garbage collector fanciers[/pune], let me push you in the other direction:

Way to go. Do not stop at the C level. Have a look at assembler programming:

.CODE
AddIt:
POPA # Store 5 in accumulator
POPX 5 # Store 7 in register X
ADC X,Y # Add with carry, result in Y
BCS :OverFlow # Goto overflow handler if carry=1
MOV Y,A # Move result from Y to Acc
RET # guess
OverFlow:
.... # omitted for brevity
RET
Main:
PUSH 7
PUSH 5
CALL AddIt
PUSH [fmt]
PUSHA # return value was passed in accumulator
CALL [printf]
STA 0
RET
.RESRC
.DATA fmt "And the return is %d\n\0"


Reverse polish notation expanded all the way through.

Thing is, C is, by all means, the most universal language available. Because it is just a glorified macro assembler.

Porting todays C compilers to new architectures is easy compared to porting python or C# libraries that make use of platform specific C libraries underneath.

All those abstraction layers of high level lingo are like horse's blinkers - purposeful, but limiting. Once you know what's really going on and grow a sense of how it will perform in the real world, wear them occasionally to avoid distraction. But if you grew up half blindfolded, you'll have two huge blind spots on the edges of your vision.

A majority of neither knowing nor caring developers is something I am very afraid of, on the bright side they just come in handy to cater for the majority of the neither knowing nor caring users ;)
PermalinkPermalink 06/05/08 @ 12:25
Comment from: hari [Member] Email · http://hari.literaryforums.org
Herd, you just hit the nail on the head.

The majority don't need to know or care.

But I know and care, yet I just cannot be bothered to code in plain C for programs which don't require the power of raw memory access and machine-specific instructions which only C can handle.

For the vast majority, speed of development is as important, if not more, than speed of execution.

Sure, C exists on all platforms, but C code is not necessarily cross-platform if pushed to the extreme.

To code for the common denominator, I'd advise *NOT* coding in C because there is not just one architecture out there, but several (Intel 32-bit, Intel 64-bit, PPC, AMD64, etc. etc.) and a variety of platforms (Windows, Linux, Mac etc.)

To code in C, you'd have to compile for every single platform and make sure it works. But using a higher-level language like Python you are assured that your cross-platform code will work in every platform with a Python interpreter. So your headaches are reduced as far as compiling/linking/testing is concerned.

Why go to ridiculous extremes to prove a point which is dubious in the first place? Machine code/assembly code is the *LEAST* portable option out there because different processor architectures are not guaranteed to have the same instruction set (at least some of the advanced instructions).
PermalinkPermalink 06/05/08 @ 13:10
Comment from: hari [Member] Email · http://hari.literaryforums.org
I am also aware that arguments can be raised against Python for cross-platform compatibility.

It's just that C code requires a lot more work for cross-platform compatibility if it is to do useful stuff with libraries (whereas the likes of Python/Java ship with a very large standard library which has a whole lot of useful facilities).

I've been there before and I know all the arguments which can be raised in favour of C. It's just that sometimes I feel that C is so low-level that it requires more development time and more maintenance over the long term for things which can be easily achieved with other programming languages.
PermalinkPermalink 06/05/08 @ 13:16
Comment from: oneandoneis2 [Member] · http://geekblog.oneandoneis2.org/
Wow. Lots of long comments on this one :o)

I didn't miss your point, hari, but I think you might have missed mine. Take a look back at these comments.

Lots of "This language is better than that language", lots of "cross-platform is easier with..", lots of "development time is shorter with.."

All of which are valid points. None of which actually matter.

I'm not learning C because I think it's a superior language. I'm not learning it because I think it's important that a coder know what's going on 'under the hood.'

I'm not a professional coder, I'm a hobbyist. I'm learning C because I *want* to learn C. I'm learning about what's going on 'under the hood' because I *want* to know what's going on. Because that's the kind of thing that interests me, as well as because I've often found it useful to know.

> learning the hard way doesn't make much sense unless you have loads of time and the intellectual curiosity to pursue it.

That's pretty much the point. I *do* have the time and I *do* have the curiosity. I'm not a professional developer looking for the best language to write software in. I'm a computer geek who happens to want to learn programming.

I don't need to be told how great a language Python is. I know. I have three O'Reilly books on the subject. It was the first language I ever made a serious effort to learn. I'm a big fan of Python. I have every intention of going on to learn it.

AFTER I've learned C.

That was the point of this post. It's not about "Which language is best." It doesn't matter how portable, how maintainable, or whatever else, the languages are.

It's about why *I* want to learn a language for *my* enjoyment. Nothing more, nothing less.
PermalinkPermalink 06/05/08 @ 16:20
Comment from: hari [Member] Email · http://hari.literaryforums.org
It's about why *I* want to learn a language for *my* enjoyment.


I'm not against your hobby, Dominic. I was just ranting because the discussion got interesting... and besides, you did want a discussion, right? Otherwise you wouldn't have posted this somewhat lengthy article in the first place. :-p

I cannot put my finger on it, but somehow I've never understood why some of your articles really rile me up like this. This has happened from time to time and I don't understand the reason. It's not just your opinion, but the way you've sometimes expressed it that has annoyed the heck out of me.

I always knew you're a big fan of "looking under the hood." To be frank, this looking under the hood business has never appealed to me unless there was something specific I could achieve using that knowledge.

You see, even as a Linux fan, I keep asking myself, "Has this been done before and better by somebody else?" and "why is there not an easier way to do this?"

I think it all comes down to our life philosophies which are very different.

And that's why I get rubbed the wrong way when I read some of your articles which come across (to me at least) as very patronizing and get needlessly annoyed.

I apologize.
PermalinkPermalink 06/05/08 @ 16:50

Leave a comment:

Your email address will not be displayed on this site.
Your URL will be displayed.

Allowed XHTML tags: <p, ul, ol, li, dl, dt, dd, address, blockquote, ins, del, span, bdo, br, em, strong, dfn, code, samp, kdb, var, cite, abbr, acronym, q, sub, sup, tt, i, b, big, small>
(Line breaks become <br />)
(Set cookies for name, email and url)
(Allow users to contact you through a message form (your email will NOT be displayed.))

Categories

May 2008
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  

Search

Misc

XML Feeds

What is this?
eXTReMe Tracker

Valid XHTML 1.0 Transitional

Valid CSS!

[Valid RSS feed]

powered by
b2evolution

blank