Multithreading / Async
The ABL Virtual Machine (which runs OpenEdge code) is single-threaded. Trying to access anything from a threaded .Net library results in a run-time error. You can do multi-process parallelism, however, there are plenty of uses for multi-threading that are not feasible with a multi-process model. The main one that I am interested in is being able to make long-running calls (DB, Long-Running Calculations, Network or Serial device polling) without locking up the UI thread. Since Windows will make it look like the application has stopped working, that often results in a lot of user frustration. Additionally, there's no reason that we can't perform other work while waiting for these processes for finish. For some of these use cases, some variation of asynchronicity would be fine as well.
OpenEdge added support for "GUI for .Net" in Version 10.2A in 2008. This added support for the use of Windows Forms as a UI for OpenEdge projects. That was the way towards "modernization" and getting a "modern"-looking UI. While they've added some more support for WinForms features, the .Net world has moved to WPF for a variety of reasons (and IMO, the strongest being that a markup language is much easier to describe a UI in than code). While WinForms is not dead, it's definitely dying and showing its age. Some companies are still in the process of adopting GUI for .Net, but is it really modernizing if you are using an already outdated UI tech?
I don't anticipate seeing this, though, because Progress seem to be very much pushing a web frontend/OpenEdge backend approach. This is fine, except that the AppServer, which is the primary component allowing you to use OpenEdge as a backend language, has additional license costs beyond the normal per-user fee for the run-time and the database[^1].
In OpenEdge, it's not uncommon to have a bit of code like this:
do i = 1 to num-entries(list):
// Action on List
i = i + 1.
In python and many other languages, the assignment being done on
i can be expressed with some syntactic sugar called "Addition Assignment".
i += 1
It's not a huge change, obviously, but it saves a few keystrokes while expressing the same idea. Longer variable names (like you might see from strings) benefit from it even more.
In recent editions of OpenEdge, support was added for Enums to provide static type checking for certain special values as well as flags. However, support is still very basic. OpenEdge enums are not full-fledged classes. You cannot add methods to them. You cannot serialize and de-serialize them automatically.
We ended up rolling our own enums-style classes with static properties for each value in order to implement these missing features. It's a huge amount of boilerplate added to get serialization. I suspect we are not the only ones who want to store Enum values in the database or in a configuration file. We also regularly use enums for a set of statuses, which usually have colors associated with them. In a standard Enum, those would need to be included in a static utility class whereas here they can be added to the pseudo-enum directly.
A related feature that would be nice to have would be to allow you to specify a database field as an enum type (that would seemlessly serialize and de-serialize to a string or integer in the background). Even if this is only allowed in temp-tables, it would still have a lot of boilerplate.
Arbitrary Number of Arguments to User Functions
There are a number of built-in functions that support an arbitrary number of arguments. Unfortunately, the same is not true of user-written functions and methods. It's not actually possible to extend these functions or create wrappers for them.