Live data from Hacker News

Good Design is Imperfect Design, Part 1: Honest Names

domainlanguage.com

121–130 of 133 posts

Re: Good Design is Imperfect Design, Part 1: Honest Names

#122

The problem is not in the `plus` method, as it's working as expected when the unit is in days. It's the `month` unit that is misleading, since `1 month` looks like a constant value but really isn't, as the behaviour depends on the other operand, breaking associativity – or any expectation on how addition between two constants work really. It would be less confusing if the API removed `month` as a period, and as a pro…

[deleted]

Re: Good Design is Imperfect Design, Part 1: Honest Names

#123

The problem is not in the `plus` method, as it's working as expected when the unit is in days. It's the `month` unit that is misleading, since `1 month` looks like a constant value but really isn't, as the behaviour depends on the other operand, breaking associativity – or any expectation on how addition between two constants work really. It would be less confusing if the API removed `month` as a period, and as a pro…

The month itself is unnecessary complex because long ago, someone decided to break a perfectly good calendar.

Ever wondered why the variable-length month is second in the year, instead of a last? English names of months offer a hint: "September", "October", "November", "December" - sound similar to "hept-", "oct-", "non-", "dec-", i.e. 7th, 8th, 9th and 10th. So as it turns out, February used to come last, as reason would demand, but then the calendar got rotated right by two months.

If we imagine the calendar as it was, with February being the last, then at least the mapping between "day of year" and "month, day of that month" would be a function of just "day of year", instead of being a function of both "day of year" and "what year is it".

Re: Good Design is Imperfect Design, Part 1: Honest Names

#124
Nope. The same philosophy of imperfect design can be held to imperfect naming as well. When will this unexpectedly-intelligent behaviour that belies its name ever bite a user in the ass? Hardly ever? Then it's fine to have a slightly dishonest name if it means a more straightforward API.

To be clear it's still a tradeoff. But I think JodaTime did the right call by settling for the simpler name in this situation.

Re: Good Design is Imperfect Design, Part 1: Honest Names

#125
post #5

Being honest with naming things is also a great roundabout way to ensure you write maintainable, readable code. If the name is honest and it feels awkward, it's a good red flag that there might be a problem with the approach you're taking. I think code golf languages (a-la [0]) are a good example of this approach as well, when your language is as terse as possible, giving very deep consideration to what the language…

I think I missed something here, does this article really suggest that plusExcuseExcuse() would be better? The domain is dates, we all know months have different numbers of days so _something_ must be done and this is explicit from the domain. Changing PI to PI_ISH because numbers in a language is limited does make code more readable. Almost everything in a computer is an imperfect model. i++ is not improved as incre…

I don't really see how neither the article nor my comment suggests anything of that kind, if anything, the opposite. Feels like you're fighting windmills.

Re: Good Design is Imperfect Design, Part 1: Honest Names

#126
post #81

Earlier quoted context omitted.

The problem is that "What is one month after 2021-02-28?" doesn't have a single meaning in plain human language . It could mean 30 days in the future. Or the same day of the week 4 weeks in the future (i.e., 28 days in the future). Or the day of the same cardinality in next month. Or any date in the next month. And those are all equally correct. It's simply not a precise measure of time when spoken from one human to…

Plus/Increment/Add 1 month, does have one single meaning, it's that the outcome may be invalid that is the issue. "2021-01-31".plus(unit="Month", size=1) => "2021-02-31" But nobody really wants that, because it's not a valid date. So implicitly the library is deciding to return a valid date. A library could be written to just provide invalid dates, and let the end user handle any errors. That library could also inclu…

> Plus/Increment/Add 1 month, does have one single meaning

No, it doesn't.

You walk in to the doctor's office on February 28. At the desk, you see another patient about to leave. They turn to the desk attendant and say, "I'll see you in a month for my follow-up."

What date is the other patient's next appointment? What if the date you walked in had been January 31?

Also, for what it's worth, in C#:

  DateTime x = new DateTime(2021, 1, 31);
  x.AddMonths(1); // Feb 28
  x.AddMonths(2); // March 31
  x.AddMonths(1).AddMonths(1); // March 28

Re: Good Design is Imperfect Design, Part 1: Honest Names

#127

I think it's possible to be both honest and readable. One way to look at the issue is that the confusion stems from giving the same name to operators of different types , namely the "Instant plus Period" operator and the "Period plus Period" operator. Period could be implemented as a vector with independent components for days, months, and so on. (I don't know if that's how JodaTime does it, but that's what I would d…

Okay, I almost wish I hadn't read this comment because it is so similar to what I have in part 2! So please don't be annoyed when you see it in a couple of weeks ;-) I actually separated it into a separate part because it undermines my primary point. Sure, we all love it when we have a better decomposition, better names, and everything falls into place. But it doesn't always. Not in the time we have. So then we need…

Heh. You didn’t have a perfect example but you went with what you had and shipped.

Re: Good Design is Imperfect Design, Part 1: Honest Names

#128

The problem is not in the `plus` method, as it's working as expected when the unit is in days. It's the `month` unit that is misleading, since `1 month` looks like a constant value but really isn't, as the behaviour depends on the other operand, breaking associativity – or any expectation on how addition between two constants work really. It would be less confusing if the API removed `month` as a period, and as a pro…

As far as I can tell, you agree with the articles main point. `plus` is a honest name for adding days to a date but dishonest when it comes to adding months. `advanceMonths` is an awkward but more honest name for adding months. An even more honest name would be `addMonthSameDayButCapIfShorter()` or something like that which reflect the gnarly behavior. A weird operation deserves a weird name.

I don't like if `advanceMonths` returns an interval though, since this indicate that the interval is a meaningful unit separately from the initial date. It should return the new date, not an interval.

Re: Good Design is Imperfect Design, Part 1: Honest Names

#129

Earlier quoted context omitted.

What is 2021-02-28 + 1 month? Is that 2021-03-28 or 2021-03-31? It is far from obvious what a normal human would do most of the time here. The lack of associativity is still a problem. If 2021-02-28 + 1 month = 2021-03-28,then (2021-02-28 + 1 month) + 1 month = 2021-03-28 + 1 month = 2021-04-28. While if I ask what is 2021-02-28 + 2 months (given 2021-02-28 + 1 month = 2021-03-31), most people would say 2021-04-30. W…

The problem is that "What is one month after 2021-02-28?" doesn't have a single meaning in plain human language . It could mean 30 days in the future. Or the same day of the week 4 weeks in the future (i.e., 28 days in the future). Or the day of the same cardinality in next month. Or any date in the next month. And those are all equally correct. It's simply not a precise measure of time when spoken from one human to…

[deleted]

Re: Good Design is Imperfect Design, Part 1: Honest Names

#130
post #81

Earlier quoted context omitted.

Plus/Increment/Add 1 month, does have one single meaning, it's that the outcome may be invalid that is the issue. "2021-01-31".plus(unit="Month", size=1) => "2021-02-31" But nobody really wants that, because it's not a valid date. So implicitly the library is deciding to return a valid date. A library could be written to just provide invalid dates, and let the end user handle any errors. That library could also inclu…

> Plus/Increment/Add 1 month, does have one single meaning No, it doesn't. You walk in to the doctor's office on February 28. At the desk, you see another patient about to leave. They turn to the desk attendant and say, "I'll see you in a month for my follow-up." What date is the other patient's next appointment? What if the date you walked in had been January 31? Also, for what it's worth, in C#: DateTime x = new Da…

I explained it pretty clearly what you get when you add a month on January 31st. You get February 31st.

A month is a discrete unit of measure. It is not decomposable into any number of days.

When you increment a month, you get YYYY - (MM+1). Any higher significance is maintained, but irrelevant to the operation. (This applies to the hypothetical statement in the doctor's office, the specific day is indeterminant, but can be assumed the same as current day next month.)

The fact that not all possible days exist is orthogonal to the singular meaning of the operation. It's obviously not greatly valuable to an end-user, but the method of addressing the ambiguity involves a second operation that ensures validity.

End-users want an method that does both the addition and coercion, but you can create consistency if you follow the simple path I laid out in GP.

I'll use your syntax but with the strictly correct definition of the operation.

  Datetime x = new DateTime(2021, 1, 31);
  x.AddMonths(1); // DateTime(2021, 2, 31)
  x.AddMonths(2); // DateTime(2021, 3, 31)
  x.AddMonths(1).AddMonths(1); //DateTime(2021, 3, 31)

  // Ensure Valid, using a coerce to clamp overflows
  DateTime(2021, 2, 31).EnsureValid(); // Feb 28
  DateTime(2021, 3, 31).EnsureValid(); // Mar 31
  DateTime(2021, 4, 31).EnsureValid(); // Apr 30
Post reply on HN