It hails from when family lines were important, and you can practically only have one line reflected in a name. Unsurprisingly, most societies considered the male's name to be the dominate lineage of interest, although that doesn't hold true 100% of the time.
> you can practically only have one line reflected in a name
Not true at all. You can trivially have two family names in a full legal name. In fact many cultures do exactly that to this day.
Also worth noting that the male's name being preferentially propagated makes a lot of sense in a society where the best off frequently inherited their vocation from their fathers.
> Just because there is an alternative doesn't mean society will adjust.
"It isn't practical to do" and "society at large didn't go this direction" are very different statements.
Hyphenation is two names in a trench coat. Maintaining two names indefinitely works just fine as long as you discard rather than endlessly compound. Presumably the only requirement is that it be straightforward to trace any given lineage.
The traditional approach is for women to keep their maternal name and discard their paternal name on marriage while men do the opposite. But of course any scheme could work, up to and including each person arbitrarily choosing which name to discard (not sure how they decide on ordering in that case).
Another historical approach is the Foo Barson, Baz Fooson (Barson) approach. That scheme treats the male and female lines as being entirely separate so it doesn't quite match what you're after but it was quite practical.
Preserving more than one lineage and providing a cohesive family name isn't practically easy, and society did not go that direction, and that likely isn't a coincidence.
Discarding names doesn't preserve lineage. If you need a book to trace the names, then the point of using a name for lineage has failed.
> The traditional approach is for women to keep their maternal name and discard their paternal name on marriage while men do the opposite
It sounds like this scheme is "men keep one name lineage, women keep another".
Which, IMO, has the practical drawback of not identifying the current family unit. Lineage was important, but so was gathering all folks together into a household. When taxes, religious ceremony, etc. occurred, there was one household name on the roster responsible. This was particularly important in societies where men held certain rights for the household.
I have a theory: They realized the right approach is to focus purely on the yes/no of what you choose to consume, rather than trying to optimize the consumption experience itself.
Remember how YouTube and Netflix used to let you rate things on 1-5 stars? That disappeared in favor of a simple up/down vote.
Most services are driven by two metrics: consumption time and paid subscriptions. How much you enjoy consuming something does not directly impact those metrics. The providers realized the real goal is to find the minimum possibly thing you will consume and then serve you everything above that line.
Trying to find the closest match possible was actually the wrong goal, it pushed you to rank things and set standards for yourself. The best thing for them was for you to focus on simple binary decisions rather than curating the best experience.
They are better off having you begrudgingly consume 3 things rather than excited consuming 2.
The algorithmic suggestion model is to find the cutoff line of what you're willing to consume and then surface everything above that line ranked on how likely you are to actually push the consume button, rather than on how much you'll enjoy it. The majority of which (due to the nature of a bell curve) is barely above that line.
I think Netflix realized that reducing ratings to a simple thumbs up/down was a bad idea after all. A while back they introduced the ability to give double thumbs up which, if you can treat non-rating as a kind of rating, means they're using a four point scale: thumbs down, no rating, thumbs up, double thumbs up.
Netflix are right that 5-stars is too many, it translates to a 6 point scale when you include non-rating, and I don't think there is a consistent view on what "3 stars" means, and how it's different to either 4 stars or 2 stars ( depending on the person ).
For some people 3 stars is an acceptable rating, closer to 4 stars than 2 stars. For others, 3 stars is a bad rating, closer to 2 stars than 5 stars. And for others still, it doesn't give signal beyond what a non-rating would be, it's "I don't have a strong opinion about this".
Effectively chopping out the 3-star rating, leaves it with a better a scale of:
- Excellent, I want to put effort into seeking out similar content
- Fine, I'd be happy to watch more like it
- Bad, I didn't enjoy this
- Terrible, I want to put effort into avoiding this
With the implicit:
- I have no opinion on this
But since it's not a survey, it doesn't need to be explicit, that's coded into not rating it instead.
These are comparable to a 5 point Likert scale:
"I enjoy this content"
- Strongly agree
- Agree
- Neither Agree nor Disagree
- Disagree
- Strongly Disagree
The current Netflix scale effectively merges Disagree and Strongly Disagree, and for matters of taste that may well be fine.
It would be interesting to conduct social science with a similar scale with merged Disagree and Strongly disagree to see if that gave it any better consistency.
When given a 5-star choice “very bad/bad/ok-ish/good/very good”, I rarely pick one of the extremes.
I suspect there are others who rarely click “bad” or “good”.
Because of that, I think you first need to train a model on scaling each user’s judgments to a common unit. That likely won’t work well for users that you have little data on.
So, it’s quite possible that a ML model trained on a 3-way choice “very bad or bad/OK-ish/good or very good” won’t do much worse than on given the full 5-way choice.
I think it also is likely that users will be less likely to click on a question the more choices you give them (that certainly is the case if the number of choices gets very high as in having to separately rate a movie’s acting, scenery, plot, etc)
Combined, that may mean given users less choice leads to better recommendations.
I’m sure Netflix has looked at their data well and knows more about that, though.
I apply my own meaning to the 5-star rating, and find it to work really well:
1 = The movie was so bad I didn't/couldn't finish watching it.
2 = I watched it all, but didn't enjoy it and wouldn't recommend it to anyone.
3 = The movie was worth watching once, but I have no interest in watching it again.
4 = I enjoyed it, and would enjoy watching it again if it came up. I'd recommend it.
5 = a great movie -- I could enjoy watching it many times, and highly recommend it.
> The current Netflix scale effectively merges Disagree and Strongly Disagree, and for matters of taste that may well be fine.
I'm a bit skeptical about this.
To me there's a big difference between "This didn't spark joy" and "I actively hated this": I might dislike a poorly-made sequel of a movie I previously enjoyed, but I never ever want to see baby seals getting clubbed to death again.
Every series has that one bad episode you have to struggle through during a full rewatch. Very few series have an episode bad enough that it'll make you quit watching the series entirely, and ruin any chance at a future rewatch.
They're only useless in that they aren't displayed for your peers, but that was always the least-useful function.
Being able to see a counter that reads as "Twenty-three thousand other people also didn't like this video!" doesn't serve me in any meaningful way; I don't go to Youtube to seek validation of my opinion, so that counter has no value to me. (For the same reason, the thumbs-up counter also has no value to me.)
But my ratings remain useful in that the algorithm still uses the individualized ratings I provide to help present stuff that I might actually want to watch.
As we all know, investors and advertisers love growth; Youtube thrives and grows and gathers/burns money fastest when more people use it more. The algorithm is designed to encourage viewership. Viewership makes number go up in the ways that the money-people care about.
Presenting stuff to me that I don't want to watch makes the number go up -- at best -- slower. The algorithm seeks to avoid that situation (remember, number must only go up).
Personally rating videos helps the machine make number go up in ways that benefit me directly.
---
Try to think of it less like a rating of a product on Amazon or of an eBay seller; try not to think of it as an avenue for publicly-displayed praise or admonishment. It's not that. (Maybe it once was -- I seem to recall thumbs-up and thumbs-down counts being shown under each thumbnail on the main feed a million years ago. But it is not that, and it has not been for quite a long time.)
Instead, think of it as one way in which to steer and direct your personalized recommendation algorithm to give you more of the content you enjoy seeing, and less of what you're not as fond of.
Use it as a solely self-serving function in which you push the buttons to receive more of the candy you like, and less of of the candy that you don't like.
I have literally not rated anything at all, ever since YouTube removed dislikes, and my recommendations are working fine. Ratings indicate(d) if a given video was likely to be a waste of my time or not, and in an age of AI slop, this feature is more desirable than ever.
Someone should make a SponsorBlock/Dearrow-type addon to flag AI slop.
You only assume recommendations are based on ratings, but you don't know. And I have seen your metaphorical green grass, because actual ratings were a thing up until about 4 years ago, remember?
>I don't find any of that on my end.
Good for you. The true crime genre has been hit hard by AI slop.
> And I have seen your metaphorical green grass, because actual ratings were a thing up until about 4 years ago, remember?
I remember this conjecture of yours (that ratings unilaterally ceased to matter as soon as they stopped being displayed to users) very well.
And unlike you, I can see over to the other side of the fence -- in the present day -- at a whim: All I have to do is fire up YouTube in a private session on a disused device. It's fucking awful over there; it's complete bedlam.
Same point as always: That it definitely doesn't have to be that way at all.
(I can't make you take the blinders off and use that utterly useless, vestigial Thumbs Down button, though. You're free to live your life with as blindly and with much suffering as you wish, no matter what anyone else thinks.)
I mean, if you read about how current industry-standard recommendation systems work, this is pretty bang on, I think? (I am not a data scientist/ML person, as a disclaimer.)
If e.g. retention correlates to watch time (or some other metric like "diversity of content enageged with"), then you will optimize for the short list of metrics that show high correlation. The incentive to have a top-tier experience that gets the customer what they want and then back off the platform is not aligned with the goal of maintaining subscription revenue.
You want them to watch the next thing, not the best thing.
I just rebuilt my PC and setup Steam on Linux. It was fairly smooth.
I've dual-booted Arch and Windows for about 16 years. I always kept Windows around for gaming, and the occasional "doesn't support Linux" workflow.
For a few years where I didn't game I found myself almost exclusively in Linux. But then I spent the last 5-6 years stuck between the two as my PC use for daily tasks dwindled, I stopped working on side projects, and I started gaming a bit more.
I hated trying to split my time between them. Most of what I used a PC for was the browser, so I could just stay in Windows most of the time. I wanted to use Linux, but rebooting to use a web browser just didn't make sense. As a result I would accidentally go 2-3 months without ever booting Arch. As a result, I had a couple of major updates that didn't go smoothly.
I wanted to use Linux, though. I like having a customized WM, I like having so many useful tools at my disposal, etc. I just like using Linux, in spite of the occasional technical complexity.
In the last couple months I rebuilt my PC and a major requirement was that I get set up to game in Linux as much as possible. I even bought an AMD card to ensure smooth driver support.
I'm so incredibly thankful that Steam has made gaming not just possible, but relatively simple. Installation was simple. My single-player games seem well supported so far. And most importantly, Steam has made it obvious they're committed to this line of support, so this isn't some hero effort that will bit rot in a couple years.
I still have to reboot to play competitive games, due to their anti-cheat requirements, but that's less of a problem, I'll take what I can get.
There are different definitions of the term "mock". You described the generic usage where "mock" is a catch-all for "not the real thing", but there are several terms in this space to refer to more precise concepts.
What I've seen:
* "test double" - a catch-all term for "not the real thing". What you called a "mock". But this phrasing is more general so the term "mock" can be used elsewhere.
* "fake" - a simplified implementation, complex enough to mimic real behavior. It probably uses a lot of the real thing under the hood, but with unnecessary testing-related features removed. ie: a real database that only runs in memory.
* "stub" - a very thin shim that only provides look-up style responses. Basically a map of which inputs produce which outputs.
* "mock" - an object that has expectations about how it is to be used. It encodes some test logic itself.
The Go ecosystem seems to prefer avoiding test objects that encode expectations about how they are used and the community uses the term "mock" specifically to refer to that. This is why you hear "don't use mocks in Go". It refers to a specific type of test double.
By these definitions, OP was referring to a "fake". And I agree with OP that there is much benefit to providing canonical test fakes, so long as you don't lock users into only using your test fake because it will fall short of someone's needs at some point.
Unfortunately there's no authoritative source for these terms (that I'm aware of), so there's always arguing about what exactly words mean.
My best guess is that software development co-opted the term "mock" from the vocabulary of other fields, and the folks who were into formalities used the term for a more specific definition, but the software dev discipline doesn't follow much formal vocabulary and a healthy portion of devs intuitively use the term "mock" generically. (I myself was in the field for years before I encountered any formal vocabulary on the topic.)
> "mock" - an object that has expectations about how it is to be used. It encodes some test logic itself.*
Something doesn't add up. Your link claims that mock originated from XP/TDD, but mock as you describe here violates the core principles of TDD. It also doesn't fit the general definition of mock, whereas what you described originally does.
Beck seemed to describe a mock as something that:
1. Imitates the real object.
2. Records how it is used.
3. Allows you to assert expectations on it.
#2 and #3 sound much like what is sometimes referred to as a "spy". This does not speak to the test logic being in the object itself. But spies do not satisfy #1. So it is seems clear that what Beck was thinking of is more like, say, an in-memory database implementation where it:
1. Behaves like a storage-backed database.
2. Records changes in state. (e.g. update record)
3. Allows you to make assertions on that change in state. (e.g. fetch record and assert it has changed)
I'm quite sure Fowler's got it wrong here. He admits to being wrong about it before, so the odds are that he still is. The compounding evidence is not in his favour.
Certainly if anyone used what you call a mock in their code you'd mock (as in make fun of) them for doing so. It is not a good idea. But I'm not sure that equates to the pattern itself also being called a mock.
I think this is the crux that separates Fowler's mock, spy, and stub: Who places what expectations.
Fowler's mock is about testing behavioral interaction with the test double. In Fowler's example, the mock is given the expectations about what APIs will be used (warehouseMock.expects()) then those expectations are later asserted (warehouseMock.Verify()).
Behavioral interaction encodes some of the implementation detail. It asserts that certain calls must be made, possibly with certain parameters, and possibly in a certain order. The danger is that it is somewhat implementation specific. A refactoring that keeps the input/output stable but achieves the goal through different means must still update the tests, which is generally a red flag.
This is what my original statement referred to, the interaction verification. Generally the expectations are encoded in the mock itself for ergonomics sake, but it's technically possible to do the interaction testing without putting it in the mock. Regardless of exactly where the assertion logic goes, if the test double is testing its interactions then it is a Fowler mock.
(As an example: An anti-pattern I've seen in Python mocks is asserting that every mocked object function call happens. The tests end up being basically a simplified version of the original code and logic flaws in the code can be copied over to the tests because they're basically written as a pseudo stack trace of the test case.)
In contrast, a stub is not asserting any interaction behavior. In fact it asserts nothing and lets the test logic itself assert expectations by calling the API. ie:
> 3. Allows you to make assertions on that change in state. (e.g. fetch record and assert it has changed)
These concepts seem distinct enough to make mock a simple.
Fowler's spy seems to sit half-way between mock and stub: It doesn't assert detailed interaction expectations, but it does check some of the internals. A spy is open-ended, you can write any sort of validation logic, whereas a mock is specifically about how it is used.
I have used spys in Go basically whenever I need to verify side effect behavior that is not attainable via the main API.
By Fowler's definition, nocks are a niche test double and I suspect that what many folks would call a mock are not technically a mock.
I generally advise to avoid introducing interfaces strictly for testing. Instead, design the data types themselves to be testable and only use interfaces when you expect to need differing implementations. ie, avoid premature abstraction and you get rid of a whole class of problems.
For example, if you only use S3, it is premature abstraction to accept an interface for something that may not be S3. Just accept the S3 client itself as input.
Then the S3 client can be designed to be testable by itself by having the lowest-level dependencies (ie, network calls) stubbed out. For example, it can take a fake implementation that has hard-coded S3 URLs mapped to blobs. Everything that tests code with S3 simply has to pre-populate a list of URLs and blobs they need for the test, which itself can be centralized or distributed as necessary depending on the way the code is organized.
Generally, I/O is great level to use an interface and to stub out. Network, disk, etc. Then if you have good dependency injection practicies, it becomes fairly easy to use real structs in testing and to avoid interfaces purely for testing.
I agree with not introducing abstractions prematurely, but your suggestion hinges on the design of the S3 client. In practice, if your code is depending on a library you have no control over, you'll have to work with interfaces if you want to prevent your tests from doing I/O. So in unit tests you can pass an in-memory mock/stub, and in integration tests, you can pass a real S3 client, and connect to a real S3 server running locally.
So I don't see dependency injection with interfaces as being premature abstractions. You're simply explicitly specifying the API your code depends on, instead of depending on a concrete type of which you might only use one or two methods. I think this is a good pattern to follow in general, with no practical drawbacks.
Yes, this is absolutely dependent on the design S3 client.
The reality of development is we have to merge different design philosophies into one code base. Things can get messy. 100% agreed.
The approach I advocate for is more for a) organizing the code you do own, and b) designing in a way that you play nice with others who may import your code.
If you add a method to an interface, you break every source file that uses a concrete type in place of the interface (ie, passes a struct to a function that takes an interface) unless you also update all the concrete types to implement the new method (or you update them embed the interface, which is yucky).
For a public interface, you have to track down all the clients, which may be infeasible, especially in an open ecosystem.
My own personal reflections, that I realize may not be true for everyone.
Hypothesis: Living in the moment and being content is a key aspect of happiness. The more you know, the smarter you are, the harder it is to live in the moment or be content.
1) The more you understand, the more problems you see.
When you understand little, everything is ind of random. You have minimal expectations. The more you understand, the more connections you make, the more you see how things could be and how far away they are from an ideal state. You focus more on the potential, and thus the future, than on the present.
2) The more you understand, the less novelty there is.
The first time you play video game in a particular genre (or watch a movie, etc), you take it all in and experience as it is. Little interactions are delightful, as your brain is happy to see two things make an unexpected connection.
After you complete a few, you understand how the system works. The balances and trade-offs that make up the nature of the genre. When you start a new one, you instantly start breaking it apart into a mental spreadsheet, rather than experiencing the literal thing in front of your face. The unexpected elements become expected because you know how even the unexpected stuff tends to work.
The more of life you experience, the less novelty there is to any part of it.
3) The more you understand, the easier it is to live in the future.
"I should try this", "I should do that". You get locked into intellectual responsibilities with long-term goals. The short term becomes just a nuisance to achieve long-term goals. You aren't only not living in today, you aren't even living in tomorrow, you're actually living 6-24 months from now.
4) The more you understand, the less of a point you see.
If you're a pattern solving machine, eventually you realize there's no bottom to find. There's always just another chaotic pattern to pick apart. Another thing to learn. The same things play out over and over again, mildly differently. You can't fix the majority of the problems you see. You can barely understand yourself.
You're good at min/max-ing problems. But what's the ultimate thing to min/max? You have no idea.
So you ask yourself, what's the point to the whole process? Simply maximizing brain chemistry? You know you can't just focus on happy brain chemicals because that will also ruin your life (ie, heroin).
5) The more you understand, the less you hope in magic.
Some optimism depends on magical thinking. "Maybe this will work out because X will happen!" Except X can't happen. But if you believe it could happen, you are genuinely more happy.
The more you understand, the more quickly you can solve all known aspects of a problem and get left with the parts that can't be solved. You know all the things that can't happen to fix a problem. The world isn't magical. Medicine isn't magic, doctors aren't magic, technology isn't magic, politicians aren't magic, problems don't just disappear over night.
> Asking why smart people aren't happier is a bit like asking why people who can jump high aren't more empathetic. There's no direct link between the two, you have to dip out to the material conditions.
I think the reason to expect a correlation is simple: Intelligence should produce a better ability to recognize patterns and identify the most useful ones. In a chaotic world, the things that can lead to a desired outcome are not always clear. It takes time and reasoning to cut through the noise and figure out how to get things done. There is absolutely a reason to suspect that reasoning faster and abstractly would make this easier, and thus produce more overall rewards.
Anytime intelligence is not associated with something, I interpret that to mean the topic is likely not a "hard" min/max problem.
Turns out, most of the human aspect of life is not a hard min/max problem.