G
Grant Edwards
So lack of a switch state is an attempt to force Python programmers to
write things in an "object oriented" way?
I also took a look at the proposals. I don't think it's the editor
issue. The variant I proposed most recently:
with self.state from Connection.State:
if CONNECTING or CONNECTED:
...
elif DISONNECTING:
...
else:
...
would be handled gracefully by all sane python editors, I believe.
The main problem is that it can't be optimized effectively without
bringing in an element of preprocessing.
A dict dispatch table is just awful. At least have the decency of
creating inner classes.
Mark Lawrence said:
[snip]Your example:
with key from ast:
if Assign:
return ' '.join(dump(t) for t in node.targets)
elif AugAssign:
# Same target and same operator.
return dump(node.target) + dump(node.op) + "="
elif Return:
# A return statement is always compatible with another.
return "(easy)"
elif Expr:
# Calling these never compatible is wrong. Calling them
# always compatible will give lots of false positives.
return "(maybe)"
Which do *you* find more readable?
Marko
Mark H. Harris said:... and between me and you, here is a snip from dmath.py from the atan(x)
function:
if (n**2 < D(1)):
a = __atan__(n)
elif (n == D(1)):
a = gpi/4
elif (n == D(-1)):
a = -(gpi/4)
elif (n < D(-1)):
a = __atan__Lt_neg1__(n)
else:
a = __atan__Gt_1__(n)
This if--elif--else is not only ugly, its just not readable either, and
besides that, its not elegant, nor is it humanly helpful... its does
work though, and its absolutely necessary. ugh.
First, its not immediately clear what it does. Well, there isn't just one
atan(x) routine, there are at least four of them, depending on whether
you're a purist, and they must be selected.
Steven D'Aprano said:You can't have it both ways: you cannot claim that switch or case is
more readable than a chain of if...elif, and then propose a syntax
which is effectively a chain of if...elif while still claiming it is
an improvement. It's not. All you've done is introduce an element of
implicit magic to the syntax.
Why (how?) would you want to use *multiple* classes for a single
switch?
Dict dispatch tables are elegant, attractive and efficient if you are
using pre-existing functions or functions you can create using lambda:
There are all sorts of simple and neat ways to handle switches in
Python. That's why the pressure on the language to grow special syntax
is quite low. It simply isn't important enough.
Ben Finney said:As has been pointed out to you, the whole point here is that string
objects often *are not* distinct, despite conceptually having distinct
cretion in the source.
The main reason to use "is" is to indicate that the object is a sentinel
object whose identity is what is meaningful, not the content. Using ==
would work but would give some poor soul the idea that the state
variable could hold any imaginable string.
The implementation should be able to change the state objects to any
(distinct) objects at all (say, the new enums, or ints, or some more
elaborate class instances) without any changes in the code.
Mark H. Harris said:if (n**2 < D(1)):
a = __atan__(n)
elif (n == D(1)):
a = gpi/4
elif (n == D(-1)):
a = -(gpi/4)
elif (n < D(-1)):
a = __atan__Lt_neg1__(n)
else:
a = __atan__Gt_1__(n)
... and between me and you, here is a snip from dmath.py from the atan(x) function:
if (n**2 < D(1)):
a = __atan__(n)
elif (n == D(1)):
a = gpi/4
elif (n == D(-1)):
a = -(gpi/4)
elif (n < D(-1)):
a = __atan__Lt_neg1__(n)
else:
a = __atan__Gt_1__(n)
This if--elif--else is not only ugly, its just not readable either, and besides that, its not elegant, nor is it humanly helpful... its does work though, and its absolutely necessary. ugh.
First, its not immediately clear what it does. Well, there isn't just one atan(x) routine, there are at least four of them, depending on whether you're a purist, and they must be selected.
Second, because of the strict intent ideology of python in the first place, I can't indent this code to make it more readable without breaking python's syntax.
Third, this is a VERY simple if elif block. More complex ones are much worse... for human reading that is...
I know its a pain in the neck, but python does need a switch statement. Is it a stubborn question? I don't really think that almost every modern computer language has a switch block because of some C paradigm. I think its because most coders find them useful, at least readable, and therefore essential.
You may be right that Python has too many practical problems for a truly
fitting switch syntax.
Well, I was just given a whole link on the very topic:
<URL: http://c2.com/cgi/wiki?SwitchStatementsSmell>
At least have the decency of creating inner classes.
[end quote]
I don't understand this. That's why I asked why and how. I can only
imagine you mean something like this:
class Outer:
class InnerOne:
...
class InnerTwo:
...
class InnerThree:
...
but I don't see how you get from that to the functionality of a dispatch
table, or what you're supposed to do with the nested classes.
That's not a way of implementing switching. That's a way of *avoiding*
switching. Despite the name, it has little to do with state machines.
Anyway, while implementing states as singleton inner class instances is
elegant and highly readable,
That's terribly, terribly inelegant. Why not use the class objects
themselves, instead of instantiating them? Even then, you haven't escaped
the use of a dict dispatch table, or a chain of if...elif. You've just
defined the symbols you use.
the technique suffers in one significant
respect: it can be very slow.
Particularly if you program Java in Python.
Often a state machine has numerous states
but the typical execution path only visits a few of them. However, the
pattern calls for declaring classes (or instances) for all states in the
state machine constructor. Switch statements make it possible to avoid
this creation overhead.
How do you avoid creating the classes or instances? If they haven't been
created, how can the compiler reference them?
I beg to differ. The dict dispatch tables are very hard to read. The
fully blown-out if-else chain beats it in elegance hands down.
Only if you lay out the dict badly. Poorly written code is ugly and hard
to read no matter what you do.
Ben Finney said:Of course. That's the point of describing something as a “code smellâ€:
it may have exceptions where the smell does not indicate an actual
problem, but those are not the normal case where the smell is
encountered. More often, it indicates a problem that should be fixed.
You know full well that this initialization creates references to
distinct objects:
class ABC:
IDLE = "IDLE"
CONNECTING = "CONNECTING"
CONNECTED = "CONNECTED"
DISCONNECTING = "DISCONNECTING"
DISCONNECTED = "DISCONNECTED"
The 5 constants can (and should) be distinguished with the "is"
operator. Using "==" in this case would be slightly misleading.
Steven D'Aprano said:I can only imagine you mean something like this:
class Outer:
class InnerOne:
...
class InnerTwo:
...
class InnerThree:
...
How do you avoid creating the classes or instances? If they haven't
been created, how can the compiler reference them?
I don't understand: you show an if/elif chain that cannot be expressed
as a switch statement (because it uses < ), and then conclude that
Python needs a switch statement? That doesn't make any sense.
I don't understand: you show an if/elif chain that cannot be expressed
as a switch statement (because it uses < ), and then conclude that
Python needs a switch statement? That doesn't make any sense.
Ben Finney said:They are *not* necessarily distinct from other strings with equal
value, defined elsewhere. That's what has been pointed out to you many
times.
So, either you care about these values being distinct from all others
because you want to compare them with ‘is’ (and so strings are a poor
choice);
I beg to differ. The dict dispatch tables are very hard to read. The
fully blown-out if-else chain beats it in elegance hands down.
That point is completely irrelevant. The state objects only need to be
distinct from each other. How do I know? I originally wrote the example.
Strings are as good objects for the purpose as any and have some nice
advantages during troubleshooting and logging.
Marko
Want to reply to this thread or ask your own question?
You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.