HN user

thefaux

1,015 karma
Posts2
Comments364
View on HN

Syntax and semantics are never orthogonal and you always need syntax so it must be considered from the start. Any reasonable syntax will quickly become much more pleasant to generate an ast or ir than, say, manually building these objects in the host language of the compiler which is what the semantics first crowd seem to propose.

It also is only the case that most of the work is the backend for some compilers, though of course all of this depends on how backend is defined. Is backend just codegen or is it all of the analysis between parsing and codegen? If you target a high level language, which is very appropriate for one's first few compilers, the backend can be quite simple. At the simplest, no ast is even necessary and the compiler can just mechanically translate one syntax into another in a single pass.

Cold-blooded cost/benefit analysis is an abdication of moral reasoning and responsibility. There is no such thing as an abstract life, only concrete realizations. What if the victim of an avoidable fatality is the one person who had they survived had the skills/insight/vision to literally save humanity from extinction?

I can accept an argument that there are societal tradeoffs that we must make that involve the sacrifice of human lives (obviously we should not try to remove risk to the extent that we live in sterile protective bubbles), but we should be honest about what we are doing and not hide behind some phony numbers that mask the fact that money, and hence numerical value, isn't an imaginary construct and that lives are fungible under this value system.

I further think that if we have an honest conversation instead of hiding behind quantitative analysis, we may actually have a productive dialogue about risk tradeoff and accountability. Perhaps if there is a wide gap between the bean counters and the bleeding hearts, there is a third possibility that needs to be explored.

I have written a compiler for a language at more or less this abstraction level. It provides access to 16 general purpose registers and a set of virtual instructions that operate on these registers. I program on an intel mac so the virtual instructions all map directly to x86_64 instructions, but it would be very straightforward to write an arm backend that may compose multiple arm instructions for the equivalent x86_64 behavior. I also could support virtual registers for platforms with fewer than 16 registers.

Having this compiler, which is extremely fast (it is self hosted and self compiles its own 9750K line source file in 15ms on my 2019 macbook pro and I've seen throughout ranging from 500K to 10M lines per second for other programs), I have little interest in ever using LLVM again. I would rather just write optimal code than pray that LLVM does a good job for me. For equivalent programs, I find LLVM can be anywhere from 50-10000x slower than my compiler and doesn't necessarily produce better code. I can produce examples of LLVM code becoming significantly worse at -O2 than at -O0.

The only real utility LLVM offers me at this point is that I could use it to figure out what an optimal solution to a small subprogram might be by compiling a small c program and inspecting the output. Then I can just directly write the optimal solution instead of being perpetually bogged down by llvm's bloat as well as also being exposed to unexpected regressions in the optimizer and/or having to learn its strange incantations to get desired performance.

Java 26 is here 4 months ago

Why would anyone create a new language now? The existing ones are "good enough", and without a body of examples for LLMs to train on, a new language has little chance getting traction.

Compiler writing can be an art form and not all art is for mass consumption.

Java has won (alongside many other winners of course), now the AI drawbridge is being raised to stop new entrants and my pick is that Java will still be here in 50 years time, it's just no humans will be creating it.

This makes no sense to me. If AI possesses intelligence then it should have no problem learning how to use a new language. If it doesn't possess intelligence, we shouldn't be outsourcing all of our programming to it.

It is interesting though that he evidently didn't notice this 2.5X productivity increase until you pointed it out to him.

The examples that you and others provide are always fundamentally uninteresting to me. Many, if not most, are some variant of a CRUD application. I have yet seen a single ai generated thing that I personally wanted to use and/or spend time with. I also can't help but wonder what we might have accomplished if we devoted the same amount of resources to developing better tools, languages and frameworks to developers instead of automating the generation of boiler plate and selling developer's own skills back to them. Imagine if open source maintainers instead had been flooded with billions of dollars in capital. What might be possible?

And also, the capacities of llms are almost besides the point. I don't use llms but I have no doubt that for any arbitrary problem that can be expressed textually and is computable in finite time, in the limit as time goes to infinity, an llm will be able to solve it. The more important and interesting questions are what _should_ we build with llms and what should we _not_ build with them. These arguments about capacity are distracting from these more important questions.

I do see this as a bad thing and an abdication of taking responsibility for one's own life. As was recently put to me after the sudden death of a friend's father (who lived an unusually rich life): everyone dies, but not everyone truly lives.

At the end of life, Maslow became convinced that self-transcendence was the pinnacle of the hierarchy. Strong identification with work will not get one to that final step. I am not sure if ai is a path to self transcendence or self annihilation, but it's interesting to ponder in the case of some like Brin.

C Is Best (2025) 7 months ago

I truly believe that the cult of c performance optimization has done more harm than good. It is truly evil to try and infer, or even worse, silently override programmer intent. Many if not most of the optimizations done by llvm and gcc should be warnings, not optimizations (dead code elimination outside of LTO being a perfect example).

How much wasted work has been created by compiler authors deciding that they know better than the original software authors and silently break working code, but only in release mode? Even worse, -O0 performance is so bad that developers feel obligated to compile with -O2 or more. I will bet dollars to donuts that the vast majority of the material wins of -O2 in most real world use cases is primarily due to better register allocation and good selective inlining, not all the crazy transformations and eliminations that subtly break your code and rely on UB. Yeah, I'm sure they have some microbenchmarks that justify those code breaking "optimizations" but in practice I'll bet those optimizations rarely account for more than 5% of the total runtime of the code. But everyone pays the cost of horrifically slow build times as well as nearly unbounded developer time loss debugging the code the compiler broke.

Of course, part of the problem is developers hating being told they're wrong and complaining about nanny compilers. In this sense, compiler authors have historically been somewhat similar to sycophantic llms. Rather than tell the programmer that their code is wrong, they will do everything they can to coddle the programmer while behind the scenes executing their own agenda and likely getting things wrong all because they were afraid to honestly tell the programmer there was a problem with their instructions.

Honestly, I found this piece depressing. Life is too short and precious to waste on crappy software.

So often the question ai related pieces ask is "can ai do X?" when by far the more important question is "should ai do X?" As written, the piece reads as though the author has learned helplessness around c++ and their answer is to adopt a technology that leaves them even more helpless, which they indeed lament. I'd challenge the author to actually reflect on why the are so attached to this legacy software and why they cannot abandon it if it is causing this level of angst.

Sure, but I prefer to work on projects that are fundamentally sound and high impact. Indeed, I have certainly noticed a pattern that very often ai enthusiasts exalt its capabilities to automate work that appears to be of questionable value in the first place, apart from the important second order property of keeping the developer sheltered and fed.

This logic is both too broad and rigid to be of much practical use[1]. It needs to be tightened to compare languages that are identical except for static type checks, otherwise the statically typed language could admit other kinds of errors (memory errors immediately come to mind) that many dynamic languages do not have and you would need some way of weighing the relative cost to reliability of the different categories of errors.

Even if the two languages are identical except for the static types, then it is clearly possible to write programs that do not have any runtime type errors in the dynamic language (I'll leave it as an exercise to the reader to prove this but it is very clearly true) so there exist programs in any dynamic language that are equally reliable to their static counterpart.

[1] I also disagree with your definition of reliability but I'm granting it for the sake of discussion.

Sometimes someone genuinely has a clear vision that is superior to the status quo and is capable of executing it, improving quality, performance and maintainability. The challenge is distinguishing these cases from the muddled abstractions that make everything worse. This argument feels a bit like "no one gets fired for buying IBM." Blanket advice like this is an invitation to shut down thinking and stymie innovation. At the same time, the author is not wrong that imposing a bad abstraction on an org is often disastrous. Use your powers of reason to distinguish the good and bad cases.

I had a roommate who failed out of college because he was addicted to Everquest (yes, Everquest, and yes I am middle-aged). Your last paragraph is barely even hyperbolic. Do you think unemployed young men who live at home with their parents, do little to no physical activity, spending most of their time playing videogaming and/or trolling on the internet are not stuck destroying their bodies (and minds) in a spiral of deadly addiction? Maybe you are a functional gamer, but there are many, many gamers who are not and this technology is maybe a quasi effective cope for our punishing society writ large, but from the outside, gaming addicts appear to be living a sad and limited life.

Or to put it more succinctly, would you want your obituary to lead with your call of duty prowess?

1 Judge not, that ye be not judged.

2 For with what judgment ye judge, ye shall be judged: and with what measure ye mete, it shall be measured to you again.

3 And why beholdest thou the mote that is in thy brother's eye, but considerest not the beam that is in thine own eye?

In the medium to long term, if LLMs are unable to easily learn new languages and remap the knowledge they gained from training on different languages, then they will have failed in their mission of becoming a general intelligence.

As impressive as this analysis is by the compiler, I shudder to think how much time the compiler spends doing these kinds of optimizations. In my opinion, a better architecture would be for the compiler to provide a separate analysis tool that suggests source level changes for these kinds of optimizations. It could alert you that the loop could be replaced with a popcount (and optionally make the textual replacement in the source code for you). Then you pay the cost of the optimization once and have the benefit of clarity about what your code _actually_ runs at runtime instead of the compiler transparently pulling the rug out from underneath you when run with optimizations.

Side note: many years ago I wrote the backend for a private global surveillance system that has almost surely tracked the physical location of anyone reading this. We could efficiently track how often a device had been seen at a location in the prior 64 (days|weeks|months) in just 192 bytes and use popcount to compute the value. I am not proud that I built this.

I liked the first few paragraphs, but the article took a wrong turn for me when it pivoted to ir. Compiler ir need not be fiendishly complex, though modern compilers, particularly clang and gcc can create this impression.

There are two nice benchmarks that I use to measure the complexity of a compiler: how long is the compiler and how long does it take to self compile. Clang and gcc are abysmal on these benchmarks. In fact, I would argue that they fail the second benchmark entirely because they are not capable of self compilation because their build systems rely on external tooling. In other words, there is no implementation of gcc or clang that does not rely on an additional tool that is external to the compiler itself.

The main pedagogical value of these compilers is not as an exemplar, but rather an antithesis.

If the boosters are correct about the trajectory of llm performance, these objections do not hold.

Debugging machine code is only bad because of poor tooling. Surely if vibe coding to machine code works we should be able to vibe code better debuggers. Portability is a non issue because the llm would have full semantic knowledge of the problem and would generate optimal, or at least nearly optimal, machine code for any known machine. This would be better, faster and cheaper than having the llm target an intermediate language, like c or rust. Moreover, they would have the ability to self-debug and fix their own bugs with minimal to no human intervention.

I don't think there is widespread understanding of how bloated and inefficient most real world compilers (and build systems) are, burning huge amounts of unnecessary energy to translate high level code, written by humans who have their own energy requirements, to machine code. It seems highly plausible to me that better llms could generate better machine code for less total energy expenditure (and in theory cost) than the human + compiler pair.

Of course I do not believe that any of the existing models are capable of doing this today, but I do not have enough expertise to make any claims for or against the possibility that the models can reach this level.

It's sad but I generally agree. Scala was in my view pretty well positioned for an up and coming language ~2010-15. Not only did the scala 3 rewrite fail to address many of the most common pain points -- compile times and tooling immediately come to mind -- the rewrite took many years and completely stalled the momentum of the project. I have to wonder at this point who is actually starting a new project in scala in 2025.

It's really a shame because in many ways I do think it is a better language than anything else that is widely used in industry but it seems the world has moved on.

This design seems very similar to async in scala except that in scala the execution context is an implicit parameter rather than an explicit parameter. I did not find this api to be significantly better for many use cases than writing threads and communicating over a concurrent queue. There were significant downsides as well because the program behavior was highly dependent on the execution context. It led to spooky action at a distance problems where unrelated tasks could interfere with each and management of the execution context was a pain. My sense though is that the zig team has little experience with scala and thus do not realize the extent to which this is not a novel approach, nor is it a panacea.

If the value of human labor is going to zero, which some say ai will induce, wouldn't the oxbridge model become the most cost effective option?