Live data from Hacker News

A Rust shaped hole

mnvr.in

291–300 of 319 posts

Re: A Rust shaped hole

#291
post #12

Earlier quoted context omitted.

TypeScript is good as a language. You can't generate static binaries out of it (except Docker images) and that itself is a deal breaker.

You can’t? I haven’t used it, but what’s wrong with “deno compile?” https://docs.deno.com/runtime/reference/cli/compile/

You are the fifth person who told me that this can be done but have never used it.

If this compile approach is so awesome why don't devs use it?

Re: A Rust shaped hole

#292
post #94

If they're serious about their criteria they should go with OCaml (or maybe, like, Swift, or any of dozens of languages in that space). (Of course they actually do want Haskell but they probably need to get there gradually)

Doesn't Rust steal a lot from Ocaml?

Kinda sorta yeah. The original implantation was in OCaml, too.

Re: A Rust shaped hole

#293
post #201

Earlier quoted context omitted.

Sounds like electron but for cli

I does indeed bundle it's runtime into the executable, but this is not dissimilar from Go bundling it's gc into every executable. Granted a compiled hello world Go program will be <2mb while a similar compiled Deno program will be more like 70. I imagine many usecases may not have a storage constraint though, and in that case why not?

My problem is running post install step of 100+ npm packages on my machine. Any of those could be malicious.

https://www.sentinelone.com/blog/unseen-threats-in-software-...

Re: A Rust shaped hole

#294
post #229

Earlier quoted context omitted.

You can use runtime ownership structures like ref cells, arcs, etc as well.

Sure. The part that people often complain about is that they have to make these decisions, rather than having a runtime default picked for them by the language.

Isn’t that having your cake and eating it too?

Like if you find the performance penalty acceptable, use an RC, and you have imho a better swift.

Re: A Rust shaped hole

#295
post #80

Earlier quoted context omitted.

Yeah, though when I say that I mean more like I'm surprised the ecosystem itself hasn't matured more. Rust and Go have both built solid ecosystems up from scratch, but it's a shame that OCaml hasn't since it's a nice middle ground between the two.

I really considered one of the BuckleScript/js_of_ocaml languages for my current frontend project, but went with Typescript for basically conservatism/conventionalism reasons. I was already taking some arguably unnecessary technical risks on that project and wasn't sure I could afford more. I agree that I really wish OCaml or something close to it was mainstream.

Sounds like a lot of people here are promoting Swift, which IIUC has some roots in OCaml. I have a mac now; maybe I'll finally give it a try.

Re: A Rust shaped hole

#296
post #229

Earlier quoted context omitted.

Sure. The part that people often complain about is that they have to make these decisions, rather than having a runtime default picked for them by the language.

Isn’t that having your cake and eating it too? Like if you find the performance penalty acceptable, use an RC, and you have imho a better swift.

I agree!

As an Objective-C veteran, I feel a lot of people overthink these decisions. You can write highly performant applications with prevalent reference counting, and Rust lets you optimize where it actually counts.

Re: A Rust shaped hole

#297

Earlier quoted context omitted.

Promise is not T and Typescript's type system will catch that in most cases with a simple type assertion (add a type to the function return; add a `satisfies` check somewhere). If it isn't catching it often enough, without a lot more extra type assertions, you may be missing a Typescript strict flag like noImplicitAny. (In general I find that I prefer the full `"strict": true` in the compilerOptions of tsconfig.json…

Yeah, the codebase in question was using an “insert into db but do not check result and let exceptions inform” pattern. It was probably transformed from JS at some point which is why it used Knex I must guess. So I suppose I should have found some condition to force use of return values and then unleashed Claude code to fix up linting errors. It’s rarely a GetX resulting in a Promise that’s mismatched and more an ins…

Yeah, that's about the point where I would have started mandating every insert be awaited and not just "fire and forget" (or "let the unhandled promise rejection handler sort it out"). Take the linter's advice there and do it everywhere. Would solve a lot more timing heisenbugs and race condition uncertainty, in my experience.

Also yes, eslint is quite slow on larger codebases, but getting faster.

I've more and more using `deno lint` which is similar to oxlint (also Rust based, also trying to be more or less similar to eslint with certain "presets" available) because I mostly like its typescript "required" opinions (I don't configure it much beyond its out of the box configuration). You can use `deno lint` just fine even if you aren't using deno as a runtime.

I think if I was working on a production Node app with a large codebase right now I'd consider `deno lint` or `oxide` as first pass in the inner developer loop and `eslint` configured with the same presets as a CI-mostly second pass.

Re: A Rust shaped hole

#298
post #252

Earlier quoted context omitted.

To be fair, the formal document isn't for language users, it's for compiler implementors. Rust doesn't have a formal document for other reasons, mainly that there is one main Rust compiler, as opposed to C or C++ where there are dozens that all need to agree on behavior.

People over-index on "formal" here, the Rust reference and Ferrocene (which will end up being adopted as the official spec) is just as "formal" as the C++ specification. There are other compilers in development, and they're able to coordinate with these documents. There is of course always more work to do, but it's really not as far away as some people believe.

It’s not even close to as formal as the C++ specification because only one of them is an ISO standard, or more generally, an international standard.

US corporations have massive influence over Rust since they bought seats on the board. Speaking of the board, it seems to me it’s all US based.

The company working on the official spec is a Berlin LLC.

Re: A Rust shaped hole

#299
post #140

Earlier quoted context omitted.

> I can't quite see how this works in Rust... You won't understand it unless refactor some Rust programs. Bunny summed it up rather well. He said in most languages, when pull on some thread, you end disappearing into a knot and you're changes are just creating a bigger knot. In Rust, when pull on a thread, the language tells you where it leads. Creating a bigger knot generally leads to compile errors. Actually he did…

I only have limited experience with Rust (only playing around a bit). But it seems the language forces you to structure the code in a specific way (and you seem to agree). This is good, because it prevents you from making a mess (at some level at least). But what others report (and it matches my limited experience) is that it makes the structure of the code very rigid. So I do not quite see how this does not limit re…

> So I do not quite see how this does not limit refactoring?

Yes it limits refactoring. But all languages provide syntactic and semantic constraints you must operate within. You can't just add line noise to a C program and expect it to compile.

So your complaint isn't that there are limits, it's that there is less of them in C, so it's easier to make changes in C without putting too much thought into it. That is absolutely correct. It's also true that's is far easier to introduce a bug in C code when you refactor than it is in Rust, and that's so because it's harder to write buggy code in Rust that gets past the compiler.

Perhaps an example. Consider:

    inline char foo(uint8_t i, char a[]) { return *(a + 1); }
What does this code do? In C or C++, it's impossible to answer. If i overflows, it's UB. If you go past the end of the array, it's UB. Since it's inlined, there is no way to know if either could happen. If compiler can prove some particular instance is UB, it can do whatever it damned well pleases, without informing the poor programmer. There are lots of worse examples, particularly in C++.

In Rust, it's entirely predictable what happens for any given input, as Rust forbids UB in safe code. But in order to pull that off, Rust forces you to re-write the above function, perhaps into something like this:

    fn foo(i: u8, a: &[u8]) -> u8 { a[(i + 1) as usize] }
or:

    fn foo(i: u8, a: &str) -> char { a.chars().skip((i as usize) + 1).next().unwrap() }
or many other variations depending what you actually need to do. Notice for example you where forced to say whether you're happy with incrementing 255 to 256. If you weren't, you would write it as (i + 1) as usize.

Yes, it's more mental effort. In return, you don't get your arse handed to you on a platter because you recompiled with a newer, smarter version of the compiler that noticed you violated some language rule only a language lawyer would know, and took advantage of it.

Re: A Rust shaped hole

#300
post #79
post #42

> And the very point of writing a native program in the first place is to make it feel solid. What does that mean, and what is it about native programs (i.e. programs AOT-compiled to machine code) that makes them feel solid? BTW, such programs are often more, not less, sensitive to OS changes. > realizing that I was just spawning complexity that is unrelated to the problem at hand Wait till you use Rust for a while,…

> For me, the benefit of languages with manual memory management is the significantly lower memory footprint (speed is no longer an issue; if you think Haskell and Go are good enough, try Java, which is faster). ... what? Speed is no longer an issue? Haskell and Go? ??? How'd we go from manual memory management languages to Haskell and Go and then somehow to Java? Gotta plug that somehow I guess... It seems to me you…

> How'd we go from manual memory management languages to Haskell and Go

Because that's what's discussed in the article, which discusses Go and Haskell specifically.

> In other words, had the Rust program been designed with the same insane memory allowance in mind as the Java program, it'd wipe the floor with it.

No, it wouldn't (I've worked with C and C++ for almost 30 years - including on embedded and safety-critical hard realtime software - with Java for over 20, and I work on the HotSpot VM). That's because tracing GCs convert memory to speed, but that's not the case for other memory management techniques. To see why, look at a highly simplified view of tracing collectors (modern collectors don't quite work like that, but the idea generalises): When the heap is exhausted, live objects are traced and compacted to the "top" of the heap. I.e. the cost of each collection is only dependent on the working set, i.e. the size of objects that are still live. Because the working set is more-or-less a constant for a given program under a given workload, the larger the heap the less frequent the collections (each of a constant cost), and so the cost of memory management with a tracing collector goes to zero as the heap size grows. There are details in the actual implementations that are worse and others that are better than this idealised description, but the point is that tracing garbage collection is a mechanism that is very effectively converts RAM to speed as its cost scales with the ratio working-set/heap-size. This is not the case for manual memory management or for primitive ref-counting GCs.

Of course, even when memory management is zero, there are still computational costs, but Java compiles to the same machine instructions as C with that kind of work (with some important caveats in certain situations that will soon be gone). It is true that even outside those specific areas, you can, with significant additional effort, get a C program (or a program in any other low-level language) to be faster than a Java program but that's due to the availability of micro-optimisations (that we don't want to offer in Java as to not to complicate the language or make it too dependent on a particular hardware/OS architecture), but that effect isn't large.

Post reply on HN