comp.lang.ada
 help / color / mirror / Atom feed
* Virtual Components in Ada and Ruby
@ 2005-06-22 15:17 Frank J. Lhota
  2005-06-30  4:12 ` Randy Brukardt
  0 siblings, 1 reply; 6+ messages in thread
From: Frank J. Lhota @ 2005-06-22 15:17 UTC (permalink / raw)


Recently I was studying the Ruby scripting language. One of the features
of the Ruby language has a parallel in Ada. A Ruby class has one or more
"attributes", which are used to read or manipulate the data in an object.

A Ruby attribute is readable if it can be used to read a value
associated with an object. The book "Programming Ruby" uses the example
of a class Song, used to represent a song that included in a Jukebox. A
readable attribute of the Song class might be durationInSeconds. If
thisSong is an instance of Song class, a Ruby programmer could write a
statement like this to increment totalDuration by the duration of thisSong:

	totalDuration += thisSong.durationInSeconds

Conversely, a Ruby attribute is writable if it can be assigned a value.
If the durationInSeconds attribute of the Song class is writable, we
could write a statement such as this

	thisSong.durationInSeconds = 190

Ruby attributes look like record components, and many Ruby attributes
are in fact implemented using instance variables (the Ruby equivalent of
Ada record components). But Ruby also support virtual attributes, that
is, attributes that do not correspond to any actual instance variable.
Instead, a virtual attribute provides methods for reading and / or
writing that attribute. To illustrate, let us go back to our Song
example. This class has the durationInSeconds attribute, implemented as
an instance variable. Assume that in some programs, it is more useful to
work with a song's duration in minutes. We therefore would like to have
a readable / writable attribute called durationInMinutes. Obviously, it
would not be desirable to implement the durationInMinutes attribute with
another instance variable, since we would then have two instance
variables that must always be updated in tandem. A better approach would
be to implement durationInMinutes as follows:

      class Song
        # Read the virtual attribute durationInMinutes
        def durationInMinutes
          @durationInSeconds/60.0
        end
        # Write the virtual attribute durationInMinutes
        def durationInMinutes=(value)
          @durationInSeconds = value*60.0
        end
      end

Basically, this approach implements reading and writing the
durationInMinutes by performing the appropriate action on the
durationInSeconds instance variable. Of course, whether or not an
attribute is virtual is an internal implementation issue. Outside of the
Song class, the durationInMinutes attribute is used exactly the same way
as the durationInSeconds attribute.

So what does this have to do with Ada? Well, one could argue that the
notion of virtual components has existed in Ada from the very beginning.
Consider a packed record, such as the following:

      subtype Seconds_Count is Natural range 0 .. 59;
      subtype Minutes_Count is Natural range 0 .. 59;
      ...
      type Timestamp is
         record
            Sec : Seconds_Count;
	   Min : Minutes_Count;
            ...
         end record;

      for Timestamp use
         record
            Sec at 0 range  0 ..  5;
	   Min at 0 range  6 .. 11;
            ...
         end record;

Technically, the type of the Min component in Timestamp is Integer. But
Min is not really implemented as an integer in memory. Min is shorter
than an integer, and it does not even start on a byte boundary, much
less meet any byte alignment requirements for an integer. Min is
definitely not aliased. The Ada compiler, however, makes it look as
though Min is an integer by using mask and shift procedures to read and
write integer values for Min. For example, if TS is an object of type
Timestamp, the Ada statement

      Ada.Integer_Text_Io.Put (TS.Min);

is often (always?) implemented by having the compiler retrieve the
integer value of TS.Min using mask and shift, then passing that integer
to the "Put" procedure. Similarly,

      TS.Min := Some_Integer;

is implemented by a mask and shirt to store Some_Integer into the bits 
for Min. Borrowing from the Ruby terminology, Min is a virtual component.

Looking ahead to Ada 201Z, should there be user-defined virtual record 
components? Currently, a component of a record must always be defined as 
a section of memory in a record. Would it be desirable to also be able 
to define a record component in terms of subprograms for reading and 
writing that component?

Last year, I had a similar proposal for virtual record components:

http://groups-beta.google.com/group/comp.lang.ada/browse_thread/thread/b5ab7c96b188b59e/83840467bdfa413f?q=Lhota&rnum=2#83840467bdfa413f



^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Virtual Components in Ada and Ruby
  2005-06-22 15:17 Virtual Components in Ada and Ruby Frank J. Lhota
@ 2005-06-30  4:12 ` Randy Brukardt
  2005-06-30  7:53   ` Dmitry A. Kazakov
  0 siblings, 1 reply; 6+ messages in thread
From: Randy Brukardt @ 2005-06-30  4:12 UTC (permalink / raw)


"Frank J. Lhota" <NOSPAM.lhota@adarose.com> wrote in message
news:2ifue.819$Z97.597@trndny06...
....
> Looking ahead to Ada 201Z, should there be user-defined virtual record
> components? Currently, a component of a record must always be defined as
> a section of memory in a record. Would it be desirable to also be able
> to define a record component in terms of subprograms for reading and
> writing that component?

I think it would likely be too ambiguous with other possibilities to be very
useful.

Certainly, Ada 200Y has "virtual record components" for reading:

    type Something is tagged record ... end record;
    function Virtual (Obj : in Somthing) return Integer;

    Object : Something;

    if Object.Virtual = 10 then ...

But there doesn't seem to be a practical way to make them writable on the
LHS of an assignment. A procedure call isn't too bad in that case:
    Object.Set_Virtual (To => <args>);

                            Randy.







^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Virtual Components in Ada and Ruby
  2005-06-30  4:12 ` Randy Brukardt
@ 2005-06-30  7:53   ` Dmitry A. Kazakov
  2005-06-30 15:53     ` Alexander E. Kopilovich
  0 siblings, 1 reply; 6+ messages in thread
From: Dmitry A. Kazakov @ 2005-06-30  7:53 UTC (permalink / raw)


On Wed, 29 Jun 2005 23:12:48 -0500, Randy Brukardt wrote:

> "Frank J. Lhota" <NOSPAM.lhota@adarose.com> wrote in message
> news:2ifue.819$Z97.597@trndny06...
> ....
>> Looking ahead to Ada 201Z, should there be user-defined virtual record
>> components? Currently, a component of a record must always be defined as
>> a section of memory in a record. Would it be desirable to also be able
>> to define a record component in terms of subprograms for reading and
>> writing that component?

Yes! Though this is not the complete list of what "record interface" should
do. Also:

1. Record aggregates should be support "virtual" user-defined components.
2. The most important thing is "virtual" discriminants. This would open a
great variety of possibilities.
3. Overriding non-"virtual" components with "virtual" ones and vice versa.
4. Abstract "virtual" components to be required for overriding and thus
abstract record types.

> I think it would likely be too ambiguous with other possibilities to be very
> useful.

I think that "record interface" could drastically improve Ada. Virtual
members is only a part of what should be: an ability to provide private
implementation of a record type (and also an array or an access type.)

> Certainly, Ada 200Y has "virtual record components" for reading:
> 
>     type Something is tagged record ... end record;
>     function Virtual (Obj : in Somthing) return Integer;
> 
>     Object : Something;
> 
>     if Object.Virtual = 10 then ...
> 
> But there doesn't seem to be a practical way to make them writable on the
> LHS of an assignment. A procedure call isn't too bad in that case:
>     Object.Set_Virtual (To => <args>);

Though it is unsuitable if you want, for example, pass a virtual record
type as a generic parameter.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Virtual Components in Ada and Ruby
  2005-06-30  7:53   ` Dmitry A. Kazakov
@ 2005-06-30 15:53     ` Alexander E. Kopilovich
  2005-06-30 18:55       ` Randy Brukardt
  0 siblings, 1 reply; 6+ messages in thread
From: Alexander E. Kopilovich @ 2005-06-30 15:53 UTC (permalink / raw)
  To: comp.lang.ada

Dmitry A. Kazakov wrote:

> I think that "record interface" could drastically improve Ada.

At least, after that addition it would not be possible to say that Ada is
clearly inferior to Object Pascal/Delphi in this respect.

Stubborn resistance to this feature in Ada somehow resembles that infamous
long-lived absence of enumerations in Java.







Alexander Kopilovich                      aek@vib.usr.pu.ru
Saint-Petersburg
Russia





^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Virtual Components in Ada and Ruby
  2005-06-30 15:53     ` Alexander E. Kopilovich
@ 2005-06-30 18:55       ` Randy Brukardt
  2005-07-01 10:04         ` Dmitry A. Kazakov
  0 siblings, 1 reply; 6+ messages in thread
From: Randy Brukardt @ 2005-06-30 18:55 UTC (permalink / raw)


"Alexander E. Kopilovich" <aek@VB1162.spb.edu> wrote in message
news:mailman.120.1120146983.17633.comp.lang.ada@ada-france.org...
> Dmitry A. Kazakov wrote:
>
> > I think that "record interface" could drastically improve Ada.
>
> At least, after that addition it would not be possible to say that Ada is
> clearly inferior to Object Pascal/Delphi in this respect.
>
> Stubborn resistance to this feature in Ada somehow resembles that infamous
> long-lived absence of enumerations in Java.

I'm not sure what you guys are talking about, but certainly there has been
no "resistance" to virtual components - I don't think they've ever been
proposed or discussed before. Yesterday was the first time I can recall ever
seeing anything like that.

But the whole idea seems misguided to me - programs shouldn't be exporting
components [including discriminants] (virtual or otherwise) in the first
place. All of that should be hidden with a set of operations to access them,
construct them, and the like. Ada 200Y certainly has made that easier by
giving real constructors to limited types, so there should no longer be any
reason to expose any components.

As always, I can think of a handful of exceptions to the rule (just like
there are a few types that probably shouldn't be tagged and derived from
Controlled or Limited_Controlled), but there aren't enough of these to
justify any additional language features.

There's a better argument for a virtual array capability, because that has
properties that are tough to emulate with subprograms. But even that's
questionable (especially in face of the difficulties of defining and
implementing slices and aggregates for such things).

                            Randy.






^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Virtual Components in Ada and Ruby
  2005-06-30 18:55       ` Randy Brukardt
@ 2005-07-01 10:04         ` Dmitry A. Kazakov
  0 siblings, 0 replies; 6+ messages in thread
From: Dmitry A. Kazakov @ 2005-07-01 10:04 UTC (permalink / raw)


On Thu, 30 Jun 2005 13:55:18 -0500, Randy Brukardt wrote:

> But the whole idea seems misguided to me - programs shouldn't be exporting
> components [including discriminants] (virtual or otherwise) in the first
> place. All of that should be hidden with a set of operations to access them,
> construct them, and the like.

So the set of operations in this case is (simplified) ".<name>" and
".<name>:=". The point is that there must be a better separation of
implementation and interface. Why something publicly declared as a tagged
record cannot be implemented using an access type?

> Ada 200Y certainly has made that easier by
> giving real constructors to limited types, so there should no longer be any
> reason to expose any components.
>
> As always, I can think of a handful of exceptions to the rule (just like
> there are a few types that probably shouldn't be tagged and derived from
> Controlled or Limited_Controlled), but there aren't enough of these to
> justify any additional language features.

It is not an additional feature in my view. It is less features, though
also a structural language reform. I'd like to remove predefined types
classes as much as possible.
 
> There's a better argument for a virtual array capability, because that has
> properties that are tough to emulate with subprograms. But even that's
> questionable (especially in face of the difficulties of defining and
> implementing slices and aggregates for such things).

Right. Slices and aggregates must become first-class citizens, first.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2005-07-01 10:04 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2005-06-22 15:17 Virtual Components in Ada and Ruby Frank J. Lhota
2005-06-30  4:12 ` Randy Brukardt
2005-06-30  7:53   ` Dmitry A. Kazakov
2005-06-30 15:53     ` Alexander E. Kopilovich
2005-06-30 18:55       ` Randy Brukardt
2005-07-01 10:04         ` Dmitry A. Kazakov

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox