Unions or other "typeless" constructs in Fortran 90? 
Author Message
 Unions or other "typeless" constructs in Fortran 90?

I've just finished reading O'Reilly's book "Migrating to fortran 90".
Fortran 90 looks great; we were considering it as an alternative to
a mixed C/Fortran application, except for one thing:

How does one handle "typeless" programming, where a buffer is read in
off of disk, say, before knowing yet what type it is, and having to
look at it differently at run-time?

Fortran 77 with DEC extensions supports unions, which helps this.
Fortran 90 does not seem to support unions with its "derived types"
(its nomenclature for "records").

Fortran 90 does have pointers, which look promising, except that they
are "typed" pointers - there is no void pointer that I can see, which
makes them resemble early Pascal pointers, solving many dynamic memory
management problems but not the "typeless" programming problem.

As a result we are starting to take a long hard look at C++ or Ada
as an alternative.

Did I misread the O'Reilly book or fail to pick up on some implication?

--Derek Jones

--
-------------------------------------------------------------------------------
Derek Jones

-------------------------------------------------------------------------------



Sat, 30 Aug 1997 03:31:11 GMT  
 Unions or other "typeless" constructs in Fortran 90?

Quote:
>How does one handle "typeless" programming, where a buffer is read in
>off of disk, say, before knowing yet what type it is, and having to
>look at it differently at run-time?

>Fortran 77 with DEC extensions supports unions, which helps this.
>Fortran 90 does not seem to support unions with its "derived types"
>(its nomenclature for "records").

The age old Fortran solution was EQUIVALENCE.  What's wrong with this?

Dan
--
Dan Pop
CERN, CN Division

Mail:  CERN - PPE, Bat. 31 R-004, CH-1211 Geneve 23, Switzerland



Tue, 02 Sep 1997 21:23:35 GMT  
 Unions or other "typeless" constructs in Fortran 90?

Quote:

>>How does one handle "typeless" programming, where a buffer is read in
>>off of disk, say, before knowing yet what type it is, and having to
>>look at it differently at run-time?

>>Fortran 77 with DEC extensions supports unions, which helps this.
>>Fortran 90 does not seem to support unions with its "derived types"
>>(its nomenclature for "records").

>The age old Fortran solution was EQUIVALENCE.  What's wrong with this?

>Dan

There are a number of restrictions on the use of EQUIVALENCE in F90.  It can
be used in almost any situation equivalent to its use in F77, but not with
many of the new F90 constructs,  primarilly as a means of encouraging better
coeding practices.  I believe the TRANSFER intrinsic function was
essentially created for this sort of application as a "safer" replacement
for EQUIVALENCE.  The buffer could be written into an integer (or
character?) array, used as the source in TRANSFER, e.g.,

    INTEGER :: SOURCE(512), INDX
    ...
    REAL :: MOLD, DATA1(10), DATA2(10,10)
    ...
    DATA1 = TRANSFER(SOURCE(INDX), MOLD, 10)
    ...
    DATA2 = RESHAPE(TRANSFER(SOURCE(INDX), MOLD, 100),SHAPE(DATA2))
    ...



Tue, 02 Sep 1997 18:01:53 GMT  
 Unions or other "typeless" constructs in Fortran 90?

Quote:

>I've just finished reading O'Reilly's book "Migrating to Fortran 90".
>Fortran 90 looks great; we were considering it as an alternative to
>a mixed C/Fortran application, except for one thing:

>How does one handle "typeless" programming, where a buffer is read in
>off of disk, say, before knowing yet what type it is, and having to
>look at it differently at run-time?

>Fortran 77 with DEC extensions supports unions, which helps this.
>Fortran 90 does not seem to support unions with its "derived types"
>(its nomenclature for "records").

>Fortran 90 does have pointers, which look promising, except that they
>are "typed" pointers - there is no void pointer that I can see, which
>makes them resemble early Pascal pointers, solving many dynamic memory
>management problems but not the "typeless" programming problem.

>As a result we are starting to take a long hard look at C++ or Ada
>as an alternative.

>Did I misread the O'Reilly book or fail to pick up on some implication?

>--Derek Jones

>--
>-------------------------------------------------------------------------------
>Derek Jones

>-------------------------------------------------------------------------------

The feature of Fortran which is most analogous to a union is EQUIVALENCE, but
there are better ways to deal with data of unknown type.

You can read your buffer into a character variable, look at the characters
to determine what the data type is, and then use an internal read to convert
to the appropriate type.  This works in Fortran 77 as well as Fortran 90.

For example:

        integer,parameter :: buffer_length = 100
        character(buffer_length) :: buff
        integer :: i
        real :: x
        read(1,'(a)') buff
        if (index(buff,'.') == 0) then
        ! No decimal point, so this is an integer
                read(buff,'(bn,i100)') i
        ! now process i
                ...
        else
        ! decimal point found, so this is a floating point number
                read(buff,'(bn,f100.0)') x
        ! now process x
                ...
        endif

Similar character tests can be used to identify whatever kind of data
happens to be in your buffer.  The many new built-in character processing
functions in Fortran 90 facilitate these operations.  The TRANSFER built-in
function is also useful for moving data bew{*filter*} types without changing the
internal representation.  

--
Ronald Sverdlove               Computational Science Research

Tel. 609-734-2517              CN 5300
FAX  609-734-2662              Princeton, NJ 08543-5300



Wed, 03 Sep 1997 01:06:14 GMT  
 Unions or other "typeless" constructs in Fortran 90?

Quote:

> I've just finished reading O'Reilly's book "Migrating to Fortran 90".
> Fortran 90 looks great; we were considering it as an alternative to
> a mixed C/Fortran application, except for one thing:

> How does one handle "typeless" programming, where a buffer is read in
> off of disk, say, before knowing yet what type it is, and having to
> look at it differently at run-time?

I'm not sure what you mean by buffer, but the old fashioned F66 way
to read mixed character & numeric records was to read a record as
alphanumeric, test the alphanumeric elements to determine which
were which, backspace & re-read.  F77 made this easier, as you could
re-read the alpha vector/array without the backspace.  This still
requires some minimal a priori knowledge of the data structure,
i.e, you have to have rules for distinguishing when numerals are
numerical or character type.

-bb  



Wed, 03 Sep 1997 06:38:54 GMT  
 Unions or other "typeless" constructs in Fortran 90?



Quote:
>>I've just finished reading O'Reilly's book "Migrating to Fortran 90".
>>Fortran 90 looks great; we were considering it as an alternative to
>>a mixed C/Fortran application, except for one thing:

>>How does one handle "typeless" programming, where a buffer is read in
>>off of disk, say, before knowing yet what type it is, and having to
>>look at it differently at run-time?

[deletia...]

Quote:
> The feature of Fortran which is most analogous to a union is EQUIVALENCE, but
> there are better ways to deal with data of unknown type.

> You can read your buffer into a character variable, look at the characters
> to determine what the data type is, and then use an internal read to convert
> to the appropriate type.  This works in Fortran 77 as well as Fortran 90.

[example deleted]

Quote:
> Similar character tests can be used to identify whatever kind of data
> happens to be in your buffer.  The many new built-in character processing
> functions in Fortran 90 facilitate these operations.  The TRANSFER built-in
> function is also useful for moving data bew{*filter*} types without changing the
> internal representation.  

        I fear that Ron has missed a  crucial point: the data being read
    is _binary_, not formatted.  All those character manipulations won't
    do  you  a  bit  of  good  if  you're  reading  binary  data.   More
    improtantly, the data are written with internal structure which  can
    be,  or could be, determined from the data itself, but once the data
    is read  in  to  a  user-defined  type  ("structure"),  there  is no
    facility  for  choosing  to access that data with one  of  _several_
    alternative substructures that may be present.

        I happen to agree with Derek that it is a serious ommission from
    the F90 standard that there is no allowance for a UNION-like syntax,
    or  functionality,  within  user-defined  type,  i.e.,  a structure.
    Having  used VAX Fortran's STRUCTURE's in this way _extensively_  in
    dealing with data from a large and complex experiment, both in early
    stages of processing (when you're dealing with "bits and bytes" from
    the hardware) and in later, "summary" format, I can  tell  you  that
    the  advantages  of  being  able  to  read a "buffer" of data into a
    structure, look at  a  particular  location  in  that structure, and
    decide on value found there how to reference other _named_ fields in
    that  structure  leads to much more readable and  maintainable  code
    than the alternatives presented: (a) using EQUIVALENCE in  the  old,
    deprecated   manner,  or  (b)  using  TRANSFER  many,  _many_  times
    throughout the  code.   [I'd  be  happy  to  supply  very _concrete_
    examples if anyone is interested.]

        We  know  the  problems  with  EQUIVALENCE.   The  problem  with
    TRANSFER  (in  contrast to UNION) is that you  cannot  transparently
    have a named field _also_  imply  a  data  type  and  size  (to  the
    compiler):  instead the user needs to know by some "external" means,
    what the data locations' size and  type  are  in order to be able to
    call  TRANSFER  with the correct parameters.  That's no better  than
    EQUIVALENCE'ing a REAL, an  INTEGER,  and  a  CHARACTER  array  (for
    example)  and  needing  to know, via parameters perhaps, which array
    should be referenced, and at what location, to get a particular data
    item.   For  the  applications  I  envision,  given  the  choice  of
    user-defined types _without_ unions, or the old-style EQUIVALENCE of
    multiple arrays, I'd have to choose the latter (or program in C...).

        I  realize  that  there  are   portability  problems,  at  least
    potentially,  when dealing with what amounts to overlaid data items.
    The world isn't all 32-bit.  But after reading the extensive  thread
    about  trying to use KIND types in a portable way, I don't think the
    problems of  overlaid  data  are  any  worse.   There  may  well  be
    performance issues if poorly designed structures, and their internal
    overlays,  lead  to unaligned data items, or  worse,  incommensurate
    sizes.  It is most likely true that _binary_ data in the  format  of
    such  a structure may not be portable since different platforms will
    have different sized REALs and INTEGERs, etc., but that is a problem
    independent of user defined-types or UNIONs within them.

        Perhaps some of  the  people  who  participated on the standards
    committees  would care to comment on why this feature of  structures
    was omitted from user-defined types?

        -Ken
--

 SLAC, P.O.Box 4349, MS 46  |  DECnet:   45537::FAIRFIELD (45537=SLACVX)
 Stanford, CA   94309       |  Voice:    415-926-2924    FAX: 415-926-3515
 -------------------------------------------------------------------------
 These opinions are mine, not SLAC's, Stanford's, nor the DOE's...



Wed, 03 Sep 1997 15:40:30 GMT  
 Unions or other "typeless" constructs in Fortran 90?
Bear in mind that using the union feature of C to provide this capability
is strictly in contradiction with the ANSI C Standard.  The compiler is
free to pad unions in any manner it wishes.

Cheers.



Thu, 04 Sep 1997 19:10:27 GMT  
 Unions or other "typeless" constructs in Fortran 90?


Quote:
> Bear in mind that using the union feature of C to provide this capability
> is strictly in contradiction with the ANSI C Standard.  The compiler is
> free to pad unions in any manner it wishes.

        True, but F9x doesn't need to conform to the ANSI C standard. :-)

        In particular, DEC Fortran  STRUCTUREs  on  VAX hardware are not
    padded.   Although individual "MAPs" within a UNION are all required
    to be the same size, there is a padding construct  (%FILL)  supplied
    for  that  purpose  (when  two MAPs are not the same length).  Steve
    Lionel will be the first  to  point  out  that  on AXP hardware, the
    structures may be padded (for efficient access), but I believe it is
    also  true  that  there are compiler directives  that  suppress  the
    padding/aligning (at the price of decreased performance).

        I'd  still  like  to  hear  from  members  of  the  various  F90
    committees  why  some  sort of UNION in F90 derived  types  was  not
    included in the standard.  What was/is the problem?

        -Ken
--

 SLAC, P.O.Box 4349, MS 46  |  DECnet:   45537::FAIRFIELD (45537=SLACVX)
 Stanford, CA   94309       |  Voice:    415-926-2924    FAX: 415-926-3515
 -------------------------------------------------------------------------
 These opinions are mine, not SLAC's, Stanford's, nor the DOE's...



Sat, 06 Sep 1997 02:55:15 GMT  
 Unions or other "typeless" constructs in Fortran 90?

:         In particular, DEC Fortran  STRUCTUREs  on  VAX hardware are not
:     padded.   Although individual "MAPs" within a UNION are all required
:     to be the same size, there is a padding construct  (%FILL)  supplied
:     for  that  purpose  (when  two MAPs are not the same length). [...]

This mention of maps reminds me of my favorite way to reslove this problem.

I would like to have a declaration which maps data in a storage associated
manner.  For example, suppose you have the type declaration:

      type flt_internal
         bit1 :: sign
         bit8 :: exponent
         bit23 :: significand
      end type flt_internal

Now, assuming your floating point data is IEEE single, this is a description
of that layout.  The BITn declarations are of unsigned integer fields of the
size given (so integer arithmetic can be applied to them).

In order to use this for type coersion you would declare:

      real x,y
      map x as flt_internal

Now, the variables x and y can be any floating point variables, they may
be procedure arguments of globals.  As above, you declare them the same
way you usually do.  However, the MAP declaration allows you to access
with X as if it were declared FLT_INTERNAL.  So, you can get the sign
bit of X as X%SIGN.  You can't do so with Y (it's not been mapped).

You should be able to map the same variable as many ways as you want.

      real x(100)
      map x as flt_internal

This also works.  The reference to the third significand would be
X(3)%SIGNIFICAND.  The map structure must be the same size in bits
as the data type being mapped of course.  And the programmer, not
the language, is responsible for any portability issues which arise
from this.

Cheers
:     Lionel will be the first  to  point  out  that  on AXP hardware, the
:     structures may be padded (for efficient access), but I believe it is
:     also  true  that  there are compiler directives  that  suppress  the
:     padding/aligning (at the price of decreased performance).

:         I'd  still  like  to  hear  from  members  of  the  various  F90
:     committees  why  some  sort of UNION in F90 derived  types  was  not
:     included in the standard.  What was/is the problem?

:         -Ken
: --

:  SLAC, P.O.Box 4349, MS 46  |  DECnet:   45537::FAIRFIELD (45537=SLACVX)
:  Stanford, CA   94309       |  Voice:    415-926-2924    FAX: 415-926-3515
:  -------------------------------------------------------------------------
:  These opinions are mine, not SLAC's, Stanford's, nor the DOE's...



Sat, 06 Sep 1997 11:05:10 GMT  
 Unions or other "typeless" constructs in Fortran 90?


|>        In particular, DEC Fortran  STRUCTUREs  on  VAX hardware are not
|>    padded.   Although individual "MAPs" within a UNION are all required
|>    to be the same size, there is a padding construct  (%FILL)  supplied
|>    for  that  purpose  (when  two MAPs are not the same length).

No, you don't have to pad out MAPs within a UNION, the compiler will do it
for you, to the maximum size of any of the MAPs, if you don't.

|>    Steve
|>    Lionel will be the first  to  point  out  that  on AXP hardware, the
|>    structures may be padded (for efficient access), but I believe it is
|>    also  true  that  there are compiler directives  that  suppress  the
|>    padding/aligning (at the price of decreased performance).

Correct on both counts.
--


DEC Fortran Development           WWW:  http://www.digital.com/info/slionel.html
Digital Equipment Corporation     CompuServe: 75263,3001
110 Spit Brook Road, ZKO2-3/N30
Nashua, NH 03062-2698             "Free advice is worth every cent"




Sat, 06 Sep 1997 23:57:39 GMT  
 Unions or other "typeless" constructs in Fortran 90?


(Rich R Car ) writes:

|>I would like to have a declaration which maps data in a storage associated
|>manner.  For example, suppose you have the type declaration:
|>
|>      type flt_internal
|>    bit1 :: sign
|>    bit8 :: exponent
|>    bit23 :: significand
|>      end type flt_internal
|>
|>Now, assuming your floating point data is IEEE single, this is a description
|>of that layout.  The BITn declarations are of unsigned integer fields of the
|>size given (so integer arithmetic can be applied to them).
|>
|>In order to use this for type coersion you would declare:
|>
|>      real x,y
|>      map x as flt_internal

Nice idea, but it's not Fortran.  (Not even DEC Fortran)  No bit types (I wish
F90 had included these) and no type casting (which is what your ficticious
"map as" statement would do.

Ignoring the lack of bit types, you can do something similar using the Cray
POINTER feature and DEC Fortran structures, both of which are widely
implemented (you could also use F90 derived types and possibly F90 pointers -
I haven't given the latter a lot of thought here - an exercise left for the
reader.)

For example, you might do something like this:

        STRUCTURE /LAYOUT_A_TYPE/
          INTEGER FIELD1
          REAL FIELD2
          END STRUCTURE
        RECORD /LAYOUT_A_TYPE/ LAYOUT_A
        POINTER (LAYOUT_A_P, LAYOUT_A)

Now lets say you've got an object in variable X - can be of any declared
type.  To manipulate it as if it were of structure LAYOUT_A_TYPE you'd do
this:

        LAYOUT_A_P = %LOC(X)
        LAYOUT_A.FIELD1 = ....

This is a bit more cumbersome than UNIONs but can lend itself well to certain
applications.
--


DEC Fortran Development           WWW:  http://www.digital.com/info/slionel.html
Digital Equipment Corporation     CompuServe: 75263,3001
110 Spit Brook Road, ZKO2-3/N30
Nashua, NH 03062-2698             "Free advice is worth every cent"




Sun, 07 Sep 1997 00:15:52 GMT  
 Unions or other "typeless" constructs in Fortran 90?

[In response to a set of suggestions mentioning EQUIVALENCE,
TRANSFER(), and internal reads with various formats from a character buffer.]

Quote:
>        I fear that Ron has missed a  crucial point: the data being read
>    is _binary_, not formatted.  All those character manipulations won't
>    do  you  a  bit  of  good  if  you're  reading  binary  data. More

No? What is wrong with the following?
      CHARACTER*512 BUF
      INTEGER IBUF(128)
      DOUBLE PRECISION DBUF(64)
      READ (11) BUF     ! Reads binary data into BUF
      IF (BUF(1:1).EQ.CHR(0)) THEN
          ! Probably an integer buffer
          READ (BUF,'(128A4)') IBUF
      ELSE IF (ICHAR(BUF(1:1)).LT.32 .OR. ICHAR(BUF(1:1)).GT.126) THEN
          ! Treat this as a dp buffer
          READ (BUF,'(64A8)') DBUF
      ELSE
          ! Interpret it as a character string
      END IF
The example is simplistic, but the binary nature of the data does not
constitute a problem. I apologise for assuming the ASCII character set
(but did I really?) and a 4:1 ratio between numeric and character
storage sizes: that is slightly non-portable.

Quote:
>    improtantly, the data are written with internal structure which  can
>    be,  or could be, determined from the data itself, but once the data
>    is read  in  to  a  user-defined  type  ("structure"),  there  is no
>    facility  for  choosing  to access that data with one  of  _several_
>    alternative substructures that may be present.

Except in that special case where the derived types all have the
SEQUENCE attribute, and all have either numeric or character storage
association. In that case, the standard allows them to be EQUIVALENCEd.
In all other cases, the EQUIVALENCE would be non-portable. Some
compilers may still allow it as an extension. In fact, I'm sure they
will allow it if there is enough demand.

Quote:
>    Having  used VAX Fortran's STRUCTURE's in this way _extensively_  in
>    dealing with data from a large and complex experiment, both in early
>    stages of processing (when you're dealing with "bits and bytes" from
>    the hardware) and in later, "summary" format, I can  tell  you  that
>    the  advantages  of  being  able  to  read a "buffer" of data into a
>    structure, look at  a  particular  location  in  that structure, and
>    decide on value found there how to reference other _named_ fields in
>    that  structure  leads to much more readable and  maintainable  code
>    than the alternatives presented: (a) using EQUIVALENCE in  the  old,
>    deprecated   manner,  or  (b)  using  TRANSFER  many,  _many_  times
>    throughout the  code.   [I'd  be  happy  to  supply  very _concrete_
>    examples if anyone is interested.]

All right. Support for variant tags would be nice, I won't dispute that.
However, I don't see that the new standard's rules about equivalencing
entities of derived types are any more restrictive than the old rules
about equivalencing items in a COMMON block. You may have to use
different variable names, A%IBUF and B%DBUF, to look at the same
object in different ways, but that's all. As for using TRANSFER many
times, that depends on your coding style. The approach I would use
would be to read in the record, determine the appropriate structure
by looking at the contents, TRANSFER the result to the appropriate
type and either pass it to a subroutine that does the rest of the work
or store it in a different variable to be used for subsequent accesses.
Of course, all this is assuming that the derived types have
incompatible storage associations; otherwise EQUIVALENCE is simpler.
--



Sun, 07 Sep 1997 19:51:06 GMT  
 Unions or other "typeless" constructs in Fortran 90?

Quote:

>        I happen to agree with Derek that it is a serious ommission from
>    the F90 standard that there is no allowance for a UNION-like syntax,
>    or  functionality,  within  user-defined  type,  i.e.,  a structure.

>    ...   For  the  applications  I  envision,  given  the  choice  of
>    user-defined types _without_ unions, or the old-style EQUIVALENCE of
>    multiple arrays, I'd have to choose the latter (or program in C...).

Would something like the following be more tasteful (even though
it still uses EQUIVALENCE)?

      type x
      sequence
      real a,b
      end type

      type y
      sequence
      integer i,j
      end type

      type (x) data1(1000)
      type (y) data2(1000)
      equivalence (data1,data2)

(The above compiles OK on the Cray f90 compiler.)

Walt
----
Walt Spector                             It usually takes more than three weeks

Sunnyvale, California                                   Mark Twain
_._ _._ _.... _. ._.

--
Walt
----
Walt Spector                             "Today is the dawn of a new age,



Sun, 07 Sep 1997 14:08:56 GMT  
 
 [ 18 post ]  Go to page: [1] [2]

 Relevant Pages 

1. "Coupling Parallel Models" in Fortran 90

2. "Fortran 90/95 Explained" by Metcalf

3. "Numerical Recipes in Fortran 90"

4. Review of "Migrating to Fortran 90"

5. Review of "Migrating to Fortran 90", J.F. Kerrigan

6. "Fortran 90 Explained"

7. Fortran 90 "no" vote

8. Reference to "Fortran 90" book wanted

9. "Union:" method

10. Function / Procedure and "others" operator query

11. "others" keyword used in reset

12. How the "OVER" construct works

 

 
Powered by phpBB® Forum Software