|
From: Tim H. <tim...@un...> - 2008-04-07 22:13:31
|
Hello,
because of a recent discussion on comp.graphics.apps.gnuplot I realized
that the parsing of if ... else ... is somewhat "unusual". If the
condition fails, gnuplot will jump to the next else (as documented). I
don't consider this to be a good solution, because this causes troubles
in nested if else statements.
A short summary on the possible nestings (more detailed in the newsgroup):
1) if if - OK
2) if else if else - OK
3) if if else else - syntax error if the first condition fails (2nd else)
4) if if else - syntactically correct; depending on the condition else
belongs to the first or second if!
Looking at the code, I think it should be easy to switch from this
evaluation to a stack-like interpretation which allows above nestings
and is furthermore the "natural" way of blocking in programming
languages. It involves only counting if else pairs and resuming
execution at the right level instead of simply the next else. I will
have a try with this in some days.
The only thing left for a perfect if would then be some blocking to make
if (if ...) else possible. But I leave this for the moment, firstly
because it appears to be more involved to insert additional tokens () or
maybe {}, and secondly because you can archive the same logic by if else
if ... and negating the first condition.
Comments are welcome.
Regards,
Tim
|
|
From: Ethan A M. <merritt@u.washington.edu> - 2008-04-08 06:14:39
|
On Monday 07 April 2008 15:13, Tim Hoffmann wrote:
> Hello,
>
> because of a recent discussion on comp.graphics.apps.gnuplot I realized
> that the parsing of if ... else ... is somewhat "unusual". If the
> condition fails, gnuplot will jump to the next else (as documented). I
> don't consider this to be a good solution, because this causes troubles
> in nested if else statements.
I think the biggest problem with gnuplot's if/else implementation is
that it is limited to a single line. The following simple construct,
if it were possible, would make the whole thing a lot more usable:
if (test) load 'option1'; else load 'option2';
The files 'option1' and 'option2' could hold arbitrarily complex
code, partially making up for the lack of block structure.
But this doesn't work, because the command 'load' destroys the rest of
the line. Since an 'else' clase must be on the same line, but the
line is lost, you can have no 'else' clause after a 'load' command.
So I suggest that the first step should be extending the syntax to
allow multi-line constructs. Here is one possibility:
if (test) begin
...
...
else begin
...
...
endif
The 'begin' and 'endif' are not needed if the command remains on a single
line, so backwards compatibility is maintained.
> A short summary on the possible nestings (more detailed in the newsgroup):
> 1) if if - OK
> 2) if else if else - OK
> 3) if if else else - syntax error if the first condition fails (2nd else)
> 4) if if else - syntactically correct; depending on the condition else
> belongs to the first or second if!
>
> Looking at the code, I think it should be easy to switch from this
> evaluation to a stack-like interpretation which allows above nestings
> and is furthermore the "natural" way of blocking in programming
> languages. It involves only counting if else pairs and resuming
> execution at the right level instead of simply the next else. I will
> have a try with this in some days.
>
> The only thing left for a perfect if would then be some blocking to make
> if (if ...) else possible. But I leave this for the moment, firstly
> because it appears to be more involved to insert additional tokens () or
> maybe {}, and secondly because you can archive the same logic by if else
> if ... and negating the first condition.
I think the blocking has to come first, because without multi-line support
the syntax is crippled.
Alternatively one could fix 'load' so that it doesn't eat the rest of the
line. But I think that would be just as much work, for less gain.
> Comments are welcome.
>
> Regards,
> Tim
--
Ethan A Merritt
|
|
From: Ethan A M. <merritt@u.washington.edu> - 2008-04-08 06:37:05
|
On Monday 07 April 2008 23:14, Ethan A Merritt wrote:
>
> I think the biggest problem with gnuplot's if/else implementation is
> that it is limited to a single line. The following simple construct,
> if it were possible, would make the whole thing a lot more usable:
> if (test) load 'option1'; else load 'option2';
Sorry, I tried to construct a minimal example but that one is too minimal.
As written, it actually does work. The file 'yes' and 'no' contain the
corresponding print statement:
gnuplot> if (1) load 'yes'; else load 'no'
^
warning: ignoring rest of line
Yes
gnuplot> if (0) load 'yes'; else load 'no'
no
But this one fails:
if (test) load 'option1'; print 'A'; \
else load 'option2'; print 'B';
--
Ethan A Merritt
|
|
From: Juergen W. <wie...@fr...> - 2008-04-08 08:47:25
|
Am Dienstag, 8. April 2008 schrieb Ethan A Merritt: > On Monday 07 April 2008 15:13, Tim Hoffmann wrote: > > Hello, > > > > because of a recent discussion on comp.graphics.apps.gnuplot I realized > > that the parsing of if ... else ... is somewhat "unusual". If the > > condition fails, gnuplot will jump to the next else (as documented). I > > don't consider this to be a good solution, because this causes troubles > > in nested if else statements. > > I think the biggest problem with gnuplot's if/else implementation is > that it is limited to a single line. The following simple construct, > if it were possible, would make the whole thing a lot more usable: > if (test) load 'option1'; else load 'option2'; > The files 'option1' and 'option2' could hold arbitrarily complex > code, partially making up for the lack of block structure. > But this doesn't work, because the command 'load' destroys the rest of > the line. Since an 'else' clase must be on the same line, but the > line is lost, you can have no 'else' clause after a 'load' command. > > So I suggest that the first step should be extending the syntax to > allow multi-line constructs. Here is one possibility: > > if (test) begin > ... > ... > else begin > ... > ... > endif > > > The 'begin' and 'endif' are not needed if the command remains on a single > line, so backwards compatibility is maintained. Sounds good. One line nested ifs should then be depricated. As soon as there are blocks, can in-file loops also be implemented? Juergen |
|
From: Ethan M. <merritt@u.washington.edu> - 2008-04-08 16:19:02
|
On Tuesday 08 April 2008 03:33, Tim Hoffmann wrote: > > > Alternatively one could fix 'load' so that it doesn't eat the rest of the > > line. But I think that would be just as much work, for less gain. > Eating the rest of the line feels wrong. But you know the code and the > reasons better than me. Maybe I understand the code better now than the last time I looked at this. It now seems to me that it is pretty easy to make the 'load' command non-destructive. See patch #1937938 on SourceForge. https://sourceforge.net/tracker/index.php?func=detail&aid=1937938&group_id=2055&atid=302055 -- Ethan A Merritt |
|
From: Tim H. <tim...@un...> - 2008-04-08 17:00:06
|
sorry, this mail went accidentally only to Ethan instead of the whole
list in the first time.
Ethan A Merritt wrote:
> On Monday 07 April 2008 15:13, Tim Hoffmann wrote:
>> 3) if if else else - syntax error if the first condition fails (2nd
else)
>> 4) if if else - syntactically correct; depending on the condition
else belongs to the first or second if!
>>
> I think the blocking has to come first, because without multi-line
support
> the syntax is crippled.
I'm not really familiar with the code. Maybe a hack for if blocking
would be possible without too much effort, but then again new problems
would araise if one ever wants to have real loops, because the command
parsing is linear. When talking about blocking, IMHO a decision has to
be made if control structures (if, while, for) should become an
elementary part of gnuplot. If so, one should really think about the way
of parsing. If not, I consider the following to be sufficient.
Blocking is desirable, but it's more than I proposed. I was just
thinking of a fix for nesting types 3) and 4) which I could manage in a
short time. For a real blocking I would have to have a deeper look in
the source code. I don't have the time for this now (maybe in two months).
My proposal would make the following possible (commands can also be more
than one):
if (test) \
command1; \
if (test2) \
command2; \
else \
command3; \
command4; \
else \
command5;
There are only two disadvantages compared to blocking:
1) The continuation char. Do you mean this by crippled? Can there be
problems because of limitations in length?
2) you can't leave out the first else. If you do, you'll end up like that:
if (test) \
command1; \
if (test2) \
command2; \
command4; \
else \
command5;
For really long commands, one could refer to your proposed solution with
load. It should be mentioned in the documentation.
> Alternatively one could fix 'load' so that it doesn't eat the rest of the
> line. But I think that would be just as much work, for less gain.
Eating the rest of the line feels wrong. But you know the code and the
reasons better than me.
|
|
From: <pl...@pi...> - 2008-04-08 19:00:10
|
On Tue, 08 Apr 2008 18:59:54 +0200, Tim Hoffmann <tim...@un...> wrote: > Blocking is desirable, but it's more than I proposed. I was just > thinking of a fix for nesting types 3) and 4) which I could manage in a > short time. For a real blocking I would have to have a deeper look in > the source code. I don't have the time for this now (maybe in two > months). Maybe this should be done all or nothing rather than a stop gap. From the thread you linked we see it is get-aroundable as it is , although a bit clumbsy. I'm not sure the stop gap would be much better. Ethans patch to fix load goes a long way since this was one thing I had tried to get around the current if sytax and , like he said, it failed. It's a bit of a hack to use load but load patch fills the gap. Blocks would really seem to be the way to a clean solution. Thanks for bringing this up, it's already improved. /Peter. |