HN user

branko_d

2,222 karma
Posts50
Comments367
View on HN
www.businessinsider.com 1d ago

Curative ditched a $600k-a-year Salesforce contract after vibecoding a CRM

branko_d
5pts2
spacedaily.com 26d ago

In 1973, eight healthy people feigned a single hallucinatory symptom

branko_d
3pts0
www.pcworld.com 9mo ago

Smart beds began roasting their owners during AWS outage

branko_d
5pts2
hillsboroherald.com 1y ago

Is Intel About to Rewrite the Rules of Chipmaking?

branko_d
3pts0
www.youtube.com 2y ago

JavaScript Visualized – Event Loop, Web APIs, (Micro)Task Queue

branko_d
2pts0
www.technologyreview.com 2y ago

Large language models can do jaw-dropping things. But nobody knows why.

branko_d
65pts36
www.youtube.com 2y ago

Is Your Workplace Toxic?

branko_d
1pts2
thenewstack.io 2y ago

Year-in-Review: 2023 Was a Turning Point for Microservices

branko_d
2pts0
www.youtube.com 2y ago

Dave Cutler: What Successful Programmers Do That Others Don't

branko_d
3pts1
www.businessinsider.com 2y ago

I've witnessed many bad managers – and they almost all had these 4 traits

branko_d
35pts12
www.infoworld.com 2y ago

You can’t run away from technical debt

branko_d
2pts1
www.technologyreview.com 3y ago

The chip patterning machines that will shape computing’s next act

branko_d
1pts0
www.aljazeera.com 3y ago

Russia says US intelligence hacked thousands of iPhones

branko_d
6pts1
awealthofcommonsense.com 3y ago

The Biggest Asset Bubble in History

branko_d
2pts0
www.theregister.com 3y ago

Singapore software vendor says own hardware in colo costs $400M less than cloud

branko_d
205pts197
www.infoworld.com 3y ago

Project Valhalla: A look inside Java’s epic refactor

branko_d
4pts0
arstechnica.com 3y ago

Key Bitcoin developer calls on FBI to recover $3.6M in digital coin

branko_d
4pts0
www.coindesk.com 3y ago

Bitcoin Fails to Produce 1 Block for over an Hour

branko_d
65pts54
www.youtube.com 3y ago

John Carmack: Best Programming Setup and IDE – Lex Fridman Podcast Clips

branko_d
287pts292
archive.fortune.com 4y ago

The risk that won't go away (1994)

branko_d
1pts0
www.madinamerica.com 4y ago

Psychology “incompatible with hypothesis-driven theoretical science”

branko_d
36pts16
www.livescience.com 4y ago

Should we kill every mosquito on Earth?

branko_d
15pts16
yetanotherdevblog.com 4y ago

Understanding LSM trees: What powers write-heavy databases (2020)

branko_d
149pts45
arstechnica.com 4y ago

A domestic newspaper warns of the Russian space program’s “rapid collapse”

branko_d
4pts0
www.buzzfeednews.com 4y ago

A Data Sleuth Challenged a Powerful Covid Scientist. Then He Came After Her

branko_d
22pts0
extranet.who.int 5y ago

Death on the Roads

branko_d
1pts0
techxplore.com 5y ago

DNA databases: New method cuts indexing from weeks to hours, searches to minutes

branko_d
27pts1
www.pressherald.com 5y ago

System failure: Inside Maine’s $35M human resources software meltdown

branko_d
22pts0
jlelliotton.blogspot.com 5y ago

The Economic Value of Rapid Response Time (1982)

branko_d
2pts0
sciencex.com 5y ago

Bell's Theorem Refuted

branko_d
3pts0

In OLTP, it's very difficult to guarantee correctness with triggers (very easy to have a race condition in concurrent environment). On a flip side, materialized views tend to lock more than you'd expect, especially when aggregates are involved.

The sweet spot is if you have a read-mostly database and use SNAPSHOT transaction isolation for the readers (which is SQL Server's implementation of MVCC). That way, writers may still block writers, but writers can never block readers, even when indexed views are being maintained.

Another neat trick is to "abuse" indexed views as multi-table CHECKs. The idea is to make a JOIN that would produce duplicated rows (and fail the indexed view's key) if some multi-table condition is not met.

You can have it in one place without using background sync.

Our application uses classical "foreground update" paradigm, but each API call automatically shows an error to the user and returns him/her to the same place where error originated to fix the input and/or retry. As a bonus, we also automatically show progress indicator for any HTTP request that takes more than 1s (which is rare).

This is as simple as:

    await context.api.explorer.rename(
        {
            objectKey,
            name
        }
    );

    // objectKey: ApiTypes.ObjectKey
    // name: string
The above initiates an HTTP request:

- If that request succeeds, you know that the new name has been durably committed to the database.

- If it fails because the new name is not unique, the user sees the error, and can then enter a different name before retrying. The key is that the UI context is preserved during API failure, so everything the user had entered is still on the screen.

- If it takes more than 1s, the user sees a progress indicator which he/she can click to cancel the operation. This also returns him/her to the original UI.

The magic is in the `rename` itself - it was auto-generated from our back-end API such that it wires into our error reporting and progress UI.

Nvidia RTX Spark 2 months ago

I think a lot of it is down to Windows, not Prism itself.

For decades, Windows made it too easy for games and even some application to install drivers. Windows games use drivers for anti-cheat (and historically for copy protection too). Neither Apple Rosetta nor Microsoft Prism can translate/emulate drivers, but since drivers have been much more prevalent on Windows, now Windows has a much biggest compatibility problem.

Nvidia RTX Spark 2 months ago

Itanium was arguably not superior. The assumption behind it (that the compiler can bring order to the chaos) was wrong, making it slower, more expensive, and less efficient than x86 in real-world scenarios.

From https://kristoff.it/blog/contributor-poker-and-ai/:

"Unfortunately the reality of LLM-based contributions has been mostly negative for us, from an increase in background noise due to worthless drive-by PRs full of hallucinations (that wouldn’t even compile, let alone pass CI), to insane 10 thousand line long first time PRs. In-between we also received plenty of PRs that looked fine on the surface, some of which explicitly claimed to not have made use of LLMs, but where follow-up discussions immediately made it clear that the author was sneakily consulting an LLM and regurgitating its mistake-filled replies to us."

This is just a footnote in the article, but is incredibly important, IMO:

”There’s a risk that codebases begin to surpass human comprehension as a result of more AI in the development process, scaling bug complexity along with (or perhaps faster than) discovery capability. Human-comprehensibility is an essential property to maintain, especially in critical software like browsers and operating systems.”

This aligns with my own experience, and I believe experience of most practitioners in the field: writing a piece of code is just a beginning of a very long journey.

We should be careful about optimizing that first step at the expense of the journey.

The wording "outside of transaction" irks me. Everything in a relational database is done within a transaction, the only question is whether it's the transaction you think it is, or some other.

I believe this is largely an API design problem. Many client APIs (especially ORMs) will start a transaction implicitly for you if you haven't explicitly specified your own, leading to problems like in the article.

Having implicit transactions is just wrong design, IMO. A better-designed API should make transactions very explicit and very visible in the code: if you want to execute a query, you must start a transaction yourself and then query on that transaction supplied as an actual parameter. Implicit transactions should be difficult-to-impossible. We - the programmers - should think about transactions just as we think about querying and manipulating data. Hiding from transactions in the name of "ergonomy" brings more harm than good.

I think this is especially problematic (from Part 4 at https://isolveproblems.substack.com/p/how-microsoft-vaporize...):

"The team had reached a point where it was too risky to make any code refactoring or engineering improvements. I submitted several bug fixes and refactoring, notably using smart pointers, but they were rejected for fear of breaking something."

Once you reach this stage, the only escape is to first cover everything with tests and then meticulously fix bugs, without shipping any new features. This can take a long time, and cannot happen without the full support from the management who do not fully understand the problem nor are incentivized to understand it.

If memory serves, Windows 2000 was the last version where search worked reliably. It was a simple linear search through files which could take a while on larger folders, but was reliable and predictable since it did not rely on a background indexing service which seems to get stale or just plain wrong most of the time.

If I search for “foo”, I’d like to get all files containing “foo” please, without a shadow of a doubt that some files were skipped, including those that I have recently created. I still can’t get that as of Windows 11!

often you have to inject data into new tables or columns

No tool can help you with that, simply because this kind of data migration depends on your particular business logic that the tool has no way of knowing about.

While SQL Server Data Tools has its warts, it has been immensely useful for us in making sure every little detail gets handled during migration. That doesn't usually mean that it can do the entire migration itself - we do the manual adjustments to the base tables that SSDT cannot do on its own, and then let it handle the rest, which in our case is mostly about indexes, views, functions and stored procedures.

After all that, SSDT can compare the resulting database with the "desired" database, and reliably flag any differences, preventing schema drift.

Boolean is rarely enough for real production workloads. You need a 'processing' ... 'retrying'... 'failed' ...

If you have more than 2 states, then just use integer instead or boolean.

Saving a few bytes on the index isn't worth losing that observability.

Not sure why having a few well-known string values is more "observable" than having a few well-known integer values.

Also, it might be worth having better write performance. When PostgreSQL updates a row, it actually creates a new physical row version (for MVCC), so the less it has to copy the better.

Why use string as status, instead of a boolean? That just wastes space for no discernable benefit, especially since the status is indexed. Also, consider turning event_type into an integer if possible, for similar reasons.

Furthermore, why have two indexes with the same leading field (status)?

That's true for seeks into the clustered (primary) index because that index includes all fields, so you don't need to "jump" to the heap to get them.

However, seeking into a secondary index, and then reading a column not included in that index incurs an additional index seek (into the clustered index), which may be somewhat slower than what would happen in a heap-based table.

So there are pros and cons, as usual...

For inserts, you cannot escape writing into the base table and all indexes. However, my understanding is that for updates PostgreSQL has a write amplification problem due to the fact that each time a row is updated this creates a new row (to implement MVCC), and a new physical location in the heap, so all indexes need to be updated to point to the new location, even those not containing the updated columns.

OTOH, with a heap-less (aka. clustered, aka. index organized) table, you would only have to update the indexes containing the columns that are actually being updated. You don't need to touch any other index. Furthermore, only if you are updating a key column would you physically "move" the entry into a different part of the B-tree. If you update an included column (PK columns are automatically "included" in all secondary indexes, even if not explicitly mentioned in the index definition), you can do that in-place, without moving the entry.

Here is how this works in SQL Server - consider the following example:

    CREATE TABLE T (

        ID int,
        NAME nvarchar(255) NOT NULL,
        AMOUNT int NOT NULL,

        CONSTRAINT T_PK PRIMARY KEY (ID)

    );

    GO

    CREATE INDEX T_I1 ON T (NAME);

    GO

    CREATE INDEX T_I2 ON T (AMOUNT);
Now, doing this...
    UPDATE T SET AMOUNT = 42 WHERE ID = 100;
...will only write to T_PK and T_I2, but not T_I1. Furthermore T_PK's entry will not need to be moved to a different place in the B-tree. SQL Server uses row versioning similar to PostgreSQL, so it's conceivable that PostgreSQL could behave similarly to SQL Server if it supported clustered (index-organized) tables.

On the other hand, if the compiler can prove at compile-time what type the object must have at run-time, it can eliminate the dynamic dispatch and effectively re-enable inlining.

Java Decompiler 8 months ago

Is there anything especially hard about decompiling (to) Java?

.NET/C# decompilers are widespread and generally work well (there is one built into Visual Studio nowdays, JetBrains have their own, there were a bunch of stand-alone tools too back in the the day).

Probably because must “emulation” is more like “transpilation” these days - there is a hit up front to translate into native instructions, but they are then cached and repeatedly executed like any other native instructions.

Sure, but the same is true of any error handling strategy.

When you work with exceptions, the key is to assume that every line can throw unless proven otherwise, which in practice means almost all lines of code can throw. Once you adopt that mental model, things get easier.

Safe things should be easy, dangerous things should be hard.

This .unwrap() sounds too easy for what it does, certainly much easier than having an entire try..catch block with an explicit panic. Full disclosure: I don't actually know Rust.

Exceptions force a panic on all errors

What do you mean?

Exceptions do not force panic at all. In most practical situations, an exception unhandled close to where it was thrown will eventually get logged. It's kind of a "local" panic, if you will, that will terminate the specific function, but the rest of the program will remain unaffected. For example, a web server might throw an exception while processing a specific HTTP request, but other HTTP requests are unaffected.

Throwing an exception does not necessarily mean that your program is suddenly in an unsupported state, and therefore does not require terminating the entire program.