|
fansipans posted:Ugh... why is this page taking forever to load?!?!?
|
# ? Nov 3, 2008 03:55 |
|
|
# ? May 15, 2024 03:54 |
|
Janin posted:Here's one for you Python programmers out there: My favorite part of this has to be the final try-except block. I'm not sure if the programmer was concerned that the return statement might raise an exception, or if it was supposed to be a really, really hacky way to either make sure that 'name' was not a unicode string or that the user's LANG environment variable was set correctly. But except: pass makes me want to strangle people.
|
# ? Nov 5, 2008 11:02 |
|
Habnabit posted:But except: pass makes me want to strangle people. Sometimes you don't or can't care if an operation fails. code:
|
# ? Nov 5, 2008 11:09 |
|
Zombywuf posted:Sometimes you don't or can't care if an operation fails. Sure, let's go ahead and swallow SystemExit, MemoryError, and KeyboardInterrupt. Seriously, I've never been in a situation where except: pass was by any stretch of the imagination the right thing to do.
|
# ? Nov 5, 2008 13:04 |
|
Habnabit posted:Sure, let's go ahead and swallow SystemExit, MemoryError, and KeyboardInterrupt. Yes, yes, and holy gently caress python makes Ctrl-C an exception. Sheesh. But fair enough, go ahead and catch KeyboardInterrupt, pass the rest.
|
# ? Nov 5, 2008 14:25 |
|
Zombywuf posted:Yes, yes, and holy gently caress python makes Ctrl-C an exception. Sheesh. But fair enough, go ahead and catch KeyboardInterrupt, pass the rest. Scaevolus fucked around with this message at 15:00 on Nov 5, 2008 |
# ? Nov 5, 2008 14:57 |
|
Scaevolus posted:But it makes sense to handle trapped signals as exceptions-- would you rather there was a different language construct specifically for those sorts of interrupts? Registered interrupt handlers? If the handler decides to exit the regular exit handlers can kick in. This is pretty much a solved problem in C, why Python does it this way is a mystery, and replaces the notion of "function X raised an exception" with "function X or something else raised an exception". You now have to disambiguate the cases.
|
# ? Nov 5, 2008 15:33 |
|
I think a lot of languages do it that way, actually. Certainly Ruby does as well. Doesn't seem like something that scales well to multiple threads (insert Ruby gag here) but it certainly seems pretty consistent with the way the language works, especially given that Exceptions are the best way to break normal control flow in exceptional cases. Edit: It might be possible to override the default interrupt handler in these languages actually. Edit 2: Yeah, Signal appears to let you override the default behaviour in Ruby, there's likely to be something analogous for Python. This makes the default behaviour seem more sensible. Edit 3: And it's signal in Python. This seems like the best compromise where ctrl-C has a nice default behaviour that you can override. zootm fucked around with this message at 18:04 on Nov 5, 2008 |
# ? Nov 5, 2008 17:53 |
|
Ruby does not catch the ^C exception from a "begin; rescue; end", you actually need to go up the Exception inheritance thing to explicitly catch everything.
|
# ? Nov 5, 2008 18:24 |
|
Zombywuf posted:Sometimes you don't or can't care if an operation fails. If you do this in our codebase I will nail your hands to the toilet. If you don't care if it fails, you should be explicit in the failures to ignore. code:
And signals are part of posix, not C last time I checked.
|
# ? Nov 5, 2008 18:54 |
|
tef posted:If you do this in our codebase I will nail your hands to the toilet. It explicitly ignores everything. If you want to ignore everything, this is the mechanism for you.
|
# ? Nov 5, 2008 19:03 |
|
tef posted:And signals are part of posix, not C last time I checked.
|
# ? Nov 5, 2008 19:15 |
|
So the functions are guaranteed just not their implmentation
|
# ? Nov 5, 2008 19:19 |
|
Don't look a gift horse in the mouth, I guess.
|
# ? Nov 5, 2008 19:26 |
|
Habnabit posted:I'm not sure if the programmer was concerned that the return statement might raise an exception, or if it was supposed to be a really, really hacky way to either make sure that 'name' was not a unicode string or that the user's LANG environment variable was set correctly. I think it's a way to check that "name" is defined, since it's assigned to within the loop.
|
# ? Nov 6, 2008 00:01 |
|
My first job was a programmer for a small software house in Manchester. I was to take over the code from another guy who was leaving. I think it was in BBC Basic or something like that (many years ago). Anyway, every method was labelled numerically, like func1(), func2(), func3() and so on, and he created variable names alphabetically - a, b, c .. z, then onto aa, ab, ac, ad .. az etc. It took me weeks to work out what the hell anything was doing. Oh, and the total lack of any comments or documentation was great too. On a more recent job, I was working on a certain Very Large Government Project. The enormous application implemented certain parts of govt. legislation, and the test team tested the code against the legislation. At one point, we found that the code in one module would go into an infinite loop. After a lot of investigation, we found the cause and suggested an appropriate fix. Several meetings later, it was discovered that the code was actually correct, as there was a contradiction in the legislation. If we fixed the infinite loop, the code would fail testing as it no longer agreed with the legislation, so it had to remain as it was until the day that the legislation was altered.
|
# ? Nov 6, 2008 01:32 |
|
Janin posted:I think it's a way to check that "name" is defined, since it's assigned to within the loop. Oh god I think you're right. That's way worse. Zombywuf posted:It explicitly ignores everything. If you want to ignore everything, this is the mechanism for you. My whole point is you never, ever want to ignore everything. Again, what if a MemoryError is raised? You really want to ignore when there's no memory available, when something higher up the stack could free some memory? Zombywuf posted:Registered interrupt handlers? If the handler decides to exit the regular exit handlers can kick in. This is pretty much a solved problem in C, why Python does it this way is a mystery, and replaces the notion of "function X raised an exception" with "function X or something else raised an exception". You now have to disambiguate the cases. When a signal comes in, python interrupts the currently executing stack frame and pushes a new stack frame with the python signal handler function. This function is passed the interrupted stack frame as well. If you have a better idea of how to do this in an interpreted language, I'd love to hear it. Unlike in C (from my understanding of how signal handlers work) you can receive a signal in the middle of interpreting the bytecode, as in, the signal can come in mid-instruction. e: zootm posted:I think a lot of languages do it that way, actually. Certainly Ruby does as well. Doesn't seem like something that scales well to multiple threads (insert Ruby gag here) but it certainly seems pretty consistent with the way the language works, especially given that Exceptions are the best way to break normal control flow in exceptional cases. As far as I know signal handlers will only interrupt the main thread in python. Habnabit fucked around with this message at 01:42 on Nov 6, 2008 |
# ? Nov 6, 2008 01:37 |
|
Here's another method, from the same application as before:code:
|
# ? Nov 6, 2008 20:21 |
|
> The Cavern of COBOL: In here something strage appends >
|
# ? Nov 6, 2008 20:25 |
|
Stoatbringer posted:Anyway, every method was labelled numerically, like func1(), func2(), func3() and so on, and he created variable names alphabetically - a, b, c .. z, then onto aa, ab, ac, ad .. az etc.
|
# ? Nov 6, 2008 20:38 |
|
Habnabit posted:My whole point is you never, ever want to ignore everything. Again, what if a MemoryError is raised? You really want to ignore when there's no memory available, when something higher up the stack could free some memory? quote:When a signal comes in, python interrupts the currently executing stack frame and pushes a new stack frame with the python signal handler function. This function is passed the interrupted stack frame as well. If you have a better idea of how to do this in an interpreted language, I'd love to hear it.
|
# ? Nov 6, 2008 23:20 |
|
Janin posted:Here's another method, from the same application as before: I think just about the only half-decent thing about this code is that it uses gettext. My first thought was that I should count up all of the stupid disgusting deviations from idiomatic, clean, working python code, but I got to the "In here something strage appends" comment and broke down in tears. Seriously, how do people write code this bad? This program probably had a rather genetic development and thus only works under one exact set of conditions. Zombywuf posted:When I don't care if the function is successful, i.e it would be nice to log the error, but we shouldn't tear down the whole program just because we can't. However it turns out you should tear down on memory error because python doesn't guarantee a consistent heap after an out of memory error. I feel dirty just knowing about that. However, a C extension or python itself can deal with it. I don't think you understand how exceptions work. The exception is not the error; the exception is a signal of an error condition. Discarding the exception does not make the error itself go away. If you can't deal with the error condition, don't pretend you can. Zombywuf posted:I wouldn't let exceptions escape signal handlers. I certainly wouldn't define keyboard interrupt as an exception. Especially not in a language famed for its simplicity and consistency of behavior. I have no idea what "escape signal handlers" means here. And, again, I urge you to explain how this could be dealt with in a cleaner way. Zombywuf posted:Then again it uses exceptions to signal generator exits, urgh.... Same thing here. How else would you do this? Python is not php; these things have been thought out carefully, and this was found to be the optimal solution. You seem to think these things were slapped together without any forethought, but you also don't seem to have any suggestions on how it could be better implemented.
|
# ? Nov 6, 2008 23:39 |
|
Zombywuf posted:I wouldn't let exceptions escape signal handlers. Zombywuf posted:I certainly wouldn't define keyboard interrupt as an exception.
|
# ? Nov 6, 2008 23:47 |
|
Habnabit posted:However, a C extension or python itself can deal with it. quote:I don't think you understand how exceptions work. The exception is not the error; the exception is a signal of an error condition. Discarding the exception does not make the error itself go away. If you can't deal with the error condition, don't pretend you can. quote:I have no idea what "escape signal handlers" means here. And, again, I urge you to explain how this could be dealt with in a cleaner way. A signal, i.e. some message received from outside your program, should be understood to be happening in a parallel context, not just lumped at the top of stack on top of whatever is currently executing. quote:Same thing here. How else would you do this? Python is not php; these things have been thought out carefully, and this was found to be the optimal solution. You seem to think these things were slapped together without any forethought, but you also don't seem to have any suggestions on how it could be better implemented. What? Because someone else thought this was the best solution I have to agree? All hail Hypnoguido, gently caress that. One simple solution is that of giving generators an iterator interface, i.e. while (mygen.has_more()) { do_stuff(mygen.get_next()); }. This has been implemented in other languages that provide generators or generator like objects - W3C Xpath interface, istream_iterator in C++ and GNU Prolog's C interface to name a few. I'm sure these were thought about and not just slapped together. zootm posted:Why not? It creates the correct behaviour in the default case in a transparent and understandable way. And if you have some special handler, you can override the default behaviour simply. Sounds like the best of both worlds.
|
# ? Nov 7, 2008 00:42 |
|
Zombywuf posted:Deal with what exactly? "Out of memory" conditions. Zombywuf posted:A signal, i.e. some message received from outside your program, should be understood to be happening in a parallel context, not just lumped at the top of stack on top of whatever is currently executing. That would make Python signal handlers pretty useless, since they wouldn't be able to manipulate the execution state except through global C variables. Zombywuf posted:What? Because someone else thought this was the best solution I have to agree? What would get_next() do when there's no more data to be retrieved, if not raise an exception? In a case like this: code:
Zombywuf posted:It only provides expected behavior in the case where you're trying to catch KeyboardInterrupt. When you're expecting the semantics of exceptions to mean "something has gone wrong with the code in my try block", the behavior will break your program. How would you recommend a python program include special handlers for SIG_STOP or SIG_KILL (insert non POSIX equivalents at your own leisure)? Exceptions are not the same as errors, they merely indicate that an exceptional condition has arisen that prevented the code in the "try" block from executing fully. To handle other signals, the programmer just needs to install a signal handler. That handler can do whatever it wants, including raising an exception. TOO SCSI FOR MY CAT fucked around with this message at 01:17 on Nov 7, 2008 |
# ? Nov 7, 2008 01:07 |
|
Zombywuf posted:It only provides expected behavior in the case where you're trying to catch KeyboardInterrupt. When you're expecting the semantics of exceptions to mean "something has gone wrong with the code in my try block", the behavior will break your program. zootm fucked around with this message at 01:23 on Nov 7, 2008 |
# ? Nov 7, 2008 01:21 |
|
Zombywuf posted:What? Because someone else thought this was the best solution I have to agree? No, I never said that. You seem to be so adamant that this not the best way to do it, without considering that there might be a reason why it is that way or providing an alternate implementation. I agree with Janin's points on your points, though. e: oh yeah, and you can't catch SIGKILL. As for catching signal handlers, it depends on what you're trying to do. For something like using SIGHUP to reload config files, you can take advantage of the suspended state of the program and update the configuration from within the signal handler. Of course, you'd have to write your code in a way to prevent reloading from a signal handler from interfering with things while you're in the middle of getting information from the configuration, but you'd have to do the same in C anyway. You could even just set a flag that the main loop would acknowledge, or post an event, or something. Habnabit fucked around with this message at 08:48 on Nov 7, 2008 |
# ? Nov 7, 2008 08:44 |
|
Janin posted:"Out of memory" conditions. Python docs posted:exception MemoryError So no, python itself is not guaranteed to be able to recover from a memory error and you can only tear down and dump a stack trace if you want to be safe. quote:That would make Python signal handlers pretty useless, since they wouldn't be able to manipulate the execution state except through global C variables. That's a hell of a lot better than injecting exceptions arbitrarily. It means a bit of code that has specific handlers for different exceptions might be seeing exceptions it has no idea how to recover from because they can be thrown anything. quote:What would get_next() do when there's no more data to be retrieved, if not raise an exception? In a case like this: If the user of function does something with it they're not supposed to then the function should throw. Charles Babbage posted:On two occasions I have been asked, – "Pray, Mr. Babbage, if you put into the machine wrong figures, will the right answers come out?" In one case a member of the Upper, and in the other a member of the Lower House put this question. I am not able rightly to apprehend the kind of confusion of ideas that could provoke such a question. quote:e: Also, it's impossible to implement has_more() for a function-based generator. quote:To handle other signals, the programmer just needs to install a signal handler. That handler can do whatever it wants, including raising an exception. My argument is that this is a bad thing. Habnabit posted:No, I never said that. You seem to be so adamant that this not the best way to do it, without considering that there might be a reason why it is that way or providing an alternate implementation. Go on then, what is the reason. Other than that the secret chiefs of python believe it to be better? quote:For something like using SIGHUP to reload config files, you can take advantage of the suspended state of the program and update the configuration from within the signal handler. Of course, you'd have to write your code in a way to prevent reloading from a signal handler from interfering with things while you're in the middle of getting information from the configuration, but you'd have to do the same in C anyway. You could even just set a flag that the main loop would acknowledge, or post an event, or something.
|
# ? Nov 7, 2008 11:35 |
|
Hello, this is a message from the Zombywuf posting advisory service. In my time of knowing Zombywuf I have made a number of observations on his behaviour and beliefs, and I think I can help somewhat here: Here is a summary of what Zombywuf has to say: quote:I don't like python. Here is a summary of the reasons for the above statement: quote:I do not like it because it does things differently from what I am used to. This comes down to the simple fact that python is not c++ or c, although sometimes the fact that python is not perl annoys me too. There might be some technical details involved in the above reasons too, but I have omitted them for clarity. There you have it. Now if all parties concerned wish to continue on this fruitless debate, you can all go and poo poo in a new thread in yospos.
|
# ? Nov 7, 2008 12:05 |
|
tef posted:Yeah, C's exception handling and generators work completely differently to Python's.
|
# ? Nov 7, 2008 12:12 |
|
Zombywuf posted:Why not just throw a hangup exception and have the controlling code catch it and reload the config? That way the code using the config won't be running when you do the reload. Hey, you managed to come up with a simple solution to the problem using the same technique that you so thoroughly hate. Anyway, I'm done here.
|
# ? Nov 7, 2008 13:03 |
|
Zombywuf posted:From the docs: CPython is not the only implementation, and even in CPython there are cases where it's safe to recover from an out-of-memory condition. Zombywuf posted:That's a hell of a lot better than injecting exceptions arbitrarily. It means a bit of code that has specific handlers for different exceptions might be seeing exceptions it has no idea how to recover from because they can be thrown anything. If a block of code doesn't know how to deal with some type of exception, it should let the exception rise through the stack until it encounters code that can handle it. Zombywuf posted:If the user of function does something with it they're not supposed to then the function should throw. If it's going to throw an exception anyway, why even use has_next()? Zombywuf posted:No it isn't. Unless you have some crazy ideas about order of evaluation. code:
|
# ? Nov 7, 2008 19:53 |
|
Janin posted:
has_next runs one more iteration of the loop and caches the result. next returns the cached result. Won't work if the result is dependent on the exact time it's generated, though. EDIT: didn't even notice the sys.exit, I thought it was just breaking on a random int which couldn't be predicted in advance. Still, if you make it explicit that generators may do their work in the has_next step rather than when calling next, that's code is just defined to be correct! JoeNotCharles fucked around with this message at 20:54 on Nov 7, 2008 |
# ? Nov 7, 2008 20:21 |
|
Janin posted:If it's going to throw an exception anyway, why even use has_next()? That's a lot like saying 'If the program is going to exit when it crashes, why bother trying to fail gracefully?' If you design your generator to make a mess then it will make a mess. Congratulations on restating the garbage in garbage out principal again. It just doesn't make a lot of sense to use what most people would consider/assume to be specialized error handling machinery for flow of control or event notification. Not that you can't, but don't expect the rest of the world to agree that it's a perfect system and a great idea.
|
# ? Nov 7, 2008 20:51 |
|
JoeNotCharles posted:has_next runs one more iteration of the loop and caches the result. next returns the cached result. If generators do their work in has_next(), then what should happen when they raise an exception? Does it appear from the has_next() call? That's awfully awkward. Munkeymon posted:That's a lot like saying 'If the program is going to exit when it crashes, why bother trying to fail gracefully?' If you design your generator to make a mess then it will make a mess. Congratulations on restating the garbage in garbage out principal again. The generator is not "making a mess". Many generators have side effects, and it's important that the side effects happen at the prescribed time. I inserted the sys.exit() to prevent arguments about pre-caching results; often, the results themselves are unimportant and it's the side-effects of the generator that matter. The issue with using a has_next()/get_next() style is that it's not as general as the current system. Any loop implemented with has/get_next() can be wrapped in a generator, but the converse is not true because the behavior of a generator allows unpredictable results. Munkeymon posted:It just doesn't make a lot of sense to use what most people would consider/assume to be specialized error handling machinery for flow of control or event notification. Not that you can't, but don't expect the rest of the world to agree that it's a perfect system and a great idea. I don't think anybody is arguing that it's perfect, but it's certainly better than the alternatives. People just need to get over the "all exceptions are errors" mentality.
|
# ? Nov 7, 2008 21:10 |
|
necrobobsledder posted:I was working with this one person that would make research report results in an HTML file in Netscape Composer. I saw her load up the stuff in the browser and was wondering why it was taking about 20 seconds to load on a really beefy UltraSPARC workstation. Eventually she sent me the actual report for me to look at and what I saw was that. I wrote a Perl script to filter out those nbsp elements and the file shrunk from about 15 MB to about 100KB. She has a PhD in electrical engineering and is an IEEE fellow. The worst part is that she's supposed to know Perl pretty well since that's what half her experiments were in and know a bit about HTML. Ugh....
|
# ? Nov 7, 2008 21:19 |
|
Janin posted:If generators do their work in has_next(), then what should happen when they raise an exception? Does it appear from the has_next() call? That's awfully awkward. Yeah, you're right. Whenever generaters are involved I automatically go into pure-functional mode.
|
# ? Nov 7, 2008 21:24 |
|
Janin posted:The generator is not "making a mess". Many generators have side effects, and it's important that the side effects happen at the prescribed time. I inserted the sys.exit() to prevent arguments about pre-caching results; often, the results themselves are unimportant and it's the side-effects of the generator that matter. I would say that exiting any serious program from (essentially) inside a loop conditional is making a mess. That's getting into serious WTF territory unless you're just doing it to screw with someone. quote:The issue with using a has_next()/get_next() style is that it's not as general as the current system. Any loop implemented with has/get_next() can be wrapped in a generator, but the converse is not true because the behavior of a generator allows unpredictable results. I think it would make some sense to force people to use a generator that can have side effects differently than one that can't in most cases, but that could easily be my newness to Python talking. quote:I don't think anybody is arguing that it's perfect, but it's certainly better than the alternatives. People just need to get over the "all exceptions are errors" mentality. Then maybe it should be called an event, rather than an exception(al circumstance)? We could just call all numbers ints, since we're rewriting common paradigms. Some ints will just happen to have decimals.
|
# ? Nov 7, 2008 21:39 |
|
Munkeymon posted:I would say that exiting any serious program from (essentially) inside a loop conditional is making a mess. That's getting into serious WTF territory unless you're just doing it to screw with someone. The actual nature of the side effect is irrelevant to his point. sys.exit() is merely an example of a side effect that will obviously cause problems if it happens at the wrong time.
|
# ? Nov 7, 2008 22:00 |
|
|
# ? May 15, 2024 03:54 |
|
Munkeymon posted:Then maybe it should be called an event, rather than an exception(al circumstance)? We could just call all numbers ints, since we're rewriting common paradigms. Some ints will just happen to have decimals. Or you could just use exceptions. Obviously you've learned, or been taught, that exceptional circumstances are inherently errors. In Python, this is not the case; an exception just means that the code was unable to finish executing, for any reason. If exception handling was to be replaced with another paradigm, I'd prefer something like LISP's conditions.
|
# ? Nov 7, 2008 22:07 |