Setting a trap for an unsuspecting co-developer...
-
We produce software for rostering...I'm afraid to give too much identifying information. We have 2 versions of a function called "getActivities()", one for a date-range and one for a single date:
public List<Activity> getActivities(int idate1, int idate2) { public List<Activity> getActivities(int idate) {
One bright spark, who left us a year ago, needed to add a 3rd parameter: "deriveLevel". He only needed it on the single-date version. He discovered that using a simple 'int' would cause a clash with the date-range version, so what did he decide to do, instead of creating a method with a new name? He created a new version using a "boxed type"!!
public List<Activity> getActivities(int idate, @NotNull Integer deriveLevel) {
Normally, having a "@NotNull" boxed type is a clue that something is wrong...after all, the only thing a boxed type parameter can do that the primitive counterpart can't, is be null, right? But in this case it seemed to be a justifiable thing to do for the polymorphism reason. I believe he did it innocently, but if you hate your co-workers then this might be the sort of "trap" you could set for them to stumble into, and then they get the blame when their code breaks the production instance. 10/10 for ingenuity, though!
Which is exactly what happened today to our other developer Rostam. Leading to 4 very irate customers. (We have very frequent releases and don't test all functionality on each release.)
-
@tcotco …and that's why I like languages which don't allow overloading methods at all. Overload resolution is not always intuitive, so people should explicitly state which method they want to call. Also, it doesn't hurt you to give methods with different parameters different names.
-
@tcotco said in Setting a trap for an unsuspecting co-developer...:
(We have very frequent releases and don't test all functionality on each release.)
Have you learned your lesson yet?
Also, consider making the
deriveLevel
an enum. Easy to do, will probably handle the cases that you actually care about without requiring crazy code to deal with stuff that'll never appear in practice, and can't cause trouble with autoboxing.
-
Ah I have an idea. Convert that Integer to an Object. That should be more explicit.
-
@DogsB
It's likely that it actually works as it stops Java from autoboxing.Though more seriously: @tcotco , why are dates even represented as ints and not as a Date or a JodaTime Interval type?
-
@JBert said in Setting a trap for an unsuspecting co-developer...:
@DogsB
It's likely that it actually works as it stops Java from autoboxing.Though more seriously: @tcotco , why are dates even represented as ints and not as a Date or a JodaTime Interval type?
I'm going to put my money on ambiguity compile error.
*edit fuck me it didn't.
-
This post is deleted!
-
@tcotco That's Java, right? Why don't you use Date types for dates, instead of integers?
Also, in this case, the correct solution is to break this apart into 3 functions with descriptive names.
-
@asdf What about multiple dispatch?
-
-
@dkf I'm not the OP but he did mention the function either returns events in a daterange or on a given date depending on which overload, that's why I'd pick Interval and Date.
-
This post is deleted!
-
@LB_ said in Setting a trap for an unsuspecting co-developer...:
What about multiple dispatch?
What about it? If we had multiple dispatch in Java, method overloading would make much more sense. Without multimethods, it may produce results you don't expect.
-
@blakeyrat said in Setting a trap for an unsuspecting co-developer...:
As long as all those params are strongly-typed (meaning: you can't confuse a login token with a username), it's perfectly fine to have one GetUser() method.
Yeah, that's kinda my point. If you could only overload methods if none of the parameter types in one version is convertible into one of the parameter types in the other, I'd like it a lot more, because that'd eliminate the confusing/ambiguous cases. Maybe compilers should enforce that.
-
@tcotco said in Setting a trap for an unsuspecting co-developer...:
We have very frequent releases and don't test all functionality on each release
This is TR
And that you use ints for dates, is this some embedded C disguised as Java?
-
This post is deleted!
-
@asdf said in Setting a trap for an unsuspecting co-developer...:
Maybe compilers should enforce that.
So write a compiler that does exactly that.
-
@blakeyrat said in Setting a trap for an unsuspecting co-developer...:
GetUserFromLastNameAndBirthDate
http://thedailywtf.com/articles/Disjoint_Twins
GetUserFromLastLoggedInDate
Generally I agree with you, but that one should be a different method.
-
@blakeyrat said in Setting a trap for an unsuspecting co-developer...:
Just use a strongly-typed language that doesn't implicitly convert anything to anything else. Problem solved.
What about type hierarchies? B extends A, and there are versions of method
foo
for both A and B. When you pass a B instance tofoo
, the result depends on the declared (static) type of the instance variable, which is counterintuitive.
-
This post is deleted!
-
@asdf said in Setting a trap for an unsuspecting co-developer...:
What about type hierarchies?
You're the person grumbling about it. You figure it out.
-
@dkf I already proposed a solution. I was just providing an example which shows that even in a strongly-typed language, the compiler would have to enforce the restriction I proposed to avoid counterintuitive behavior.
The alternative is changing the behavior of overload resolution to be intuitive by supporting multimethods.
-
@asdf said in Setting a trap for an unsuspecting co-developer...:
I already proposed a solution.
No, you talked about a possible solution. Get implementing.
-
@asdf said in Setting a trap for an unsuspecting co-developer...:
What about type hierarchies? B extends A, and there are versions of method foo for both A and B. When you pass a B instance to foo, the result depends on the declared (static) type of the instance variable, which is counterintuitive.
If it's a problem, you can always sort it at the start of the function
void Foo(B b) { b.DoStuff(); } void Foo(A a) { if (a is B) { Foo((B)a); } else { a.DoSomething(); } }
-
@blakeyrat For fucks sake, nobody is calling you stupid, stop complaining whenever someone tries to have a discussion with you.
-
@Jaloopa That's just a bad manual implementation of multimethods.
My point was that a language should either have proper multimethods or disallow such cases
-
@dkf said in Setting a trap for an unsuspecting co-developer...:
No, you talked about a possible solution. Get implementing.
Why so aggressive today? Did I say something offensive?
-
This post is deleted!
-
-
@blakeyrat You started being aggressive and telling me I should use a strongly-typed language. I provided you with an example to show why that wouldn't solve the ambiguity problem. Which you misunderstood, BTW. I was talking about two overloads which take the parent and child class as arguments.
BTW: You're the only one calling anyone stupid in this thread.
-
This post is deleted!
-
@blakeyrat said in Setting a trap for an unsuspecting co-developer...:
I'm not a fan in dealing with stupid hypothetical bullshit.
Then don't fucking reply, you prick.
-
@asdf if they do different things, that's a code smell IMO. B should be enough like A that you don't need two different methods.
However, I see your point and multiple dispatch does sound like a good idea. I've never used a language that uses it, and it is pretty easy to implement manually, so it's hardly the most important thing
-
This post is deleted!
-
@asdf It's difficult to get type systems right (and overloads/multimethods fit into part of the type problem). Just how difficult it is, well, you won't really believe it until you try to write it yourself.
It looks like it is obvious. It isn't.
If you really want fun, mix in variadic
functionsmethods as well. And/or default values.
-
@blakeyrat Yes, I asked you a question and all you did is accuse me of being stupid and/or calling you stupid and whine like a little child because I didn't provide an example (FYI: I would have if I wasn't on mobile right now).
-
This post is deleted!
-
@blakeyrat said in Setting a trap for an unsuspecting co-developer...:
What the fuck ever. It's a stupid example I yanked out of my ass in 10 seconds.
Stupid hypothetical bullshit, you mean?
@blakeyrat said in Setting a trap for an unsuspecting co-developer...:
I'm not a fan in dealing with stupid hypothetical bullshit.
-
@blakeyrat said in Setting a trap for an unsuspecting co-developer...:
Blakeyrat said a thing so now I must stretch all logic to find some way of calling him an idiot!
-
@anotherusername Yeah, if Blakey's own arrogant posts in this thread are not an example of someone indirectly calling someone else stupid (which, ironically, he complains about in the same post), I don't know what is.
-
@dkf said in Setting a trap for an unsuspecting co-developer...:
Just how difficult it is, well, you won't really believe it until you try to write it yourself.
I may actually do that. I recently bought a few books about compilers and language design because I find it interesting and only know the basics so far.
-
@asdf If you're getting into that sort of thing, the key is being very clear about what semantics you are really implementing. Then pick your target (JVM, CIL or LLVM IR are the three that I think are most worthwhile right now) and get some code spat out. Don't worry about making everything work; get something basic going first and build out from there. It's a lot of fun, though it will probably max out your geek score. ;)
Types are difficult though. Really fucking difficult. Well, unless you make everything lame and who wants that?
-
@dkf said in Setting a trap for an unsuspecting co-developer...:
Types are difficult though. Really fucking difficult. Well, unless you make everything lame and who wants that?
Right now, I'd settle for proper primitives and half-decent string manipulation functions. Because I have seen what happens when a bunch of clowns try to design their own language and the accompanying parser. Hint: everything is a string. Most of the time.
-
@Onyx said in Setting a trap for an unsuspecting co-developer...:
Because I have seen what happens when a bunch of clowns try to design their own language and the accompanying parser.
I think I might count as a clown.
-
@dkf possibly, but I doubt you fell out of this particular car.
-
This post is deleted!
-
@fbmac First alts, now identity swaps? This forum is getting really confusing.
-
@asdf said in Setting a trap for an unsuspecting co-developer...:
First alts, now identity swaps?
Right? Since when does @blakeyrat delete his posts?
-
@Tsaukpaetra join us
-
@fbmac said in Setting a trap for an unsuspecting co-developer...:
join us
We reject your invitation with a counter invite: Join Us. We have space for you!