axiom-developer
[Top][All Lists]
Advanced

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

[Axiom-developer] Dimensions as types...


From: Ralf Hemmecke
Subject: [Axiom-developer] Dimensions as types...
Date: Tue, 29 Aug 2006 11:44:11 +0200
User-agent: Thunderbird 1.5.0.5 (X11/20060719)

Hi Cliff,

I'll copy that to axiom-developer, because it might start another discussion about dimensions in Axiom.

So what we need, in effect, is types that have types.

You have NOTHING in Aldor that has no type.

And we also need a * operation that can take two types that are
themselves of type Dimension and generate a new type (also of type
Dimension) as the output type, not determined in advance because the
output type is in fact GENERATED based on the input types.

Do you see a problem?

Does Aldor permit this "types having types" behavior?

Of course.

Analyse the code below and ask if something is unclear.
I would very much like to see an upcoming dimensions package programmed along these lines. There are certainly lots of things just rudimentary, but as you can see, multiplying types to construct new types is not at all complicated. That is the power of having types as first class citizens.

Run the program via

>aldor -grun -laldor -mno-mactext -mno-abbrev dimension.as
a = 2e-2*meter
b = 1.08000003e+4*second
c = 2.16000008e+2*meter*second
d = 6.48000001e+2*meter*second*second

And if you think that the numbers are wrong, then complain at aldor.org. My guess is that the SingleFloat implementation has a bug when it comes to printing floats.

Enjoy.

Ralf

PS: I think it gets a bit complicated to convince Aldor to believe that
Length*Time and Time*Length are not so different. With the code below these are different dimensions.

---BEGIN dimension.as
#include "aldor"
#include "aldorio"

macro Unit == String; -- for simplicity
macro R == SingleFloat; -- R could be a parameter to Dimension.
extend SingleFloat: with {
        integer: Literal -> %; -- to make input easier
} == add {
        integer(l: Literal): % == integer(l)$MachineInteger :: %;
}
import from R;

define Dimension: Category == with {
        OutputType;
        value: % -> R;
        unit: % -> Unit;
        bracket: (R, Unit) -> %;
        apply: (R, %) -> %;
}

AuxiliaryDimension: Dimension == add {
        Rep == Record(val: R, unit: Unit);
        import from Rep;
        (tw: TextWriter) << (x: %): TextWriter == {
                tw << rep(x).val << "*" << rep(x).unit;
        }
        value(x: %): R == rep(x).val;
        unit(x: %): Unit == rep(x).unit;
        bracket(r: R, u: Unit): % == per [r, u];
        apply(r: R, x: %): % == per [r * value x, unit x];
}

Length: Dimension with {
        meter: %;
        centimeter: %;
} == AuxiliaryDimension add {
        meter: % == [1, "meter"];
        centimeter: % == [1/100, "meter"];
}

Time: Dimension with {
        second: %;
        minute: %;
        hour: %;
} == AuxiliaryDimension add {
        second: % == [1, "second"];
        minute: % == [60, "second"];
        hour: % == [3600, "second"];
}

(*)(A: Dimension, B: Dimension): Dimension with {
        *: (A, B) -> %;      
} == AuxiliaryDimension add {
        (a: A) * (b: B): % == {
                [value a * value b, unit a + "*" + unit b];
        }
}

main(): () == {
        a: Length := 2 centimeter;
        b: Time := 3 hour;
        c: (Length * Time) := a * b;
        import from Length * Time * Time;
        d := c * 3 second;
        stdout << "a = " << a << newline;
        stdout << "b = " << b << newline;
        stdout << "c = " << c << newline;
        stdout << "d = " << d << newline;
}

main();
---END dimension.as




reply via email to

[Prev in Thread] Current Thread [Next in Thread]