• 0 Posts
  • 85 Comments
Joined 1 year ago
cake
Cake day: June 17th, 2023

help-circle

  • Why do we need tests to be understandable by any human. IMO tests that go to that degree do so by obscuring what logic is actually running and make it harder as a developer to fully understand what is going on. I would rather just keep tests plain and simple with as few abstractions around them as possible.

    Cypress cy.get(‘h1’).contains(‘Result’)
    Playwright await expect(page.getByTitle(‘Result’)).toHaveCount(1)
    Testing library expect(screen.getByTitle(/Result/i)).toBeTruthy()

    We can nit pick about syntax here and I prefer the cypress one as it immediately tells me what it is doing and I am not even familiar with those frameworks but:

    UUV Then I should see a title named “Result”

    That tells me nothing about what it is actually doing. How is the framework meant to interpret that or similar things? It is imprecise and I have no way to validate it will do what I expect it should. I do not trust AI or LLMs enough to translate that into a workable test. Even if it works for simple situations like this how does it grow to far more real and complex test cases?

    It would be one thing to use a LLM to generate a test for you that you can inspect - but to generate it probably on every run quite likely without being able to see what it did? Um No thanks. Not with the current state of LLMs.

    At least I assume it is LLM based as there is no other way to do this as far as I am aware, though they dont seem to mention it at all.


  • I am not convinced by this argument TBH. The one use case they come up with is testing APIs exposed through the FFI. APIs that need to be written in such a way as to avoid RAII as C does not support that. Their use case is testing and that is the only use case I can see that makes this valid - but TBH I don’t really see the value of adding defer as a language feature for testing FFI APIs. Any leaked data will be cleaned up at the end of the test suite and I would never use such APIs in production rust code without wrapping them in a RAII abstraction. Any other uses of such an API I would expect to happen in other languages where a rust defer feature wont help at all.

    I am not a huge fan of the defer feature overall. It is error prone and easy to forget to use. With RAII the compiler deals with all that so you don’t have to. I have seen far too many memory leaks in prod in go where someone has forgotten a defer foo.Close() and it is not obvious at all when they have done that. Even flagged a few times where it looked like it was needed (like with things that are constructed with a Open(...) but that didn’t have a Close method… It just makes code reviews harder than when you can rely on RAII IMO.

    This feels like wanting a feature to code in a non-rust style for those not used to the language which I really don’t want to encourage.

    Hmm, ok… So I guess the only way to not trigger Undefined Behavior on the C side when freeing, would be to keep the capacity of the Vec around and do:

    if (capacity > 0) {
       free(foos);
    }
    

    Let’s ignore for now that this will surprise every C developer out there that have been doing if (NULL != ptr) free(ptr) for 50 years now.

    That is not the only way, you can in the rust code return a null pointer when the Vecs capacity in 0 which will give you the behavior C developers are used to.

    And I think generally their problem with needing to keep track of cap and length is due to Vec not being equivalent to a C array. If you want a C array then use a array or boxed slice instead of a Vec. The big problem here is not that C developers are not used to caring about capacity - but that they are not used to having to care about the difference between length and capacity. Instead the just call capacity ‘length’ and allocated/deallocate based on that. So the ‘length’ in a Vec is not the ‘length’ they typically deal with.




  • Of these 25 reasons, most apply to a lot of languages and are far from Java exclusive or even java strong points. Pick any mainstream language and you will hit most of the benefits it lists here. With quite a few being almost meaningless. Like this:

    Java/JVM/JIT can achieve runtime optimization on frequently run code, especially on something that’s running as a service so that you avoid the overheads from JVM startup times.

    Compiled languages generally don’t need a JIT or to be optimized at runtime as they are compiled and optimized at compile time. And most language that don’t have a runtime like Javas already run faster than Java without its heavy startup time. Language with JITs are generally interpreted languages which have these same benefits as java lists here. Though do often suffer from other performance issues. But really at the end of the day all that really matters is how fast the language is and how good its startup times are. Java is not ahead of the pack in either of these regards and does not do significantly better then other languages in its same class (and often still drastically sucks for startup time).

    Or

    Much of a company’s framework can be stable Java, with Scala or Clojure-backed business logic.

    Many languages you can embed other languages inside. Nothing really special about scala or clojure here except that they work well with java. And I don’t really see this as a major benefit as most places I see dont separate their core code and business logic into different languages.

    And the remaining issues that are more java specific are:

    Java was one of the first mainstream GC strongly typed OOP languages. So it got its niche.

    Java has been one of the main programming languages taught in colleges and universities in the last few decades.

    Java’s Legacy Migration: Many banks in particular migrated legacy systems to Java in the early 2000’s when it was getting a lot of popularity and the industry was collectively in the midst of a huge OOP fever dream.

    Which all paint a picture - it was popular long ago and taught in universities and lots of business pushed it when back in the day. And now it is hard to move off it.

    And lastly:

    Oracle

    What? How is this a point? If anything this should be a massive negative.

    Not exactly 25 reasons to pick java in financial enterprise.


  • It might. Depending on how much tension there is. Too much and it will cause the filament to slip in the extruder causing under extrusion. If you are not seeing signs of under extrusion then you are fine for now - but that might change if you change filament or anything else. I would try to lower how much tension the filament is under to avoid problems in the future. Otherwise it would be something to keep in mind if you do start seeing signs of under extrusion.


  • Did you read the article at all?

    “Putting all new code aside, fortunately, neither this document nor the U.S. government is calling for an immediate migration from C/C++ to Rust — as but one example,” he said. “CISA’s Secure by Design document recognizes that software maintainers simply cannot migrate their code bases en masse like that.”

    Companies have until January 1, 2026, to create memory safety roadmaps.

    All they are asking for by that date is a roadmap for dealing with memory safety issues, not rewrite everything.




  • You could do a lot of things. Rust had a gc and it was removed so they have already explored this area and are very unlikely to do so again unless there is a big need for it that libraries cannot solve. Which I have not seen anyone that actually uses the language a lot see the need for.

    Not like how async was talked about - that required a lot if discussion and tests in libraries before it was added to the language. GC does not have anywhere near as many people pushing for it, the only noise I see is people on the outside thinking it would be nice with no details on how it might work in the language.


  • So someone that is not involved in rust at all and does not seem to like the language thinks it will get a GC at some point? That is not a very credible source for such a statement. Rust is very unlikely to see an official GC anytime soon if ever. There are zero signs it will ever get one. There was a lot of serious talk about it before 1.0 days - but never made it into the language. Similar to green threads which was a feature of the language pre 1.0 days but dropped before the 1.0 release. Rust really wants to have a no required runtime and leans heavy on the zero-cost abstractions for things. Which a GC would impose on the language.


  • There are quite a few places where a GC is just not acceptable. Anything that requires precise timing for one. This includes kernel development, a lot of embedded systems, gaming, high frequency trading and even latency critical web servers. Though you are right that a lot of places a GC is fine to have. But IMO rust adds more than just fast and safe code without a GC - lots of people come to the language for those but stay for the rest of the features it has to offer.

    IMO a big one is the enum support it has and how they can hold values. This opens up a lot of patterns that are just nice to use and one of the biggest things I miss when using other languages. Built with that are Options and Results which are amazing for representing missing values and errors (which is nicer than coding with exceptions IMO). And generally they whole type system leads you towards thinking about the state things can be in and accounting for those states which tends to make it easier to write software with fewer issues in production.


  • but imagine if you have to perform this operation for an unknown amount of runtime values

    This is a poor argument. You dont write code like this in rust. If you can find a situation where it is an actual issue we can discuss things but to just say imagine this is a problem when it very likely is not a problem that can be solved in a better way at all let alone a common one is a very poor argument.

    Typically when you want an escape from lifetimes that means you want shared ownership of data which you can do with an Arc. Cow and LazyLock can also help in situations - but to dismiss all these for some imagined problem is a waste of time. Comes up with a concrete example where it would help. Very likely you would find another way to solve the problem in any realistic situation you can come up with that I would suspect leads to a better overall design for a rust program.

    I would say this is just a straw man argument - but you have not even created a straw man to begin with, just assume that one exists.




  • Creating functions is IMO not the first thing you should do. Giving variables better names or naming temporaries/intermediate steps is often all you really need to do to make things clearer. Creating smaller functions tends to be my last resort and I would avoid it when I can as splitting the code up can make things harder to understand as you have to jump around more often.


  • Comments are not always a waste of time, but comments that repeat or tell you what the code is doing (rather than why) are a waste. For legacy code you generally don’t have comments anyway and the code is hard to read/understand.

    But if you can understand the code enough to write a comment you can likely refactor the code to just make it more readable to start with.

    For code that does not change generally does not need to be read much so does not need comments to describe what it is doing. And again, if you understand it enough to write a comment to explain what it is doing you can refactor it to be readable to begin with. Even for mathematical equations I would either expect the reader to be able to read them or link to documentation that describes what it is in much more detail to name the function enough that the reader can look it up to understand the principals behind it.


  • And they were arguing the same - just renaming the property rather than reusing it. You should only have one not both but naming them differently can make it clear which one you have.

    But here I am arguing to not have either on the user object at all. They are only needed at the start of a request and should never be needed after that point. So no point in attaching them to a user object - just verify the username and password and pass around user object after that without either the password or hash. Not everything needs to be added to a object.


  • Worse, refactors make comments wrong. And there is nothing more annoying then having the comment conflict with the code. Which is right? Is it a bug or did someone just forget to update the comments… The latter is far more common.

    Comments that just repeat the code mean you now have two places to update and keep in sync - a pointless waste of time and confusion.