Hacker Newsnew | past | comments | ask | show | jobs | submit | solatic's commentslogin

> free to use at launch

How does this help me control spend if I don't understand how much it will cost me a year after I bake it into my infrastructure?


> For someone else it's the wrong choice, they don't know Python

The author ruins their entire argument with this one claim.

If "we picked this tool because we know it best" is a legitimate requirement, then every tool choice is justified as a "perfect" choice because it's what the architect was most comfortable with. If your emotions and current knowledge levels are considered reasonable justifications for a "perfect" solution, then all solutions are perfect solutions; they simply haven't had enough emotional justification yet. If all solutions are perfect solutions, then none are.

There are, ultimately, two kinds of software - those that need to ship by a deadline, and those that don't. A deadline forces you to eject dead weight that you don't need - requirements have a habit of getting clarified real fast when you need to build to a deadline. If you had time to over-engineer despite a deadline, you should consider working for a more productive organization. Meanwhile, the concept of "over-engineering" is a little vague for software that doesn't have a deadline. If you don't have a deadline, you don't have to compromise on quality. "Over-engineering" is then just a value judgement that you made poor use of your infinite timescale and built the wrong things with it. But who is making that judgement? Not the person who built it, not the person who funded it (i.e. usually self-funded as a hobby project), and not the person who uses it (since over-engineering is an implementation detail, rather than a product choice), so who cares?

edit: to clarify: "pick a stack you know already since we don't have time to learn a new one" is a totally valid requirement. But I disagree that it means that you built a "perfect" solution with it. I also disagree that you usually need to build perfect software - getting comfortable with adequate is how most people ship most software.


I wouldn't say it's impossible, rather un-ergonomic. TypeScript can add type information to ordinary JavaScript code via JSDoc comments; the result can both be executed as ordinary JavaScript as-is and type-checked with TypeScript. But it's a huge pain to try to write (and maintain) everything that way, it was supported as a hack to help migrate legacy codebases. You could probably take a similar "the lifetimes are embedded in comments" approach with other languages, and the result would be similarly un-ergonomic.

A better comparison would be Python.

The way Python added types is the most disgusting thing imaginable... but it has type hints now, so I guess that makes some people happy.


That is possible (clang has experimental lifetime annotations support), but that is not enough to guarantee memory safety.

As a simple example, Zig has no private fields. That makes encapsulating any unsafety impossible.


no. You don't need private fields. All you have to do is analyze the code, harness the compiler to generate a time-dependent data dependency graph, and map allocation/frees/uses, if you can 'color' branches where data are shared you can also track and check to see there isn't an aliasing violation too.

it is easy to patch the zig compiler to enable this this (export the code graph; about 50 LOC). The analysis is much much harder to get right.


This analysis is undecidable. There is a reason sound static analyzers (including languages like Rust) require in-code annotations.

it is possible to do in-code annotations in zig, if you're clever. you can get pretty far without them too.

as an example, you can check for double free without ownership tagging, by being agnostic about who should free, and flagging if two nondisjoint code paths attempt to free the same allocation.


It seems like it'd be pretty reasonable to get something akin to polonius. I can write up an engine in zig if it'd help?

start by examining zig-clr

It is only feasible to do this if the whole of the codebase idea designed to allow it, and it's still going to blow up in odd ways of you don't have a way to describe lifetimes in your interfaces. The magic of rust's design is that it turns this memory tracking into a local problem, such that you can design an interface and be sure that every use case is safe and verifiably so.

> Zig has no private fields

You may have missed the point here. You could add a comment to the struct field that marks the field as private, and build a TypeScript/JSDoc analogue that analyzes all accesses to the field and fails if it finds accesses from functions that aren't part of the struct that owns the field. You don't even need a comment on the field - you could copy Go's convention, add a comment to the struct definition marking it as "follows Go convention", and then fail any access from outside the struct to a field that starts with a lower-case character.

It doesn't prevent you from ignoring that tool and writing Zig code that imports the struct and accesses the field. It is, of course, not part of the Zig language itself. But if you adopted a tool like that, it would be your responsibility to run it across-the-board and pay attention to the results - same as how it is your responsibility to pay attention to the results if you added those JSDoc comments.


I have picked private fields as an example of feature that is needed because it is very simple. You're right that you can build an analyzer (with additional code annotations) to support that, but it's only one example.

Take another example: unsafe traits. They are fundamental to some safety encapsulations, most famously concurrency (`Send`/`Sync`). Here you cannot just build an analyzer to mark something unsafe, because Zig has no traits, its generics are duck-typed.

You can, of course, add traits. But at this point you're essentially creating your own language that compiles to Zig, with all problems this entails (e.g. bad ecosystem support). It's also hard to claim that Zig can be memory safe then.


> You can, of course, add traits. But at this point you're essentially creating your own language that compiles to Zig

I think herein lies the rub. What's the difference between a static analysis tool and an actual separate language that transpiles to the original? Hypothetically - again, very un-ergonomically - you could add traits to Zig code in comments, or in example-traits.typezig files that would be skipped by the Zig compiler (like how *.d.ts files are skipped). How much of a language is writing code in a particular syntax, versus how much of a language is writing code that will pass a tool "building" it, versus how much of a language is about the final compiled output that you get from the tool? All static analysis tools that support line-level exceptions are, essentially, programmed by comments, with their own language (typically highly simplified compared to a "full" programming language), that affect whether or not the "language" passes or not. What Typescript/JSDoc shows is that, actually, much more complicated tooling can be built with this programming-by-comments model than had been done before (to my knowledge), and thus even more powerful still tooling could be built with that model.

Of course there's a difference between static analysis and a language that transpiles. But perhaps it's more a question of degree than a simple binary classification.


Exactly.

Every part of the language must support memory safety from first principles.


empirically untrue. several projects exist that bolt on extra safety to unsafe languages or unsafe parts of language. SeL4 for C, MIRI for rust unsafe. i guess ada/spark for ada too, is the OG, spark being added to ada 4 years after its first release

Hardening is definitely possible, we've had sanitizers in C/C++ for a long time. It's not full memory safety though. Miri is the same.

SeL4C is formal verification, and while it can prove memory safety (and much more) it is much more difficult, to the point that you're basically programming in a different language.

Ada/SPARK is your best example, and also the example I know the least of, so I won't comment on.


SPARK omits some features of Ada, so it would only reinforce the sentiment that bolting on verifiability after-the-fact is difficult. Expressivity is generally the antithesis of static analysis, and it's very easy and tempting to make a language that is accidentally too expressive to support a given analysis without being required to make breaking changes to reduce expressivity.

i mean in zig-clr it pushes you towards more expressive patterns, for example, making you label pointers as optional if their status is ambiguous

A language is more expressive when it allows more programs and less expressive when it allows fewer programs. I don't know zig-clr, but if it rejects programs that Zig accepts (for example, by rejecting the aforementioned ambiguous pointers), then it is less expressive, not more (keeping in mind that being less expressive is not a pejorative).

no thats not the definition of more expressive. more expressive means the language can encode more programmer intent without making a dog's breakfast of the code.

Now we're just having a semantic argument over the word "expressiveness", which is not especially interesting; see https://chrispenner.ca/posts/expressiveness-spectrum . My argument above remains true regardless of the terms you choose to use.

> I've said for a long time that composability in software is a bit like playing Tetris: the lines have to clear.

I love this analogy, and I find it darkly hilarious that most sibling commenters don't seem to understand. Maybe you need to have worked within a million-line codebase to get it.

The only way to "clear the lines" in software is to eject them from the main codebase and into imported libraries with stable, well-documented, well-tested APIs that you very rarely if ever (security vulnerabilities?) need to touch after "stabilizing" them. Great public examples: the Go standard library, https://github.com/spf13/viper , https://github.com/uber-go/zap . Viper and zap combined are more than 20,000 lines of code (according to cloc) that I don't need to read or understand how they work - their lines have been "cleared" and all I need to know is the abstraction.

Half the joy to be found when working within massive codebases is successfully clearing lines.


Just curious: the people behind HTMX have a frontend sibling project called Hyperscript, which handles stuff like frontend state: https://hyperscript.org/docs/reactivity/

Did you give it a try?


At that point just use React.

I'm not convinced. Hyperscript's reactivity model is highly greppable, and it keeps the no-build approach to Web frontend interactivity. It's "just enough" in the same way that HTMX is.

React probably scales better for huge engineering divisions, but that isn't who the GOTH stack is aiming for anyway.


AWS and Google at least own their own hardware (Trainium and TPUs, respectively). It's a moat in the sense that designing, building, and deploying your own chips at scale is quite a feat and not easily replicated. The vertical integration will allow them to continue to be profitable once the models get good enough and competitors' prices race to the bottom. Google has Gemini; AWS may not deploy its own models (yet?), but that's not necessarily a losing position, as long as the market is able to run models sourced elsewhere on Trainium and the price is right.

That's exactly what giant train corporations thought. "We own all the railways, we've squashed the competition"

and they STILL went out of business because they over-estimated the demand for their shitty rails they built to the middle of nowhere. Same with "AI."

https://www.youtube.com/watch?v=2J2Fb1bBufA


Isn't specialized hardware also a big risk? GPUs are more amenable to any big changes that may happen in the next 5, 10 years of AI research. Maybe we won't even be talking about LLMs anymore. Maybe matrix multiplication won't even be the main primitive.

If matrix multiplication isn't the main primitive, I think we have a lot of pain coming our way.

Maybe that is far fetched, but I could see them specializing for some super high dimension multiplication and meanwhile 5 years later turns out "all you need" are 3x3 matrices and suddenly 90% of your specialized hardware is now dark silicon :)

Their "own" as in built by Marvell and Broadcom. Especially Trainium but also TPU4.

> have never measured it

That's because it's practically impossible to collect objective data here, i.e. without confounding factors.

A product where the user spends 99+% of their time reading/consuming is almost certainly easier to use with a GUI. The market settled on thumb-flicking for doom scrolling instead of a button or scroll wheel interface, for a reason.

A product where the user spends 99+% of their time writing is almost certainly easier to use with a keyboard. Most sane people do not write essays on their phones with two thumbs; a keyboard and a proper word processor are preferred.

Most products fall somewhere in the middle. Most products have multiple interfaces, some primarily for consuming information and some primarily for producing it, and thus would find different inputs more productive in different modes. When people claim that they find one input type is more productive than the other, most likely is that their particular use-patterns fall more in-line with the one most aligned with their use-patterns.


> 10 years ago, apps had to explicitly state if they needed network access. And then the powers that be decided that really all apps need network access no matter what.

Why does network access need to be a binary, all or nothing?

When you install an app, the app should request permissions to specific DNS names, i.e. pointing to the servers that the app's authors operate. If I install Todoist, the app should only ask for access to Todoist's servers. If I install Netflix, the app should only ask for access to Netflix's servers. The OS can then put a DNS firewall in and block any network access that wasn't granted when the app was installed.

> And both ios and android make it hard to deny apps network access

The list of apps that genuinely need "any" network access (web browsers, VPN apps, stuff like Termux...) is incredibly small compared to the list of apps that need access to a small number of VPN targets (these days, most apps). Apple / Google could even decide, if they really want to make it easy for apps to request network access, to basically allow apps to automatically get network access, so long as the list of domains the app needs access to is no more than a handful. The security value of isolating "all" network access permissions to only the relative handful of apps that actually need to request it, would be huge.


Yeah, I'm working on a communications platform as a side-project, architecturally providing reliable communications is exceedingly difficult to self-host.

* Mobile calls are another form of push notification, Apple/iOS requires setting up APNS and Google/Android requires FCM, there is no self-hosted option for that at all and, for battery life reasons, no independent replacement is supported. Genuine ownership / independence from the main project requires, iirc, basically compiling from source to register different IDs against APNS/FCM.

* Trying to get into telephony, integrating with SIP is a huge pain. Nobody wants to deal with this.

* Nobody supports high availability for the underlying calls. None of the cloud L7 load balancers support media protocols - you're dropping down to L3 UDP load balancing. All of the available solutions (including LiveKit) depend on stateful services that, at best, place ceilings on call lifetimes (e.g. 5 hours) to allow for graceful draining, but "calls" in Discord-style settings where people connect to a room and stay connected will easily outlast those ceilings. Not supporting high-availability, IMO, is a huge ask for self-hosters - the price isn't in the maintenance window itself, but in deferring updates until the maintenance window, which can leave you vulnerable, particularly if you decide to leave the firewall open to ingress from 0.0.0.0/0 for ease of use. And of course, as a self-hoster, you rarely have a full follow-the-sun ops team, so either you schedule maintenance when everybody else is off (and you should be off too) or when everybody is on (and it's disruptive).


To be fair, I don't think Discord supports HA. As a pretty active user of voice calls on Discord, I've had plenty of cases where the entire channel drops for a second or two and reconnects, presumably to a different server.

If you do some kind of rolling upgrade, where each server has E.G. a lifetime of two weeks, with a 5 hour window where it doesn't accept new connections, I think you'll be fine.


You're right, but idTech is almost by definition that "novelty" kind of engine. And it did help id to sell more games. It's just apparently not enough.


Id made games to demo their engine. No one is going to buy an engine without any games. They don’t even sell idTech anymore. It’s used for their games which are not making any money. No game sales doesn’t support the reasoning they should keep the engine around.


For whatever reason idsoft has not been licensing their engine for a long while. AFAICT it's not that "nobody's buying", it's that "they're not selling".


Except that the obvious reason their recent games see lackluster sales is because they're on Gamepass, which precludes needing to buy the game to play it.


They still get usage stats.


Yes, and those usage stats show that the overwhelming majority are playing the game without having bought it. One can't argue that these studios should be shut down for poor sales when Microsoft themselves are sabotaging the ability for these games to sell for full price.


The whole point of gamepass is that you don't buy the games. If enough people are playing it through gamepass that shows it supports the value of gamepass, if not sure that's a problem.


Consider applying for YC's Fall 2026 batch! Applications are open till July 27.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: