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

Yeah, exactly. DCOM was a failure for the same reason that every other RPC thing is a failure. It turns out that introducing cascading failure or partial failure opportunities due to synchronous remote calls was never a good idea. It was always, and still is, treating the fallacies of distributed computing as first principles.


Yes, quite. Unless my function has no side-effects, idempotency will always be my responsibility. This feature is a lie and an outright hazard. It should not be called idempotency and it should have a big bold warning stating that the function may be called more than once.


I'd appreciate it if you could point out how the function can be called more than once. Here's the source code for the orchestrator [1] and a demonstration of it [2].

If there's an error in the source code or the copy, I'll happily retract it.

[1] https://github.com/differentialhq/differential/blob/236ffc53...

[2] https://github.com/differentialhq/differential/blob/236ffc53...


Without looking at the code, I can tell you that this will reproduce one of two things:

1. Invoke function that has two side effects

2. Function does first side effect

3. Pull the computer's plug out of the wall

A framework can only do one of two things:

A. Invoke the function again

B. Not invoke the function again

If you choose A, you have at least once processing

If you choose B, you have at most once processing

Neither of these are exactly once, therefore, neither one of these are idempotent unless the first side effect that the function performs is also idempotent. That is, you must be able to retry that one.

I believe you mention exactly once processing in another comment. It's this. The massive lie that many of these types of frameworks tell is that they can manage idempotence for you. Aside from functions that are side effect free (that is, pure, that is referentially transparent, that is can be made mathematically idempotent) you cannot possibly make them idempotent. It's the two generals problem.

So, I believe what you have implemented is idempotence at the sender with the reservation pattern. This is not the same as idempotence at the processor which is literally the only thing that matters. Idempotence at the sender is simply a performance (or storage, in the case of event sourcing) optimization.

Please correct me if I'm wrong on any of this, but if I am, then clearly my understanding of the two generals problem and distributed systems are wrong and I'm going to have to do some significant rethinking of our system's architecture.


I don't think you're wrong about any of this. I just feel like we're talking over each other. You clearly demonstrate an understanding of the domain, so I'm happy to engage. After all, if we fail, we want to fail fast.

Maybe we can focus the conversation on the scenario you mentioned above.

> Neither of these are exactly once, therefore, neither one of these are idempotent unless the first side effect that the function performs is also idempotent. That is, you must be able to retry that one.

So, what I'm telling is, yes - the first side-effect (or any side-effect) that you put through the system can be made idempotent through the same tooling that makes the caller idempotent.

  func foo(n1) {
    return networkCall(n1)
  }

  func bar(n2) {
    return networkCall(n2)
  }

  func foobar(n1) {
    n2 = foo(n1)
    n3 = bar(n2)
  }

  func main() {
    foobar(42)
  }
Given the above, the framework allows you to wrap foo, and bar all independently in higher order functions which will not issue a duplicative function calls for the same idempotency key. Therefore, you can call foobar repeatedly, and get the same result.


Understood, and perhaps the difference here is more about what I said in my other comment. I don't see this as particularly useful, and I see it as deceptive. What matters is that when we intend to do something is that it happens. We actually want retries. We want exactly-once processing with at-least-once handling. That's the only way that I know of to build resilient systems.

Our back end components literally crash when they fail. No other processing is done. They crash and if there is a bug they will keep crashing. Because our back end components have autonomy, this results in a very narrow service disruption. We fix the issue, identify the root cause and eliminate it. As a result, we have extremely resilient systems that, even in the face of 3rd party downtimes, we can know that every command that gets submitted will be effected. Dead letter queues or anything of the sort are anathema. We try until we succeed. Idempotence is considered in every single handler all the way from the inside to the outside as it must be, mathematically.


I see elsewhere you mention that you use at most once processing. So, I was possibly mistaken that the function can be called more than once assuming you did this right (cleared the job before even invoking the job). My primary point still stands: this is not idempotent, at least not in the way that matters. This is single-try processing. If all you are doing is returning a synchronous error to the user so that they can retry (and again, every other operation leading up to the one that failed to process is actually idempotent) then this would not be catastrophic. The issue is when people start to think that this actually is idempotence, i.e., they attempt to reuse an idempotence key across requests when the first one straight up failed (or not, who knows).

In other words, don't use the idempotence helper if you care about the thing happening. If it's optional, sure, go for it. You could rename it to "tryOnce", or "maybeRun" rather than "idempotence" and it'd be more accurate / less misleading.


> You could rename it to "tryOnce", or "maybeRun" rather than "idempotence" and it'd be more accurate / less misleading.

This is valuable feedback. Thank you.


The problem though is that you're taking the known failure mode interpretation of microservices (what we call a distributed monolith) and making it "easier" by adding significantly more complexity. As many of the other comments here have said, this has been done before. You are repeating the mistakes of DCOM and gussying it up with a modern-looking marketing page.

You demonstrate a lack of understanding of idempotence on your marketing page, which is enough to dismiss your service outright. With all due respect, I'm sure you've put a ton of work into this, and you may even manage to sell it to some teams, but this has been tried and failed so many times in software development's history. It won't be any different now. This is very likely to cause long term harm to any team that adopts it.

For anyone considering it, please make sure you actually understand idempotence and autonomy. Look into event sourcing. Study the fallacies of distributed computing. Check out the work of Udi Dahan and Scott Bellware. Run, do not walk from anything purporting to do the things that this does.


Thanks for the time and effort you put into writing this comment.

> As many of the other comments here have said, this has been done before. You are repeating the mistakes of DCOM and gussying it up with a modern-looking marketing page.

Respectfully disagree, it's not really comparable to DCOM and CORBA. It contains a control plane which is stateful [1]. CORBA does have an ORB [2], which is close, but the specification does not allow for durability.

I do apologise for having a modern looking marketing page.

> You demonstrate a lack of understanding of idempotence on your marketing page, which is enough to dismiss your service outright.

I think we discussed this elsewhere in the thread where I gave you the implementation details that prove the claims of the marketing page.

> With all due respect, I'm sure you've put a ton of work into this, and you may even manage to sell it to some teams, but this has been tried and failed so many times in software development's history. It won't be any different now. This is very likely to cause long term harm to any team that adopts it.

It's actually open-source [4] and self-hostable, so teams don't have to "buy" it. I admire you confidence about this failing, and you might be right. But the reason why this has been tried before in the software development history tells me that the proper abstraction is somewhere out there. If everyone resorted to not trying something that failed before from a new perspective, we probably wouldn't be very successful as a species. Everything is a remix, after all.

> For anyone considering it, please make sure you actually understand idempotence and autonomy. Look into event sourcing. Study the fallacies of distributed computing. Check out the work of Udi Dahan and Scott Bellware. Run, do not walk from anything purporting to do the things that this does.

Wise words, but I'd appreciate it if you could dive into the way things are [1] [3] a little bit, and let me know if you hold the same views.

[1] https://docs.differential.dev/advanced/architecture/

[2] https://www.sciencedirect.com/topics/computer-science/object...

[3] https://docs.differential.dev/getting-started/thinking/

[4] https://github.com/differentialhq/differential/


This would likely require a longer, higher bandwidth conversation than we could or should do in a comment thread. If you're interested, you can join me in the Eventide Slack [4], but I will warn you there's already some discussion about this offering (though, nothing I haven't said here). But, I'm here, so... :)

When I say it's like DCOM/CORBA, I'm referring to the notion of RPC. Specifically, the notion that it's a good idea to perform synchronous remote calls as a matter of course. It significantly reduces autonomy. In my opinion, we should not be encouraging people to build distributed monoliths, even if we can make it look like a regular monolith.

Monolithism is the problem [1] [2], and distributing that monolith only solves technical issues, but not the productivity ones that typically matter more. Distributing them also creates technical issues in terms of latency and cascading failures.

The existence of a control plane doesn't impact my concern about this, but it does add an additional concern. See smart pipes vs. dumb pipes. [3]

> I do apologise for having a modern looking marketing page.

That's not necessary, I wasn't saying that was bad. It looks nice, but if it's marketing something that can be harmful, that would be the problem. Its aesthetics are a differentiating factor. I wasn't trying to say anything more about it than that.

> But the reason why this has been tried before in the software development history tells me that the proper abstraction is somewhere out there.

Maybe, or maybe we don't pay enough attention to our past learnings and the body of knowledge that came before us.

> Wise words, but I'd appreciate it if you could dive into the way things are [1] [3] a little bit, and let me know if you hold the same views.

I read these, and there's nothing that I would consider new, although it is somewhat surprising to read what effectively amounts to the goal being to add network hops and complexity to monolithic code in order to get scaling and other technical benefits.

> Monolithic codebases provide a great developer experience, but resulting monolithic services often do not.

I disagree [5]. They only appear to provide that to teams that don't yet have the skills necessary to do proper partitioning. I believe that teams, and developers in general, will be better served by learning how to do this. They will unlock long term continuity [6] in productivity that they couldn't have imagined.

> Instead of n services talking to n services...

Here's a hint at the fundamental disconnect. Services shouldn't talk to other services. Period. Not if that can be avoided. See: autonomy. This is where pub/sub comes in. When services have autonomy, developers have productivity, and products are more resilient (at the very least).

[1] https://github.com/aaronjensen/software-development/blob/mas...

[2] https://github.com/aaronjensen/software-development/blob/mas...

[3] https://twitter.com/sbellware/status/1760037861347258416

[4] https://eventide-project.org/

[5] https://github.com/aaronjensen/software-development/blob/mas...

[6] https://github.com/aaronjensen/software-development/blob/mas...


Thanks for the invitation and your engagement.

I do disagree with some of your opinions, but I find them interesting and valuable. I've definitely changed my mind about things before, so you might be right on all of these counts - but our experiences might differ enough to have different opinions.

> Here's a hint at the fundamental disconnect. Services shouldn't talk to other services. Period. Not if that can be avoided.

I agree in principle, but I've not been able to see this followed in a large sprawling engineering organisation.

I will definitely join the slack once I have some distance from this. To be honest, I didn't expect this to be posted on HN at this point in the project - and HN can be somewhat merciless :)

Thanks again for engaging with me. You've inspired me to do some changes - especially in how I position the value prop and I learned a lot from reading your references. Much appreciated :)


I too appreciate your engagement. I understand that HN can be merciless, and I do try to be direct, which can sometimes be felt as merciless or harsh. I'm trying to give my unadulterated perspective because I care about the outcomes for the industry as a whole.

And yes, I can imagine it was quite a shock to get this much unexpected feedback all at once. You handled it well, from what I've seen.

> I agree in principle, but I've not been able to see this followed in a large sprawling engineering organisation.

Ours isn't large and sprawling (only around 15 devs) but we managed to build and maintain ~100 back end services and ~20 front end web applications and we're only speeding up as we go. It's possible, but it takes effort and it requires doing things that go against "best practices". [1] It also requires significant cultural and managerial work (see Lean, Steven Spear's work, etc.).

Good luck in your product and learning journey. Hopefully we can connect again down the road. Cheers.

[1] https://github.com/aaronjensen/software-development/blob/mas...


> I understand that HN can be merciless, and I do try to be direct, which can sometimes be felt as merciless or harsh.

I definitely didn't see your engagement this way. I believe you entered the conversation and held your ground with good intentions.


Given that the only comments worth having are typically those that explain why, and an AI would have a hell of a time knowing why code was the way it was, there's very little chance that this does anything but add noise. It's exactly the type of "productivity enhancement" we should expect from AI right now. That is, as long as you measure productivity by lines of code and nothing else that actually matters to the business.


Instead of letting our tools lead us by the nose, what if we let design principles lead us? Why would a styling tool lead me to model my markup? That's the complete inverse of how one should be thinking about it. You model the markup first, you create reusable bits if you need them first. Then you style them. If the CSS forces your hand to change the markup, then you must, but that's becoming more and more rare with modern CSS.

I have no doubt that people that don't know the fundamentals at play have an easier time with Tailwind. That's how it goes with hacks. They're usually easier to apply than proper design and implementation. We're throwing in the towel with Tailwind, plain and simple.


> You model the markup first, you create reusable bits if you need them first.

Agreed, and with Tailwind you never have to leave this fragment of markup you're designing. You don't have to switch files to add CSS and invent meaningful names for styles, then ensure you use the same name in the markup file, nor do you ever have to hunt down and change these names and the markup across multiple files to ensure they are applied consistently down the road of you're using HTML components.

In fact, you rarely have to write CSS at all, you just focus on the markup and sprinkle in the predefined styles that you need. Much simpler.

> We're throwing in the towel with Tailwind, plain and simple.

If by throwing in the towel, you mean we're acknowledging that they took a suboptimal design path, I agree. Transclusion of HTML fragments would have been a much better path to take, and some people were arguing for it even back then (Xanadu folks IIRC). Now we've come full circle, and people are still arguing that decomposition for reuse are not good ways of structuring dynamically changing and evolving content.


For what it's worth, I was exactly where you are 3 years ago. I made all of the same arguments. I saw the value in Tailwind. I had come from rebuilding a CSS system for another application multiple times because we never could get it to work for us.

I would have never believed me now either, not until I saw it done first hand and learned how to do it. So, call it uncommon knowledge, or a rare skill, or whatever you want, but do know that not only is it possible, but the skills required are the same skills that enable you to build maintainable applications -- not just CSS.

In large part, this is why we failed in the past. We would often treat CSS as a second-class citizen and put our most junior "front end" developers on it. It should have been no surprise that it ended up as a tangled mess.

> You don't have to switch files to add CSS and invent meaningful names for styles, then ensure you use the same name in the markup file, nor do you ever have to hunt down and change these names and the markup across multiple files to ensure they are applied consistently down the road of you're using HTML components.

This isn't a real problem. The only time we've struggled to come up with a name is when CSS forces us to use some mechanical name that includes the word "container" or something like that. Usually, we just name the thing what it is. Usually, very often this is in the domain of the UI (hint, it is likely the same name as your React component, if you are using React and naming things well).

There's another problem here that complicates things. Most people shouldn't be using React for their forms over data applications. It's unnecessarily complex, but people now tend to think that server rendered HTML is yet another lost art. React plays very well with Tailwind in a sense, because you are already forced to make components for your UI, so what's sprinkling a little class soup in that file? What's sprinkling a few type declarations in the same file? What's sprinkling a few hooks in that file? What it all adds up to, once you can see it, is very difficult to read and reason about code all in one place. You can learn to see through the forest, but I personally would rather work on one tree at a time.

By the way, I'm not advocating for writing HTML in multiple places (and therefore re-using the CSS classes), that often should be abstracted in some way. In Rails, we use helpers and view template partials. Every technology has its options. Technically, web components fit this bill as well, but we don't make heavy use of them as I've found them unnecessarily complex.


Sure, Tailwind isn't inline styles. Fine. That doesn't make it good. And yes, most CSS is average or below average in implementation. Most software is too. That's just statistics. Tailwind is an attempt to prevent people from recognizing that, like software, CSS requires design and modeling.

It's perfectly possible to have a CSS system that is completely maintainable. It takes skill. That skill can be learned, but it cannot be learned if a person is tricked into relying on rapid-application-development tooling like Tailwind and not taking the time to understand the real problems with their CSS (which is very often special cause variation and/or not taking it seriously enough).

Tailwind doesn't solve anything, it just trades one bad thing (poorly written CSS) for another. I won't list the problems with Tailwind as that's been done plenty. I'm just pointing out the fundamental mistake here.

My experience: The first version of our app used React + Tailwind. When we started to ditch React and use server rendered HTML our React components and their embedded Tailwind were useless. When we wanted to share styles with our emails, they were useless. We had to start from scratch. We now have a plain CSS system (well, SASS) that is very well maintained, has only essential variation, and is used across 20+ web apps (that are all served on the same domain -- the user thinks they are one app).


> It's perfectly possible to have a CSS system that is completely maintainable. It takes skill

Yeah, and people wrote complex games in assembly. The difference is maintainability and if it can be done by more than one people. CSS doesn’t scale across teams/dependencies in its vanilla form in my experience, not at all. It is “spooky action at a distance” almost by definition, often with no way to even control/revert what some deep dependency does.


> CSS doesn’t scale across teams/dependencies in its vanilla form in my experience, not at all.

In your experience. It was my experience too, until it wasn't. See this: https://news.ycombinator.com/item?id=39501442

> often with no way to even control/revert what some deep dependency does

Without looking at specifics, it is hard to say, but it is very likely that this is a design mistake. It's very likely that the person making these mistakes is also making these mistakes in code and creating tangled messes there.

The state of development is quite poor. "Average" (read: most) developers create tangled messes because it's all they know how to do and they've never taken the time to learn how not to do it. So, when something like Tailwind comes along and says "you can't make a mess with this", then of course they will jump on it. They will not, however, be very interested in recognizing the costs that come along with it. They also will be incapable of seeing that the other path is not only simpler, but it can become easier with practice.


I'm a fan of understanding the grittier side of the box-model but I've found that I can't outpace a system designed by a team of engineers to solve the problem of quick and easy layouts and components.

The comment above is definitely a great counter argument to rolling your own CSS from the ground up. I've seen projects with many engineers breaking each other's features because they weren't specific enough with their CSS targeting. The worst part is that sometimes it takes a keen eye to see that something broke in the first place - for example a font is wrong or a div moved etc. It's surprising how many customers don't even raise an issue, they just work around it.

I remember the days when the industry was shifting between Underscore, jQuery, Backbone, Knockout, Ember and React.

React obviously won with its bastardisation of compiled frontends and DOM diffing and Vue recently seems to have caused a stir by giving old paradigms a fresh coat of paint.

After all these years this ecosystem is still in flux...reflux...redux... and no static solution is going to suit every individual or survive indefinitely - the ideal solution seems to be able to adapt to requirements as they come and embrace stack requirements as learning exercises in what does and doesn't work.


Or it's to call to the carpet the people that are enforcing "stack requirements" of tooling that is overly complex for the job.

> I've seen projects with many engineers breaking each other's features because they weren't specific enough with their CSS targeting.

Agreed, and to add to that -- unless a team is willing to stop the line and understand why and how this happened, it will keep happening. Tailwind eliminates classes of problems without requiring people to collaborate or think. That's its "benefit". As I've said elsewhere, it comes with costs, but many of those are subtle (many devs won't have enough experience to observe them) in their short term effects.

> I'm a fan of understanding the grittier side of the box-model but I've found that I can't outpace a system designed by a team of engineers to solve the problem of quick and easy layouts and components.

> I've seen projects with many engineers breaking each other's features...

I don't usually comment on people using "engineer" to describe software developers, but the irony in these statements is a bit much. What is being described is not engineering, it is hacking. It shouldn't be a surprise that when we hack, we break things.


Have you ever tried making your SCSS/CSS codebases not a huge monstrosity? It can be done.


It's not about DRY. It's about modeling. It's about design. It's about being able to look at markup (as a human) and tell what the heck it is. Tailwind soup obscures what things are. How many of your Tailwind-using apps ALSO have meaningful class names and IDs in your markup? How many of you rely on data-test-id or other such hacks to make up for the fact that you are not doing design.

Classes are used to categorize the markup. It's a document model. Model the document. Then, you apply styles to that. It's about design.


> It's a document model. Model the document.

I think this may be the source of many religious wars in frontend land. HTML was originally a document model, but now it does dual duty as a way to block off rectangular sections of application UI.

The purist approach of writing perfectly semantic HTML and placing all presentation in optional, layered style sheets works beautifully - for documents. But I don’t think it works as well when you are designing an interactive UI and you’re really just trying to manipulate pixels on a screen.

Tailwind sure is ugly, but it’s quick to write and a cinch to debug. And in my experience, most UI code is pretty ugly. It seems to come with the territory?


I've also made this argument, but I was wrong. It turns out it's also possible to model a UI. And, it's possible to do that relatively well with HTML. You can see web components or React for contemporary examples of doing this (though no guarantee that the example you look at will be doing it well).

It stands to reason that if it can't be done with HTML, then it can't be done with React, or Swift UI, or anything and we are all doomed. Of course, that's not true.

> Tailwind sure is ugly, but it’s quick to write and a cinch to debug. And in my experience, most UI code is pretty ugly. It seems to come with the territory?

UI code doesn't need to be ugly. It may come with the territory for most teams, but it doesn't need to be that way. We don't need to be working in giant monoliths that take an hour to deploy and run tests either, yet many teams are. We don't need to live in squalor, but when it's all we've known, we become accustomed to it. We give TED talks telling people how great it is to live in squalor and about the "one weird trick" that makes it a little more palatable.

The only "trick" we need is design. I'm not saying it's easy (in that it is readily available and applicable knowledge for the average developer), but it is attainable.


Don't you find when developing web apps that you often need to use elements that have no semantic value? I'm referring to divs that are needed as hooks/exploits/workarounds for CSS, such as redundant containers that have (or don't have) relative position, or are needed for their stacking context, or to contain overscroll, or to prevent a shadow from being clipped, etc.? These problems also grow more complex when you have to compensate for Safari's issues. I always try to abuse ::before and ::after to streamline the markup, but there's a lot these pseudo-elements can't do.


I wouldn't say it's often anymore, but it happens. It comes with the territory. We can sometimes avoid giving them class names by targeting them with things like immediate child selectors. We do end up with mechanical class names from time to time. But that doesn't mean we throw in the towel on modeling entirely.


I concur. A lot of frontend problems wouldn't exist if HTML had something like XSLT. The fact there's no non-javascript way to reuse HTML code is a already a failure of DRY. Pretty much every web 2.0 technique so far has been just us trying to add DRY to a language that doesn't support it.


> How many of your Tailwind-using apps ALSO have meaningful class names and IDs in your markup?

The markup doesn't need meaningful class names because CSS is encapsulated in reusable HTML fragments that have meaningful names. Your approach to structuring markup is simply unnecessarily more repetitive.

Poorly defined "design" principles have a cost, and where they conflict with concrete principles with a proven track record, like "reusable abstractions", then the poorly defined principles are wrong.


> The markup doesn't need meaningful class names because CSS is encapsulated in reusable HTML fragments that have meaningful names.

They have meaningful names... where? In React (or whatever). They don't in the web inspector (so just use the React dev tools! Yes, more complexity). They don't for testing tools like playwright, cypress, or capybara (so just use data-test-id! Yes, now you have to name something FOR TESTING PURPOSES ONLY, which is a clear sign of failure).

> Poorly defined "design" principles have a cost, and where they conflict with concrete principles with a proven track record, like "reusable abstractions", then the poorly defined principles are wrong.

I'm not sure that attempting to redefine design into something that you can ignore will do you much good, in the long run. If you think that "reusable abstractions" are a problem, then it's highly unlikely that there is a fraction of a square inch of common ground between us and any further conversation will just lead to frustration.


> They have meaningful names... where? In React (or whatever). They don't in the web inspector (so just use the React dev tools! Yes, more complexity).

They have meaningful names in the locations where people actually need to care about meaningful names: in the template language or the component model used to generate the final markup. If you're suggesting that class names should be meaningful for people who want to read the generated markup and they can only make sense of it because of class names, you're penalizing all front-end development for an absurdly small niche.

If you need identifiable names for testing purposes, that's what other queryable HTML attributes are for (id and name in particular). In your template language you already have the component name available, so just assign a queryable attribute using that where necessary. Nothing wrong with that.


I appreciate people taking the time to write articles like this, but please consider the people who are going to read it. ADB is an acronym. Not everyone knows what it means. If you're going to write an entire article about a feature being removed, please at least describe the feature in a way that people can understand without having to google it so that they can have an idea as to whether or not this is relevant to them.


> ADB is an acronym. Not everyone knows what it means

I've used ADB a half-hundred times, and I had no idea what it meant until I read replies to your comment. Defining the acronym is likely not helpful to anyone who has used it before (and thus be affected by the change)


If I recall, the article seemed to indicate that certain apps would be broken. I would be worried that apps I relied on would not function anymore. This has nothing to do with me using ADB, it has to do with apps using it (at least from how I read the article).

You use adb, you have a mental model for it. It does something because you make it do that thing and see it happen. You must be able to put yourself into the shoes of a person that isn't you and doesn't have that experience to recognize what I'm saying. Note: many developers not being able to or choosing not to do this is the source of most of the bad UX that is inflicted upon us today.


To each their own, but your response baffled me. If you've used ADB a half hundred times, weren't you ever curious what it stood for? I can't even use acronyms without knowing what they mean - it's always the first thing I look up, primarily because it helps me really remember and understand what the topic is about. Sure, the acronym soon takes on an "atomic unit of meaning" in my head, but especially for something like "Android Debug Bridge", which pretty perfectly describes the tool, knowing the original meaning still often enhances my understanding.


I think it depends on people. I've used adb and it was vaguely related to debugger acronyms so I assumed it would be debugger something. It does not matter to me what the exact name is.

I use a SOAR and never know what this is for (the name, not the product :)). Idem for the plethora of acronyms we use in France they expand to weird words.

Do not even get me started about the acronyms in my company, I have up completely and use them randomly. The fact that it usually does not bother anyone shows their importance :)


I generally wasn't consciously aware that it even was an acronym. For me adb was just a command like cat. I don't randomly ask myself what cat stands for, or all the other obtuse commands I use on the command line. Life is too short.


Catenate, if you're wondering.


Android Debug Bridge, for future readers


I always mentally converted it to:

Android De Bugger

Does that make sense? No. But that’s what I subliminally assumed it must mean.


It does make sense — the Unix debugger has always been *db, with no bridges in sight.

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


I was thinking Apple Desktop Bus. Obviously dating myself.


"adb" was also the name of the debugger in early versions of UNIX. I remember using it in Version 7:

https://www.unix.com/man-page/v7/1/adb/


"adb" is the name of the executable. Expanding the acronym isn't that relevant. It wpuld be like explaining that KDE stands for Kommon Desktop Environment.


Of course it would be. Even in your example, I would know that KDE is a desktop environment, which, from KDE alone, I would not. ADB is a debug bridge (apparently), which means it's a debugging tool, which means it likely wouldn't be terribly relevant for most typical Android users (and if that's wrong, then the article makes an even bigger mistake).


Typical Android users? Maybe not. But any non-developer user who has tried to sideload an app has used it. It’s hard to overstate how central adb is for doing anything on Android that goes beyond vanilla usage.

(But I agree, 5-7 words of explanation would be helpful)


“Desktop Environment” does a fantastic good job of explaining what kde is


Not "Kool Desktop Environment"?


Oh whoops. Anyway point made I think


The larger issue with the article for me is that it waits until the second paragraph (after a screenshot and so below the fold) to even name what the feature is.


Immediately after using “ADB” for the first time:

> While it’s not a capability used by many Fire TV apps, without it, Fire TV apps can no longer perform certain advanced tasks, such as freeing up internal storage space by clearing the cache of all installed apps.

Maybe the article was edited? Because that seems to give the context required.


The issue is that it doesn't say what the letters of the acronym stand for. ADB? Maybe it means Acme Digitization Business.


All Dissertation But (a status of a student in a graduate Jedi program)


How many people are very capable of using an ATM any day but don’t know what it stands for?


Anyone that has a mental model that includes what ATMs do. The point is that most people don't use ADB and therefore don't have that mental model. Many people have used an ATM, so if an article talked about someone stealing cards/pins on an ATM, most people would know what it meant. There are certain abbreviations that are so commonplace it may be safe to assume people know what they mean, even if they do not know what they stand for.

ADB is not one of those. This is the point, and this is the thing that anyone who is arguing against that point fails to recognize. It's myopia, or self-centered thinking. It leads to bad things in our industry (poor UX being one of them) and I'd encourage anyone thinking this way to consider what "empathy" means and how it is applicable to our field.


My point is defining the letters in an acronym doesn’t matter. It doesn’t matter what ADB stands for. What matters is what ADB does and literally the next sentence after “ADB” explains exactly what the implications are of it being removed.

“There is a thing called ADB and it being removed means apps can’t clean caches any more” would in no way be helped by defining what ADB stands for.


That’s all it does?


Why not read the article, which went into considerably more detail than I did?


I totally agree with you, but I'm deeply amused that you didn't define the term yourself!

This is a pet peeve of mine, for real, especially with PR releases that sometimes hit the top of HN. Sometimes you'll see a post about "Updates from Widgetizer" and then it just talks about the features, assuming everyone already knows what Widgetizer is. It's kind of crazy. The writers are missing out on a lot of conversion by not doing a "by the way, ADB is the Amazon Debug Bridge, a tool that lets you..." and then people go "Wow, I didn't know that existed," and go investigate.


I didn’t know what it was until someone posted a reply to my comment. I don’t have an Android device and I can’t be bothered to fill in the obvious gaps the author left when the thing isn’t of immediate consequence to me.

It wasn’t intentional, but one could argue by my not defining the term I helped it really sink in for people how annoying it is, heh.


ADB is an abbreviation (or initialism), not an acronym. RADAR is an acronym.


Thank you for the correction/reminder. But I might just start pronouncing it Ahdib so I don't have to acknowledge I made a mistake. Kidding. Thanks.


I'm afraid the answer to this doesn't actually lie in tooling. It lies in software design. If something needs to be controlled, it needs to be controllable. Typically this means push. In a React component, this means props. It could be an optional prop, but once that prop was there, this component could be controlled. Once the component could be controlled via push, the page rendering the component could also be controlled via push. How do you push to a page? Query string params is the most straightforward.

So, imagine a page that rendered a version of this component that a human could navigate to (this is what was historically called a test fixture before Rails rewrote the meaning of this word), then imagine that that human could have complete control over this interval by setting a query string argument. A human can do all of the interactive testing they need. Then, when it comes time to automate, all we need to do is automate what the human can already do.

This is another principle of automation that has been lost in history. We should first be able to do things manually before automating them. When we (as automaters) jump right to automation we often simultaneously necessitate and embrace (again, because we identify as automaters) additional complexity in the form of tooling.

I'd venture a guess that SafeTest is not likely to be necessary for the things that it was built for. Software design could have solved the problems with significantly less complexity and tooling while simultaneously providing useful test fixtures for humans to explore.

Storybook kind of enables, but it's also tooling fixation in my opinion. That's another post, however.

Oh, and I saw your other post about rewriting components to allow testability. You may be attempted to accuse me of suggesting that here. I'm not. I'm suggesting that components are written with fundamental design principles in mind, especially the necessity to exert control.

There's more to say about this that touches on the example of the sign in, and I can expand if interested.


Need to print this and hang it on my wall! Exactly.


Consider applying for YC's Winter 2026 batch! Applications are open till Nov 10

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

Search: