- Keywords are all uppercase, and the language is case-sensitive. Uppercase keywords really annoy me and my fingers. They were justified back in the days when text editors didn't have syntax highlighting, but these days, they are just a major annoyance IMHO.
This would have to be the most common gripe I have heard. To me it is like somebody saying they wouldn't drive a Ferrari because they can't get it in any colour other than red.
I'm sure it is, and I can see why. I don't quite agree it's just a simple matter of taste, although it's certainly partly this.
Again, I would fully understand how this would make the code a lot more readable in the absence of syntax highlighting. But otherwise, it's annoying. Even reading it is annoying (but OK, that part alone is a matter of taste I guess.) As to typing, sure you can implement tricks in text editors to make up for it, but I frankly hate editors that would "auto-correct" things while I type. It's extremely annoying, and I know many people agree. I never enable anything like this in my text editors. I never enable auto-completion on the fly either. I hate things popping up when I'm typing. I set up a key shortcut for auto-completion when I need it. All this is absolutely not major of course. Just a little gripe. But the way a particular language appears on screen is important for readability IMO, and certainly we probably all have a different way of considering readability.
- Constants (CONST section) are typeless. They are essentially like macros. That bothers me. Not a huge dealbreaker, I admit, but I'd like typed constants. I know you can always declare variables, initialize them in the "body" of the module, and use them as constants, but they are not proper constants as they could be modified, at least within the module.
I'm not sure that I follow you here. Floating-point constants are REAL, string constants are character arrays, numeric constants are INTEGER. You can't assign a constant to a variable of a different type.
Maybe I didn't express it fully clearly. What you are talking about are *literals*. Every prog. language has a way of writing literals. But in CONST section, those are not linked to a type.
I guess the fact you don't see a difference is because of Oberon's simplicity which has only very few basic types (especially integers as I mentioned), no array literals, and so on, so that the type can always be unambiguously derived from the literal, but that's not always the case in languages for which there could be ambiguities.
- Related: you can declare variables and make them private to a module, but you can't make variables constant (AFAIR, please correct me if I'm wrong). So, I think that's a limitation.
Stand corrected Exported variables cannot be directly modified in a client module. There would need to be a 'setter' procedure also declared in the exporting module to enable modification. The setter procedure could then do any necessary validation if required.
Yes, but not within a module itself. I guess it all boils down to the point about CONST above. But I'll give you an example: since Oberon doesn't allow array or record literals, they can't be CONST. So you can't have a constant array or record within a module itself. It is a limitation IMO.
- Point I'm not 100% sure of: there are no array or record initializers. So initializing them is very clunky compared to other languages.
True. However, it is rarely a problem in practice for me as I rarely, if ever, use array or record initialisers even when using languages that allow them.
Many people do. It's much more compact that initializing members/items one by one with an assignment. C has solved the member "ambiguity" for structs since C99, you can pass the member identifier like: "{ .x = 1, .y = 2 }". It's compact and readable.
One somewhat related point is that to make up for it, developers in Oberon (and similar languages), following what Wirth was himself doing, tend to put several statements on the same line. So with the example above, they will usually just write: "S.x := 1; S.y := 2;" and call it day. I for one have a rule of never putting more than one statement on a single line. I think it hinders readability, and that's something that for me makes a lot of Oberon code hard to read. Statements all over the place. Of course you're not forced to doing this. But I just don't like this style, and having no initializers for arrays and records will kind of push this style.
One way having no initiliazers ("literals") for arrays and records is a real issue regarding the point I made above with constants. You can't declare a constant array or record. Yes you pointed out that outside of a module, exported arrays or records will essentially act as constants, but not within the module itself. This can be problematic. You can argue that you may put all your "constants" in a separate module, and that would solve the issue. Which woud be fair enough, if making things a bit harder than needed.
I won't get into more details for dynamic allocation, but just saying the model is still limited for general-purpose use, and as we're talking about a replacement for C, there's not reason not to consider dynamic allocation. And, it seems that the ability to use a non-GC allocator in your implementation is an extension of Oberon. The report doesn't mention anything like this AFAIR.
- Something C was long plagued with as well: there are no fixed (and standard)-width integers. No unsigned integers in general either, except for the BYTE. So IIRC, you have BYTE (which should be an 8-bit unsigned integer on most platforms), and INTEGER, which is a signed integer. The width depends on the platform. If you need to define and/or access integers with a specific width, look elsewhere... you may have to resort to the SYSTEM module. Now see below as well.
An actual parameter declared as ARRAY OF BYTE can have ANY data type passed to it as long as it has the same size.
This is interesting, but not part of the original language report. You have acknolwedged it was lacking, and added this as an extension. Like your non-GC allocator. I'm sure you have added a few other extensions as well, for instance for dealing with interrupts. So, see, you were forced acknowledging some things were lacking in the language. Now all things I've mentioned here would likely be pretty simple to add/modify in the language as well. It would just not be the exact language defined in the report...
As to integers, I still think there are things missing. Not having integers of various widths makes certain kinds of arithmetics difficult or clunky. Having only BYTE and INTEGER doesn't quite cut it IMO. Not that you can't circumvent this, but it's a bit limiting.
Not at all. Thank you for your feedback. I very much appreciate the time and thought you have put into it.
Well, this is a thread about thinking of a replacement for C, and I mentioned Oberon while saying it wasn't quite there, so obviously that meant I thought there were things missing. Still, I suggest anyone at least curious to have a look at Oberon.
Oh, and as said here, you have already implemented a number of extensions. Possibly adding a couple others would make it even better. That was my point.
Now apart from the few things I talked about, and that could be seen as "details", there's something more drastic.
Some people (many these days actually) do think modern programming languages should include built-in constructs for dealing with "parallel multitasking" (multi-threading if you will), some of those people are in this thread. But Wirth was convinced of the opposite. C is obviously lacking anything regarding this, but that's part of what many people think it's seriously limited. So if you're one of those people, you would have to consider this for any potential language replacement.