Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
necrobobsledder
Mar 21, 2005
Lay down your soul to the gods rock 'n roll
Nap Ghost

fansipans posted:

Ugh... why is this page taking forever to load?!?!?


Click here for the full 800x587 image.


oh ..... dammit.
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....

Adbot
ADBOT LOVES YOU

Habnabit
Dec 30, 2007

lift your skinny fists like
antennas in germany.

Janin posted:

Here's one for you Python programmers out there:

code:
snip
:psypop:

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.

Zombywuf
Mar 29, 2008

Habnabit posted:

But except: pass makes me want to strangle people.

Sometimes you don't or can't care if an operation fails.

code:
try:
  log_error(error)
except:
  pass

Habnabit
Dec 30, 2007

lift your skinny fists like
antennas in germany.

Zombywuf posted:

Sometimes you don't or can't care if an operation fails.

code:
try:
  log_error(error)
except:
  pass

Sure, let's go ahead and swallow SystemExit, MemoryError, and KeyboardInterrupt. :v:
Seriously, I've never been in a situation where except: pass was by any stretch of the imagination the right thing to do.

Zombywuf
Mar 29, 2008

Habnabit posted:

Sure, let's go ahead and swallow SystemExit, MemoryError, and KeyboardInterrupt. :v:

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
Apr 16, 2007

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.
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?

Scaevolus fucked around with this message at 15:00 on Nov 5, 2008

Zombywuf
Mar 29, 2008

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.

zootm
Aug 8, 2006

We used to be better friends.
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

Vanadium
Jan 8, 2005

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.

tef
May 30, 2004

-> some l-system crap ->

Zombywuf posted:

Sometimes you don't or can't care if an operation fails.

code:
try:
  log_error(error)
except:
  pass

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:
except IOError:
    pass
Isn't as bad and is a little more obvious what you're trying to do.


And signals are part of posix, not C :3: last time I checked.

Zombywuf
Mar 29, 2008

tef posted:

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.

It explicitly ignores everything. If you want to ignore everything, this is the mechanism for you.

Mustach
Mar 2, 2003

In this long line, there's been some real strange genes. You've got 'em all, with some extras thrown in.

tef posted:

And signals are part of posix, not C :3: last time I checked.
C gaurantees signal(), raise(), and SIGABRT, SIGFPE, SIGILL, SIGINT, SIGSEGV, SIGTERM. However, "The complete set of signals, their semantics, and their default handling is implementation-defined…"

tef
May 30, 2004

-> some l-system crap ->
So the functions are guaranteed just not their implmentation :c00l:

Mustach
Mar 2, 2003

In this long line, there's been some real strange genes. You've got 'em all, with some extras thrown in.
Don't look a gift horse in the mouth, I guess.

TOO SCSI FOR MY CAT
Oct 12, 2008

this is what happens when you take UI design away from engineers and give it to a bunch of hipster art student "designers"

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.

Stoatbringer
Sep 15, 2004

naw, you love it you little ho-bot :roboluv:

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.

Habnabit
Dec 30, 2007

lift your skinny fists like
antennas in germany.

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. :barf:

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

TOO SCSI FOR MY CAT
Oct 12, 2008

this is what happens when you take UI design away from engineers and give it to a bunch of hipster art student "designers"
Here's another method, from the same application as before:

code:
def __save_cache (self):
	"""Save the cache (for all pending instances in queue) to self.path."""
	# loop through all instances in queue:
	for id in self.__queue:
		# if element with id not exists, remove it and break
		if self.__instances.has_key(id) == False:
			print _("Queue-element <%s> not found (already removed?)!") % id
			self.__queue.remove(id)
			break
		# create list with options
		#print _("CachingBackend: Saving <#%s> :) ...") % id
		lst = []
		for oname in self.__instances[id]:
			lst.append([oname, self.__instances[id][oname]])
		# and save them (if any)
		if len(lst) > 0:
			backup = ''
			try:
				backup = open(self.path + id + '.ini', 'r')
				backup.close()	
			except:pass
			try:
				# In here something strage appends , sometimes it opens the file , then it cant write to it  so it writes and empty file reseting all settings
	
				f = open(self.path + id + '.ini', 'w')
				for el in lst:
					f.write(el[0] + '=' + el[1] + "\n")
				f.close()
				print "OK"
			except:
				if backup != '' and os.path.exists(self.path + id + '.ini'):
					try:
						backup_restore = open(self.path + id + '.ini', 'w')	
						backup_restore.write(backup)	
						backup_restore.close()
					except:pass								
				print _("error while saving config: %s %s") % ( oname , self.path)
	# clear queue
	self.__queue = []
	# NOT continue the timeout-function (!!!!!)
	return False
:smithicide:

Smugdog Millionaire
Sep 14, 2002

8) Blame Icefrog
> The Cavern of COBOL: In here something strage appends >

RoadCrewWorker
Nov 19, 2007

camels aren't so great

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.

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.
That kind of naming scheme along with missing comments is indicative of him letting some sort of obfuscator programm run over the code. Did you actually see him using those name while progamming? If not he might just have been a gigantic rear end in a top hat.

Zombywuf
Mar 29, 2008

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?
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.

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.
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. Then again it uses exceptions to signal generator exits, urgh....

Habnabit
Dec 30, 2007

lift your skinny fists like
antennas in germany.

Janin posted:

Here's another method, from the same application as before:

code:
snip
:smithicide:

I think just about the only half-decent thing about this code is that it uses gettext. :smith:
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.

zootm
Aug 8, 2006

We used to be better friends.

Zombywuf posted:

I wouldn't let exceptions escape signal handlers.
Why not? Anything else would be terribly inconsistent.

Zombywuf posted:

I certainly wouldn't define keyboard interrupt as an exception.
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.

Zombywuf
Mar 29, 2008

Habnabit posted:

However, a C extension or python itself can deal with it.
Deal with what exactly?

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.
I don't think you understand what "not caring if it fails" means. Unless you're implying that I should expect all code to be exception unsafe and need daddy (some function further up the call stack) to clean up after it. If control has returned to the try block the error should no longer be the problem. The whole point of exceptions is that you get notified that an error happened, not that an error is happening.

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.
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)?

TOO SCSI FOR MY CAT
Oct 12, 2008

this is what happens when you take UI design away from engineers and give it to a bunch of hipster art student "designers"

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?

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.

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:
while (mygen.has_more()) { do_stuff(mygen.get_next()); }
mygen.get_next();
e: Also, it's impossible to implement has_more() for a function-based generator.

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

zootm
Aug 8, 2006

We used to be better friends.

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.
The user requested that the program be interrupted, and the program execution was interrupted. That's the correct behaviour in most cases, especially since if it's not handled it will quit the program with an error code like a good citizen. If you are expecting exceptions to mean 'my code went wrong in a recoverable way' rather than 'there was an exceptional circumstance' you've got the semantics wrong. Blanket catching exceptions is a terrible idea for many reasons, and the fact that you catch user interrupts is a very minor one of those.

zootm fucked around with this message at 01:23 on Nov 7, 2008

Habnabit
Dec 30, 2007

lift your skinny fists like
antennas in germany.

Zombywuf posted:

What? Because someone else thought this was the best solution I have to agree?

All hail Hypnoguido, gently caress that.

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

Zombywuf
Mar 29, 2008

Janin posted:

"Out of memory" conditions.
From the docs:

Python docs posted:

exception MemoryError
Raised when an operation runs out of memory but the situation may still be rescued (by deleting some objects). The associated value is a string indicating what kind of (internal) operation ran out of memory. Note that because of the underlying memory management architecture (C's malloc() function), the interpreter may not always be able to completely recover from this situation; it nevertheless raises an exception so that a stack traceback can be printed, in case a run-away program was the cause.

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:

code:
while (mygen.has_more()) { do_stuff(mygen.get_next()); }
mygen.get_next();

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.
No it isn't. Unless you have some crazy ideas about order of evaluation.

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.
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.

tef
May 30, 2004

-> some l-system crap ->
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.

Zombywuf
Mar 29, 2008

tef posted:

:words:

Yeah, C's exception handling and generators work completely differently to Python's.

Habnabit
Dec 30, 2007

lift your skinny fists like
antennas in germany.

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. :v:
Anyway, I'm done here.

TOO SCSI FOR MY CAT
Oct 12, 2008

this is what happens when you take UI design away from engineers and give it to a bunch of hipster art student "designers"

Zombywuf posted:

From the docs:


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.

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:
import random
import sys

def gen_func ():
	while True:
		var = random.randint (0, 2)
		if var == 0:
			sys.exit ()
		yield var
		
gen = gen_func ()
gen.has_next () # How could this **ever** be implemented?

JoeNotCharles
Mar 3, 2005

Yet beyond each tree there are only more trees.

Janin posted:

code:
import random
import sys

def gen_func ():
	while True:
		var = random.randint (0, 2)
		if var == 0:
			sys.exit ()
		yield var
		
gen = gen_func ()
gen.has_next () # How could this **ever** be implemented?

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

Munkeymon
Aug 14, 2003

Motherfucker's got an
armor-piercing crowbar! Rigoddamndicu𝜆ous.



Janin posted:

If it's going to throw an exception anyway, why even use has_next()?

code:
import random
import sys

def gen_func ():
	while True:
		var = random.randint (0, 2)
		if var == 0:
			sys.exit ()
		yield var
		
gen = gen_func ()
gen.has_next () # How could this **ever** be implemented?

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.

TOO SCSI FOR MY CAT
Oct 12, 2008

this is what happens when you take UI design away from engineers and give it to a bunch of hipster art student "designers"

JoeNotCharles 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!

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.

Vulture Culture
Jul 14, 2003

I was never enjoying it. I only eat it for the nutrients.

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....
Scientists do not know Perl

JoeNotCharles
Mar 3, 2005

Yet beyond each tree there are only more trees.

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.

Munkeymon
Aug 14, 2003

Motherfucker's got an
armor-piercing crowbar! Rigoddamndicu𝜆ous.



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.

Plorkyeran
Mar 22, 2007

To Escape The Shackles Of The Old Forums, We Must Reject The Tribal Negativity He Endorsed

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.

Adbot
ADBOT LOVES YOU

TOO SCSI FOR MY CAT
Oct 12, 2008

this is what happens when you take UI design away from engineers and give it to a bunch of hipster art student "designers"

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.

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply