Bill Allombert on Fri, 28 Jun 2002 16:21:58 +0200


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

Re: [PATCH 2.2.2] mnemonics for flags


On Thu, Jun 27, 2002 at 09:30:26AM -0400, Ilya Zakharevich wrote:
> On Thu, Jun 27, 2002 at 01:34:52PM +0200, Bill Allombert wrote:
> > > The diffence is that in the former case no change to gp2c is needed
> > > when a new flag-capable function is coded.
> > 
> > It makes no difference. In both case you have to update the gp2c functions
> > description file to let gp2c knows about the new definition. 
> > 
> > This file is automatically build from the PARI/GP source. If we add a way to
> > specify symbolic flags in PARI, gp2c should be able to read it and add it
> > to its functions description file.
> 
> 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.

Anyway we have plan to do that in a better anyway.

> > Anyway if flag names are t_STRING, using G or M does not make a real
> > difference.
> 
> 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.

use Math::Pari qw(PARI Vec);
$a='"Runge-Kutta"';
print Vec($a);

output correctly ["Runge-Kutta"]
(btw, thanks a lot for Math::PARI. I rewrote the GP generated part of
my thesis to Math::PARI and the output is much better.)

> 
> Three intertwined questions remain:
> 
>   a) Should the "pattern" for the flags be exposed via the struct entree;
> 
>   b) Should the corresponding C function take a long or a GEN;
> 
>   c) Should the pattern be embedded into the argument signature
>      string, or be available elsewhere?
> 
> If a==NO, then b==GEN, and "c" is N/A.  As I already discussed it,
> this requires the compiler to be changed each time the pattern is
> changed.

Only the interface definition file need to change and it can be shipped with
GP.  We are working on that indeed.

Also we can provide a interface function:
(assuming ploth take only a GEN)
enum Func_tags {Func_ploth};
struct flagnames flag_names[]={"M...",};

GEN
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
GEN
ploth_flags(GEN x, GEN flags)
{
    return plot_proto(ploth,flag_names+Func_ploth,x, flags);
}

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

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.

> No ambiguity: a default for a long should be a long, and GD0 isn't.
> [But I also look at "DG" with suspicion; note that it was not in the
> initial implementation I did; I would prever it to be denoted as "D,G"
> or some such.  There may be other examples with a *legitimate* ambiguity.]

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

> > > How do you perform operations over enums with a check of validity of
> > > the operation?
> 
> > That's a good point for you. What kind of check do you want to perform ?
> 
> See my initial message.  There are two safeguards:
> 
>  "Set to a value" should be done first (may be followed by |-type and
>       &~-type modifiers;
> 
>  "Set to a value and that's it" may be used standalone only.
> 
> AFAIU, this is all what is needed with the current PARI API, and with
> other flag-taking API I had seen in my life.
> 
> > Can you do it with the current numeric flag interface ?
> > Using sufficiently explicit enum value name, we should be able to avoid 
> > most mistakes (but not to *check* them, agreed).
> 
> 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.

Cheers,

Bill.