Linuxcare Home Your Account-Site Map-Help

ProductsServicesSupportResourcesAbout Linuxcare
Home > Archives > Viewpoints > Open Source Interviews > December 14, 1999
Your accountSite MapHelp

Weekly Columns
Dear Lina

Linux: A User's View

Tales from the Tech Support Pit

Application of the Week

Open Source Interviews

Featured Articles

Book Reviews
Linuxcare Interview

Richard Stallman: The Coder

-- Although most well known today as the father of Free Software and the GNU project, Richard Stallman, a coder of genius, is also the creator of some of the most important programs in the whole software world: GNU Emacs, the GNU C Compiler (GCC), and others. On a recent visit to the Linuxcare offices in San Francisco, Richard Stallman sat down with Nick Moffitt, Dave Sifry and Jim Schweizer to an in-depth interview about OS standards, the GCC, LISP, and a sneak peak at EMACS 21. After the interview, and a helping of the Friday company luncheon, RMS spoke to our staff about the history of the Free Software Foundation and the future of GNU development.

Richard Stallman launched the GNU project in 1984 and created the now famous GNU General Public License. The Free Software Foundation is a tax-exempt charity that raises funds for work on the GNU Project.

Linuxcare: One of my favorite documents on the GNU web site is a talk you gave at Sweden's Royal Institute of Technology in 1986. The way that talk was structured was 1/3 historical, 1/3 technical, and 1/3 social. I was wondering if we could spend a bit of time to discuss the technical part now.

Richard: Okay.

Linuxcare: I understand it's not your focus right now. One of the initial questions I have is since the portability of ITS [Incompatible Timesharing System] failed...

Richard: It had no portability.

Linuxcare: Okay, then in the absence of portability, what really made you think that UNIX was a good idea?

Richard: It was a portable operating system and it had real users on different kinds of machines. So it wasn't just portable in theory, but the portability had been tested. In addition, UNIX had some good ideas by the standards of the day. Nowadays we take them for granted perhaps, but compared with other operating systems that I had worked on they were interesting and powerful; things like pipes and redirection, shell programming, the convenient fork() and exec() system calls; these were an advance. So I thought UNIX was a pretty good idea. Since I had never used it, I didn't know about some of the things that were actually badly designed. There were some ways in which UNIX was a step backwards from the other operating systems I had worked on. For example, the lack of atomic supersede. These days we've pretty much forgotten what that is. It means that when a program starts to write a file in UNIX, it starts by truncating the file to zero length, then it rewrites the contents. This means if somebody tries to read it at that time they will get a half written file. On the operating systems I used in the 1970s, there was no danger of that because the new version would appear instantaneously when it was closed. Until a certain point, anybody reading the file would get the old version, and then instantly it would be replaced by the new version. So anybody reading the file would always get a complete version.

Linuxcare: For example, sometimes it's nice to be able to "tail" a file as it's being created.

Richard: Yes it is. There are some uses in that, but it seems to me that having a special system call you can use to get at a file being written is better than lacking atomic supersede. At least there was some way you could get to look at the file while it was being written.

"I don't like the idea of having security within a shared computer system at all. I also don't like the idea of saying no to everyone by default."
-Richard Stallman

Linuxcare: Doesn't file locking take care of a lot of that?

Richard: To an extent it works. EMACS has the ability to write it under another name and rename it. Of course, there's no other name you can be sure won't cause a problem. There is some ugliness in the design of UNIX, but fortunately most of it is pretty good.

Linuxcare: One of the ugly points you mentioned in the 1986 talk was that of a security model. You explained that rather than make it easy for people to do the right thing, it simply forbids them from doing the wrong thing.

Richard: You're mixing several issues. One is that I don't like the idea of having security within a shared computer system at all. I also don't like the idea of saying no to everyone by default. Now, in fact, I do that. Our computers have security now, and because I am so bitter about what I have done, I'm so ashamed of what I have done, that I treat myself like one of those outsiders. I cannot log in remotely to the new machines. I know a way that I could, but I won't do it because the same maltreatment I am giving to everybody I must give to myself as well out of shame.

Linuxcare: One thing I noted in talking to Richard Stevens was the fact that you were pretty responsible for coming up with the name POSIX.

Richard: Yes.

Linuxcare: Originally it was going to be IEEEIX.

Richard: I was part of the committee, and that's why I knew what it was going to be called. When I realized people were all going to be calling it "UNIX-like," standards for "UNIX-like" operating systems, because they didn't want to say IEEEIX, I decided I had better get them a euphonious name on the double. This was after the standard had been finalized and they were about to officially publish it.

Linuxcare: It might be said that the new system could almost be a reference to the product.

Richard: It could, except that we don't religiously try to follow it. You have the POSIXLY_CORRECT environment variable.

Linuxcare: There are specific examples where POSIX is specifically seen as backwards compatibility.

Richard: Basically, my attitude towards standards is that they are useful. They help users figure out how to support a variety of systems, and then they help system implementors figure out how to give the users what the users will expect. But you shouldn't treat standards as though they were gods. There's no need to. We support standards in the ways that are useful to users, and we depart from them when that becomes more useful to users.

Linuxcare: Can you think of any major coups or major features that were brought to the POSIX table?

Richard: I can't remember any more. That was in the 1980s. However, I do remember one where we didn't succeed in persuading them. This was in the POSIX.2 specification for the utilities. They made a decision that they would follow System V by default, and in System V when you did "df" or "du," file sizes were measured in disk block units of bytes.

Linuxcare: Right; instead of kilobytes.

Richard: Well, it occurred to me that this was not good for anybody, so I asked them if they could please change it for the sake of the users. They said, "No, our rules say we follow System V." So I took a poll and asked users which they preferred, and it was 20:1 in favor of kilobytes. I sent them the poll results and they said they didn't care. Unfortunately, I didn't catch this at a time when I could officially object to it. It was already approved and we had already had a chance to object, so all I could do was make a comment. So I couldn't block approval of the standard because I was a voting member of the committee. I couldn't block approval of the standard on those grounds, so instead... speaking of coups, this was about the time of the coup that eliminated the Soviet Union. So, I posted a notice about the coup in which the evil repressive forces of POSIX were being thrown off, and as we speak, teams of new developers are taking control of the major new utilities because they were making the changes to support K by default. To have an excuse to say that we still support the spec, if you define the environment variable, POSIX_ME_HARDER was the original way. Then a slightly prudish board member convinced me to change it to POSIXLY_CORRECT which I now think was a mistake. I should have left it as POSIX_ME_HARDER.

Linuxcare: I'll ask a stupid question. Have you put any Easter eggs into anything? Just some wacky key code combination or something?

Richard: I did once. It was a joke about the C specification which said #pragma was supposed to do something about implementation design. So I decided that a particular #pragma should do some absurd thing, just to point out that it's ridiculous to use pragma for anything, because you never can tell what it's going to do in some other compiler.

Linuxcare: Which pragma was it?

Richard: I don't remember, but we took it out. There was some pragma that other people were using and we decided to have compatibility to support it. We took that out and made it something that was somewhat useful. The other problem with pragma is you can't use it in macros. This means that for almost all purposes it's a bad solution. To have a mechanism that's guaranteed to be wrong is inappropriate for almost all cases.

Linuxcare: Right.

Richard: I think they finally got the message and started designing other mechanisms that could be used inside a macro extension. We did eventually find one situation where a pragma could actually be used to be appropriate because it was something that never was useful to do in a macro. I can't remember what it is, but I think you might be able to find it in the GCC manual.

Linuxcare: Speaking of GCC, we've got a couple of questions submitted here by somebody.

Richard: Okay.

Linuxcare: To what extent does the basic architecture of GCC need changes to support the language front-ends, such as the new GCC Java compiler?

Richard: I don't know anything about what's happening with the Java compiler. I stopped dealing with GCC around 1992 and I don't know what changes, if any, were needed. Some changes were needed mainly in the tree data structure, which is what programs get parsed into. Occasionally, when you handle a language that has the kind of construct that hasn't been handled before, if there's no way to represent it with the existing tree data structure, you need to add something so you can represent it. Things like methods and core methods needed a way to be represented, so we added them.

Linuxcare: Does GCC still use a LISP-like intermediary language?

Richard: Printed syntax is what's LISP-like. It's not really LISP-like in the sense that it consists of tuples that point to a number of other tuples, which is not by any means a new format for priority use. It's printed out in a LISP-like syntax because that makes it easy to work with in EMACS.

Linuxcare: How did you come to choose LISP as the EMACS engine?

Richard: LISP is the most powerful programming language, and if you want an interpreter, LISP is the best. None of the other languages come anywhere near LISP in their power. The most exciting things about LISP are read, eval, and print. If you look at other languages, they have no equivalent for any of those.

Linuxcare: Why are there so many parameters?

Richard: The minimal set of parameters are small, but on the other hand, there are many standard functions available to do lots of interesting things with lists. With other languages, you need to define exactly the data types you want and define all of the basic things for working on them. Well, they're starting to wise up about template libraries where you can define various kinds of applications, specific list data types, and then have various functions that you can substantiate for any one of those. However, you're still limiting each of those data types you define to using one particular data type for the elements, which is not very convenient. With lists, you have one data type, and you can put anything in any list. You can mix together different kinds of types of elements. It's so flexible.

Linuxcare: One technical point is you don't necessarily limit yourself to a specific set, but the beautiful thing about LISP is that everything is a list.

Richard: Yeah, everything is generic.

Linuxcare: You can build functions using a very small set of primitives. Those functions become useable over lists themselves, or lists of lists and so on.

Richard: Any list of anything in your program and you can have all these built in things that you can do. Not only that, programs are representable as data, which gives you all sorts of convenient, powerful things.

Linuxcare: That's not unique to LISP though.

Richard: Well, it is mostly unique to LISP. Yes, you can write a parser for some other language, and you can invent some data structure to parse them into, but you will have been the one who invented that data structure. There will be nothing you can do on it except the things you provide ways to do.

Linuxcare: That's not true. You can do that in Perl for example.

Richard: Well, with Perl what is their format? They're strings.

Linuxcare: Yeah, you can create strings which are programmed.

Richard: Yes, with string-based interpreters you can represent programs as strings, and you can interpret them as strings, but you can't parse their syntax very easily as strings. In LISP, programs are represented as data in a way that expresses their structure, and allows you to easily do things to the programs that are based on understanding them.

Linuxcare: Right, but you have to count the strings.

Richard: No, you don't have to count strings. Strings are only in a textual representation. When it's data, you have lists that are nested in exactly the same way that the programs are.

Linuxcare: This data structure versus pure list argument is one which the XEMACS people often make.

Richard: They've apparently been indoctrinated by some rather rigid kind of object oriented design philosophy, and they feel they should make as many layers as possible in the program, and at each layer make a whole bunch of primitives to do everything you could possibly want to do. This is a recipe for making a program very big and hairy. Sometimes it's a good thing to do. When the thing has enough hair anyway, then it's sometimes good to make such a data structure. In the 1980s, there were people trying to run it in terms where you could only get an address space of 1 meg. Nowadays, that's an irrelevant design goal, and EMACS is much bigger than it was and that's okay. If it were just technical issues separating us and the EX people, I would be willing to make compromises on those things, but unfortunately it's not just technical issues.

Linuxcare: How much of the current development are you still doing?

Richard: I'm doing a substantial part of it, but not most of it anymore. I found a very good person who I think is about to be hired as an EMACS retainer, who just in the past year and a half rewrote the read/write completely to support variable response and images in the documents, and all sorts of other nice things which seem to work. You'll be able to put postscript into your document and have it display and all sorts of other neat things. We're headed towards word processor.

Linuxcare: Any release dates?

Richard: No. It will be done sooner if you help.

Linuxcare: So what are you doing more of now?

Richard: I have been compelled to involuntarily promote myself into management.

Linuxcare: Which means no more coding?

Richard: Not much coding; sad to say. It's much less fun, but it has to be done.

Linuxcare: Also, you seem to be doing a lot of going out and dealing with issues such as these.

Richard: Exactly. It's the leadership of the movement that I'm doing. Sometimes it involves managing people within new projects, sometimes it involves recruiting, negotiating with other projects, or persuading people to change their licenses. For instance, I worked for two years to persuade Berkeley to change its license to get rid of the obnoxious advertising clause. It took a long time and now it's done, but now we have lots of other people to persuade.

Linuxcare: The BSD people seem to use a new code that they wrote.

Richard: Exactly. I persuaded them a year and a half or more before I persuaded Berkeley. They took to the idea very quickly, so they don't put that into their code, but now they can remove it from the Berkeley code too.

Linuxcare: Getting back to EMACS, I've heard that there are some rather peculiar methods by which it's compiled.

Richard: Well, it has to dump itself out. The reason is to avoid taking the time to load up the standard LISP code every time you start it, so it actually unexecs itself.

Linuxcare: In other words, you compile the base LISP interpreter, then you load up the LISP codes.

Richard: Exactly.

Linuxcare: Do you share libraries at all?

Richard: No. Well, it may if you build it on a system where LISP libraries are being shared. In that case it's using shared libraries, but other than that, no. The C shared library mechanism is not designed to be used to link any LISP codes.

Linuxcare: Is that how LISP programs are normally compiled? To say it core dumps itself sounds kind of frightening.

Richard: No. LISP is interpreted. This is a different issue. This is the issue of: "How can I go out and make something start running quickly?" So much of EMACS's interpreted LISP code is the idea that, rather than starting with something small, having it bootstrap itself, and then start running interpreted LISP, you actually see something pop up on the display. There are about 30 files of LISP codes that are standardly included in EMACS. If EMACS had to load them each time, it would take probably a minute or so to start up. That would be inconvenient.

Linuxcare: It's basically just a snapshot? Okay, it makes an executable file that represents the state of what is in memory at that time.

Richard: Exactly, and that way it starts up like that and all of the loading and preloading... Well, it still takes much longer to start up than we wish, but it's much faster than it would be if it didn't do this. In the old days, it used to take 10 minutes to do that pre-loading. That was really a pain.

Linuxcare: What inspired you to write EMACS?

Richard: It sort of happened almost by accident. Let me give you the whole story. In the early 1970s, what we used for editing was TECO. Except, our version of TECO had a nice display screen feature where at the end of each TECO command string... because the way you used TECO was, you typed a command string which was a long or short sequence of commands, and at the end you would type escape/escape, and that executed all of these commands. In most versions of TECO you never saw what was in your text unless you used the command to type it out. But we had some display consoles, so we put in an automatic redisplay thing where, at the end of the command string, it would display the current area of the buffer on the screen automatically. It would keep track of what was on the screen already, and it would not redisplay the things that were changed. So that made redisplay faster.

"Guy Steele had the idea of collecting the best ideas of the various TECO-based editors, and synthesizing them into one editor. We got together to implement it. After the first night, he dropped out, so I did most of the work. This became EMACS."
-Richard Stallman

Anyway, somebody else decided to implement a real time editing feature where you would type single character commands and they would update the screen immediately. He decided to do this with its own completely separate redisplay mechanism though, which turned out to be utterly unusable and painfully inefficient. It didn't work and nobody used it, so I decided to reimplement that completely and make it display compatibly with the usual redisplay mechanism. So, you'd go into the real time editing mode and you wouldn't see any of your text on the screen change, but then as you typed characters which changed the text, you would see the redisplay happen immediately. I optimized this and people actually started to use it. At first there were only a very limited set of things you could do to your text in this real time editing mode, so you had to edit it to do anything else like delete or save a file.

So, somebody said to me, "How about giving us a couple of characters in the real time editing mode that we can redefine and make them run TECO macros?" A TECO macro was just a command string that you had written in advance to serve as a subroutine that you could call up when you wanted to. So I looked at the idea, and I saw it would be just as easy to let you redefine any and all of the characters.

Linuxcare: Right.

Richard: So I did that, and other people really went to town redefining these realtime editing characters, until eventually just a very few of them were left with their standard definitions. People had written several different packages, essentially editors written in TECO. So TECO had changed from being the editor, to a system for writing editors. Then Guy Steele had the idea of looking at these various TECO-based editors that people had written, collecting the best ideas of them all, and synthesizing them into one TECO-based editor that would end all TECO-based editors. He did a lot of work designing a new command set that would be clean and symmetrical, and then we got together to implement it. Then after the first night it happened, he dropped out, so I did most of the work. This became EMACS, and it basically replaced the other TECO-based editors. When it caught on, other people wrote implementations of the same basic idea, but not using TECO typically. Bernard Greenberg, I believe, was the first one to use LISP as the language to implement the editor in. Then, people working for a system I can't recall, tried the approach of writing their own LISP interpreter and implementing most of the editor in that, and it worked well. So I used that for doing my second implementation of EMACS. Then, to gain portability, I wrote the LISP interpreter, the parts of the editor that had to run really fast, and some editing primitives, all in C.

Linuxcare: Like which ones?

Richard: Well, like insert some text in the buffer, delete some text in the buffer, communication with subprocesses, and so forth.

Linuxcare: Wasn't the LISP interpreter written using lex and yacc?

Richard: No, absolutely not. There's no reason to use lex and yacc to write a LISP interpreter. The syntax is so simple you don't need it. You'd just be making things harder.

Linuxcare: I understand that you had a version on your LISP machine too.

Richard: Yeah, there was an EMACS-like editor written in LISP machine LISP.

Linuxcare: Did you work on the development of that?

Richard: I did some, but not very much except in the later stages in the time of the war with Symbolics. There were some neat features I added, like the selective undo feature where you could select a region and undo the last change in this region.

Linuxcare: Oh, that's cool.

Richard: Now the new EMACS has that feature too.

Linuxcare: What's the key for that?

Richard: You use it with CTRL-U as an argument that requests selective undo. Also, a transient mark mode. When you have a region active then undo the last action.

Linuxcare: So C-u and then what?

Richard: Either C-Xu or C-_.

Linuxcare: Are there any plans to include Guile bindings in EMACS?

Richard: Well, I want to switch over to replace EMACS LISP with Guile.

Linuxcare: Oh, that's interesting.

Richard: Because Guile, which is the new project scheme interpreter, is our standard for extensibility. It's a library. It's designed that you build it into your program, and then you make the lower level parts of your program into added scheme packages. Oh, here's a new feature you can see. You can see here that one of the words in this buffer is highlighted. EMACS 21 supports faces on TTY's.

Linuxcare: Cool.

Richard: It has lots of other neat features too.

Linuxcare: So you're running EMACS 21 here?

Richard: Well the development sources are not finished. We're still putting new features into it.

Linuxcare: It's been a rumor that TECO had such a first impact.

Richard: It was designed to be something you edit with, not designed to be a programming language.

Linuxcare: Right.

Richard: It was really lousy as a programming language. So the lesson of EMACS was, pick a good programming language to write your editor in, and your sensibility language really ought to be designed to be a good programming language. You shouldn't think you should throw away what you know about programming language design. Well, obviously the best programming is LISP.

Linuxcare: Any real words can be considered a TECO macro?

Richard: Yeah, just about anything.

Linuxcare: So you can figure out what your names did?

Richard: I never did that. We didn't have that game. However, I do remember that there was an editor, not TECO, in which the command EDIT {carriage return} would wipe out the text that you were editing because it means "everything delete, insert T." Now if you only did everything DELETE {carriage return} you could undo the change. There was just a one level undo buffer.

Linuxcare: But not with a standard text editor.

Richard: Not on that system. I never edited on a UNIX machine until I had EMACS to edit with. I was at MIT, and there were other things that I could edit with. I could save the files over the net, so I did my editing on a LISP machine.

Linuxcare: Every time, I've heard people say that the reason they're still working on the HURD is because it was a good design and it's almost done.

Richard: Yes. Unfortunately, progress right now is very slow. We don't have anybody working on it full time, and I wish we did.

Linuxcare: What are some of the major big wins?

Richard: Well, the big win is that it's a collection of individual servers that communicate with each other, and each user can replace the ones he or she doesn't like.

Linuxcare: Such as the scheduling, or what?

Richard: Well, the scheduling is actually done inside the micro kernel, but you can write your own memory managers, you can write your own file systems, and you can write your own terminal driver. So, you can replace your own terminal driver. You can't replace somebody else's, and as an ordinary user you can set up additional file systems that you've written, different file names, and then people can open them.

Linuxcare: What advantages would this have over other micro kernels?

Richard: I don't know very much about a lot of micro kernels, but I know that the OSF multiservers were designed specifically to mimic the features of UNIX. That would trap the system call handler, which would send a message to a server, and the server would cooperate to get the job done. As far as the user program was concerned, it would have only the features of UNIX. The HURD was designed to completely expose to the user program the various servers. So something that would be a system call in Unix would just be a function in the library. It would send various messages to get the job done, and you could send messages to those same servers any time you wanted. So, all of the underlying implementation was made available, and you could take advantage of whatever you wanted. In addition, the multiserver derived some benefit of modularity due to the fact that it was divided into these several servers, but you couldn't replace the servers you were using. Only the operator could make an alternate kind of server run. That would be good for debugging a new version of the servers, but it didn't give the user any additional power.

Linuxcare: Can you make reference to the new Mach?

Richard: There is a new version of Mach that we maintain, but we didn't write Mach, and we did that basically once all the work on Mach came to an end.

Linuxcare: Could you expand a little bit on the PDP-10?

Richard: The PDP-10 had several nice things. One is that it was a very symmetrical design. The instructions formed very symmetrical classes, including a number of instructions that were NOOP's. If you hit the class of instructions that were complete, there were a few things that were trivial and didn't do anything useful. In many cases, there were several different instructions that would do the same job just because trivial cases of two different classes of instructions were the same. Another very nice thing about the PDP-10, was that each word of 36 bits was big enough to hold two addresses. In effect, it was designed for LISP, you see. It was the original LISP machine. So, because it was a word addressed machine, you could address a megabyte using just 18 bits, and this megabyte consisted of 256K of 36 bit words, each capable of holding two pointers to other words.

Linuxcare: Right.

Richard: Another nice thing about the PDP-10 was, if you looked at a word, you could pretty much tell from its contents what kind of data it contained, whether it contained text, or instruction, or a pair of addresses, or just one address, or just some number. Typical values were different enough that you could generally tell, and this is a big help for debugging.

Linuxcare: Other than the PDP-10, what would be your favorite architecture?

Richard: As you point out, the PDP-10 was great for its day, but eventually its address space just became too small. There was no way to extend it cleanly to a larger address space, so it really was obsolete. Nowadays, I basically don't pay attention. It doesn't matter so much anymore, and now that you write in something portable rather than assembler language, you have no reason to prefer one architecture to another. Back when everybody was writing in assembler language, it really was much more of a joy to program for the PDP-10.

Linuxcare: Any final thoughts?

Richard: I'm not very good at making up final thoughts.

Linuxcare: Anything?

Richard: If you're trying to debug a program, get into the symbolic debugger as soon as possible. Assuming that you've got a reproducible test case, don't bother wasting any time looking at the cases that don't fail. Just use the debugger to find out what happens in a case that does fail. Use breakpoints, and then stepping, to localize the problem until you see where it's happening. Other approaches that might seem like shortcuts usually end up taking longer. This one is sure and steady, and it will generally find you the problem faster than any other method. But when there is no reproducible test case, then that's a different kind of fish, and you may have to put debugging buffers and save information into your program, so you can get enough information to figure out what happened.

Linuxcare: There was also a program change with the debugger. [Heisenbug]

Richard: Do you know about the bug that depends upon the phase of the moon?

Linuxcare: I've heard about this.

Richard: We always liked to talk about the bugs that depended on the phase of the moon. So, when Guy Steele wrote the Rabbit compiler, which is a scheme compiler, he made it print out a comment at the beginning which showed the time it was compiled and so on, but it also put in the phase of the moon. So, you could always look. If you had a bug that depended on the phase of the moon, you could look at the thing and see at what phase of the moon it was compiled, and that might help you figure out what went wrong. Eventually, he got a bug report about a certain program that had been compiled once, and worked, and when it was compiled at another time it didn't work. So, he looked and he discovered that when the initial comments were printed out, the LISP feature that would automatically put in a line break if a line got too long was activated on one occasion, because the phase of the moon took too many characters to print out. So, it triggered that feature, and the last part of the phase of the moon was on another line, and therefore it wasn't marked by comments. So it was just sitting there in a file, whereas at another time the phase of the moon didn't take up so many characters, and the whole thing was properly commented. So, this was a bug that actually depended on the phase of the moon. You can take that as a final thought.

Hardware Certification Reports

Copyright 1999-2002 Linuxcare, Inc. All rights reserved.