Evolving a programming language
started 5/30/2003; 2:43:48 PM - last post 6/4/2003; 11:44:57 AM
|
|
Toby Reyelts - Evolving a programming language
5/30/2003; 2:43:48 PM (reads: 710, responses: 16)
|
|
I just finished reading a post in which it was suggested (for Java) that a version statement be required to identify the particular version of the Java language that a class was written in. The idea, being that changes could be made to the language syntax, which would be incompatible with an earlier language syntax.
I'm wondering why this isn't commonly done. It seems to me that during the evolution of most languages, you reach a point at which you realize that you would like to improve the syntax of the language, and it would be best served by changing the existing language incompatibly, but, as the language designer, you're afraid of the errors that you will introduce into the large source code base which already exists.
If modules were explicitly tagged with a language version, then you could ship a compiler, which was really a compiler collection, that could compile any number of modules written in any number of incompatible language versions. It doesn't seem like this would introduce any extra maintenance burden either.
What is it that I'm missing?
|
|
Frank Atanassow - Re: Evolving a programming language
5/31/2003; 6:51:39 AM (reads: 715, responses: 3)
|
|
First, `evolve' is not a transitive verb. :)
Second, this idea sounds reasonable to me. I think Python has an interesting way of handling language versioning, with its `future import' mechanism. XML also has explicit versioning.
|
|
Ehud Lamm - Re: Evolving a programming language
5/31/2003; 8:19:54 AM (reads: 736, responses: 2)
|
|
I can think of several reasons why this sort of thing is usually done via compiler switch and not a source code annotation. Perhaps the most important reason is that by automatically supporting different language versions you imply that code fragments written in different versions should interop correctly, or at least that the compiler should detect when this is not the case. Doing this is not trivial, and most would add to the complexity of compilers.
It is easier to try and introduce language features that are backward compatible, and clearly state when recompilation is required, to what scope and what are the changes and difficulties programmers should expect.
|
|
Frank Atanassow - Re: Evolving a programming language
5/31/2003; 9:33:57 AM (reads: 764, responses: 1)
|
|
I can think of several reasons why this sort of thing is usually done via compiler switch and not a source code annotation. Perhaps the most important reason is that by automatically supporting different language versions you imply that code fragments written in different versions should interop correctly, or at least that the compiler should detect when this is not the case. Doing this is not trivial, and most would add to the complexity of compilers.
If the changes between versions are only syntactic sugar, and whose semantics can be expressed by translation to a core language which does not change across versions, then it would not be so hard to assure interoperability in a way which most programmers can understand.
|
|
Adewale Oshineye - Re: Evolving a programming language
5/31/2003; 9:42:20 AM (reads: 699, responses: 9)
|
|
There's also the problem that there are lots of corner cases when you start wanting to build a project using compiled binaries which may have been tagged with a different version number. How do you interoperate with code that has different expectations about scoping rules (as happened with Python), keywords, method resolution order in inheritance structures and parameter passing conventions. Most people seem to have gone for the option of ignoring the problem and hoping it goes away.
Python's development team has gone a bit further than that. As well as future imports there's also the PendingDeprecationWarning and FutureWarning classes to indicate that you're using features that are likely to change in the future.
I also seem to remember that there was some discussion in one of the earlier Perl apocalypses about handling interoperability between Perl5 and Perl6. Here's the link: http://www.perl.com/pub/a/2001/04/02/wall.html. The interesting thing is that Wall is particularly worried about the situation where you're running Perl5 code in Perl6--do you use Perl6 semantics, Perl5 semantics or some special compatibility mode that's going to minimize unpleasant surprises?
|
|
Ehud Lamm - Re: Evolving a programming language
5/31/2003; 9:50:25 AM (reads: 794, responses: 0)
|
|
Of course. But once you start supporting such a feature programmers will begin to expect you to always provide it. Now try to explain to them what is and isn't syntactic sugar...
|
|
Frank Atanassow - Re: Evolving a programming language
6/1/2003; 6:17:38 AM (reads: 708, responses: 8)
|
|
How do you interoperate with code that has different expectations about scoping rules (as happened with Python), keywords, method resolution order in inheritance structures and parameter passing conventions.
Scoping and keywords are clearly not a problem because they are syntactic issues, but you do raise two good points.
First, I was thinking (as I always do :) of a functional language, which always have a compositional denotational semantics: the denotation of a program depends only on the denotations of its subprograms, and not on the way they are expressed, or on programs which are not mentioned in the source text. This is not the case for things like OO languages where the behavior can depend on the context, or the order in which you declared things. I would say this is a defect of such languages, but I guess most people disagree with that idea.
Second, even in a functional language, one relies on a knowledge of the operational semantics. If I have two modules compiled against different language versions, I still expect to know what they denote, so there is no problem figuring out how to make them interoperate if all I'm interested in is the program result. But if the operational semantics are different, then things get more difficult, since essentially you will have two abstract machines running at once. So if the `parameter-passing conventions' changed (say, eager to lazy) then you may have genuine problems reckoning the algorithmic complexity of your programs, especially if you have a things like higher-order functions, since you cannot know in which module they originated, etc. This is a very good point.
|
|
andrew cooke - Re: Evolving a programming language
6/1/2003; 8:26:06 AM (reads: 727, responses: 2)
|
|
Scoping and keywords are clearly not a problem because they are syntactic issues, but you do raise two good points.
doesn't scoping change the semantics of closures?
|
|
Frank Atanassow - Re: Evolving a programming language
6/1/2003; 9:46:12 AM (reads: 759, responses: 1)
|
|
doesn't scoping change the semantics of closures?
You mean like dynamic versus static scoping? That would be a non-conservative semantic change.
If we are talking about visibility, that's syntactic. But almost any syntactic change is going to change the semantics of a piece of source text. Indeed, the whole point of assigning language version numbers is that you can assign multiple semantics to identical source texts. The question is, rather, whether the denotational and operational semantics is `big enough' to accomodate all of them. You can sidestep this issue if there is a core language which all versions can be translated to.
For example, say version 1 is the language Scheme, and version 2 is Scheme except that the meanings of `car' and `cdr' are exchanged. (You would never want to do this, of course, but for the sake of example...) Then the source text
(let ((xs '(1 2))) (list (car xs) (cdr xs)))
will have the semantics '(1 2) in version 1, and the semantics '(2 1) in version 2. They're different but that's fine. What we care about is just that there is a way of comparing them. In this case it's easy to do: you can either translate version 1 programs to version 2 programs or vice versa.
Likewise, it doesn't matter if changing the scoping rules changes the semantics, as long as there's a common ground, or reference we can translate the different versions to.
|
|
andrew cooke - Re: Evolving a programming language
6/1/2003; 1:43:42 PM (reads: 786, responses: 0)
|
|
You mean like dynamic versus static scoping?
yep.
i agree that syntax changes semantics (otherwise it's pointless), but my current working definition for "syntactic sugar" is that the changes are "local" to the sugar.
i was going to make the observation earlier, and your comment about common ground makes it obvious, that you can view virtual machines as the "kernel implementation". so different java syntax may need different java compilers, but these can be considered pre-processors that generate byte code which can be combined and compiled by the jvm. afaik the jvm spec has not changed (much) since 1.2 (1.5 is compatible with 1.4, i believe, despite the various new things being discussed in another thread). (wasn't there a thread about this recently?).
|
|
Dan Shappir - Re: Evolving a programming language
6/2/2003; 3:21:46 AM (reads: 686, responses: 0)
|
|
So if the `parameter-passing conventions' changed (say, eager to lazy) then you may have genuine problems reckoning the algorithmic complexity of your programs
But everybody knows that the only parameter passing mechanism endorsed by Real Programmers is call-by-value-return, as implemented in the IBM/370 Fortran G and H compilers!
Sorry, I just couldn't resist ;-)
|
|
Dan - Re: Evolving a programming language
6/4/2003; 6:53:03 AM (reads: 639, responses: 3)
|
|
Scoping and keywords are clearly not a problem because they are syntactic issues
This turns out not to be the case. Syntactic issues are definitely a problem in any language that allows runtime compliation, and some syntactic things (such as scoping) may be an issue with any language that allows introspection. While not entirely common, changes in syntax can be quite an issue if a routine is dynamically building up source that gets passed into another routine for final processing and ultimate compilation. While not hugely common as a problem, mostly because I don't know of any language that allows both runtime compilation and multiple differing language definitions simultaneously, it is an issue that shouldn't be overlooked. Disallowed, perhaps, but not overlooked.
|
|
Dan Shappir - Re: Evolving a programming language
6/4/2003; 7:06:50 AM (reads: 671, responses: 2)
|
|
I don't know of any language that allows both runtime compilation and multiple differing language definitions simultaneously
Actually JavaScript does allow this to an extent. You can mark JavaScript sections in HTML as compatible with a particular version of that language.
|
|
Dan - Re: Evolving a programming language
6/4/2003; 8:29:20 AM (reads: 695, responses: 1)
|
|
More and more I'm coming to believe that JavaScript is the single most underappreciated language around....
|
|
andrew cooke - Re: Evolving a programming language
6/4/2003; 9:23:11 AM (reads: 731, responses: 0)
|
|
what's the history behind the language? who was involved? apart from the notorious name choice and Netscape it doesn't seem to have a history (google isn't that helpful when you're looking for the history of a language that manipulates browser histories...!)
|
|
Isaac Gouy - Re: Evolving a programming language
6/4/2003; 10:49:32 AM (reads: 560, responses: 1)
|
|
google isn't that helpful
Sure it is! "programming language history javascript"
And then "livescript history"
Origins of JavaScript
|
|
andrew cooke - Re: Evolving a programming language
6/4/2003; 11:44:57 AM (reads: 581, responses: 0)
|
|
|
|
|