Five questions about programming language design

Five questions about programming language design

Guiding Philosophy

1. Programming languages ​​for people

Programming languages ​​are how people talk to computers. The computer will be happy to speak any language that is not ambiguous. The reason why we have high-level languages ​​is because humans can't handle machine language. The point of programming languages ​​is to prevent our poor fragile human brain from being overwhelmed with a mass of details.

Architects know that some design problems are more mundane than others. One of the clearest and most abstract design problems is the design of bridges. In this case, your job is to cover the required distance with as little material as possible. At the other end of the spectrum is chair design. Chair designers should spend their time thinking about human butts.

Software development has a similar distinction. Designing algorithms to route data through a network is a good, abstract problem, like designing bridges. Whereas designing programming languages ​​is like designing chairs: you have to deal with human weaknesses.

Most of us have a hard time realizing this. Designing elegant mathematical systems sounds much more appealing to most of us than pandering to human weaknesses. The role of mathematical elegance is that some degree of elegance makes programs easier to understand. But elegance is not limited.

And when I say that languages ​​should be designed to accommodate human weaknesses, I don't mean that languages ​​should be designed for bad programmers. You really should be designing software for the best programmers, but even the best programmers have their limits. I don't think anyone would like to program in a language where all variables would be denoted by the letter "x" with integer indexes.

2. Design for yourself and your friends

If you look at the history of programming languages, most of the best languages ​​were designed to be used by their own authors, and most of the worst languages ​​were designed for other people.

When languages ​​are designed for other people, it is always some specific group of people: people are not as smart as the creators of the language. This is how you get a language that speaks condescendingly to you. Cobol is the clearest example, but most languages ​​are infused with this spirit.

It has nothing to do with how high level the language is. C is fairly low-level, but it was created for its authors to use, which is why hackers love it.

The argument for designing languages ​​for bad programmers is that there are more bad programmers than good ones. Perhaps this is so. But this small number of good programmers write disproportionately more software.

I'm interested in the question, how to create a language that will appeal to the best hackers? It seems to me that this question is identical to the question, how to create a good programming language?, but even if it is not, then at least it is an interesting question.

3. Give the programmer as much control as possible

Many languages ​​(especially those made for other people) act like babysitters: they try to warn you against things they don't think will be good for you. I'm of the opposite opinion: give the programmer as much control as you can.

When I first learned Lisp, what I liked the most was that we talked as equals. The other languages ​​that I had learned up to that point had a language, and had my program in that language, and they existed quite separately. But in Lisp, the functions and macros I wrote were the same ones that the language itself was written in. I could rewrite the language itself if I wanted to. It had the same appeal as open source software.

4. Brevity is the sister of talent

Brevity is underestimated and even scorned. But if you look into the hearts of hackers, you will see that they are very fond of brevity. How many times have you heard hackers lovingly talk about how, say, in APL they can do amazing things with just a couple of lines of code? I guess really smart people actually like to pay attention to this.

I think almost anything that makes programs shorter is a good thing. There should be a lot of library functions, everything that can be implicit should be so; the syntax should be more concise; even entity names should be short.

And not only programs should be short. Manuals should also be short. A good part of the manuals is filled with explanations, disclaimers, warnings and special cases. If you need to shorten the manual, the best option is to fix the language that requires so much explanation.

5. Recognize what hacking is

Many people would like hacking to be mathematics, or at least something similar to the natural sciences. I think hacking is more like architecture. Architecture is related to physics in the sense that an architect needs to design a building that will not fall, but the real goal of an architect is to create a great building, not to make discoveries in the realm of statics.

What hackers love is creating great programs. And I think that, at least in our own thoughts, we should remember that writing great software is great, even when that work doesn't translate easily into the normal intellectual currency of scientific papers. From an intellectual standpoint, it's just as important to develop a language that programmers love, as it is to create a terrible one that embodies an idea that you can publish an article about.

Open problems

1. How to organize large libraries?

Libraries are becoming an important part of programming languages. They get so big that it can be dangerous. If it takes longer to find a function in a library that does what you want than to write that function yourself, then all the code does nothing but thicken your manual. (Symbolics manuals were an example of this.) So we'll have to deal with the organization of the libraries. Ideally, design them in such a way that the programmer can guess which library function is suitable.

2. Are people really scared of prefix syntax?

It's an open problem in the sense that I've been thinking about it for years and still don't know the answer. The prefix syntax seems completely natural to me, except perhaps for its use in mathematics. But it may be that much of Lisp's unpopularity is simply due to unfamiliar syntax...Whether it's worth doing something about it, if it's true, is another matter.

3. What do you need for server software?

I think that most of the applications that will be written in the next twenty years will be web applications, in the sense that the programs will be located on a server and will communicate with you through a web browser. And to write such applications, we need new things.

One of those things is support for a new way of releasing server applications. Instead of one or two big releases a year like desktop software, server software will be released in a series of small changes. You might have five or ten releases a day. And everyone will always have the latest version.

Do you know how to design programs to be maintainable? Server software must be designed to be changeable. You should be able to change it easily, or at least know what a small change means and what is important.

Another thing that can be useful in server software is, all of a sudden, continuity of supply. In a web application, you can use something like CPSto get the effect of routines in the stateless world of web sessions. It might be worth it to have continuity of supply if the option isn't too expensive.

4. What new abstractions remain to be discovered?

I'm not sure how reasonable that hope is, but personally I'd really like to discover a new abstraction - something that could be as important as first class functions or recursion or at least default parameters. Maybe it's an impossible dream. Such things are often not opened. But I don't lose hope.

Little known secrets

1. You can use any language you want

Previously, the creation of applications meant the creation of desktop software. And in desktop software, there is a big bias towards writing applications in the same language as the operating system. So ten years ago, writing software in general meant writing software in C. Eventually the tradition evolved: applications shouldn't be written in fancy languages. And this tradition has been developing for so long that non-technical people, like managers and venture capitalists, have learned it too.

Server software destroys this model completely. With the server software, you can take any language you want. Almost no one understands this yet (especially managers and venture capitalists). But some hackers get it, which is why we've heard about indy languages ​​like Perl and Python. We don't hear about Perl and Python because people use them to write Windows applications.

What this means for us, people interested in designing programming languages, is that there is a potential audience for our work.

2. Speed ​​comes from profilers

Language designers, or at least language implementers, like to write compilers that generate fast code. But I think that's not what makes languages ​​fast for users. Knuth noticed a long time ago that speed depends on just a few bottlenecks. And anyone who has tried to speed up a program knows that you can't guess where the bottleneck is. Profiler is the answer.

The language designers are solving the wrong problem. Users don't need benchmarks to run fast. They need a language that can show which parts of their program need to be rewritten. At this point, speed is needed in practice. So it might be better if language implementers spend half the time they spend optimizing the compiler and spend it writing a good profiler.

3. You need an app that makes your language evolve

Maybe this is not the ultimate truth, but it seems that the best languages ​​have evolved along with the applications in which they were used. C was written by people who needed systems programming. Lisp was designed in part for symbolic differentiation, McCarthy was so eager to get started that he began writing differentiation programs even in the first Lisp paper in 1960.

This is especially good if your application solves some new problems. It pushes your language to have new features that programmers want. Personally, I'm interested in writing a language that will be good for server applications.

[During the discussion, Guy Steele also made this point, adding that an application should not consist of writing a compiler for your language, unless your language is designed to write compilers.]

4. The language must be suitable for writing one-time programs.

You know what a one-time program means: it's when you need to quickly solve some limited problem. I believe that if you look around, you will find many serious programs that started out as one-shots. I wouldn't be surprised if most programs started off as one-offs. Thus, if you want to create a language that will be suitable for writing software in general, then it should be suitable for writing one-time programs, because this is the initial stage of many programs.

5. Syntax is related to semantics

Syntax and semantics are traditionally thought to be very different things. It may sound shocking, but it's not. I think what you want in your program has to do with how you express it.

I recently spoke with Robert Morris and he remarked that operator overloading is a big win for infix languages. In languages ​​with prefix syntax, any function you define is actually a statement. If you want to add a new type of number that you've made up, you can simply define a new function to add it. If you do this in a language with infix syntax, you will see that there is a big difference between using an overloaded operator and calling a function.

Ideas that come back over time

1. New programming languages

Looking back to the 1970s, it was fashionable to develop new programming languages. Now this is not so. But I believe that server software will again bring back the fashion for creating new languages. With server software, you can use any language you want, so if someone creates a language that seems better than the rest, then there will be people who dare to use it.

2. Time sharing

Richard Kelsey brought this idea forward, and it's time again, and I fully support it. My guess (and Microsoft's too) is that a lot of computing will move from the desktop to remote servers. In other words, time sharing is back. I think it will need support for this at the language level. For example, Richard and Jonathan Reeves have done a lot of work to implement process planning in Scheme 48.

3. Efficiency

Recently it seemed that computers were already fast enough. More and more we hear about bytecode, which at least for me means that we have power in reserve. But I think that with server software, we don't have it. Someone will have to pay for the servers that run the software, and the number of users the server can support per machine will be a divisor of their capital costs.

I think that efficiency will matter, at least in the bottlenecks of computing. This will be especially important for I/O operations, because server applications perform a lot of such operations.

In the end, it may turn out that bytecode is not the answer. Sun and Microsoft seem to be head-to-head on the bytecode field at the moment. But they do it because bytecode is a convenient place to embed themselves in a process, not because bytecode is a good idea in itself. It may turn out that this whole battle will go unnoticed. It would be funny.

Traps and Traps

1. Clients

This is only a guess, but it is that only those applications that will be completely server-side will benefit. Designing software that works on the assumption that everyone will have your customer is like building a society based on the assumption that everyone will be honest. It would definitely be convenient, but you have to accept that it never will.

I think there will be a proliferation of devices with web access, and it can be assumed that they will support basic html and forms. Do you have a browser on your phone? Will there be a phone in your PalmPilot? Will your blackberry have a bigger screen? Will you be able to go online with your gameboy? From your watch? I don't know. And I don't have to find out if I bet that everything will be on the server. It's just much more reliable to have all the brains on the server. .

2. Object-oriented programming

I realize this is a controversial statement, but I don't think OOP is anything important. I think this is the right paradigm for specific applications that need specific data structures, like window systems, simulations, CAD systems. But I don't see why it should be suitable for all programs.

I think people in big companies love OOP, in part because it does a lot of what looks like work. What can naturally be represented as, say, a list of integers can now be represented as a class with all sorts of scaffolding, hustle and bustle.

Another attractive feature of OOP is that methods give you a kind of first-class functionality. But this is not news to Lisp programmers. Once you have real first class functions, you can just use them in whatever way suits the purpose instead of pushing everything into a template of classes and methods.

I think what this means for language design is that you shouldn't embed OOP too deeply into it. Maybe the answer is to offer more general, foundational things, and let people design any kind of object systems as libraries.

3. Design committee

If your language is designed by a committee, then you are in a trap, and not only for reasons that are known to all. Everyone knows that committees tend to create lumpy, inconsistent language designs. But I think the big danger is that they don't take risks. When one person is in charge, he takes risks that the committee will never agree to take.

Do you have to take risks to create a good language? Many people may suspect that language design is where you have to stick pretty close to traditional wisdom. I can argue that it is not. In everything else that people do, the reward is proportional to the risk. So why should language design be any different?

Source: habr.com

Add a comment