Last update December 11, 2012

Languages Versus D /
Page Discussion



CrossTalk Feb.2003 contains a number of articles concerned with programming language choice. Maybe it will give some idea what to add to this table? http://www.stsc.hill.af.mil/crosstalk/2003/02/ --IlyaMinkov

Started filling in Sather. I'm not sure whether Complex and Imaginary should be in the Comptibility section. I also correct C&I for Delphi to "NO", since Delphi's solution is library and somewhat analogous to C++, which is marked with "NO". This decision also forces me to correct Operator Overloading on Delphi to "NO", because this actually isn't overloading - it's just the way operators are defined for the Variant type internally, and is no way comparable to operator overloading in any other language in the list. Besides, I come to agree with GeorgeWrede?'s "NO" to module support in C++, since it is much weaker and not comparable to this feature in D, Delphi, and other languages. But maybe all of these cases should be marked as "partial"? --IlyaMinkov

I'm surprised you included Sather. I was investigating it back in the mid-1990's. But I didn't think anyone was using it anymore. -- JamesCGraves?

Having read Scott Robert Ladd's article at Coyote Gulch, http://www.coyotegulch.com/algorithm/libcoyote/BeyondAssert/BeyondAssert.html I have to remove RAII from C# and add RAII to Delphi. --GeorgWrede

I put Yes for Unit testing in Delphi. The scope of a unit test in D is the class, in Delphi it is the unit. Also filled in Static Construction Order and Guaranteed Initialization for Delphi. --GeorgWrede

Using the "using" statement and IDisposable, you get deterministic finalization [in C#]. --sebmol

Should the same be done with "In mainstream use"? -- StewartGordon
Only if we can decide a common definition of "mainstream use"... In other words, probably not.

Does "Some" mean that some dialects of whatever language have this feature, or that the language has some of the feature? Similarly "Most" --StewartGordon

Do we have any criteria for including a language in this list? Surely we can't aim to list every language ever invented, or we'd end up with pageloads of horizontal scrolling making it tricky to read. And do we really need the empty columns? --StewartGordon

Would you like to suggest some criteria? If someone wants to actually add information about a language, I think it would be helpful to add that language to the table. I assume ObjectiveC and Lua were added because someone thought they would be good languages to compare to D, but since no one has filled in any of the columns, I think they can be removed. I was afraid I'd mess it up if I tried to remove them, but I managed to safely remove ObjectiveC. --JustinCalvarese

We could split the page into, say, CompiledLanguagesVersusD? and ScriptingLanguagesVersusD?, or exclude dynamic languages entirely, as such a comparison isn't really useful anyway. --AndyFriesen

I just discovered there's an Ada lineup patterned after the original chart: http://home.att.net/~jimmaureenrogers/AdaAdditionToDComparisonTable.htm --SimonHeath

It is not 100% true however. Lightweight arrays is "No"? Of course, LA is "Yes". -- IvanLevashew?

I fear without some agreed-upon definitions, this list is just a bunch of fluff. (And good luck with the 'agreement' part...) Some especially fluffy parts:

What makes a syntax "Algol-like"? Python's syntax is as Algol-like as any of the languages marked "Yes", to me. More so, in some ways. (Note that "Algol-like" can't mean "uses braces", because Algol itself didn't use braces.)

Python has a module 'unittest'. Is this not sufficient for the "unit testing" feature? (It seems pretty silly to me -- things like unit testing can be done in any language. Having explicit support for it only makes it a tiny bit easier.)

Python also has the 'doctest' standard module, which can easily be used to create literate unit tests

Java has "string switches" now? I can't find any reference to that.

The single most important performance feature a language can have is missing from this table: a profiler. I'll take a decent profiler over easy "inline assembler" any day. --anonymous

I would instead say that conditional compilation doesn't make sense for Python. Changed it to N/A. Set 'no' on introspection for D because optimism doesn't count. Also, I summarized and nipped a few older comments for brevity; this page is begging to be simplified. --AndyFriesen

From "Common Lisp, The Language, 2nd ed": "All implementations are also required to provide specialized arrays of bits, that is, arrays of type (array bit)" (page 33). Is there a reason that Lisp / Array of bits is not 'Yes'?

Also from CLTL2: "Complex numbers (type complex) are represented in Cartesian form, with a real part and an imaginary part, each of which is a non-complex number (integer, ratio, or floating-point number)." (page 22). Is there a reason that Lisp / Complex and Imaginary is not 'Yes'?

(While I'm here: Is there a reason the title of the Lisp column is "Lisp/CLOS", instead of "Common Lisp"? CLOS has probably never worked with any Lisp dialect other than Common Lisp, and it's been an official part of Common Lisp for well over a decade now. The name of the language is "Common Lisp". Unless you mean the column to be "Lisp", and include all Lisp dialects, but that seems silly: Lisp dialects vary between each other at least as much as say, C and C++ do, or Java and C#.)

--anonymous

This may be an unwarranted comment. However, I'd like to see that the top row would be fixed on the screen. Then I wouldn't have to remember what column is which programming language.

I added line for dynamic/strong typing of language and reorganize languages by this criterion. Filled most of cells for Ruby. Added Haskell. Added block for datatypes and moved some features to this block. Used mark "Lib@#yellow" to specify features implemented with built-in libraries - it's part of a language but not supported by special syntax and semantics --BulatZiganshin, bulat_z##mail.ru

Marked Python as not supporting 80 bit floating point. Its float type is implemented with a C double. Additionally, Python has the ctypes module available, that allows it to natively import and call dynamic libraries with C linkage. Plus, the "standard" implementation of Python is written in C, and has a very useful C API. I know ctypes is not a standard library, but it might be enough to put "Lib" under "Support all C types" and "Direct access to C." Python also has the "struct" module in the standard library, which may or may not be enough for "Struct member alignment control." --KirkMcDonald

'ctypes' is part of the stdlib since 2.5, so I edited both properties to 'Lib'

SamKass?: Here are my comments from looking at this chart, especially with relation to Java. (By the way, since Objective-C? is the primary development language of one of the major platforms today (Macintosh), it would be interesting to see it compared instead of some of the more obscure language/scripting languages included.)
  • Java 1.4 added regular expressions into the standard JDK, so that should be "Yes"
  • While D supports integer enums as encapsulations of value definitions, the enum itself is not very manipulable, especially compared to enums in Java. In Java, enums can hold any type of data, and can be treated like a class for many purposes (including very efficient collections of objects, initialization, and containing methods that manipulate enum values). So at best "D" would get a "Some" under "Enumeration", IMHO.
  • Java has both List and Hash containers, so if you mean something different perhaps this entry needs clarification (or change Java to "Yes")
  • While Java doesn't have "Arrays of bits", it does have "Sets of bits", so perhaps that should be "Some"
  • Using NIO buffers, Java supports "Array slicing" paradigms, so that should at least be "Some"
  • I understand the point you're trying to make with "Use existing debuggers", but is there really a lack of debuggers for Java these days (including GDB)? It's an important point for "D" adoption, but not for any comparison purposes.
    • The support for debugging Java has been standardized. Many IDE's use this standard now, allowing full control of the current VM state, an integration with native code debugging within the VM itself or native JNI implementations, from a Java or native/C debugger host, locally or remotely... It's just to GDB to implement this JVM debug interface... -- VerdyP
Shouldn't standard-library content be counted as a green 'Yes (stdlib)' for the language, with third-party libraries be 'Lib'?

I'd say third-party lib should be equal to "No" because it is something external to the specified language. Almost anything can be implemented in almost any language with sufficient effort. If it isn't provided in core or in std lib, it is not supported by the language proper. -- AndersHallström?

Haskell corrections

These are issues I think the chart is wrong about Haskell. Feel free to update these (or delete things and merge with the chart). btw why is the chart representing as having things in the standard library as yellow? I thought that that was better than having them in the core normally...

EinarKarttunen? (ekarttun##cs.helsinki.fi.nospammers-please):

  • What does Range mean? Haskell has things like [1..n] which constructs a list from 1..n in a lazy fashion which gets optimized away if it is used like a Range - or are you referring simply to a pair of integers?
  • Regex - see http://haskell.org/ghc/docs/latest/html/libraries/base/Text.Regex.html
  • Template - see template haskell - http://haskell.org/th - but that should probably be marked yellow
  • Reflection - see http://www.cs.vu.nl/boilerplate/
  • Independent of VM - yes it is. GHC compiles native executables whose only dependency is the GMP bignum library.
  • Use existing debuggers - yes you *can* debug haskell programs with GHC. Of course debuggers knowing haskell do a much better job.
BulatZiganshin (bulat_z##mail.ru):
  • Range mean an integer range datatype, which have only pascal-derived languages: "var i: 1..MAX". i think that it don't have much value for programmers and must be replaced with "ability to support range-generated lists", which exists in different ways in perl, ruby, haskell and may be other languages
  • Regex/Template/Reflection are supported by external libraries. we can find libraries to almost anything for any wude-spread language. i think that readers of this page must know himself which features can be suported by external libs, and which can't
  • Independent of VM - i mean that executable include VM
  • Using existing debuggers (those written for C code) is meaning-less for Haskell
EinarKarttunen? (ekarttun##cs.helsinki.fi.nospammers-please):
  • Range should probably be reworked
  • For regex we should probably remove the No for all No entries or make all the empy ones No.
  • I think we are meaning different things by VM. GHC generated code has VM by the definition of 1) including user level threads 2) garbage collection 3) using a specific calling convention for functions and exceptions. But not VM in the sense of an executable being an interpreter + bytecode. This would lead to clumping Haskell, Common Lisp (clos) and Ada to the same package (Ada can be standalone too, but remember e.g. the concurrency).
BulatZiganshin:
  • Einar, i send your a message, but don't get any answer. so, i just put a copy of this meaasage on my page: BulatZiganshin
LionsPhil?: I've stuck some Perl info in and fixed the capitalisation. It doesn't have function delegates AFAIK, but then closures can cover that functionality. Several things are 'lib', because they're covered by CPAN modules (yes, this includes inline assembler). String switches I'm not sure how to deal with, because Perl doesn't have explicit switches at all, instead getting the compiler to spot if/else-if chains (there is, natch, a CPAN module which implements 'switch').

JamieTurner?: Python does have lightweight C-type arrays in the standard library, so I updated that entry to a yellow "Lib". Also, python does have thread synchronization primitives.

ChadRobinson?: The Struct member alignment control entry is incorrect for C. Nearly all compilers support this in one form or another (with varying levels of control). Even if it's not quite to spec, it should at least be listed as "Some" or "Most". I set it to Most for now.

DevNull?: Regular expression support in C exists through several libs, libPCRE for example. Changed to Lib.

JouniHeikniemi?: I published a criticism for this comparison at http://www.heikniemi.net/hc/archives/000292.html. I don't mean to bash on your work, but the comparison has sufficient amount of errors and a considerable bias to be considered quite misleading in my opinion. I'm sorry I can't offer to help here; it would be beyond my resources to do things the right way.

CGittinger: From a Lisp/Smalltalk point of view, the "Use Existing Debugger" column should be marked red for all those that do. Both Lisp and especially Smalltalk IDE's are way beyond anything seen there. Also, I added a few rows (which C/D/J friends might remove), as I dont think its fair to simply leave out major features from such comparisons either because the language that is to be praised does not support it , or because the author does not know about it . Marking Lib-implementations as yellow is unfair for languages, where everything is under the programmers control (i.e. a "Lib") as in Lisp, Smalltalk, Haskell etc. On the other hand, every language can implement features like arbitrary precision arithmetic or simulate continuations, but if this is not transparent to the programmer (i.e. she has to write explicit function calls for it, and cannot mix arithmetic with ints, floats etc), I would mark this with a red "No". Therefore, I changed the "Lib,3rdParty-yellow" for Complex/Rationals in the Java column to "No-red". You simply cannot do mixed arithmetic with these library-class-types in Java. On the other hand, if you allow the use of a library call, you MUST as a consequence make every other column in the table yellow (yes, because if everything else fails, write a lisp-interpreter in that language, and call it as a library function . I think that its fair to regard a dynamic compiler which does constant expression evaluation and dead code elimination as a conditional compilation feature (actually, it much better than that). Finally, I added the "Explicit Memory Allocation" column to the "Reliability" section, with reverse colors. There is no doubt among reasonable computer scientists, that explicit memory allocation - and especially deallocation - has and is one of the major sources for some of the biggest problems in the history of computer science.

I concur with the first remark in particular. Existing debuggers for what? Debuggers for Lisp and Smalltalk to this day have functionality unseen in those for other languages, so "use existing debuggers" is a rather disingenuous point of comparison, as it suggests that somehow the debugger you already have for one language is suitable for another. --MarkLaws

New Rows Requests & General Questions

I think we'd better specify allowed memory allocation models. For example, in Ada there is a "new" operator, but there isn't a "delete" operator. But we can still deallocate objects using protection bypassing primitives (Unchecked_* ones). So it's still "Explicit Memory Allocation". But it's not the same as in C++. Another example : in Cyclone we have to spend some time annotating memory regions. Annotating is an explicit action, but again it is not the same as in C. In Cyclone we can combine Reference Count, Garbage Collection, LIFO regions, Unique Pointers. I'm not sure if "Yes" must always be red.
all new languages are now designed to eliminate pointers as much as possible (a goal impossible to achieve if you want a native integration of external C libraries). So they promote failsafe references (or managed handles), automatic memory management (controled separately from the algorithm needing memory, using a separate management system which may sometimes be written and overridable in the language itself), attempt to remove the old concept of counted references (for locks and synchronization issues with non failsafe environments like external C/assembly libraries). Trying to give semantics to pointers (phantoms, unique, temporary, ...) only creates their own new problems. Abandon this concept and use a good GC as part of the language, and implement design by contracts for integrating and isolating external non failsafe libraries (to predict and avoid deadlocks). -- VerdyP

And... Garbage Collection. I see it's either Yes or No. But in fact in Ada GC existence is not specified. Ada programs can exist on Native environment, .NET and JVM. In Cyclone we can avoid using the 'H heap region with GC. Thus "disabling" it. And what about Boehm GC bindable to a lot of languages? They too can have GC and can avoid GC.
It is demonstrated now that GC offers a definitive performance advantage due to its static O(1) runtime behavior compared to O(n) with explicit memory management (so the global performance is much better with a GC-based strategy, as it can profit from threads idle time during blocking I/O). Implementing GC in a VM or process supporting multithreading for parallel GC is now very performant, and not blocking with long pauses, in addition to providing very safe runtime environment and elimination of the memory leaks (synchronization issues caused by deadlocks are now eliminated using VM-enforced locking policies and atomic short operations that only depend on a single independant lock). An excellent feature for critical application servers that need to remain responsive for lots of concurrent service client threads... -- VerdyP

I think some new info will be very useful too : existing compilers : Native compilation, .NET, JVM and C/C++. Ada 95 have all theese targets enabled by existing compilers. Ada 2005 has some temporary issues. I think it's meaningful because if someone wrote something in Ada once he can use then theese sources everywhere. Can I write a Java applet or J2ME? game in D? No. Can I write them in Ada? Yes. And they can share some piece of code with their desktop native versions. Really exciting, you see?

-- IvanLevashew?

Displaced arrays

Both FORTRAN and Common Lisp have them. I suppose we can count C and C++ too, since you can actually use pointers to implement that (you can wrap the initialization in a library function). Should these be in the list?

Corrections about Lisp

  • Why is there a "No" for covariant return types in Common Lisp? In CLOS, you can extend and completely change the definition of a class... Below is a silly example, but it's enough to show the idea
(defclass a ()
  ((x :type fixnum)))

(defclass b (a)
  ((x :type real)))

(defgeneric set-val (c v)
  (:documentation "Sets value in slot"))

(defgeneric get-val (c)
  (:documentation "Gets value from slot"))

(defmethod set-val ((c a) v)
  (check-type v fixnum)
  (setf (slot-value c 'x) v))

(defmethod set-val ((c b) v)
  (check-type v real)
  (setf (slot-value c 'x) v))

(defmethod get-val ((c a))
  (the fixnum (slot-value c 'x)))

(defmethod get-val ((c b))
  (the real (slot-value c 'x)))

(let ((thinga (make-instance 'a))
      (thingb (make-instance 'b)))
  (set-val thinga 10)
  (set-val thingb 5.4)
  (let ((value-a (get-val thinga))
	(value-b (get-val thingb)))
    (check-type value-a fixnum)
    (check-type value-b real)
    (format t "~s ~s ~%" value-a value-b)))

  • Common Lisp can do Currying with a simple function. I think this at least could count as "lib":
(defun curry (function &rest args) ; From the Common Lisp Cookbook
  "Curries a function: returns a function that is the same as function, with
   args applied."
  (lambda (&rest more-args)
    (apply function (append args more-args))))

  • "Existing debuggers" are not as powerful as good Common Lisp environments. You can do wonders wih a good Lisp IDE (including disassembling functions, tracing them, expanding macros, profiling, inserting breakpoints, inspecting data (including their types), *changing* data on the fly...) All withing the same environment (a single IDE)
  • Also, about static typing, it is possible to have it in Common Lisp (the first Haskell implementation was on top of Lisp). See also Drew McDermott?'s Nisp: http://cs-www.cs.yale.edu/homes/dvm/
(If it looks like Common Lisp would have to many rows counting as "lib", it is exactly why people say it is a "programmable programming language". If a feature is not there, you can add it without changing the core standard. For example, currying, pattern matching etc)

Corrections about Ada : GC – mentioned above. Hash=Lib – Ada 2005 has Ada.Strings.Hash resizeable arrays – not specified by standard, but GNAT has some packages for this. GNAT.Table & GNAT.{Dynamic Tables}?. -- IvanLevashew?

Missing Java capabilities : most of the cells stating No should better indicate a MayBe?, because they are supported by libraries. Some cells are specified in Yellow (Lib), despite these libraries are part of the core standard and mandatorily supported (for example Bitset). Dynamic class loading is Yes (through the standard core library, by instanciating a new ClassLoader?). Dynamic class generation is possible as well through this mechanism, using a standard library to compile it (if generating Java source code), or a utility libary for generating "native" bytecode (now partly integrated of the Java core libraries since Java 6), or even debug it (through a standard core library based on a unique interface and a default implementation also provided with the VM but that may overridden using the same interface), and using the Classloader to load the dynamic class in that protected environment where these dynamic classes can then be instanciated. If security is an issue, there's even the possibility of instanciating a separate VM initialized with this classloader and completely control its execution and its used resources (even if this separate VM crashes completely). -- VerdyP

Compatibility with C : how come C itself has a 'Most' and a 'No' for C compatibility? The features should be described in a C-positive fashion. Changed the languages that answered 'For Interfaces Only' (yellow) to 'No' (red) for Multiple Inheritance, since there is a separate Interfaces which cover that. On Interfaces, C++ probably should be downgraded to (yellow), since it can sort-of support Interfaces using Multiple Inheritance as a kluge, but C++ Multiple Inheritance (used for Interfaces) does not provide the safety/security of real Interface support. It would also be nice to have a D 2.0 column, separate from D 1.0 -- since D 2.0 is a work-in-progress. It would be nice to have someone savvy with Objective-C? and Objective-C? 2.0 to do an language comparison analysis. Is anyone working on a API-compatible Objective-D?, which would be GNUStep and Cocoa compatible (Objective-C? could vastly be improved if the C part and all that bad legacy mojo could be replaced with 20/20 hindsight beauty of D)? -- EljayLoveJensen

Corrections about C-derivatives

  • Complex says "Yes" in C - certainly not in C89(ANSI) and older. Is this C99 then?
  • String says "No" in C and "Yes" in C++. This does not make sense. C and C++ are pretty equal here: both have primitive char[] (and char*) which is just an array (pointer) to the compiler. Both have std library support for string operations, although C++ is more sophisticated about it. Therefore both should be marked "std lib". D boasts core support for native string type and basic manipulation, unlike C++, and this is supposed to motivate the "Yes" for D.
  • Certain OOP features should be marked "N/A" in C rather than "No", for example "inner classes". In fact there should be some fundamental OOP feature(s) listed, such as "classes", with "No" for C, and several derived features "N/A".
-- AndersHallström?

Rows for OOP vs Modules

Modules should not be confused with OOP. (Interfaces seem to fall somewhere in between though.) There should be one section "Modularization" and one section "OOP". -- AndersHallström?

C++11 updates C++11 added a lot of new features, the table should be updated to reflect this:

  • C++11 adds some definitions about garbage collection to the standard, allowing garbage collected implementations (though this is implementation-defined and no major implementations provide garbage collection as of speaking)
  • Regexes are now part of the stdlib
  • C++11 has fixed-size arrays with bounds checking (std::array), through not for dynamically allocated arrays.
  • "Function delegates" are in fact not a lot more than function pointers, which both C and C++ have. C++11 introduces std::function as a convenience wrapper on top of that.
  • Nested functions are possible in C++11.
  • Function literals, dynamic closures and lexical closures are all available through the new lambda syntax.
  • Currying is now available (std::bind)
  • Higher-order functions have always been available (e.g std::transform ("map"), std;:accumulate ("fold"), std::for_each), C++11's lambda and std::function make this even easier.
  • C++11 includes the new thread library.
  • C++ should have access to all C types (no idea why that is marked as 'no').
  • C++11 has alignment control (alignas, alignof)
Also, a few general remarks:
  • Garbage collection can be implemented in C++ and c through a library (e.g. bdw-gc)
  • Arbitrary-precision arithmetic is available through libraries as well (e.g. libgmp)
-- SeySayux?
FrontPage | News | TestPage | MessageBoard | Search | Contributors | Folders | Index | Help | Preferences | Edit

Edit text of this page (date of last change: December 11, 2012 13:58 (diff))