November 03, 2005
In article <dkch0u$1k2o$1@digitaldaemon.com>, Don Clugston says...
>
>Again, I really think it would be more useful to be able to apply class invariants to built-in types. Then, you could call it "PositiveReal", "NonNegativeReal", "ufloat", or anything else.
>
>Maybe with an extension to the typedef syntax; something like:
>
>typedef real invariant { assert(signbit(this)==0); }  NonNegativeReal;
>
>typedef int invariant { assert(this&1==1); } OddInteger;
>
>because I really think your request is a specific instance of a more general requirement.

This would be most useful. Although, I think a higher goal should be to make it possible to define UDT that behave as transparantly as possible as primitive types. With its value based semantics, the D struct is the obvious candidate.

It is only lacking the ability to define:

- Constructor/destructor (maybe not needed, but very powerful)
- Assignment/Copy semantics
- Some of the comparison operators (!<>=, etc...)
- Implicit casting and promotion (may harm more than help)
- anything else?

What are the good reasons not to support user defined assignment/copy semantics for structs?

One already assumes copying of structs to be a potentially non-trivial operation. The default copy would need to be redefined from a memcpy to memberwise assignment.

Making structs more powerful would make it possible to support both the limited range data types you suggest and things like transparent BigNum types, automatic ref-counted resource handles, automatic (and safe) COW types, and more...

/Oskar


November 03, 2005
> If you're building a purely mathematical application, why don't you just build a custom class for numerical values? It's easy to define arbitrary value ranges using the class invariant.

I don't mind doing this.  Part of my original post was a question as to whether psuedonumeric class can interact naturally with the built-in types.  I guess what I'd really like to know is whether float opCast() allows implicit conversion to float, or whether explicit conversion is still required.  Thanks for the interesting discussion.


November 03, 2005
Oskar Linde wrote:
> Don Clugston says...
> 
>> Again, I really think it would be more useful to be able to apply
>> class invariants to built-in types. Then, you could call it
>> "PositiveReal", "NonNegativeReal", "ufloat", or anything else.
>> 
>> Maybe with an extension to the typedef syntax; something like:
>> 
>> typedef real invariant { assert(signbit(this)==0); }
>> NonNegativeReal;
>> 
>> typedef int invariant { assert(this&1==1); } OddInteger;
>> 
>> because I really think your request is a specific instance of a
>> more general requirement.

IIRC, this is how it is done in Euphoria. Then we'd have OddInteger (as described above), range types like in Pascal, but also for floats, etc. We could also have coordinate types that allow/disallow a specific area, etc.

> This would be most useful. Although, I think a higher goal should be
> to make it possible to define UDT that behave as transparantly as
> possible as primitive types. With its value based semantics, the D
> struct is the obvious candidate.
> 
> It is only lacking the ability to define:
> 
> - Constructor/destructor (maybe not needed, but very powerful)
> - Assignment/Copy semantics
> - Some of the comparison operators (!<>=, etc...)
> - Implicit casting and promotion (may harm more than help)
> - anything else?
> 
> What are the good reasons not to support user defined assignment/copy
> semantics for structs?
> 
> One already assumes copying of structs to be a potentially
> non-trivial operation. The default copy would need to be redefined
> from a memcpy to memberwise assignment.

A struct without reference type variables or pointers, could always be memcopied. This could go in the language spec.

> Making structs more powerful would make it possible to support both
> the limited range data types you suggest and things like transparent
> BigNum types, automatic ref-counted resource handles, automatic (and
> safe) COW types, and more...

We could implement a lot if we had structs that are sensitive to changes of their fields!

(This could be implemented so, that whenever there is an assignment to the struct's field, the compiler inserts a call to user defined code!)

---

I wonder, should we differentiate between

 - structs in general
 - structs with no reference or pointer variables

I mean, we are already redefining in D the semantics between Objects and Structs, so why not make a proper job of it?

We could call the new type Subject. The idea being that they are further away from Objects than what Structs are.

- Subject contains no ptrs/refs. Memcopy. Fields can be sensitive.
- Struct  just like they are now
- Object  just like they are now

To really be useful, Subjects should be usable in arithmetic and string contexts just like pre-existing data types. Probably they should contain a field that says whether they are "string friendly" or "float compatible".
November 03, 2005
"Georg Wrede" <georg.wrede@nospam.org> wrote in message news:436A4D5A.5050106@nospam.org...
> (This could be implemented so, that whenever there is an assignment to the struct's field, the compiler inserts a call to user defined code!


This sounds alot like the Property syntax in D.  A property is a virtual method, so you can derive from a class whose values are all accessed via properties, and insert user code between the assignment and the underlying storage of the value.


November 03, 2005
Garett Bass wrote:
> "Georg Wrede" <georg.wrede@nospam.org> wrote in message news:436A4D5A.5050106@nospam.org...
> 
>>(This could be implemented so, that whenever there is an assignment to the struct's field, the compiler inserts a call to user defined code!
> 
> This sounds alot like the Property syntax in D.  A property is a virtual method, so you can derive from a class whose values are all accessed via properties, and insert user code between the assignment and the underlying storage of the value. 

Like this?

class C {
    int getSomething() {
        return doGetSomething();
    }
protected:
    abstract int doGetSomething();
}

This is actually the suggested method for doing interfaces in C++, as it creates a clean separation between interface and implementation.


Sean
November 04, 2005
In the struct-alike case, I prefer to do this:

class Base {
    private int _i;
    final int i() { return _i; }
    int i(int i) { return _i = i; }
}

class PreDerived {
    int i(int i) {
        writefln("i = %d", super.i); // old value
        return super.i = i;
    }
}

class PostDerived {
    int i(int i) {
        super.i = i;
        writefln("i = %d", super.i); // new value
        return super.i;
    }
}

This way you have the flexibility to process the input before and/or after it is assigned to the base class's storage.

With the protected handler method, you can only process
the input at one point in the assignment sequence, i.e.
whenever the handler is called.  Of course, in some
implementations, this may be desirable, so it's nice to
have both tools in your box ;)

BTW, I've come to realize that the opCast() operator
allows me to do just exactly what I should do to create
a pseudonumeric ufloat class.  All the debate here
worked out nicely.

Regards,
Garett


"Sean Kelly" <sean@f4.ca> wrote in message news:dkduf7$g95$1@digitaldaemon.com...
> Garett Bass wrote:
>> "Georg Wrede" <georg.wrede@nospam.org> wrote in message news:436A4D5A.5050106@nospam.org...
>>
>>>(This could be implemented so, that whenever there is an assignment to the struct's field, the compiler inserts a call to user defined code!
>>
>> This sounds alot like the Property syntax in D.  A property is a virtual method, so you can derive from a class whose values are all accessed via properties, and insert user code between the assignment and the underlying storage of the value.
>
> Like this?
>
> class C {
>     int getSomething() {
>         return doGetSomething();
>     }
> protected:
>     abstract int doGetSomething();
> }
>
> This is actually the suggested method for doing interfaces in C++, as it creates a clean separation between interface and implementation.
>
>
> Sean


1 2
Next ›   Last »