At least Rust has a chance to be largely correct because it has much greater effort per amount of code (in the compiler) invested into it than most any application code.
Java's byte code verification algorithm had a proof. This was important for running untrusted java in the browser. If it said the byte code was ok, it was.
Turns out, nobody made a proof for the verifier actually finishing. So it could return true, or false, or run longer than the universe has time. So around Java 6(?), someone wrote some bytecode that basically took forever to validate, DOSing the validator. Sun had to change the file format and add extra information to get the guarantees back.
Not the grandparent you were replying to, but from the note added to the original linked issue (emphasis mine):
> Rust's type system is *intended to prevent memory unsafety. Upholding this promise is something we take very seriously*, .... It is a large priority of the Types Team to *fix all type system unsoundnesses* and to work towards there being a solid foundation to minimize the risk of unknown ones.
So, yes, if you have a group who "takes very seriously" the job to "fix all type system unsoundness", I would expect them to utilize some manner of formal proof verification that their type system is mathematically correct up to some defined limit.
That work is ongoing even if the RustBelt project ended. It's been a / the major focus of Ralf Jung's work for over 10 years and he's an assistant professor at ETH Zürich now, still working on it. https://www.ralfj.de/blog/categories/research.html
I wouldn’t say so… I consistently choose Rust mainly because it’s a sanely designed modern C++ alternative. It’s 20% more effort than writing Python or Typescript, and you get to use the full power of your hardware without compromise.
Safety is a nice side-benefit. The main reason why I like the safety is because it allows you to fearlessly write high-level code without being constantly paranoid about memory as in C++. It’s more about enabling ergonomics without loosing performance, rather than security or correctness.
> It’s 20% more effort than writing Python or Typescript
I'd disagree with this point, there is more typing involved with a first draft of code than Python or Typescript, that's certainly true, but if we bring all the tools (e.g. docblock comments for "type declaration") that are habitual to make up for the shortcomings in most developer's minds then that gap shrinks and, imo, ends up swapping. It's cheaper to have automatically enforced and consistently maintained checks than moving that information out of band and the resulting code in a strictly typed and memory enforced language ends up removing a significant cognitive overhead when reading and maintaining the code.
I have a strong aversion to boilerplate code so it's important to try and allow terse expressions when possible - but unstated assumptions are worse than overstated assumptions.
Most things like "sanely" and "20%" are pretty subjective. To me writing (or really reading well written) Nim (https://nim-lang.org) is less effort than writing Python or Typescript. Nim is mostly Ada & Lisp ideas packaged in a more terse & flexible surface syntax. Nim also has nice compile-time introspection and very low effort macros to allow packaging near zero-code APIs like github.com/c-blake/cligen. Also, something like 5 out of 5 times I've investigated some Rust alternative to some Nim code, the Rust ran more slowly than my Nim on my tested CPUs.
With access to inline asm, all speed is ultimately more a measure of effort applied than PLang. So those perf ideas are just "with my level of effort". Even Python via Cython has pretty direct access to asm. The "do it in pure X" that Sun popularized (even in a meta-/cross-PLang-sense) as a business attempt to define Java virtual machines as The platform has had many casualties, not the least of which is the quality of discussion of PLang practicalities, not just on HN, but everywhere.
I have heard great things about Nim, you may be very right. It’s just that it’s impossible to ignore the benefits of a mainstream dependency ecosystem. The ecosystem is exactly what made Python and Javascript the giants they are today, despite being somewhat mediocre languages. And the Rust ecosystem is in that same league, without giving up exceptional performance, and without giving up too much ergonomics.
PS: I was very enthusiastic about Cython for a good while and I went deep into it, but I found that it is rather a mess to use in practice. Yes you get C performance within Python, kinda, but you also get all the C footguns, amplified by the complex interactions with Python features.
Yeah. Other ecosystems are undeniably larger than Nim's. I keep hearing about how LLMs are going to nullify that advantage with "not so sloppy" ports of anything to any PLang, but I've yet to see that pattern materialize. "What is a clean interface" is probably a kind of subjective judgement call, but also very clearly depends on PLangs and even PLang cultures. For example, the microdependency culture of Rust/JS/Node have very little to do with the PLang's themselves.
EDIT: With Cython how I mostly kept things organized was the "caller allocation" so common in C where memory was always managed the usual mostly refcounting way of CPython/NumPy, but I had dozens (maybe even 100) little "kernels" I could pass that memory into that could even use Intel/MSFT "intrinsic" asm calls (things like immintrin.h) or even just #include C code which did similar. It didn't seem too bad to me, but Nim always seemed a more complete solution (at the PLang level - not counting ecosys). (And these days there is even NimPy (https://github.com/yglukhov/nimpy) to write low-level speed-up code for Python in Nim.)
This is misinformation. There is (at least!): `method`, procedurally typed fields (inside case-object variants or not), run-time keyed `Table` with proc values, {.dynlib.}, importc/importcpp things. Beyond that, yes, Nim has rare compile-time superpowers that do lead many of its proponents to use static constructs (totally grant that!). So, you may not see a lot of dynamic dispatch in code bases, but there is little stopping you from using them in your own code.
Ah, yes, I should have been more precise. It doesn't have an equivalent of an interface/trait/protocol with dynamic dispatch.
Yes, you can pass around an object of procedures, but that is awkward, doesn't have any support from the language or stdlib, and from what I can tell isn't a normal thing that is done.
I think you & I are really back & forth-ing "the PLang not enforcing/strongly encouraging a very specific way of doing things that a whole ecosystem/community organizes around". Relying instead on self-organization has many pros & cons, to be sure. Lisp suffered much the same "until" Common Lisp (which still leaves many things open). My tag line lately is: delegation affords so much, but trust sure is tricky. Much of the time people seem to discount the often rather large cost of establishing/maintaining trust. (I'm not saying you are - just that it's an easy thing to do. I think it's why there is this is a big megathread on "trusting rust", even though "rust" is a veritable suffix of "trust". Lol.)
The paranoia about memory use in C++ should mostly be a thing of the past if you’re using smart pointers and sane patterns. In 2026 almost nobody should be calling new and delete and passing around raw pointers.
The reality though it many people are not using smart pointers. I have seen many people argue they don't like them because they want to see every place delete is called. (meanwhile of course they never notice all the places it should be called but isn't - but at least where it is they see it)
It's more than that. Smart pointer help, but there are cases where even when using smart pointers you can encounter memory safety issues. Especially when you need to interact with c or older c++ code that doesn't use smart pointers. And smart pointers don't provide any protection against data races in multi-threaded code, like rust does.
And yet applications written in modern C++ are constantly discovering new memory safety issues. Sean Baxter wrote a whole manifesto talking about the shortcomings of the existing C++ model [0].
The problem with manefestos is they often harp on small parts that don't matter much in the big picture. There are real shortcoming of the C++ model, but if you use modern C++ they are rare.
The real shortcoming it is very common for people to not write modern C++. I know several C++ developers who refuse to use smart pointers because they don't like magic happening.
It's not enough for memory safety issues to be "rare". To meet your obligations under the standard and have defined behavior (i.e. rust's basic guarantee), memory safety issues can't exist at all.
Ah, so this article invalidates all of the safety guarantees of rust? Since one hole was found the entire boat is shot and should be left at the bottom of the harbor?
C++ has a terrible reputation which is well associated with, say C++98, if you have a good linter you can bop people on the head for using news anywhere outside a few limited locations where you consider it warranted. All working environments have language features or even programming paradigms that are considered detrimental to code ecosystem health and fighting against these is an organizational lift when working in any programming language. Full type security doesn't mean someone can't create an overly generic object and just start breaking code contracts across the code base. C++ has an awful lot of footguns and more warts than most but it can be made to be sane for development and the new language features really bring it on par with other modern languages.
I have worked in C++ (primarily within the Qt framework which pushed hard into const refs instead of pointers) and it's fine. I've also worked in PHP which can also be fine. Rust isn't something I've worked at scale in but it certainly is very attractive if I ever jump to an org working in it - but even in Rust you'll want to restrict style divergence and bad patterns with linting.
The answer depends on how foo() is implemented. You can't reason about it locally, and strictly speaking it's not possible to determine at compile time. Now, I should be declaring this gsl::not_null<std::unique_ptr<int>> to comply with the core guidelines, but I think we can agree that optional support libraries aren't relevant to this discussion.
That's trivially untrue. Nothing about turing machines or lambda calculus requires temporal unsafety. Even this example wouldn't exist if the compiler rejected covariant lifetimes. You already know this of course, so I'm not going to keep beating that dead horse.
The obvious follow-up is to find a minimal set of rules that allow us to express what we want without permitting temporal unsafety. The borrow checker is one set of fairly minimal rules that works pretty damn well. Alternatively you could define away the unsafety by giving it semantics, like fil-C does.
C++ still doesn't have a sane modern pattern for tagged unions. If you want to define a type to represent, say, a simple parse tree, then Rust makes that easy and obvious, whereas C++ offers you a hundred options, all of which suck.
I take your point about it being the default, but IMO std::variant is pretty much unusable for a parse tree. It could work for small unions that you visit once in a while, but traversing a nested tree of std::variant types is just a disaster. It somehow manages to be comprehensively worse than using manually tagged unions in all aspects except safety.
Idk, it also has a nicely expressive typesystem outside of lifetimes, a lot of modern syntactic features like pattern matching and monadic error handling, well-written compiler error messages, a well-designed standard library, and substantially less accrued cruft when compared to its largest competitor. Safety might be the cudgel its evangelists like to beat everyone over the head with, but there are certainly things to recommend it outside of that.
Rust has a lot of things that make it nice to write in. Robust enums and pattern matching are something I miss greatly when I’m back in C++. The trait inheritance system is also very flexible and I miss that. Especially compared to monstrosities like multiple inheritance.
Neither C++ nor Rust is zero cost in many cases. Rust needs unsafe or expensive runtime primitives for doubly linked lists, an lru cache, a tree with parent pointers...
Both patch the language gaps with libraries.
Love the energy, but I can hardly believe the title "Proven Metals" because your website does not stand up to basic scrutiny:
1) First issue: I do not know what your manufacturing constraints are for PCBs...the number of layers is not documented. I don't even know if you support FlexPCBs.
2) I suppose I could figure out if you could make my boards in seven days if I played your upload game...but I should have to do that. Even the following site, with its clunky UI, makes it more clear what they can or can't do:
https://quickturnpcb.co.kr/
3) You say you ship "tested" boards, but what does that mean? Firmware testing? Emissions testing? If you ultimately choose the MPNs, does that mean you own the failures if the board doesn't come up?
4) It's not clear if you accept consigned parts. It's not even clear if you are properly storing the parts you are kitting with respect MSL, ESD, etc.
5) In the end, what makes you any different from a typical broker like Millenium Circuits Limited? (Not that I am endorsing them, as I have had terrible experience from them as well)
6) If you are owning testing and promising quick turnarounds, I would assume you are actually shipping test fixtures to the CM before they ship so they can rework if necessary. But again unclear from your description
1) Well noted, we are working on fixing that
2) Agreed, fixed with 1)
3) We should be more clear about testing. We offer a range of tests (in house x-ray, functional, bring-up) that we should show more clearly.
4) This will be made more clear on the site
5) We don't aim to be a broker in the end. We aim to own the whole stack. This is how we start.
6) True, we do in-house testing and rework, which should be more clear on the site.
I looked at your site again and see you made changes.
Stop working so fast, it's actually hurting your presentation pretty badly.
I see "We make PCBs fast". I suppose it may mean something to the layman, but to me it just means you do what 4PCB does, except not in 24 hrs like they do. But never mind about determining turn time. When I click that I only see a single time listed (5 days). But if I look at the top of the screen I see another turn time of 7 days.
Just stop working on this site for 3-4 days and get your mission statement together. Maybe put some pictures of actual test fixtures if you test boards or any of your rework equipment. Every PCB/PCBA shop out there puts rework videos on its 'gram. It's just really hard to understand your business with this edgy/terse hustler kind of talk. Or your careers page where I get the sense that move fast and break things is the backend philosophy. Not a good look for someone who wants PCBs fast.
I so want this to work but holy cow I can't even understand where you guys are coming from.
I run in LAN/Developer Mode on the X1C and P1S and I sync filaments just fine. I don't monitor my prints with my phone but if I wanted to I wouldn't complain about the lack of Bambu support on the DEVELOPER MODE! I think the clear call to action here is to DEVELOP your own software.
Depends on the quality of the solder joint.
Poor quality solder joints do not survive mechanical shock.
If you are fighting a GND pin that sinks a lot of heat, using leadfree solder and you aren't that skilled...don't trim that lead flush with the PCB.
Otherwise, if you are sure that the solder has wicked into the hole, trim away.
So if someone is telling you not to trim the lead...I'll let you draw your own conclusion.
Pipes and named FIFOs are easy and great. I say this after implementing various IPC methods (unix domain sockets with fd passing, POSIX message queues, 0MQ, XML RPC, local TCP sockets, just to name a few). Use a simple line oriented protocol. If you are passing complex data through your IPC, you know it's time for files. Shared memory is another way to do IPC but hopefully you have robust method of detecting the liveliness of your local processes and you want to give up the Unix file paradigm.
Apparently you didn't bother to fully read their comment, or even look at the page. It is a subtracted sphere, meaning it could be any shape contained within a sphere, and the one in question has features that give axes, and to me eye appears to have a strange axial rotation
As a matter of fact I even put my finger up to the screen to verify that the edges were not in any way wobbling. The subtracted shape is a gyroid, which in no way has natural axes, so I beg your forgiveness for still not understanding the question.
I think you are referring to first video on home page while other two are talking about first video on examples page. That example has CSG operations on solids that share the vertical axis so the resulting shape should not wobble.
Yes, wrong side of the bed, I usually sleep on the left, but I definitely was on the right side that day, not that it's pertinent.
I meant what I said, that it appeared that you hadn't bothered to read the page, or to fully read the comment. Your question is talking about a sphere (which can, btw, be rotated "off axis"), while the original comment was indicating one of the subtracted spheres from the page. Any of those subtracted spheres could be rotated off axis. So either you were ignoring a pertinent part of the original comment, or hadn't bothered to look at the subjects that comment was directed towards (either of these scenarios would violate HN guidelines).
Off-axis rotation could mean many things in the context of the original comment, as is pointed out by other responses to your first comment. While it's true that a gyroid has no planar natural axes (by design), a gyroid can have many natural axes, depending on the space it is modelled in and the criteria for axis selection. For example, an axis can be found in the radial symmetry about the center of mass of a gyroid, in an infinite number of planes.
A sphere can also be rotated off axis. If the axis of rotation is not projected across the center of mass of the sphere (rotation would be different than the infinite number of natural axes going through center of mass) is one way. Another way would be if the axis of rotation tended toward one of the COM natural axes at both ends, but was non-linear. Another off axis rotation would be if the axis of rotation was the natural axis, but was not co-planar with the rotation of the viewing axis, which would make it appear to wobble.
>Apparently you didn't bother to fully read their comment, or even look at the page.
Was there a need for this attitude (which, by the way, violates HN guidelines)?
I was looking, not unreasonably, at the linked page. I see that indeed the first example on the "Examples" page exhibits this wobble - thanks to user jmiskovic who was actually helpful.
I'll direct you to my second response to you, where I point out why it appeared from what you wrote that you either hadn't read the original comment fully, or had not examined the subject of that comment. I believe pointing this out was not a violation of HN guidelines, while your negative attitude in multiple comments since then is most definitely in violation.
As far as being helpful, I don't think your first comment falls into that category either.
I'd argue that an invalid string concept would be neither correct nor efficient. Why should all code that deals with strings carry the burden of fallibility of a subset of string functions?
You've mentioned NaN propagation in another comment and I think that's a perfect example of the problem with this approach. Sorting a vector of arbitrary floats is a notoriously thorny problem because any float could be NaN, and as NaN is incomparable to any other float, there is no total ordering of floats. There is no general solution to this problem that doesn't involve making assumptions that could be faulty for some applications.
Please support your argument against correctness by providing an example where an INVALID string as input to a suitable modified generic string function would result in a valid string.
I would expect an invalid string to have an invalid length. For integer-valued lengths you'd have to use a negative number to differentiate from a valid, empty string. But then the sum of the invalid-string lengths differs from the length of the concatenated invalid strings. Which is wonky.
Safe string manipulation never exceeds the bounds of the buffer. So negative values are dangerous, as all as any additions that would exceed the maximum size.
Negative lengths are not compatible with unsigned representation.
A system implementing invalid string values must choose a text encoding such as UTF-8 that supports the concept of an invalid character. Null termination is too flexible. As such is simple length prepending.
I don't understand the fallibility.
Clearly misuse of string functions is epidemic.
A propagating INVALID string result makes it very clear there is a logic error and not an exploit.
I understand how one could shoot down implementations, but none has made a convincing argument about shooting down the idea.
I wouldn't prefer one more special case to test against (empty string / null string / 'invalid' string). Why can't those operations just return error codes instead? How about memcpy if you try to memcpy into a buffer that's too small - it writes an 'invalid buffer' type instead?
”This would be the result of trying to copy a string to a buffer that is too small.”
C doesn’t have the notion of “size of buffer” (yes, arrays have a size that can be queried by sizeof, but only at compile time). You would have to fix that, first.
NULL is the lack of any string.
If one view a string as a result of an operation, then an INVALID string is the consequence of bad input to an operation.
If you have studied Computer Science, you should know that the null string is quite a valid string.
Let's take strstr, which finds a matching substring needle in a haystack string.
-returns a NULL string if the needle is not in the haystack.
-returns pointer to first matching substring.
Extend strstr with VALIDITY
Understood behaviour if both are valid.
Say the haystack is INVALID...as the return value is NULL or a strict substring of haystack, should return INVALID. A poison haystack should poison dependent strings.
Say the haystack is valid but the needle is INVALID...should return NULL. A valid string never contains an INVALID string as a subsequence.
I tried really hard to find a main() function browsing the demo source code, but I could not. I also find it interesting that code boilerplating is called out as a problem, but I run into code like this:
Choose the size representation that bests fits your use case:
// Put this in header to help user calculate allocation needs but hide size from user
size_t LIBNAME_alloc_size(param1, param2, ...);
// Put this in the header to hide the size from user code but allow inlined size calculations
extern const size_t LIBNAME_ALLOC_X;
// Put this in the header to make size known to user (for static const allocation)
#define LIBNAME_ALLOC_Y ((size_t)42)