15 ms·
I don't want to go to Chel-C
- rurban 4y agoReads like a typical mid-80ies manifesto for safer languages until we arrive at gcc-11. There was no gcc-11 then.
- Sphax 4y agoI don't use gcc, curious to know what gcc 11 adds.
- jcelerier 4y agoCool static analysis features: https://developers.redhat.com/blog/2021/01/28/static-analysis-updates-in-gcc-11 https://developers.redhat.com/blog/2021/01/28/static-analysi...
- mhh__ 4y agoUnless you build the program around the static analysis you're going to have a bad time. David Malcolm has done a really good job with the analyser but it can't catch everything by virtue of the C type system making it possible to write code that can't be guaranteed either by construction or by making opaque boundaries.
- rurban 4y agogcc-11 was released last year, not in those times, when we had gcc-2.95.
- gerikson 4y agoUpvote for Elvis Costello reference alone.
- filippp 4y agoThere's also a The Smiths reference right at the beginning.
- tomcam 4y agoDon’t worry, that’s still forgivable
- BurningFrog 4y agoInstantly knew the age of the author :)
- hsn915 4y agoThe basic premise of this article seems to be "writing good programs without heavy runtime checks is physically impossible". I'd like to ask the author, how does he think his computer works? The hardware is rather complex and it has to work near perfectly all the time. It should be impossible according to his premise, but it's clearning happening.
- moonchild 4y agoHardware goes through extensive formal verification as well as testing (incidentally, it tends to be heavily instrumented, cf 'runtime checks', while it is being tested), and has its design frozen months before it goes into mass production. If you developed software the same way, you might see similar results. Most people do not develop software this way.
- uxp100 4y agoYeah, formal verification of software is sort of a niche topic, formal verification of hardware is like, one of the primary tools. Shit even something like Built in Self Test, which is common in hardware, I’ve seen only rarely, and never comprehensive (I’m also not sure comprehensive BiST is the right way to think about reliability for software, it’s probably only very specific things that actually want that)
- mhh__ 4y agoHardware is also much simpler than software conceptually at least. You might think of a modern CPU as a black-box that goes out and finds (the lack of) dependencies in the instruction stream to exploit them, but this all has to be condensed into a logical circuit that is bounded in memory (registers), can be pipelined, and verified. And even then with hardware you are typically verifying things like "The pipeline never locks up entirely" or "The cache never gives back memory from the wrong physical address" basic things like that whereas these same kinds of invariants in software are rarely profitable to try and verify.
- TazeTSchnitzel 4y ago
- benreesman 4y agoJon Blow live-codes compilers and 3D rendering engines and shit from scratch on YouTube or whatever. Starting you essay by dissing him is not a great intro.
- drakonka 4y agoI don't think live-coding compilers puts anyone above criticism.
- tialaramex 4y agoI'm not even sure what "live-coding compilers" would mean. What's "live" about it? I've watched people live coding audio software. That's a performance, like jamming or rap battling where you make music spontaneously for an audience. It's a distinct skill from being able to polish stuff in a studio, just like playing a guitar or singing live is a distinct skill, it's even distinct from working with a loop sampler (like Marc Rebillet) although it's often related. But for a compiler, what's "live"? Somebody writes some code and you... tokenize it in real time, transform it into some intermediate representation, optimise that and then spit out machine code? No? Then it's not "live coding", you're just talking about how he got paid to stream on Twitch or whatever. Loads of people do that. Ketroc streamed his last minute strategies for the recent SC2 AI tournament, he's not even a "professional" programmer, half his audience haven't seen Java before.
- kelnos 4y ago"Live coding" just means that you are writing code in front of an audience. All that means in this case is that while he was working on his compiler, he was recording and streaming what he was doing.
- benreesman 4y agoI’m saying that John Blow works on fairly difficult software projects and shows the process, mistakes and all. That’s takes a lot of both confidence and humility. I tend to make more mistakes the first 2 or 3 times I pair program with someone, I can only imagine with 10k people watching my every mistake. Add to this that John Blow is such an exemplar of the entrepreneurial spirit that this site has basically its foundational value. The guy worked in the rat race for awhile, saved a modest amount to self-fund building Braid. Braid smashed every record both commercially and critically for what one guy in a garage could do in games. He took all that money, hired a few people carefully, and built The Witness, not on fucking Unity or something, but from the shaders up so that it would have a unique look and not be a clone of something else. The Witness was also a huge commercial and critical success. His most recent project is, uh, ambitious. I don’t know if it’s going to prove feasible. But I’m sure as hell rooting for success rather than failure. Now mostly this is directed at the auth or the post, but you’ve kind of signed up for a little of this: what the fuck is your CV?
- travisgriggs 4y agoBuried in the lengthy conclusion at the end: > Simplicity needs to be pervasive through the system, and further in the context it resides in, for one to benefit from it This should have been the opening text of the essay.
- cyber_kinetist 4y agoBut this is what Jon would actually agree? (Design right abstractions for the right hardware?)
- travisgriggs 4y agoMaybe? One man’s abstraction is another man’s bureaucracy?
- cobertos 4y agoI think when they say "system" they mean "computing stack" from the gate-level up. You can't have a different simple on top of silicon that expects another type of simple. It's too incompatible with the throughout increase that pipeline and the specific caching implementation give. Though I don't think Jonathon Blow is necessarily ignoring the underlying silicon expectations from the Livestream or two I've seen.
- Stampo00 4y agoI agree with the overall sentiment. There's a loud minority of developers out there who are nostalgic for something they never actually experienced. It's a reaction to the explosion of complexity of computers and the increasing depth of the stack of software we must depend on to get anything done. It makes us vulnerable because we must depend on leaky abstractions since there's too much software to fully understand all of it. And sometimes there are bugs and it only takes being burned once or twice before you become suspicious of any software you haven't (or couldn't have) written yourself. But starting from scratch kills your productivity, maybe for years! I'm truly sympathetic. The simplicity of the microcomputer era has a certain romance to it, especially if you never lived through the reality of it. There's a sense of freedom to the model of computing where only your program is running and the entirety of the machine is your own little playground. So I get why people make stuff like PICO-8 and uxn. I agree with the criticism of Jon Blow's rhetoric, even though the tone is harsher than strictly necessary. Blow's criticisms and proposed solutions seem overly opinionated to me, and he's throwing out the baby with the bath water. He describes things like compile time and runtime hygienic macros like they're a new invention that hasn't existed in Lisp since before he was born. However, I think targeting uxn is unfair. Uxn would be viewed better as an experiment in minimalism and portability. I think of it more like an art project. It's unfair because the author is comparing mainstream languages that benefit from countless users' input and innovations over the course of 60 years to a niche system with a small handful of developers that has existed for maybe 2 years or so. That's a strawman if I ever heard one.
- Animats 4y ago"There's a loud minority of developers out there who are nostalgic for something they never actually experienced." Having actually experienced it, all the way back to writing business applications in mainframe assembler, I am not nostalgic for it. Today I write mostly in Rust.
- mwcampbell 4y agoLikewise, as a child born in the early 80s, my family's first computer was an Apple IIGS, and I routinely used Apple IIe computers in school from 1st through 7th grade. I wrote Apple II assembler during that time (albeit heavily relying on routines copied from books and magazines). And while occasionally fooling around with an Apple II emulator with an Echo speech synthesizer, or even just listening to one [1], makes me nostalgic for my childhood, I don't miss the experience of actually using or programming those computers. Things are so much better now, even (or perhaps especially) for disabled folks like me. [1]: https://mwcampbell.us/a11y-history/echo.mp3 https://mwcampbell.us/a11y-history/echo.mp3 This file has a real Echo followed by an emulator. Unfortunately, I forgot where I got it, so I can't provide proper attribution.
- twic 4y agoAs an aside, Tony Hoare is a national treasure.
- ezy 4y agoThis is, of course, an argument against a strawman. I wish the author had not mentioned certain folks by name, because the analysis is interesting on its own, and makes some good points about apparent simplicity. However, by mentioning a specific person, and then restating that person's opinion poorly, it does a disservice to the material, and basically it just devolves the whole thing. My understanding of Jon Blow's argument is not that he is against certain classes of "safe" languages, or even formal verification. It is that software, self-evidently, does not work well -- or at least not as well as it should. And a big reason for that is indeed layers of unnecessary complexity that allow people to pretend they are being thoughtful, but serve no useful purpose in the end. The meta-reason being that there is a distinct lack of care in the industry -- that the kind of meticulousness one would associate with something like formal verification (or more visibly, UI design and performance) isn't present in most software. It is, in fact, this kind of care and dedication that he is arguing for. His language is an attempt to express that. That said, I'm not so sure it will be successful at it. I have some reservations that are sort of similar to the authors of this piece -- but I do appreciate how it makes an attempt, and I think is successful in certain parts, that I hope others borrow from (and I think some already have).
- benreesman 4y agoI endorse your much more thoughtful and well-argued post than my knee-jerk response down in the gray-colored section below. John isn’t right about everything: he criticizes LSP in the cited talk, and I think the jury is in that we’re living in a golden age of rich language support (largely thanks to the huge success of VSCode). I think he was wrong on that. But the guy takes his craft seriously, he demonstrably builds high-quality software that many, many people happily pay money for, and generally knows his stuff. Even Rust gives up some developer affordances for performance, and while it’s quite fast used properly, there are still places where you want to go to a less-safe language because you’re counting every clock. Rust strikes a good balance, and some of my favorite software is written in it, but C++ isn’t obsolete. I think Jai is looking like kind of what golang is advertised as: a modern C benefitting from decades of both experience and a new hardware landscape. I have no idea if it’s going to work out, but it bothers me when people dismiss ambitious projects from what sounds like a fairly uninformed perspective. HN can’t make up its mind right now: is the hero the founder of the big YC-funded company that cuts some corners? Is it the lone contrarian self-funding ambitious software long after he didn’t need to work anymore?
- chubot 4y agoI tend to agree (although this article feels a bit like it's "picking on" some whimsical projects that aren't making grand claims ... or are they?) A term I like to use for this phenonemon is "Inner Platform Effect". https://en.wikipedia.org/wiki/Inner-platform_effect https://en.wikipedia.org/wiki/Inner-platform_effect The prime example is that in the 90's, Java thought they were going to make Windows irrelevant (a pile of poorly debugged device drivers or something like that). But now Java is just Windows/Unix process. Same with all these "alternative computing stacks" -- in the end they will almost certainly be just Unix processes. The only situation I can think of where they wouldn't be is a revolution in hardware like the IBM PC producing MS-DOS, etc. And even not then, because we already had the mobile revolution starting ~15 years ago, and both platforms are based on Unix (iOS/Android). ---- I do think people should carefully consider whether they want to create an "inner platform" or make the platforms we ACTUALLY USE better. That is the purpose of https://www.oilshell.org/ https://www.oilshell.org/. Evolving working systems is harder than creating clean slates. So clean slates are fun for that reason: you get to play God without much consequence. Sometimes clean slates introduce new ideas, and that's the best case. But a common pattern is that they are better along certain dimensions (the "pet peeves" of their creator -- small size, etc.), but they are WORSE than their predecessors along all the other dimensions! So that is the logic of Oil being compatible and painstakingly cleaning up bash -- to not be worse than the state of the art along any dimension! I've experimented writing a clean slate shell in the past, but there are surprising number of tradeoffs, and a surprising number of things that Unix shell got right. ----- But Oil can ALSO be viewed as a clean slate, which is sometimes hard to understand. https://www.oilshell.org/release/latest/doc/oil-language-tour.html https://www.oilshell.org/release/latest/doc/oil-language-tou... I just drafted this doc, and surprisingly little breaks even in the non compatible mode: What Breaks When You Upgrade to Oil https://www.oilshell.org/preview/doc/upgrade-breakage.html https://www.oilshell.org/preview/doc/upgrade-breakage.html So I would like to see more systems take a DUAL view -- compatible, but also envision the ideal end state, and not just pile on hacks (e.g. Linux cgroups and Docker are a prime example of this.) You will learn the wisdom of the system that way, and the work will be more impactful. For example, it forced me to put into words what Unix (and the web) got right: https://www.oilshell.org/blog/2022/03/backlog-arch.html https://www.oilshell.org/blog/2022/03/backlog-arch.html
- spicyusername 4y ago> In a DevGAMM presentation, Jon Blow managed to convince himself and other game developers Setting the content aside, when an author starts off their with with this kind of tone I'm immediately turned off. There's no need to be so antagonistic. Jonathan Blow "said", "claimed", "discussed", or any of the infinite other neutral and non-insulting ways to refer to another person's work.
- mhh__ 4y agoIsn't this basically exactly the same tone the arguments the article is trying refute use anyway?
- avgcorrection 4y agoBlow is not any less confrontational and opinionated himself so I’m fine with it.
- cyber_kinetist 4y agoThe article is all over the place, I don't really know what it's trying to say. It starts by criticizing Jon Blow's talk about "collapse of civilization by nobody being to able to do low-level programming anymore" as a tirade against the tirade of abstractions, but then talks about dxn as a prime (flawed) example of this "effort to remove abstractions". I mean, dxn is clearly just a wrong abstraction for the hardware we have right now, it's actually opposite to what most low-level programmers would do. So the dxn example is actually supporting what Jon was saying in the talk? It's just not a good example. Also, the example about dynamic dispatch isn't really as persuasive as the author might think. Even if everyone benefits from these abstractions, what's the point when that abstraction is fundamentally slow on hardware in the first place, no matter how much optimization you can do? I mean, the Apple engineers have done everything they can do to optimize obj_msgSend() down to the assembly level, but you're still discouraged to use Obj-C virtual method calls in a tight loop because of performance problems. And we know in both principle and practice that languages which heavily rely on dynamic polymorphism (like Smalltalk) tends to perform much worse than languages like C/(non-OOP)C++/Rust which (usually) doesn't rely heavily on dynamic polymorphism. In these languages, when performance matters devs often use the good ol' switch statement (with enums / tagged unions / ADTs) instead to specify different kinds of behavior, since they are easier to inline for the compiler and the hardware is made to run switch statements faster than virtual calls. (Or to go even further you can just put different types of objects in separate contiguous arrays, if you are frequently iterating and querying these objects...) The problem I think for most programmers is that they don't know they can actually make these design choices in the first place, since they've learned "use virtual polymorphism to model objects" in OOP classes as a dogma that they must always adhere to, whereas a switch statement could have been better in most cases (both in terms of performance and code readability/maintainability. Virtual calls may be a good abstraction in some cases, but in most cases there are multiple abstractions competing with it that are more performant (and arguably, can actually be simpler). The point Jon is trying to make (although maybe not that clear enough from the talk), is that we simply need better abstractions for the hardware that we have. And C/C++ doesn't really cut it for him, so that's why he's creating his own abstractions from scratch by writing a new language. He has often said that he dislikes "big ideas programming", which believes that if every programmer believes in a core "idea" of programming then everything will magically get better. He instead opts towards a more pragmatic approach to writing software, which is writing for the hardware and the design constraints we have right now. Maybe he may seem a bit grumpy from the perspective of people outside of OS/compiler/game development (since he also lets out some personal developer grievances in the talk), but I think his sentiment make sense in a big picture, that we have continuously churned out heaps of abstractions that have gone too far from the actual inner workings of the hardware, up to the point that desktop software has generally become too slow compared to the features it provides to users (Looking at you, Electron...)
- mhh__ 4y agoMy personal opinion of this is that you can have high and low level code written in the same language at the expense of requiring more skill from the programmer. You can write a pure-functional RPN calculator in a handful of lines of D, you can also write D's entire implementation in D including the "low-level" aspects. I also think the distinction between low and high level code in languages that are not built around some theoretically abstract model of execution (e.g. the lambda calculus) to be rather pointless and mostly useful only for making poor arguments. I'm also sceptical of simplicity as an unqualified idea. I have read "simple" code with no abstractions that makes it extremely hard to read, I have read "simple" code that can be considered as such because the abstractions are actually abstractions: "Abstraction is the removal of irrelevant detail".
- stephc_int13 4y agoThis is beyond stupid. There is no such thing as "safe language". The author has clearly never seen what real safety critical code look like. When safety/robustness really is critical, there are ways to achieve it with high confidence, and it can be done in any language as long as the team doing it is qualified and applying stringent rules. Of course this is time consuming and costly but luckily we've known how to do it for decades. The kind of rules I am talking about are more stringent than most people who never worked on those fields realize. In the most extreme case I've seen (aerospace code) the rules were : no dynamic memory allocation, no loop, no compiler. Yeah, pure hand-rolled assembly. Not for speed, for safety and predictability.
- deleted 4y ago[deleted]
- benreesman 4y agoQuality is costly in time and money, but to your point, it’s not mysterious how to achieve. I write slow, half-assed Python scripts every single day, because “good enough” is in fact good enough for some things. But over-extrapolating the “good enough” mindset to everything is lazy and makes computers less fun.
- Avshalom 4y agoFor example, the specification framework for the C language by Andronick et al8 does not support "references to local variables, goto statements, expressions with uncontrolled side-effects, switch statements using fall-through, unions, floating point arithmetic, or calls to function pointers". If someone does not want to use a language which provides for bounds checks, due to a lack of some sort of "capability", then we cannot imagine that they will want to use any subset of C that can be formally modelled! that said this isn't an essay about safety, it's about the emotional appeal of a sort of false simplicity that some programmers are prone to falling for and pointing out the inherent inability of a couple projects (in synecdoche for a whole shit ton of other projects) to live up to promises of that mirage.
- stephc_int13 4y ago
- mwcampbell 4y ago> we'd even say that the greatest programmers are so because of how they produce redundancy. Perhaps the greatest of all programmers produce redundancy while depending on very little of it in their own code. For example, Richard Hipp created SQLite, the ubiquitous and amazingly high-quality embedded database, in C. Thinking about that makes me feel like I ought to be using C in my own, much more modest attempt at a reusable infrastructure project [1]. Cue the cliches about younger generations (like mine) being soft compared to our predecessors. [1] https://github.com/AccessKit/accesskit https://github.com/AccessKit/accesskit (it's too late now, I'm committed to doing it in Rust)
- saagarjha 4y agoIt might be important to consider that making a high performance, reliable database is something that is far more dependent on the author than the language they choose to use, and that it may not be a good choice to cargo cult their language choices in your own project.
- RcouF1uZ4gsC 4y ago> Thinking about that makes me feel like I ought to be using C in my own, much more modest attempt at a reusable infrastructure project [1]. Before you do that, read https://www.sqlite.org/testing.html https://www.sqlite.org/testing.html SQLite has a crazy amount of verification and testing. There are something like 640x the code for tests as for the actual implementation. If you are looking to SQLite as an inspiration to write in C, you should also consider the verification and testing that makes it work.
- avgcorrection 4y ago> > Perhaps the greatest of all programmers produce redundancy while depending on very little of it in their own code. And that’s a self-own.
- mwcampbell 4y agoYou're right, I forgot about the extraordinarily thorough test suite.
- Xeoncross 4y agoThere are best practices and optimized algorithms. Due to ignorance or preference these are sometimes ignored. This results in a lot of confusion, bloat, and failed attempts. We all want less sloppy code and less sloppy abstractions, but it's hard to do in the real world with tens of millions of developers placed under different constraints. "I was not given time to do this correctly, I'll just use a library that adds 200mb RES but basically works for now." The Internet Architecture Board, W3 working groups, OWASP, Open telemetry, and hundreds of other groups are working hard to standardize things so we don't have to repeat the same mistakes in a problem area. Heck even community sites like leetcode help raise awareness about sub-optimal solutions to problem spaces.
- entaloneralie 4y agoHi all, My name is Devine, and I'm to blame for the uxn disaster.. I'm getting this link thrown at me from all sides right now, so I figured I might as well chip in. I'm a bit more on the design-y side of things, and all these fancy words to talk about computers and retro computing, are a bit beyond me, and reference an era of computing which I didn't really had a chance to experience first hand. But let's talk about "the uxn machine has quite the opposite effect, due to inefficient implementations and a poorly designed virtual machine, which does not lend itself to writing an efficient implementation easily." This is meaningful to me and I'd love to have your opinion on this. Before setting on the journey to build uxn, I looked around at the options that were out there, that would solve our specific problems, and I'd like to know what you would recommend. Obviously, I take it that the author is not advocating that we simply return to Electron, and I take it they understand that re-compiling C applications after each change is not viable with our setup, that Rust is manyfolds too slow for us to make any use of it, and that they understand that our using Plan 9, C is not a good candidate for writing cross-compatible(libdraw) applications anyway. So, what should we have done differently? I'm genuinely looking for suggestions, even if one suggestion might not be compatible with our specific position, many folks come to us asking for existing solutions in that space, and I would like to furnish our answers with things I might have not tried. Here are some directions we tried prior to Uxn: https://wiki.xxiivv.com/site/devlog.html https://wiki.xxiivv.com/site/devlog.html Ah, one last thing, this is how you fib the first 65k shorts in uxntal: https://git.sr.ht/~rabbits/uxn/blob/main/projects/examples/exercises/fib.tal https://git.sr.ht/~rabbits/uxn/blob/main/projects/examples/e...
- mwcampbell 4y agoI think a VM for a small, but highly abstract, language like Scheme might address the objections of the author(s) of this article. You might like Chibi-Scheme: https://github.com/ashinn/chibi-scheme https://github.com/ashinn/chibi-scheme Having said that, IMO, if you're having fun with uxn and its retro 8-bit aesthetic, by all means keep going with that.
- entaloneralie 4y agoI did use Chibi! I've implemented a few lisps, but I always found their bytecode implementation too convoluted and slow, so I went with a stack machine for this particular project. I might at some point, implement a proper scheme in uxntal. It's neat, but I don't remember seeing a graphical API for it, I'll have a look :)
- yellowapple 4y agoThe "analysis" of uxn is unproductive to the point of being anti-productive. In particular: > The most significant performance issue is that all uxn implementations we have found use naïve interpretation. A typical estimation is that an interpreter is between one and two magnitudes slower than a good compiler. We instead propose the use of dynamic translation to generate native code, which should eliminate the overhead associated with interpreting instructions. Okay, go for it. Literally nothing is stopping you from implementing an optimizing compiler for uxn bytecode. Meanwhile, zero mention in this "analysis" of program size, or memory consumption, or the fact that uxn implementations exist even for microcontrollers. Interpreters are slow, but they're also straightforward to implement and they can be pretty dang compact, and so can the interpreted bytecode be much smaller than its translated-to-native-machine-code equivalent. (Interpreters also don't need to be all that slow; I guess this guy's never heard of Forth? Or SQLite?) > Writing a decent big-integer implementation ourselves requires some design which we would rather not perform, if possible. Instead, we can use a library for simulated 32-bit arithmetic. […] The resulting program takes 1.95 seconds to run in the "official" uxn implementation, or 390 times slower than native code! This amount of overhead greatly restricts what sort of computations can be done at an acceptable speed on modern computers; and using older computers would be out of the question. Well yeah, no shit, Sherlock. Doing 32-bit arithmetic on an 8-bit machine is gonna be slow. Go try that on some Z80 or 6502 or whatever and get back to us. And no, using older computers ain't "out of the question". There are literally uxn ports to DOS, to the Raspberry Pi Pico, to the goddamn Gameboy Advance, to all sorts of tiny constrained systems. The author would know this if one had done even the slightest bit of investigation before deciding to shit all over uxn and the folks making it. > The uxn system could also be a sandbox, and prevent damage outside of its memory, but a filesystem device is specified for the platform, and is often implemented, and so a uxn program can destroy information outside its virtual machine. Any isolation would have to be performed outside of the virtual machine; thus running a random uxn program is as insecure as running a random native executable. Absolutely nothing in the uxn spec suggests that the "filesystem" in question should be the host's filesystem; it could very well be some loopback device or a sandbox or what have you. If security/isolation is desired, then that's pretty trivial to implement in a way that a tiny bytecode stack machine would have a very hard time escaping. Either the author is incapable of actually reading the documentation of the thing being analyzed, or one is being blatantly intellectually dishonest. ---- Like, I don't know what the author's beef is - maybe Rek and Devine ran over the author's dog with their sailboat, or maybe the Bytecode Interpreter Mafia smashed the author's kneecaps with hammers - but the article reads more like bone-pickery than some objective analysis.
- bebrws 4y agoIn my experience this statement is incorrect: “Using abstractions extensively actively encourages study into how to implement them efficiently, contrary to Blow's claim that their use will lead to few understanding their implementation.” I would agree with Jonathon Blow here that it is very common to use abstractions without there being any understanding of or even an interest to discover the underlining implementation of that abstraction. For example, why else would the question, “Do you use multithreading in NodeJS?” be a common interview question? It is commonly known that NodeJS “runs code asynchronously” but how often would it be that an engineer could accurately explain how this is done? While some may find the benefit in understanding the system in which they work in completion I believe a majority is content with living with assumptions.