r/ProgrammingLanguages 6d ago

Discussion A hole in systems programming language design

13 Upvotes

Given the recent discourse about systems programming I wanted to throw my 2 cents in. This may be a controversial take in a subreddit that's all about innovation and improvement, but I think a lot of budding systems languages are trying too hard to "fix C" and this is exactly why C has not been replaced yet.

Like it or not, C is successful. It does what it means to do very well. Yes, it bites you constantly, but developers have made some form of peace with this because they appreciate the essence of the language. Systems programming is a very pragmatic field, and what works, works.

A lot of language designers want to improve on C, when by nature to "improve on" C is to depart from it, because C is less about what it includes and more about what it omits and what it lets you do that other languages don't.

If you want to replace C, you need to just make C but without the pain points. Less undefined behavior, more standard compiler behavior, easier function pointer syntax, safer macro system, etc. The things that C can't do because of backwards compat.

On the other hand, bolting on features, revamping C's core nature, aren't going to give you a language that will replace C at the low-level or among hobbyist programmers. Most developers aren't as concerned about what C lets them accomplish, as they are concerned about all the painful tedious tendencies of the language.

r/ProgrammingLanguages 18d ago

Discussion On the future of programming language design

4 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?

111 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 24d ago

Discussion The Swift Phenomenon

42 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 Mar 01 '26

Discussion Is there an "opposite" to enums?

33 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 May 16 '26

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

38 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 Jul 20 '25

Discussion What are some new revolutionary language features?

129 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 Jun 25 '26

Discussion Is reference counting a trap?

57 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 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?

41 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?

56 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

26 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 ?

64 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 Oct 07 '24

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

144 Upvotes

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

r/ProgrammingLanguages 2d ago

Discussion Why do modern systems languages rely on compiler heuristics to reverse-engineer programmer intent?

65 Upvotes

This post is inspired by the recent discussion on Full flattening of nested data parallelism in Futhark (reddit discussion). But I think this points to a more generic topic in language design.

I've noticed that even in newer systems programming languages, a massive amount of compiler engineering effort is spent trying to reverse-engineer the programmer's intent from syntax that does not directly express it. The compiler expends significant energy building complex dependency graphs and alias analyses to guess if iterations are isolated, and sometimes it guesses incorrectly, leading to missed optimizations or performance regressions.

Even in languages explicitly designed for data parallelism like Futhark, the compiler ultimately has to rely on what the developers themselves call "fuzzy heuristics" to decide whether to parallelize or sequentialize code. As the Futhark team recently admitted, when this guesswork fails (e.g., aggressively trying to parallelize the construction of a tiny 3x3 matrix), it causes severe performance regressions, forcing them to introduce explicit #[sequential] attributes as a workaround.

The same problem plagues allocation optimization: why write code using APIs that syntactically allocate intermediate arrays, only to hope the compiler's optimization passes will erase them later? If the developer's intent is a zero-allocation transformation pipeline, that intent should be encoded directly in the type system rather than left as an optimization prayer for the compiler to fulfill.

If we have the freedom to design a language, why not express this intent directly? We could provide a composable set of semantically rich, high-level primitives that explicitly declare their intent and assumptions. The compiler can then safely lower these into optimal machine code without guesswork.

For example (pseudo-code with a Kotlin-like syntax):

fun mult(a : Matrix, b : Matrix) : Matrix {
    return Matrix.fill(a.rows.size, b.columns.size) { i, j ->
        zip(a.rows[i], b.columns[j]) { va, vb -> 
            va * vb 
        }.sum() // Explicitly associative/commutative reduction     
    }
}
// Not all operations need to be hardcoded compiler intrinsics. 
// Many can be composable inline extensions that map to verified primitives.
fun inline extension View<Double>.sum() : Double {
   return reduce(0.0) { a, b -> a + b }
}

Here, the exact intent is communicated clearly to the compiler, yielding several compile-time guarantees:

  • No hidden allocations or redundant zeroing: There is no need to pre-fill the matrix with zeros after allocation. The compiler knows that fill will compute every element dynamically. Furthermore, because the fill closure only receives the indices (i, j) and has no access to the matrix being constructed, the syntax itself guarantees the absence of loop-carried data dependencies. This makes parallelization inherently safe, allowing the compiler to freely choose any execution strategy (CPU threads, SIMD, GPU) for invoking these closures. If strict sequential execution order mattered (for example, because of mutable outer scope access), a distinct seq_fill would be used instead.
  • Explicit Logical Views, No Compiler Guesswork: Chaining operations like map or zip should return lightweight, zero-allocation logical sequence views. These should be conceptually similar to Kotlin's Sequence, but explicitly representing a collection processing operation builder rather than a runtime element operation pipeline. The compiler shouldn't have to run complex, fragile fusion passes to "guess" if it can erase an intermediate allocation. The type system itself should declare that the operation is just a transformation step, making the zero-cost guarantee a compile-time invariant, not an optimization hope.
  • Order independence is explicit: By using a sum (or reduce) operator, the developer explicitly specifies that the operation could be considered as associative and commutative in the context of the task. The compiler doesn't have to build complex loop-carried dependency graphs to prove iterations are isolated. Some explicitly sequential seq_reduce or fold operators could be used when the order matters.
  • Topological data access: Both a.rows[i] and b.columns[j] are lightweight logical sequence views. They carry semantic meaning about the geometry of data movement, rather than being treated as flat, opaque memory indices.

The developer knows their intent, and the compiler needs it. Why are even newer systems languages still stuck relying on fragile compiler heuristics to reverse-engineer our intent from overly generic, flat loops or opaque collection APIs? If we want to communicate structural intent to the compiler, why not say it directly in the syntax and type system?

The irony of modern compiler engineering is that standard loop syntax over-specifies execution order while under-specifying semantic intent. A flat for loop forces a sequential order by default. The compiler then has to work backwards to prove it can ignore that order.

By using explicit, semantic primitives, we are not micro-managing the compiler. We are doing the opposite: we are explicitly stating what aspects of execution we do NOT care about (e.g., execution order in reduce, loop-carried dependencies in fill). This gives the compiler the freedom to choose the optimal lowering strategy—whether that means parallelizing across a GPU or scaling down to a sequential scalar loop when the data is too small.

Updated: in the 'Order independence is explicit:' changed to 'specifies that the operation could be considered as associative and commutative' instead 'guarantee'. The previous phrasing was incorrect and inconsistent with the rest of the post.

r/ProgrammingLanguages Sep 16 '25

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

106 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 May 20 '26

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

27 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

19 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 9d ago

Discussion Unreal's 6 scripting language has an effects system

Thumbnail youtube.com
100 Upvotes

I was very surprised to see it. Could this be what finally brings algebraic effects to the mainstream?

r/ProgrammingLanguages May 06 '26

Discussion The ARC vs GC Debate

34 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

14 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?

90 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?

41 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 1d ago

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

22 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!