16 Mar, 2010, flumpy wrote in the 41st comment:
Votes: 0
Deimos said:
flumpy said:
1. wrong. 10 - 100x slower, when scaled up to a system handling 5000 concurrent users, could mean a very great deal slower.

Deimos said:
What MUD do you know with 5000 concurrent users? I'm pretty sure we're just talking in the context of MUDs here, not scalable enterprise applications.


Well, yes. But my rebuttal of being hand waved away was based on my working experience of, strangely enough, enterprise applications. And who says within a "gaming" genera that you may not have 5000 concurrent users?

flumpy said:
2. No, its not personal preference. Exceptions should be used, as DH says, with explicit regard to the language being used.

Be careful using the word "should". Several paradigms you take for granted in day-to-day coding started out being used for things they "shouldn't" have been used for. Besides which, "should" is a very good indicator of "personal preference", and you completely ignored the question, which was "why is it less readable?", not "what should exceptions be used for?"

You are confusing a real world performance issue with a personal preference. I would argue that doing this is actually a wasteful operation and tbh I do not actually need to. The preference comes from knowledge, not from a whim.

Why is it less readable? Well, perhaps readable was the wrong word. I was on my mobile device and didn't feel like expanding on that anyway. I would actually say that throwing an exception can cause a jump in the code to some other, perhaps unrelated, area of code, thus disrupting program flow. If this happens several times in a row, throw catch, throw, catch, debugging or just grokking the code can become more complicated than it needs to.

Deimos said:
flumpy said:
3. I was not talking about "program" exceptions versus "user code" exceptions. I was distinguishing between a real exception use case (file cannot be found, out of memory when allocating, door reference being null) as opposed to program flow "conditional" errors (is the door open, does the file exist, is there enough memory?). Each of these conditions can be checked before performing a task, so the exception really is exceptional (i thought i had a door but now i don't, i tried to allocate memory i thought i had space for but now can't - oops).

An "exception use case" is any case one uses an exception to handle. That's it. You're back to what people "should" and "shouldn't" use them for, and that's personal preference.


Preference based on knowledge, not whimsy. "I feel like wearing fancy dress" is a whim. "I feel like wearing a coat, because its cold" is a preference based on the weather conditions. (Unless, of course, you wear warm fancy dress… in which case both conditions are covered :smirk:)


Deimos said:
flumpy said:
I found a blog with benchmarks for ruby, the first results are bunkum but the second lot are all real:

http://www.simonecarletti.com/blog/2010/...


some code


That's only a ~1.4 second variance across 100,000 iterations. That's a dump-truck load of unopenable doors, my friend.


Now run those in parallel, with 5000 threads, and then we can talk.
16 Mar, 2010, David Haley wrote in the 42nd comment:
Votes: 0
I think you're all agreeing with each other, at least mostly. Exceptions have overhead when they're thrown. Avoid using exceptions in the absolutely common case. Even if you use exceptions, you are unlikely to notice the performance penalty unless it's a tight inner loop. Different languages treat exceptions differently.

Which claims are people disagreeing with? AFAICT you're all saying more or less the above.
16 Mar, 2010, flumpy wrote in the 43rd comment:
Votes: 0
David Haley said:
I think you're all agreeing with each other, at least mostly. Exceptions have overhead when they're thrown. Avoid using exceptions in the absolutely common case. Even if you use exceptions, you are unlikely to notice the performance penalty unless it's a tight inner loop. Different languages treat exceptions differently.

Which claims are people disagreeing with? AFAICT you're all saying more or less the above.


Well, he seems to have gone from "thats a funny definition for exception use" to "here's how they're slow", so ask him..
16 Mar, 2010, Runter wrote in the 44th comment:
Votes: 0
David Haley said:
I think you're all agreeing with each other, at least mostly. Exceptions have overhead when they're thrown. Avoid using exceptions in the absolutely common case. Even if you use exceptions, you are unlikely to notice the performance penalty unless it's a tight inner loop. Different languages treat exceptions differently.

Which claims are people disagreeing with? AFAICT you're all saying more or less the above.


Particularly I still disagree with his assertion that where I used an exception was a bad place. And it seems like he's continuing to try to dispute it with some weird argument about the overhead of using an exception–even if it's in a place where it won't often be raised. He's acknowledging the facts, then pointing to other dubious statistics to prove his previous argument. Which has changed from "It's not efficient." to "it's not a good convention" and back to efficiency.

And it all ends up sounding an awful lot like, "We don't do this in Java."
16 Mar, 2010, flumpy wrote in the 45th comment:
Votes: 0
Perhaps what it really comes down to is that I do not understand why you are using an exception where logic would suffice.

If your object explicitly recommends, as part of its interface documentation, that you check if the door is open or closed first and yet some other api call still tries to use the enter method, then throwing an exception would be a valid use case.

As it was, your example seemed to print user information out using the exception as control flow logic for the class it was for.

There's a reason for the convention, that's all I'm saying, and you hand waved my reason away without consideration. These things often need considering…

I think we can move on here.
16 Mar, 2010, Runter wrote in the 46th comment:
Votes: 0
flumpy said:
Perhaps what it really comes down to is that I do not understand why you are using an exception where logic would suffice.

If your object explicitly recommends, as part of its interface documentation, that you check if the door is open or closed first and yet some other api call still tries to use the enter method, then throwing an exception would be a valid use case.

As it was, your example seemed to print user information out using the exception as control flow logic for the class it was for.

There's a reason for the convention, that's all I'm saying, and you hand waved my reason away without consideration. These things often need considering…

I think we can move on here.


The code was never throwing an exception for the door being closed. I made that clear multiple times. It was only for when the exit was not enter-able for reasons now and reasons in the future. It's also not associated with character input. There's a big difference. In other words, at the moment, the only condition that could trigger the exception is the exit being locked. But as already said multiple times, this isn't even associated with character input. That means if I type "east" and I hit a locked door there is no exception. There are other places where it could happen, though. And in those places it would indeed be an exception. And in those places it would be rare and quite trivial for "overhead."

I hand waved away your objection because you weren't addressing the actual code I posted. Just some problem you are having with a convention you didn't like. I thought I made it pretty clear I didn't care what you thought about it. Guess I didn't.
16 Mar, 2010, David Haley wrote in the 47th comment:
Votes: 0
Well, for what it's worth, my general policy is to use assertions for irrecoverable errors, exceptions for recoverable errors, and then decide on a case-by-case basis for everything else (usually favoring return values). If I can cleanly return errors, I tend to prefer that. But often, an exception is a far more convenient way of "returning" an error across many layers of control flow. For example, this is basically C++ handling exceptions from Lua.

void Character::handleInput(const std::string & line)
{
lua_State * state = gTheWorld->getLuaState();

// push the actor input function onto the state
if (!Character::getInputFunction(state)) {
return;
}

// push the actor binding and the input line
if ( !pushBinding(state) )
{
gTheWorld->LogBugString("Error pushing character binding");
return;
}
lua_pushstring(state, line.c_str());

int retval = lua_pcall(state, 2, 0, 0);

if (retval != 0)
{
gTheWorld->LogBugString("Error in Lua actor input handling:");
gTheWorld->LogBugString(lua_tostring(state, -1));
lua_pop(state, 1); // pop the error message
return;
}

// All done.
}


I probably wouldn't do what Runter did if I were writing C++ or Java. But I might consider it when writing Python. Again, the answer is a relatively boring "it depends"…
16 Mar, 2010, Deimos wrote in the 48th comment:
Votes: 0
I recognize your convention. I recognize your (sometimes) valid reasoning behind that convention. I also recognize that your convention doesn't produce any practical performance gain in any of my code, and makes it less flexible and harder for me to maintain.

The relatively minuscule overhead of throwing exceptions here and there doesn't even come close to breaching network latency. This means that if you're on the other end of my application, you can't tell the difference. And as long as you can't, I don't see any practical purpose in conforming to your convention.
16 Mar, 2010, flumpy wrote in the 49th comment:
Votes: 0
Good. all solid stuff. I must have misunderstood Runter, and Deimos thats fine by me.

Lets move on.
17 Mar, 2010, Chris Bailey wrote in the 50th comment:
Votes: 0
I've used character.move(x,y) on multiple projects. I have no particular reasoning other than it just made the most sense to me. =)
17 Mar, 2010, David Haley wrote in the 51st comment:
Votes: 0
It's not that it's clearly bad. To summarize from the thread I linked to,
- Commands being on actors makes it harder to have command plug-ins because you must be adding things to the actor class. Even with mix-ins, this is irritating.
- If commands are methods, they can edit private data on the object which can lead to all kinds of confusion and brokenness. (Of course, well-written commands would be using the appropriate interfaces anyhow. But if the commands are forced to be separate, the good standards are also forced upon you.)
- Certain commands might be applicable to entities that do not yet have an in-world presence, for example the 'who' command.


Now if character.move(x,y) isn't an actual command but rather some function that sets the character's internal coordinates to x,y it's a different story. As usual it depends and it's difficult to give answers in the absolute. The above points are just something to keep in mind. Note that modularity doesn't always actually gain you something, because if you have no need at all for modularity it's only adding complexity. The counterpoint is that it's hard to know when you might need modularity later. But, adding it now means more work now, whereas maybe adding it later might result in no work at all. IMHO this is just something one develops with practical experience writing software.
17 Mar, 2010, Deimos wrote in the 52nd comment:
Votes: 0
To be honest, I don't really see why allowing World to handle this kind of logic is so bad. I look at it like a chessboard, with the tiles being rooms, and the pieces being creatures. The pieces don't move themselves. They require a ominously looming presence to control them and everything they do (World). Shrug.
17 Mar, 2010, donky wrote in the 53rd comment:
Votes: 0
David Haley said:
Different languages use exceptions different ways. The Pythonic way to get an element out of a map (dict), for example, is not to test if it's present and then get it, but to just get it and catch the KeyError that's raised if it's not present.

Interesting, I use and generally see this pattern:

movementShift = {
"\x1b movementShift = {
"\x1b[A": ( 0,-1),
"\x1b[B": ( 0, 1),
"\x1b[C": ( 1, 0),
"\x1b[D": (-1, 0),
}.get(keycode, None)
if movementShift:
# Do something.[/code]And very rarely see anyone rely on catching KeyError.
17 Mar, 2010, quixadhal wrote in the 54th comment:
Votes: 0
Deimos said:
Quote
Brush your teeth? ToothBrusher(myTeeth).go().

Hahahaha. Classic.

Heh!
17 Mar, 2010, KaVir wrote in the 55th comment:
Votes: 0
Deimos said:
To be honest, I don't really see why allowing World to handle this kind of logic is so bad.

Because:
David Haley said:
Certain commands might be applicable to entities that do not yet have an in-world presence, for example the 'who' command.
17 Mar, 2010, David Haley wrote in the 56th comment:
Votes: 0
donky said:
David Haley said:
Different languages use exceptions different ways. The Pythonic way to get an element out of a map (dict), for example, is not to test if it's present and then get it, but to just get it and catch the KeyError that's raised if it's not present.

Interesting, I use and generally see this pattern:

movementShift = {
"\x1b movementShift = {
"\x1b[A": ( 0,-1),
"\x1b[B": ( 0, 1),
"\x1b[C": ( 1, 0),
"\x1b[D": (-1, 0),
}.get(keycode, None)
if movementShift:
# Do something.[/code]And very rarely see anyone rely on catching KeyError.[/quote]
Well, that works when you don't need to distinguish between things being in the map or not. Perhaps it's just a style thing; most of the code I've seen (not written by myself) makes extensive use of KeyError. This [url=http://www.python.org/dev/peps/pep-0008/... guide for Python[/url] doesn't make explicit a suggestion on this point, however it does show the try/catch KeyError pattern I was talking about.

But your approach is also more efficient than first testing if something is in the map and then grabbing it (which entails two lookups).

(I say 'map' because this reasoning applies to any map type, not just dicts. Two lookups can be quite expensive on complex map types.)
17 Mar, 2010, David Haley wrote in the 57th comment:
Votes: 0
KaVir said:
Deimos said:
To be honest, I don't really see why allowing World to handle this kind of logic is so bad.

Because:
David Haley said:
Certain commands might be applicable to entities that do not yet have an in-world presence, for example the 'who' command.

For those who didn't read the other thread, I actually grabbed that example from KaVir in my summary because I thought it was a good one. :smile:

(That said: I think you can still have a "master manager object" that can deal with commands like this, even for entities that don't fully exist yet.)
17 Mar, 2010, Scandum wrote in the 58th comment:
Votes: 0
OO design is about creating maintainable and reusable code, not for the sake of OO design.
17 Mar, 2010, David Haley wrote in the 59th comment:
Votes: 0
Was there a reason given here that you found was just for the sake of OO design, and not related to maintainability, reusability, or extensibility?
17 Mar, 2010, Deimos wrote in the 60th comment:
Votes: 0
KaVir said:
Deimos said:
To be honest, I don't really see why allowing World to handle this kind of logic is so bad.

Because:
David Haley said:
Certain commands might be applicable to entities that do not yet have an in-world presence, for example the 'who' command.

What does that have to do with World handling what boils down to world logic? If "who" gives you a list of online players, what contains that list? World (or whatever your equivalent is). I see no problem there, personally.
40.0/163