How good of an idea do you think it would be to teach people Assembly (some variant) as a first programming language? It would take a lot more effort than learning for instance Java or Python, but one would have good understanding of the machine more or less from "programming day one" (compared to many higher level languages, at least). What do you think? Is it a realistic idea, at least to those who are ready to make the extra effort? Advantages and disadvantages?

I think its better suited to people studying computer science and not software engineering / development
–
Imran Omar BukhshFeb 9 '11 at 18:54

1

@Imran I agree in principal, but every college-level program I can think of has degrees in Computer Science which are earned by people who mostly go on to work in Software Engineering. (I'm assuming this question is about a serious basis for a programming career, not e.g. a high-school survey course)
–
GregFeb 9 '11 at 19:01

@Imran - I found that a little surprising. Computer science is surely more leaning towards mathematics and theory? More interested in sets, abstract algebras and asymptotic notation than in bit-fiddling and writing endless repetitions of move-blah-to-blah.
–
Steve314Feb 9 '11 at 20:14

2

Computer Science certainly has abstracts subjects, but it's also very "close to the hardware" in some respects. I once attended LICS, a Computer Science conference. I remember it had papers about data locality of various sorting algorithms which I imagine gives theoretical foundations to the study of practical efficiency of algorithms. Regarding assembly, I personally find it has some resemblance to some theoretical computation models (Turing machines, counter machines...)
–
JohFeb 10 '11 at 12:07

16 Answers
16

It would be difficult to inspire a new programmer with assembly code. A dynamic hello, user website is much cooler with less effort. I'm not saying that the fundamental lessons are the same, but an introductory course is going to have a large inspirational content, or else there won't be a second course.

I remember my early programming courses were taught in Scheme and I was mostly frustrated that I couldn't easily just compile to an .exe and "run" my program (I thought MS Visual Basic was the end-all of programming). It wasn't until years later that I really grasped what a powerful tool I had been playing with. I think that I would have appreciated it more and gotten those lessons down better if I'd had some early experience in something a little more pragmatic at first.

I've seen many students who were vastly more amazed making an LED blink and a motor move.
–
whatsisnameFeb 9 '11 at 19:16

1

@Whatsisname +1, that would make a nice impressive demo, as long as it can be done without getting caught up in the electronics. Of course, that could be done with a higher-level language too i.e. Roomba hacking, if the "driver" were an instructor-provided black box.
–
GregFeb 9 '11 at 19:21

1

Plenty of new programmers were inspired by assembly on the VIC20, C=64 and similar machines.
–
GaiusJun 7 '12 at 10:06

2

@Gaius Not at first! You turn on those machines and you're in a basic interpreter. Assembly comes in after a fair amount of experience and hitting the limits of what basic can do...
–
GregJun 7 '12 at 21:51

1

@whatsisname but you can use something like an Arduino to blink LEDs and move motors without having to learn assembly
–
Ken LiuJul 14 '12 at 2:38

I think it's a terrible idea for both Software Engineering and CS students, and generally anyone more interested in programming than in electronics.

It can be done, but it doesn't mean it should be done. Back in the day, the way to do really cool stuff with home computers was to learn assembly first. That was because of early hardware limitations -- higher level languages just weren't powerful and fast enough. Nowadays, you can do much cooler stuff, in a shorter time, with a higher-level language.

What sounds more interesting, writing a fast prototype for a simple game and toying with variations on an algorithm, or struggling with registers and low-level stuff?

As a pianist, I'd certainly have found it more interesting to jump right in with some songs, but to become decent you need to practice arpeggios, scales, etc. And then to do really groundbreaking stuff (playing with "prepared pianos" and the like) you need to know how the piano works from the inside out. It's all how well you want to know your craft.
–
JohnFeb 9 '11 at 19:18

10

@John at CashCommons: Bad analogy. Starting with assembler is like starting the hammers, keyboard, weights and dampers. And then moving on to music theory (circle of fifths) to explain the black-key, white-key business. Then moving on to yet more music theory before playing a scale.
–
S.LottFeb 9 '11 at 19:22

3

@S.Lott: Ehhhhh ... don't quite buy that. I can write a "hello world" type program in assembly without worrying about transistors. One doesn't need to be a chip designer to be a programmer. The knowledge you're talking about would be foundations for building or repairing a piano, which is only cursorily related to playing one.
–
JohnFeb 9 '11 at 19:33

3

@John at CashCommons: "building or repairing a piano". That's the analogy with assembler. A trivial "hello world" in assembler can be written, but it's just OS API calls -- in effect ignoring all the horrifying details of assembler. For writing I/O drivers, assembler is essential. Same way the hammers and dampers are about building and maintaing, not performing.
–
S.LottFeb 9 '11 at 19:36

1

@S.Lott: Hmmmm ... I guess the particular instruction set does depend on the chip, doesn't it? Good point.
–
JohnFeb 9 '11 at 19:40

One thing is for sure, if the people, learning Assembly first, make it, they will be amazing programmers.

This reminds me of when I learned how to drive. My mom insisted

Learn on an automatic car until you gain confidence, and then you can drive our manual cars.

The reasoning being she didn't want me to be distracted with more than I need to be, all at once.

Apply that to learning how to program, is it necessary to throw everything on a learner all at once? They learn what a variable is at the same time they learn how much data they can store in what kind of register?

Over half my class failed our assembly class, and this was a group of people who, at that time, had considered themselves knowledgeable of programming for 2+ years.

My personal preference, if I had to learn everything again, would be to start with a language that does as much as possible for me. Then, as I learn, move backwards towards the lower level languages.

I think this is good and sound advice. At some point it's important to be aware of bits and bytes and what the processor does with them but starting with them is a hugely wasteful endeavor because we have languages like ruby and python that are perfect for beginners and encourage excellent software engineering principles.
–
davidk01Feb 9 '11 at 20:22

1

Have you considered the possibility that the instructor did a less-than-stellar job of teaching the assembly language class?
–
John R. StrohmFeb 10 '11 at 1:32

I don't think it's a terrible idea, but just how complex a program are you going to give these students? Assembly takes a lot more work. It might be OK to start them with for very basic stuff and then move them to something that's easier to work in, once they've gotten an appreciation for working at the lower level. First-time students sometimes get ideas in their head they'll code the next Halo, or MS Office or AutoCAD or something, and when they see how much work goes into a simple assembly language, they could be scared off, so make it clear that there's better things than assembly and then move them to that once they've seen the concepts. You could also try teaching assemlby concurrent with something else like C.

Also, which assembly language? I somewhat recall MIPS was relatively easy to work in, and I think it runs in an emulator so no danger of causing problems to the real machine, though there may be better tools than that now.

Assembly was the first language we learned in electronics school (back in the 1900s) and it seemed like a natural choice. We worked our way up through our courses from discrete components, to resistor-transistor logic, logic gates, integrated circuits, processors, and on to programming in assembly. A lot of the students in these classes had never programmed in any language before and they picked it right up.

So assembly can be a good choice for a first language if the right foundation is laid for the student. For anyone whose goal is to be an applications or Web developer, however, I think assembly is probably too low-level a starting point.

Is it a realistic idea, at least to those who are ready to make the extra effort?

No

but one would have good understanding of the machine

Why is that advantageous? Can you provide an example or a hint as to how this could be of any value?

Advantages and disadvantages?

Advantages: None.

Disadvantages:

A clutter of random trivia about flags and states and registers and complex memory-addressing schemes and I/O devices and DMA and interrupts and clock cycles and stuff. None of which helps understand modern VM-based languages and computing.

A disconnect from actual problem-solving to which computers are actually applied.

An divorce from end-users and the practical data and processing problems they need to solve.

A needless spate of explanations of machine and virtual machine and compiler and interpreter and the entire stack of turtles holding up the world.

A lot of detailed "this is the physical implementation of an 'object'" in the higher-level language that they eventually arrive at.

A lot of detailed "this is how method functions are dispatched" in the higher-level language that they eventually arrive at.

A lot of "this doesn't apply to 80386 but does apply to 80586 chipset" explanations.

A lot of low-level OS API calls to make an ASM program do anything that appears similar to being useful by someone.

The point of a first programming language is not to master the chipset.

@S.Lott - Sure, that's not the point of my original question, but it could be advantageous to have these before you go to the higher level languages. Don't get me wrong, you make a valid point.
–
AntoFeb 9 '11 at 19:31

3

-1 A lot of your disadvantages I consider advantages. It is better to know how the low level works, before you use it from above. Foundations are important.
–
OrblingFeb 9 '11 at 19:53

1

Assembler as a programming language, exposes you far better to data structure, logic and more low level foundations than the higher level languages do. Both have a place, assembler could well be simpler to understand than the higher level languages, providing you did not try to achieve anything too complicated. People should not be trying to do complex things at first.
–
OrblingFeb 9 '11 at 20:03

4

The advantage of assembler is it demonstrates how a real computer works. You know. The thing everything actually runs on.
–
Paul NathanFeb 9 '11 at 20:06

1

@S.Lott - No, but that means that you can very well use most of the old knowledge which you have gathered and add new knowledge over time. Look, high-level languages such as Python come with new versions over time, but old knowledge is still usable (and actually, Python broke backwards compatibility with v3)
–
AntoFeb 9 '11 at 20:27

I used to TA introductory computer science classes, and I think it's a bad idea.

Assembly uses both logic (if this goto that) and very difficult translations between concepts and numbers. Intro CS students often struggle with just the logic (loops, if/else, boolean expressions), and really need to just deal with this before they also worry about which numbers mean what logical expressions. Using higher-level languages abstracts out this logic for students who haven't had any reason to think that way before.

Intro CS classes are not necessarily being taken only by CS majors who will continue on with CS. Often, they are also taken by other engineering majors and non-majors who are just "touring" an interesting subject for an elective. Assembly is great for a foundation for hard-core, committed CS students, but doesn't give a very good overview of what programming often is for students considering the major or who are never going to take the major but want an introduction to the field; nor is it terribly useful on its own in most fields.

Higher-level languages make the core of actual programming work more transparent. Assembly hits some key foundational topics - basic memory concepts, basic performance concepts, etc. - but doesn't really get into creating a maintainable, readable design, which is more important these days, IMO. Early students seem to often have the old-fashioned "Real Programmers write code no one else can handle" ideas, and teaching a higher-level language helps teach that coding is a collaborative task and not just about being brilliant.

Having said that, I do think assembly / computer hardware should be a very early class - ideally, the first quarter in the major. Have students get one high-level language under their belts, then jump into low-level hardware stuff right away before moving on to data structures - ideally in a language that requires management of memory.

If I was tasked to design a curriculum, I would have two courses running at the same time the first semester: asm + basic computer organization/architecture, and a SICP-based course founded in Scheme. The second semester would be oriented around data structures and elementary algorithms in Scheme.

The second year would be a year-long project using one of Delphi, C++ or C#, focused on modern software design (OO design, some functional design, software engineering, version control, etc).

The effect should be to give an intense grounding in both the abstract and the practical, leading out to in-depth courses in the third and fourth years.

Assembly was my second language, right after BASIC. However, when I was learning it was a different time. My Commodore 64 had other languages available, but if you wanted anything to seem fast, or wanted to do more than one thing at a time, you needed to learn assembly language and how to work with interrupts. The Graphic Environment Operating System (GEOS) that gave the Commodore a windowing system was also all assembly. It was by and large the best assembly API I have ever seen. It was also the only platform I used where you could style your code. That's right, you could use italics and different font sizes--something that proved useful for reading the comments.

I learned a lot about how the Commodore worked, but the Motorolla chip had a very simple opcode set. It's not too difficult to keep less than 255 opcodes separate from each other. I was not able to parlay my experience on the Motorolla 6510 chip to programming for the Intel 8086. The chips and system architectures were too different. I imagine I would have had the same trouble moving up to the Amiga's Motorolla 68000 chip as well.

In short, I have to wholeheartedly disagree with anyone who says Assembly should be a good first language. Here's why:

You have no inherent structure, no common way of breaking down functionality in an application. This is the very thing that makes higher level languages so useful.

You have to know useless things like how to call a method in a library correctly. When the library was created by C that means manipulating the stack (better get everything in the right order), but in another language it might mean setting registers. These are all things taken care of by a compiler or an interpreter--and you can't optimize them.

Your code can not be used on another chip, and very likely will break with a different hardware platform.

These days assembly language is used to speed up certain finite actions where hand-crafted assembly would be quicker than compiler generated assembly. The main structure of the application is done in a higher level language like C, C++, etc. Of course, assembly programming would become very important if you start writing compilers. How many of us do that?

I took assembly in my senior year of high school. I had taken classes in Java, Pascal, C and C++ already, and wasn't proficient at any of them and I really sucked at Assembly - was the only person taking the class in a distance learning program at the community college, took me a month or two before anyone could even get the compiler working for me.

I don't think it's necessary or wise to learn assembly language first, but it is smart to learn the stuff they teach you in the first few weeks of assembly, about how the processor works and some of the debug tricks. That stuff I found very interesting and enlightening as a neophyte.

I don't see why it couldn't be done, although how good of an idea it is totally depends on the crowd you would teach it too. Somebody whose end goal is to be a web developer would probably get bored and might quit as it wouldn't give them the immediate satisfaction of creating something that Python, Ruby, etc. would. If they want to eventually work on hardware or other low level projects then I think it would be an ok start (provided that you give enough of a computer architecture background for it to make sense). I think it could help the people write better code in the future, although I think it would be more difficult than learning other languages to start.

I think assembly language is only going to make sense if you focus on things like:

Memory management techniques

HW IO (especially timing and performance related challenges)

CPU features - in particular, security features

Without a focus in this area, it's just a simplistic language that will tend to teach bad organization habits. Machine level coding is good to have in the tool kit to know how things work, but it isn't a good first language.

I would get somebody interested in a higher level language. Then teach C++; then assembly with a focus on how C++ compilers generate assembly code. Understanding v-tables and other higher level language features will go a long way to help the developer think about how languages really work than just filing the information under 'magic.'

Assembly is too tied to hardware issues and memory models to be a useful introduction to programming so if you are going to teach assembly you are better of using some kind of cool widget that requires programming in a low level language like assembly that makes sounds and lights and whatnot.

I'm not sure I agree with your exact reasoning, but I'd like to express my approval of the general principle of 'low level first'. While I wouldn't think teaching assembler is itself a great idea, there's definitely virtue in other low-level activities such as fluency with command-line compilers, examining PE and library formats, the structure of the various system APIs (e.g. Win32) and so on. Learning high-level concepts is easy compared to these things, which often have antiquated and impenetrable documentation, and are pretty damn tricky to understand.

I believe Scheme is the ideal first language. Languages like Asssembly, C, and C++ certainly shouldn't not be taught at first, nor should you start students out with a scripting language like JavaScript because there is more to programming then just scripting.