|
In Which a Perfectly Sensible Interface for Co-Inductive Types Is Foolishly Extended to Inductive Types
|
# ? Jan 18, 2014 08:54 |
|
|
# ? Apr 27, 2024 07:30 |
|
Jewel posted:So you're saying the item after the current item is nothing? So why not return None? What if you're iterating over a list with None in it?
|
# ? Jan 18, 2014 09:01 |
|
return StopIteration instead
|
# ? Jan 18, 2014 09:27 |
|
Dren posted:
Yes, that's exactly what I said in my post. I said that the user doesn't need to invoke it by hand, which is true; it's taken care of behind the scenes. And this is fine. Invoking get() and catching StopIteration by hand would be stupid (because there's already a very nice control flow mechanism that does this for you) QuarkJets fucked around with this message at 12:21 on Jan 18, 2014 |
# ? Jan 18, 2014 12:18 |
|
M31 posted:return StopIteration instead What if you're iterating over a list with StopIteration in it? I don't think there's anything you can return from a function that you can't also put in a list so I don't see how this pattern is going to work.
|
# ? Jan 18, 2014 12:57 |
|
Nippashish posted:What if you're iterating over a list with StopIteration in it? I don't think there's anything you can return from a function that you can't also put in a list so I don't see how this pattern is going to work. Return two values, one fo which is false when you finish iterating, or rather than having a .next() method, have a .get() method for the current entry, .next() returns no value, or returns whether there is a next, and a .finished() method which says whether there is a next value in the iterator.
|
# ? Jan 18, 2014 13:53 |
|
Nippashish posted:What if you're iterating over a list with StopIteration in it? I don't think there's anything you can return from a function that you can't also put in a list so I don't see how this pattern is going to work. Option types work just fine - either you return Nothing, or you return Just <value>, and it's fine. If you're storing an option type in the list, who cares, you're just going to return either Nothing, or Just <option type> - i.e. Nothing (finished iteration), Just Nothing (a Nothing contained in the list), or Just Just <something>. Of course if you're using a language with option types you probably have a better mechanism than iteration to express what you're trying to do, so in practice this doesn't come into play too much.
|
# ? Jan 18, 2014 14:31 |
Jabor posted:Option types work just fine You know I think a simple way Python could have done it would be to have None represent end of iteration, and a single-element tuple represent a value in the iteration. Tadaa, option type defined, the world is saved.
|
|
# ? Jan 18, 2014 15:09 |
|
HORATIO HORNBLOWER posted:Exceptions are great, quit being afraid of them and quit pretending anyone gives half a poo poo that they're "expensive." This isn't 1995 and unless you're doing real-time work it literally does not matter at all. *throws exceptions in inner loop* "Why is our web server cluster CPU bottlenecked?" Yeah, this is a thing I've had to fix before. The code in question was filling in an option list for a drop down. IIRC the number of exceptions per second was in the 100,000s.
|
# ? Jan 18, 2014 15:10 |
|
My opinion on exceptions straight outta YOSPOS:MononcQc posted:What if you have different classes of exception handling mechanisms available for each of these cases? What about languages that may support exceptions, option types, tagged values, multiple return values, signals, continuations and/or whatever mix of them that exists?
|
# ? Jan 18, 2014 16:43 |
|
nielsm posted:You know I think a simple way Python could have done it would be to have None represent end of iteration, and a single-element tuple represent a value in the iteration. Tadaa, option type defined, the world is saved. That adds a dereference and an if statement to every iteration, plus a bunch of boilerplate. Exceptions are cheap in Python, especially when caught right away. Maybe they suck in other languages, maybe Haskell has some feature that gets around the need for it, but in python exceptions are a pretty acceptable, and let you write cleaner, clearer interfaces.
|
# ? Jan 18, 2014 17:25 |
|
Could the 'inappropriate' use of exceptions as control flow be just a symptom of the typically horrible support languages have for explicit multiple return values? You only really have the following options in most languages:
These are all just boilerplate and non-explicit ways to really mean you want multiple return values. comedyblissoption fucked around with this message at 19:08 on Jan 18, 2014 |
# ? Jan 18, 2014 18:50 |
|
What do you mean by "Create a struct/class/tuple just for your particular case."? Like, in Python you can just return (True, 8) or (False, "you hosed up"). Or is your argument that every function should do this?
|
# ? Jan 18, 2014 19:32 |
|
Tuples in python are good and are what I mean by decent multiple return values. Tuples in C# and other statically typed languages have a bit awkward syntax. It's okay-ish I guess besides the syntax. code:
In static languages where you can't have templated tuples, you'd create a class/struct just for returning the tuple you want. This is just a lot of boilerplate.
|
# ? Jan 18, 2014 19:47 |
|
Opinion Haver posted:Like, in Python you can just return (True, 8) or (False, "you hosed up"). Or is your argument that every function should do this? There are lots of reasons a function might fail though, and the calling code might need to do different things depending on what happened, so instead of just True or False you probably want to return an object that describes the failure somehow. Of course, whomever writing the calling code probably has a few code paths for the vast majority of failures, and a couple code paths that are appropriate only certain failures, so it'd probably be nice if you used a class hierarchy so the calling code could write handlers with varying levels of specificity. And of course, since your function has multiple return points and it might be hard to tell from the error type exactly what was wrong, that object should maybe include a message with more details and a record of which return point was used. Finally, if that calling function just can't continue, it should probably go ahead and return right there as well, and pass along details of its failure whatever called it. That seems like a totally reasonable alternative to exceptions, which are really scary.
|
# ? Jan 18, 2014 20:08 |
|
evensevenone posted:There are lots of reasons a function might fail though, and the calling code might need to do different things depending on what happened, so instead of just True or False you probably want to return an object that describes the failure somehow. If something went wrong, throw an exception. If you hit the end of the list, return (False, None). It's not that such a mechanism should replace all exceptions (unless you're coding in Go), it's that it would replace many 'bad' uses of exceptions.
|
# ? Jan 18, 2014 20:16 |
|
While we're on this exceptions kick, here's some code from a project we inherited from another company:C# code:
|
# ? Jan 18, 2014 20:22 |
|
Bognar posted:While we're on this exceptions kick, here's some code from a project we inherited from another company: Here's my entry into exception week. I've posted this before, but it bears repeating: code:
|
# ? Jan 18, 2014 20:28 |
|
If we're resubmitting...C++ code:
|
# ? Jan 18, 2014 20:35 |
|
This is the worst exception-related horror I've ever seen: doing typechecking with try/catch.Java code:
|
# ? Jan 18, 2014 20:46 |
|
Ithaqua posted:Here's my entry into exception week. I've posted this before, but it bears repeating: Wow, that is... extra special . Not only does it check exception type instead of catching specific exceptions, it re-throws the exception so you lose the stack trace. Wonderful.
|
# ? Jan 18, 2014 20:50 |
|
Suspicious Dish posted:This is the worst exception-related horror I've ever seen: doing typechecking with try/catch. Yes, this sounds about right for what I've seen of Verizon. My favorite is: Java code:
How many issues can you spot? Fun fact: File.delete (edit: in Android) never throws an exception, I double checked. Volmarias fucked around with this message at 22:46 on Jan 18, 2014 |
# ? Jan 18, 2014 21:31 |
|
Volmarias posted:Fun fact: File.delete never throws an exception, I double checked. Uh, yes it does. Specifically it can throw all the ones mentioned here, depending on your program settings. That is bad code, though.
|
# ? Jan 18, 2014 21:38 |
|
Volmarias posted:Yes, this sounds about right for what I've seen of Verizon. Yep. Java code:
|
# ? Jan 18, 2014 21:53 |
|
Suspicious Dish posted:This was from a Verizon internal project. After having worked in telecom for a few years now, I'm surprised it's even possible to make phone calls.
|
# ? Jan 18, 2014 21:59 |
|
Tesseraction posted:Uh, yes it does. Specifically it can throw all the ones mentioned here, depending on your program settings. Sorry, I left out relevant info. This is for Android, so in this case it doesn't.
|
# ? Jan 18, 2014 22:46 |
|
Ahhh, Android. Never used the Android API so my bad!
|
# ? Jan 18, 2014 23:08 |
You guys are so lucky, you actually have things in your exception blocks
|
|
# ? Jan 18, 2014 23:23 |
|
comedyblissoption posted:Tuples in python are good and are what I mean by decent multiple return values. Please don't confuse statically typed with having bad syntax. code:
|
# ? Jan 19, 2014 02:23 |
|
Every time someone assumes that all statically typed languages have lovely syntax because they've only looked at C# and Java, Simon Peyton Jones sheds a single tear.
|
# ? Jan 19, 2014 03:32 |
|
Regarding StopIteration: as demonstrated, the efficiency of an if: else: versus a try: except: depends on the expected rate of occurrence of exceptions. For even not-very-large sequences it becomes more attractive to use exceptions rather than an explicit conditional every iteration. Yes, I think it's a little weird too, but I can also understand the pragmatic compromise, especially considering most python programmers will never use it unless they write their own generators. If you want a bullshit handwavy feel-good justification, I'd note that one of the best features of the python iteration protocol is that it transparently accommodates unbounded sequences, endless data streams coming in over the network or continuous sensor measurements. If you start from the premise that whenever you start iterating, it could potentially be unbounded until shown otherwise, then not having another element is an "exceptional" circumstance.
|
# ? Jan 19, 2014 17:35 |
|
BigRedDot posted:Regarding StopIteration: as demonstrated, the efficiency of an if: else: versus a try: except: depends on the expected rate of occurrence of exceptions. For even not-very-large sequences it becomes more attractive to use exceptions rather than an explicit conditional every iteration. Python code:
code:
|
# ? Jan 19, 2014 19:10 |
|
Basically my reasoning is that Guido von Rossum is smarter than me so if he chose for something to happen one way it's probably for a good reason.
|
# ? Jan 19, 2014 21:14 |
|
Tesseraction posted:Basically my reasoning is that Guido von Rossum is smarter than me so if he chose for something to happen one way it's probably for a good reason. He isn't infallible. What we'd really like is an as-efficient sentinel value that tells the interpreter to jump to a special handler, but doesn't unwind the stack all the way, but we don't have that.
|
# ? Jan 19, 2014 21:35 |
|
I admit I've not looked into it but doesn't D do that? Also I know Guido isn't infallible, but I'm firmly of the belief that if someone is smarter than you then you can at least trust them to make relatively sensible decisions in the field they're smarter than you in. Now if Guido disagreed with me about lovely anime plotlines then I'd be more than happy to argue with him. Tesseraction fucked around with this message at 22:01 on Jan 19, 2014 |
# ? Jan 19, 2014 21:58 |
|
Doesn't it only unwind until it gets to an except: clause that handles it, which is probably only going to be a frame in most of the cases presented and thus not really any different than the frame returning? I'm guessing that the cost is in instantiating the exception object.
|
# ? Jan 19, 2014 22:29 |
|
SurgicalOntologist posted:I forgot to mention that when a new key is encountered, I reassign all the other keys as well. Funny enough, I just did exactly this and approached it differently. New sensors are append-only, and removal is a human-initiated operation. Removal is 'shift everyone below the item to be removed up a slot' so the relative order is a constant. I couldn't imagine it being useful to go around replacing batteries and have all your sensors end up in a new and random order. Maybe I don't understand what you're doing, but resorting the keys whenever you see a new one doesn't sound right. Edit: Found your more detailed description. What do you do if someone leaves a controller on within radio range that's a lower ID then the ones your subjects have? Playing "Hang on for 30 minutes while we go hunt down a stray controller" doesn't seem like a great plan. For your specific case, something along the lines of putting every sensor you've seen into a 'available' list, then start by requesting user 1 press a button. Go over the available list, then take whichever one has a button pressed and assign it to user 1. Repeat for user 2, etc. Your staff could even do it as they hand the controllers out, grab one from the pile, hit the button, hand to user 1, etc. Harik fucked around with this message at 07:55 on Jan 20, 2014 |
# ? Jan 20, 2014 07:33 |
|
Plorkyeran posted:So yeah, on anything but very short lists throwing an exception is cheaper than boxing the values. These things aren't orthogonal. The Python implementors have made a (defensible) implementation choice to make exceptions relatively more efficient. (More accurately, they have declined to spend time making the non-exceptions path more efficient at the disproportionate expense of the exceptions path.) They have also chosen to make tuples relatively expensive because they don't fit into their immediate representation. Of course, had they chosen to use tuples as the intermediate iteration result, they would have made certain that that kind of tuple was efficiently representable, at least along the critical paths, and the need for efficient exceptions would have diminished. Meh. It's fair to say that the performance argument against exceptions is at least partly a constructed thing. Most languages/environments could provide faster exceptions that they do; for example, I could probably name half a dozen ways in which we could optimize libUnwind and thus make Unix C++ exceptions faster. But there are limits, and the feature (as seen in most of its use cases) is essentially begging for a biased implementation that exaggerate those limits. That makes it easy to just consistently advise against triggering exceptions in hot loops, which (modulo API impacts causing representational threshold effects, like you're showing) should pretty much be unconditionally valid.
|
# ? Jan 20, 2014 08:15 |
|
That is a good point. I don't think you could pull off zero-cost (or even nearly zero) Maybe in anything even vaguely resembling CPython, though, so there'd always be an attainable break-even point, and even if it was at something like 10,000 elements I suspect that for the use cases where the decision actually matters the fixed overhead would win out over small overhead per loop iteration.
|
# ? Jan 20, 2014 14:51 |
|
|
# ? Apr 27, 2024 07:30 |
|
Harik posted:Funny enough, I just did exactly this and approached it differently. New sensors are append-only, and removal is a human-initiated operation. Removal is 'shift everyone below the item to be removed up a slot' so the relative order is a constant. Not sure if that's what you meant, but our sensors don't have buttons. If the batteries all get replaced the sensors end up in the same order, since they're sorted by physical device number. The closest solution to what you propose would be to have the experimenter type the device numbers of the sensors in use, in whatever order they choose. I can't say it's an obvious choice either way but I went for convenience over the chance of a missing sensor screwing things up. Anyways, battery life is bad enough that if someone doesn't put the sensor back on the rack to charge they've already screwed up.
|
# ? Jan 20, 2014 15:35 |