Some of the things you mention are also discussed in the linked paper. For example, quoting from Section 8.11 (Module system):
"... other than inertia one of the main arguments in favor of the status quo was that Elisp’s poor man’s namespacing makes cross-referencing easier: any simple textual search can be used to find definitions and uses of any global function or variable ... "
A few of the issues you mention can likely be improved, or resolved by using a better abstraction, or by deprecating features that are no longer needed. The Emacs community is typically very responsive and willing to discuss many issues in great detail. For example, if you run into performance issues or missing features, you can use Emacs itself to file a bug report, using:
M-x report-emacs-bug RET
As an example for switching abstractions and also addressing one of your points, I find that working on strings can be extremely frustrating and error-prone, both in Elisp and also in other languages. In Emacs, it is often much more convenient to work on buffer contents instead. So, to perform complex string operations in Elisp, I often spawn a temporary buffer (with-temp-buffer), insert the string, and then perform the necessary modifications on the buffer content. A significant advantage of this is that I can use common editing operations such as moving forward or backward by several lines or characters. When done, I fetch the whole buffer content (using for example "buffer-string"), and use that as the result. In many cases, and especially if the data are logically structured, it is better to use Lisp forms instead of plain strings.
However, some of the basic things you mention are in my experience quite straight-forward. For example, with only a few lines of code, I can copy the front page of HN as HTML text (in fact, the whole HTTP response) into the current Emacs buffer:
This automatically spawns a TLS connection, and I find this API quite convenient. I can then operate on the response as on any buffer content. Also, I can inspect the connection for example with list-processes, and many other functions. Spawning processes is quite similar, using for example start-process.
To write code that performs decently in Emacs-Lisp, you have to work with buffer contents rather than substrings, and it is just another frustration, the primitives for working with buffer contents are low level and heavily stateful, you end up writing imperative code that looks a lot like pascal or whatever, while loops conditioned on regexp searches, tons of setq's, moving point and mark around etc. It isn't a convenient way of programmatically modifying text. The basic examples of doing search and replace described here:
I think the issue is not that there are missing features, it is that there are too many features. Elisp would benefit a lot from pruning and standardization of its many, many, many builtins.
This is a very hard problem to recover from, because backwards compatibility is so important for something like Emacs. Breaking old versions would be completely unacceptable, which makes it very difficult to remove any features.
"... other than inertia one of the main arguments in favor of the status quo was that Elisp’s poor man’s namespacing makes cross-referencing easier: any simple textual search can be used to find definitions and uses of any global function or variable ... "
A few of the issues you mention can likely be improved, or resolved by using a better abstraction, or by deprecating features that are no longer needed. The Emacs community is typically very responsive and willing to discuss many issues in great detail. For example, if you run into performance issues or missing features, you can use Emacs itself to file a bug report, using:
As an example for switching abstractions and also addressing one of your points, I find that working on strings can be extremely frustrating and error-prone, both in Elisp and also in other languages. In Emacs, it is often much more convenient to work on buffer contents instead. So, to perform complex string operations in Elisp, I often spawn a temporary buffer (with-temp-buffer), insert the string, and then perform the necessary modifications on the buffer content. A significant advantage of this is that I can use common editing operations such as moving forward or backward by several lines or characters. When done, I fetch the whole buffer content (using for example "buffer-string"), and use that as the result. In many cases, and especially if the data are logically structured, it is better to use Lisp forms instead of plain strings.However, some of the basic things you mention are in my experience quite straight-forward. For example, with only a few lines of code, I can copy the front page of HN as HTML text (in fact, the whole HTTP response) into the current Emacs buffer:
This automatically spawns a TLS connection, and I find this API quite convenient. I can then operate on the response as on any buffer content. Also, I can inspect the connection for example with list-processes, and many other functions. Spawning processes is quite similar, using for example start-process.