Better Software Design with Clean Architecture - <AUTHOR> https://fullstackmark.com/post/11/better-software-design-with-clean-architecture <comment><USER2> This design puts entities in the middle - everything else pivots around entities. Additionally, it uses the OO approach of implementing logic as methods on the entities.

After a couple of decades of experience, I've come to the conclusion that this isn't right. Most business rules involve processes, which are inherently procedural, or, from another perspective, functional - functions of the whole state of the system to a new state of the system. Most processes don't logically belong on an object, and when you stick them to one end, you create lots of problems for yourself.

Just take that example Student entity class; what stops you from writing:

        student.RegisteredCourses.Add(course);

Moreover, when you have a relation between two entities, it's not uncommon for the relation to be modelled at both ends; that is, a student has a list of courses, and a course has a list of students. Do you implement the same validation at both ends? Make one end (choose one) read-only? Do edits done on one end automatically turn up on the other end? How do you protect the visibility of methods that keep either end in sync, without exposing invariant-violating APIs to other code?

Invariants and validations for fields are trivial with an OO approach; for entities, they're reasonably easy, but sometimes you need partially invalid versions while editing or constructing an entity; but once you bring in multiple entities, and relations, everything starts getting hairy pretty quickly. Assertions and validations that would be trivial to write [1] in a relational language like SQL aren't possible in an object-oriented language without a lot of system-building.

So I've come around to the idea that the database is a better thing to put at the centre; that encapsulation and hiding of the main fact store is harmful to the architecture of a system, especially in a heterogeneous environment where your entities are represented in different languages, all backed by the same fact store.

[1] Trivial to write, but not necessarily cheap to evaluate. I'm not advocating writing all global validations in SQL.

<comment> UK-AL This is solved by DDD and aggregates. Here's how i would do it.

       Course - Aggregate Root

       Student - Aggregate Root

           RegisteredCourses[RegisteredCourse[]) - Sub Entity Collection - with id reference to course. With metadata like date time when the registration occurred.

           RegisterForCouse Method

There should be no mutable public properties, internal methods should be private. Everything should go through an aggregate root method.

<comment><USER3> How did you decide that the registration is a property of the student and not the course?

<comment><USER4> Registration is definitely _not_ a property of the student.

It's always a good idea in these situations to appeal to real life. The actual business will point the way of the business simulation. In the real world we don't ask students to register for a course. Instead students ask the _Registrar_ to register for a course. When the Registrar makes her decision she considers far more than just the internal state of the Student; she considers (1) does the course have any available seats? (2) has the Student met all the course pre-requisites and, most importantly, (3) has the student paid his tuition and is he even a valid member of the university community.

What the Student does have is a history and a context -- that is, a state -- that must be considered when registering for courses. The student may also have preferences -- courses he wants to register for.

The language of the business should guide these decisions always. A student submits a request tfor a course and it is the office of that accepts or denies this request.

<comment> UK-AL This guy has been thinking about this properly.

<comment><USER5> Take this thinking to the end and realize that it leads to freestanding functions. In general all the context of the program is needed to execute a functionality. It's not like the registration office owns all the students. It's not like a registration wouldn't change the student's context. Students are both an independent and related concept. The proper object to call most things on is a "Global" object. Now instead of

        Global.do_some_thing(foo, bar)

just

        do_some_thing(foo, bar)

There you have it. OO is an unsound approach which survived so long mainly due to the perceived real world "analogy" and because the Object-Verb-Predicate syntax simplifies code completion.

<comment><USER6> I like the simplicity of this. If the app is of appreciable size, do_some_thing depends on databases, webservers, external processes, filesystems and configuration. How do you test/debug/explore its functionality without setting all of that up?

<comment><USER5> I would actually say these all make good "objects", i.e. isolated pieces. On the other hand, no runtime polymorphism is needed. To avoid OOP at a syntactic level, what do you think of the following?

\- For tests at a smaller level, decompose the application such that most parts are easily testable in isolation (without external "hard" dependencies).

\- For mid-sized tests with external dependencies but mostly unidirectional dataflow, setup a global virtual table with all the mock methods (and instances) that are needed. Alternatively, traditional linking methods.

\- For larger "integration" tests there is no substitute to testing the real thing. At some scale and level of interactivity with the database, you just have to talk to the true filesystem, the true database etc. You can still setup a test instance for most cases where there is no interaction with external services.

</comment></comment></comment></comment></comment></comment></comment></comment><comment><USER7> I've seen this a few times before, and it led me to believe that I was stupid. Comments like _"...business rules simply don't know anything at all about the outside world"_ left me wondering what components that DO know something about the outside world, actually know about the outside world?

Turns out that the answer is a data access component might know where to find a database, and a client app might know where to find a web service. These things were rather obvious to me, so I failed by trying to find loftier answers. Which probably says a lot of about how I think.

Also, the concentric circles did nothing for my way of thinking, as messages are linear - they start from a place, and they end in a place. Thus a stack was a lot easier for me to digest than these concentric circles.

And finally, the ambiguous language. Why should I care that there are enterprise business rules, and application business rules? They're both rules. Rules go into a component in the middle, or business layer.

And thus I found it a lot more useful to think of app design in terms of vertical tiers (hardware abstractions), and layers (software abstractions). Tiers include perimeter, DMZ and corpnet, and layers include (but not limited to) user interface, façade/service gateway, business layer, and data layer. With some cross-cutting concerns like comms, security and operational management (logging, exceptions and so on).

I don't think either is better than the other. It was, however, the first time I really understood that two people can be very knowledgeable about the same thing, and yet speak using a completely different vocabulary.

<comment><USER8> > _Also, the concentric circles did nothing for my way of thinking, as > messages are linear - they start from a place, and they end in a place. Thus > a stack was a lot easier for me to digest than these concentric circles._

Messages might be linear but scopes are encompassing inner scopes. Encapsulation is not usually depicted as a stack.

> _And finally, the ambiguous language. Why should I care that there are > enterprise business rules, and application business rules? They 're both > rules._

Obviously because different scopes apply to the former than to the latter. TFA even clarifies that: "The key is that they ("enterprise business rules") contain rules that are not application specific - so basically any global or shareable logic that could be reused in other applications should be encapsulated in an entity".

In general, the similarities ("they're both rules") between two things don't say much (if anything at all) without considering the differences. Shiitake and Amanita Muscaria are "just mushrooms", but one can kill you.

<comment><USER9> As an aside: according to wikipedia, there are no recorded deaths from ingestion of Amanita Muscaria. It's not really a poisonous mushroom, though it can have intense psychoactive effects when taken in large quantities.

<comment><USER8> > _As an aside: according to wikipedia, there are no recorded deaths from > ingestion of Amanita Muscaria._

Well, the Wikipedia lemma puts it this way:

      Although classified as poisonous, reports of human deaths
      resulting from its ingestion are extremely rare. A fatal
      dose has been calculated as 15 caps.[55] Deaths from this
      fungus A. muscaria have been reported in historical journal
      articles and newspaper reports,[56][57][58] but with modern
      medical treatment, fatal poisoning from ingesting this
      mushroom is extremely rare.[59] Many older books list
      Amanita muscaria as "deadly", but this is an error that
      implies the mushroom is more toxic than it is.[60] The
      North American Mycological Association has stated that
      there were: "no reliably documented cases of death from
      toxins in these mushrooms in the past 100 years".

</comment></comment></comment></comment><comment><USER10> Oh look, more kludgy over-designed enterprise gumf.

When are people going to learn that if you just start with the entry point with granular components, letting each define the interface for its dependencies, you get a much nicer, looser, more flexible structure than these enterprise "patterns" that ultimately all just turn into a big ball of mud?

Stop pretending you can design codebases.

<comment><USER11> People forgot at some point that design patterns are for solving problems. The key being that you should only be solving problems you actually have, and stop making up imaginary problems in your head before you even start coding.

My code is typically some dumb data objects, static functions to apply rules to that data, and a bunch of interfaces for abstracting external dependencies. The code that ties everything together lives at the entry points, and is hopefully written like one is reading a requirement.

To take the course registration example, the "register" entry point might look something like:

        register(studentID, courseID):
            // Load student from data store interface.
            Student student = this.datastore.getStudent(studentID)

            // Business rules for whether a student can still register for classes.
            // This would check things like course overload and duplicate registrations.
            if (!Students.canRegister(student, courseID)):
                return CannotRegisterError

            // Record registration.
            this.datastore.addRegistration(studentID, courseID)

Advantages:

* Data objects are dumb. No need to even test them.

* Rules are all static functions, so you can call them anywhere, anytime, including for testing. Extremely flexible and allows easy remixing of rules for new requirements.

* All external dependencies live behind an interface, so they can all be mocked away for testing.

<comment><USER12> What kind of design is this? Is there a name for it? I'd like to read more (both out of interest and being skeptical of how this scales)

<comment><USER11> I should come up with some catchy name and a blog post for it. It's basically my own custom mix of procedural (entry points), functional (static validations), and design by contract (external abstractions) in the noun worlds of Java and C#. I arrived at it after seeing too many instances of:

* Architecture / design pattern lasagna, where breaking through abstraction layers felt like Inception. And adding a data field meant going through all 5 layers of code...

* Inheritance for functionality instead of typing.

* Also, breaking Liskov substitution willy nilly then wondering why things are hard to reason about. (Because your code becomes entirely reliant on the types actually present at runtime, since you can't rely on semantic equivalence.)

* Tacking methods into data objects because that's where the data is. See other comments on this post advocating a "register" function on the Student object, or should it be on the Course class... Answer is neither. Encapsulation is about maintaining invariants. It's not about putting all functions related to students in the Student class.

* Zero unit tests because external dependencies weren't isolated and all the logic is hard coded into exact use cases, which eventually end in hard coded external dependencies...

</comment></comment></comment></comment><comment><USER13> I had been quite skeptical of Clean Architecture when I first came across it. I don't find Uncle Bob's post on it particularly insightful; for me it's not vocational enough.

Then a few years ago I had to maintain a software stack written by contractors from Pivotal ([https://pivotal.io/](https://pivotal.io/)) in a Clean Architecture style - it was truly a revelation for me; akin to that "aha" moment of fully grokking homoiconicity in LISPs.

Now, up until this point, all code I'd encountered at Twitch heavily reflected the domain of the problem it was solving and the technology in which it was written. That is, if you were looking at a certain piece of architecture you had to really fully understand not only _exactly_ the intent of that code base but also the _details_ of the framework in which it was written. As codebases increased in number and size, it became much harder to scale as an engineer. Jumping from a Rails monolith, to a highly concurrent Golang HTTP CRUD-API, to a highly asynchronous Twisted-Python request routing system (broadly the main three backend techs) had a very large cognitive load. The eng org cleaved along these lines and maintaining velocity in that world was very hard; attempts to introduce new tech or join chunks of the org took on a "religious" tone.

So initially coming across this clean architecture stack felt very similar to that. It had a lot of "weird new things" in it, but once I understood that much of it was routing (tagging inbound requests in a manner that a deeper layer could understand the intent of the request and pass it to the correct interactor, which would then work on the appropriate entities) it suddenly became incredibly easy to hop around the code base and update the important aspects of it.

I asked the authors who had been contracted to build this system where they got their inspiration and they cited many lunchtime discussions and pair programming sessions influenced heavily by Uncle Bob's clean architecture.

I would have really enjoyed seeing more systems built like this because, to the maintenance programmer, it was _very_ clear where things had to go. However only encountering one Clean Architected system didn't really give me a solid idea of how well it would scale across various domains.

<comment><USER14> That codebase sounds interesting, is there a change some parts of it were open sourced?

<comment><USER13> Unfortunately no :(

<comment><USER15> Oh wow. I can't be sure, but I'm pretty sure I'm the engineer at Pivotal that you paired with. I definitely remember you making reference to homoiconicity in lisp when we were pairing the day that Clean Architecture really clicked in your head. It was a really cool moment.

There's a lot of engineers at Pivotal, and we have a lot of projects, so maybe I can prove I worked on that codebase by referencing obscure details from it? I remember writing a LOT OF TESTS that used quotes from Wutang Clan and 36 Chambers as strings for names of entities, and a lot of references to 90s hip hop. Was this the same project?

Also, I took some time after our project (and several others) to start a small example of applying Clean Architecture in a toy Go Project, which is open sourced. Maybe check it out?

[http://github.com/tjarratt/go-best-practices](http://github.com/tjarratt/go- best-practices)

<comment><USER13> Yes, it was you! Nice to reconnect :)

</comment></comment></comment></comment></comment><comment><USER16> Surprising this has been written in 2017. It looks like java written a decade ago.

This can be a kind of organizational solution much like microservices to separate concerns. This is important when collaborating with a large amount of people. Clear boundaries and all that.

You pay for those boundaries with a convoluted mess of classes that describe the design pattern rather than the business logic. You end up with AbstractRequestInterfaceFactory type stuff.

Trade offs. Decide when they're worth it.

<comment><USER7> _" You pay for those boundaries with a convoluted mess of classes that describe the design pattern rather than the business logic. You end up with AbstractRequestInterfaceFactory type stuff."_

I disagree. If a design (call it an architecture) is clean and coherent, it's obvious.

Because obviously a client must send the order to a server, which is protected by a gateway. And of course that gatway validates the client request, and the data coming in. And of course the server must have business rules to validate and process the order. And clearly the business components must call a data access component to persist the orders to a database. Simple, no?

<comment><USER17> > Simple, no?

what happens when the business rule clashes with the database's constraint implementation, because different people either misinterpreted, or due to incompetence or miscommunication?

I think splitting up sounds great in theory, but in practise, has lots of pitfalls. That's not to say it's not a good idea, but one musn't look at it with rose-tinted glasses.

<comment><USER7> Well you'd test, which would catch that scenario. Assuming you're not testing and discover it after releasing to production you'd just use your change process.

Either way this is just part of building a system. Refector, re-test and release (or re-release). It's hardly going to be the only bug you find.

</comment></comment></comment></comment><comment><USER18> I been using a very similar pattern [Port and Adapters][http://blog.ploeh.dk/2016/03/18/functional-architecture- is-p...](http://blog.ploeh.dk/2016/03/18/functional-architecture-is-ports-and- adapters/) since moving to F#, paired with [Railway Oriented Programming][https://fsharpforfunandprofit.com/rop/](https://fsharpforfunandprofit.com/rop/) for the 'Adaptper' level and using DDD for modelling the 'Entities' & 'Use Case' layers' and it been working well for me so far.

Scott Wlaschin has recently released an [ebook][https://pragprog.com/book/swdddf/domain-modeling-made- functi...](https://pragprog.com/book/swdddf/domain-modeling-made-functional) on the topic which goes into more detail.

<comment><USER19> These are all architecture ideas I've been interested in, I'll have to check out the book.

Overall architecture in development is still early on in maturity.

</comment></comment><comment><USER20> You know someone is certified when you have to scroll code sideways because the names don't fit the screen. I thought we already agreed that process is the opposite of progress? I mean come on, RequestCourseRegistrationInteractor, who are you trying to impress here? These processes were designed to turn humans into machines; to decrease the dependence on creativity and skill at the cost of additional effort and complexity; to enable large groups of unmotivated developers to deliver mediocre software reliably; which makes them sub-optimal for any other use case.

<comment><USER21> I think you are opposing it for the wrong reason.

There should not be a lot of room for creativity when implementing specific business rules. The goal should be clarity and readability.

These convoluted patterns obscure the logic and confuse the reader with their pointless abstractions.

<comment><USER20> I think you are confused. The whole point of software is to create something that didn't exist before, building the same software over and over again doesn't make any sense. I'm not talking about creativity in interpreting business rules, I'm talking about creativity in building software.

</comment></comment></comment><comment><USER22> IMHO, the most important thing in architecture are the concerns and goals of the architecture. Not the particular architecture itself. A single architecture can't check all the marks, or you end up with a monster. The job of an architect is to identify the main risks and pain point of a particular system, and adapt the structure of the project to address them best.

"Enforcing separation of concerns" is a good one. But so would be "identify the various runtime threads of your system easily", or "minimize code surface responsible for mutation of shared data", or "decouple configuration primitives from the components themselves".

Those concerns are more or less important depending on your use case. MMORPG server code or regular desktop app, or mobile webapps sold as templates, all have very very different concerns, so i dont think it would make sense to use a single architecture as a template for every problem.

</comment><comment><USER23> It's interesting to note that a layered dependency architecture is nothing new. As a matter of fact, it was one of the fundamental design decisions of the 1968 THE Operating System [1], on which Edsger Dijkstra had been programming and designing extensively.

[1] [https://en.wikipedia.org/wiki/THE_multiprogramming_system](https://en.wikipedia.org/wiki/THE_multiprogramming_system)

</comment><comment><USER24> Oh god no. DON'T POLLUTE THE CURRENCY.

This is a massive fuck up and it won't scale or be modular. The idea is fine but you need the entities/currency into a smaller core with your DAL and relationship objects above that layer. The only functions your currency should have are accessors or read-only convenience calculations. Other operations should be handled by another parent because let me tell you that that Course collection is going to end up being null or empty A LOT when it "shouldn't" be.

You'll want your use cases to return shallow object graphs (e.g. GetCourses => courses.Enrolled => StudentName, StudentId) from the data layer/services and then if you want to look up a Students details you make that another call. The alternative is to run some sort of "scope" object that defines the depth of graph you want when accessing a general api. The thing you're looking to avoid though is returning more information than is necessary.

Also who taught this guy to model? Students are in courses in this model the courses are inside students and that's silly.

<comment><USER25> For shallow vs deep, what I decided for my code base was that I'd pick the appropriate depth as a general rule for an object and not worry about I/O micromanagement.

If it is cheap to pull the additional data and it makes sense to expect that data in using the object, I'd simply embed the representation. If it was expensive or not commonly used, I'd include a reference to the data (usually ID(s) of the data).

Then in the repository, I'd just get everything necessary to return a full object as designated.

An onion architecture gets funky if you don't know if the object you are working with has all its data, especially because the object itself shouldn't know how to fetch more data about itself.

In this particular case, the two objects probably shouldn't have ANY domain connection, and there should just be a method on the course repository to "GetCoursesForStudent" that accepts a student ID. It's perfectly ok to model relationships in the database that don't have parallel relationships in the domain objects.

Or, one could create a "SemesterEnrollment" object that contains a student object and a collection of courses. Which would probably make more sense, as that's the object that should be referenced to generate bills, report cards, etc.

</comment></comment><comment><USER26> I was studying this topic yesterday, the same idea with another name, functional core and imperative shell.

Came across this collection of articles and talks, for anyone interested: [https://gist.github.com/kbilsted/abdc017858cad68c3e7926b0364...](https://gist.github.com/kbilsted/abdc017858cad68c3e7926b03646554e)

</comment><comment><USER27> As a teenager I would sit in the offices of grey haired old men at the software company I had no business working for after dropping out of high school. These men would hand me a photocopy of an OOPSLA paper, or something from a journal. I was told to read it, then come back and discuss. This was my intro to many areas of software architecture.

I became familiar with the names of people like Booch, Rumbaugh, Jacobson and others. Over the years I learned various object oriented programming languages and patterns. Each new thing was like discovering a horcrux, at first magical and powerful, but ultimately evil. Later I began to learn functional programming and that's what I try to use most these days but it too has its promises and lies. I have built and helped others reason about many many complex systems and all I can say is this:

The only system that is well ordered internally is the one that accreted complexity in increments, and was continually refactored along the way. Best practices be damned.

Those systems might not look how you'd design them were you Uncle Bob. They work, can be understood, and can be modified without much consternation. We all can recite examples of masterpiece turned morass. Conversely some of us can recite an example of a frog, a weird complex beast but ultimately very well adapted to its environment and quite resilient. Frogs are not beautiful but great at eating bugs.

One fact of complex systems is: humans cannot know the "right" design until AFTER he has arrived at it.

If a human can know the design a priori then the problem is NOT COMPLEX and if it is not complex then it is not modern software.

This is humbling knowledge for someone who wants to believe there can be a language and pattern of order for all systems. One that can be expressed in anything less precise than code itself.

Given a fanciful machine that could assemble subatomic particles in any fashion the user desires none of us could, having never seen one, design a frog.

</comment><comment><USER25> I've been using a very similar architecture on an application for about 2 years now, and it's been incredibly smooth to work with, especially in Go (passively satisfied interfaces and enfirced lack of inheritance), though I do feel like the article overcomplicates the design (also recommend looking up onion architecture).

Basically, for me, it boils down to the following:

1\. Create domain package(s) with the basic business entities (users, vendors, products, etc) - can't import anything. 2\. Create usecases package(s) that acts on these objects and can import anything in the domain package, but nothing else (though can accept repository store interfaces). 3\. Create infrastructure packages for taking to databases, caches, etc - can't import from rest of application. 4\. Build repository stores to translate between repositories and domain objects (can import domain and usecases, and accepts interfaces for infrastructure). 5\. Add controllers/main packages that build repository dependencies with infrastructure config, and pass those interfaces into usecases that do the necessary work and spot back results (imports everything).

The end result is a bit topsy turvy to get used to at first, but then it's a dream. Extremely easy to test (very little dependency coupling in each package), and the most complex parts of the application logic are totally isolated from the complex parts of the infrastructure, so you end up with less cognitive load when dealing with either.

After my experiences so far, I can't see ever switching back to "top down" architecture instead of "inner out" when given a choice.

</comment><comment><USER28> Also relevant to this discussion is 'Domain Driven Design and Onion Architecture in Scala' by Wade Waldron from Scala Days 2016

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

</comment><comment><USER29> The entire time I read this I kept thinking of the fundamental theorem (and its corollary). Also, considering this an all-solving hammer has the risk, like with everything, of being premature optimization, methinks.

</comment><comment><USER30> It's so refreshing to see vibrant discussion of _how_ a domain layer should be implemented, when I have practically been run off from teams for suggesting that a domain layer pattern, any domain layer pattern, should be used.

I've seen enormously complex domains implemented as DTOs that are acted duplicately in ORM queries, in PDF rendering, in CSV exporting and then again in CSV importing.

</comment><comment><USER31> Which language is he using? Is that C#?

It looks like this only deals with in-memory data structures. How does stuff get read from / written to the DB?

<comment><USER32> Actually, very similar, since Entity Framework is usually used. Sources implement the IQueriable interface which lets you write queries with method chaining or LINQ. To be honest, it kinda looks better than it is. In reality I find it produces sub-optimum performance and a lot of things can not be done without spilling query logic to the app. Not to mention a lot of linq/method chaining queries cannot be translated to SQL (by the database provider).

<comment> UK-AL You can persist this model using anything you want.

You would have some kind adapter/library that handles the persistence.

It would take these models, and covert them into your datastore.

<comment><USER31> How would that work in practice? Would this line stay the same:

        RegisteredCourses.Add(course);

And magically trigger an insert in the database?

<comment> UK-AL The repository pattern in the original example would allow you serailise your objects to whatever datastore you want. His object design isn't that great for being persistence ignorant though. I would instead do something like this.

        Course - Aggregate Root

        Student - Aggregate Root
            RegisteredCourse[] - RegisteredCourses - An array objects with date time of registration, and id reference to course.

The method for adding a course would simply create a new RegisteredCourse and place it in the registered courses array.

_studentRepository.save(student) would be a simple matter converting this in memory representation into sql.

I'm not big fan of using lazy loading, and direct references to other aggregates inside of other aggregates. This makes mapping these models without ORM difficult.

<comment><USER31> Can you show in real code, what you mean? From the text you wrote, I cannot grok it.

</comment></comment></comment></comment></comment></comment><comment><USER33> If you see an architecture that has a box or a ring with the word "controller" in it - the design is wrong.

</comment><comment><USER34> It's a shameless plug, but I just have to throw in [http://manuel.kiessling.net/2012/09/28/applying-the-clean- ar...](http://manuel.kiessling.net/2012/09/28/applying-the-clean-architecture- to-go-applications/)

</comment><comment><USER35> Every new system starts out fairly clean, at least in certain dimensions. Then the real world intervenes.

</comment><comment><USER36> At what point should basic validation be completed?

<comment><AUTHOR> Superficial validation on things like form fields still occurs up in the UI layer before a Use Case is invoked. Additional validation is likely to happen in the Use Case as well. It's a ubiquitous thing so just like in any other app it should be happening at a few different points but the stuff validated in the Use Case is going to be related to the business rules it's trying to execute.

<comment><USER7> My approach has always been to validate anything that crosses a trust boundary. This might be user->app; client->gateway; or app->database.

<comment><USER37> >My approach has always been to validate anything that crosses a trust boundary.

That's a good approach unless a validation requires a db call with inner join (for example). This becomes too costly to do it 5 times (for example) just to get something written into db.

<comment><USER7> It remains a good approach, even in your scenario - because that perf problem is solved using a temporal cache.

<comment><USER2> Caches are an excellent way to introduce path-dependent, time-sensitive bugs.

<comment><USER7> The safest, most bug-free code is no code at all.

</comment></comment></comment></comment></comment></comment></comment><comment><USER38> looks like onion architecture, no?

<comment><USER25> Basically "Uncle Bob" took the onion architecture, changed it slightly, and took ownership of it.

But yeah, regardless of the lame appropriation, a solid concept.</comment></comment>


Hacker News clone for Python - <AUTHOR> http://www.pythonmeme.com/ Another weekend project, only focus on python news, still not support comments. <comment><USER3> You're over your Google API quota. Also, we can see the error traceback - <USER2> that supposed to happen? Anyway, this is really good that you're trying awesome stuff like this and you're 11. At your age I was still writing noughts and crosses XD

</comment><comment><USER4> You want me to sign up with no privacy policy? And using my Google login? Nope. Go find a free policy generator. Follow the instructions and put it up on the site. It shouldn't take you more than an hour.

Edit: I see in your "about" you're 11! I'm shocked -- what a fantastic show of skill on your part. However, as smart as you are, at your age you might not get the nuances of privacy policies. Shoot me an email (check my profile) and I'll help you create one.

<comment><USER5> 11 years old, or a programmer for 11 years?

<comment><USER6> I think he means the latter considering that he seems to be employed by one of the biggest phone manufacturers. However, it's in China so I wouldn't be too shocked if he actually is 11.

<comment><USER7> Oh stop being silly and pretend that you know something about China

</comment></comment></comment></comment><comment><USER8> While the developer deserves his/her fair share of criticism for the site being inaccessible, I think that this also reflects poorly on Google App Engine.

The quotas should be used to capture revenue from those who regularly exceed a defined level of resources. They should not be used to punish or extort from those who find themselves suddenly very popular, but will (in all likelihood) settle into a normal traffic pattern somewhere on the order of one percent of the spike.

I recognize that many, if not most, other hosting and *aaS providers operate the same way. Still, the second thing I muttered to myself upon encountering the traceback was "Don't host on GAE".

I'll also note that a significant percentage of the upvotes given to this HN listing occurred without having seen the site!

<comment><USER9> pair.com, shared hosting, throws away your highest stat day per month.

</comment></comment><comment><USER10> <http://www.pythonmeme.com/about>

> I'm a 11 years programer, and I'm a python new guy.

I am impressed.

<comment><USER11> May I know what packages do you use to build the site?

<comment><USER12> It's on the google app engine.

</comment></comment></comment><comment><USER13> oops, we killed Kenny

\</comment><comment></comment><comment></comment><comment>-

        Traceback (most recent call last):
        File "/base/python_runtime/python_lib/versions/1/google/appengine/ext/webapp/_webapp25.py", line 701, in __call__
        handler.get(*groups)

(snipped 25 lines)

        File "/base/data/home/apps/s~pythonmeme
        OverQuotaError: The API call datastore_v3.RunQuery()  required more quota than is available.

</comment><comment><USER14> Ah yes.

</comment><comment>==

Traceback (most recent call last): File "/base/python_runtime/python_lib/versions/1/google/appengine/ext/webapp/_webapp25.py", line 701, in __call__ handler.get( _groups) File "/base/data/home/apps/s~pythonmeme/4.356927075625222638/hello.py", line 395, in get normallist = item.all().order('-time').order('-vote').fetch(limit=20, offset=(pageNumber-1)_ 20) File "/base/python_runtime/python_lib/versions/1/google/appengine/ext/db/__init__.py", line 2084, in fetch return list(self.run(limit=limit, offset=offset, __kwargs)) File "/base/python_runtime/python_lib/versions/1/google/appengine/ext/db/__init__.py", line 2237, in next return self.__model_class.from_entity(self.__iterator.next()) File "/base/python_runtime/python_lib/versions/1/google/appengine/datastore/datastore_query.py", line 2655, in next next_batch = self.__batcher.next() File "/base/python_runtime/python_lib/versions/1/google/appengine/datastore/datastore_query.py", line 2525, in next return self.next_batch(self.AT_LEAST_ONE) File "/base/python_runtime/python_lib/versions/1/google/appengine/datastore/datastore_query.py", line 2562, in next_batch batch = self.__next_batch.get_result() File "/base/python_runtime/python_lib/versions/1/google/appengine/api/apiproxy_stub_map.py", line 592, in get_result return self.__get_result_hook(self) File "/base/python_runtime/python_lib/versions/1/google/appengine/datastore/datastore_query.py", line 2317, in __query_result_hook self._conn.check_rpc_success(rpc) File "/base/python_runtime/python_lib/versions/1/google/appengine/datastore/datastore_rpc.py", line 1182, in check_rpc_success rpc.check_success() File "/base/python_runtime/python_lib/versions/1/google/appengine/api/apiproxy_stub_map.py", line 558, in check_success self.__rpc.CheckSuccess() File "/base/python_runtime/python_lib/versions/1/google/appengine/api/apiproxy_rpc.py", line 133, in CheckSuccess raise self.exception OverQuotaError: The API call datastore_v3.RunQuery() required more quota than is available.

</comment><comment><USER15> Cached version:

[http://webcache.googleusercontent.com/search?q=cache:In9qxky...](http://webcache.googleusercontent.com/search?q=cache:In9qxkyrr1IJ:www.pythonmeme.com/+http://www.pythonmeme.com/&cd=1&hl=it&ct=clnk&gl=it)

</comment><comment><USER16> Great aggregator, we should have the same for ruby,c, c++ and all the major languages.

<comment><USER13> True, there's a few vaguely similar things, like planet.haskell.org, the subreddits, ruby.alltop.com.

You used to be able to pull off delicious tagged URLs for e.g. ruby, that had only a few people tag those and assume they were new/obscure, but you can't do that since they revamped format late last year. Can't do with pinboard either

</comment></comment><comment><USER17> Your site just ran out of the daily allowance

<comment><USER12> Google app engine: the new geocities.

</comment></comment><comment><AUTHOR> I was surprised with its on hacknews first page when I wake up today, and So much visits due to the site down about 8 hours and I have to chang the cache policy to keep the site run, its seems its need a more power host.

I'll fix these issues on comments, and I plan to add some these features: support social auth, comments.

Much appreciate for your comments, and sorry for the site hang up so long, its obvious not enough stable to post here.

</comment><comment><USER18> Love it. Just center the main table with margin:0 auto;

</comment><comment><USER9> I won't make an account here for the same reason I don't log in to sites using facebook, I only want a relationship with the site, not a giant 3rd party.

The site itself looks great, and would be a site I'd like to join, except for the google login part.

</comment><comment><USER19> Log in link doesn't seem to be working:

# Click log in

# Authorize with google

# Get sent to the submit page

# Manually go back to home page, click log in again

# Sent back to home page, and am not logged in. Can't vote or comment.

<comment><USER20> I didn't even dare to start the auth process. Who is the owner of this site? Not very much in the open.

</comment></comment><comment><USER21> When I click new or hot I get a trackback error

</comment><comment><USER22> error

<http://dpaste.org/0fO2k/></comment>


US space shuttle programme faces its final countdown - <AUTHOR> http://www.guardian.co.uk/science/2010/oct/31/us-space-shuttle-discovery-mission

<comment><USER2> Engineers at Rocketdyne, the manufacturer, estimate the total probability [of catastrophic failure] as 1/10,000. Engineers at Marshal estimate it as 1/300, while NASA management, to whom these engineers report, claims it is 1/100,000. An independent engineer consulting for NASA thought 1 or 2 per 100 a reasonable estimate.

— Personal observations on the reliability of the Shuttle by R.P. Feynman [http://science.ksc.nasa.gov/shuttle/missions/51-l/docs/roger...](http://science.ksc.nasa.gov/shuttle/missions/51-l/docs/rogers- commission/Appendix-F.txt)

As of STS-132 2010-05-26 <http://en.wikipedia.org/wiki/STS-132>

Total launches 131

Failures 2

Successes 129

Failure rate: 1.5%</comment>


Sysadmin marched without an exit interview had no chance to explain big savings - <AUTHOR> http://www.theregister.co.uk/2015/12/04/sysadmins_100000_revenge_after_sudden_sacking/?mt=1449218256053 <comment><USER2> "revenge" is the wrong word, as that implies intent. This was more like a king deciding to banish their doctor during a stomach ache, and being surprised by a ruptured appendix.

</comment><comment><USER3> For those not in the know the company in question is going to be Games Workshop.

"Revenge" is also the wrong word for this. I'd suggest schadenfreude.

<comment><USER4> Used to have friends who liked Warhammer stuff apparently they are a pretty awful company to deal with though.

<comment><USER5> They've gotta be terrified of the rise of 3D printers.

<comment><USER6> Eh, most of their lucrative customers want to play in stores or compete in official painting competitions, etc, which only accept Games Workshop products.

Arguably you can already play Warhammer 40k with any bits of plastic, but you still need the printed codexes and the setting, which is controlled by GW.

<comment><USER7> I think it would be really cool if a community formed to crowd source their own game. Have people work together on the rules, lore, and model design. That way anyone with access to a 3d printer could just print their own army.

<comment><USER8> Aren't board games some what popular on kick starter, and don't they have a pretty bad history of abuse/fraud/mismanagement/underperformance?

<comment><USER9> > Aren't board games some what popular on kick starter

Yes, very much so, and miniatures games (not really the same thing) also.

> don't they have a pretty bad history of > abuse/fraud/mismanagement/underperformance?

No? At least not by Kickstarter standards. The category has a much better track record than computer games or new hardware gadgets.

</comment></comment></comment></comment></comment></comment></comment><comment><USER10> Lousy title.

Corollary: if you treat your employees like disposables don't be surprised if you find out they were productive individuals after all and that you now officially hold the bag. They shouldn't even have had the guts to call him after such a termination.

An ex business friend of mine on a good Friday morning fired 3 long time employees out of the blue 'to cut costs'. Haven't been in touch since. That's just not the way to do it and if you do then all the resulting side effects are yours.

You've made your bed, now you must lie in it.

</comment><comment><USER11> It's hardly revenge if it wasn't preconceived. A decent lesson in due diligence however the title suggests that the Sysadmin intended for this to happen.

<comment><USER12> yeah the title is inflammatory and the story does not bear it out. The guy did his job but typical with too many organizations when they remove people with administrative authorities they tend to lock them out because of the perceived danger of leaving them their access to the site.

I don't know of any examples backing that stance up, but it is a perfect fear, uncertainty, and doubt, example that most upper management would never be called out on

</comment></comment><comment><USER13> The only part that bothered me here was:

"I had great delight in telling them I knew exactly why the bill was so large and had they not made me redundant they would have not blown the whole year's IT investment budget in a single month," James recalls. "Even better, they had gone over the cancellation period, locking them into a year's contract."

I'd have preferred him to complain about how he was prevented from doing any knowledge transfer/communication. The above implies he'd not have told them regardless, just because they were firing him.

<comment><USER14> Given that he was terminated and marched out immediately, I feel that he owed them nothing, not even the courtesy of answering the call from the IT Director.

He gave the company an interim solution because they demanded it, before the actual solution was available. It sounds like he had every intent to switch them over once it was available.

<comment><USER15> Like some people have pointed out it's not uncommon to do so when privileged employees are fired, a rogue sysadmin can bring the organization down to it's knees out of spite and if they even remotely capable do so with sufficient plausible deniability to avoid prosecution.

The lack of an exit interview is odd, but not uncommon in many cases especially in smaller companies where your direct supervisor or line manager is not your "technical" supervisor so the exit interview is pretty much pointless. Small organizations also tend to be less compartmentalized and they assume that knowledge transfer is unnecessary which might be the case in some cases and really not the case in others.

If he wasn't fired for gross misconduct and actually made redundant even in the UK severance is often paid, heck severance is paid even in cases where it's not warranted because employers rather to settle right away than face a unwarranted termination law suit (if you are officially made redundant there is statutory redundancy pay which employers very often increase considerably ex-gratia which is also tax exempt in the UK), the lack of notice can also point to the fact that this might not have been such a clear cut case of redundancy because although in some cases employers will just give payment in lieu of notice.

Now regarding the case he could've warned them and while he "owed them nothing" anyone with any respect for his work would've done so in such case, a better question would be why would a system which could incur such a hefty payment was setup in the first place and how it was authorized and by whom because. No one in their right mind would go into an agreement that could lead to such fees unless they are utterly incompetent as if the system misbehaved and transferred data excessively or that sysadmin would've gotten sick or otherwise incapacitated the same end result would've occurred. If the sysadmin was in charge of the setup for this system then he was utterly incompetent for not being able to see a clear business risk regardless if this was just a quick hack that he intended to cancel a week later. That said the whole ordeal smells funny a 100,000 connection fee for a single monthly usage even at the "dawn of the broadband age" in the UK seems utterly impossible a E1 line would not cost you that a year, so not sure how they could rack that bill over an ISDN30 line (BT Megastream probably).

<comment><USER16> I once researched trying to set up an ISP in Juneau, Alaska, and an ISDN line from Seattle, Washington was going to cost me over $2500 a week. This was around the "Dawn of the Broadband Age", too.

While that only comes to 10k a month, the connection would have gone over existing fiber cables. I can see where a custom installed point-to-point might run that high.

</comment></comment></comment></comment><comment><USER17> Replace "fired" with "hit by a bus" and you can see the ex-employee was not entirely inculpable.

<comment><USER18> according to the article, the manager was fired immediately afterwards. He or she may well also have been aware of this plan.

</comment></comment><comment><USER19> Good old GeeDubs, it saddens me that this still sounds as applicable to now as to then

</comment><comment><USER20> I would have preferred the title "Company reaps karma for abrupt termination of critical Sysadmin"

</comment><comment><USER21> At-will employment is something that should be universally banned.

Politicians expect their population to consume stuff, to raise kids... if at- will employment were legal I'd have to save and save and save money for anything because I could not be certain to still have a job tomorrow.

Get rid of this shit, impose minimum 2 weeks (better 4) of prior notice, except of course for stuff like theft, assault etc, and watch as your in-land economy rises.

<comment><USER22> I note that if you build up four weeks of savings in at-will employment, then compared to four-weeks-notice, you have the same level of security and more time to dedicate to job hunting.

(For people living paycheck to paycheck, four weeks of savings might not be easy to accumulate. But those people can't suddenly start spending more money if they get better job security. So there might be a compassionate argument, but the economic one doesn't seem to hold.)

<comment><USER21> > For people living paycheck to paycheck, four weeks of savings might not be > easy to accumulate.

That is the major problem: those who are poor and don't know their rights are hit the hardest - and this is why at-will should be abolished.

<comment><USER22> I'm confused by your addition of "and don't know their rights". In at-will, not knowing their rights means they get fired with no notice because that's allowed. Without at-will, not knowing their rights means they potentially get fired with no notice because they don't know it's not allowed.

I would think that giving people more rights is more helpful when they do know their rights.

</comment></comment></comment></comment><comment><USER23> "Instant karma" would be a better title.

<comment><USER24> Worse if you ask me.

</comment></comment><comment><USER25> We changed the title to the subtitle since people were objecting.</comment>


Show HN: (The Only) Tab Suspender for Safari - <AUTHOR> https://apps.apple.com/app/apple-store/id1495356253?pt=120681337&ct=hn&mt=8 <comment><AUTHOR> I believe this is the first Tab Suspender for Safari since the transition to the new Safari App Extension model.

Depending on your tab count and how "heavy" the websites are, you can expect a considerable reduction of memory and CPU usage and indirectly your battery consumption, by automatically suspending the tabs you aren't using.

Some of the options you can configure are:

\- Whitelist urls or domains that you do not want to suspend (You can still manually suspend them by using the menu)

\- Show a screen shot of the page just before it was suspended

\- Detects tabs playing audio and will not suspend them if you don't want it (experimental)

\- Detects tabs that contain active forms and will not suspend them if you don't want it

\- Optionally, do not suspend tabs if on battery power or no network connections

This extension is inspired by the The Great Suspender for Chrome

The UI and some features still need to be polished a bit and I plan a minor update next week but wanted to show this to the HN community to hopefully get some feedback.

Please let me know what you think.

Thank you</comment>


Building a Model for Retirement Savings in Python - <AUTHOR> http://sam-koblenski.blogspot.com/2018/08/building-model-for-retirement-savings.html <comment><USER2> re: pulling historical data with pandas-datareader, backtesting, algorithmic trading: [https://www.reddit.com/r/Python/comments/7zxptg/pulling_stoc...](https://www.reddit.com/r/Python/comments/7zxptg/pulling_stock_market_data_yahoo_and_google_dont/)

re: historical returns

\- [The article uses a constant 7% annual return rate]

\- "The current average annual return from 1923 (the year of the S&P's inception) through 2016 is 12.25%." [https://www.daveramsey.com/blog/the-12-reality](https://www.daveramsey.com/blog/the-12-reality) (but that doesn't account for inflation)

\- [https://www.quantopian.com/posts/56b62019a4a36a79da000059](https://www.quantopian.com/posts/56b62019a4a36a79da000059) (300%+ over n years (from a down market))

Is there a Jupyter notebook with this code (with a requirements.txt for [https://mybinder.org](https://mybinder.org) (repo2docker))?</comment>


Wigix: A Stock Market for Your Stuff - <AUTHOR> http://billburnham.blogs.com/burnhamsbeat/2008/04/wigix-an-idea-w.html

<comment><USER2> Stock and commodity markets work well because one share or contract is pretty indistinguishable from another. A continuous, bid/ask model will only work if they're careful to trade within certain bands of quality. Even then the 'lemons' problem applies. The rest is interesting, though.

<comment><USER3> Bingo. That was the major problem I saw with this as well. Your iPod and my iPod may have been bought on the same day and at the same location. But you left your's on your desk for 3 years, and I took mine on my deployment to Iraq. There are two very different values there.

</comment></comment><comment><USER4> I think it's an interesting idea only in that it seems to be a case of throwing a whole bunch of stuff at the wall and seeing if any of it sticks.

It allows you to do a whole bunch of things, none of which I want to do. You can sell/buy stuff, but as others have mentioned evaluating quality seems like a huge problem. You can make a list of all the stuff you own and find out what it's worth, but since that's an awful lot of effort and all my stuff is worth less than I paid for it, why would I want to? You can tell everybody about all the stuff you own, but that just seems kind sad. And you can ask people about the stuff they own, but there are plenty of online review systems which make getting the opinion of random people easier.

But of all these services, there might be _something_ that's of interest to some subculture somewhere. Maybe obsessive stamp collectors, or obsessive [something] collectors will find one or more of these features to actually be useful, and that might be enough to build a business on.

</comment><comment><AUTHOR> This is an interesting follow-up to the "better Ebay" discussion (<http://news.ycombinator.com/item?id=184988>).

Not sure whether or not they'll get enough users, though.

</comment><comment><USER5> This might be a relic of the industrial age. Every thing I see in manufacturing today seems to be drifting toward the "customized" product. The more options and customizations available to consumers, the less we'll all have "the same thing". Are black macbooks really worth more than the white ones? What if I get mine laser etched or painted red?

This depends on everybody having copies of a limited number of mass produced products. I think (and sincerely hope) we're headed for a much brighter future.

</comment><comment><USER6> I think this is pretty awesome. One of the things I do most often on eBay is check completed sales for items I own, to see what the opportunity cost of me hanging on to my stuff is. I was thinking a few weeks ago about how I needed a site that had a list of all my possessions(of the non-sentimental variety) and gave me updated values of their worth. I considered building one myself for about 5 minutes because I knew my skillset wouldn't be a good fit for this type of project. But am very glad to see someone has taken up the challenge. I think for young people and others without a whole lot of income, a site like this is very useful. I think there is a huge market here. Wigix is definitely a site to watch.

<comment><USER7> On a somewhat related note: Have you ever thought about re-selling on ebay?

Say an item has a really shoddy presentation/page and it is obviously keeping the bids down. You could buy it, make a better site and let the original seller ship it to your buyer instead of you.

For example you could ask the original seller for more photographs of the item.

<comment><USER6> Yeah I have an uncle that does that in his free time. I think he makes decent money. It seems like a lot of work though. I've only done about 20 or so transactions on eBay in the 10 years I've been a member. I'd say half of those have been more trouble than it's worth.

<comment><USER7> My mother has sold tons of stuff on ebay since I introduced her to it a few years ago.

She has a friend who does dissolving of households - that's where she gets most of her stuff from. People buy the oddest things.

</comment></comment></comment></comment><comment><USER8> I would be interested to see if they did any sort of market research into whether people are interested in such a service. It doesn't seem like it will be all that useful for one of a kind/rare items.

<comment><USER9> You can probably find and get rid of one of a kind/rare items already. What's harder, is dealing with used generic items. I have a bunch of electronics I wouldn't mind selling, and a bunch I would like to have, but it would be more hassle than its worse to go through eBay or craigslist. This thing looks well implemented, with the focus on the type of item, rather than each discrete item in particular (like existing listing sites). This is a good fit for mass produced items, whose differences are basically limited to just condition.

</comment></comment><comment><USER10> Wigix: please get rid of the stock photo on the front.

<comment><USER11> You mean this one:

[http://images.google.com/images?hl=en&q=woman+with+lapto...](http://images.google.com/images?hl=en&q=woman+with+laptop)

Seems like a pretty good idea, though.

</comment></comment><comment><USER12> I'm a little confused as to how they handle different types of products under an SKU.

For example, an iPhone with a short, abused life is going to carry a different market price than a nearly new one.

Or have I misunderstood the site?

edit: It seems they have quality categories when adding a product but they still seem discrete.

</comment><comment><USER13> they need a lot of users to get liquidity to "make real markets work" but if so, they will beat ebay based on its inherent usntructuredness. worth a try.

</comment><comment><USER14> From the description, it looks a little too "be everything to everyone", but that may well be a mistaken impression.

</comment><comment><USER15> It's definitely a great exercise to see how much you spend/lose on gadgets and stuff.</comment>


Why it matters where COVID came from - <AUTHOR> https://threadreaderapp.com/thread/1306775734598250496.html <comment><USER2> At this point, I think learning how to manage a pandemic without destroying the economy is the only question we should care about.

Pandemics will keep showing up regardless of if they're engineered or natural. It may be a 100% antibiotic-resistant bacteria next time, or some weird prion thing no-one thought about before, or the T-virus, or whatever's floating in the atmosphere of Venus. Who knows.

If we learn to correct what we're doing right now, then even if this happens again from a completely novel threat vector we didn't anticipate, we can handle it quickly and effectively.

<comment><USER3> I am not entirely sure that we would learn those lessons from dealing with covid-19. Much of the policy around it has been with the assumption that a vaccine could be produced in a somewhat reasonable time line, and we just need to hold out a bit longer.

The genome was sequenced increadibly quickly, and much of the vaccine work is based on all of the research that went into dealing with SARS 20 or so years ago.

A pandemic caused by something completely novel- whether a contageous and infectious prion disease (does that even make sense?) Or T-virus or venus flu- means that there will be far greater uncertainty than what we have been dealing with. A vaccine wouldn't even make sense in the case of a pandemic prion disease.

I think that Sweden had the right of things, but as others have pointed out before (and likely will again) it is still too early to tell. Not only that, but complicating matters is that every country captures statistics differently- especially the US and UK versus Europe. Numbers get bandied about quite a bit, and I suspect it will be many years before cool heads can evaluate all of the confounding factors into what actually helped and what we should do in the future.

<comment><USER2> What will be interesting is if we aren't able to develop a safe and efficacious (enough) vaccine. We might need to find ways to make social- distancing the status-quo for multiple years.

Edit: Hang on, why couldn't you make a vaccine against a prion? I can't see why it's not possible theoretically.

<comment><USER4> presumably since the protein is usually present, and the prion is just has a misfolded shape, it would be very tough to get the immune system to attack just the prions... however, there's at least one paper that has researched a vaccine in mice against a scrapie prion infection.

are there even treatments for any prion diseases? for BSE/mad cow disease, they killed millions of cows. to this day, if you're from/were in the UK during the outbreak, you can't give blood in quite a few countries.

and - surprise! - apparently prions could be spread via the air [0]. but it isn't clear how this could occur naturally, so at least that's good news.

[0] [https://www.wired.com/2011/01/airborne-prions- disease/](https://www.wired.com/2011/01/airborne-prions-disease/)

<comment><USER2> That's a cool question about treatments. I guess there's no FDA-approved therapy for mad cow, but I did find this cool animal model using 'anti- prions.'

"Here, we report a novel experimental strategy for preventing prion disease based on producing a self-replicating, but innocuous PrPSc-like form, termed anti-prion, which can compete with the replication of pathogenic prions."

"...a prophylactic inoculation of prion-infected animals with an anti-prion delays the onset of the disease and in some animals completely prevents the development of clinical symptoms and brain damage."

[https://www.ncbi.nlm.nih.gov/pmc/articles/PMC5738294/](https://www.ncbi.nlm.nih.gov/pmc/articles/PMC5738294/)

So that's more good news.

Edit: Hold on, that's the paper you were talking about, right? I didn't make the connection until just now.

</comment></comment></comment></comment></comment><comment> jerome-jh I am probably begging for downvotes, but here is a reasoning I came about recently.

Virus mutations are not rare events. This is what supports the natural evolution/selection/mutation of a wild virus into Sar-cov-2 hypothesis. People often say that the "natural hypothesis" is far more likely than a virus escaping a BSL4 lab. Let's look at that.

According to Wikipedia, there have been 3 virus outbreaks in "wet markets" in the last 20 years ([https://en.wikipedia.org/wiki/Wet_market#Health_concerns](https://en.wikipedia.org/wiki/Wet_market#Health_concerns)). That makes about 1 outbreak in 7 years.

That's for China as a whole. China is big. The probability of having a virus outbreak in a particular town is of course somewhat lower. The particular town we are looking at is Wuhan: this is the only city in China having a BSL4 lab, and it did gain of function experiments on Coronaviruses.

There are 108 towns with more than 1m population ([https://all- populations.com/en/cn/list-of-cities-in-china-by...](https://all- populations.com/en/cn/list-of-cities-in-china-by-population.html)). We're going to make rough estimates: let's say there are 100 "wet markets" in China, about one per city >1m. That makes the probability for a natural virus outbreak in _a_given_ "wet market" to be 1 in 700 years.

The question to be answered is this one: what is the most likely event between:

1/ a natural virus outbreak at Wuhan's "wet market"

2/ a modified virus "escaping" Wuhan's BSL4 lab

Hypothesis 1 has been estimated at 1 in 700 years. Do you believe the probability of hypothesis 2/ to be much lower than 1/?

Would the probability of hypothesis 1/ be 1 in 100 years, would you still thing it is much bigger than hypothesis 2/?

<comment><USER5> Hypothesis 3: Rogue actor, a la James Bond style.

<comment><USER6> It happens (though without a motive, no real story here).

After September 11, the next immediate terrorist attack on US soil was the anthrax scare. It was likely initiated by a specific researcher who had relevant access to the lab and had been lodging complaints for years that US authorities weren't taking anthrax threats seriously.

(The scientist in question never faced justice because they committed suicide before the dragnet closed in on them --- [https://en.wikipedia.org/wiki/2001_anthrax_attacks](https://en.wikipedia.org/wiki/2001_anthrax_attacks)).

</comment></comment></comment><comment><USER7> Pandemic response was really chaotic. So much conflicting information from politicians instead of relying on scientist and healthcare system to take care of what message must be delivered about COVID19. Often just pure speculation instead of proper emergency communication.

</comment><comment><USER8> I know a doctor who works at multiple hospitals, she have talked about how there are a lot more infections and strange ones, in the rural population, things that jump from animals, that she never sees in the urban population. Maybe there's just a general problem with hygiene ?

<comment><USER9> > things that jump from animals

My physician father was involved with a case where a drunken idiot decided to go play on a beach filled with elephant seals. The deep tusk wound he earned in one thigh had the local internists hitting the books to figure out what rare and exotic marine bugs had infected the fellow... IIRC the guy lived, but he was very ill.

Sometimes I wonder if he lives on in textbook case studies (with the requisite black bars over his eyes in any photos).

</comment></comment><comment><USER10> Original content: [https://twitter.com/JeffLadish/status/1306775734598250496](https://twitter.com/JeffLadish/status/1306775734598250496)

Threadreaderapp is silly.

<comment><USER11> Normally I'd agree, but in this case Twitter abruptly ended the thread, hiding it behind a click to ask me if I wanted Covid-19 info and show me tangentially related content.

[https://imgur.com/a/LPXeSb4](https://imgur.com/a/LPXeSb4)

<comment><USER10> Twitter is amazing — it's a company that exists in spite of itself.

</comment></comment></comment><comment><USER12> The virus most likely came from close contact between animals and humans in which humans wanted to consume the animal. Virtually all of the new infectious diseases come from animal to human transmissions, and virtually all of those come from either direct consumption of animals or from animal agriculture. The total number of animals kept for agricultural purposes, plus the conditions they are kept in, means we can expect more and more diseases to come from this industry.

Shifting our food sources away from industrial animal agriculture would significantly decrease the number of new infectious diseases we have to encounter. This looks like lab grown meat, like plant based meat substitutes such as Impossible, Beyond, and Oatly, like grass fed beef, like backyard chickens, and it looks like less beef burritos and more bean burritos.

<comment><USER13> It would not be the first time nature is blamed for human activity, so I am not sure what makes you so sure.

Two separate papers have come out saying pretty much the same thing, that there is lots of evidence pointing to this virus being more likely engineered (by modifying existing viruses) and that each piece of evidence also matches papers put out by researchers working at the Wuhan-based virus research lab, which is also where the outbreak is thought to have begun.

<comment><USER14> The problem is though that a lot more dangerous (than Covid) pathogen, Influenza A H5N1 is waiting to jump from chicken on people, which is only possible if people come into close contact with poultry. It has happened with Pig Flu. Influenza by far is most dangerous pathogen around, it had shown what it is capable of in 1918, and it may happen again.</comment></comment></comment>


I hope pmarca doesn't continue posting quotes in place of thoughtful original content. - <AUTHOR>

I started reading Pmarca because he is one of my personal heroes, and because he was one of the few guys that seemed committed to writing smart original content. Recently, I noticed a tendency to post re-post content with a 1 line descriptor. I know Marc is busy....what with selling his company for billions, funding twitter, and running Ning... but I'd rather see 1/3 as many posts that are all original, than see his blog become an amalgamation of repostings like so many other silicon valley rags. Marc doesn't have a comment form to save time, so I hope this gets to him. Quality is important; I think that's why PG's rare essays are immensely more valuable than the flow of half-baked banter coming out of blogs like GigaOm these days. <comment><USER2> I love knowing what he's reading and what inspires his thinking. I don't think these posts are in place of his original content, they're "extras". He's also well-aware that these posts aren't as popular. He mentioned his incoming traffic was way bigger with his original posts.

</comment><comment><USER3> Is your issue with the brainstorming quote that Marc didn't write it, or that it isn't of the quality you've come to expect from the pmarca blog? Choosing high-quality content is a valuable service. Quality and originality are orthogonal.

The brainstorming quote may not have the wow factor of some of the pmarca essays, but it's certainly relevant to people interested in startups, who spend a lot of time talking about ideas.

PG has some thought-provoking non-original content on his site too, by the way, e.g. <http://www.paulgraham.com/perils.html>

</comment><comment><USER4> It is hard to come up with original content on a continuous basis. Maybe Marc believes that the quotes are repostings are relevant for his audience to read. Regardless of the reasoning, keep up the good work Marc.

</comment><comment><USER5> I don't care who said it, just what was said. The brainstorming post was just the tonic I needed today.</comment>