From: Hans-Bernhard B. <br...@ph...> - 2004-07-22 02:07:19
|
On Wed, 21 Jul 2004, Ethan Merritt wrote: > Let me start with a plea to drop the term "late evaluation", > which I think is side-tracking the current discussion. Objection, on the grounds that a shared understanding of what that term means, and what the relation between that and the string variable/function support you're coding is *exactly* the core of the entire discussion we're (still) having. In a very small nutshell: your patchset, combined adds two things: 1) string variables, expressions and functions 2) late evaluation of a special type of string literals: 'sprintf("%g", x)' as expressions. I fully support 1), but object to 2) in its current shape, for reasons of user interface clarity and future extensibility. Now, the long version of the above: As far as I can see, we all agree upon 1), but somewhere along the way we lost track of what you're doing, and thought 2) was the *only* kind of string expression evaluation you're proposing. Well, at least that what threw me off. So I suggest we take 1) for granted, and concentrate on 2). > Whatever it may mean to different people, I don't think it is > a useful way of thinking about my patchsets. Well, then let me point out what it means (by my understanding, which I do hope is pretty standard): in any language where functions or macros are defined whose final value depend on other variable's values, it's a central design question when to to actually resolve those unknowns into known values and compute the result of the function/macro, i.e. "evaluate" them: at the time the function/macro is defined, or at the time it's value is actually used. The latter case is called "late evaluation". In other words, 'late evaluation' means you store the expression as it was entered, and only substitute values for the variables the moment you need the value. > The evaluation is never "late"; it happens when it happens. That statement makes no sense. If it happens at a later stage than it could have been done at, it is late. Let me show you how this distinction translates into gnuplot: gnuplot> x = 1 gnuplot> y = x gnuplot> a(b)=x gnuplot> print y, a(0) 1 1 gnuplot> x = 2 gnuplot> print y, a(0) 1 2 As you see, a(b) picks up the modified value of x, but y doesn't. That is late evaluation in action. Now, the goal which your 'sprintf() inside quotes' method addresses is that there's currently no way at all to do "even later" evaluation of the parameters that get stored by the various 'set' commands. In other words, the actually stored parameters currently can't be expressions --- they're all fixed values that have been computed from the actual expressions at the time of the 'set' command: gnuplot> set arrow 1 from x, y to x, a(0) gnuplot> show arrow arrow 1, linetype 1, linewidth 1.000 nofilled back from (2, 1, 0) to (2, 2, 0) In the light of this, I hope you can see how the only part about your proposal I really don't agree with is the fact that it introduces late evaluation only for strings. I do agree that late evaluation is a useful tool to add. But I disagree about it being useful for strings _only_. I'm aware that an approach that does this from the outside instead of the inside of string literals will be harder to implement, because it'll have to be done as part of command line parsing, and will have repercussions pretty much all through the program. But I'm stricly opposed to any syntax that can't be applied to numerical late evaluation, too. I think a syntax like later(sprintf("%g", y)) later(x); or, shorter $(sprintf("%g", y)) $(x) would be strongly preferrable, even at the cost of extra work at source level. Since there's nothing one can do with late evaluation that one couldn't also achieve without it (by changing the order of commands, possibly re-loading a saved series of commands), I suggest we keep this part of the patch collection out of the CVS tree and go for a mode broadly scoped implementation of that feature. -- Hans-Bernhard Broeker (br...@ph...) Even if all the snow were burnt, ashes would remain. |
From: <mi...@ph...> - 2004-07-22 08:25:58
|
> later(sprintf("%g", y)) > later(x); > > or, shorter > > $(sprintf("%g", y)) > $(x) I would prefer the later() function; it would be advantage to have the 'late' evaluation for real-value functions as well. Maybe, there could be a synonym sPrintf() = later(sprintf()) (aka \def vs \gdef in TeX). I don't like the syntax with $ because it breaks for call'ed scripts. --- PM |
From: Ethan A M. <merritt@u.washington.edu> - 2004-07-24 20:44:30
|
On Wednesday 21 July 2004 12:33 am, Volker Dobler wrote: > There are two functions: quote_str and m_quote_capture. > Using quote_str you will have to do memory allocation yourself, > whereas m_quote_capture will do allocation for you if I remember > correctly. My old patch replaced (hopfully) all the invocations > of quote_str with m_quote_capture and did substitution there. You guys may yet convince me. I think it may be even cleaner than you describe, because the expression parsing code can now handle string constants as well as string-valued functions. So many of the instances of isstring() + m_quote_capture() can be replaced by const_express(&a). Better yet, in many places this is what the code was going to try next anyhow. So the test for string constants as a special case just goes away. Example (taken from the "print" command): #ifndef GP_STRING_VARS /* This is the version 4.0 code */ if (isstring(c_token)) { s = NULL; m_quote_capture(&s, c_token, c_token); fputs(s, print_out); need_space = 0; free(s); ++c_token; } else { (void) const_express(&a); if (need_space) putc(' ', print_out); need_space = 1; disp_value(print_out, &a); } #else /* This is the code after adding string variables */ (void) const_express(&a); disp_value(print_out, &a); if (a.type == STRING) free(a.v.string_val); else putc(' ', print_out); #endif Yes, I know that this code fragment does not exactly duplicate the whitespace layout of the old behaviour. I also see that I must work on when, if ever, to print quote marks when showing the value of string variables. The only thing I am stuck on at the moment is trying to automatically free the dynamically-allocated string created by evaluation of const_express(&a). It is annoying to test for it everywhere, though I suppose it's no worse than having to do the same thing after m_quote_capture in the current code. -- Ethan A Merritt Department of Biochemistry & Biomolecular Structure Center University of Washington, Seattle |
From: Harald H. <h.h...@tu...> - 2004-07-16 16:49:45
|
On Fri, 16 Jul 2004, Ethan Merritt wrote: > > internal.c internal.h > > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D > > 1) Define a new internal function f_sprintf(). [...] > > I think this patch looks like a good thing, but I really > > don't like the name `sprintf'. It really sounds like a c > > programmer had no good idea how to call it. > > I was not clear enough. This *is* the C language > sprintf routine [*]. The gnuplot code just collects the > variables and the format and passes them along to > the C library. The documentation will refer users to > "man sprintf" or to any C language manual. > > > set xlabel string(" %d %d %d", 1,2,3) > > > > The sprintf (or string) command should really understand all > > gnuplot formats (%t, %T, %l, %L, etc.). > > For me, part of the rationale for this work is that the gnuplot > formats are limiting. If there is some particular format that > you cannot produce using a C language printf() variant, then > we can provide a separate routine for that. Or there could > be a second formatting function that specifically uses only > the non-C gnuplot format conversion specifiers. > > mystring =3D string("Format using %T %L etc", var1, var2) > set title sprint("C Format with embedded %s", mystring) I would prefer one function that does everything. Maybe, it could parse the string for gnuplot format specifiers (%t, %T, ...), first. All formats that are not known by gnuplot can then be parsed to the C function snprintf(). When deviding it into two function you really have to know too much about internel things of the implementation. When using one function the documentation may say something like The `string` function understands all gnuplot format specifiers (see format specifiers) and all C specifiers (see Kerninham/Ritchie). Of course programming of a string command is much more work than passing the arguments to snprintf(). But I think it is worth it. Yours Harald --=20 Harald Harders Langer Kamp 8 Technische Universit=E4t Braunschweig D-38106 Braunschweig Institut f=FCr Werkstoffe Germany E-Mail: h.h...@tu... Tel: +49 (5 31) 3 91-3062 WWW : http://www.ifw.tu-bs.de Fax: +49 (5 31) 3 91-3058 |
From: Petr M. <mi...@ph...> - 2004-07-16 17:02:24
|
> > I was not clear enough. This *is* the C language > > sprintf routine [*]. The gnuplot code just collects the > > variables and the format and passes them along to > > the C library. The documentation will refer users to > > "man sprintf" or to any C language manual. > > > > > set xlabel string(" %d %d %d", 1,2,3) I will prefer sprintf(). That's compatible to all our famous programming languages and does not require user to search / think "what kind of command has gnuplot for sprintf?". --- Petr Mikulik |
From: Harald H. <h.h...@tu...> - 2004-07-16 17:13:12
|
On Fri, 16 Jul 2004, Petr Mikulik wrote: > > > I was not clear enough. This *is* the C language > > > sprintf routine [*]. The gnuplot code just collects the > > > variables and the format and passes them along to > > > the C library. The documentation will refer users to > > > "man sprintf" or to any C language manual. > > > > > > > set xlabel string(" %d %d %d", 1,2,3) > > > I will prefer sprintf(). That's compatible to all our famous programming > languages and does not require user to search / think "what kind of comma= nd > has gnuplot for sprintf?". But then, we have to rename `print', too. Or, at least introduce a new command `printf' which uses the same syntax as sprintf and prints to the shell (as `print' does with a different syntax). Yours Harald --=20 Harald Harders Langer Kamp 8 Technische Universit=E4t Braunschweig D-38106 Braunschweig Institut f=FCr Werkstoffe Germany E-Mail: h.h...@tu... Tel: +49 (5 31) 3 91-3062 WWW : http://www.ifw.tu-bs.de Fax: +49 (5 31) 3 91-3058 |
From: Petr M. <mi...@ph...> - 2004-07-16 17:26:09
|
> > I will prefer sprintf(). That's compatible to all our famous programming > > languages and does not require user to search / think "what kind of command > > has gnuplot for sprintf?". > > But then, we have to rename `print', too. Or, at least introduce a new > command `printf' which uses the same syntax as sprintf and prints to the > shell (as `print' does with a different syntax). I don't see a problem. sprintf() is a function which creates a string, while print is a command to print something on screen. --- PM |
From: Harald H. <h.h...@tu...> - 2004-07-16 17:41:47
|
On Fri, 16 Jul 2004, Petr Mikulik wrote: > > > I will prefer sprintf(). That's compatible to all our famous programm= ing > > > languages and does not require user to search / think "what kind of c= ommand > > > has gnuplot for sprintf?". > > > > But then, we have to rename `print', too. Or, at least introduce a new > > command `printf' which uses the same syntax as sprintf and prints to th= e > > shell (as `print' does with a different syntax). > > I don't see a problem. sprintf() is a function which creates a string, wh= ile > print is a command to print something on screen. While you want to name sprintf according to C names, print does not refer to it at all. I really do not see any command in gnuplot (expect the format specifiers) that is named similar to C functions. But I really think if a command (let it be named sprintf or string) exists with the syntax described by Ethan that prints its result into a string a command should exist that uses the same syntax and prints onto screen. For example, the print command should understand sprintf syntax if its argument starts with a (. Yours Harald --=20 Harald Harders Langer Kamp 8 Technische Universit=E4t Braunschweig D-38106 Braunschweig Institut f=FCr Werkstoffe Germany E-Mail: h.h...@tu... Tel: +49 (5 31) 3 91-3062 WWW : http://www.ifw.tu-bs.de Fax: +49 (5 31) 3 91-3058 |