The Drift Away from Low-Level Languages

sort by: newest oldest
January 1, 2009 at 11:18 pm - by devsnapshot (7 Posts)
icon
We're in a time of technological shifts of epic proportions. It wasn't long ago when people were still feeding room-sized chunks of metal simple commands in the form of flimsy, porus paper pieces. Now we have keyboards for the same task. I only see diabolic trickery like this on standardized testing.

I believe the same kinds of advancements have been made in software development and programming. Consider the low-level AT&T Assembly language and the high-level Python language. Assembly language was once the universal language because it was the only language. It gave step-by-step instructions on what registers the processor had to push, and what system calls to make in order to print outputs. How often have you heard of Assembly language in frequent use? Just as often as you've heard of punched cards still fed to computers. The majority of high schools don't teach it anymore. In Assembly, a 'clean' "Hello World" program takes many lines of source code. Each call made is the simplest of those available in the processor itself. An example can be seen here, under section 2.3. http://asm.sourceforge.net/intro/hello.html Why? Well, because there was no other way than to tell the computer every little instruction to execute. I feel the advantage in using this code today is to understanding how the software interacts with the hardware at a deeper level.
Meanwhile, a clean "Hello World" in Python is simply:
print "Hello, World!"
This is easy to understand and I like it for actual development because of its simplicity. It masks all the processor calls and data definitions found in ASM -- but the calls and definitions are still there.
All code is eventually converted to Machine Language. If you open an executable file with a hex editor, that's what you'll see; machine language. It is something that is not meant for humans, but the CPU. Low-level languages like Assembly and C provide the least abstraction from it while high-level languages like Python and Ruby heavy disfigure and cover it.
There is a certain speed tradeoff in high-level languages masking the low-level stuff. Sometimes, they can't provide the most efficient means of following instructions in a program. Most of the time, modern computers allow this to be neglected.
The number of people adept in low-level languages steadily diminishes and code becomes easier and easier to write as languages become more and more masking. This greatly expediates the development process, but may cause a shortage of knowledge in software-hardware interactions.
In my opinion, low-level languages should be limited to scholarly study and cut-throat optimizations, while high-level languages are to be used in real-world development. I take in to consideration the power of modern computers.
June 11, 2009 at 05:55 pm - by CocoaMac (1 Posts)
icon

It is in my belief that both high level languages and low level languages have the same merit. However, to suggest the use of one over the other is simply something that should not be done. 

 In many cases, both work hand in hand. For example, when a finished product needs to be modular and extensible, plug-ins and modules can be developed in a high-level language, such as Ruby, Python, or even AppleScript.  High-level languages are often easier to use for novices and other individuals starting out in the Art, and it allows for quick deployment in enterprise situations. Especially because a high-level language can make a piece of software, coded in a low-level language, hold a longer lifespan. 

 Video games, for example, will employ a high-level language. Titles such as Warcraft III, and The Elder Scrolls, when providing game-extending equipment such as a world editor, will provide that scripting interface for users to use. This in turn makes the product last longer, and become more desirable.

While some programs created in a low-level language may not be easily portable, high-level languages are interpreted and very easily portable. This portability decreases the workload on the developer, should he or she decide to port it to another OS, processor, or even platform. 

February 8, 2009 at 12:59 pm - by ipndrmath (1 Posts)
icon

I'm rather torn in stating whether one should learn assembly as a programmer. As stated before, by comprehending a low-level language, all other languages appear simple and programming quality rises. On the other hand, with such a surplus of languages and their increasing simplicity, more individuals have the opportunity to program. This greatly improves the community as the amount “I have an idea, but don’t know how to program” posts diminish and become “Here is my program, what do you think?” Even better, is when the people that don’t post their ideas begin to program. When someone posts an idea, there is the chance that someone else will like it and program it. For those that don’t post, the idea just sits idle and dies. By easing the complexity of programming, more code is released and new innovations are developed.

I think that High-Level languages are not acceptable for finished, complex projects, but for quick solutions or brainstorming they are ideal.

January 4, 2009 at 12:37 am - by broopet09 (6 Posts)
icon
I absolutely agree with RockyMtnBrain. Undoubtedly higher level languages speed up the process. The wealth of APIs and abstraction from technical nitty gritty is a boon for almost all programming tasks. But you won't really be a great high level software engineer without a low-level understanding. For example, take a very simple example that I read a few months ago in MSDN magazine, where the author had a 2-dimensional array that he was reading. Not much thought goes into whether you would iterate over the columns or the rows first, but he showed how by iterating over each row first, then accessing each column, he greatly increased the efficiency of the code. Basically, every time he accessed a row, it copied that row into the L2 cache. So if he iterated rows first, then all of the column reads were reading from L2 cache. If he instead iterated columns first, it would copy all of the first row, read the first column, trash the first row data, read the second row, read the first column, etc. Of course on a modern computer this isn't a big deal for simple programs, but when dealing with a more complex problem, it might not be as easy to blow off a 30-40% performance boost on an algorithm as "cut-throat optimization." In addition to this example, a common question of data structures in Java comes to mind. To use Java effectively, it is very important to understand the proper times and ways of using all of the different data structures available. Understanding what makes a certain data structure good for a problem is a key piece of being a good Java developer (in my opinion), and is much more valuable than just memorizing what to put where. Of course you can get by on many things without this knowledge, but the higher you get, the more people will expect you to fully understand what it is that you are developing. Just my $.02, -Peter
January 2, 2009 at 01:17 pm - by RockyMtnBrain (76 Posts)
icon

Yuck -- sorry for the poor formatting, I thought I had nice paragraphs and then it ended up all run together.

January 2, 2009 at 02:24 pm - by devsnapshot (7 Posts)
icon
I feel your pain; before, I could format something neatly with
tags, but now that doesn't even work anymore. :( Garbage collectors. I've heard they took hours to clean memory on some machines, some forty-years back and were a terrible pain on machines with Lisp. C++ scares me because it combines the functionality of high-level languages while still retaining C's low-level memory management. If you ask me, I think that's terribly dangerous so I dislike C++, and should probably go learn a functional language better.
January 2, 2009 at 12:32 pm - by RockyMtnBrain (76 Posts)
icon

Interesting post, I think you touched on a lot of things here ...

I've had opportunity to program in both lower level languages (some ASM in school, lots of C in school and after -- although at the time, we thought of C as a "higher level language"!), and higher level languages (lots of Java code under my belt).

One of the differences that I always mention as a great improvement in Java over C is memory management.  In C, the programmer is responsible for explicitly allocating and releasing all "heap" memory.  This is typically done using the malloc() and free() library calls.  This burden on the programmer is responsible for all sorts of program defects, mostly in the form of memory access errors (attempts to read and/or write to memory outside the bounds of a legally allocated block, which typically manifest themselves as fatal errors) and memory leaks (failure to "free" memory that is no longer needed by the program, which manifests as program bloat, causing poor system performance).

Java provides a garbage collection (gc) system, which takes care of returning unused memory to the system.  You are no longer required to track the objects that are in use and explicitly "free" them back to the system when you are done with them; the gc takes care of finding objects that are no longer in use and returns them for you.  Sounds ideal!  And it really is a nice feature.  Does this mean the programmer is off the hook?  Absolutely not!

Think for a minute about what it means for your program to be finished using some piece of memory (in Java, this "piece of memory" is represented by an object).  How does the gc system know when you are finished using the object?  Basically, it checks to see if there are any references to the object anywhere in your program.  Ok, so what constitutes a reference to an object?  A lot of the time, objects are allocated in the scope of a function, and when that function terminates, the reference to the object is gone.  Seems simple enough.  But a program that doesn't have some objects hanging around for extended periods of time during the lifetime of the running process probably isn't very interesting.  So "real" programs are often going to have classes that are holding references to objects, and providing access to those objects so the program can operate on them.  So classes holding "static" references to objects is one way to keep objects around.  Sometimes these classes hold direct references to these objects; other times, the refereces may be indirect, by inserting the objects into data structures such as lists or hashtables, which in turn are referenced directly by the class.

Suddenly things have become a bit complicated again.  While the programmer doesn't have to be concerned with things as "addresses of blocks of alloacted memory", it is still important to be aware that sections of the code are holding references to objects, and if/when those objects are no longer needed, there needs to be a way for the program to release the references to those objects so the gc system can clean them up.  The Java libraries provides "weak references" and data structures that use weak references to help with this, so the program can hold references that aren't considered by the gc system.  But there is still a responsibility on the programmer to understand when it is appropriate to use these sorts of features to avoid memory bloat in the running program.

So, after all that rambling, what's my point?  :-)   Well, higher level languages are a great thing, and their advances and abstractions have increased programmer productivity immensely.  Do I think that every modern professional programmer needs to learn an assembly language?  Not really, no.  But I do think it's still important to understand the structure of a running computer program, that there is instruction code, data code, a heap, a stack, etc.  It's still important today to understand those concepts when you're trying to write efficient, correct code.  And one nice thing about getting exposure to a lower-level language, those concepts are right in your face, all the time.  Understanding those concepts is going to make you a better programmer, a better debugger, and a better troubleshooter, no matter what language(s) you end up using.