Microservices Are Something You Grow Into, Not Begin With - <AUTHOR> https://nickjanetakis.com/blog/microservices-are-something-you-grow-into-not-begin-with <comment><USER2> Most of the time, I've found a push to microservices within an organization to be due to some combination of:

1) Business is pressuring tech teams to deliver faster, and they cannot, so they blame current system (derogatory name: monolith) and present microservices as solution. Note, this is the same tired argument from years ago when people would refer to legacy systems/legacy code as the reason for not being able to deliver.

2) Inexperienced developers proposing microservices because they think it sounds much more fun than working on the system as it is currently designed.

3) Technical people trying to avoid addressing the lack of communication and leadership in the organization by implementing technical solutions. This is common in the case where tech teams end up trying to "do microservices" as a way to reduce merge conflicts or other such difficulties that are ultimately a problem of human interaction and lack of leadership. Technology does not solve these problems.

4) Inexperienced developers not understanding the immense costs of coordination/operations/administration that come along with a microservices architecture.

5) Some people read about microservices on the engineering blog of one of the major tech companies, and those people are unaware that such blogs are a recruiting tool of said company. Many (most?) of those posts are specifically designed to be interesting and present the company as doing groundbreaking stuff in order to increase inbound applicant demand and fill seats. Those posts should not be construed as architectural advice or _best practices_.

In the end, it's absolutely the case that a movement to microservices is something that should be evolutionary, and in direct need to technical requirements. For nearly every company out there, a horizontally-scaled monolith will be much simpler to maintain and extend than some web of services, each of which can be horizontally scaled on their own.

I also wrote [https://adamdrake.com/enough-with-the- microservices.html](https://adamdrake.com/enough-with-the-microservices.html) as a way to communicate some of this, including some thoughts on when and how to structure a codebase (monolith) and when it might make sense to start moving towards microservices, etc. There are cases where it's reasonable (even advisable) to move towards microservices, but they are rare.

<comment><USER3> I don't believe it os reasonable to portray microservices as the result of incompetence and blame-shifting.

Microservices are actually a very basic and fundamental principle of software engineering: separation of concerns. If your system is extensive enough so that it covers multiple independent concerns and your team is large and already organized into teams focused on each concerns then it makes technical and organizational sense to divide the project into independent services.

<comment><USER4> They're subject to a clear limit, though. The more micro you make your services, the less they resemble operational units and the more they resemble primitives from which your actual system is built, sort of like an inner- platform effect. And then you have to debug interactions between microservices, with all the overhead that entails.

</comment></comment></comment><comment><USER5> I agree that microservices is the new "must have" technology but actually it isn't a great deal different from a monolith. The monolith can have separation between services and still requires interfaces to work between them.

As others have said, microservices bring a lot of baggage that you might never have seen before (i.e. big learning curve) and the myth of isolated changes is just that, a myth. Unless it is some low level thing, you cannot change it without impacting other services and this is no different than a monolith.

Like the article yesterday about OOP, the same principles exist to write a good application whatever you use to do it.

<comment><USER6> Indeed. It just replaces internal calls between services of your monolith with flaky and slower network calls.

<comment><USER7> Counterpoint: if network calls weren't flaky and slow would it make a difference in deciding whether to separate modules via a physical machine boundary?

<comment><USER8> But network calls ARE inherently flakier and slower. What good does it to imagine they weren't?

<comment><USER7> It helps demonstrate where additional investment and development might be warranted. If we have hit a physical limit in networking, then that is one thing - but if we are only hitting an artificial limit because our technology and infrastructure is not sufficiently advanced - then this problem is actually showing an opportunity.

As an architect you have to sometimes ignore constraints to understand if the final picture you would assemble makes any sense. If the final picture you assemble makes sense, then working backwards through the limitations, to find out, are these really limitations or are these opportunities to innovate?

That's my thought as to why you would imagine they are not a limitation. To aid in brainstorming, innovation and identify opportunities for improvement, or alternative solutions you would not have seen if you simply accept the bottleneck as a given.

<comment><USER9> As GP said the network is inherently flakier and slower and yes, we are very close to the physical limit.

</comment></comment></comment></comment></comment></comment><comment><USER10> Having worked in a payments company, where SLAs can be very demanding,

We broke our monolith server into microservices, and realized that we broke in to too many pieces as our SLAs broke. (every microservice you add to your usecase adds a small but fixed cost)

and finally decided to convert some microservices into libraries to save milliseconds and bring down our 95th percentile, I completely agree with the premise of the article.

never start with microservice, start with monolith with enough flexibility and inbuilt abstractions which can allow you to replace an abstraction with a monolith.

</comment><comment><USER11> people jump into this because of shit processes like agile which push for incremental and iterative development processes instead of thinking things through properly. usully just to be able to have easy deliverables and easy reporting to upper management about the epic progress that is made. all the while product quality usually is degraded to a point where customers will start to feel it badly. always the same dumb excuse is used that tech is changing so fast. but really, it's only changing so fast because people invent retarded processes which move too fast. you don't need to keep up with every innovation if you have a good quality product. you only need to keep up with this if you require all the latest buzzwords in your product because without them you are unable to sell your piece of junk. /endrant

<comment><USER12> What drives me crazy is that what you're saying is absolutely spot on, and I share the sentiment, but this kind of criticism is usually tone-policed into oblivion.

</comment></comment><comment><USER13> There are many ways to slice an apple.

Sometimes it is a good idea to build something as microservices, but you just have taken the wrong approach, and therefore it is a pain in the __*. So slicing it a different way might still be a microservice architecture but feel much better.

Recently I thought about setting up a Firefox Sync server. The first bumper was when I learnt that the sync server has a dependency on the accounts server... But the full-featured accounts server, in turn, consists of a bunch of services of its own [1]:

\- fxa-content-server

\- fxa-profile-server

\- fxa-auth-server

\- fxa-oauth-server

\- browserid-verifier

\- fxa-auth-db-mysql

After seeing that I decided to tackle that project another day.

For Mozilla that architecture might be perfect, but for most people who just want to run a separate server for <10 people, that architecture is just a burden.

[1]: [https://github.com/michielbdejong/fxa-self- hosting](https://github.com/michielbdejong/fxa-self-hosting)

<comment><USER14> FWIW, as a developer on the Firefox Accounts team, I strongly endorse the sentiment of this article. We've occasionally found ourselves merging microservices back together because the abstraction boundaries we designed up- front weren't working out in practice...

</comment></comment><comment><USER15> I have a _slightly_ different opinion. Start with a mostly monolith, sure, that makes sense. But also start off with just _one_ separate microservice for something important. It's important that you establish good patterns for integrating services in to your codebase early on. Its really easy to write a monolith without any thought of external service abstraction, which makes it WAY harder to do down the road if you decide you need to.

</comment><comment><USER16> I think you can selective. We started with ~5 services all built fairly ad- hoc, splitting on sensible boundaries with the goal of never having a "mega" service.

This means it has been reasonably easy over time to fully replace them on an individual basis with more mature systems without changing the API design.

Now we're 3 years in with ~40 services and the approach has served us very well.

Definitely agree you shouldn't start with a ton of services, but I think you should definitely start with more than one. The jump from monolith to service- oriented thinking is a huge one. But the jump from a few services to more is much easier.

<comment><USER17> > Definitely agree you shouldn't start with a ton of services, but I think you > should definitely start with more than one. The jump from monolith to > service-oriented thinking is a huge one.

I can't get my head around this.

Why should you start with more than one?

What is so different about "breaking your application into services" and "breaking your your application into appropriate modules / classes"?

If those need to scale then you should have an interface that you can expand to a micro-service.

As another poster said "It just replaces internal calls between services of your monolith with flaky and slower network calls. "

<comment> ex-aws-now-goog What is different about breaking an application into services is that because services run as different processes: * you have an immediate natural failure domain (the process) as well as resource isolation between services, * services can be updated independently (something that is done many thousands of times every day at companies like Amazon or Google), * a corollary of independent updates is that services can be tested independently and new code can be "canaried" by initially deploying only a single instance of a service.

The statement that service orientation "... just replaces internal calls between services of your monolith with flaky and slower network calls" is correct in that network calls are flaky and slower but incorrect in its assessment that you gain nothing from using services.

<comment><USER17> I'll give you that you can deploy services separately, but the other advantages that you give could be accomplished with automated testing - that's kind of the point in unit testing to test components independently.

The vast majority of people aren't working at Amazon or Google's scale despite developers seeming to think that they need to work the same way.

</comment></comment></comment></comment><comment><USER7> I am in the middle of implementing a POC/MVP of a greenfield micro services architecture that I was assigned to do at work.

My background is more monolithic and some SOA, so I have had to adapt my thinking to try to make this work.

I am an open minded architect and always willing to explore what the good and bad takeaways are from a given approach.

I think that microservice architecture gives us a chance to think about what would happen if we thought of an ecosystem of applications fully decomposed into a fabric of services.

The first and hardest thing I have encountered so far, was trying to understand the right decomposition into ideal smaller units, something that is nearly impossible without understanding the requirements in full up front. I am not sure you can easily identify your service/domain contexts and boundaries (a la DDD) perfectly enough when you are doing agile development and the microservice architecture is intended to be used by many applications.

However, there is a caveat- if you build modules to be smaller it is easier to reason about what each one does by itself. So that part actually fits in with Agile well.

Also, if you, for a minute, imagine that network / machine boundaries didn't have implications (latency, retries, etc.) and were as reliable as service calls, and if you imagine that we had reliable distributed two phase commit (it can be done, but all subsystems involved have to understand transactions and someone has to coordinate it)... I at least can start to see a picture that works.

I believe microservice as simply to be an old idea (build in a modular small form) in a new light, and I think it is part of us trying to evolve our system development and architecture further.

Don't look at microservice as a panacea nor fad. Look at the problems it raises as opportunities to improve the problems it highlights, and then suddenly all of this might make sense as a scaled up architecture that can start small and scale smoothly to big in the future.

I believe it's all part of the same journey we all have been on, developing systems that go from local, to global and maybe someday, beyond.

<comment><USER7> To add, one other problem that still needs solved in this picture is data federation - and if you solve the network problem and IO limitations fall away, you might actually be able to do crazy things like make joins across distributed systems work, as well as distributed transactions. We already do this with some planet-scale databases, but we are early in this - and it might need to work in the application layer outside of databases too.

</comment></comment><comment><USER18> We are finishing up a 2 year migration out of a data center to Aws and a complete rewrite of a Frankenstein Soa (of sorts) to a couple of monoliths __.I was basically in charge of choosing the tech selection (we wanted to minimize tech stacks until we could get a handle on it) and the "how."

A monolith made perfect sense as there was nothing salvageable, and I mean nothing. And the traffic requirements were definable, growing predictably and not that large. Pretty bag for a medium-sized enterprise.

Picture a company that has no tests, little documentation, 4500 line stored procedures (2000 sPROCS in total containing all the business logic), one data center and no dr, and they would deploy once every 8 days...in 2016! Oh, while making 300M a year with 600 employees.

We are weeks away from turning off the data-centers, have great test coverage, ci/cd; we deploy hundreds of times a week, site is much faster. We were able to combine our front end react tech to gives 99% code reuse in desktop/mobile web and native mobile.

The company makes more money than ever and we have made huge conversion wins by getting our shit together and doing normal, smart product things, while redoing the culture, software and infrastructure.

I hated fighting with these "do-nothing" people that had read articles about SOA/uServices/message passing arch/etc. the worst are the ones that can't avtually do anything. They are usually the loudest.

In reality we use three different architectures, but the core business and logic is in one single backend DB and rails backend and it's beautiful.

We have about 100 developers. We had a couple of issues with people stepping on each other at first, but with some structural changes to our app and some automated process (oh and letting 40ish people go while hiring new people) we solved it.

I can't wait to burn the old servers to the ground. I'm leaving our so much detail. One day I'm going to write the whole story along with my two other partners who really spearheaded the change.

* front end monolith talking to a backend over REST apis. We have internal monolithic applications to help us get our job done. And We have a message passing system called Wormhole and a single uService. Simple...

<comment><USER19> I'm dying to read the whole thing. Please.

</comment></comment><comment><USER20> Bottom line is that it's all a case by case basis. However I'll always warn against slicing microservices too thin. Each slice is a moving part outside of the machine and therefore brings in additional risk. I recently refactored/rewrote a monolithic project into a few fairly chunky services. Each one is sliced by a broad context. The only reason I did it was because the monolithic app required separate physical deployments per client due to data sharing restrictions and the service model (I won't call it micro) allows sharing of the data I'm able (and should) share between them. Perhaps we need a name for the model in between monolithic and "micro"-services. Maybe Macro Services?

<comment><USER21> The term used before "microservices" got trendy was "service-oriented architecture," or SOA.

So this isn't exactly a new idea. ;)

<comment><USER20> Nope. Nothing new here. I remember SOA very well as the buzz word du jour back then. It sounds less cool than micro services though. At least we got our buzz words through the PR & Marketing departments in this decade.

</comment></comment></comment><comment><USER22> IMHO, the monoliths vs microservices debate is akin to monorepos vs multi- repos: they are both strategies used to share work when your organization grows. Both can work well, depending on your tooling and organization.

But do not forget that those abstractions layers you add, while very useful (say, for release velocity), might also be a direct application of Conway's Law: [https://en.wikipedia.org/wiki/Conway%27s_law](https://en.wikipedia.org/wiki/Conway%27s_law)

Which means that refactoring some code, might sometime require refactoring your organization, so if you lack the ability to do that incrementally, you might converge to an ossified system that stops evolving.

</comment><comment><USER12> Interesting that the article mentions Shopify supporting over 600,000 users with a Rails monolith.

At my day job, one of the justifications for us adopting microservices is that we want to horizontally scale.

We have fewer than 8,000 users.

Hubris, eh?

<comment><USER23> The load per user can be widely different in different application. We don't have a great measure for that, one cound use a combination of requests per user per day, and the sum of CPU-seconds used to serve them. The sum of CPU- seconds should contain the periodic (e.g. cron-like, not directly request- answering) tasks too.

At one extreme, you have applications that need horizontal scaling from day one (Scientific computing). At the other, a monolith serving 10^6 users from a single app instance.

<comment><USER12> Yes, that is a reasonable response and I should have preempted that.

For context: the product at my day job does something likely at an equivalent level of complexity to Shopify. It's just another SaaS business that handles payments, invoicing, etc. If anything, Shopify is _more_ complex.

<comment><USER23> So the fact that Shopify succeeds doing that in Rails, not in C with assembler optimized code, is even more impressive!

</comment></comment></comment></comment><comment><USER24> Why not? I mean we don't use micro-services for what it is supposed to do. The application would perfectly be a monolith. We do it, just because it lets us experiment newer technologies in not-so-important services in a smaller scale without undergoing major re-work since when the change is big, everyone in management layer understandably becomes conservative.

<comment><USER25> Sounds like resume-driven-development.

I worked at a company with this disease before. The system was an abomination of vastly different technologies over the years stitched together loosely.

Development was slowed substantially by having such a mess and the company couldn't move fast enough to compete so the startup died. Usually tech isn't the reason for a startup's death. In this case, it was.

<comment><USER24> > Sounds like resume-driven-development.

Sure. That's one of the responsibilities of a team lead: to help team members to work and gradually build up their CVs. I want my team to experiment new stuff and learn while working. But I also want to limit the risk boundary. The whole reason why younger people are leaving dinosaur companies is that no one in management layer lets juniors experiment and fail. End of the day junior devs also want to improve and develop.

<comment><USER26> Nah, your job is to lead the team in the most effective direction in order to fulfil business objectives, not build resumes.

<comment> ex-aws-now-goog Your job is whatever you agreed to when accepting that job.

Some companies require managers to aid in the technical development of employees, some don't. Some provide a lot of latitude in how that's done, some don't.

<comment><USER21> _> Some companies require managers to aid in the technical development of employees, some don't._

It's not about what a company "requires". It's about the moral duty you take on when you manage people.

<comment> ex-aws-now-goog I'm not sure why you think that striving only to achieve business objectives could be considered to be a moral duty. Are you perhaps perhaps thinking of fiduciary duty?

If a company decides that technical development of engineers is good for retaining engineers and you as a manager refuse to do that, then no moral argument is going to help you when you get dinged in your performance review.

edit: Upon rereading the thread, I suspect that we may agree more than we disagree. My comment was directed at asknthrow's comment and I wanted to make the point (which other posters have more eloquently made in the meantime) that if technical development is part of your job as manager, you don't have a choice in the matter and your job is not just "to lead the team in the most effective direction in order to fulfil business objectives" (to quote asknthrow).

<comment><USER21> For sure. To be clear, I mean that _regardless of what your bosses say_ you have an obligation to the people you manage. Obligations do not only run upward. (This is something bad managers often do not understand.)

</comment></comment></comment></comment></comment></comment></comment></comment><comment><USER27> Microservices, test driven development, Agile, 4GL and so on. It's all the same thing: a technique that is applicable some of the time but not all of the time that ends up getting a bad rap because the people promoting them tend to come from the theoretical side of the street, and they see the subject matter as their new revenue stream. They will then promote it to be used even when it isn't applicable.

A web based service can be as messy or as clean as you want no matter whether the underlying architecture is a monolith or a bunch of microservices. I don't like the 'micro' in microservices to begin with, to break up a large and complex problem into multiple smaller problems that are each simple to solve is a core principle of programming. If you take that to an extreme you end up with services that do almost nothing and then you have a communications problem (or at least, you will have one in most environments you are likely to encounter). If you glue everything together in on giant hairball you don't have the comms overhead but you have a cognitive overhead in trying to understand it all.

Like with everything else: there is a happy medium: services that are easy to understand because they do not have horizontal ties to other parts of larger whole, enough isolation to help you with debugging, not so much isolation that you end up doing remote requests for data that should have been nearby.

Everything in moderation.

As an illustration of 'microservices' done well: I worked - the last time I had an honest job+ - as a programmer on a message switch for KVSA, a company that brokers shipping capacity. Super interesting job, even more interesting architecture. Right from day one (contrary to the article title!) it was decided the system was too complex to tackle as a monolith. The reliability demands and the latency requirements led to the base system being built on top of QnX, a soft real time Unix like operating system with a micro kernel. Since in a microkernel environment message passing and service oriented architectures go hand-in-hand the technique percolated through to the application level, which ended up being a series of queues and 'admins' (QnX parlance for a daemon or a service) handling the inputs from these queues and effecting transformations on those inputs resulting in new outputs or side effects (such as a fax or a telex being sent). The system worked flawlessly, had a very high degree of redundancy built in and it most likely would have never made it to production if it weren't designed like this from day #1. For that particular use case it was ideal.

\+ in 1993, if you're wondering whether microservices are something new you have your answer.

<comment><USER28> >It's all the same thing: a technique that is applicable some of the time but not all of the time that ends up getting a bad rap because the people promoting them tend to come from the theoretical side of the street, and they see the subject matter as their new revenue stream.

Also because we've created an industry where everyone must stay up-to-date, so if anything gets traction, suddenly people start getting worried that those things are not on their resumes.

<comment><USER19> Which leads to Resume Driven Development driving choices rather than logical debates where merits and trade-offs are considered.

</comment></comment></comment><comment><USER29> I grew out of microservices because it felt like I was doing the same boilerplate REST service over and over.

So I made a modular REST API service that could load plugins. The plugins can contain anything from simple endpoints to database schemas with sqlalchemy. All this is loaded into the main app at runtime.

So the main app can handle authentication against LDAP for example while all the various deployed microservices can have their own roles.

<comment><USER30> So a Python version of a J2EE app server?

<comment><USER31> Or a framework like Django.

<comment><USER17> We love to reinvent wheels in this industry.

<comment><USER32> And the result generally looks more like a square than a circle

</comment></comment></comment></comment></comment><comment><USER33> What I love about microservices is isolation and forcing you to do thing well from the beginning. Monoliths tend to become horrible to maintain after few years. On the opposite change one small 50 lines microservice is a lot less risky!

<comment><USER34> What I love about monolith is coherence and forcing you to do things well from the beginning. Microservice mesh tend to become horrible to maintain after a few years when no one really measure which components will be impacted by a single change. On the opposite, change one small 50 line function and your IDE will happily show you all the calls to that specific function.

<comment><USER35> Just like you have tests between monolith modules you can have integration tests between microservices

<comment><USER36> The more layers you are testing, the slower and harder it is to write tests and the feedback loop is way longer also.

<comment><USER37> Depends how you do it. Having a sane communication model/interface between the services allows you to test it in two ways: 1) You test the internal structure with unit tests 2) You test changes to the API contract with E2E tests Both are fairly straightforward once you set it up properly.

Same goes for the monolith, assuming you do your work on following somethink like the SOLID principle, it is easy to test piece by piece. The only thing here is that the interface contracts are internal to the codebase vs external to other codebases. (You might argue the last point actually forces you to write a more coherent API contract in both situations)

</comment></comment></comment></comment></comment><comment><USER38> I don't like the phrase "microservice" because it now has a certain amount of baggage, similar to "service oriented architecture" which it was meant to be somewhat of a counter-point to. Whereas the issue with SOA was its association with maligned/feared technologies (SOAP, WSDLs, CORBA), the issue with microservices is the implied granularity. SOA was a good idea, but people (particularly in start-ups) don't want to say they're doing SOA because it has old-school, corporate connotations. On the other hand, the granularity of microservices seems too extreme for what most products would actually need but the concept is associated with more modern technologies which are attractive to developers, like gRPC or Avro or Kubernetes (or even something as simple as HTTP). So I would say the most pragmatic approach for a greenfield web product (rather than a corporate IT integration) is have a fairly standard core (probably a REST API, a server-side MVC framework, or a GraphQL backend if you're nasty) and factor out services that make sense to the team (maybe a service that handles push notifications, or a service that does image processing, or a service that is the secret sauce of your product) because they need to scale independently or handle async/computational tasks that should have dedicated resources or they pull from a data source that is orthogonal to the rest of the system. You need to strike a balance between "micro" and "service".

There is this idea that you either have microservices or you have a monolith, while its really more of a gradient. I guess what I'm advocating for is "modern service-oriented architecture" or "chunky services" vs "microservices"; reasonably sized, well-considered services that use modern technologies for inter-service communication.

</comment><comment><USER39> There's trade-off's. They are using a fairly complex CI while with micro- services you release each service individually. It's hard to turn a monolith architecture into a architecture with micro-services. So it all depends on what works best for you. The idea with micro-services is that with a much smaller service - development is faster and cheaper, you can for example rewrite the entire service, use different software stacks (the best tool for the job), etc. Where as a total rewrite is not feasible in a monolith.

<comment><USER12> Why do you believe development would be faster and cheaper? Because the individual services are smaller?

Come on. The system is as large and as complex as will be necessary. Separating components with network calls doesn't make them any less interdependent.

<comment><USER39> There's a saying that if it takes one man one year to build a wall, you hire 20,000 workers and the wall would get built in a couple of seconds. That's the monolith thinking. Now if we make several small teams, and each team build a very tiny wall anywhere they like, each team could iterate faster, and quickly rebuild that tiny wall if needed, that's the thinking of micro-services. The later plan is of course not so smart if the wall is intended to stop people from entering, so not all systems are a perfect match for micro-services.

<comment><USER12> Your allusion to The Mythical Man-Month is completely orthogonal to the debate between monoliths vs micro-services.

It's just not at all relevant.

</comment></comment></comment></comment><comment><USER40> The argument here is that microservices are another level of code reuse, with their own encapsulation.

But microservices are also about coupling: just have a self-contained service that does one thing.

<comment><USER41> > But microservices are also about coupling: just have a self-contained > service that does one thing.

What stops you from creating a module inside a monolith with an interface that provides a self-contained service that does one thing?

<comment><USER40> You can. But one day, some 10xer will be short on time and will duct tape your module with 10 other modules.

<comment><USER42> The newish argument for microservices is that they enable compositionality, so wouldn't that same hypothetical apply? I.e. some 10xer is short on time and glues a bunch of microservices together and now you have the same problem but worse because there's no IDE allowing you to trace the code?

<comment><USER19> You have a problem. You decide to use regular expressions to solve it. Now you have two problems.

You have a problem. You decide to use microservices to solve it. Now you have ten problems.

</comment></comment></comment></comment></comment><comment><USER43> I agree if you have no idea what you're doing - which seems to be the case for many developers starting new projects stuck in the paradox of choice.

But like anything else, if you understand the toolset, ecosystem, and have the experience, it can take far less time than esoteric documentation and conversation would have you believe.

I always begin with this pattern, but it's because I've acquired so much experience and know-how with it that it's a quick upstart. However, this didn't come with any ease. Most want to just dive into really myopic course work or tutorials that are "just examples" and "shouldn't be used in production." The WORK to understand it is getting each nuance under your belt. It's just like any other skill set - it takes patience and deliberate effort. Documentation spelunking and trial / error experiments.

That being said, under the fire of a manager, timeline of capital, or just the raw impatience inherent to humans we wind up falling back to what's safe, what has plentiful easy-to-learn patterns, and listen to all the other folk who get 50% through, stop, and then just spin up terribly organized monoliths.

</comment><comment><USER44> This article and articles like it presume some magical workforce you can hire that will transform or organically evolve your application into a microservice ecosystem. But the fact is that people who know how to execute a microservice architecture, muchless willing to work on your particular budding application are few and far between. So if you don't know how to build microservices, it seems really hard to start with microservices by factoring a live running application while you are also simultaneously trying to keep that application up and functioning and feature developing in order to monetize it. Wow does that sounds difficult.

So it makes more sense to me to build out from microserves—they can be embedded in one JVM or whatever—so you know how to organically evolve and can focus on monetizing your application.

</comment><comment><USER45> You really can get all the benefits of popular architectures without going off the rails!

Don't start out with a DI framework, use poor man's DI (ie 'passing stuff in').

Don't start out with microservices, use (poor man's) DI, ban all public static/global variables, and segregate code into separate processes with public 'interfaces' (but don't use actual interfaces until you actually need them! 1 interface per class is an antipattern!). These can all run in an async process pool you build, which can monitor bottlenecks when you get to that point. You can then (years later) easily break an internal service into a microservice when the trade off makes sense.

I'm obviously static typing/oop focused, but there's a version of this which applies to any paradigm.

</comment><comment><USER46> You should always start with domain specific microservices. Those "microservices" shouldn't be out of process services necessarily. They can just as easily be in process "domain services" in a monolith that are only accessed via an interface where each module is treated as a black box.

</comment><comment><USER47> I mostly agree with the article except the part where the author plays down the architectural considerations during project inception.

> Right now it's just me working on the project, and you can be sure I just > cracked open my code editor and started writing code on day 1.

It's definitely fun to start with writing code, but in my view it may be more efficient to pause for a moment, understand the problem and find the right solution for it. Then start writing PoC code, which can be refactored at a later stage. That's just pragmatism - lots of code will go to the bin anyway, but at least we give ourselves a chance to have a longer and happier run with it before that happens.

</comment><comment><USER48> When making generic rules one should provide a lot of context. I have found that a fairly large rearchitecture is needed to move from a monolithic product to something with microservices. It is not something to grow into that way.

And the technical reasons to move will be mostly for fault tolerance and resiliency (you don't want your whole service to go down because a small widget failed somewhere). Of course this does not come for free.

Basically it's not that one is better than the other for all cases. This is a case where people should consider many things including non-technical aspects before making sweeping statements or decisions.

</comment><comment><USER49> Can't you have both in a way? A monolith that's glued together by an "interface language" (e.g. GraphQL), that can be broken up by "ejecting", removing the glue code?

</comment><comment><USER50> This is an interesting read, and thanks for sharing. While keeping things monolithic is an efficient, worry-less and simple approach to architecting a product to maturity; what would you advise if it will take as much work or greater to break it down micro-services; 1\. To continue anyways or 2\. Find a mid-point in the life cycle to break things down or 3\. Have a deep thought about the future of the project at the beginning (then decide)?

</comment><comment><USER51> I am just starting to develop web apps. Is [JAMStack]([https://jamstack.org](https://jamstack.org)) + Lambda functions (AWS Lambda) a good place to start with?

Since Lambda functions are similar to microservices, I am now confused if I should stick to simpler backends or full stack instead of JAMStack.

<comment><USER9> Is that a joke website or serious?

<comment><USER51> Serious. It is a concept by the creators of Netlify.

</comment></comment></comment><comment><USER52> I agree with writing a lot of code being the way to write better code, but as soon as I encountered the part about "absolute and total intent to replace almost everything you write with better code once you start experiencing real problems first hand" strikes me as not possible in every environment.

If you are writing your own monolith from a basement and are a single developer, sure. Once you have founded your company and made your millions you can decide what, where, and when to change in the code. However, for the vast majority of people who do professional development it is just not plausible to suggest that you create every project as a throwaway.

Because in corporate development, once a project works (even a low percentage of the time or with major problems) it can and often will continue its life forever. Greenfield development has a different process in most places than maintenance / sustaining, and most people will find that making any reasonable structural changes to a legacy / monolith / inherited code base will take years of mostly political arguments because management will be unable or unwilling to recognize the writing on the wall.

Analysis paralysis is obviously a problem as well that exists on the extreme end of the other side. However, I believe actually prototyping and testing early in the cycle is the best of both worlds: you get both the ability to respond to problems early in the cycle because you're exercising the code already, and the process will not cripple you from making those changes.

I agree that writing a lot of code is the cure, but please, for the love of all that is programming, stop insisting that every early prototype makes it into production with their awful duct tape and bubble gum patches intact.

Break the problem down early, learn some of the finicky bits of the technologies you've chosen, and be pragmatic...but insisting on taking your first (often terrible) crack at the problem directly into production where you'll be stuck on it for possibly a decade is pretty bad advice in most environments I have developed in my professional career.

It's a recipe that'll often get you stuck troubleshooting irritating design- induced problems for years to come or hopping to a different company.

There is a middle ground between no design and spending years on whiteboards and blogs before writing a single line of code...that middle ground is what needs to be mined instead of constantly taking an extremist stance.

But hey, this is corporate development...so the loudest voices and most extreme opinions always seem to win out.

</comment><comment><USER53> There is a lot of tooling for getting started with microservices now-a-days.

</comment><comment><USER54> www.appcontinuum.io

</comment><comment><USER55> My problems with microservices irl:

1\. Sharing models - the models can be moved out to another repository or a NuGet package, but guess what happens when you have to modify them? Inevitably, devs duplicate models.

2\. Debugging across five different code bases - have fun changing all the environment variables to point to your local every time, or running five different applications at the same time for local development.

3\. Docker and Kubernetes add a LOT of overhead.

4\. Multiple front-end apps combined into one "coherent" site always leads to routing problems...and token management problems.

5\. Web Components cause bloat by pulling in web component scripts and the fact that each web component needs to fit the style of the whole site. Since shadow dom is isolated, each component pulls in styles again - slow. Again, debugging and checking in web component code is a pain.

6\. Finally, siloing is inevitable.

Imo, this doesn't make sense at all for a smaller web app.

<comment><USER9> Is duplicating models that big of a problem? Just an honest question, hoping to get more answers/opinions besides parent's.

<comment><USER55> It's a good question. Going to let others answers. My tldr opinion is "Not really, but code duplication any time, but especially across repos can lead to hard-to-troubleshoot errors".</comment></comment></comment>


Apple terminated my developer account for no reason - <AUTHOR> https://github.com/cyanzhong/apple-terminated-my-dev-account <comment><USER2> Apple has done a pretty bad job at connecting with developers especially indies. Though at WWDC every year, the're demonstrating how they treat well to developers, how much developers have earned, it's has never been a time when Apple and developers are at a same table. If you're an Apple developer, ask yourself the question how you can communicate with Apple and how soon you can guarantee they would respond.

This hurts, not only Ying, but also indie developers like me.

<comment><USER3> Cannot agree more. This story brings a lot of concern to me.

</comment></comment><comment><USER4> This is really a terrible and sad news. Apple should not treat such a pure and good independent developer at all, and does not give any representations and explanations.

I don't know if it is an Apple misunderstanding. But Apple should give developers at least one opportunity to request and communicate. These developers have been supporting your iOS platform for so long and should not be treated as rudely. It is a disaster for the weak independent individuals and our dreams.

</comment><comment><USER5> Unbelievable. As a developer, if I can't feel safe to develop App for iOS/macOS, why should I do it? Apple should explain why they did such a terrible decision.

</comment><comment><USER6> Any developers including individuals and enterprise developers should be treated equally. I cannot figure out why the developer's account would be terminated without any notices in advance. At least, Apple must provide the proof to justify the termination action. Unfortunately, there's nothing so far.

There indeed exists controversy whether developers can build applications with interpreters which can be the container of other "apps". But, what about Wechat or Alipay. Both of these two apps give their own developers ability to create so-called "Small Program" which could potentially "be harmful to the ecosystem of AppStore". Apparently, powerful enterprises can do anything without any punishment while the single developers have always to be cautious.

</comment><comment><USER7> It's terrible that the large tech companies are so arrogant that they just terminate an account without a reason or a way to appeal. So this guy should get a chance to argue.

But I also know that every time I read a story in HN about X company terminating my account for no reason there is usually a good reason for the termination. It usually comes down to a user/developer violating the terms of service. I also know that if there was a way to appeal, everyone would do it, and clog the system, since there would be nothing to lose.

I'm conflicted. But anyhow good luck to him.

</comment><comment><USER8> The indies were the additions to the Apple ecosystem. There quite of ideas, group of people's requests that enterprises does not care about.

Apple should communicate with developer on what wrong with these apps, how to fix it. Instead of just arbitrarily terminated the account that does not help for both developers and Apple itself.

</comment><comment><USER9> I really enjoyed being indie developer but now I feel so sad about this sentence:

> Believe or not, the era of indie developers has passed.

It's getting obvious that Apple doesn't care much about indie developers. Although most of the unique, special apps are coming from indie.

I wish they not only provide tools but also fix their relationship with developers.

</comment><comment><USER10> I feel terrified when I saw this news. I'd never expected this news happened to any of developers, especially for those who work very hard and not intended to do anything wrong with Apple policy. We do very expecting that Apple would response to this developer and wish the problem can be solved.

Best luck Ying.

</comment><comment><USER11> Apple should be more open and transparent when dealing this kind of things, or we indie developers will lose confidence in Apple ecosystem.

</comment><comment><USER12> Really bad news. I don't know what to say. As an indie developer, I feel hurt too.

</comment><comment><USER13> Apple hurts the heart of the entire Chinese indie developer community.

</comment><comment><USER14> 该封的不封。我今年也被封,投诉我们,经济损失不小,毁了我一年。

</comment><comment><USER14> 投诉无门,垃圾苹果在赶开发者走。

</comment><comment><USER15> Best wishes

</comment><comment><USER16> shame on Apple.

</comment><comment><USER15> best wishes</comment>


UK govt considering facial recognition to verify age of online users - <AUTHOR> https://www.theregister.co.uk/2019/10/18/gov_splashed_22m_on_failed_age_verification_policy/ <comment><USER2> Not even a week after they conceded that their previous such effort was a failure. [0]

I recall reading somewhere that the reason for all this nonsense (don't forget this stuff too [1]) may be that the Conservative Party still wants to score points with their ultra-conservative base after legalising gay marriage.

I have no doubt that the upshot of this latest effort will be just like the last time: wasting a few million pounds of tax funds, and online mockery.

[0] [https://www.theregister.co.uk/2019/10/16/age_verification_po...](https://www.theregister.co.uk/2019/10/16/age_verification_pornblocking_plans_shelved/)

[1] [https://www.theguardian.com/science/brain- flapping/2014/dec/...](https://www.theguardian.com/science/brain- flapping/2014/dec/05/uk-pornography-law-scientific-perspective-children- safety)

<comment><USER3> It's likely not a serious proposal; possibly more aimed at shifting people's perception of what's reasonable towards a 'more moderate' solution that would previously have been considered unacceptable.

Common technique: have someone not too senior (or retired) propose something outrageous, then introduce what was really planned all along and present it as a compromise.

<comment> Funes- >more aimed at shifting people's perception of what's reasonable towards a 'more moderate' solution that would previously have been considered unacceptable.

Playing with the Overton window [0], then. Interesting.

[0] [https://en.wikipedia.org/wiki/Overton_window](https://en.wikipedia.org/wiki/Overton_window).

</comment></comment></comment><comment><USER4> Facial recognition is almost universally trivial to defeat as an authentication mechanism. A colleague had a Microsoft Surface with facial unlock. I could hold up my phone to the camera, with his Slack profile picture fullscreen, and it would unlock.

<comment><USER5> But how easy would it be to defeat as an identification mechanism in public areas when used for widespread surveillance? That's the real aim of facial recognition for governments I think.

<comment><USER4> [https://cvdazzle.com/](https://cvdazzle.com/)

</comment></comment></comment><comment><USER6> The MP who said this, Nicky Morgan, has a less than stellar reputation. Sounds like the comment was purely a case of throwing out a buzzword as a terrible answer to a good question.

The minute any implementation of this hit the real world it'd fail. Teenagers are very good at working around technology, whilst anyone other than the average caucasian is likely to get an incorrect age assessment.

<comment><USER7> >The MP who said this, Nicky Morgan, has a less than stellar reputation.

Based on the Wikipedia article her career has been one long series of blunders.

<comment><USER8> In the current government, that's a prerequisite. PM himself sets the tone.

</comment></comment></comment><comment><USER9> I presume they expect to do this by means of webcams or uploaded photographs. What's to prevent somebody holding up an enlarged photograph or sending a JPEG of Uncle Pete?

<comment><USER10> Chrome actually makes this easy. It has a literal option "\--use-file-for- fake-video-capture" which does what it says. [https://webrtc.org/testing/](https://webrtc.org/testing/)

</comment></comment><comment><USER11> This isn't a serious proposal it's just incoherent ramblings of somebody who doesn't know what they are talking about.

</comment><comment><USER12> So either identifying individuals based on a national database mapped against profile and age (privacy nightmare), or guessing age based on looks using a janky ML model (very error prone).

What could possibly go wrong...

</comment><comment><USER13> Taking their cues from China now?</comment>


Burning laptops and flooded homes: Courts find Amazon liable for faulty products - <AUTHOR> https://www.washingtonpost.com/technology/2020/08/29/amazon-product-liability-losses/ <comment><USER2> Big discussion a couple of weeks ago: [https://news.ycombinator.com/item?id=24174276](https://news.ycombinator.com/item?id=24174276)</comment>


Google Analytics Goes Async - <AUTHOR> http://www.stevesouders.com/blog/2009/12/01/google-analytics-goes-async/

<comment><USER2> Previously, what stopped you async adding the google JS to the DOM via a setTimeout()?</comment>


OpenNMT: Open-Source Neural Machine Translation - <AUTHOR> https://github.com/OpenNMT/OpenNMT <comment><USER2> The amazing thing about this new wave of innovation in AI is that the technology is democratized -- anyone can have near state-of-the-art technology to power their applications without paying for it.

One of the lasting principles in the "business of AI" is that the data is the true source of value. If you don't have a monopoly on the data, you're going to have a tough time sustaining a competitive business because everyone else will more or less be able to clone your technology. My PhD advisor taught me this based on his experience founding one of the first really successful neural networks companies, HNC, which was later acquired by Fair Isaac (FICO). HNC put together a consortium of banks in order to train their credit card fraud detection system and maintained a monopoly on the data. FICO still runs this business today and I've heard from recent employees it still runs on the same old single-hidden-layer multi-layer perceptron architecture as it did in the 90s.

</comment><comment><USER3> I tested it on the live demo with a few sentences from Google News, English to Italian and viceversa. It looks to be at the same level of Google Translate: some sentences are better translated to Italian by OpenNMT, others by Google, even in the same excerpt from the news.

Both tools seems to be better at translating to English, but maybe because I don't realize some of the mistakes they do.

Overall it's a great tool. I suggest to read the FAQ at [http://opennmt.net/FAQ/](http://opennmt.net/FAQ/)

<comment><USER4> The code implements a pretty close model to what Google Translate has published ([https://arxiv.org/abs/1609.08144](https://arxiv.org/abs/1609.08144)). However the two systems are likely trained on very different datasets.

</comment></comment><comment><USER4> Hi, I'm Alexander Rush (@harvardnlp), one of the project leads on OpenNMT and an assistant prof at Harvard. Feel free to ask me anything about the project.

<comment><USER5> As a terrible human being, I tested Chinese-to-English translations on f-word- based profanity on the demo page ([https://demo- pnmt.systran.net/production](https://demo-pnmt.systran.net/production)). The results were arguably not as good as Google Translate, which can recognize the colloquial form 操[^1] but not the more orthodox 肏. PNMT's results were great in another way as they form more fluent English.

      [^1]: Everyone hijacked the character.

On the other hand, OpenNMT appears able to translate the "f __* you! " sentence to "你妈!" in Chinese, a form of "操你妈" with the F word not spoken but implied. The single-f-word sentence generates amusing variations when used with different punctuations, although many ("...", "?", "!", "") fail by reducing the sentence to a normal call for one's own mother.

These experiments make me curious about what kind of corpora the system was trained on.

* * *

The test sentences used were:

        操你十八辈子祖宗![^2]
        操你十八辈祖宗!
        操你妈!
      [^2]: This one is technically wrong.

For the orthodox version, replace all instances of 操 with 肏.

As an additional experiment, I tested some variations of "mother" profanities without "操":

        1. 你妈!
        2. 他妈的!
        3. 他妈的。

Between #2 and #3, PNMT appears more sensitive to punctuations than human do. #1 is only included as a round-trip validation.

Edit: (#1) ... and is not supposed to be translated back into profanity due to high false positive rate.

<comment><USER4> While this type of translation is heinously understudied, the opposite problem of controlling the politeness forms of translation is actually an important area of research. For instance Controlling Politeness in Neural Machine Translation via Side Constraints ([http://homepages.inf.ed.ac.uk/abmayne/publications/sennrich2...](http://homepages.inf.ed.ac.uk/abmayne/publications/sennrich2016NAACL.pdf)) is something that OpenNMT can support.

</comment></comment></comment><comment><USER6> Neural translation has been really amazing and impressive. I stumbled into a way to be mean to Google translate this week: [https://twitter.com/driainmurray/status/818934530207862784](https://twitter.com/driainmurray/status/818934530207862784)

OpenNMT can also run amok given totally unreasonable input too (example below). I'm being unfair, but the more serious point is that translation systems might go crazy in less obvious ways. While fluency is greatly improved, they certainly don't always get the meaning correct. I'm excited to see what people will do to better diagnose when we can trust the translation.

Input: _" Toll ach toll toll ach toll toll toll toll toll toll toll toll toll toll toll toll toll toll toll toll toll toll toll toll Deutsch."_

Output: _" Tell me great great, great great, great great great great great great great great great love great ? ? ? great love ? ? ? ? ? ? ? great ? ? ? ? great love ? ? ? great great ? ? ? great great ? ? ? great great ? ? ? great great ? ? great great ? ? ? great great ? ? great great ? ? great love ? ? Good ? ? ? great love ? ? great love ? ? Good love ? ? great love ? ? great love ? ? great love ? ? great love ? ? great love ? ? great love ? ? great love ? ? great love ? ? great love ? ? great love ? ? great love ? ? great love ? ? great love ? ? great love ? ? great love ? ? great love ? ? great love ? ? great love ? ? great love ? ? great love ? ? great love ? ? great love ? ? great love ? ? great love ? ? great love ? ? great love ? ? great love ? ? great love ? ? great love ? ? great love ? ? great love ? ? great love ? ? great love ? ? great love ? ? great love ? ? great love ? ? great love ? ? great love ? ? Good ?"_

[Each ? was a musical note glyph, but HN ate the unicode character.]

<comment><USER4> Unfortunately we do run into these types of "robustness issues" in our experiments. They're rare enough that they don't really change many of the performance metrics of the system, but they are quite embarrassing. It is currently a bit of a mystery as to why they go so wrong, better diagnostic tools are sorely needed. Informally, these mistakes similar to the more well- known mis-classification of noise issues in cnn's for vision.

</comment></comment><comment><USER7> What resources does this require to run? Obviously you need some fairly heavy lifting for the initial training, but once trained, could the models be used on, say, a mobile phone?

<comment><USER4> Yes, you can actually run them on a phone! We had an earlier demo of very strong system running on android [https://github.com/harvardnlp/nmt- android](https://github.com/harvardnlp/nmt-android)

Without tricks the large models takes up about 700 megs, opennmt.net/Models/. They can run on a standard CPU relatively quickly. We also have a pure C++ decoder if you want to do translation without the NN framework.

</comment></comment><comment><USER8> These NMTs seem tragically bad at translating simple straightforward Chinese e.g.: 我要下班了。下班了再说。

      Google: I have to get off work. Off to say.
      OpenNMT: I am going to work. After work, again.

If this is the state of art for NLP. We have a long way to go.

<comment><USER4> It's not there yet, but the improvement has been quite significant in aggregate. Key table from the GoogleNMT paper, empirically showing a 60% relative improvement on this task:

                      PBMT  GNMT  Human Relative Improvement

English → Spanish 4.885 5.428 5.504 87%

English → French 4.932 5.295 5.496 64%

English → Chinese 4.035 4.594 4.987 58%

Spanish → English 4.872 5.187 5.372 63%

French → English 5.046 5.343 5.404 83%

Chinese → English 3.694 4.263 4.636 60%

<comment><USER8> This is obviously data dependent. I suspect that the advantage of human is much higher in colloquial content vs written (esp. news) content. "Universal Adversarial Perturbations"[1] last year showed that you can easily generate reasonable (to human) perturbations to completely fool the state of the art DNNs for images. I suspect that the same is true for the current batch of NMTs as well. As a simple demo, I change the example Chinese a little (就要下班了。下班了再说吧。Only aux characters changes with the same meaning) and all NMTs failed spectacularly in different ways.

      Google: It is necessary to get off work. To say it again.
      OpenNMT: it's going to work. Go back to work again.
      Baidu: It's going to work. After work.

[1] [https://arxiv.org/abs/1610.08401](https://arxiv.org/abs/1610.08401)

<comment><USER4> Yeah this is a nice connection. Note however that there has been much less success in using perturbation in language. The fact that inputs are discrete makes it harder to apply some of the tricks in the adverserial image work.

</comment></comment></comment></comment><comment><USER9> Train top20 language pairs.

Make mobile app that takes picture, runs OCR, detects language and feeds into model.

Translate

???

Profit

All offline, after the models have loaded once.

<comment><USER4> Better: Train the same model for all twenty language pairs ([http://opennmt.net/Models/#multi-way--- fresptitrofresptitro](http://opennmt.net/Models/#multi-way--- fresptitrofresptitro)).

Even better: Use OpenNMT to do the OCR too ([https://github.com/opennmt/im2text](https://github.com/opennmt/im2text)).</comment></comment>


Happy 20th Anniversary Qt - <AUTHOR> http://blog.qt.io/blog/2015/05/20/happy-20th-anniversary-qt/

<comment><USER2> Qt has been indispensable to my daily work. When I first started my current job, I had to convince my boss that we should transition from C# to PyQt (and also the rest of the Python ecosystem, which is awesome because we do commercial scientific computing). Mixing Python and Qt has been great for productivity, as you can imagine. There is also a great Python visualization ecosystem based on PyQt/PySide including pyqtgraph and vispy. Lastly, the documentation is absolutely outstanding, and the community is very active.

A project I have been wanting to start is to use Qt as a substrate for a (functional) reactive programming framework in Haskell or Python. The Haskell lib could be based on any current FRP implementation, and the Python lib could be based on RxPY [1].

One thing I would change in Qt would be the Model/View system. I try to use a strict Model-View-Presenter approach, but since we have millions of rows in our tables we have to use Qt's Models/Views instead of controlling all view behavior ourselves. It would be nice to have performant views easily while using a different API, instead of being forced to use the QAbstractItemModel API.

Congrats Qt project, and thanks for the hard work!

[1] [https://github.com/ReactiveX/RxPY](https://github.com/ReactiveX/RxPY)

<comment><USER3> I've also been using Qt for a long time and I've seen it go from Qt 1 to Qt 5. KDE is desktop of choice and would look very different today without Qt. If there was no Qt, there'd probably be no KDE and hence no GNOME and GTK.

Using Qt in a FRP fashion would indeed be wonderful. My (slightly uninformed) vote goes to a binding of Reflex (i.e. Haskell) to Qt.

</comment></comment><comment><USER4> We've been using Qt as a core part of our product but increasingly it is looking more difficult to justify. Most of our customers don't want it and it adds constraints that could be hurting us. Add to that the exotic licensing model and I don't know how sustainable it is.

</comment><comment><USER5> Qt is awesome! \o/</comment>


Ask HN: Trustworthy backup service? - <AUTHOR>

A particular pain point that I've had managing websites and services hosted over a hodgepodge of shared hosting accounts and VPSes is centralized and secure backup of web content and databases. AKA, I can schedule complete backups of the source files and database contents across multiple hosting accounts.
While some hosting services have their own internal backup systems, and there are a number of local backup clients you can run, the market of cloud backup service providers that offer a backup-everything service seems to be pretty sparse.
Of course, the major caveat is that in order for such a service to work, you must provide them with credentials to access all of your servers. While services like Mint seem to have slowly made more people comfortable with this idea, it still feels "wrong".
What solutions exist for this problem? Has anybody had experiences (good or bad) with cloud backup providers like dropmysite.com or similar services? <comment><USER2> Thinking out loud: At each host, backup to an encrypted local store (only you have to access the crypyto-key(s)). Then have the centralized backup service copy those encrypted stores.

You need more storage and it's more labor to setup, both of which could be impractical depending on the systems you manage, but the central service would have no access to anything confidential. Also, integration between the central backup and the variety of local hosts would be greatly simplified, with no file locks, database backups, consistency issues, backup window coordination, etc.

EDIT: Also, the granularity of available recovery points might be limited, at least from the central service. Block-level backups (and the associate recovery points), for example, could be implemented locally but might be hard to implement on the central service.

<comment><AUTHOR> This is a great idea - unfortunately, some of the servers I need to back up are feature-poor shared hosting accounts where it would be difficult or impossible to run a script that serves this purpose locally.

<comment><USER3> Do yourself a favor and stop using shared hosting services. A few years ago, you could justify it because of the cost. VPSes are _so_ cheap these days, though, that it's silly to hamstring yourself with shared hosting. Digital Ocean is a good place to start, and they'll even pre-install LAMP for you if you want. $5/mo for your own box.

<comment><AUTHOR> I've been planning to get everything off the shared hosting accounts for awhile. Is Digital Ocean a better deal than, say, AWS for hosting dynamic websites?

<comment><USER3> It's definitely cheaper.

</comment></comment></comment></comment></comment><comment><USER3> Tarsnap. Cheap, encrypted, and reliable.

</comment><comment><USER4> If you can get the backups as dump files, have them sent to a Dropbox account or remotely to a server. Then install Backblaze or Crashplan on that server.

You end up with a Dropbox backup, server backup and a 3rd backup via Backblaze or Crashplan.

Cost is around $10/mo for Dropbox, $30 - 40/mo for a server if you go with OVH and $5/mo for Backblaze or Crashplan.</comment>


Terry Tao (Fields medalist) on time management - <AUTHOR> http://terrytao.wordpress.com/2008/08/07/on-time-management/ <comment><USER2> It's almost 1900 words for an article about time management. But being that my time is worth zero now I read through it all.

</comment><comment><USER3> I liked his honesty here:

"my ability to do any serious mathematics fluctuates greatly from day to day; sometimes I can think hard on a problem for an hour, other times I feel ready to type up the full details of a sketch that I or my coauthors already wrote, and other times I only feel qualified to respond to email and do errands, or just to take a walk or even a nap."

<comment><USER4> What struck me is how great is is that his career allows him to do that. Most people have to sit and work at a slow pace instead of just relaxing for a bit and getting back into things when they are ready.

</comment></comment><comment><AUTHOR> Terry Tao's blog and wiki also has a lot of useful articles about productivity, professional and personal growth, vocational matters related to maths, etc. Worth visiting it.

</comment><comment><USER5> Fun fact, Terry Tao is an alum of this program: <http://news.ycombinator.com/item?id=269717>

</comment><comment><USER6> Can someone summarize this for me? I don't have time to read that much text.

</comment><comment><USER7> It would be good to change the title to "On Time Management". It shouldn't matter that Terry Tao wrote it, or that he won a Fields Medal.

<comment><AUTHOR> I'm not so sure about that. Most literature about time management is terrible, so, you tend to ignore it unless the one writing seems to have something to say. And Terry Tao is a great achiever, and also somebody who seems to be doing many useful things at once all the time. Certainly I do care that he's the one that wrote the article... otherwise probably I wouldn't have even read it.

<comment><USER7> If the writing is good, it will stand on its own. All I'm saying is that the difference between "Tarry Tao (Fields medalist) on time management" and "Terry Tao (don't click this link) on time management" is pretty small. They both make you want to click on the link to see what it's about, and they are both totally irrelevant to the actual content of the article.

<comment><USER8> _If the writing is good, it will stand on its own._

Indeed -- and if this were, say, a fiction contest, it would be a great way to do things. But when someone is giving advice, the identity of the advisor (and the success they've had by following the advice) is important.

<comment><USER7> You're correct.

<comment><USER9> "Joe Idiot Teaches Quantum Physics"

<comment><USER10> This made me check - apparently there really isn't an "Idiot's guide to quantum physics" yet. I wonder why? I bought an "Idiot's guide to economics" the other day... So Quantum physics is more complicated than economics?

Edit: put "Write Idiot's Guide TO Quantum Physics" on my TODO-list...

<comment><USER11> I just checked and there is a "Quantum Physics for Dummies" on Amazon for preorder. It's due to come out early next year.

<comment><USER10> Ah OK, maybe I just confused the title of the series, I thought it was "Idiot's guide to...", not "... for dummies".

<comment><USER12> Both are real series. Considering that the Dummies haven't published yet, the Idiots appear to be ahead:

[http://www.amazon.com/Complete-Idiots-Guide-String- Theory/dp...](http://www.amazon.com/Complete-Idiots-Guide-String- Theory/dp/1592577024)</comment></comment></comment></comment></comment></comment></comment></comment></comment></comment>


All evidence points to OOP being bullshit (2013) - <AUTHOR> http://blog.pivotal.io/labs/labs/all-evidence-points-to-oop-being-bullshit <comment><USER4> > Extremist languages like Java force you to think of everything in terms of > objects.

Erm, Java is by far not the most OO programming language there is.

For example, primitive types are not objects (no, auto-boxing doesn't make them objects).

> But is Object Orientation (OO) a good idea?

Probably as good as any other programming paradigma out there.

> Does it have problems?

Sure, like every other language as well.

> Is it the right tool for everything?

No, like every other language isn't as well.

> Let's explore some of these questions in a slightly tongue in cheek and > cathartic rant.

And here I stopped reading. If you need to rant, do it over coffee and don't waste my time when even your introduction is not witty enough to keep my interest.

<comment><USER5> My sentiments exactly, kinda surprised this title made it so high up!

OOP has some fantastic applications and may have been oversold to the author for a project he worked on. OOP(s)!

<comment><USER6> > OOP has some fantastic applications

Yes, OOP is great for agent-based simulations. Only. This is a fantastic, exciting area, but it is extremely niche and tiny.

Anywhere else, OOP is nothing but an obstacle.

<comment><USER7> It's kind handy for using other peoples code. Like if you want a couple of Google maps on your page you can create a couple of map objects and set their location, colouring, add and remove markers etc. I'm not sure how you'd do that neatly without objects. Beyond that I'm happy without it.

<comment><USER8> I don't think anyone is saying don't use objects, it's the OOP paradigm that is being critiqued.

</comment></comment></comment></comment></comment><comment> d--b Can someone make a chrome extension to filter out the OOP vs FP articles on hacker news? I mean, how many more articles do we need? Is there anything new? Yes, FP is cleaner. Yes, OOP is useful for things like plugins. Yes, favor composition over inheritance. Yes, FP is impossible to read. Yes, immutability has its limits. Yes, Yes, Yes. Enough already.

<comment><USER9> The filter exists. It is community + flag. It works in all browsers.

</comment></comment><comment><USER10> Compare the DirectX XNA OOP library to the OpenGL procedural library, and you will quickly see that when OOP is done right it makes code fun and easy to work with again.

In my my mind OOP is the next logical step after procedural programming (simply packaging up a set of procedures into an object, and adding a few new ideas like inheritance and so on). Functional programming though is not the next logical step; it is a total paradigm shift. The main argument is that you get rid of state etc which means you can parallelize better - but why are no cutting edge games made in an FP language I wonder? Surely they would want to distribute all the physics collision rendering and so on to multiple cores?

It's because functional programming as a separate language makes no sense, you lose too much. But incorporating FP style into OOP languages (such as with the new C++ constexpr, C# linq, and Java lambda), and giving the programmer the _choice_ to use it when it makes sense is a far more powerful option.

<comment><USER11> OOP is about information hiding and providing well defined state transitions.

objects are used to hold a state and to act as gateway for valid transitions.

most complaints I see come from people using OO programming languages badly, leaking abstractions all over the place and making it so you have to mentally take care of the state of everything instead of trusting your objects to take care of themselves, and thus you get the worst of both world: rigidity coupled with complexity

I need information hiding because my brain is only so big, so I cannot possibly have in mind the whole application state and all it's permutation at all time while programming.

functional languages work similarly in a sense: you avoid thinking about state transitions because the only things you have to take care of is each function input and output

in a broader sense, programming becomes way way simpler if you think of your functions as having 4 well defined input output: the inputs, the return values, data from a persistent store and a state.

And with experience you start noticing that it is much much more simple and productive if in any of your method at a given time you only reduce the 4 io ports in 2: on one side you have functional languages, only ever working with inputs and returns, on the other you have OO languages, which focus so much on the input, state and state, return couples.

mastering the ability of using both styles where appropriate is the key here. but people get dragged into name specific too much, forgetting that these pattern emerged from coding and not the other way around.

<comment><USER12> Very well put. I've found that in some cases objects make a lot of sense, and the more functional approach would really end up emulating objects through closures and whatnot.

That said, especially for a lot of the typical web-related work I do, I find that I'm generally better off leaning towards a more functional approach, as most of what I do boils down to transforming database values to html in 'one pass'. I'd say many of the typical functional programming approaches are excellent for that. Avoiding mutable state has been a wonderful lesson, for example.

</comment></comment></comment><comment><USER13> OOP, as defined as a set of principles, is a complete load of horse shit. There are many more reasons other than what the article states as to why it doesn't deal with realities of software (e.g. data oriented programming solves some of them). OOP principles are likely one of the reasons it takes so long to train fresh-out-of-college employees, as they first need to learn how to forget that utter bullshit.

However, that does not mean that OOP languages are a bust. It is only the OOP _principles_ that are a problem.

So far my experience goes, I've learned to mostly stop creating analogues of real-world things (as OOP principles would have it), except where it makes sense to, and instead use OOP features to create distinct _responsibilities._ Turns out OOP languages are identical to, let's say, "responsibility oriented programming" languages.

OOP languages can also be used for other things, as previously mentioned: data oriented programming. DOP is used widely in gamedev. Gamedev also happens to be an industry that heavily uses an OOP language: C++.

Hate the principles, not the languages. There's a big difference.

<comment><USER14> > stop creating analogues of real-world things

I agree. Almost everything useful around us is the product of ideas with our needs in mind, there was no TV and TV remote control in nature, no vacuum cleaner, clothes, watches... if ever, nature inspired us. We create _artitifical_ things that make us more efficient and effective than it would be by just dealing with raw stones and sticks as they are found in nature. When it comes to today OOP we have to deal with stones and sticks again instead of thinking about a new aritifical thing that directly satisfies our needs (you call it 'responsibility').

<comment><USER13> > you call it 'responsibility'

That was simply the closest word I could come up with. You've described what I was trying to say in significantly more detail (thanks!).

</comment></comment></comment><comment><USER15> To me, as a C++ programmer, none of this really matters. I'm working on a very compute-intensive program with a lot of modules, used in professional settings. It _has_ to go fast. If using C++ means we can go faster than someone using whatever else, at the expense of needing five times the people and six times the development effort, we'll pick C++. We're interested in the maximum performance achievable with the language, not the average use-case.

Someone would ask "why not assembly/plain C/Fortran/etc.". The answer is that C++ gives you a lot of good ways to structure your code semantically, while still letting you produce tight machine code. That's the real kicker here - <USER2> need to reason about my program as an engineering construct running on real hardware, not as an expression of Computer Science algorithms.

In a nutshell, for a new programming language to be a viable way to build our core product, it has to

1\. Go Fast and let us Go Faster Than Everyone Else, preferably letting me write platform-specific assembly when I need to

2\. Interoperate with C++

I've seen a few recent languages attempt to cover 1., e.g. Go, Rust, Julia, for some use cases. However, I have never seen a language attempt to tackle 2. Not even for the case when you have vanilla classes with virtual functions and a few sane templates.

<comment><USER16> Check out Julia ' s Cxx.jl. it's probably the best c++ FFI in any language. You can even evaluation and call cpp code on the fly from the repl

</comment></comment><comment><USER17> Depends on how you use it, of course. Libraries make wonderful showcases for OOP strengths - I always like to give Java Collections as an example. But if you actually build your application code as OOP... well, I might privately think you deserve everything that happens to you because of that.

I think education carries most of the guilt for this. The typical examples given in OOS classes are stuff like Car is an ancestor of Truck and SportsCar. Which led to Beans and Entreprise Java. You never want this kind of shit with your data. Much better to use plain old maps to carry content the way God intended, and to put your effort in creating flexible and reusable methods.

<comment><USER18> > But if you actually build your application code as OOP

> Beans and Entreprise Java

I don't know. Netflix is built on Java, using OOP. It works well for them. Windows is built on OOP, quite a big application and works.

J2EE has its problems, but it also gives you a lot of functionality. Reusing methods is nice, but developers on projects with very complex business rules (does not equal simple, but large scale projects!) don't worry that much about flexible methods as they're experienced enough. Distributed transactions, session replication, etc. are slightly more important. J2EE gives you all that by default.

(And I really don't like EJBs and this kind of stuff, but don't mix up two very different levels of problems.)

<comment><USER17> > J2EE has its problems, but it also gives you a lot of functionality

I did have that in the back of my head when I wrote the comment. And speaking of, I'm also aware that OOP was very popular, and I don't feel completely comfortable when I criticize successful stuff - it must have worked for a reason. But still, that's as far as my brain can take me by itself: OOP should be used sparingly and EJB should not exist.

(For the record I code mostly in Java, though as lisp-like as I can)

</comment></comment></comment><comment><USER19> What probably scares me most is, that managers think OO is in general a wonderful best practice you need to have in the company...

<comment><USER20> Managers who think, there is a silver bullet, always scare me!

<comment><USER21> Your use of commas has changed the meaning of your sentence. They look like parenthetical commas [0] to me, so the sentence reads as "Managers who think (there is a silver bullet) always scare me!".

[0] [http://www.bristol.ac.uk/arts/exercises/grammar/grammar_tuto...](http://www.bristol.ac.uk/arts/exercises/grammar/grammar_tutorial/page_06.htm)

<comment><USER20> Thank you. I am sorry, I am no native speaker!

Unfortunately, I can not change the post any more.

</comment></comment></comment></comment><comment><USER22> [Shameless plug] For a philosophical interpretation on the differences between OOP and FP, you may enjoy my gist: Descartes, Berkeley and Functional Reactive Programming

[https://gist.github.com/dmvaldman/f957dd9a8ed3f6edf35d](https://gist.github.com/dmvaldman/f957dd9a8ed3f6edf35d)

<comment><USER23> It's actually a common misquote of Descartes to say "I think therefore I am." A more proper translation is "I think, I am" which has significant implications for his philosophy.

<comment><USER24> It is not a misquotation. In Meditations on First Philosophy what he says translates to "I think, I am" but he'd used "Cogito ergo sum" (I think, therefore I am) in previous works.

Subtlely different meanings to be parsed...

</comment></comment></comment><comment><USER25> This article is just pointing at the flaws, not really offering any alternative. It is just as GP said, a rant better kept for the water cooler area.

You can guess that functional programming is going to be his response I suppose considering this page is the second part of a functional programming article. (the first part being missing)

If you want to analyse, you would need to also talk about what OOP is good at and how that translate in whatever other paradigm. This article only concludes with a "I do think it is a valuable mechanism for developing software", but there is absolutely no backing for that statement anywhere in the article.

I tend to agree with GP. At the end of the day, for general programming, any paradigm is going to end up producing similar quality of code. Developer competence, motivation and budget are going to be #1 factors that determine code quality.

Google, OSS, Modern IDE, Engineering practices like Continuous Integration/Deployment, TDD/BDD are all having a much bigger impact on the code quality than the specific languages or paradigms.

<comment><USER17> > At the end of the day, for general programming, any paradigm is going to end > up producing similar quality of code. Developer competence

I'd say that "pure" paradigms tend to be almost equally bad (tried functional programming in production code, wasn't all it's advertised to be). But this actually leaves you with more freedom, because you have to pick pieces and create your own style. So it turns out to be more important, not less, that you understand the how and why of each paradigm.

As for how good this particular article was - well, I agree with the premise and it gives links to sources. May not be the Mona Lisa of articles, but it got my upvote. I'm not a regular HN reader so it's the first article on this topic I've seen in a while.

</comment></comment><comment><USER26> "All evidence" [https://xkcd.com/605/](https://xkcd.com/605/)

</comment><comment><USER27> I appreciate there's something I'm missing, but:

I use closures to hold state all the time in node, I still don't understand why state in a closure is better than state in an object.

If someone could explain this I'd be grateful: articles like this just seem to say 'state is bad' and ignore that it still exists in functional scopes.

<comment><USER28> State in a closure is equally as bad as state in an object. The difference is FP gives you ways to manage and isolate state that simply don't exist in OOP.

</comment></comment><comment><USER20> "All evidence" seems to me a real gross overstatement here. The author collected some topics, where he means that OOP is bad and sticks some (partly related) statements of other people to it and wants to convince with that, even when he makes some valid points here [1].

I do not buy that.

The reality is, that when OOP is correctly executed (and there is the real culprit, since few people have really understand it!) it really can help you to lower the complexity of programs -- and that is decisive, not some halve- religious statements.

[1] One example: Inheritance vs. Composition -- even OOP people have seen the problem that overuse of inheritance is bad. But they don't throw the whole thing out of the window, but tell where to use it or restrict its usage. Don't just find the problems and fanatically throw all (even the good stuff) out of the window!

<comment><USER6> > it really can help you to lower the complexity of programs

Yet to be proven. I _never_ seen a single example of OOP bringing anything but more unnecessary complexity.

<comment><USER20> Than you might not have seen good OOP designs. My experience is different -- when you really apply good OOP design to software, you can reduce complexity and come to a clearer overall design. But of course the typical 5 day Java or C++ course will _not_ get you there. You must learn to think in OOP -- and that is a process that might take years.

<comment><USER6> Could you please point to a classic example of a good OOP design, where it is clear that OOP made it simpler.

</comment></comment></comment></comment><comment><USER29> Zed Shaw talked about experiences teaching programming in this LXTHW series. I cannot cite the exact source right now, but in essence he said, that novices grasp all concepts up to OOP, where there is no more analogy in computer architecture and people seem to get stuck.

</comment><comment><USER30> Seems as good a thread as any to drop this

Bjarne Stroustrup - Object Oriented Programming without Inheritance - <USER3> 2015

[https://www.youtube.com/watch?v=xcpSLRpOMJM](https://www.youtube.com/watch?v=xcpSLRpOMJM)

</comment><comment><USER31> Does anybody know of any language that supports OO, but that lets you declare pure functions/methods - enforcing that those pure functions/methods only use other pure functions, don't use global objects, etc? Lately we're adopting Redux [1] together with React and the idea of being able to mix functional and OO in a better way looks more and more interesting to me.

[1] [https://github.com/rackt/redux](https://github.com/rackt/redux)

<comment><USER32> _Does anybody know of any language that supports OO, but that lets you declare pure functions /methods - enforcing that those pure functions/methods only use other pure functions, don't use global objects, etc?_

Well, turns out that one of the oldest programming languages in existence, Fortran lets you do OOP, it also has _pure_ functions and subroutines. I'm talking about about Fortran 95/2003/2008:

[http://h21007.www2.hp.com/portal/download/files/unprot/fortr...](http://h21007.www2.hp.com/portal/download/files/unprot/fortran/docs/lrm/lrm0157.htm)

<comment><USER31> I would never have guessed. I wonder why this didn't spread more - it looks like a great way to mix FP and OOP.

</comment></comment></comment><comment><USER33> As a comment indicates, all evidence points to this article being a load of bullshit. There's not a single concrete example in it that proves anything of the author's claim. To counter, I think this will do nicely: [http://www.johndcook.com/blog/2015/07/31/the-success-of- oop/](http://www.johndcook.com/blog/2015/07/31/the-success-of-oop/)

</comment><comment><USER34> I really like many points of FP. I like to stick to immutability, map-reduce and expecially Redux.

But after I saw a comparison of OOP and FP [0] I had to laugh a bit. What about monads and category theory? I also didn't fully grasp FRP with all its streams and lifting.

[0] [https://pbs.twimg.com/media/CNPKc6xU8AApYPy.jpg](https://pbs.twimg.com/media/CNPKc6xU8AApYPy.jpg)

</comment><comment><USER35> This argumentation is compilation of unjustified and demonstrated claims. It really doesn't help in understanding the author's point.

</comment><comment><USER36> I found it ironic that he used a quote from Alan Kay to attempt further his point that "object-oriented programming is bullshit"

<comment><USER37> Yes, and the 'quote' from Dijkstra, who would certainly have known about OO's Norwegian roots, sounds bogus as well. Wikiquote lists it as unsourced.

A bit of Googling yields no source for the alleged Alan Kay quote either.

</comment></comment><comment><USER38> I believe OOP gained such a foothold in programming world because it was (and still is) very useful for building GUIs on the PC. Since PCs have taken over the world, so had the OOP. But in other areas the OOP model is questionable. For example, you have transaction processing applications that have been built for years on mainframes with different models.

</comment><comment><USER39> I agree with Carmack on:

"'good C++' is better than 'good C'"

OOP has some brilliant patterns. It is also very hard to do correctly.

<comment><USER6> Good C++ is a generic C++. And generic programming is incompatible with OOP. Those who do not agree with this statement should stop using STL.

</comment></comment><comment><USER40> A little off-topic, but do people think that mainstream software development will ever be mainly functional, or more likely to be an OO-Functional hybrid like OCaml, Scala, or F#? Just wondering what to learn next.

</comment><comment><USER41> The best way to see through language paradigm war propaganda is to look at pseudocode. Scientists, mathematicians, logicians write tons of pseudocode and it's almost entirely procedural.

<comment><USER42> As one of those people who have used pseudocode in papers, I have to disagree. In a scientific paper, you describe what you have in mind using mathematical definitions. This makes it easier to reason about (proofs) and to describe it in an unambiguous way to other people (papers). Pseudocode is used to describe an algorithm following those mathematical definitions. In your paper, you might use sets. A set is defined by what it contains or does not contain. Never by how the elements found their way into the set. Including that kind of implementation detail is considered bad form (cf. forest and trees). If you wish to implement it using purely procedural code, FP, or OOP is up to you. Don't think scientists shun any kind of method just because they rarely talk about it. And for the record, I remember a number of papers that used pseudocode that could have been directly translated to working code using an OOP paradigm.

<comment><USER41> The algorithm might take set(s) as input, sure. If that's inherently OOP then C structs are OOP. In any case, what actually happens to those sets once they're declared, will probably be procedural. "Let I be the intersection of A and B." "Let Restriction be those elements of S which are positive." Etc. You'll rarely ever see factories, managers, private variables, explicit inheritance, or any other flagship OO mechanisms in pseudocode.

<comment><USER42> > You'll rarely ever see factories, managers, private variables, explicit > inheritance, or any other flagship OO mechanisms in pseudocode.

Because they are implementation details that have no place in pseudocode. Their absence there does not say anything about their usefulness in general. You can't point at some observation about pseudocode and say "See, they don't use it so it must be rubbish." Exceptions, handling of error variables, monads, unsigned ints are also absent from typical pseudocode (unless the context is _about_ those concepts). Does that make them useless concepts aswell?

</comment></comment></comment></comment><comment><USER35> This argumentation is a compilation of unjustified and demonstrated claims. It really doesn't help in understanding the author's point.

</comment><comment><USER43> Wow, so many people commenting in the thread below that article seem to have swallowed tiny uncle bobs.

</comment><comment><USER44> For an article with evidence in the title, it is sorely lacking. Pretty words are proof of nothing.

</comment><comment><USER45> Wonder why the author doesn't mention Smalltalk. Or Ruby...

</comment><comment><USER46> Entirely content-free bullshit article.

</comment><comment><USER47> With billions and billions of wealth created by SaaS companies that base their platforms and websites on OOP.

<comment> max-a >With billions and billions of wealth created by SaaS companies that base their platforms and websites on software.

FTFY

<comment><USER47> Your data points may differ, but eBay makes profits of 1B on mainly a Java platform. Other large companies use Ruby, PHP, Python and Java which all are based on OOP.

But I would be interested in your arguments.

</comment></comment></comment><comment><USER48> Humanity has to accept that half of any population (including the team in our current workplace) is less intelligent than the other half. Then when we address a problem we have to accept that both halves will have to touch the problem at some stage in a project. Following this we need to aim for simplicity rather than complexity. With this in mind I think that both FP and OOP _can_ be used to build simpler programs but that OOP has in the past failed in doing this.

Basically I think we need to use tooling (in which I include languages and paradigms) that aim to come with less foot-guns and more safety rails.

<comment><USER48> Just wondering why people don't like this post? Anyone care to explain why I'm wrong or maybe discuss?</comment></comment>


Dollar General Hits a Gold Mine in Rural America - <AUTHOR> https://www.bloomberg.com/news/features/2017-10-11/dollar-general-hits-a-gold-mine-in-rural-america <comment><AUTHOR> Money quote: _"It reminds me of a craps table," Brown, the commercial real estate analyst, says. "Essentially what the dollar stores are betting on in a large way is that we are going to have a permanent underclass in America. It's based on the concept that the jobs went away, and the jobs are never coming back, and that things aren't going to get better in any of these places."_

<comment><USER2> I am a very proud and happy customer of Dollar Tree. I assume the business model is similar to Dollar General.

I get so much awesome shit from there, $1, and no tax on groceries. Portion sizes are proper, quality/safety of off-brand food is completely acceptable.

In a world where millions of Americans are spending $10 minimum per day on Starbucks coffee, I am probably spending $1-2 per day on my entire daily intake of food.

And it's all thanks to Dollar Tree, or alternatively Costco if I am nearby, where prices are similar thanks to wholesale prices.

And I'm not unemployed, I should add. Just a complete and total cheap skate, employed or not, both of which I have experience with :)</comment></comment>