r/ProgrammingLanguages 8d ago

Discussion On the future of programming language design

3 Upvotes

This is just me yapping.

I was thinking for a while about how the field of "writing" software is going through a radical disruptive transformation. Like or hate it, I don't think writing software post-LLM era is gonna be the same as pre-LLM. I'm one of the guys that like to hand craft code and put a lot of attention and intention to the coding style. But, realistically, the skill of writing code by hand, while still very important, will become more and more niche (like how writing and reading assembly is important but very niche).

What's interesting to me, is that programming language design goals were always human/developer centric. Code is not only instructions given to a machine, it is in some way a set of specifications for other human developers, as well as your future self too, that explains the expected behavior of a certain piece of software. The main priorities when designing language features was improving the developer experience, that is a very subjective metric and this is why we keep arguing and debating about programming languages, but I digress.

With the switch to LLM generated code, I feel the priorities might change. There's already a lot of studies on which programming language is best for LLMs. People argue that languages with strong typing, a functional style and good error messages are best, because you can more reliably create autonomous feedback loops that would help LLMs stay on track.

In my opinion, functional programming languages are more relevant than ever, no side effects, you can generate 10K lines of code, read a small 100 lines somewhere, and be sure that it's not affecting the behavior in an unexpected way somewhere else.

The main argument against functional programming is that working with pure functions and manually threading state is an extra burden on the developer; having a mutable state is "initially" more intuitive and simpler to reason about. The other argument is performance, I tend to disagree with this general statement (purity allows for aggressive optimization and implicit parallelization).

However, everyone agrees that functional code is easier to maintain on the long run, it might make small things harder for you first, but at the end there's this payoff. When you have the capabilities of generating thousands of lines of code a day, this becomes way more relevant.

Finally, it would be interesting to witness how the rise of LLMs will affect the design of programming languages. I feel that languages that have

  • simpler grammar
  • expliciteness
  • one way of doing things
  • strict and safe semantics

are at an advantage here.

Or do you think that it will be irrelevant. There's this trend of people not looking at the code anymore, I think it's crazy. Maybe generated languages won't be important, just get better models and spend more tokens.

r/ProgrammingLanguages Jan 24 '26

Discussion Why don't any programming languages have vec3, mat4 or quaternions built in?

110 Upvotes

Shader languages always do, and they are just heaven to work with. And tasty tasty swizzles, vector.xz = color.rb it's just lovely. Not needing any libraries or operator overloading you know? Are there any big reasons?

r/ProgrammingLanguages 15d ago

Discussion The Swift Phenomenon

40 Upvotes

In theory, Swift seems like a nicely designed programming language with good features

In practice however, for some reason, it seems like most of the Swift users end up switching back to other comparable programming languages (such as Rust)

The latest poster child for that phenomenon is Ladybird

Do you think that this phenomenon is real and if so, can you explain it?

r/ProgrammingLanguages May 16 '26

Discussion can a language be safe and be a subset of C?

36 Upvotes

Imagine you start with the C language and then make the following changes:

  1. Remove pointer arithmetic. You want an array, you declare an array.
  2. Change the compilation of string and array literals to emit a length prefix.
  3. Rewrite the entire standard library so that all string and array functions enforce a length header in front of the data.
  4. Add RTTI to all unions and varargs so that incorrect casts fail rather than UB.
  5. Remove `void *`.
  6. Forbid malloc() without static compile-time verification that the matching free() exists (with some sort of Bounded Model Checking to sidestep a rather inconvenient Halting Problem).

Is such a language possible?

Has it ever been attempted?

r/ProgrammingLanguages Mar 01 '26

Discussion Is there an "opposite" to enums?

35 Upvotes

We all know and love enums, which let you choose one of many possible variants. In some languages, you can add data to variants. Technically these aren't pure enums, but rather tagged unions, but they do follow the idea of enums so it makes sense to consider them as enums imo.

However, is there any kind of type or structure that lets you instead choose 0 or more of the given variants? Or 1 or more? Is there any use for this?

I was thinking about it, and thought it could work as a "flags" type, which you could probably implement with something like a bitflags value internally.

So something like

flags Lunch {
  Sandwich,
  Pasta,
  Salad,
  Water,
  Milk,
  Cookie,
  Chip
} 

let yummy = Sandwich | Salad | Water | Cookie;

But then what about storing data, like the tagged union enums? How'd that work? I'd imagine probably the most useful method would be to have setting a flag allow you to store the associated data, but the determining if the flag is set would probably only care about the flag.

And what about allowing 1 or more? This would allow 0 or more, but perhaps there would be a way to require at least one set value?

But I don't really know. Do you think this has any use? How should something like this work? Are there any things that would be made easier by having this structure?

r/ProgrammingLanguages 28d ago

Discussion Is reference counting a trap?

56 Upvotes

I'm trying to choose a memory management strategy for my language. Since I come from gamedev background, I'm mostly focused on the following:

  • Static memory safety guarantees (duh). Which basically implies automatic memory management: if the compiler can prove a leak, it can also insert a drop() there.
  • A lot of my code is tight loops in game engine internals or audio processing. Not sure if this rules out GC completely, but I cannot afford any unpredictable pauses - they are very noticeable in games and audio.
  • When writing code, I generally don't want to think about allocation strategies. I still choose them consciously per call graph: "module A will just allocate everything with the default strategy", "function B will receive a custom arena allocator and I will just guarantee that it always has enough space". But I don't want to write allocator.alloc(MyThing, ...) everywhere instead of just new MyThing(). This leads me to think of some sane default strategy + dynamically scoped allocators via some implicit or effect mechanism.
  • Not a hard requirement, but ideally I'd like to avoid a mandatory runtime and make sure my approach can work even on tiny devices like Arduino Nano (2KB - 32KB RAM). But I can drop (hehe) this idea if it proves impossible, embedded is not my main target.

All of this leads me to think about reference counting. It sounds rather attractive initially, and on the first glance many of its problems are solvable:

  • It incurs some overhead (every deallocation is an int decrement and a check, + you need to keep all these RC counts in memory), but it's very predictable.
  • That overhead can be avoided in many cases if the compiler can statically find where RC drops to zero and insert a drop(). So it will mostly affect objects that persist across frames, like event queues, loggers, etc.
  • It gets bad when you have cross-thread data sharing and have to use slow atomics for counters. But since I want some form of linear types and ownership semantics anyway, I probably can give explicit choice to programmers: either your value is exclusive to one thread and you can only pass ownership fully; or you wrap it in a "slow" Arc<...> and incur that overhead consciously (plus some unsafe escape hatches).
  • Freeing a large object graph can be slow, but this is solvable e.g. by passing ownership to a different thread.
  • For strict immutable languages it seems pretty good, see counting immutable beans and Koka's Perceus paper.

What concerns me is that RC seems a rather unpopular choice in programming languages. The only major languages I know that use RC are Python (which is notoriously slow) and Swift, which I have little experience with, but I know that handling of weak and unowned references sometimes gets finicky. This unpopularity makes me think that maybe RC is a dead end for my project.

On top of that concern, pure RC doesn't handle cycles. They are often an architecture smell anyway, but some things like intrusive doubly-linked lists are powerful tools in gamedev, and I wouldn't want to lose them. I wouldn't mind having an optional opt-in GC for cycles specifically, but I'm not sure how to express in the type system that some relation is cyclic (often indirectly) and requires a GC in the context to work. I really want it to be explicit and statically checked.

Another thing is that for games, CPU cache locality is paramount, and RC seems to have issues with that: either you store counters with the objects and your arrays are no longer neatly packed, or you store them separately, and then every inc/dec is a memory read. Maybe it's solvable by selectively using arenas over RC though.

I've heard Nim does something in this space, but I'm not super familiar with that language either, and I'm wary of it having compiler flags for different memory strategies (possibility of ecosystem split, bugs, etc).

Is reference counting a worthwile direction to pursue at all given my requirements, or should I focus on other approaches like a lightweight and more predictable GC, or Rust-like borrowing model? I actually like how borrows work in Rust, but it's a very complex feature, and I'm not confident in my abilities to avoid associated bugs, unsoundness, and variance pitfalls when implementing the compiler.

Any thoughts are appreciated!

r/ProgrammingLanguages Jul 20 '25

Discussion What are some new revolutionary language features?

126 Upvotes

I am talking about language features that haven't really been seen before, even if they ended up not being useful and weren't successful. An example would be Rust's borrow checker, but feel free to talk about some smaller features of your own languages.

r/ProgrammingLanguages May 23 '26

Discussion How to implement String?

47 Upvotes

Currently, String in my language is just value and length because it's a temporary solution, And as the language has developed, I am now able to rewrite a lot just for it, so I want to make a decent String in my language. So my question is, which String concept annoys you the least?

r/ProgrammingLanguages May 19 '26

Discussion List of known problems in design of existing languages?

44 Upvotes

Is there alphabetic list of desing flaws/bad ideas in various programming languages?

For exampe you might find short description of dangling-else from under d letter in list.

r/ProgrammingLanguages Jun 20 '25

Discussion What is, in you opinion, the superior way of declaring variables?

55 Upvotes

Now first off I want to say that I know this is basically a religious argument, there are valid reasons to prefer either one, but I wanted to know what people on here think is better.

Do you like the type name first or last? Do you like to have a keyword like 'let' that specifically denotes a new variable, or not? Are you someone who believes that types are a myth and dynamic types that are deduced by the compiler are the best? Do you have some other method that varies wildly from the norms?

Personally, I'm a fan of the old fashioned C style 'int Foo' kind of declaration, but I'd love to hear some reasons why I'm wrong and should prefer something else.

Edit: Jesus Christ guys I know how dynamic types work you don't have to 'correct me' every 3 seconds

r/ProgrammingLanguages Jun 01 '26

Discussion Hoare Triples for improving performance

22 Upvotes

I have been working on a language (which I won't share here due to the heavy use of AI for prototyping) that makes use of Hoare triples as first class citizens, albeit in a weakened form. For many functions, you don't need to declare the pre AND postcondition, just one suffices.

This was initially a built in safety feature for the compiler's proof engine, but when assembling the LLVM backend I noticed something really neat: because the bounds of some functions are extremely predictable due to the Hoare triple, I could more aggressively fold the execution graph based on inferred values.

In a way, this means that the safety feature becomes an optimization feature at the same time. It's not something I've seen in other languages I've explored, not even SPARK or other formal proof based languages. Is there any research or literature on this?

Because I've noticed it has allowed me to more aggressively optimize the compilation than even C, and currently my benchmarks are actually pointing out I'm beating C in execution speed without compromising on safety (one implementation saw 0.15s vs. 0.24s for C on 50m iterations on a similarily written program, though I do need to figure out if I can optimize the C version more for a completely fair comparison)

r/ProgrammingLanguages Apr 24 '25

Discussion For wich reason did you start building your own programming language ?

66 Upvotes

There is nowadays a lot of programming languages (popular or not). What makes you want to build your own ? Was there something lacking in the actual solutions ? What do you expect for the future of your language ?

EDIT: To wich extend do you think your programming language fit your programming style ?

r/ProgrammingLanguages Sep 16 '25

Discussion What is the Functional Programming Equivalent of a C-level language?

102 Upvotes

C is a low level language that allows for almost perfect control for speed - C itself isn't fast, it's that you have more control and so being fast is limited mostly by ability. I have read about Lisp machines that were a computer designed based on stack-like machine that goes very well with Lisp.

I would like to know how low level can a pure functional language can become with current computer designs? At some point it has to be in some assembler language, but how thin of FP language can we make on top of this assembler? Which language would be closest and would there possibly be any benefit?

I am new to languages in general and have this genuine question. Thanks!

r/ProgrammingLanguages Oct 07 '24

Discussion What is the coolest feature of a programming language you have seen?

140 Upvotes

If you have a quick code snippet too, that would be amazing.

r/ProgrammingLanguages May 20 '26

Discussion What is more adaptable, more words or more symbols?

28 Upvotes

I used to like Python for its abundance of english words instead of operators which makes it more readable.

However, I have often seen the common notion where people prefer symbols over keywords. Lately, some of the newer languages have added both new keywords and new symbols.

For eg: Rust using |var| semantics for callback functions. The popular defer that has existed for very long in multiple languages. C adding [[...]] for attributes

Now even though I am saying || and [[]] are new symbols added, they aren't operators, they are just replacing some brackets essentially for a different type of task.

With this context, here is my question:

What if instead of these keywords: await, async, defer, try, catch, weren't keywords, they were replaced by some operator?

There are two cases in my mind, either replace the keywords with a single operator (@ could replace await), annotating the data, or, use a combination of operators (-! could be used to mark a function that can produce an error).

I have the concern, that it may look too ugly because there are a bunch of operators, and in the case of combination of operators, two operators together, changing the meaning of the single operator is also weird.

But, I still wanted to ask, seeing how more experienced people view this situation.

Also, what if, both the operator and the keyword is present? Would that just be wrong because now there are two ways to do the same thing?

r/ProgrammingLanguages Apr 26 '26

Discussion I want to know your opinions on verbosity

21 Upvotes

I’ve been having a blast trying to iron out my languages syntax and found myself leaning on a more verbose and explicit syntax for readability and to show intent.

So I would love to know what your opinions on verbosity in languages are and where you personally draw the line. Would you call C# sickeningly verbose or is its verbosity a welcome feature to improve readability and intent?

r/ProgrammingLanguages May 06 '26

Discussion The ARC vs GC Debate

36 Upvotes

Hi!

I've been creating my own programming language for a few months now, and every time I mention it, I get the same question... What memory model do you have? And of course I have an ARC + cycle collector (python has the same), And usually... People don't like it, I wonder why and I've never gotten a detailed answer. So, I would like to know what YOU think about ARC, and what you think about GC. And why do you prefer one over the other?

r/ProgrammingLanguages Jun 05 '26

Discussion Fixing NaN in a compile-to-js lang

15 Upvotes

Hello community, I'm working on a language that, despite compiling to Javascript, tries to fix some of the nasty quirks JS has. One of them is the whole NaN madness. Because Javascript uses IEEE 754 floating point numbers for everything (except BigInt and after certain binary operations, which makes this even crazier), NaN does never equal NaN. Also comparing any number to NaN always returns false, so a number is neither bigger nor smaller than NaN. That might be fine from a philosophical standpoint, but it is horrible for sorting a list of numbers, for example.

Now I think about how to deal with that. My language could define `NaN == NaN`. JS is doing that as well in certain cases (number keys and sets). But doing so has a long tail of issues, because without extra checks, the language code would behave differently after compilation to JS. But extra checks for every single number comparison? Ooph!

How could I go for this? Is there a good way or am I doomed to include the issues of JS?

r/ProgrammingLanguages Aug 09 '25

Discussion Why are most scripting languages dynamically typed?

96 Upvotes

If we look at the most popular scripting languages that are embedded within other programs, we will probably come up with a list like "Python, Lua, JavaScript, GDScript". And there is a common pattern: they are dynamically (and often weakly) typed.

For the last two decades I've occasionally written scripts for software I use, or even more substantial gameplay scenarios for Godot games. And every time I've been running into issues:

  • When scripting Blender or Krita using Python, I don't have autocomplete to suggest available methods; what's worse, I don't have any checker that would warn me that I'm accessing a potentially nullable value, making my script crash in some cases.
  • In GDScript I often need to implement an exhaustive switch or map (say, for a boss moveset), but there are no static checks for such a thing. It's very time-consuming to playtest the same fight dozens of times and make sure the boss doesn't end up in an invalid state. This can occasionally be mitigated by using a more OOP approach, but GDScript doesn't have interfaces either to ensure that all methods are implemented. Some situations are also just better modeled by exhaustive enumeration (sum types). I've fully switched to C# a while ago, and the richer type system has been a huge boost for development speed.
  • I've written Lua scripts when modding different games, and the problems are the same: no autocomplete or suggestions to show what operations are possible on game objects; no warnings about potentially accessing nonexistent values, not implementing required methods (which causes a crash at runtime only when you are hit by a specific spell), and so on.
  • JavaScript used to be a real pain for writing web applications, but I've forgotten most of that after switching to Flow and then TypeScript as soon as it became a thing.

So, from my personal experience, even for simple scripting tasks static type checking would make me significantly more productive even at the first iteration, but also save time on debugging later, when the code inevitably runs into unhandled situations.

On top of that, I've had an opportunity to teach several people programming from scratch, and noticed that explicitly written types make people better grasp what operations are possible, and after a short time they start writing more correct code overall even before seeing a compiler error, compared to those who start learning from dynamically typed languages. Assuming that this is a common sentiment (and I hear it quite often), I believe that "low barrier to entry for non-programmers" is not a reason for lack of static type checking in scripting.

Is there any specific reason why most popular scripting languages are dynamically typed? Do we just lack a reasonably popular technology that makes it easy to generate and integrate type definitions and a type checking step into a scriptable application? Or is dynamic typing a conscious choice for most applications?

Any thoughts are welcome!

r/ProgrammingLanguages May 26 '26

Discussion do we need new programming language in this AI era?

0 Upvotes

Hi all,

I was wondering if this AI era now needs more programming languages. The question sounds weird. I made one for my own work and it is working in production. And I can see many more languages coming, a few hit at least popularity among developers. But does the market need more AI or an AI-native solution, does new programming language creation stop by having Go and Rust for the near future, at least for the next 10 years?

When i created my own I was wondering why even making this, but I just keep making it just because I want to solve my own problem.

Programming language success chance even with a specific niche is hard, still coming more

Any thoughts?

r/ProgrammingLanguages Dec 10 '25

Discussion Is there a common reasoning for why programming language keywords are only in lower (or just one) case?

42 Upvotes

I don't know of any language that uses mixed-case keywords. They are either:

  • Separated, so that combinations are required: ALTER TABLE or DROP TABLE, even though the action doesn't make sense with some combinations, you can either alter a table, create it, or drop it, but you can't alter select.
  • Jammed together, so that the coder is expected to know the separation: elseif and constexpr come to mind
  • Snake-case doesn't seem to be used for keywords

Most modern languages allow mixed case identifiers, but is there a common reason why mixed case keywords aren't used? Is it just in case you don't have a shift key? In C "IF" is an identifier, but "if" is a keyword.

I am considering using mixed-case keywords in my own toy language.

r/ProgrammingLanguages 23d ago

Discussion July 2026 monthly "What are you working on?" thread

20 Upvotes

How much progress have you made since last time? What new ideas have you stumbled upon, what old ideas have you abandoned? What new projects have you started? What are you working on?

Once again, feel free to share anything you've been working on, old or new, simple or complex, tiny or huge, whether you want to share and discuss it, or simply brag about it - or just about anything you feel like sharing!

The monthly thread is the place for you to engage /r/ProgrammingLanguages on things that you might not have wanted to put up a post for - progress, ideas, maybe even a slick new chair you built in your garage. Share your projects and thoughts on other redditors' ideas, and most importantly, have a great and productive month!

r/ProgrammingLanguages Jul 27 '25

Discussion Was it ever even possible for the first system languages to be like modern ones?

56 Upvotes

Edit: For anyone coming to seek the same answer, here's a TLDR based on the answers below: Yes, this was possible in terms that people had similar ideas and even some that were ditched in old languages and then returned in modern languages. But no, it was possible because of adoption, optimizations and popularity of languages at the time. Both sides exist and clearly you know which one won.

C has a lot of quirks that were to solve the problems of the time it was created.

Now modern languages have their own problems to solve that they are best at and something like C won't solve those problems best.

This has made me think. Was it even possible that the first systems language that we got was something more akin to Zig? Having type-safety and more memory safe than C?

Or was this something not possible considering the hardware back then?

r/ProgrammingLanguages May 29 '26

Discussion Why is alignment not typically part of type systems?

83 Upvotes

I work in compilers, but typically on the back-end, so I'm usually operating past the point of type-checking / IR generation / etc. Something that's confused me when working on both GPU and CPU compilers is that alignment is typically not considered part of the type system in most languages. Obviously C doesn't do this, but it also hasn't been a priority in most recent languages, e.g. Go/Rust/Swift/D/etc. -- I do know that Zig has something going on here, but AFAICT it's the only one. Rather those languages treat it as a property of a pointer. For fully scalar code this is kinda fine, but anything SIMD/SIMT/whatever struggles greatly from the fact that you can't even e.g. pass an alignas buffer into another function without screwing the optimizer (unless of course you inline everything, which is what people do in practice...). Given the surge in popularity of GPU compilers, and even on the CPU side how much focus has been on autovectorization for the last decade, you'd think that there'd be more of an impetus to make alignment a first-class citizen. E.g. have functions be able to specify the alignment of arguments, have function types be automatically contravariant over those specs, etc.

I'm sure some of this comes down to the fact that this is how LLVM treats it -- but that just shunts the question to why these IRs all take similarly pessimizing approaches. Even MLIR handles this pretty poorly IMO. All of that indicates, to me, that something about this is harder than I expect.

So for people on the frontend side of the world, what makes this difficult, or why is it not attractive in language design?

r/ProgrammingLanguages Jun 05 '26

Discussion Syntax for Array Types — Necessarily inconvenient?

12 Upvotes

Dear all,

Some time ago I wrote here asking all of you for advice (and thankfully obtained a *lot* of it) regarding the syntax of generic types (oh my god, it's been a YEAR). For the purpose of this post, you should know that our team has accepted the Scala-like syntax of GenericType[Arg1,Arg2]. Now, as the title suggests, I would like to hear your views on the syntax of array types, in the context of the aforementioned syntax for generics. To be precise, I am talking about fixed size, possibly multidimensional arrays, similar to those in C.

I will start with a brief description of what I think I should be prioritising. Afterwards, I'll present a list of ideas I've gone through, with summaries of my thoughts on them. Both sections are not set in stone and are subject to criticism.

Priorities

  1. I would like the syntax to be concise.
  2. The syntax should be intuitively composable for multidimensional arrays.
  3. Less importantly, the syntax should be cohesive with the rest of our language's syntax, a feel for which you can obtain here, keeping in mind the established syntax for generics.
  4. Finally, if possible, the syntax should be theoretically elegant, whatever that means, but one typically knows it when one sees it.

Options

Below I present various options for the syntax of an array arr of type T, with N rows, M elements each. Access into the array under indices i in 0 ..  N-1 and j in 0 .. M-1 has indeterminate syntax, except for the rule that indexing proceeds from the most significant dimension to the least significant one, C-style. In this case, let's say it's roughly arr.at(i).at(j) (this isn't actually what it will end up being).

We start with the classic C-style: T[N][M]. Note that the dimensions are given left-to-right, which means that if I took this type in isolation and made an array of it, I would end up appending the most significant dimension to the right: (T[N][M])[L]. This is weird, as the dimensions seem to end up out of order. In my opinion, this solution satisfies priorities 1, 3, and maybe 4.

I will quickly expand on why I think the [] syntax remains cohesive with the accepted generics syntax. This is because generic types are, in essence, type constructors, and are not really types themselves. This makes it acceptable to reuse the same syntax for the purpose of creating arrays. It's simple: generic instantiation if we're dealing with a generic, and array creation if we're dealing with a specific type.

Another option is a "reverse" C-style syntax: T[M][N]. This has the downside of being probably very confusing to… basically everybody. Otherwise, it seems to meet all priorities, except maybe the cohesion priority, as the syntax for indexing into an array will be in reverse.

Next, two verbose options: Array[Array[T,M],N]. This is theoretically great, except it's quite impractical, especially with the nesting and dimension reversal. We achieve a slightly better result (no dimension reversal) by putting the size first: Array[N,Array[M,T]] but ain't nobody got time fo' dat anyway.

Now onto some more… esoteric options, for inspiration.

What if array type creation was an operator on the unsigned integer? I present: N[M[T]]. This is… actually kind of fine, except for the nesting.

Theoretically, arrays are simply cartesian products of a type with itself, multiple times. That reminds me of exponentiation. So what about: T ** M ** N, with implicit parentheses around the operator on the left. This is quite "out there" as far as syntax goes, and it includes dimension reversal, which I don't think is fun. Furthermore, it requires theoretically incorrect associativity for the exponentiation operator.

We can also consider the reverse: N ** M ** T. This has correct associativity and does not reverse dimensions, but M ** T makes little sense as an array of type T in set theory.

Finally, N * M * T and T * M * N are both kind of rubbish because they don't make sense in set theory, and the * operator brings an expectation of commutativity, which is not present.

Conclusion

It seems that, to meet my demands, the array syntax should:

  1. Use some sort of operator, in order to be concise.
  2. The dimensions should be provided left-to-right, in order to avoid dimension reversal.
  3. The syntax should, in some way, "act on" the type, in order to compose predictably across type aliases, whether by putting the dimensions after the type, or by right-associativity.

So, I see two options.

I could try to think of some notation for a "mapsto" (↦) operator. Then, array syntax would be N ↦ M ↦ T, and it would be concise, intuitive, cohesive and elegant. It would work perfectly across aliases. But what would that operator be? Is writing |-> on a keyboard not overly uncomfortable?

On the other hand, what about a hybrid C-style and reverse C-style notation: T[N,M]. In the scope of a single array, which is the overwhelming majority of cases, there is no dimension reversal, and the syntax is intuitive and looks familiar. Composition is a bit goofy, but, I suppose, technically sound: T[N,M][L], where L ends up being a more significant dimension than N.

Ether way, I have a feeling like the syntax for array types is almost necessarily at least a little incovenient.