Watching “Why is C# Evolving This Way?” strengthened my realisation that the Delphi 12 language by now is light years behind C# 12
Posted by jpluimers on 2023/12/07
Though after C# 4 (covariance and contravariance) and C# 5 (async/await) the evolvement of C# might have seemed to slow down a bit, the big picture hasn’t as shown in the [Wayback/Archive] Why is C# Evolving This Way? – YouTube video by Zoran Horvat which comes down to:
- Summing up all major changes between C# 1 and C# 12
- Grouping them by major aspects:
- Generics (covariance and contravariance, generic constraints, and covariant return types)
- Performance upgrades (expression trees, null-conditional, async/await, spans and async streams)
- Define behaviour in a functional model (ranges, extension methods, and many kinds of pattern matching)
- “Pure gold” (lambda expressions, expression-bodied methods, nullable references, init-only setters, lambda types, primary constructors, records and record structs) allowing all other aspects to be written in far more elegant ways
- Grouping them by usage:
- DATA (ranges, records, records, record structs, primary constructors, init-only setters and nullable references)
- BEHAVIOUR (“just” pattern matching)
- SYNTAX (extension methods, lambda expressions, lambda types, expression-bodied methods)
- Explaining the WHY
The last step can only be done by performing the former steps.
LINQ (made possible by generics, expression methods, lambda expressions and expression trees) and immutable collections (from .NET core 1, made possible by the same features as LINQ) were the first big examples of the WHY as it allowed mixing OOP and functional paradigms.
People more closely familiar to F# would probably have guessed by .NET core 1 (and maybe even by C# 3: LINQ prerequisites) that C# was heading steadily into supporting functional programming very well.
That is really the WHY of all the other big C# language enhancements.
The WHY of going functional is separating data and behaviour.
And that is needed because of how we develop software today: with the ever spreading of dependencies on external services, stacks or other data storage (or APIs not even having their own storage) we have far less influence on underlying data models and interfaces. More often than not we are mapping or rewriting data from one set of domain models to another set. Pattern matching based on functional programming is way easier to write and comprehend than procedural coding styles.
Delphi 12, stuck between the language level of C# 3 and C# 4 and a few features of later C# versions is indeed light-years behind.
–jeroen
Jan Snyder said
Old is gold.
Cameron said
The fundamental problem with C# has been that it is an evolving language with evolving underpinnings making long term development projects in it a serious problem for many shops. Contrast to C++, SQL, ADA, Delphi/Pascal, Python, etc which are nearly immutable at this point. While I appreciate new language features, apps that have long lives need consistency which C# hasn’t really provided at least since its inception. Outside of the unicode conversion in Delphi which IMO was handled poorly, apps built two plus decades ago still compile. That isn’t a big seller for new development or young programmers looking to pad a resume but it certainly is for long running projects.
In my industry of medical billing many of the big players still run COBOL, MUMPS and even some in old dbase style setups like FoxPro. More modern languages like C# are abject failures at cracking the market and the few that have almost entirely rely on SQL stored procedures for the bulk of the logic while using some form of HTML/Javascript for the front end. In those apps, C# becomes almost a transactional layer to communicate with a database engine.
C# moving through near countless data layers and interfaces… Winforms, Silverlight, WPF, Xamarin, WinJS, XAML and those are the ones I can remember off the top of my head. Microsoft has a legacy of abandoning their programming languages which makes banking on their programming environments dicey when apps in many industries are measured in decades.
jpluimers said
I think you are mixing up C# as a language with the various frameworks that exist in the .NET ecosystem.
In addition, there is hardly any old C# code that fails to compile with modern C# compilers. In that respect, the C# language team pays similar respect to backward compatibility as the Delphi language team.
Of course there have been issues, in Delphi not just while migrating from ASCII to Unicode, but also much earlier transitioning from 16-bit to 32-bit world and later the introduction of the .NET compiler, even later when introducing 64-bit compilers (good bye
Extended
data type) and compilers for other platforms than Intel through LLVM (good bye parts of reliable exception handling (see https://dalijap.blogspot.com/2023/12/catch-me-if-you-can-part-ii.html)) and with the introduction of localvar
the change in lifetime of variables (see https://blog.synopse.info/?post/2021/09/21/Delphi-10.4-/-Delphi-11-Alexandria-Breaking-Changes) breaking RAII (see http://blog.barrkel.com/2010/01/one-liner-raii-in-delphi.html). Some were solved with adding extra warnings or directives (see https://docs.embarcadero.com/products/rad_studio/radstudio2007/RS2007_helpupdates/HUpdate4/EN/html/devcommon/delphimessagespart_xml.html), others were breaking after very careful consideration (see https://hallvards.blogspot.com/2005/08/danny-thorpe-on-unicode-and-vcl.html via a lengthy discussion at https://groups.google.com/g/borland.public.delphi.language.delphi.general/c/6PI_ZnvwwTM).BTW: I think it is quite a shame that the Delphi 2007 and 2009 parts of the documentation have recently been excluded from Search Engines (see https://docs.embarcadero.com/robots.txt).
Similarly there are issues in C# as well. The proposal there was also to add warnings (see https://github.com/dotnet/csharplang/discussions/7033). I am really looking forward with what they come up with.
How many layers you put in between your GUI and your backend isn’t a matter of the language, but about how you design a system. If few layers work in either Delphi or C#: great!
The only real drawback of the many features that are in the C# language now is that for new people it takes longer to get started.
A big drawback on the .NET ecosystem is Microsoft killing frameworks almost as quickly as Google kills products. On the Delphi side of things, only the killing of Kylix was a really bad move.
On the other hand, quality of even the RTL in Delphi has been below par since Idera got in the picture and worse for non-RTL libraries which is why I far prefer for instance Omni Threading library over Task Parallel Library and 3rd party Data Access Layers over the internal ones (see for instance https://wiert.me/2018/06/13/delphi-ibx-and-the-turkish-i-problem/ and https://blogs.embarcadero.com/ibx-qp-issues-addressed-in-rad-studio-10-3-3/ which took 2 major versions to fix even after presenting the solution on a silver plate).
With Ian Barker on the team, hopefully quality will gets a boost.
On the language feature side of things, for a long time groundwork has been missing to introduce a LINQ like system (helpers on interfaces, lambda types and lambda expressions are missing, a lambda operator also would make things much cleaner), covariance and contravariance in generics, and async/await like language features (preferably with a plugable library like the memory manager currently is plugable too) for me.
--
jeroenMarco Breveglieri said
I am long time Delphi developer and (I think) a real Delphi lover, meaning both the language and the tooling, but I must agree with you. 😐
I believe that many of the most recent additions to the C# language are nothing less than syntactic sugar, especially when they concern abbreviations of some constructs to make them less verbose when, having a fully functional IDE and a code generator (even AI powered!), the tool generates and maintains most of the code automatically.
However, there are some elements that in my opinion are essential nowadays, for example a simplified and shorter syntax for expressing anonymous methods, i.e. lambda expressions. Maybe there are technical issues that I ignore about the process, but I believe that such a syntax would be easily supportable without breaking compatibility with legacy code and would pave the way for interesting developments in the future.
I would also like to see something similar to LINQ integrated into the language/RTL, perhaps taking inspiration from the “Spring4D experience” but with all the quality controls that Embarcadero considers appropriate to bring this into Delphi. I would also add constructs to create arrays or collections, in order to complete the started path (well started) with type inference and inline variable declaration.
I believe that the language is given less effort than it would require in order to accelerate code production especially on open source projects, which are a golden resource, and to better challenge emerging languages.
I understand that there are large customers with huge projects that need to continue to migrate and support, but new developments and new developers also need to receive more attention.
jpluimers said
I totally agree with you on the direction the Delphi should take.
MohamedMowafaq Arab said
Sorry to say that this sounds and feels like a paid Ad.
I think there is no benefit gained by Delphi developers from this article. I think you should show C# advantages if you are eager to let Embarcadero enhance Delphi to compete with C# instead.
jpluimers said
Hopefully the blog post will inspire the Delphi language team to add pressing features for instance allowing libraries to provide async/await or LINQ. Having the groundwork in the language does not mean Delphi should provide the libraries as well: 3rd party library vendors usually have way shorter feature and bug-fix cycles.
Marco Cantu said
Delphi IS Dead.
jpluimers said
On the contrary. Tt could flourish even more with the addition of core features like groundwork for LINQ and async/await.