Andrew Koenig (long time C++ Standard contributor, author, and former AT&T Research Fellow) is famous for describing C++ as being “as close as possible to C – but no closer” (see https://isocpp.org/files/papers/N0007.pdf). C++ was designed from the outset to be both a “Better C” and a migration path for C programs, and so it was important that (most) C programs ran (pretty much) unchanged under a C++ compiler. That document lists a number of deliberate incompatibilities and most of them are really fairly minor. One of C++'s long standing incompatibilities with C was eliminated when the C Standards committee voted to change the behavior of "default
int" in declarations to match C++, thus bringing C in line with C++, rather than the other way around.
This approach to language design can also be seen in Groovy, which consciously decided that (almost) every valid Java program should be a valid Groovy program: just change the file extension from
.groovy and off you go! Groovy made a lot of Java syntax optional (including the type system) and treated several Java constructs as no-operations (e.g., fields and methods declared
private in Groovy are still public). Groovy also added language features, so most idiomatic Groovy code looks like stripped down Java code with more expressiveness, as Groovy developers just omit elements of syntax they don’t need.
On the other hand, when Java itself was designed, although C++ was an inspiration, no compatibility was assumed: Java was to be a strictly “better” language than C++. The same happened with C#, when Microsoft had already taken Java and evolved it into J#, they decided a new language would be “better” and C# was designed without any real attempt at compatibility. Scala, in its own way, is a “better Java” only in the sense that it is a more powerful, more modern language that builds on the good things in Java but drops a lot of the bad things. In all three cases, there is no anticipated need nor expectation that the earlier language, the inspiration, should be runnable under the new language’s compiler. Other “inspired by Java” languages that are completely incompatible include Ceylon and Kotlin. Go and Rust were both “inspired by C++” (and both intended to be a replacement for it), yet they are both very different and neither are in any way source compatible with C++.
That’s not to say there’s no interoperability: C and C++ can happily call back and forth between each other at the native API level, along with Go and Rust. Java, Groovy, and Scala can all leverage each others’ libraries. Mixed language systems are increasingly the norm these days. Indeed, even wildly different languages such as C# and F# can be perfectly interoperable (and on the JVM, we have Clojure and “everything else”).
So what about LuceeLang? How compatible should it be with CFML? The Manifesto – http://lang.lucee.org/t/lucee-manifesto/183 – has this to say (my emphasis):
Lucee Language has its roots in the ColdFusion Markup Language (CFML) but Lucee Language is not CFML.
LuceeLang is intended to be modern, yet familiar, and to “grow in a more ambitious direction”.
Where possible lucee language should facilitate the transition of developers from CFML to Lucee Language.
LuceeLang is specifically designed to be interoperable with CFML, including CFML templates and creating instances of CFCs for example, and CFML developers should be able to quickly get up to speed with LuceeLang. Note that the Manifesto talks about the transition of developers, not programs. LuceeLang’s approach to tags is different:
<:whatever> so you cannot just change your
.cfm file extension to
.lucee and expect to run your code. At best you might be able to effect a mechanical translation, perhaps followed by some manual editing. What about changing
.lucee for all-script CFCs? I think this might be a more feasible change but even there some fundamental decisions need to be made about what’s available in LuceeLang, even if the syntax itself is almost the same.
The first question that needs to be answered is whether there really is an expectation that some subset of (mechnically transformed) CFML code should run otherwise unchanged as LuceeLang code, or whether the expectation is that in a CFML / LuceeLang project new files would be written with
.lucee extensions (and therefore in LuceeLang) and perhaps pieces of legacy code ported over to LuceeLang over time as the project grows?
The second question is whether “all” of CFML’s top-level function-based library should be available directly in LuceeLang, or whether the “cruft” should be removed, or whether LuceeLang should go further and eliminate all those top-level functions in favor of member functions and, perhaps, a set of static class-based methods. Remember, this is a question of language design rather than one of theoretical performance. Folks who are concerned solely or primarily about performance tend to stay with languages that have less abstraction and that are “closer to the metal”. This is a question which needs to be answered on the basis of what makes a “better” programming language? Generally, history has shown that increasing abstraction and improving consistency are “better”.
CFML as it stands today is quite a sophisticated language but it also has a lot of strange semantics (behavior) and some definite syntactic warts. LuceeLang is committed to being a tag + script language in the same vein, but “better”. We need to decide how much of CFML we’re willing to simply “leave out” and how much we’re willing to “replace with (better) alternatives”. We should be guided by the Manifesto:
Lucee language is a modern alternative
LuceeLang does not have to be a superset of CFML. In my opinion, it should not be.