Ilya Zakharevich on Fri, 28 Jun 2002 10:49:15 -0400

[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]

Re: [PATCH 2.2.2] mnemonics for flags

On Fri, Jun 28, 2002 at 04:21:58PM +0200, Bill Allombert wrote:
> > As I said: *this* is the difference.  With "M Pattern", there is way
> > for the external program to precompile the mneumonic flags.  With "G",
> > one needs some additional way to allow this.
> For the sake of this argument, imagine we add a second table in
> src/language/init.c with only the M macro. External programs could be
> able to read both, without making simple prototypes harder to parse.
> But GP do not need it, since the function will do the conversion
> t_STRING-->long itself.

Even though this was hypothetical, note that this breaks the RULE1:

  one should not need to manually duplicate complicated tables.  Too
  error-prone, and one copy will *always* lag behind during upgrades...

> > Of course it does.  E.g., Math::Pari converts an argument of type
> > "String" to G via lisexpr().  Doing this over a mneumonic flag would be
> > a disaster.  Thus a special flag is needed anyway (call it "M" for the
> > sake of discussion).
> Why? You can enter t_STRING in Math::PARI, you just need to quote the quote:
> Writing "\"Runge-Kutta\"" or even '"Runge-Kutta"' is a burden, but probably
> less than breaking the GP grammar.


We should think not only from the point of view of the program, but
from the point of view of the user too time to time ;-).  [This is why
personally, I would prefer to have doublequotes optional for GP code

> Also we can provide a interface function:
> (assuming ploth take only a GEN)
> enum Func_tags {Func_ploth};
> struct flagnames flag_names[]={"M...",};
> plot_proto(long f(GEN, long), struct flagnames *fn, GEN x, GEN flags)
> {
>   long flag=decode_flags(flags,fn);
>   if (typ(flags)==t_STR)
>     flag=decode(flags);
>   else
>     flag=itos(flags);
>   return f(x,flag);
> }
> similar to the arith_proto
> and
> now
> ploth_flags(GEN x, GEN flags)
> {
>     return plot_proto(ploth,flag_names+Func_ploth,x, flags);
> }

This assumes all the functions taking a flag take only one of them,
and have the same signature...  And again, the information which
function takes which struct flagnames need to be duplicated somewhere.

This is an enormous amount of work per *each* function taking a flag.
[Somehow I think you assume there are going to be many functions
sharing the same set of ]

> GP will use ploth_flags, but data are stored to allows external programs
> to know they can just use ploth if 

No, the data is not available to them unless you have a table
ploth_flags -> {ploth, Func_ploth}.  And having no hashes in PARI,
such a table is quite complicated to create...

> Admittedly, it is a perfect overkill for plotting functions which are
> slow by nature. But we can make this mechanism very generic to every
> kind of functions without performance issue for GP2C generated code,
> or even GP once we will learn it to precompile code.

"We can make" is too optimistic.  I see no way to do it in a robust way.

> I agree it would make sense that Dxxx,L, allows only xxx to be a long, but it
> is not the case currently.
> ? install(gpowgs,"GDM,L,");
> ? M=5
> %1 = 5
> ? gpowgs(3)
> %2 = 243

Just a lazy coding.  ;-) [On my part...  I reused the PARI parser to
safe a few lines of C code when processing the defaults.]

> > Enum do not even come close.  You need to remember which flags require
> > ORing, which ANDing.
> It is what "sufficiently explicit" do :
> have both ORploth_xxx enum and ANDNOTploth_xxx.
> There is no checking, but it should be fairly obvious that
> ORploth must be OR'ed and ANDNOTploth must be AND-NOT'ed.

This is ugly, and, again, completely ignores the user's convenience.
And, in my experience, "fairly obvious" never works as far as
programming is concerned.