Bastiaan Veelo is the lead developer of a specialised program for the
computer aided geometric design of ship hulls called Fairway, for the
company SARC in the Netherlands.
Imagine there is this little-known programming language in which you enjoy programming in your free time. You know it is ready for prime time and you dream about using it at work everyday. This is the story about how I made a dream like that come true.
My early acquaintance with D
Back when “google” was not yet a common verb, I was doing a web search for “parsing C++”. The reason was that writing a report for an assignment had derailed into writing a syntax highlighter for noweb using bison and flex, and I found out firsthand that C++ is not easy to parse. That web search brought up this page (present version) with an overview of the D Programming Language, and the following statement has had me hooked ever since:
D’s lexical analyzer and parser are totally independent of each other and of the semantic analyzer. This means it is easy to write simple tools to manipulate D source perfectly without having to build a full compiler. It also means that source code can be transmitted in tokenized form for specialized applications.
“Genius,” I thought, “here we have someone who knows what he’s doing.” This is representative of the pragmatic professionalism that still radiates from the D community, and it combines with an unpretentious flair that makes it pleasant to be around. This funny quote decorated its homepage for many years:
“Great, just what I need.. another D in programming.” – Segfault
Nevertheless, I didn’t have many opportunities to use the language and I largely remained sitting on the fence, observing its development.
Programming professionally
With mostly academic programming experience, I started programming professionally in 2006 for SARC, a Dutch engineering company serving the maritime industry. Since the early ’80s they have been developing software for ship design and onboard loading calculations, which today amounts to roughly half a million lines of code. I think their success can partly be attributed to their choice of programming language: Extended Pascal (the ISO 10206 standard, not one of the many proprietary extensions of Pascal).
Extended Pascal was a great improvement over ISO 7185 Pascal. Its compiler, by Prospero Software from England, was fast and well documented. The language is small enough and its syntax appropriately verbose to make engineering professionals quickly productive in programming. Personally though, I spent most of my time programming in C++, modernizing their system for computer aided design of ship hulls using Qt and Coin3D.
When your company outlives a programming language
Although selecting an ISO standard in favor of a proprietary Pascal dialect seemed wise at the time, it is apparent now that the company has outlived the language. Prospero Development Software Ltd was officially dissolved 15 years ago. Still, its former director, Tony Hetherington, continued giving support many years after, but he’d be close to 86 years old now and can no longer be reached. Its website is gone, last archived in 2013. There’s GNU Pascal, which also supports ISO 10206, but that project has stopped moving and long ago lost synchrony with gcc. Although there is no immediate crisis, it is clear that something needs to happen sometime if the company wants to continue its activities in the coming decades.
Changing the odds
A couple of years ago, I secretly started playing with the fantasy of replacing Extended Pascal with D. Even though D’s syntax is somewhat different from Pascal, it shares at least four important similarities: support for nested functions, boundary checking, modules, and compilation speed. In addition, it has many traits that make the language attractive to engineers: good focus on performance and numerics, garbage collection, dynamic arrays, easy parallelization, understandable templates, contract programming, memory safety, unit tests, and even wysiwyg strings and formatted numerals. D’s language features encourage experimentation, which resonates well with engineers.
So I wondered what I could do to highlight D’s significance to my employer and show it’s an attractive language to switch to. I thought I could make a compelling case if I could write a parser in D that would take Extended Pascal source and transpile it to D source. At least I would have fun trying!
So I went over to code.dlang.org to see if there were any D alternatives to flex and bison. There, I found Pegged, and instantly the fun began. Pegged combines the functionality of flex and bison in one incredibly easy to use package, for which its creator Philippe Sigaud obviously enjoyed writing excellent documentation. Nowadays, Pegged is part of the D language tour and you can try it out on-line without having to install a thing. The beauty is that the grammar from the Extended Pascal language specification maps almost linearly to the PEG from which Pegged generates the parser. For this it makes heavy use of D’s generic programming capabilities and compile-time function evaluation — it can generate a parser at compile time if you want it to!
However, it wasn’t smooth sailing all along. As I was testing D, I suddenly found myself being tested as well. I learned the hard way that there is a phenomenon called left-recursion, from which a PEG parser typically cannot break out of. And the Extended Pascal grammar is left-recursive in several ways. Consequently, I spent many evenings and weekends researching parsing theory, until eventually I managed to extend Pegged with support for all kinds of left-recursion! From one thing came another, and I added longest match alternation, case insensitive literals, the toHTML()
method for dynamically browsing the syntax tree, and a tracer for logging the parsing process.
Obviously, I was having fun. But more importantly, I was demonstrating that the D programming language is accessible enough that a naval architect can understand other people’s code and expand it in non-trivial ways. The icing on the cake came when I was asked to present my experiences at DConf 2017 in Berlin, which you can watch here (and here’s the extra bit I presented at lunch time for the livestream audience).
At this time, I was able to automatically translate the following trivial example:
program hello(output); begin writeln('Hello D''s "World"!'); end.
into D:
import std.stdio; // Program name: hello void main(string[] args) { writeln("Hello D's \"World\"!"); }
Language competition
Having come this far, the founder of SARC agreed that it was time to investigate the merits of various alternative programming languages. We would do a thorough and objective comparison based on trial translations of a comprehensive set of language features. Due to the amount of manual labor that this requires, we had to drastically prune the space of programming languages in an initial review round. Note that what I am about to present does not declare which programming language is the best in our industry. What we are looking for is a language that allows an efficient transition from Extended Pascal without interrupting our business, and which enables us to take advantage of modern insights and tools.
In the initial review round we looked at general language characteristics. Here I’ll just highlight what fell through the sieve and why.
Performance is important to us, which is why we did not consider interpreted languages. C++ is in use for one component of our software, but that was written from the ground up. We feel that the options for translation are not favorable, that its long compile times are a serious hindrance to productivity, and that there are too many ways in which one can shoot one’s self in the foot. We cannot require our expert naval architects to also become experts in C++.
Nowadays, whenever D is publicly evaluated, the younger languages Go and Rust are often brought up as alternatives. Here, we need not go into an in-depth comparison of these languages because both Rust and Go lack one feature that we rely on heavily: nested functions with access to variables in their enclosing scope. Solutions for eliminating nested functions, like bringing them into global scope and passing extra variables, or breaking files up into smaller modules, we find unattractive because it would complicate automated translation, and we’d like to preserve the structure and style of our current code. GNU C does offer nested functions, but it is a non-standard extension and it has been predicted that many will move away from C due to its unsafe features. After this initial pruning, three languages remained on our shortlist: Free Pascal, Ada and D.
As a basis for our detailed comparison, we wrote fifteen small programs that each used a specific feature of Extended Pascal that is important in our current code base. We then translated those programs into each language on our shortlist. We kept a simple score board on how well these features were represented in each language: +1 if the feature is supported or can be implemented, 0 if the lack of the feature can be worked around, and -1 if it can’t. This is what came out of that evaluation:
Test | Free Pascal | Ada | D |
---|---|---|---|
Arrays beginning at arbitrary indices | +1 | +1 | +1 |
Sets | 0 | 0 | +1 |
Schema types | 0 | 0 | +1 |
Types with custom initial values | -1 | 0 | +1 |
Classes | +1 | +1 | +1 |
Casts | +1 | +1 | +1 |
Protection against use of dangling pointers | -1 | +1 | +1 |
Thread safe memory [de]allocation | +1 | +1 | +1 |
Calling into Windows API | +1 | +1 | +1 |
Forwarding Windows callbacks to nested functions | +1 | +1 | +1 |
Speed of calculations | +1 | +1 | +1 |
Calling procedures written in assembly | +1 | 0 | +1 |
Calling procedures in a DLL | +1 | +1 | +1 |
Binary compatibility of strings | 0 | +1 | +1 |
Binary compatible file i/o | -1 | 0 | 0 |
Score | 6 | 10 | 14 |
So, Free Pascal is the only candidate with negative scores, Ada positions itself in the middle, and D achieves an almost perfect score. Not effortlessly, though; we’ll talk about some of the technical challenges later. Because Free Pascal is, like D, fully Open Source and written in itself, extending the language and filling in the gaps is theoretically possible. Although some of its deficiencies could certainly be resolved that way, others would be quite complicated and/or unlikely to be accepted upstream.
We also estimated the productivity of the languages. Free Pascal scored high because it is closest to what we are used to. Despite its dissimilar syntax, D scored high because of its expressiveness and flexibility. Ada scored lowest because of its rigidity and because of the extra work the programmer has to put in (most importantly casts and conversions). Ada is more verbose than Pascal which was disliked by some of us because it can somewhat obscure the essence of what a piece of code tries to express, and frequently the code became not only verbose but cryptic, which was unanimously disliked.
Third, we estimated the future prospects and the advantages each language could bring to the table. Although Free Pascal has a more active community than we expected it to have, we do not see great potential for growth. Ada is renowned for its support for writing reliable code (although it has no monopoly in that field) but it does come at a cost and requires real effort. D has a dynamic and open community, supports both script-like productivity and high performance, includes various features for writing reliable software (approaching Ada but at a much lower cost), and offers some unique advanced features with which wonders can be accomplished.
Finally, we estimated the effort of translation. Although Free Pascal is very similar to Extended Pascal, missing features pose a real problem and would require a high degree of manual translation and rewriting. Although p2ada
exists, it only works partially in our case and does not fully support Extended Pascal. Because Ada frequently requires additional code (casting to the correct type, pulling in a package, instantiating a generic type, adding a pragma, splitting up Put_Line
s etc.), writing or extending a reliable transpiler into Ada would be more difficult than doing the same into D.
Selecting a winner
I gave away the winner in the title, but we landed at that conclusion as follows. Ada was the first language to be dropped. We really felt that the extra work that the programmer has to put in is a brake on productivity and creativity. Although it barely played a role in our evaluation, illustrative is the difference between the Ada and D equivalents to the Expressive C++17 Challenge. The D solution is both concise and expressive, the Ada solution is hardly expressive and consists of more lines than I want to write or read. Also of secondary importance, but difficult to ignore, is the difference between the communities surrounding the languages, which in Ada’s case is AdaCore Support, who has no problems demanding annual five-figure subscription fees.
Although akin to our current language, Free Pascal was mainly dropped due to its porting challenges and our estimation that its potential is lower and its future outlook is less optimistic than that of D. If we were to choose Free Pascal, we would basically invest a lot of effort only to arrive at a technological solution that we felt would be of lower quality than we currently have.
And that’s were I saw a dream come true: A clap on the table by the company founder and it was decided to commit to the effort of bringing twenty-five years worth of Extended Pascal code to D!
What makes a difference
In short, my experience is that if a feature is not present in the language, D is powerful enough that the feature can be implemented in a library. Translating each sample program by hand has really helped to focus on replicating functionality, leaving the translation process for later concern. This has led to writing a compatibility library with types and functions that are vital for the conversion. Now that equivalents are known and the parser is done, I just have to implement code generation.
Below follows another example that currently translates automatically and executes identically. It iterates over a fixed length array running from 2
to 20
inclusive, fills it with values, prints the memory footprint and writes it to binary file:
program arraybase(input,output); type t = array[2..20] of integer; var a : t; n : integer; f : bindable file of t; begin for n := 2 to 20 do a[n] := n; writeln('Size of t in bytes is ',sizeof(a):1); { 76 } if openwrite(f,'array.dat') then begin write(f,a); close(f); end; end.
Transpiled to D (or should I say Dascal?) and post-processed by dfmt to fix up formatting:
import epcompat; import std.stdio; // Program name: arraybase alias t = StaticArray!(int, 2, 20); t a; int n; Bindable!t f; void main(string[] args) { for (n = 2; n <= 20; n++) a[n] = n; writeln("Size of t in bytes is ", a.sizeof); // 76 if (openwrite(f, "array.dat")) { epcompat.write(f, a); close(f); } }
Of course this is by no means idiomatic D, but the fact that it is recognizable and readable is nice, especially for my colleagues who will have to go through an unusual transition. By the way, did you notice that code comments are preserved?
One very-nice-to-have feature is binary file compatibility; In fact it may have been the killer feature, without which D might not have been so victorious. The case is that whenever a persistent data structure is extended in our software, we make sure that we can still read and convert that structure from its prior format. That way, if a client pulls out an old design from its archives and runs it through our current software, it will still work without the user even being aware that conversion occurs, possibly in multiple steps. Not having to give up that ability is very attractive.
But it wasn’t easy to get there. The main difficulty is the difference in how strings are represented in D and the Prospero implementation of Extended Pascal, in memory and on file. This presented the challenge of how to preserve binary compatibility in file I/O with data structures that contain string members.
Strings
In Prospero Extended Pascal, strings are implemented as a schema type, which is a parameterized type that can be used in the following ways:
type string80 = string(80); var str1 : string80; str2 : string(60); procedure foo(s : string);
This defines string80
to be an alias for a string type discriminated to have a capacity of 80 characters. Discriminated string variables, like str1
and str2
, can be passed to functions and procedures that take undiscriminated strings as arguments, like foo
, which thereby work on strings of any capacity. In memory, str1
is laid out as a sequence of 80 char
s, followed by a ushort
that encodes the length of the string. I say encodes because a shorter string is padded with \0
s up to the capacity and the ushort
actually contains the length of that padding. This way, when a pointer to the string is passed to a C function and the contents of the string occupy its full capacity, the 0
in the padding length doubles as the terminating \0
of the C string.
My first thought was to mimic this data representation with a D template. But that would require procedures like foo
to be turned into templates as well, which would escalate horribly into template bloat, a problem with multiple string arguments and argument ordering, and would complicate translation. Besides, schema types can also be discriminated at run time, which does not translate to a template.
Could some sort of inheritance scheme be the solution? Not really, because instances of D classes live on the heap, so a string embedded in a struct
would just be a pointer instead of the char
array and ushort
.
But binary layout is actually only relevant in files, and in a stroke of insight I realized that this must be why user-defined attributes, or UDAs, exist. If I annotate the string with the correct capacity for file I/O, then I can just use native D string
s everywhere, which genuinely must be the best possible translation and solves the function argument issue. Annotation can be done with an instance of a struct
like
struct EPString { ushort capacity; }
The above Pascal snippet then translates to D like so:
@EPString(80) struct string80 { string _; alias _ this; } string80 str1; @EPString(60) string str2; void foo(string s);
Notice how the string80
alias is translated into the slightly convoluted struct
instead of a normal D alias
, which would have looked like
@EPString(80) alias string80 = string; </code>
Although that compiles, there is no way to retrieve the UDA in that case because plain alias
does not introduce a symbol. Then hasUDA!(typeof(str1), EPString)
would have been equivalent to hasUDA!(string, EPString)
which evaluates to false
. By using the struct
, string80
is a symbol so typeof(str1)
gives string80
, and hasUDA!(string80, EPString)
evaluates to true
in this example.
There is one side effect that we will have to learn to accept, and that is that taking a slice of a string does not produce the same result in D as it does in Extended Pascal. That is because string indices start at 1 in Extended Pascal and at 0 in D. My strategy is to eliminate slices from the source and replace them with a call to the standard substr
function, which I can implement with index correction. Finding all string slices can be accomplished with a switch in the transpiler that makes it insert a static if
to test if the slice is being taken on a string
, and abort compilation if it is. (Array
s are transpiled into a custom array type that handles slices and indices compatibly with Extended Pascal.)
Binary compatible file I/O
Now, to write struct
s to file and handle any embedded @EPString()
-annotated strings specially, we can use compile-time introspection in an overload to toFile
that acts on struct
s as shown below. I have left out handling of aliased strings for clarity, as well as shortstring
, which is a legacy string type with yet a different binary format.
void toFile(S)(S s, File f) if (is(S == struct)) { import std.traits; static if (!hasIndirections!S) f.lockingBinaryWriter.put(s); else // TODO unions foreach(field; FieldNameTuple!S) { // If the member has itself a toFile method, call it. static if (hasMember!(typeof(__traits(getMember, s, field)), "toFile") && __traits(compiles, __traits(getMember, s, field).toFile(f))) __traits(getMember, s, field).toFile(f); // If the member is a struct, recurse. else static if (is(typeof(__traits(getMember, s, field)) == struct)) toFile(__traits(getMember, s, field), f); // Treat strings specially. else static if (is(typeof(__traits(getMember, s, field)) == string)) { // Look for a UDA on the member string. static if (hasUDA!(__traits(getMember, s, field), EPString)) { enum capacity = getUDAs!(__traits(getMember, s, field), EPString)[0].capacity; static assert(capacity > 0); writeAsEPString(__traits(getMember, s, field), capacity, f); } else static assert(false, `Need an @EPString(n) in front of ` ~ fullyQualifiedName!S ~ `.` ~ field ); } // Just write other data members. else static if(!isFunction!(__traits(getMember, s, field))) f.lockingBinaryWriter.put(__traits(getMember, s, field)); } }
At the time of writing, I still have work to do for union
s, which are used in the translation of variant records (including considering the use of one of the seven existing library solutions 1, 2, 3, 4, 5, 6, 7).
Currently, detecting union
s is a bit involved . Also, there is a complication in the determination of the size of a union when the largest variant contains strings: the D version of that variant may not be the largest because D string
s are just slices. I’ll probably work around this by adding a dummy variant that is a fixed size array of bytes to force the size of the union
to be compatible with Extended Pascal. This is the reason why D scored a mere 0
in file format compatibility. It is amazing what D allows you to do though, so I may be able to do all of that automatically and award D a perfect score retroactively. On the other hand, it is probably easiest to just add the dummy variant in the Pascal source at the few places where it matters and be done with it.
The way forward
Obviously, this is long term planning. It has taken years to grow into D; it will possibly take a year, and probably longer, to migrate to D. Unless others turn up who are in the same boat as us (please contribute!) it’ll be me who has to row this ship to D-land and I still have my regular duties to attend to. My colleagues will continue to develop in Extended Pascal as usual, and once my transpiler is able to translate all or almost all of it, we will make the switch to D overnight. From then on, we’ll be in it for the long run. We trust to be with D and D to be with us for decades to come!
I’m curious as to why golang wasn’t considered.
Golang (Go) was considered. It did not make the shortlist due to missing nested functions. Goroutines could possibly have offered an alternative to nested functions, but they would not translate 1-1.
Go offers closures, which seem to me to be a practical superset to nested functions. (Indeed, that D now implements closures with nested functions suggests that they are functionally equivalent.) They do have a slightly different syntax (as you define them the way you define a variable), but it wouldn’t seem to me to be a major issue for an automatic translator. What am I missing?
I think delegates are the D equivalent to closures. They can point to nested functions, and member functions. I don’t know if the following applies to go closures as well, but these arguments are being made against Rust closures: https://news.ycombinator.com/item?id=17359708 regarding recursion and borrowing. And there is some overhead https://news.ycombinator.com/item?id=17356539, https://www.reddit.com/r/programming/comments/8si75b/how_an_engineering_company_chose_to_migrate_to_d/e10cotu/
>Rust and Go lack one feature that we rely on heavily: nested functions with access to variables in their enclosing scope
It sounds like your company found a great fit with D, so I’m only asking out of curiosity: is there a downside to declaring closures instead of nested functions (specifically in rust)? It sounds like a feature you rely on heavily and I’m wondering if there’s nuance that prevented you from using closures. Excuse my inexperience in Rust, I’m a javascript developer by profession.
Yes, closures could possibly have offered an alternative to nested functions, but their different syntax to ordinary functions would have complicated automated translation. I must admit that I only recently learned about how closures and goroutines can emulate nested functions. Note also that D has delegates which I think are like closures, which will come in handy but are not necessary in the translation of nested functions.
Thanks for the writeup! Really cool you ended up making the jump 🙂
Never heard of Freepascal? (http://www.freepascal.org)
Of course I have heard of Free Pascal. You didn’t read the article.
“We would do a thorough and objective comparison based on trial translations of a comprehensive set of language features. Due to the amount of manual labor that this requires, we had to drastically prune the space of programming languages in an initial review round.” … “After this initial pruning, three languages remained on our shortlist: Free Pascal, Ada and D.”
You were “thorough and objective” in only one phase of the review. The criteria selection and initial pruning were highly subjective. By the time you got to the objective phase of the review, only 3 languages remained, with one the clear winner.
We’re going to pick a new material for building skyscrapers, and we’ve narrowed it down to straw, sticks, and bricks — now let’s perform some objective testing to see which is best!
“Performance is important to us, which is why we did not consider interpreted languages.”
Are you suggesting that people writing in interpreted languages consider performance unimportant? Did you do any (objective) performance testing on the languages in your survey to see if they were actually as efficient, for your workloads, as their feature list implied?
“we find unattractive because it would complicate automated translation, and we’d like to preserve the structure and style of our current code”
So if you’re going to continue to write Pascal in another language? (Ed Post observed back in the 1980’s that Real Programmers “can write FORTRAN programs in any language”, in his roast of Pascal. Considering how similar they are, it’s funny that your stated goals are to “take advantage of modern insights and tools”.) This sounds like a bad idea. Why not just pick up maintenance on the compiler? At least that way there’d be a good abstraction layer.
It’s not clear why one-shot automatic source translation was ever a requirement here. That seems to be the opposite of the industry best practices, and I can count on the fingers of one hand how many companies have done it successfully. You require the ability to make Windows calls, and you must know that Windows isn’t written in Pascal, so I’m not sure why you’d think that there’d be any issue making function calls across programming language boundaries.
“I thought I could make a compelling case if I could write a parser in D that would take Extended Pascal source and transpile it to D source. At least I would have fun trying!”
So despite all the talk, this wasn’t really about an engineering decision. It was about fun. Good for you! Most people don’t have fun at work, and if you can manage it, keep it up. I hope your non-engineering approach doesn’t cause too many problems for your company.
“The criteria selection and initial pruning were highly subjective. By the time you got to the objective phase of the review, only 3 languages remained, with one the clear winner.” You have a point. But I have not the capacity to compare every programming language out there in equal detail. I already have a PhD, and it too took a lot of time. We have to keep our focus at the goal, which is to translate an awful lot of code. We cannot spend all our time on deciding which language is the absolute best. We need something that we think is obtainable, and desirable. It seems you are underestimating Free Pascal and Ada. Before we started, I had no idea who would come out on top, it could have been any of the three.
“Are you suggesting that people writing in interpreted languages consider performance unimportant? Did you do any (objective) performance testing on the languages in your survey to see if they were actually as efficient, for your workloads, as their feature list implied?” No and yes.
“So if you’re going to continue to write Pascal in another language?” Possibly, but I hope not. The transpiled code will look like Pascal, but that is unavoidable. There will be many opportunities to learn idiomatic D and take advantage of its potentials.
“Why not just pick up maintenance on the compiler?” We have considered that. As the source to the Prospero compiler and run-time are unavailable, we would need to switch to GNU Pascal, and implement some Prospero extensions there. Or extend Free Pascal. We made a deliberate choice against that.
“so I’m not sure why you’d think that there’d be any issue making function calls across programming language boundaries.” I’m not sure why you’d think I’d think that. Using cross-language linkage is the way to go for extending a system using modern techniques, and that is what I’ve done for Fairway. However, there is no way that I’ll manually translate the core of Fairway that is still in Extended Pascal. As long as we don’t translate or port that code, we are bound by the limitations of the aging compiler. And Fairway is just one component of our toolset.
Thanks for reading and doing a thorough analysis of my text. You seem not to share our optimism. Time will tell if we succeed. Please check back here in a long while, as I’ll likely write about it when/if we do succeed!
Programming: no fun allowed.
Very ambitious project and I hope you get enough support from the D community to make this a real success.
Their work can lead to more general tools for transitioning code from xlang to D. (xlang = any procedural language).
Just my two cents, but I see you haven’t evaluated Crystal, despite it’s not that far from what you were looking for.
Moreover, from what I’ve seen in you examples, your generated D source code will really loose in readability compared to the original Extended Pascal code.
While I’m also a big fan of D, if you really have one or more man-years to implement your Pascal-to-D transpiler, then I’d your use case is literally screaming : “make your own Extended Pascal compiler front-end over an existing compiler back-end (LLVM, etc)”.
This way the readability of your existing code base remains perfectly unchanged, your teammates don’t have to change anything to their habits, and you can now benefit from the assistance of many volunteer developers interested in helping you develop your Extended Pascal compiler for their own use if you make it available on Github as an open source project…
”
So despite all the talk, this wasn’t really about an engineering decision. It was about fun. Good for you! Most people don’t have fun at work, and if you can manage it, keep it up. I hope your non-engineering approach doesn’t cause too many problems for your company.
”
Language is a medium of expression and is intimately tied to thought. And that means that any decision about language choices is a decision about values as well as about intrinsic technical merits. So it’s the right values for the domain not merely the right tool for the job. And the right choice of values depends on who you are as a group as well as the context of the problem domain faced by your company.
You’re asking a lot of a short blog post! It’s quite presumptuous to tell someone you don’t know in a group you don’t know in an industry you don’t know that they are doing it wrong…
Have you read Paul Graham’s essay on Great Hackers? It’s dated in how it refers to Java and Python, but I think the substance still speaks to us today.
”
When you decide what infrastructure to use for a project, you’re not just making a technical decision. You’re also making a social decision, and this may be the more important of the two. For example, if your company wants to write some software, it might seem a prudent choice to write it in Java. But when you choose a language, you’re also choosing a community. The programmers you’ll be able to hire to work on a Java project won’t be as smart as the ones you could get to work on a project written in Python. And the quality of your hackers probably matters more than the language you choose. Though, frankly, the fact that good hackers prefer Python to Java should tell you something about the relative merits of those languages.
Business types prefer the most popular languages because they view languages as standards. They don’t want to bet the company on Betamax. The thing about languages, though, is that they’re not just standards. If you have to move bits over a network, by all means use TCP/IP. But a programming language isn’t just a format. A programming language is a medium of expression.
“
Actually what should happen in their case is that the existing team of hacker will be educated to D. Your quote is more relevant for, let’s say, a start-up starting from scratch.
Honestly i think it will be a straight transition. There are many ex-Delphi / ex-Pascal coders in the D community, incl. me, and i don’t see why they wouldn’t succeed.
Indeed, “non-idiomatic” D is closer to EP than to Rust or C++ for instance.
But what you forget is that with this transpiling approach there will be many tips and indirections involved (wrapper functions, string user attributes, etc), in order to make the generated D code work exactly as the original Pascal code (strings, files, etc). I still think it’s a very convoluted approach to solve the problem of an obsolescent Pascal compiler. Using (and if needed fixing) the existing GNU Pascal compiler in Extended-Pascal mode was probably the most pragmatic solution.
And if that solution didn’t work, then the second best solution to this problem, IMHO, if at least one man-year was allocated for this transition, which seems to be the case, was to hire a compiler specialist to implement an EP compiler front-end over an existing back-end, inspired from an existing or similar front-end. AFAIK there are already two partial Pascal compiler implementations based on LLVM, which could have been used as least as a basis or an example for this front-end implementation.
So yes, D is clearly not the hardest strongly-typed language his fellow programmers could have to learn, but I still think that replacing the old EP compiler by a new one was the smoothest approach, and maybe also the less risky…
Btw, the LibJIT project provides a sample Pascal implementation :
https://www.gnu.org/software/libjit/doc/libjit_3.html#Dynamic-Pascal
https://github.com/ademakov/libjit/tree/master/dpas
This code is quite old, but I think it may be useful as an example, as it’s both a simple and complete implementation. It should still give you a few clues on how to implement a Pascal transpiler, JIT compiler or AOT compiler, even based on another backend…
There is also a very clean implementation of a D-like language compiler here :
https://github.com/VoltLang/Volta/tree/master/src/volt
It’s written in D and based on LLVM.
I was choosing a programming language for myself to play with for the next year, with the help of which I plan to implement all sorts of small things for myself and for my projects at https://engre.co/services/software/it-engineering/ and drew attention to such a language as D, the tour passed, I looked through it, the compiler installed it, I drove examples, everything seems to be like.
However, it is embarrassing that, for all its coolness, the D language has no interest from the community, which, for example, shows the fact of a very small ecosystem D and I really do not understand why this happened, why the Haskell has 11 times more modules, for example, or even grow already 9 times more .. wtf
Therefore, I want to ask which of the local specialists uses D and for what? and then go after a couple of working projects bothered me, how many times I haven’t tried to master Rust and write something real on it – I don’t like it and that’s it, I don’t have a heart for it.
D has plenty of interest from its community. It’s still small, but it has been slowly and steadily growing for years.
I don’t know what you mean by “local specialists”, but the D forum is a good place to connect with D users:
https://forum.dlang.org/
There’s also an active Discord server maintained by community members where D users frequently discuss their current projects:
https://discord.com/invite/bMZk9Q4
Hi Michael,
I am sorry about the “local specialist”. Yes, I find that on the forum there is valuable information for me.
Thanks for all links. I hope that in the future we will build a strong community.