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

The ease in which you can get away with these tactics ad infinitum is starting to make me a pessimist. It feels like it takes almost an entire population of unified people, that are diligently advocating on behalf of themselves, to compete with a ruling class that has the resources to stay on the offense forever.

The ruling class doesn't even have to actively communicate and conspire with one another (although they do). Their independent attempts to undermine and control government furthers the agenda of all private businesses.


It would help if Americans educated themselves on the basics of taxes. They would realize quickly how W-2 income employees pay a very high tax rate when you factor in FICA vs high wealth individuals who pay little to no FICA or income taxes. Add in the benefit of compound interest, cheap margin loans, and you have an incredibly unfair system. It's also why many wealthy individuals argue for a "smaller" government & less taxes. They travel private, go to private schools & prefer to avoid anything "public".

All this is with just the very basics, not counting step up basis, trusts or anything slightly complicated.


I feel like you're fighting the fallacy of "the rich" being collectively blamed for every problem, by giving them credit for everything instead.

We know that none of the goods you listed would be available to the masses unless there was profit to be gained from them. That's the point.

I have a hard time believing a large group being motivated and mutually benefiting towards progression of x thing would result in worse outcomes than a few doing so. We just have never had an economic system that could offer that, so you assume the greedy motivations of a few is the only path towards progress.


> We just have never had an economic system that could offer that

Please propose it yourself.

> you assume the greedy motivations of a few is the only path towards progress

No. I assume the greedy motivations of the many is the best path towards progress. Any other attempts to replace this failed miserably. Ignoring human nature in ideologies never works.


That's extremely difficult. I just don't assume something is impossible because it hasn't been done yet. Especially when there is an active battle to undermine and destroy such ideas by almost every powerful entity on earth.


It's quite odd to me that Nix or something similar like Mise isn't completely ubiquitous in software. I feel like I went from having issues with build dependencies to having that aspect of software development completely solved as soon as I adopted Nix.

I absolutely can't imagine not using some kind of tool like this. Feels as vital as VCS to me now.


We'd have been a lot further along if tools like make had ever adopted hashes for freshness checking rather than timestamps. We'd have ccache built in to make, make could hash entire targets, and now we're halfway to derivations. Of course that's handwaving over the tricky problem of making sure targets build reproducibly, but perhaps compiler toolchains would have taken more care to ensure it.


I'd say the sad part is that nix really works well when the toolchain does caching transparently. But to deliver good DX outside of nix, you kind of want great porcelain tooling that handles everything behind the scenes - downloading of libraries, building said libraries, linking everything together. Sometimes people choose to just embed a whole programming language to make their build system work e.g. gradle. Cargo just does everything. Nix then can't really granularly build everything piece by piece when building rust crates with Cargo - you just get to rebuild every dependency any time the derivation is built and any one input changed. I wonder how much less time would've been wasted if newer languages chose to build on top of nix. Of course, nix would need to become slightly more compatible with Windows and other OSes for this to be practical.


Timestamps have the property of being easily comparable; you can always tell if one file is older then the other. If you were to use hashes for the same purpose, you'd have to keep a database of expected hashes, and comparing them would be a less trivial task, etc. It's doable, but it would be a very differently designed (and much more computationally expensive) program then make.


I bet we could get pretty far with symlinks, but then again even those were an exotic feature on some of make's supported platforms. Nowadays, may as well use sqlite.


Agreed. Recently started a new gig and set up Mise (previously had used nix for this) in our primary repos so that we can all share dependencies, scripts, etc. The new monorepo mode is great. Basically no one has complained and it's made everyone's lives a lot easier. Can't imagine working any other way — having the same tools everywhere is really great.

I'll also say I have absolutely 0 regrets about moving from Nix to Mise. All the common tools we want are available, it's especially easy to install tools from pip or npm and have the environments automanaged. The docs are infinity times better. And the speed of install and shell sourcing is, you guessed it, much better. Initial setup and install is also fantastically easier. I understand the ideology behind Nix, and if I were working on projects where some of our tools weren't pre-packageable or had weird conflicting runtime lib problems I'd get it, but basically everything these days has prebuilt static binaries available.


Mise is pretty nice, I'd recommend it over all the other gazillion version-manager things out there, but it's not without its own weak spots: I tried mise for a php project, neither of the backends available for php had a binary for macos, and both of them failed to build it. I now use a flake.nix, along with direnv and `use flake`. The nix language definitely makes for some baffling boilerplate around the dependencies list, but devs unfamiliar with nix can ignore it and just paste in the package name from nixpkgs search.

There's also jbadeau/mise-nix that lets you use flakes in mise, but I figured at that point I may as well just use flake.nix.


The beauty of mise is that as long as someone is hosting a precompiled binary for you, it's easy to get it. I just repro'd and yeah, `mise use php` fails for me on my machine because I don't have any dev headers. But looks like there's an easy workaround using the `ubi` downloader:

https://github.com/jdx/mise/discussions/4720#discussioncomme...

or see the first comment on this thread to see a way to explicitly specify where to find the binaries for each platform:

https://github.com/jdx/mise/discussions/4720#discussioncomme...

Having these kind of "eject" options is one of the reasons I really appreciate Mise. Not sure this would work for you but I'd rather be able to do this than have to manage/support everyone on my dev team installing and maintaining Nix.


Nix is just one installer (I steer devs toward Determinate's installer) so technically not super-different from needing Docker. Lots of files in /nix but actually less disk use since the store has much more fine-grained de-duping than container images. Nix is still a big bite though, and for most projects I wouldn't make nix a requirement, but the project in question is itself a build system with reproducibility requirements in its design, so I'm not losing too much sleep over this one. The final artifacts don't depend on Nix anyway.


I can say why I bounced off of Nix.

Lots of package combinations didn’t work and I was not skilled enough to figure out why.

The error messages are terrible.

They don’t provide enough versions of packages. I want Python 3.10.4 exactly. But Nix packages by default only provide 3.10.something

I would love to use Nix everywhere, but it’s just too cumbersome for me.


If the nix ecosystem moved entirely to flakes, you could just point at the flake in python's repo, pin it to the proper commit hash, and job's done. Might result in a lot of extra near-duplicate dependencies in the store, but that's unlikely to affect you at the level of Python. Otherwise yeah, you're stuck with whatever combinations were blessed by nixpkgs at the time, or with writing your own derivation.

And the error messages are ... well, yeah. I don't find the nix language as awful as some do, but it's still a functional language by and for functional programmers, and being lazy, a lot of errors surface in very non-obvious places. Ultimately Nix could use a declarative config format on top of everything, but I'd rather they ironed out the other issues first. Guix seems to be a bit further along there, but its platform options are more limited.


Tried Mise?


I think bazel is the tool lot of people are converging towards, but turns out that maintaining complex build setups is a lot of work.


Yep Rust approach won. Pretty much every new language is adopting Result style errors and it's been adapted to plenty of existing languages.

It's a product of functional programming, and for me I can't see how you would ever want to handle errors outside of the functional programming railway-oriented style. For me it's just superior.


Umm, actually, it's specifically a coproduct of functional programming. ;-)

https://en.wikipedia.org/wiki/Coproduct


Ha learned something


I'm not sure that nobody thinks of this. We just have a finite amount of time. Usually with a solid approach, you get solid performance. Fixing a performance related bug rarely when it comes up, is still a time savings over designing this kind of rigorous process from scratch, and getting everyone on board with it.

Getting rid of a whole host of bugs due to the compiler is a big deal because you won't have to design this extra acceptance system or deal with keeping an entire organization disciplined by it. If you can solve this seamlessly I think that's an interesting product that others would be very interested in.


> because you won't have to design this extra acceptance system or deal with keeping an entire organization disciplined by it.

This is just a matter of tooling. (On that note, here is a free business idea, prompt engineer an LLM agent that sets this up for you)

While the compiler does do a lot of things for you, you still end up with things that you should check because compiler doesn't understand your program logic. If Rust was a absolutely strict typed language, where basically everything had a type that defined what data it could hold, then it would be a different story. For example, when parsing a json into an object, instead of strings/numbers/bools, every single field has a finite set of values that it can hold. Then the compiler can figure out a lot of things. For example, if you try to convert a string to int, if the string field type doesn't have a defined regex expression it must match, then the compiler can catch this.

Anything less then that, you are better of writing the validation system once and reusing it for all your code bases now and in the future.


I'm interested in what scenarios you don't get this same feeling when writing TS code? I of course agree with Ruby, JS, and Python.


One big source of bugs in TS is structural sharing. Like, imagine you have some complex object that needs to be accessed from multiple places. The obvious, high performance way to share that object is to just pass around references wherever you need them. But this is dangerous. It’s easy to later forget that the object is shared, and mutate it in one place without considering the implications for other parts of your code.

I’ve made this mistake in TS more times than I’d like to admit. It gives rise to some bugs that are very tricky to track down. The obvious ways to avoid this bug are by making everything deeply immutable. Or by cloning instead of sharing. Both of these options aren’t well supported by the language. And they can both be very expensive from a performance pov. I don’t want to pay that cost when it’s not necessary.

Typescript is pretty good. But it’s very normal for a TS program to type check but still contain bugs. In my experience, far fewer bugs slip past the rust compiler.


Appreciate it, that makes a lot of sense. I feel like I've been trained to favor immutability so much in every language that I sometimes forget about these things.


Yes, immutability is great for safety. But the copies you have to make to keep everything immutable extracts a price in copies and garbage collection.

Rust is advertised as having fearless concurrency. That's true, but not that important as concurrency is not that common. What's important to everyday programming is Rust provides fearless mutability. The fearless concurrency you get with that is just a bonus.

Fearless mutability provides Rust the same safety as a functional language in a without the speed or space cost. IMO, it's Rust's true secret sauce.


Yea this seems like a super power I thought only functional languages had. I have to make time to learn some Rust


Similar. I mostly design my code around something like pipe and lifetime. The longer something needs to live the closer it is to the start of the program. If I need to mutate it, I take care that the actual mutation happens in one place, so I can differentiate between read and write access. For anything else, I clone and I update. It may not be efficient and you need to track memory usage, but logic is way far simple.


Not parent comment, but TS is generally safe if you have types correct at system borders, but very scary when you don't. Some of the most impactful bugs I've seen are because a type for an HTTP call did not match the structure of real data.

Also, many built in functions do not have sufficient typesafey like Object.entries() for instance


That is an issue with how TS works, but it can be significantly improved upon by using a library to verify the structure of deserialized data. zod is one example, or you could use protobufs. Fundamentally, this is an issue with any programming language. But having your base "struct"-like type be a hashmap leads to more mistakes as it will accept any keys and any values.


I disagree that this is an issue in every language - the problem is that in other languages the validation against some schema is more or less required for unmarshalling, and it's optional in TS.

Seeing a deserialization error immediately clues you in that your borders are not safe. Contrast that with TypeScript, where this kind of issue can lead to an insidious downstream runtime issue that might seem completely unrelated. This second scenario is very rare in other languages.


I don't know Rust, and I'm genuinely curious: How does it improve over that problem?

When you call a REST API (or SQL query for that matter), how does it ensure that the data coming back matches the types?

TS allows you to do parse the JSON, cast it into your target type, done (hiding correctness bugs, unless using runtime verification of the object shape, see sibling comment). Does Rust enforce this?


It validates the object shape at runtime, much like you can do in Typescript with a library like Zod. The key difference in this case is that Rust makes it scary to not validate data while Typescript will gladly let you YOLO it and blow your legs off, even in strict mode.


Okay I see, that's a nice secure-by-default point, whereas TS is arguably not secure-by-default.


It’s not. And trying to just be a transformation of the source to JS without its own standard library (mostly, some old stuff doesn’t follow this) means it really isn’t possible with just TS alone.

That’s OK with me. I use TS because I like it and hate the total lack of safety in JS. I have to use JS on the web, so TS it is.

If I don’t need it to run on a webpage, I wouldn’t be writing it in TS. I like other languages more overall.


The worst offender is toString which has different types between objects and is everywhere by default.


What do you mean by "safe" in this context?


If you type correctly at border of your system, then TS will be very close to a formal verification of your code. This won't catch all bugs, but even broad categories for you data is helpful. If you know your input is a non-null string. Then it will warn you of every non string usage. It won't catch whether it's a name or an email, but knowing someone tries to divide it by zero is helpful.


It's a lot more effort, but branded types for conceptual differences can bridge that last gap


Typescript doesn't even support notions like "unsigned integer". It is not a serious attempt at type-safety; its main claim to fame is "better than raw Javascript" which is not saying much.


If you need to run in a JS environment it’s a hell of a lot. It’s a FANTASTIC improvement.

I wouldn’t use it server side or for a client application that doesn’t run in a web browser. That’s not its place, for me.

But I will 100% reach for it every time if I need to run in a JavaScript environment.


TS actually works very well as an HTTP server, I’d say better than typed Python. Plain JS… a minute of silence, please.


I’ve never been a JS on the server person, I was used to other languages when that was developed.

Well I think I would prefer python, but simply because it’s “more traditional“ and I realize that’s specious reasoning, I prefer to use strongly typed languages whenever possible.

I would generally reach for Java since it’s the language I’m most proficient in due to my career. There’s also Go, which I played with long ago, or maybe I’d try Rust.

This is only for anything important. If I was just toying with something locally I’d probably do whatever was fastest. In that case Python or JS might be my choice for a very tiny script.


I'm sure most would stay at valve if they could. The just do so much contract work, and I'm sure a stable job at intel is better pay, benefits and stability.


F# seems really awesome. Used it briefly for an internal tool. Are you at a startup working with it?


I am working at a 2k fte company and we use F# for a lot, its very nice to work with, prefer Rider over Visual Studio though.


Similar for us in magnitude of sized company, maybe a bit bigger. Lots of services are F# (internal and main services), but we don't advertise it that much nor want to. Every time we consider switching (even to C#) the developers want to switch back even though C# is a fine language. Its not perfect, but its enjoyable to code in all the same. At this point the stack is battle tested.


Are you on (or would you mind adding your company to) the F# companies list?

https://github.com/fsprojects/fsharp-companies


Highly disagree. The commissary on most military bases are awesome. Spent most of my life going there with my parents. Not sure where you heard they were bad. Never got that impression from any military serving people, like ever.


Now imagine how the commissary would turn out if instead of being placed in a spot where any commercial business would love to exploit (center of military base where every family has employment, a process for permanently kicking out people who engage in major crime, and private competition controlled unless you go through a security checkpoint) -- instead you put them in many of the places I witnessed food deserts in major US cities that had underemployment, elevated crime, outsiders afraid to enter during the day and ~never enter at night, bars on every window, and every other establishment has you slide your cash in a rotating tray adjacent to a bulletproof window.


I feel like the commissary these days is really far behind private grocers. Yeah, 15 or 25 years ago they were awesome, but now it just resembles a poorly stocked (and much smaller) Walmart. Regional grocers have gotten really good in my lifetime. Used to go to the commissary regularly to save money and have a good selection, but those days are just long past. Same deal with base liquor stores, they are merely "OK", but again your regional private option is just so much nicer in the 2020s.


I stopped using eza and lsd in favor of aliasing nushell's ls command.

I guess it's not worth the entire dependency of nushell if you don't see yourself ever dabbling with it in other ways (you should it's sick).

Also I'd add to your list zoxide

I've aliased cat to bat, cd to zoxide, and ls to nushell ls with zero issues.


I've started writing all of my scripts in nushell (unless It's critical that they keep working long-term without maintenance). It's incredible, and improving fast.


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

Search: