What Is The Future Of Programming Languages?
MrProgrammer asks: "With hybrid languages like C# coming down the pike, what do you see as the next advances to be made in programming? We have languages from Assembly to Visual Basic, covering what would appear to be the entire spectrum. Is there anything else to be added? Is there anything beyond OOP?"
For a mature example, look at Macsyma or Mathematica. These are extensible algebraic tools which have extensible rule sets, and "intentions" which are stated in mathematical expressions. A massive search engine powers the system by applying rules and attempting to construct a reduced or simplified expression from the original. These are handy (in fact I think calculators now use a simplified version), but not exactly a dream to program. For one thing, the algorithm to generate solutions meets the textbook definition of "intractable".
I think in the example of legacy code, the idea is to treat the FORTRAN or whatever as natural language and re-create all of the semantics of the compiler in some sort of rule base, and then go to town by adding to or modifying the ruleset to extend the domain. This seems like a hopeless endeavor.
As a kicker let me leave you with this quote, the result, apparently, of 4-5 years of intense IP research:
---- "If we have to go on with these damned quantum jumps, then I'm sorry that I ever got involved" - Erwin Schrodinger
Personally I like Common Lisp. It is completely different from the other languages I've used. One of the most interesting things is that it encourages practices that the profs usually tell people to avoid like self-modifying code and bottom-up programming.
Having the compiler available at run-time makes for some very nice opportunities for optimization and the macro system allows for overhead-free abstractions. Using a suitable library can seem like moving from C to C++ in terms of added functionality to the language. For instance CLOS, the Common Lisp Object System was written in Common Lisp on top of Common Lisp.
This ability to extend the language is probably something we'll also see in new languages, because building abstractions to suit the problem might just be better than trying to fit the problem to a certain set of preselected abstractions.
BTW, CMUCL is just fine. I use it myself and I don't know of better free lisps (clisp - no native compiler, gcl - poor standards support, sbcl - fork of CMUCL, should be as good). It includes a good optimizing native code compiler. Note that CMUCL is freeware (as in totally free for any purpose, with no obligations), not GPL. You can get it at www.cons.org.
When (hopefully not if) someone does pursue this idea, it's reasonable to postulate that some programming languages or even paradigms might be better suited than others to the first-stage static compilation to bytecode. So I guess that's what my own answer to "what is the future of programming languages" depends on. One thing I'll say is that I'm not sure it's Java, which means Sun's MAJC design for the purposes outlined above.
There's another nice article (companion to the one linked above) at Ars Technica that talks about some of this, though it actually ends up being a sort of review of CPU evolution from hardware lock-in though ISAs through microcode emulation of ISAs. It doesn't really talk about a bytecode-oriented-CPU, but it sure seems a natural next step to me. It's an idea in many ways similar to Crusoe or even (shudder) EPIC, but doing things at different times and in different places.
-- Life is short. Forgive quickly. Kiss slowly. ~ Robert Doisneau
Microcode allows you to soft-code each "instruction" in the instruction set. There is therefore nothing to stop you making those as high-level as you like.
(There have been microcode processors, where each machine-level opcode equalled a Pascal command.)
What I'm suggesting is that the compiler does NOT compile the "program" to suit the processor(s), but change the processors to suit the program. In this case, what you'd do is, for each object, is replace the microcode for each opcode on the corresponding processor with the compiled code for a given method.
eg: Let's say you have a class "btree", with methods for creating a new root node, checking if a tree is empty, adding a node, deleting a node, and returning the value of a node.
You program these as your new opcodes for your processor. You now have a RISC instruction set, with 5 opcodes and a pseudo-register for the value of the node.
(You actually have a further opcode for selecting an instance.)
The concept of a program no longer exists, in this model. As your "program" is now just a series of opcodes, spread over a number of processors, ALL you have, in the way of a program, is an initial call to one opcode on one processor. Nothing else has any meaning.
Further, because all your data is held in pseudo-registers, there is no need to access main memory. Your processors =BECOME= memory.
This concept calls for the elimination of the traditional model of seperate memory, main processor and dedicated supplementary processors for various devices and tasks. What you would have is a collection of totally programmable processors and nothing else. Your motherboard becomes a grid of processors and communications lines. Maybe one EEPROM to hold the bootstrap. But that's it. There would be no need for anything else.
This means that OO programming becomes parallel programming. Each instance of each object can talk to any instance of any object on the system, in parallel, WITHOUT messy scheduling code, time sharing, or any other such rubbish. This means that whatever OS you used would not need to handle any of this. It would all be done at the hardware level, inherently.
By using this kind of massive parallelism, you are moving from traditional models of parallel programming (which are generally blocking, and based on layers upon layers of fluff to get anything done), and moving closer to the Internet's concept of nodes which exist and operate in an inter-dependent to independent manner.
You also move OO from a merely artistic language to a practical language. If you can develop an application in a simpler, more testable manner, using the OO paradigm, AND have it's execution time superior to a functional program, THEN you have reached the level of usable OO technology.
(Note: It'd be faster, because you might only have 10-15 opcodes on a processor, which is much more efficient to handle than 200-300 instructions, typical on a CISC or CRISC hybrid.
It's a small world and it smells funny; I'd buy another if it wasn't for the money; Take back what I paid (SoM)
A while ago I posted some C code about the value of xor in swapping int's, etc., but some of the followups noted that most of it wouldn't compile. The reason is that ANSI C and C++ have moved away from K&R and made most type abuses illegal.
That got me to thinking about C in general, and the values that got me interested in it in the first place.
When I took up C I had already learned several high-level languages like BASIC, Pascal, and even APL and some Lisp. C immediately stood out, because it had tight integration with hardware, based on an abstract, but very accurate, Von-Neuman-type processor and memory model. The basic goal of C was to do everything that assembler did, with similar tightness of code and familiarity with registers, bit sizes, and machine addresses. Unfortunately, the prevailing trend was to take C and make it a higher-level and not a lower-level language.
However, these days, just about all processors are pipelined or multi-pipelined, and C code is hacked to pieces by the compiler or the on-chip optimizer. That's handy, but, in effect, C and even many assembly languages have become interpreted! The IA-64 will pull C code into separate, independent instruction streams, based on dependency and dataflow analysis. Crusoe will do speculative execution and even backtracking on unsuccessful branches, going so far as to do a rollback on memory locations, in cache.
That's all fine and dandy, but I wonder if there are features there that could be put under more programmer control. Maybe there are some new #pragma'sthat I don't know about, but still I see C as getting farther and farther behind the hardware model.
As a few naive suggestions, here are some ideas I have:
Tagging statements to designate which pipeline they go into. This is what IA-64 compilers do anyway, so why not us! (maybe we can, but I haven't checked).
adding cache control statements to variables - eg lock in cache, pageable, or page immediately (useful for scans, where,say, 2G of RAM is being scanned one byte at a time - there's no reuse). Oddly enough, I got this one from Oracle, which has this option for certain table operations.
More machine-level operators. I don't know what these would be, but anything bitwise would qualify.
---- "If we have to go on with these damned quantum jumps, then I'm sorry that I ever got involved" - Erwin Schrodinger
- Send a message. This used five bits to index into a table of message names.
- Put a message string in the table.
- Extend identifier. This is used to have more than a five bit index, either for putting in the message or retreiving it.
- Non-local return.
- Primitive assign. Used five bits for the slot name.
and a couple others I dont recall - non-local return probably, and possibly one to push "self" onto a stack. I suggest you look into the Agents programming language, by Gul Agha. This is exactly what it is. Even simpler, really - each agent (processor) can send and receive messages, and has one register worth of local storage and a script describing what messages to send when other messages are received.-----
Klactovedestene!
A major reason for the development of Ada was that the Department of Defense was wasting large amounts of money on the support of hundreds of programming languages used in embedded systems. Maybe we need more than one programming language, but we don't need hundreds of them.
the languages now are really CRUDE. programmers have to build infrastructure whenever we code. thats prolly the most annoying part (and sometimes the most fun) of coding. what i'd like to see is a language which would provide basic functions off the shelf. if i want an HTML editor stuck between two translucent animated buttons which pull up a hex editor and a MP3 player..i shouldnt have to *code* all that. three function calls and a few lines of code should do that for me in (insert language of choice). i should have to build stuff to parse files...if i want a XML tag called weather in a file somewhere on the disk, it should be able to retrieve it for me in one functional call. Java & the GTK stuff has been trying to do that but it doesnt go far enough. I want a seamless environment to manipulate all the functions available, plus i should be able to cut and paste bits from a library of examples available. And i should have a choice of writing bits in assembly and controlling the machines registers at the same time. tall order huh ?
I believe that programming, as it transends from a science to a field of engineering, will become more of a COP (Component Oriented Programming). In the future, 5 to 15 years, I believe that programming will become more of putting/gluing components together rather than developing applications from scratch or developing apps from scratch and including a few light components.
But for this paradime to be accepted a good, reliable, easy to use, and fast component aractecture must be created. Microsoft has COM, *NIX has CORBA but the overhead for understanding and implementing these technologies is just too big. VB with COM tries to make an effort of making COP a viable solution but as everybody knows Microsoft cannot innovate. The system is cludgy and still very difficult to understand. What I feel a good COP environment would be is 90% of development time drag and drop and 10% of development time scripting, to glue everything together, i.e. passing data back and forth and implementing some dynamic interfaces.
I'm hoping that bonobo with the GNOME project will provide the ease of use portion of this but I have not had the time to look into it. Until then we will be stuck with the current form of programming.
If at first you don't succeed, skydiving is not for you.
When you look at the progression of programming languages over the years, you see a growth in complexity followed by a simplification and maturation. This cycle, I believe, will continue.
The B language is a perfect example. It's atomic elements mapped one-for-one with the DEC PDP-7 instruction set, and included interesting shorthand that sped development. The C language fixed some of the growth pains of B; the standard mandated strong typing so that the compiler could do better what "lint(1)" tried to do. C++ tried to extend the C syntax into the object world, with some consequences good and bad.
What I see, though, is the creation of new languages to solve specific problems in ways that are natural to the particular problem-solver. You see this with business languages that abstract several thousand lines of COBOL code in a single statement. The further abstraction makes writing certain code easier, faster, and more bug-free.
Emphasis needs to be increased on program accuracy. Debugging has been bolted on for years; it's time for significant debugging aids to be included in languages.
OOP isn't about run-time efficiency -- it's about abstracting a complex problem into logical units that are simpler to visualize and manipulate; it is about programmer efficiency.
Almost every decision in computer science involves a trade off, because there are so many variables that are inversely proportional to one another. Run time performance is only one variable in a complex equasion; to optimize for maximum run-time efficiency a language designer has to sacrifice somthing else.
C compilers produce efficient code because they intentionally do not do things like automatic bounds-checking and garbage collection at run time. Java does do bounds-checking and garbage collection at run time, at the expense of run-time performance. Debating if C is better than Java or vice-versa is as pointless as arguing if a crescent wrench is better or worse than a socket wrench: both do pretty much the same job, but one may be better suited for one particular task than the other.
OOP exists because it makes it easier to solve certain types of problems. Not all problems are best modeled using an OOP model, just as all problems are not best modeled using a procedural model. Granted, everything eventually ends up as machine code (which, under existing processer architectures, is procedural). If you really wanted to be pedantic, you could say that you don't really need any other languages besides assembler. Of course, programming everything in assembler would be as silly as building a house by baking your own bricks and milling your own lumber.
"The axiom 'An honest man has nothing to fear from the police'
Why is it that the proponents of "one nation under God" are so eager to get rid of "liberty and justice for all"?
Basically you're just analyzing one axis of the evolution of programming languages,(the pure imperitive branch) from the Assembly to Fortran to Basic to VB (with a few backwards steps with GWBASIC and QBASIC in there.) Its not that far of a stretch. I plan on taking a close look at functional programming, logical programming, 4GLs, etc. before I ask "is that all there is".
I worry about the way you dismiss object oriented programming so quickly too. The way objects work in C++ vs. Smalltalk vs. Python vs. Dylan shows a huge range of study just to decide what objects are and how they work.
Karma seems to be stuck for people above 50. Last time I checked moderation _does_ affect karma in the hidden sids, but there's a chance that that has been disabled to prevent abuses (creating 50 accounts that post slowly in hidden sids to gain moderation tokens, using those to moderate the person's main alias up.
--
Friends don't let friends misuse the subjunctive.
OO, for example, will NEVER surpass, or even equal traditional functional programming, until the hardware is itself OO. (The Crusoe is one step in this direction, where the end result is placing one method in one instruction, one class on one processor, and one instance in a selectable set of registers.)
The reason is simple. OO languages need to be translated to a functional form (which is going to be inefficient) and then compiled to a low-level form (which also looses efficiency).
By designing hardware that is NOT based on the functional concept, you can improve the quality of non-functional languages to the point where they become practical under stress.
Then, there are other developments that badly need to be made. Abstract Data Type compilers are not exactly thick on the ground, but would make writing complex data structures much easier.
Then, too, there is an assumption in computing that you have to move from beginning to end. Yet when you draw up a specification, you don't give a flow, you give mathematical rules which are valid. Nor do you say -how- something is to be done, you simply define the consequences of performing a given operation. Extend the concepts a bit, and you totally seperate the "whats" from the "hows", and the content from the presentation. Allowing the user to control THEIR end, and the machine ITS end will be the next major step forward in computing.
It's a small world and it smells funny; I'd buy another if it wasn't for the money; Take back what I paid (SoM)
We have dozens of programming languages because each one does some specific task better than it's alternatives. C and assembly put you very close to the machine, giving you performance and low-level control over the hardware at the expense of maintainability, reliability, and development time. SQL works well for manipulating large sets of data and reliable transaction processing. Scripting languages like Perl let you easily manipulate text streams. Java gives you portability and code maintainability. The list goes on.
Software tools are just like physical tools: you have tools like a Swiss Army Knife, which do a lot of things well enough for some jobs; and you have tools which are designed to do a specific job and do them well. Just as in meatspace, you have to pick the proper tool for the job at hand. A Corvette, a Jeep, and a pickup truck will all get you where you are going; but depending on the particualar circumstances, one might be better than the other -- the Corvette is going to be better if you're driving on the highway, the Jeep is best if you have to go on unpaved roads, and the pickup is best if you have to haul a lot of stuff along with you.
The future (and present) of programming, as I see it, is systems where different bits are implemented in the most suitable language, then tied together with a glue language. The days when a programmer could make a career out of knowing one language are, for the most part, gone and buried.
"The axiom 'An honest man has nothing to fear from the police'
Why is it that the proponents of "one nation under God" are so eager to get rid of "liberty and justice for all"?
OOP is not meant to be a Holy Grail, despite what many people claim. OOP is meant to be efficient, which is not the same thing as fast during run time.
... will NEVER surpass, or even equal traditional functional programming" just shows that you don't know OO very well.
Sometime, write a basic program in C which accepts input from a user (like their name, for instance) and then writes "Hello, <username>!". Make sure that it does bounds checking; that it has no arbitrary limits on how long a user's name can be; that it's well-behaved in the case of a crash; that it's this, that and the other. It takes pages and pages of code to write a simple, basic program well in C, because C is an inherently low-level language.
C++, on the other hand, simplifies all of this for you. Just do a "string username; cin >> username" and you get a boatload of functionality.
C++ is more efficient in that case, because processor time is cheap and my time is worth a hell of a lot. In that case, it's better to minimize my time rather than the processor's time. This is the way it is for most software projects, by the by; programmer time costs much more than computer time.
There are situations when this is reversed, where it's more efficient to have teams of programmers working for years on a program than it is to trust the processor to do the Right Thing at run-time. The Space Shuttle is a good example of this. The people who write code for the shuttle's flight computers use HAL/S as a development language ("High Order Assembly/Shuttle", if I recall). HAL/S is ugly. It's just about the last language I'd use for any given engineering task. But it works perfectly fine for the Shuttle, because it's more important that the programmers do their job right than it is that the language is perfect.
The cost of Shuttle programming is astronomical (pardon the pun). However, in almost 25 years of operation they've never had a single catastrophic crash (save the 1986 one, which was caused by a catastrophic failure of other systems which interrupted computer operation). Try getting that sort of uptime from a UNIX box.
Moral of the story: OOP isn't a panacea. Neither is traditional procedural programming. Saying that "OO
OO isn't competing with procedural programming. It doesn't need to. The two paradigms exist completely independent of each other, and neither one of them needs to justify their existence. They just are, and wise programmers use whichever one is proper for a given application.
What I'm hoping for in the future is a language which surpasses Smalltalk in it's simplicity, elegence and splendid design. Smalltalk does have it's issues (slowish runtime), but in many ways, the peak of language design has reached it peak - in 1980. Twenty years have passed since Smalltalk-80 was made public, and about thirty years since resarch on what would be come Smalltalk started at Xerox PARC.
And after all this time past, all the pionerring research done at Xerox PARC which lead to Smalltalk and the modern GUI, nothing new has come up. We've got Java, and now, C#, nothing but half-assed attempts at Smalltalk flexibility, but catering to those who cannot think past C's syntax.
It's a shame, and it doesn't seem to be getting better- Stanford's Self project was interesting, and also responsibile for a lot of new ideas and techniques, but has not really bloomed. Often do I look around for new languages, new ideas in language design, and it seems it's all just the same ideas being rehashed.
I love Smalltalk as a language, but I'm ready for something just plain better to come along. Perhaps Smalltalk is just too good that it'll be another 20 years before the rest of the world catches up with it.
Working toward a usable PDA environment in the spirit of Newton OS: Dynapad
I believe the very next great improvement in programming is not going to be some great development environment allowing us to glue together components - you're always stuck with learning the component and making the component do what you want it to do and often it doesn't allow you to do exactly what you need (ssh/scp instead of telnet/rcp).
No I think it's in the interface we use to program. My source codes are basically one dimensional lines of text expressing a logic that has a lot of variables interacting. The operational structure is in my head and the keyboard is a poor tool to translate the mind/logic to the practical/computer. I wouldn't know what type of input device would bring an improvement, I certainly don't think voice recognition will help programming, but I do believe that current languages are limited by the input devices we use to translate what is in our mind. Once such a device becomes available programming languages will start to reflect it.
Of those to whom much is given, much is required.