kingdomcome50
Farewell FFmpegKit. You will be missed.
``` def login(self) -> AppClient ```
My father had to _literally_ practice hiding under his desk at school with a Geiger counter in preparation for nuclear war. He was then _drafted_ into Vietnam... I don't think I have it so bad.
I'm my experience the _vast_ majority of CSS never gets reused. Sure if all you are building is marketing websites or landing pages then I suppose some generic "cards" or whatever will get you pretty far, but for anything even moderately more complex... no chance
DDD is not about how software is physically organized nor how it is deployed. You can have a traditional N-tier architecture AND follow DDD. The domain model is a logical model used to abstract the functional requirements of a system. It doesn't "lock" you in anymore than whatever else you have in place serving the same purpose. You cannot simply avoid your functional requirements. DDD is a methodology with the specific goal of drawing boundaries (answering "what" goes "where") in such a way to minimize the cost of change. If your resulting design is not doing so, you have simply failed to model your domain in a useful way.
In the author's case, maybe they really did need a generic "data integration" or "workflow engine" application. That's not an unreasonable assumption. And it follows that coupling those kinds of applications to the data/workflows contained therein would lead to all sorts of problems.
But surely he is not arguing that every application should be designed as a platform? It's considerably more difficult to design and maintain a "workflow engine" than "a single workflow", or a "data ingestion" application than to "just ingest the data". Most of the important bits in the above are already abstracted away from users.
There are many glaring issues with the ideas presented in that linked "take down" of DDD.
I can forgive the early strawman comparing "spreadsheets" to bespoke software solutions. As if they cover exactly equal problem/solution spaces. Fine. I'll play along...
I can even forgive failing to understand that DDD is a design methodology, not an architecture; That DDD in no way prescribes or enforces any particular code organizational or deployment strategy. Easy to get wrong I suppose, and doesn't necessarily invalidate what could become a coherent argument...
But the author then has to go on and give examples of just how little they understand the topic at hand!
The first points to database software as "an example of good architectural design where their purpose of storing data is not confused with the domain the database will be used for". Oh the irony! Of course that's the case! The domain of database software is... (drumroll) persisting data! What would you expect to see if you opened the source code for an RDBMS? Code for blasting out marketing emails? I could go a step further and opine that it isn't possible to know whether any piece of software follows DDD without actually seeing the design/code base... but I digress. This point is not forgivable. It's a clear and obvious misunderstanding of DDD and how it is applied to systems.
The next examples they give are of applications they worked on! In both cases the author completely misses the fact that the software they "fixed" by decoupling it from the "domain" are simply examples where they followed DDD to create a "better" system. That's right! If the goal of your software is to create a generic "data integration application" or "workflow engine", then yes, coupling your design to "healthcare" is a mistake. Both are examples where the author is confused about what domain their software is servicing, and how aligning the software design to the correct domain was a major improvement. Hmm... sounds like DDD to me :)
I think there are valid criticisms of DDD, but the article linked is quite poor at articulating them.
In terms of ease-of-debugging, sure, splattering local variables and extra control statements may allow you to break/inspect a certain class of bug in a certain way. But it also creates a lot of noise and makes the code a lot more "dense". It's hard to see given an example in isolation, but when all of your code looks like this it can make it significantly more "tiring" to understand. "Easy to debug", while important, is also something that must be balanced against other factors.
And in terms of easy-to-understand, again, I agree that the author's example has a slight edge (give the first one a shot though... it's not so bad). But what does it mean for a `Contact` to both be "inactive" and also "a family or friend"? They have forgotten to capture the single most important condition! Similar to my first point, it can be hard to see the issue when given an example in isolation, but imagine looking for whatever condition or rule the author is enforcing in a sea of other blocks that look similar.
A simple comment over the original version would suffice for me:
// If the contact is staleThese questions, while certainly aimed at identifying core competency areas, are also an opportunity for the candidate to demonstrate an aptitude for problem solving. Nobody really cares "how many piano tuners operate in Seattle". What they care about is, given that kind of question, how a candidate responds. You might be surprised by the number of people totally unable to even generate a reasonable estimate:
- How many people live in Seattle? - What percentage have pianos? - How often does a piano need tuning? - How long does it take to tune a piano? - How many pianos can be tuned per work day (given commuting time)? - etc.. driving towards a number.
Did the candidate attack the problem and even attempt to solve it? Did they use metrics? The list goes on... Most LC-style questions (save the "aha! moment" ones) have a similar impetus, but are also much more practical and efficient because they test for many things at once.
And if I'm being honest... most FAANGs aren't looking for engineers that require quiet and time to solve problems. They are looking for elite engineers who can write a solution nearly as fast as the problem is presented (I'm obviously exaggerating a little bit here). The difficulty of the questions presented to me (6 technical interviews) were what I consider semi-trivial. I was able to describe the solution-space within seconds of reading the prompt and code an optimal solution nearly as fast as I could type in all cases. It honestly made me wonder about how poorly the average programmer must perform such that these were the questions they needed to evaluate my potential.
Another commenter posted this article [0] about the interviewing philosophy back in the early '00s. I found it very enlightening, and reassuringly, while reading through it I knew the answer to nearly every question (and could expand upon the topics) just off the top of my head. I'm not trying to sound arrogant here but the idea that a FAANG, who pays top-dollar for engineers, would settle for "10 years experience" as a suitable replacement for "demonstrates ability" is what's absurd. A false positive is way more costly than a false negative.
[0] https://sites.google.com/site/steveyegge2/five-essential-pho...
You see and interview is like a “test” or a “pop quiz” where the day to day is more like “homework”. That is, you want to hire people who do their homework, but the only reasonable method to evaluate a candidate is to give them a test. And while a “high test score” may serve as a proxy for “completes homework”, as we all know, it’s far from perfect.
The unfortunate reality is that the best process for determining the quality of a candidate benefits neither the candidate nor the company. That is some sort of paid-trial-period-type arrangement to evaluate fit.
So we are left with these gauntlets of an interview process because it kind of splits the baby…
Many of your other concerns are big "nothing burgers". It's not like versioning, patching, config, tuning, monitoring, etc. are any less of a pain in other runtimes. At worst you could argue that it's different.
I cannot think of an easier deployment paradigm than what essentially amounts to a copy and paste in the simplest case (i.e. what we should strive for), and maybe one or two more steps in a more complex case (e.g. `composer install`).
An entire PHP installation can literally be copied and pasted onto another machine and "just work"(though you may need to fiddle with some paths in the .ini). Similarly PHP is fast enough that it's unlikely to ever be the bottleneck in terms of performance/scaling for 99% of use-cases.
I suppose I can agree that PHP may lend itself well to certain kinds of "bad practices", but that's true for any system if not managed well.
PHP as a language is... okay. It's been modernized to include many of the faculties a developer would expect of a language in 2022. But honestly, I'm ready for the "improvements" to the language to stop. The closer you get to C# or Java the more obvious it is that PHP will never catch up! It's not that it has to catch up, rather, that few people actually choose PHP because the language is so great. If you were choosing a your stack based on "which language offers us the most features or highest ability to express our problem" you wouldn't be choosing PHP!
Here's the secret: PHP is probably the best language for server side webdev because of the runtime! It's so dead simple to develop and deploy PHP. I mean the language itself is basically a web framework right? How many other languages automatically parse an HTTP request and hand it to you by default? Or offer built-in templating semantics for composing HTML? Or have request routing by default? I don't know of another one. That's why I, and many others, choose PHP!
You know what I'd like to see? The trajectory of PHP's development change to lean in to the above -- to focus development on improving the reasons why it is chosen in the first place! I don't need a C# with slightly different syntax (or named parameters). I'd like:
- Improved templating semantics
- A better module system
- A way to bake routing into each file (overwriting the default semantics)
- Adding a built-in service-locator pattern/DI
- A way to make PHP scripts more testable
What I'm saying is just make it a better framework by default. I know I know... "Laravel this, Symfony that, have you heard of Slim?". Yes... I get it. There are community-made solutions to the above problems. And you know what? They won't be as performant or integrated as if the runtime itself was upgraded to make them obsolete. It's not like routing and DI are that complicated (the two most obvious reasons frameworks are employed).
I like that I can write a simple API in PHP without pulling in a single dependency! It makes so many things easier (the right things too). Now let's just extend that to all of the basic facets a modern web framework offers!
What I mean is that, as I have aged (and I am by no means old), the most obvious relationship between "creativity" and "age" has been the ever-raising bar that must be reached in order for me to think of something as creative.
Growing up I always thought it was so odd how indifferent my parents (and older people in general) felt towards all the newest music/movies etc., but now I realize that none of it was really new at all! It's the same stories/tropes/punchlines being regurgitated over and over. I was just young and hadn't yet had the breadth of experience to know what creativity actually looked like.
Maybe it's not that getting older makes us less creative in an absolute sense, rather, that as we get older we find it harder and harder to be creative in a relative sense? And so efforts that we may have found "worth it" at 25 no longer appeal at 65, and are therefore not even attempted (despite containing some creativity).
I have no doubt that a sizable portion of these functions' bodies is dedicated to figuring out which type each of our input variables represent (from our wide variety). So now instead of having our editor/compiler help us out, we are now actually writing code to figure it out ourselves... this is more absurd (and less efficient).
And FWIW, using union types makes it trivial to denote that a function can accept a wide variety of types in a type-safe way. But guess what you will be doing first thing in the function body? Discriminating that union!
Is this better or worse than no type definition? Whether or not a type is defined it is still consumed. I can totally understand that sometimes types can get a bit unwieldy, but those are the exact scenarios that save future-you from introducing a bug because you didn't know what a variable is (and is not). At the very least it may be an indicator of poor design/code smell when the above occurs.
I hear you on compilation/build process woes. That's the fairest criticism against TypeScript IMO (though it's a fairly weak argument as well).
Most of your other critiques aren't really levied against TypeScript, rather, your work environment (not that it makes working with TS any less painful!).
I kid... mostly. But in all honesty I have found very few instances of developers who have worked significantly with both languages and have come to the conclusion that TS has a marginal upside (though maybe they will come out in defense here!).
It's a balance. Extracting logic into new components (and often new files!) isn't exactly ergonomic either.
I've found it's better to decrease readability if it makes understanding the logic more straight-forward (i.e. not hunting through several files to exhaust all possible outputs).
My counter example is about exactly as detailed as the author's example. Of course I was being tongue-and-cheek, but clearly standardization has worked in software.
You can toss your example right on top of all of the other failed attempts at standardization. It in no-way supports the conclusion that "standardization" is a problem. Like I said, I agree with the author's argument, but their conclusion is not supported by that argument. There are many failure modes to large projects.
I agree with the thrust of this post: Changing something that is not understood is a dubious undertaking. But the author fails to make a compelling connection between the above and software development. A poor solution may be a result of not understanding enough of the system as a whole, or it may not. We simply can't tell.
Standardization (i.e. simplification) is generally a good thing in software development. How would Tim's system look if they had opted for his approach from the start? How does the 3rd iteration of the system compare to the 1st iteration? Maybe Tim's solution is stepping-stone to something better. Impossible to tell.
But more importantly, you also don't need to very much about the above if your goal is just to reach competency. My understanding is the OP was claiming the candidate will be competent because "he knows how to program". Now that may mean anything from "candidate has written a python script to display a graph once" to "candidate is the lead dev of our game engine".
If the former, then of course, yes, they would likely struggle a little bit at first (though I would expect competency within hours -- many frameworks, as part of their core design, aim to reduce time-to-competency). If the latter, give them a brief overview of the system architecture, point them at the docs, hand them a ticket, pat them on the back and walk away.
But to your point. Yes, experience is critical for mastering a skill.
But even for authors that _are_ highly competent at authoring SQL, it is dubious to allow them to compose ad-hoc queries ad-nauseum (let's even pretend these "developers" are _also_ excellent at performance tuning).
This is death-by-a-thousand-cuts. The approach is just too granular. Databases _notoriously_ don't have unlimited throughput, and depending on your particular RDBMS it may be prohibitively expensive to just "throw more hardware" at the problem (I'm looking at you MS SQL Server).
For any system that you can imagine there is a point (i.e. scale) at which the above paradigm becomes a very big problem. Believe me. We are in the process of moving logic _out_ of SQL for this exact reason at my current company!
SELECT
CASE WHEN o.EmailAddress IS NULL OR o.PhoneNumber IS NULL
THEN 1
ELSE 0
END AS [IsSubmitDisabled]
FROM Customer c
INNER JOIN Order o ON c.Id = o.CustomerId
AND o.IsActiveOrder = 1
WHERE c.IsActiveCustomer = 1
These queries aren't identical in their output, though they are logically the same. Is that a good thing? What are the implications of allowing such ad-hoc queries within a system?Are we having the same discussion?
> I did make a deliberate choice to not reproduce specifically because I didn't want to bring a child into an environment that's on the brink of collapse
I suppose I assumed you didn't think "the brink of collapse" would last 100-200 years, rather, that you fear your children would have to (in their lifetime) deal with the fallout from such a "collapse". And that such an event will be so traumatic that it would be better they weren't ever alive to experience it.
I take your pivot towards attacking me as a compliment, and a sure-fire sign you believe your position has weakened. Though I don't care either way. You are free to make whatever decisions you want for whatever reasons you want. I can respect that.
The impetus for my original comment was an "in good faith" attempt to get you to consider (or reconsider) a decision I believed to have been made in ignorance (or at the very least with a healthy dose of hysteria). I have no inclination to change your mind. That's for you to do.
Precisely! My point is that my (or your) grandparents/parents could have held the same sentiments you are holding now. And they would have been wrong.
> I'm thinking about 100-200 years down the line
Your children will not be alive in 100-200 years so your point is also moot.
Unfortunately, I believe you believe what you are saying will come to pass and it will be "society collapsing". I don't. No point in arguing about it any further. Message me in 100-200 years to say "I told you so".