This week's book giveaway is in the Design forum.We're giving away four copies of Design for the Mind and have Victor S. Yocco on-line!See this thread for details.
Win a copy of Design for the Mind this week in the Design forum!

# How to deal with illegal arguments

Jeff Verdegan
Bartender
Posts: 6109
6
Campbell Ritchie wrote:
Winston Gutkowski wrote:… should you throw NPE or IllegalArgumentException? …
Now that really would start a fight
I think it is NPE if you pass a null and IAE if you pass a “real” argument which has the wrong value. So I think we would agree in this instance.

I'd throw IAE. I don't think I ever throw NPE myself. I let the JVM throw it when code tries to dereference null. I think IAE makes more sense because to me the real problem is that an illegal argument was passed. The fact that the argument is null is an additional detail, and if I wanted to capture it, I'd define and throw IllegalNullArgumentException extends IAE.

But it's about a grain of sand difference between the two sides of the balance.

Jeff Verdegan
Bartender
Posts: 6109
6
Junilu Lacar wrote:
As my final note on the discussion about the identity element of max() - after reading the wikipedia entry on the Empty Set, I understand how negative infinity is the identity element for the maximum operator. However, to translate that to "Integer.MIN_VALUE is the identity element of max()" (in the context of collections, where an empty collection can be considered) is not mathematically or logically correct and we should not try to bolster that assertion with a mathematical proof because that would be misleading at best.

I think you'll find that mathematicians disagree with you here.

In terms of defining real-world methods, go with what makes sense for that particular context, requirements, and use case, and document it. In some cases the identity element may be appropriate, and in some cases an exception may be appropriate. As a programmer, my first instinct would be to throw IAE. However, returning the identity element from max({}) is mathematically sound, so there's something to be said from doing it that way and letting the caller deal with the result if he passed an empty set.

Junilu Lacar
Bartender
Posts: 7465
50
Jeff Verdegan wrote:I think you'll find that mathematicians disagree with you here.

I can check with a couple of them that I know from college (not being facetious, I really do know a couple of Math professors who are big on advanced math, logic, and topology). I let you know what they say.

Jeff Verdegan
Bartender
Posts: 6109
6
Junilu Lacar wrote:
Jeff Verdegan wrote:I think you'll find that mathematicians disagree with you here.

I can check with a couple of them that I know from college (not being facetious, I really do know a couple of Math professors who are big on advanced math, logic, and topology). I let you know what they say.

Fair enough. And in case you weren't aware, Paul, who was giving the explanations earlier, has a PhD in Math, if I'm not mistaken. I find he pretty much always knows what he's talking about.

Junilu Lacar
Bartender
Posts: 7465
50
Maybe I'm just a victim of one of my favorite Mark Twainisms but so far I have yet to see convincing proof that Integer.INT_VALUE is unconditionally equivalent to NEGATIVE_INFINITY. My biggest hurdle perhaps is that the former is a discrete and valid value for an Integer whereas the latter is indeterminate and not a valid value. They just can't be the same without resorting to some kind of compromise or the convention that I already said I can accept.

And I just ran a JUnit test:
assertTrue(Double.NEGATIVE_INFINITY < Double.MIN_VALUE) and this passed. I can't think of an equivalent test for Integer.MIN_VALUE that will pass, unless you mix types assertTrue(Double.NEGATIVE_INFINITY < Integer.MIN_VALUE)

"It ain't what you don't know that gets you in trouble, it's what you know for sure that ain't so." -- Samuel L. Clemens

Winston Gutkowski
Bartender
Posts: 10226
58
Junilu Lacar wrote:"It ain't what you don't know that gets you in trouble, it's what you know for sure that ain't so." -- Samuel L. Clemens

The politician's lament.

"For every common human problem there is a simple solution - and it's almost invariably WRONG."

Winston

Campbell Ritchie
Sheriff
Posts: 48652
56
Winston Gutkowski wrote: . . . I tend to agree with Campbell,
It does happen. Only rarely, but it does happen.
time to return this thread to its owner (although, like Elvis, he's probably left the building).

Winston
Even if OP has left the building, can we return him his thread, please.

Winston Gutkowski
Bartender
Posts: 10226
58
Campbell Ritchie wrote:Even if OP has left the building, can we return him his thread, please.

Right. I'm going to try to split all this crap into another thread, like Junilu suggested.

Hopefully, I get it right....

Winston

Campbell Ritchie
Sheriff
Posts: 48652
56
It’s not crap. but a worthwhile discussion.

Junilu Lacar
Bartender
Posts: 7465
50
It is a great discussion. Thanks to all the moderators who, despite differences of opinion and perhaps even agreeing while disagreeing, have kept it very civil and non-confrontational. I think Campbell is right in saying that we probably don't disagree that much, just some differences on the details.

Winston Gutkowski
Bartender
Posts: 10226
58
Junilu Lacar wrote:It is a great discussion. Thanks to all the moderators who, despite differences of opinion and perhaps even agreeing while disagreeing, have kept it very civil and non-confrontational. I think Campbell is right in saying that we probably don't disagree that much, just some differences on the details.

I think that the division probably comes down to experience. I may be wrong, but Junilu (and this is going to sound patronising, but it's not meant to be) you sound like a young man with a good brain and lots of good ideas; it's just that experience sometimes tells us old farts that dogma, even with the best of intent, can be as brittle as bad code. There's always more than one way to skin a cat; and that certainly holds true in programming.

TDD is a paradigm, and it has a lot of merit, especially, I suspect, in RAD or high-maintenance environments, because
(a) it focuses on what's needed, not what's been asked for.
(b) it works from a stable base.
but it's not a universal one, and many of us haven't had the luxury of working in such an environment; so you'll have to excuse us if we're a bit slow on the uptake sometimes.

Winston

Junilu Lacar
Bartender
Posts: 7465
50
Winston Gutkowski wrote:I think that the division probably comes down to experience. I may be wrong, but Junilu (and this is going to sound patronising, but it's not meant to be) you sound like a young man with a good brain and lots of good ideas; it's just that experience sometimes tells us old farts that dogma, even with the best of intent, can be as brittle as bad code. There's always more than one way to skin a cat; and that certainly holds true in programming.

In any other context, I'd take that "young" thing as a complement, but no, I'm actually not as young as you seem to think I am. I learned programming starting concurrently with Apple ][ BASIC on an Apple ][ clone and Turbo Pascal on CP/M, then went with "advanced Disc BASIC" on a TRS-80. That's how long I've been around. I cut my teeth on xBase and Clipper, then moved to RPG for a while, hated it, got some work doing COBOL, hated it, then got into MS-Access and Visual Basic. Didn't like that much either. Then got into Delphi (Object Pascal) before landing in Java on the cusp of Y2K. I've seen most anything you can think of in business application systems development and I've been through a lot of projects, some multi-year, multi-million \$ ones. I've been a technical lead at my current company for a number of years now, mentoring a number of developers, and have been told I'm a pretty darn good one, although I'm overly critical of myself sometimes, thinking that I still have a lot to learn. My wife says I read too much and work even more too much. So, you could say I have a few miles on me and I've been around the block a few times.

As for TDD, it's a "powerful discipline that helps you organize your code, your tests, and your time" as Uncle Bob says and I can attest to that from first-hand experience. I stand behind my rules of thumb because I have seen them save myself and my teammates a lot of grief. No offense taken and I agree that there are many ways to skin a cat. I don't think in any of the posts so far that I've said "Your way is wrong" (except for the Integer.MIN_VALUE thing, of course); I've tried to keep it to "Well, here's how I do it" because it's what has proven to work for me and my teams so far.

Cheers

(That picture on my bartender profile is over 10 years old -- I have a few more pounds of blubber and a lot less hair than that now -- the kids are teenagers now)

Winston Gutkowski
Bartender
Posts: 10226
58
Junilu Lacar wrote:As for TDD, it's a "powerful discipline that helps you organize your code, your tests, and your time"

Alleluyah!

But seriously, I've read a bit about TDD, and I like what I read. I've even got into the practise of creating a JUnit module for every major class I create, and mapping out tests for revisions - but I can't claim to follow the discipline religiously.

I guess my question is: I can understand it's use for creating properly tested, well thought-out classes; but I could also envision it creating the programming equivalent of an anthill: extremely efficient, and highly adaptive; but not really changing much. Where does the impetus for change come from in In a TDD environment?

Winston

BTW: From your CV, I guess you qualify as a middling fart. TRS-80? There's a blast from the past. Didn't even know it was a real computer...

Junilu Lacar
Bartender
Posts: 7465
50
Winston Gutkowski wrote:but I could also envision it creating the programming equivalent of an anthill: extremely efficient, and highly adaptive; but not really changing much. Where does the impetus for change come from in In a TDD environment? ... qualify you as a middling fart.

I'll leave my bodily functions out of this, thank you very much.

I just got some survey results back from our corporate learning group about a TDD workshop I gave on September 11 to about 30 engineers in our San Jose offices. Feedback was pretty good (he says, feigning humility with an understatement). What I told those guys and what I think impressed them the most was the passion that TDD brings back to you as a programmer. It's a rush to be able to get things done and be so much more certain that the code actually works. You can actually take pride in the work that you did. There's more of a "Hey, look what I did, it's beautiful!" kind of feeling going around. I'm not sure if this is what you're talking about but the change that I see when people start doing TDD effectively is that designs are much better, there are more tests, developers are not debugging so much (expertise with a debugger is an undesirable skill for agile practitioners!) and teamwork is generally a lot better.

Yesterday, in a virtual code review and group development I was doing with two other engineers, we decided to make a fairly significant change to the design of a piece of functionality we were working on. This is a legacy code base we have been working in for a couple of years now, but following the Boy Scout Principle, we have slowly cleaned up the areas of the code that we have to occupy and maintain. My policy with new code is that it MUST be written TDD style. Old code that we touch has to be refactored and covered with as many unit tests as we can get. In the old code, the change we made would have taken at least two weeks because of all the spaghetti we would have to untangle and tease apart, trying not to break anything. Yesterday, we were done in two 30-minute pomodoros. We thought that we'd have to deal with a lot of ripple effects but because we had done TDD on surrounding code, our tests gave us the assurances that we were not breaking anything as we made changes and our TDD-driven design (TDD-DD!) was loosely coupled enough that we didn't even have to deal with any ripple effects! A very pleasant surprise indeed. That was a great feeling, and we were actually whooping it up a little bit when we saw those green bars flash every time we made one little change after another.

Imagine three engineers yelling "Yeah, baby!" into their respective headsets as they watched JUnit flash a green bar on WebEx. Pretty crazy, right? Yeah, we need to get ourselves a life. But that's just it. Those guys got about four 1-hour pomodoros and three 30-minute pomodoros done yesterday and it was very satisfying for them. I got to quit work at 5:00, go downstairs and check on my daughter before heading out to pick up my son from wrestling practice. Then I watched a movie on DVD with my wife, then spent a couple of hours reading "Lean Architecture" by Jim Coplien before falling asleep on the couch.

That, to me is the real impetus for change when you do TDD. That last part about my "life" thing might seem unrelated but I don't see it that way. It's an eventual result of the development values and habits that I have instilled in myself and the people I work with. But maybe I've been blabbering away, totally out of synch with what your were asking.

Jeff Verdegan
Bartender
Posts: 6109
6
Junilu Lacar wrote:Maybe I'm just a victim of one of my favorite Mark Twainisms but so far I have yet to see convincing proof that Integer.INT_VALUE is unconditionally equivalent to NEGATIVE_INFINITY.

I assume you mean MIN_VALUE, and I don't think anybody is asserting that that equivalence exists, and certainly not unconditionally.
valid value.

They just can't be the same without resorting to some kind of compromise or the convention that I already said I can accept.

I had a hard time accepting MIN_VALUE as a valid result for max({}). I also used to have a hard time accepting that some infinities were larger than other infinities. I got over both prejudices.

And I just ran a JUnit test:
assertTrue(Double.NEGATIVE_INFINITY < Double.MIN_VALUE) and this passed. I can't think of an equivalent test for Integer.MIN_VALUE that will pass, unless you mix types assertTrue(Double.NEGATIVE_INFINITY < Integer.MIN_VALUE)

That test and the lack of an equivalent in int has zero bearing on the validity of Integer.MIN_VALUE is the result of max({}) over ints.

Junilu Lacar
Bartender
Posts: 7465
50
Jeff Verdegan wrote:That test and the lack of an equivalent in int has zero bearing on the validity of Integer.MIN_VALUE is the result of max({}) over ints.

Unless you have better reasoning than "has zero bearing", I remain unconvinced. Integer.MIN_VALUE is a valid value in the range of Integer values so the unqualified statement that "Integer.MIN_VALUE is the identity element of max({}) over Integer" does not calculate for me. I can believe that "Double.NEGATIVE_INFINITY is the identity element of max({}) over Double" so why should this have no bearing on the believability of the other statement? Double.NEGATIVE_INFINITY is NOT in the range of Double.MIN_VALUE.Double.MAX_VALUE. How would Integer.MIN_VALUE be any different?

I know you said that nobody is saying anything about unqualified/unconditional but the other assertions you guys have been making read otherwise to me. At this point, I'm beginning to think that it might be better if I just sleep on this a little bit, then if I still don't get where you guys are coming from, then we can agree to disagree. I won't think any less of you guys for sure and I think I'll be fine living in blissful ignorance of the reasons for "Integer.MIN_VALUE is the identity element of max()" being true. Gotta go pick up my daughter from volleyball practice now! Later...

Jeff Verdegan
Bartender
Posts: 6109
6
Junilu Lacar wrote:
Jeff Verdegan wrote:That test and the lack of an equivalent in int has zero bearing on the validity of Integer.MIN_VALUE is the result of max({}) over ints.

Unless you have better reasoning than "has zero bearing", I remain unconvinced. Integer.MIN_VALUE is a valid value in the range of Integer values so the unqualified statement that "Integer.MIN_VALUE is the identity element of max({}) over Integer" does not calculate for me.

Paul already demonstrated how it is valid. I don't know what else I can add to that.

I can believe that "Double.NEGATIVE_INFINITY is the identity element of max({}) over Double" so why should this have no bearing on the believability of the other statement?

Because the definition of identity element doesn't hinge on anything that Double.NEGATIVE_INFINITY has that Integer.MIN_VALUE doesn't have.

Double.NEGATIVE_INFINITY is NOT in the range of Double.MIN_VALUE.Double.MAX_VALUE. How would Integer.MIN_VALUE be any different?

Why would it be required to be outside the range? (Also, not that MIN_VALUE in Double has a totally different meaning than MIN_VALUE in Integer. In Double, it is the minimum magnitude that a Double can have. The actual minimum value (farthest to the left on a number line, not counting negative infinity) is -Double.MAX_VALUE.

I know you said that nobody is saying anything about unqualified/unconditional but the other assertions you guys have been making read otherwise to me.

I think it's been made pretty clear that in a mathematical sense, MIN_VALUE is the identity element of max() over int, by definition. And I have stated explicitly, 2 or 3 times, that although this can be the right result for a Java max() method that gets passed the empty set, it isn't automatically always appropriate.

Winston Gutkowski
Bartender
Posts: 10226
58
Junilu Lacar wrote:That last part about my "life" thing might seem unrelated but I don't see it that way. It's an eventual result of the development values and habits that I have instilled in myself and the people I work with. But maybe I've been blabbering away, totally out of synch with what your were asking.

Not at all. Makes me wish I'd worked in a few more places like it. Unfortunately only one for me: about 8 years in total (in 3 separate stints) with the guy who used to be my boss and became a good friend in the process. Basically, he let me play - get things wrong, work 'em out, get 'em right, work out why I got 'em wrong... Don't get me wrong, it was hard work, and I probably pulled a couple of month's worth of all-nighters for him; but by God was it fun, and I learnt a hell of a lot in the process. I also had a fair bit of power to "run my own ship".
So many other places, it's simply a case of learning procedures, and "fitting in", and not rocking the boat...

I guess my question was about the strengths and weaknesses of TDD. Did you follow my analogy of the anthill? It's possible for an organisation/system/program to be highly efficient, but rigid, and slow to change. I was wondering, in a test-driven environment, which seems, to an outsider like me (maybe incorrectly), to be based on "the concrete" and "the provable", where the impetus for change comes from? Who provides the "that's funny..." moment?

And just in case you don't know the reference:
Isaac Asimov wrote:The most exciting phrase to hear in science, the one that heralds new discoveries, is not 'Eureka!' (I found it!) but 'That's funny ...'

Winston

Junilu Lacar
Bartender
Posts: 7465
50

I can't explain what blocked me from understanding it and what finally unblocked me but I'm sure the unwavering attempts of Jeff Verdegan and Paul Clapham had something to do with it. Thanks guys, and sorry for putting you through all that. I'm sure it must have been exasperating for you to read all my misguided refutations. I would have dismissed me as an absolute idiot after the first few tries--and I don't blame you if you actually have--but still you stayed with it.

@Winston: the most exciting phrase Paul and Jeff will hear from me in this thread: "Eureka!" -- I think I finally got it. Wow, was I thick or what?

Or maybe "DOH!" is more appropriate.

At least it didn't take all night for my subconscious to wake up and kick me in the head. A few hours of sleep on the couch was all it took.

Rather than me boring you guys who already knew you were right with my convoluted brain-ramblings, let me summarize what I think helped me get in line with the math:
1. The difference between proofs involving finite and infinite sets: Extended Real Numbers, positive and negative infinity are necessary because of the range of R is infinite.
2. Both the java.lang.Double and java.lang.Integer are finite sets, not infinite (Duh) so you don't need negative or positive infinity
3. Integer.MIN_VALUE is the identity for max() in the domain of Integer (double, triple Duh) Check with Paul - he has the proof.

Thanks again for your patient guidance -- it was a cattle prod worthy performance on my end and a Nobel prize worthy effort on yours.

(I'll leave at that for now and go back to the start of the thread to add a cautionary note for innocent passers by in the morning) Cheers!

Junilu Lacar
Bartender
Posts: 7465
50
Winston Gutkowski wrote:where the impetus for change comes from? Who provides the "that's funny..." moment?

And just in case you don't know the reference:
Isaac Asimov wrote:The most exciting phrase to hear in science, the one that heralds new discoveries, is not 'Eureka!' (I found it!) but 'That's funny ...'

Winston

Seems like there's no end to my thickness tonight but I'll give it a shot anyway, I might be on a roll here...

I think the impetus for change in the team comes from the first developer for whom the concepts of TDD finally click in his head. Once one guy gets fired up about it, he wants to test-infect everyone else he works with. That's what happened with me and my team and that's why I am giving workshops on TDD at work. On a personal level, it's hard to unlearn old habits and learning TDD requires a 180-degree shift in the way you think about tests, code, and design. It requires you to expect to be wrong, which goes against the grain of most developer's instincts. Once you accept that it's OK to be wrong, the going gets a lot easier. For me, my "That's funny..." moment was when I realized that it's actually GOOD to be wrong when you do TDD. Like this whole intertwined discussion about Integer.MIN_VALUE and max. I find it very refreshing to be able to admit that I was wrong even after I totally made myself look like a fool. And that's OK. At least now I've learned (or maybe even relearned) and grokked something. Just like in TDD. And I think that's pretty cool...

Jeff Verdegan
Bartender
Posts: 6109
6
Junilu Lacar wrote:Thanks guys, and sorry for putting you through all that[/b]. I'm sure it must have been exasperating for you to read all my misguided refutations.

Not at all. Like I said, I was in exactly your position just a few months ago. And I can't even claim to 100% grok it now. It makes sense to me in an isolated context, and I can see how it can logically transfer to the Java int context, but there's still a part of me that doesn't feel quite right about it. I suspect that to Paul it seems blatantly obvious on all levels.

@Winston: the most exciting phrase Paul and Jeff will hear from me in this thread: "Eureka!" -- I think I finally got it. Wow, was I thick or what?

I've uttered that phrase no small number of times myself. It is at once humbling and illuminating.

When all is said and done, I'm glad you were willing to engage in the discussion without things getting personal. As I'm sure you've realized, a lot of folks here like a good argument, as long as it's kept civil and the points of contention are logical rather than personal.

Winston Gutkowski
Bartender
Posts: 10226
58
Jeff Verdegan wrote:I'm glad you were willing to engage in the discussion without things getting personal. As I'm sure you've realized, a lot of folks here like a good argument...

Me, for example.

@Junilu: Thanks for your explanation, and yes, it makes a lot of sense. Expect to be wrong, eh? I'll have to give it a try...

Winston

Junilu Lacar
Bartender
Posts: 7465
50
Here's my speil on not being afraid to be wrong:

When Thomas Edison created the first practical light bulb, he went through hundreds of different materials, trying to find the right one to use as a filament. He finally succeeded with a carbonized sewing thread. The bulb burned for 13.5 hrs and it was considered a success. After more refinement, he made one that lasted 40 hours. Then after even more refinement, he had one that lasted 1200 hours.

If you are doing something creative, you have to accept the fact that you won't get it exactly right the first time. Or the second. Or the third. You have to be willing to be wrong. Sir Ken Robinson says "If you're not prepared to be wrong, you'll never be able to create something original." When you're doing TDD, you start with a failing test. No production code, just a failing test. Then you write some seemingly idiotic production code to just make the test pass. This sounds like a crazy way to develop software because it goes against your most basic instincts as a developer. But it's OK! You know you'll fix it later, once you have another failing test that says you're allowed to fix it. That's kind of what the TDD cycle feels like. Don't be afraid to be wrong. The more times you're wrong, the closer you are to getting it right.