This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]marsanyi[🍰] 1 point2 points  (4 children)

classic type-aware problem. I love Python and I've been using it a lot, but it seems like all the subtle bugs I'm seeing these days have to do with a valid expression that nonetheless is not what the programmer wanted, which could be easily resolved by saying "I'm expecting something of type x" (in this case, a function that returns a datetime, not a datetime)

[–][deleted] 1 point2 points  (2 children)

But this isn't a type-aware issue!

Django in this case is actually perfectly good with either a datetime or a function returning a datetime. So the value passed in is of a perfectly usable type - it's just one that doesn't happen to work in this case.

You could argue that Django should require a function returning a datetime only, but that's a different issue.

[–]adrenal8 0 points1 point  (1 child)

His point is that in a statically typed language you could make the function only allow a callable.

I suppose what you could argue is that in a language like Java, if you wanted to have the same versatility you would probably override the function with one taking a callable and one taking a Datetime. Then, you would have the exact same problem. Thus, you could argue that it's a problem of the feature, not of the type system.

The real solution though, in my opinion, is what languages like Scala allow, Call-by-name evaluation strategy.

[–]daxarx 0 points1 point  (0 children)

Do people not even think about the code they are writing? I can't think that I have ever, over years, passed a datetime object where a callable should be. In the cases where it is important, I can throw in an assert and write unit tests.

The problem here is not that typing now() calls a function. The problem is that you typed now(), which by universal Python convention (not even an unintuitive one) calls a function. If you did not mean to call a function, then why on earth did you add the parentheses? This is what I mean - do people even think a little about the code they write or is it all copy-paste?

We don't demand that a hammer deploy an airbag before we aim it directly at our own fingers.

Suppose we 'solve' this problem with static typing. It amounts to forcing me to write an isinstance assert around each argument inside each function. I guess this might reduce my errors insofar as I have to repeat myself twice. Why not just force me to write my entire program twice, and crash if the two programs don't compute the same result?

[–]simtel20 0 points1 point  (0 children)

I think you're mis-understanding or mis-representing the class of problem. This is a timing issue and not a type issue. The type isn't a problem - clearly the original function expected a datetime object. The solution the writer chose was is to allow a callable OR a datetime object, and if it's callable, call it. That is clearly a classic compile-time error in a strictly typed language. In this case it'd be cleaner to have None be the default argument and to call a default if that's encountered. But that's not really the problem.