Re: [fricas-devel] Re: "has" in the interpreter

View: New views
6 Messages — Rating Filter:   Alert me  

Parent Message unknown Re: [fricas-devel] Re: "has" in the interpreter

by Ralf Hemmecke :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

> I do not see any immediate need for reflection (self description) in a
> mathematical library  [snip]

Good.

> Programmers might use reflection in order to avoid having to consider
> the most general cases. Look at the following code in
> 'src/algebra/numsolve.spad.pamphlet':

I'd say that is not the best piece of code.

>        numeric(r:K):F ==
>          K is I =>
>            F is Float => r::I::Float
>            F is RN    => r::I::RN
>            F is CF    => r::I::CF
>            F is GRN   => r::I::GRN
>          K is GI =>
>            gr:GI := r::GI
>            F is GRN => complex(real(gr)::RN,imag(gr)::RN)$GRN
>            F is CF  => convert(gr)
>          error "case not handled"

K is I => r::I::F

for the first part would probably have worked fine and even covers more
cases.

But it shows that 'is'/'has' might lead to lots of branches and thus the
code doesn't scale very well.

But look at

mygcd(R: EuclideanDomain)(a: R, b: R): R == {
   R has Field => if zero? a and zero? b then 0 else 1;
   while not zero? b repeat { (a, b) := (b, a rem b) }
   return a;
}

That I consider a case where 'has' is useful.

I actually wonder what will happen if I define two functions:

mygcd(R: Field)(a: R, b: R): R == {
   if zero? a and zero? b then 0 else 1;
}
mygcd(R: EuclideanDomain)(a: R, b: R): R == {
   while not zero? b repeat { (a, b) := (b, a rem b) }
   return a;
}

and then try to say:

Q ==> Fraction Integer;
g: (Q, Q) -> Q := mygcd Q

Should a compiler reject it or simply take the most specific code? Note,
that the compiler already knows that 'Q has Field'.

Even for Aldor I don't think there is a specification for that. (Can
somebody prove me wrong?)

> So my conclusion in the end is that the use of reflection is (almost
> always) undesirable and usually indicates the presence of some other
> deficiency in the language.

+1

Ralf

_______________________________________________
Aldor-l mailing list
Aldor-l@...
http://aldor.org/mailman/listinfo/aldor-l_aldor.org

Re: [fricas-devel] Re: "has" in the interpreter

by Bill Page-7 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Wed, Nov 19, 2008 at 12:31 PM, Ralf Hemmecke wrote:

> ...
> But it shows that 'is'/'has' might lead to lots of branches and thus
> the code doesn't scale very well.
>
> But look at
>
> mygcd(R: EuclideanDomain)(a: R, b: R): R == {
>   R has Field => if zero? a and zero? b then 0 else 1;
>   while not zero? b repeat { (a, b) := (b, a rem b) }
>   return a;
> }
>
> That I consider a case where 'has' is useful.
>

I agree. I am not arguing against such usage. It seems to me that when
'has' refers to a category this tells us a lot about the user's
intentions (i.e. it is good documentation) and because categories are
(usually) rather large things, it is unlikely that we will see a lot
of branching code.

'is' however is something else. It invites the programmer to deal with
specific cases rather than the most general case.

> ...

Regards,
Bill Page.

_______________________________________________
Aldor-l mailing list
Aldor-l@...
http://aldor.org/mailman/listinfo/aldor-l_aldor.org

Re: [fricas-devel] Re: "has" in the interpreter

by Ralf Hemmecke :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

> 'is' however is something else. It invites the programmer to deal with
> specific cases rather than the most general case.

I'd would discourage 'is' for such a case.

In some experimental code, I had myself some need of 'is' in Aldor.
Since there is no 'is' I used some workaround.

Here I don't need it for selecting special cases, but rather to check
whether the domains are identical so that I could safely 'pretend' that
one value 'y' of type Y is also of type X.

Instead of the line
                 if List X has ListType Y then {
you should read
                 if X is Y then {
.

I don't say that I am completely happy with the code at all, since
'Object' as presented in the AUG is not really one of my favourite
types. (Same for Any, but this is a another story.)

Ralf

---
define ObjectLabelType: Category == with {
         LabelType;
        label: (Lab: LabelType, Lab) -> %;
        explode: % -> (Lab: LabelType, Lab);
}
Label: ObjectLabelType == add {
         macro LT == LabelType;
        Rep == Record(LabDom: LabelType, label: LabDom);
         import from Rep;
        label(Lab: LabelType, l: Lab): % == per [Lab, l];
        explode(x: %): (Lab: LabelType, Lab) == explode rep x;
        equals?(X: LT, x: X)(Y: LT, y: Y): Boolean == {
                 -- We must check whether X is the same domain
                 -- as Y. We can do that by asking whether
                 if List X has ListType Y then {
                         (x = y pretend X)
                 } else {
                         false;
                 }
        }
        (x: %) = (y: %): Boolean == equals?(explode x)(explode y);
         ...
}

_______________________________________________
Aldor-l mailing list
Aldor-l@...
http://aldor.org/mailman/listinfo/aldor-l_aldor.org

Re: [fricas-devel] Re: "has" in the interpreter

by Bill Page-7 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Wed, Nov 19, 2008 at 3:30 PM, Ralf Hemmecke wrote:

>
> In some experimental code, I had myself some need of 'is' in Aldor.
> Since there is no 'is' I used some workaround.
>
> Here I don't need it for selecting special cases, but rather to check
> whether the domains are identical so that I could safely 'pretend'
> that one value 'y' of type Y is also of type X.
>
> Instead of the line
>                 if List X has ListType Y then {
> you should read
>                 if X is Y then {
> .

I do not understand. If two domains are identical than why is there
any need to "pretend" that they are the same?

Regards,
Bill Page.

_______________________________________________
Aldor-l mailing list
Aldor-l@...
http://aldor.org/mailman/listinfo/aldor-l_aldor.org

Parent Message unknown Re: [fricas-devel] Re: "has" in the interpreter

by Ralf Hemmecke :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

>> Q ==> Fraction Integer;
>> g: (Q, Q) -> Q := mygcd Q
>>
>> Should a compiler reject it or simply take the most specific code? Note,
>> that the compiler already knows that 'Q has Field'.
>>
>> Even for Aldor I don't think there is a specification for that. (Can
>> somebody prove me wrong?)

> The code is bad for two reasons:
>
> 1) it is hard to check statically due to overloading on type argument
> 2) the overloading is ambigous
>
> In current Spad the code is illegal because of 1 (Spad compiler
> can not handle overloading on type arguments).  I believe that
> in Aldor it is illegal because of 2.  

Now it depends on what you meant by 'code' above. So let me repeat:

---BEGIN aaa.as
#include "algebra"
#include "aldorio"
mygcd(R: Field)(a: R, b: R): R == {
        if zero? a and zero? b then 0 else 1;
}
mygcd(R: EuclideanDomain)(a: R, b: R): R == {
        while not zero? b repeat { (a, b) := (b, a rem b) }
        return a;
}
#if Ambiguity
Q ==> Fraction Integer;
g: (Q, Q) -> Q := mygcd Q;
#elseif Field
Q: Field == Fraction Integer add;
g: (Q, Q) -> Q := mygcd(Q@Field);
#elseif ED
Q: EuclideanDomain == Fraction Integer add;
g: (Q, Q) -> Q := mygcd(Q@EuclideanDomain);
#else
Q ==> Fraction Integer;
g: (Q, Q) -> Q := +;
#endif
import from Integer, Q;
q4: Q := 4::Q;
q6: Q := 6::Q;
stdout << g(q4, q6) << newline;
---END aaa.as

So let's go through the different options.

 >aldor -lalgebra -laldor -grun aaa.as
10

That is fine. The two mygcd have different types so there should be no
problem with defining two constants with different types.

 >aldor -lalgebra -laldor -grun -D Ambiguity aaa.as
"aaa.as", line 12: g: (Q, Q) -> Q := mygcd Q;
                    ..................^
[L12 C19] #1 (Error) There are 2 meanings for the operator `mygcd'.
        Meaning 1: (R: Field) -> (a: R, b: R) -> R
        Meaning 2: (R: EuclideanDomain) -> (a: R, b: R) -> R

Also clear. Q is at the same time a Field and a EuclideanDomain, so the
compiler does not have enough information to uniquely choose one of the
two functions.

 >aldor -lalgebra -laldor -grun -D ED aaa.as
6

The interpretation of the result is a bit questionable, but that it
works could be agreed upon. I pass Q considered as a EuclideanDomain to
the function. There is only one mygcd that accepts a ED. The other one
requires Field.

 >aldor -lalgebra -laldor -grun -D Field aaa.as
"aaa.as", line 15: g: (Q, Q) -> Q := mygcd(Q@Field);
                    ..................^
[L15 C19] #1 (Error) There are 2 meanings for the operator `mygcd'.
        Meaning 1: (R: Field) -> (a: R, b: R) -> R
        Meaning 2: (R: EuclideanDomain) -> (a: R, b: R) -> R


At first I didn't like that so much, but if Q is considered to be a
Field then it is still a EuclideanDomain. So selection is ambiguous.

I've tried many more versions like

g: (Q, Q) -> Q := (mygcd@((R:Field)->(R,R)->R))(Q@Field);
fgcd(R: Field): (R, R)-> R == mygcd R;
fgcd(R: Field)(a: R, b: R): R == mygcd(R)(a,b);

All lead to the same ambiguity.

Conclusion must be: The definition of the two mygcd functions is OK, but
bad in the sense that I don't see any language construct to
unambiguously select the appropriate function.

Ralf

_______________________________________________
Aldor-l mailing list
Aldor-l@...
http://aldor.org/mailman/listinfo/aldor-l_aldor.org

Re: [fricas-devel] Re: [fricas-devel] Re: "has" in the interpreter

by Ralf Hemmecke :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On 11/19/2008 10:22 PM, Bill Page wrote:

> On Wed, Nov 19, 2008 at 3:30 PM, Ralf Hemmecke wrote:
>> In some experimental code, I had myself some need of 'is' in Aldor.
>> Since there is no 'is' I used some workaround.
>>
>> Here I don't need it for selecting special cases, but rather to check
>> whether the domains are identical so that I could safely 'pretend'
>> that one value 'y' of type Y is also of type X.
>>
>> Instead of the line
>>                 if List X has ListType Y then {
>> you should read
>>                 if X is Y then {
>> .
>
> I do not understand. If two domains are identical than why is there
> any need to "pretend" that they are the same?

You removed too much from my mail (at least if I understand your
question correctly).

     equals?(X: LT, x: X)(Y: LT, y: Y): Boolean == {
                 if List X has ListType Y then {
                         (x = y pretend X)
                 } else {
                         false;
                 }
     }

equals? works on 4 things. X and Y are domains which both belong to
category LT. Now, my construction is a workaround for the missing 'is'
and therefore the compiler (after having interpreted 'List X has
ListType Y') is not (yet) smart enough to figure out that X and Y are
identical and in the 'then' branch y could actually equally be
considered to be of type X (without 'pretend').

If 'is' were part of the (Aldor-)language, then of course, inside the
'then' branch the compiler should not require 'pretend', i.e. 'x=y'
should just work.

But we speak in dreams here. The only thing mentioned about 'is' in the
AUG is that it is a reserved keyword.

Ralf

_______________________________________________
Aldor-l mailing list
Aldor-l@...
http://aldor.org/mailman/listinfo/aldor-l_aldor.org