Re: proposal: reswitch



On 25 Jan 2006 13:55:48 GMT,
Andreas Leitgeb <avl@xxxxxxxxxxxxxxxxxxxxxxxx> wrote:
> Fredderic <put_my_name_here@xxxxxxxxxxxxxxx> wrote:
> > Andreas Leitgeb <avl@xxxxxxxxxxxxxxxxxxxxxxxx> wrote:

> > I totally disagree that using [break] and [continue] in [switch]s
> > will break anything, so long as you do it via an option
> Again, I agree with you on the point, that break/continue
> *with* arguments/options are at least feasible to re-use.
> (The "out of question" was minted on break/continue as
> argument-less commands, and I still stick to that)

*nods* No arguments there.


> > Since [break] and [continue] are little more than convenience
> > functions these days, this opens the possibility to at a latter
> > date introduce the "return -levels" concept to loop levels within
> > a procedure (which I've used, and have seen used, very successfully
> > in some other languages). I
> Yes, I've also dreamt about such a feature in tcl (namely
> breaking out of several loop-structures at once), and that's
> exactly the reason, why I'm not too happy with break/continue
> used with arguments for switch, because this really might
> raise some confusion, as to which arguments will leave
> which (and how many) levels of loops and/or switches and/or
> other constructs before they're really handled.

The [socket] command, and I think some others I can't think of
off-hand, have more than one use-case;

socket ?-myaddr addr? ?-myport myport? ?-async?
socket -server command ?-myaddr addr? port

The [socket -server] form doesn't have either the -myport (port number
is mandatory) or -async (implicit in the definition of a listening
socket) options.

In this case, break and continue would be defined something along the
lines of;

break ?loops?
break -switch ?string?

It's clear, then, that the two forms are mutually exclusive. The
[break -switch] form affects the immediately enclosing [switch] only.

These two forms could be merged at a latter date, but for now I think
that having the [break] and [continue] commands extended as I
suggested, covers all the functionality that anyone would want, except
for being able to match backwards (or from the top again, which is a
case that SHOULD be dealt with separately, and maybe even generally
shunned).

You've got the quick-exit (break, no string), the fall-through to next
block (continue, no string), the find next match but don't do default
(break, with string), and the find next match or default (continue,
with string).


> As long as they are limited to loops, it's somewhat easier
> to recognize every loop that encloses the break. If some
> argument makes it work on (e.g. for a start) switches, I'd have
> no idea, which other constructs would be counted and which not:
> while {...} {
> switch {...} { ... {
> foreach ... {
> if {...} {
> break -someoptions -level 2

Well, in my original idea, [break 1] would stop the [foreach]. [break
2] would stop the [while]. It'd still only be counting "looping"
constructs.

The [break -switch] form would go direct to the nearest [switch]. If
[break -switch] still allows the loops argument (specified before the
-switch option), then it'd be the nth switch. But in either case, it'd
carry with it an optional (unspecified is not the same as blank/empty)
string to re-switch on.

You COULD, I suppose, implement a [break -blocks n] variant that would
count everything including [if]s and [switch]s. But that's just
getting scary. Besides, [catch will already let you do that (though
presently re-throwing the caught exception is a pain in the arse).
Better still, would be a [try ... catch ...] type structure that will
automatically re-throw anything it's not interested in. Furthermore,
[continue] doesn't make any sense at all with other non-loop
constructs. So if [break] did support breaking to a non-loop level,
it'd still need to be an option.

A better idea than a [break] that'll reach non-loops, would be the
ability to name a block. You could synthesise such a feature in TCL
quite easily, I suspect, using a new exception number. Something
vaguely resembling this:

proc do {name script} {
set code [catch [list uplevel 1 $script] resp]
if { $code != 10 || $resp != $name } {
# rethrow everything... use that new catch feature too!
}
}

proc break-do {name} {
return -code 10 $name
}


> I've been Tcl'ing since about 1995 (iirc, that was with tcl7.4b4)
> And since the earliest days I'd been asking for a feature, which
> is now finally in 8.5: the {expand}-feature :-) (although it's
> very different from my original proposals, it's only (but still)
> slightly different from my own latest proposal in that direction)

I find the {expand} notation rather odd. I suppose it's hard to find
something that is clearly not to be taken as part of the argument, and
an essentially illegal list construct, coming at the very head of an
argument, is as good as any. I still find it looks odd. But as long
as it works. :)

Wonder if there are any others planned... {filter script}, perhaps? ;)


> While I understand, that the core should not clutter
> the global namespace too much, I can freely do it in
> my own code :-)

Well of course...! One CAD package I was using which used TCL as its
scripting mechanism, didn't understand namespaces. So I wrote a script
that renamed all the commands it offered which dealt with callbacks,
then created wrappers in-place that were namespace-aware. You could
even take my [do] idea just above, and make [if] take an optional
name. ;)


> > Also IMHO, a switch-only command is just cruft
> > in every other context -- admittedly sometimes
> > this is necessary, but this time it isn't.
> Hmm, you're probably right that "reswitch" really isn't it.
> As you say it's much to switch-specific.
> But break/continue also have their problems.

EVERY option has its problems. No matter how creating you are, SOMEONE
will pick on it for SOMETHING. Even more so when you're tampering with
something that everyone knows and loves. Like [break] and [continue].
But that doesn't mean it's still not the best way to do it.

How else are you going to introduce functionality that makes sense only
to [switch], without introducing a new command that only works from
within [switch], and is useless cruft everywhere else? You take the
functionality onto some other command(s) that already serve a similar
purpose. And to get all the functionality of my break/continue pair,
you'd need to still provide options in your new command, which would
make it even more complicated than either of those.


> Something like "redo" could be a name general
> enough, but would be a new exception, still.

I'd prefer [reloop], just to stress the looping nature of it.
Especially in the context of a [switch] (which would use a -switch
option exactly like [break] and [continue]). Like I also said, the
[reloop] concept of a un-conditional-continue kind of fits in to
complete the trio with the other two. I think, personally, that WOULD
be worth an extra exception.


> > > I personally don't care about a loop-ability of switch.
> > I agree... Which is why I thought the use of a [reloop] type
> > function was appropriate, because it streses the fact that contrary
> > to the other two, this one CAN cause loops. [switch] to my mind,
> > isn't a looping construct. However it is none the less a block
> > construct, and so the possibility to loop is worth considering.
> "if" is also a block-construct, isn't it ?-)

Which is a scary thought that I had, but didn't want to bring up.
Although, being able to jump directly to the else block, or have a
second else that gets executed any time the normal one ISN'T..... ;)
(insert evil laugh here)


> > One place where I've needed to wrap a [switch] in a [while], is to
> > implement state machines, for example.
> Yes, that would be Use#1 for me, too (currently I wrap switch in a
> loop for this type of use, and I think that the keepers of tcl spirit
> would rather not change that).

True enough. But if [reloop] is ever implemented, and if it was given
a -switch capability, I'd certainly make the most of it in a couple
places.


> > The documentation I have reads: " The switch command matches
> > its string argument against each of the pattern arguments in
> > order. " I'd be concerned that hash-based optimisation might remove
> > this constraint.
> Even if it does so, it would do so only for -exact matching.
> and in that case, it doesn't make a visible difference other
> than speed.

Yes, it does, in the presence of a re-switch concept. Read my other
reply further down this thread.


> > The only part that would need further discussion, is whether reloop
> > would run the increment part of a [for].
> Imo, it should most certainly *not* run it.
> The incr-part generally advances some index or iterator, and
> the loop-condition is supposed to check, if we're out of
> iterable things. While it is surely conceivable to have
> a situation where the incr-part needs to be run more than
> once before checking the condition, I think this would be
> a bad thing for almost (but not quite entirely) all loops.

I quite agree, personally. Just thought I'd ask. :)


> > Personally, considering the stringyness of TCL, I think they should
> > have broken with tradition and added an "else" clause to the
> > [switch], similar to the [if].
> I guess you're right, but then perhaps not:
> the patterns and bodies can be separate arguments,
> so you might end up with:
> switch 42 12 {} 13 {} default {puts buh}
> where the other way would be:
> switch 42 12 {} 13 {} else {puts buh}
> Not much of a gain :-)

I actually wasn't aware of that... I've always grouped all the
patterns and bodies in {}'s... It never occurred to me that you could
put them in a line like that. Which is odd, because I've accidentally
done just that while testing an idea in tclsh. :)

I was thinking more of the long form...

switch 42 {
12 {}
13 {}
} else {
...
}

That CLEARLY separates the default clause from the others. Though as
you say, there's no great gain in the single-line form. So it's
certainly not worth enough to change it now.


Fredderic
.



Relevant Pages

  • Re: String-based Switch Request...
    ... Facilitate good callback programming design and modularization within GUI code ... When ever switch statements are used, they are typically over used being favour over polymorphism, which leads to brittle shoddy design. ... Use the string type-code as the Key and a Command or Strategy Object as the Value. ...
    (comp.lang.java.programmer)
  • Re: Question about timeit
    ... so it doesn't need to parse the string into a float. ... 1000000 loops, best of 3: 1.97 usec per loop ... Use double-quotes around the command itself - may not be necessary ...
    (comp.lang.python)
  • Re: newgie string help please
    ... > hi iam righting aprogram that creates its own desktop shotcut and a ... > want to add a command line switch ... > my problem is how do i get the single " quote mark into my string ...
    (microsoft.public.dotnet.languages.csharp)
  • Re: Strings to only find letters
    ... Using one command with no loops, find the indices of all the ... characters in a string that are letters (not punctuation or ...
    (comp.soft-sys.matlab)
  • Re: problem with sscanf in email client
    ... switch (command ... If I do this...Does that mean I have to use sscanf all way along for ... got the string already in which I need. ...
    (comp.lang.c)