Live data from Hacker News

Good Design is Imperfect Design, Part 1: Honest Names

domainlanguage.com

101–110 of 133 posts

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

#101
post #15

Earlier quoted context omitted.

You seem to be stuck on: 'what is the value of 1 month' and thinking in terms of days, because that appears to be the precision of the left value. Programmers exist in a world where things such as leap seconds matter. Normally if you have a timestamp that is just before a leap second, then add exactly a day's worth of seconds, you'd slide back a little in time. This might matter in another context, such as defining t…

You’ve ignored your critique and answered only the more obvious anecdotes. So I’ll repeat: What’s Feb 28th + 1 month? Does the human expect the last day of March? Or the 28th day of March? The API doesn’t make that clear - I think you could reasonably argue for either.

The human expects March 28th. Ask any normal person and they’ll answer March 28th.

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

#102
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…

FWIW, I believe there are only two ways to build this library correctly: the way you described here (where intermediate date values are allowed to be invalid) and simply making "one month after 2021-01-31" throw an exception.

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

#103

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…

> The problem is that "What is one month after 2021-02-28?" doesn't have a single meaning in plain human language.

Thank you. That's exactly it. Crazy to see how many developers don't seem to grasp it here. I guess it's the "trap" that we are used to datetimes before the time when we became developers and we have to actually relearn this stuff to get the idea.

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

#104
post #4
post #2

I disagree about "plus" in the JodaTime example. The month addition with corner cases did exactly what I expected because the whole library has been polished to "do what a normal human would do, most of the time". A normal human would not suspect Jan + 1 month, is any month other than Feb. However I suspect, not even reading the documentation, if it were fed 30 or 31 days, rather than '1 month', it would also do exac…

I found the argument about lack of associativity convincing: it's very counterintuitive that date + 1 month + 1 month is different from date + 2 months

If I tell someone on January 31st “call me a month from today” then we have a call on February 28th and I tell them “call me one month from today” I would expect them to call on March 28th.

In contrast if on January 31st I told them “call me two months from today” I’d expect them to call on March 31st.

It’s very intuitive.

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

#105
post #75
post #48

Earlier quoted context omitted.

I think that's the easier case—most people would expect Feb 28th + 1 month = Mar 28th. The tricker one is Jan 31 + 1 month, because there is no Feb 31st. I don't think there is a "correct" answer to that.

If I pay you Jan 31, Feb 28, March 31, April 30, etc., don't I pay you monthly? Shouldn't I be able to express this as a repeated addition of a month? At any rate, these problems have been solved in finance, with proper date and schedule libraries.

To express this in a sane way you want to express "the last day of the month". You can't claim it is "just keep adding to the hire date one month times the current month minus the hire month" as if I hire you in February that won't work. You really need to be calculating "take the current time, replace the day with 1, add one month, subtract one day" to get the next pay date.

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

#106
post #85
post #75

Earlier quoted context omitted.

If I pay you Jan 31, Feb 28, March 31, April 30, etc., don't I pay you monthly? Shouldn't I be able to express this as a repeated addition of a month? At any rate, these problems have been solved in finance, with proper date and schedule libraries.

No, you should be able to express it the way I mentioned in other examples: Base .plus( N months ) where N is whichever month after the reference you want. .plus .plus .plus isn't correct because "x months" doesn't have a fixed size. You are NOT saying Base .plus(30 days), NOR are you saying Base .plus(4 weeks) ((which BTW, I'd expect to stay on the same weekday)). You're incrementing by an unstable value.

This doesn't work either as it wouldn't work correctly if started in a month with less than 31 days. To represent "the last day of the month" you really need to be subtracting one day from the first day of the next month, full stop: any solution working off of these weird rounding rules is going to be unreliable.

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

#107

Strong disagree - 'plus' is quite a good name for Joda Instant, and his alternatives are atrocious. Certain problem domains require baseline familiarity with the subject. Far more people can recite the old "30 days has September, April, June, and November" rhyme than can explain what the words commutative and associative mean. Date math may annoy pure mathematicians but normal humans are used to working with calendar…

Exactly right. Although I think your comment here rather underestimates mathematicians :) Regular people are the ones who are only used to thinking in real numbers or integers. While some may be familiar in a practical way with how dates and times work, they would probably struggle to rigorously define the algebra of time math where associativity and commutativity don't hold. Mathematicians will be familiar with area…

Yeah ironically I think STEM non-mathematicians (STE?) in these comments seem to have the most difficulty with the concept of “month” because they try to conceive of it as a numerical quantity of days rather than an abstract concept in its own right as a pure mathematician would recognize.

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

#108

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…

I was going to post exactly this: the problem is "month" which is not a fixed value. "Year" also has the same problem due to leap years. I suppose that leap seconds could also pose problems too. I've recommended that clients specify time periods in days or weeks and avoid "months" entirely (ie, 90 days or 26 weeks, but not 3 months) or to specify an end date explicitly.

None of day†‡, hour‡, or minute‡ are fixed duration, either, depending on use cases & circumstance.

An absolute delta type is good to have, but it's also useful to have a "relative delta" type (how my language calls it). Each has their use cases.

† ±1–2h on DST enter/exits

‡ ±1s during leap seconds

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

#109
post #102
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…

FWIW, I believe there are only two ways to build this library correctly: the way you described here (where intermediate date values are allowed to be invalid) and simply making "one month after 2021-01-31" throw an exception.

I agree those are the technically correct way to do it.

But if the reason people are wanting to use the library, is they want something to handle the complexity for them, coercing the data is good for simplication.

There is actually another option, that provides idempotent/associative consistency and implicit coercion to valid values.

This option, which discards some use cases (days beyond 28, when manipulating months), you coerce all values 29..31 to 28. This isn't even as technically correct, as the original option, but it removes the inconsistency and holds to the simplification contract to users.

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

#110
post #57

Also ``` .plus(1 month) ``` The unknown behavior of 1-30 + 1 month is a red flag that maybe you shouldn't be using "month" as a unit of time because it isn't. Months suck. Bill for services every 10 days or every 25 days or every 50 days instead of every month.

Product: we need to support doing x on a monthly cycle Dev: Actually, months are a really inaccurate way of measuring time and we should convince all our clients not to use them. CEO: you're fired.

Programming is the art of turning messy, real world, human problems into tools that work in the best way possible.

If you abdicate that responsibility, quite frankly, what use are you?

Post reply on HN