Recent submissions

Comment · 5 months ago
This is so true. In webgpu, the functions to request a GPU device / GPU adapter are both async, and I often wonder, what is my engine going to do in the few milliseconds before it's grabbed a handle to the GPU? It can't render anything, it can't load anything... If I really had to guess I would think it's so that when compiled for web, the page doesn't lock up when the browser is showing the "allow this site to access your GPU? yes/no" popup. But it makes far less sense in desktop land.
Comment · 6 months ago
I dislike the trend among computer users that query strings == tracking data. They're just one of the many ways a browser request can contain data. They are used for all sorts of things in perfectly valid websites, and it's difficult for me as a developer to just just arbitrarily accept that a certain feature HAS to be used for a certain malicious technique, despite it being common.

With more limited copy-paste functionality, tracking parameters could just as easily be put in the request body. Or a cookie/session data. Or, if you're nasty, you could get everything you want to know out of a user via fingerprinting with very little up-front data at all.

We as users have basically already been collectively pwned, the solution being to use VPNs, anti-tracking scripts/extensions, encryption, and just plain ol 'stop using services that track you'. The preceding are all leagues better for one's privacy than superstitiously chopping up a URL.

Honestly, disallowing other websites from from adding their query strings to your URLs I think is awesome, and I think it makes sense that websites should validate their URLs against their internal APIs only. But, given this was only done for query strings, and not other parts of the request, I still feel like this whole thing establishes more of a taboo than an actual security or privacy guideline.

Comment · 9 months ago
I'm a huge fan of the 'parse, don't validate' idiom, but it feels like a bit of a hurdle to use it in C - in order to really encapsulate and avoid errors, you'd need to use opaque pointers to hidden types, which requires the use of malloc (or an object pool per-type or some other scaffolding, that would get quite repetitive after a while, but I digress).

You basically have to trade performance for correctness, whereas in a language like C++, that's the whole purpose of the constructor, which works for all kinds of memory: auto, static, dynamic, whatever.

In C, to initialize a struct without dynamic memory, you could always do the following:

    struct Name {
        const char *name;
    };

    int parse_name(const char *name, struct Name *ret) {
        if(name) {
            ret->name = name;
            return 1;
        } else {
            return 0;
        }
    }

    //in user code, *hopefully*...
    struct Name myname;
    parse_name("mothfuzz", &myname);
But then anyone could just instantiate an invalid Name without calling the parse_name function and pass it around wherever. This is very close to 'validation' type behaviour. So to get real 'parsing' behaviour, dynamic memory is required, which is off-limits for many of the kinds of projects one would use C for in the first place.

I'm very curious as to how the author resolves this, given that they say they don't use dynamic memory often. Maybe there's something I missed while reading.

Comment · 10 months ago
I'm not a fan of the recent trend in software development, started by the OOP craze but in the modern day largely driven by Rust advocates, of noun-based programming, where type hierarchies are the primary interface between the programmer and the code, rather than the data or the instructions. It's just so... dogmatic. Inexpressive. It ultimately feels to me like a barrier between intention and reality, another abstraction. The type system is the program, rather than the program being the program. But speaking of dogma, the author's insistence that not abiding by this noun-based programming model is a form of 'lying' is quite the accusatory stretch of language... but I digress at the notion that I might just be a hit dog hollering.
Comment · 10 months ago
I love Ruby and have tried to use mruby several times, but the one thing that always becomes an issue is that it uses Ruby’s own native-extension build system for compilation, which is configured in Ruby itself. It makes it a total pain to include in other build systems, or when compiling to other targets (i.e. WASM)

Frankly, I love Ruby as a language, but if it were as easy to embed as Lua I would have no reason to use Lua.

Comment · 11 months ago
I agree with the author - I'm sick of hearing the cliches from people who prefer 'dark mode'. But I remember long before there was 'light mode' and 'dark mode' there were themes based on a spectrum of hues and values - actual colors. Why not bring that back? "Light mode" can be way more bearable if it's not pure #ffffff. I dislike the invented dichotomy of light and dark anyway, there's an entire spectrum that designers can use, and I think apps in general would look way better if they took advantage of that.
Comment · 1 year ago
You'd also be more productive and have less unknowns and potentially less decision paralysis if, say, everyone started using excel hooked up to a database instead of writing their own bespoke CRUD app, but alas, those aren't the reasons one asks programmers to program.
Comment · 1 year ago
I love Crystal but I’m surprised at how nothing the WASM story is this late in the game. I’d love to run Crystal directly in the browser, especially given how web-focused they seem to be.

Also, windows support has been more or less “done” for a couple of years now, is the “preview” tag still necessary?

Comment · 1 year ago
Regarding the 'Modular Monoliths' bit, I wholeheartedly agree. I always found it kind of disappointing that while we're told in our OOP classes that using interfaces increases modularity and cohesion and decreases coupling, in reality in most programming languages you're relying on the nominal type of said interface regardless. All libraries have to use a common interface at the source code level, which is obscenely rare. For interfaces to truly live up to what they're describing, they merely ought to be structural (or whatever the equivalent to functions is that structural typing is to data).

Edit, since I remembered Go has this behaviour: I think Go's auto-interfaces I think are easily one of its biggest selling points.

Comment · 1 year ago
I'm of two minds when I see comments complaining about header files. Practically speaking, I think "have the preprocessor copy & paste source files together" is a bit of a hackjob, but, conceptually speaking, having your interface and implementation separate is ultimately a good thing.

The problem of course lies not with header files, but C++ the language, as all public fields and private fields must be specified in the class declaration so that the compiler knows the memory layout. It's kind of useless in that sense. You can move private methods out to a separate source file, but, you don't gain much in doing so, at least in terms of strict encapsulation. And of course, if you use templates at all, you can no longer even do that. Which is its own can of worms.

Unfortunately, none of these problems are problems that modules solve. Implementations very much disagree on interfaces vs implementations, precompiled vs simply included, etc etc. In my own usage of modules I've just found it to be header files with different syntax. Any API implemented via modules is still very leaky - it's hard to just import a module and know what's truly fair for application usage or not. You still ultimately have to rely on documentation for usage details.

At the end of the day I don't really care how the implementation puts together a particular feature, I care about how it affects the semantics and usability of the language. And modules do not really differ in proper usage from headers, even though the whole backend had to be changed, the frontend ends up being the same. So it's net nothing.

All said and done, when it comes to defining library APIs, I prefer C. No public/private, you just have some data laid out a particular way, and some functions to operate on it. The header file is essentially just a symbol table for the binary code - and said code can be a .c file or a .o file or even a .a or .lib or .dll or whatever - C doesn't care. Raw functionality, raw usability. No hoops.

Comment · 1 year ago
The idea that arrays of structs are inherently more cache friendly and thus data-oriented-er is a bit reductive of the whole practice of data-oriented code. The point is to optimize data layout for access patterns. Putting fields of a struct into their own arrays is only actually an optimization if you're only accessing that field in-bulk. And if so, why is it even in a struct in the first place? If you use all fields of a struct in your algorithm, then an array of structs is the optimal way.

All the same is true for enums.

Comment · 2 years ago
I have a problem with how procrastination and perfectionism, this sense of being 'not good enough', is almost universally phrased as not being good enough for others. For caring too much about others' opinions. And that the solution is to just Do Art For Yourself :tm:.

I've tried that. I've tried shunting out everyone else's opinions. But then of course, if you lock me in a room with me, myself, and I, you now have 3 of my biggest critics all in the same room.

I don't really care what others think, never really did, and none of these anti-procrastination or anti-perfectionism pieces help when it's my own standards that I'm not meeting.

Comment · 2 years ago
>Prerequisites: VSCode & RunMe

>Foyle relies on VSCode and RunMe.dev to provide the frontend.

Well that’s a lot to take in, especially from a Mozilla project.

Comment · 2 years ago
I’ve implemented platformer collision dozens of times now and the only way I’ve found it to be genuinely smooth is to do it one pixel at a time, just like the author suggests.

But something always bugs me about that - we know the closest edge of the closest obstacle, we know the vector of the player’s motion, by all accounts we should be able to calculate the point of contact in one go without doing any substeps.

And yet, doing it in one pass always seems to result in a myriad of edge cases (literal!) that break the whole thing, unless you do heavy preprocessing, converting your tiles to a graph of lined surfaces, etc etc.

Comment · 2 years ago
This is directed more at the above comment than yours, but, do note that gay marriage is in fact not legal in Israel, nor is inter-faith marriage.

Live from the official Hacker News API

A modern reader for Hacker News · SvelteKit + Skeleton