Re: proposal: reswitch



On 19 Jan 2006 12:29:20 GMT,
Andreas Leitgeb <avl@xxxxxxxxxxxxxxxxxxxxxxxx> wrote:

> > we can not use [break] as it would break loop behaviour
> > we can not use [continue] as see above.
> 100% agree that break/continue are out of question

I totally disagree that using [break] and [continue] in [switch]s will
break anything, so long as you do it via an option; can anyone
come up with a solid definitive reason exactly WHY [break] and
[continue] can't be applied to [switch], apart from "because that's the
way is was decided ages ago when TCL was young and still trying to
define itself".

Since neither [break] or [continue] take ANY arguments at all (as far
as my documentation says), there's no chance of any kind of clash
anywhere. After all, what was the rationale of making [return] take
options in addition to its return value, the first place? 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
certainly know I've wanted to be able to [break 2], or something along
those lines, in a few TCL scripts (and end up using a variable kludge to
"carry" the break). That's a discussion for another time, for sure,
but the broader concept behind [break] and [continue] is "stopping the
currently executing code to some degree". TCL has already implemented
three such degree's (that I know of offhand); inner-most loop, an
intervening catch, or the procedure boundary (which is an error case).
So refusing to expand the [break] and [continue] functions because
they're small and neat is just wrong.


(Personal note: Yes, I do accept, and already accepted the possibility
of, my [catch] idea being rejected. :) I've been using TCL for a few
years now, since about 1997, though until recently I was stuck with
using an oldish version that was supplied -- now that I'm able to use a
reasonably up-to-date version, I'm taking the opportunity to discuss
some of the things that have been bugging me for most of those years,
when they come up, and I'm taking the opportunity here to express some
things that have been bugging me on a conceptual level, during this
overall discussion.)


> > creating a new command (reswitch|nobreak|more|moreswitch ..)
> > is intrusive and might lead to unpleasant complaints on
> > comp.lang.tcl.
> 0% agree on this, though.

I don't think it's intrusive as such, it's just a quick patch
one-hit-wonder type thing, which I have always felt is evil in any
"core" environment. Look at OS kernels (preferably not Windows ;) ),
even some application software, they're all about re-usability and
connectivity. A one-hit-wonder is only acceptable if it IS the means to
obtain such generalised usage. TCL's tendancy towards "package"
type commands (dict, file, etc.) are a very good example of not
creating one-hit-wonder functions, and a very nice style that IMHO
fits in well with TCL. Also IMHO, a switch-only command is just cruft
in every other context -- admittedly sometimes this is necessary, but
this time it isn't.


The rest of this reply was pulled from the "Nonstandard completion
codes" thread, because I think it fits back here better.

> > If we continue searching, should we restart the search from the
> > beginning (this can cause loops, and can be fudged with a bit of
> > scripting, [...] -- but it's still occasionally handy).
> I personally don't care about a loop-ability of switch.
> If it gets in, I'll probably use it. On the other hand, its
> a "dangerous" tool, that can easily be misused to create
> unmaintainable code (programming BASIC in tcl).

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. One place where I've needed
to wrap a [switch] in a [while], is to implement state machines, for
example. A small, simple tight state machine could very easily be
built using a loop-capable [switch], such as you might use for
processing a character string.

I would love the ability to create a quick tight switch-loop that
processes a few characters of a string at a time, [reswitch]ing with
the currently un-processed portion of the string. I'd also hate to
lose the top-down flow, in SOME cases. Not all, many of them don't
really care. But I've had a few where the top-down flow was very
important. 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.


> > Two options come to my mind for very good solutions; how about
> > extending [break] and [continue] with a "-switch ?string?" option.
> This would be *the* solution, if reserving new exception codes
> was considered a taboo. But reserving a new exception code
> for this task looks&feels better, imho.

The break and control exceptions are general concepts. They apply to
most looping constructs throughout any language, even totally new
ones. The reswitch "exception" kind of breaks that mold, in my mind,
being very restrictive in purpose (with the string thing, the
exception itself is generalised, but the usefulness of that is a
little wishy -- it doesn't automatically do much for the rest of the
language). At least a reloop exception has a new concept attached,
that can be applied back to add functionality right through, being a "go
back to the start of this code block", as opposed to "skip the rest of
this code block, and optionally (depending on the exact exception) try
for another iteration". The only part that would need further
discussion, is whether reloop would run the increment part of a [for].


> > So [continue] and [break] would never reach a "default" block.
> There are surely pros and cons for reaching the "default" block.

I tried very hard to ignore getting in that. ;) Though my gut feeling
is that "default" should be a "if nothing else matched" type thing.
Other cases can be implemented with little work, but the "if nothing
else matched" is a harder one to implement on your own.


> I don't have any strong feelings for or against.
> Btw. there can be two "default" blocks, the sequentially first
> of whose will just match a literal "default" value :-)

I'd hope that only the last "default" block would be the default one.
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]. ie. taken right out of the body so it couldn't be
confused. (In C, for example, the "default" case is a very distinct
clause in its own right) Though I understand why they didn't do that;
it'd look rather ugly for starters. :)


> > Along those same lines, I've often wanted to be able to "reloop
> > without retest" (both in [for] and [while]), and have had to do
> > some mildly ugly hacks to get that functionality. We could consume
> > return code 5 for that purpose, and use that code to carry the
> > [reswitch] functionality (yes, I'm un-repenting in my statement
> > that anyone who used return code five deserves what they get ;) ).
> > A kind of "reloop" command.
> hmm, "reloop" doesn't "look" like it would do anything with switch.
> perhaps "redo"? This would sound like "reswitch" in switch and
> "continue without incr/test" in loops)

[redo] works for me... My main pet hate in this discussion, is the
introduction of a switch-only command and/or exception. It feels to me
like a patch or hack tacked on the end, where concepts already exist to
perform the same job.

But then that's me... I don't like too many one-hit-wonders (like a
[reswitch] or [continue_at]) in a programming language (mind you,
[continue_at] might be nice to have also... But the idea of "now try
to match this" is to my mind far more "TCLish" than a "goto", which is
essentially what [continue_at] is all about). I also hate exceptions to
rules. I'd much rather make the most of what's already there. If
you're going to add the ability to break execution of a switch code
block and either stop or continue elsewhere, then to my thinking you
should call it break or continue. [continue_at] is the only one that
codes close, but as I said, it sounds far too "goto"ish for me.
(The only good use I've seen for "goto", is adding a cleanup block
that can be goto'd as soon as we realise things have gone sour.)

A -switch option to [break] and [continue] (and [redo] or [reloop])
allows the concept of those functions to persist in the context of a
[switch]; we can "break" a switch _unless_ there's a matching code
block further down, or we can "continue" a switch onto the next code
block or the next matching code block -- it also allows the user the
freedom to pick whether they want to include the default case or not
(although there is a slight corner case, in that a bare [continue
-switch] wouldn't run the default case, where a [continue -switch
string] would, however it's by no means the only one, and well worth
the extra sentence or two in the documentation). This method, however
also keeps the top-down (non-loop) nature of a [switch], unless you
explicitly want it (via [redo]).


I'm hoping this issue won't be solved on the basis of "oh, it's just
too hard to fit that stuff into my new idea for optimisation".
Optimisation is good, but I think it should never be a driving factor
in a high-level non-compiled language, that's what low-level and
compiled languages are for. Develop the language, THEN optimise. Not
the other way around. If the optimisation doesn't work out, maybe
you'll come up with a better method next version.

Besides which, even if the hash switch optimisation only works on the
initial step, and degenerates from there back to the usual switch style
sequential search, it would probably be fine. MOST cases will still
enjoy the optimisation at its best. I'm not sure how the byte-code
compiler in TCL works, but should it not be possible to decide late
which method to use to represent it? If there's no [reswitch]ish
behaviour, then use the hash method. If there is, fall back to the
usual. It may also be possible to add a -fast option to [switch],
telling it that you don't care about the test order, or alternatively
add a -strict option that states that you do (depending on the current
consensus of what the existing official documentation says).


Fredderic
.



Relevant Pages

  • Re: proposal: reswitch
    ... Again, I agree with you on the point, that break/continue ... As long as they are limited to loops, ... >> I personally don't care about a loop-ability of switch. ... > too hard to fit that stuff into my new idea for optimisation". ...
    (comp.lang.tcl)
  • Re: test if a string is a valid number?
    ... Generally, you watch for the use of switch to decode and realize that in most cases, ... virtual methods and subclasses are a better solution. ... you use virtual methods, you only have to change the definition site. ... exception type so I could issue a meaningful error message. ...
    (microsoft.public.vc.mfc)
  • Re: Hundreds of cases in a switch, optimization?
    ... > In terms of generated machine code, how does hundreds of cases in a switch ... Do compilers or processors do any ... extern int f; ... compiled both with and without optimisation. ...
    (comp.lang.c)
  • malloc() causes an Access Violation when compiling with the /MT switch
    ... Multithreaded Debug CRT) but as soon as I change it to the /MT switch ... causes an Access Violation exception ... The first few calls to mallocare allocating very small memory blocks, ...
    (microsoft.public.dotnet.languages.vc)
  • malloc() causes an Access Violation when compiling with the /MT switch
    ... Multithreaded Debug CRT) but as soon as I change it to the /MT switch ... causes an Access Violation exception ... The first few calls to mallocare allocating very small memory blocks, ...
    (microsoft.public.vc.language)