12 ms·
While the article states that other languages were evaluated, it seems as though the project was motivated entirely by the author and the evaluation was just pa
by Xophmeister 8y ago
While the article states that other languages were evaluated, it seems as though the project was motivated entirely by the author and the evaluation was just paying lip service to what was basically a foregone conclusion. Don't get me wrong, I like D from the small amount of playing I've done with it -- and maybe it is the best tool for their purposes -- but this doesn't strike me as an impartial evaluation.
The need for nested functions bugged me as well. That seems like an odd deal-breaker and hints at code smell, rather than a genuine technical need. If it's just for the sake of one-to-one transpilation, then I can see the point, but a refactoring exercise seems like a better effort to make than language migration. (Also, don't Rust and Go have closures? Surely that would satisfy this requirement.)
- Cyph0n 8y ago> If it's just for the sake of one-to-one transpilation, then I can see the point, but a refactoring exercise seems like a better effort to make than language migration. I think the author makes it clear that direct conversion from Pascal is the primary goal. I'm guessing that once the codebase is fully transpiled to D, refactoring would be the logical next step.
- _veelo 8y agoConfirmed.
- philjohn 8y agoThe biggest problem is they have engineers who have turned their hands to programming, one would expect, without the formal training and so have latched onto various antipatterns without knowing any better because Pascal allowed them to get away with it - painting themselves into a corner. He mentioned an awful lot of code that would have to be refactored, and it could be that they are just too far down the rabbit hole to get themselves out.
- fsloth 8y agoI have a hunch the majority of domain specific engineering products are at least initially implemented by engineers of the domain and not software engineers.
- walshemj 8y agoVery strange in a hardcore technical programming context, I would have thought they would have used Fortran which is still being actively developed. I have never seen a reasoned argument why C++ vs Fortran is better for technical programming.
- scj 8y agoIn this case, I'd look into compiling the existing code into .dll/.so files, and just linking between Extended Pascal and ${NEW_LANGUAGE}. Then, convert the code to ${NEW_LANGUAGE} as needed, if needed. That solution is probably the lowest cost / safest course... Assuming the Extended Pascal compiler they have supports it. But I suspect choosing D was a fait accompli.
- Skunkleton 8y agoThis approach has always been the one that makes the most sense to me, but yet it also seems to be rare. I couldn't explain why.
- _veelo 8y agoThis is the approach I took to modernise Fairway (which is just one component of our suite). It doesn't free us from the limitations of the Extended Pascal compiler. It still works, but we want a way out.
- scj 8y agoHello, I assume by your username that you're the author! Transpiling is normally a little risky. Transpiling with a custom transpiler over ~500KLOC is downright terrifying. I'd be concerned that the cure is worse than the disease. I understand the allure of this solution. Bringing 30ish years of code into the modern era with a single piece of code sounds like a huge win. But you owe it to your employer (who seems really gracious and trusting) to ask: 1. Are there edge cases? Programmers are a clever bunch, and you can never be too sure about what features/bugs they've used/abused! 2. How will success of the transpile be determined? I'd use unit tests, but that'd take a lot of unit tests! 3. What % of that code path is critical? Can you get away with ensuring the functionality of a subset of the codebase? If so, could you just manually port that? 4. "Blaming the compiler" will be a reasonable excuse for any problem over the next year or two after deployment. I guarantee you'll be spending time proving that other peoples' mistakes are not your fault. How much flak are you and your boss going to take for this? 5. Since the code can be linked, might a more popular language (that will be known by a wider community) with a slow porting plan be reasonable? 6. Python is commonly used with scientific computing. Why does this case preclude it? If you are doing mostly numeric processing, that gets directly passed to the hardware anyway! You have been given a rare chance to pay down technical debt. From what I understand of your solution, I believe the bespoke transpiler and semi-known language will ultimately increase it. And I know you love D, but if I were brought in as a consultant, I'd be recommending the .dll/.so solution with Python. If something is really time sensitive, use Python binding to work with other languages (avoiding premature optimization). Even if myself or my fellow posters made a point that resonated, it might be too late for such discussions. I can't weigh the political costs for changing strategy now. So I'll wish you good luck, and hope that Extended Python doesn't have too many sharp edges for you to contend with. I hope to see a postmortem a few years from now detailing the outcome of this plan.
- noir_lord 8y agoGiven they started in the 80's Pascal probably has fewer corners to paint oneself into then many languages then (and now probably).
- _veelo 8y agoIndeed!
- 52-6F-62 8y agoTo be fair, I work with a large number of formally trained engineers who commit far worse in terms of anti-pattern and data hygiene infractions on the regular and I’ve had the fortune of refactoring their messes. I don’t think it’s solely dependent on having afforded formal training. Knowing enough to know that you might not know and just might need to measure or look something up and caring enough to do so is more of the core of it.
- burntsushi 8y ago> (Also, don't Rust and Go have closures? Surely that would satisfy this requirement.) Indeed they do. It's completely unclear why they don't satisfy the OP's requirement.
- _veelo 8y agoTo be frank: I have never used Rust nor Go. Nevertheless, I am quite sure closures and goroutines would complicate the translation due to different syntax from ordinary functions. The same argument is being discussed at reddit https://www.reddit.com/r/programming/comments/8si75b/how_an_engineering_company_chose_to_migrate_to_d/ https://www.reddit.com/r/programming/comments/8si75b/how_an_...
- jerf 8y agoSpeaking at least for Go, the "different syntax" between closures and functions is that for closures, you don't give a function name. The only way they could be any more similar is if closures did take a function name, which is generally a bad idea because there's no single behavior I've seen that captures what programmers expect to happen in that case. (In general, for the code x = func blah() { ... } there is a conflict between "x is the only new binding we should have as a result of executing that line" and "the function name 'blah' should do some sort of binding".) If that's enough to throw your translation process, you've got bigger problems.... (Cards on the table, D is probably a good choice and I'm not advocating for Go here.)
- kibwen 8y ago> I am quite sure closures and goroutines would complicate the translation due to different syntax from ordinary functions. It's unclear where the root of that confidence lies. The translation is just as mechanical in either language as it would be otherwise: see an inner function, replace it with the one thing that can capture variables. Speaking for Rust, it would actually be even easier to do the translation using closures, because Rust closures can have their signatures inferred whereas Rust functions cannot.
- 8y ago
- pjmlp 8y agoWell Microsoft deemed they are still relevant enough to add them to C# 7.
- Volt 8y ago>While the article states that other languages were evaluated, it seems as though the project was motivated entirely by the author and the evaluation was just paying lip service to what was basically a foregone conclusion. Now you understand how all of these "How we chose this language" writeups work.
- ssdd 8y agoYeah, almost all the time its the inclination of an individual towards a new language that becomes the driving factor of migration rather than the actual shortcoming of current language.
- acehreli 8y agoExcept that "the inclination of an individual towards a new language" is because of "the actual shortcoming of current language."
- deleted 8y ago[deleted]
- coldtea 8y agoActual or imaginary would be a better wording...
- protocode 8y agoI see mostly imaginary. As a back end systems guy for over 20 years, I deal with guys all the time wanting to introduce new tools into the mix that add zero value. There is a reason why *nix tools are still around. There is nothing that Python can do better than awk for grabbing data columns and piping them into some other tool. There is a reason why COBOL still exists, for example, what with its ability to ensure accuracy out to 38 digits. Nothing else comes close w/o tons of extra crap libraries, questionable code mangling, and TRUST. Banks trust COBOL because it has an almost 60-year history of trust. When kids get all shiny-eyed over golang or Rust or any other "new" language or tool and think it would be a good fit in the financial arena, I start to get a little nervous.
- closeparen 8y agoFraming closures as a “requirement” is pretty strange. Depending on the context they can be an ergonomic nice-to-have, but it’s not like you can’t express a program without them.
- setr 8y ago>Depending on the context they can be an ergonomic nice-to-have, but it’s not like you can’t express a program without them. When talking about turing complete languages, everything is an ergonomic nice-to-have. All language features aspire to be so nice to have, that you come back around and call it a necessity. But you can still express a program without them, unless you strip out so much as to lose turing completeness.
- closeparen 8y agoRight, which is why "requirement" is a silly framing that ascribes a sort of objective engineering necessity embedded in the problem to what is actually an subjective aesthetic choice between solutions. (I'm generally pretty skeptical of the whole "write down your requirements with no awareness of available solutions and then choose a solution that meets them" approach to decision-making).
- lomnakkus 8y agoWhy do you find it strange? To me, "requirement" signals that there's some sort of pain threshold for writing/maintaining code that the writer isn't willing to go above. Is there anything weird in that? > (I'm generally pretty skeptical of the whole "write down your requirements with no awareness of available solutions and then choose a solution that meets them" approach to decision-making). I also don't understand this. If there's a solution that meets all of the requirements what does it matter what there are other solutions? I mean, yeah, you be doing a local vs. global optimization, but as long it meets the requirements it's probably not a big deal. (The only exception is if the requirements are so broad as to be meaningless, but as long as they're reasonably specific, I don't see the problem.)
- 8y ago
- lambda 8y agoYeah, it looks like the author started playing around with D and writing a Pascal to D compiler for the migration, then did the evaluation with a "requirements" list that seems fairly heavily weighted towards D and their approach to translation by doing a simple recursive walk of the Pascal parse tree and outputting equivalent D, then decided to go with what they had already started working on. Rust does support nested functions that don't close over their environment, and has a separate syntax for closures which do, and closures can either move or borrow their captured variables. This makes it a bit harder to write a translator that produces good, idiomatic results; you could always use a closure that borrows the closed over variables, which I think matches the Pascal semantics, but that would mean the code would look a little odd for cases in which you had a nested function just to factor out some functionality and didn't need the closure. fn main() { let a = 10; fn function() { println!("Hi!"); // println!("a is {}", a) // fails with: // can't capture dynamic environment in a fn item // use the `|| { ... }` closure form instead } let borrow_closure = || println!("a is: {}", a); let move_closure = move || println!("a is still: {}", a); function(); borrow_closure(); move_closure(); }
- WalterBright 8y agoD nested functions are defined exactly like regular functions, including all attributes, parameter types, etc. There's nothing new to learn. My experience as a language designer is that syntax matters, and leveraging the users' existing knowledge is worthwhile.
- pmarin 8y ago>The need for nested functions bugged me as well. That seems like an odd deal-breaker and hints at code smell Nested functions were a very common pattern on languages like Pascal, Modula or oberon. They are equivalent to code blocks inside a function in C.
- _veelo 8y agoIndeed, it serves encapsulation.
- WalterBright 8y agoThe equivalent in C is code blocks connected with gotos. In my conversions of C code to D, I'm able to replace these gotos with nested functions, which makes the code significantly easier to read.
- mratsim 8y agoGiven the Pascal history and even consideration of Ada, with the focus on expressiveness and ergonomics I'm surprised that Nim didn't make the shortlist. Nim even has an official Pascal-->Nim converter (called pas2nim) as the very early versions of Nim before bootstrapping were in Delphi.