Home     |     .Net Programming    |     cSharp Home    |     Sql Server Home    |     Javascript / Client Side Development     |     Ajax Programming

Ruby on Rails Development     |     Perl Programming     |     C Programming Language     |     C++ Programming     |     IT Jobs

Python Programming Language     |     Laptop Suggestions?    |     TCL Scripting     |     Fortran Programming     |     Scheme Programming Language


 
 
Cervo Technologies
The Right Source to Outsource

MS Dynamics CRM 3.0

Fortran Programming Language

limitations on function reference


AFAIK if f(x) is an array-valued function one can't access an element
by saying (for example)
   PRINT *,f(x)(1)
but must be more long-winded, by declaring an array g of the same shape
as f, with elements of the same type, and then saying
   g = f(x)
   PRINT *,g(1)

If f is of type character one could also imagine 3 pairs of parentheses:
   PRINT *,f(x)(1:2)(3:4)
to print characters 3 and 4 of elements 1 and 2 of the array f(x)

Does some possible ambiguity I haven't thought of prevent allowing
that sort of thing?

-- John Harper, School of Mathematics, Statistics and Computer Science,
Victoria University, PO Box 600, Wellington 6140, New Zealand
e-mail john.har@vuw.ac.nz phone (+64)(4)463 5341 fax (+64)(4)463 5045

John Harper wrote:
> AFAIK if f(x) is an array-valued function one can't access an element
> by saying (for example)
>    PRINT *,f(x)(1)
> but must be more long-winded, by declaring an array g of the same shape
> as f, with elements of the same type, and then saying
>    g = f(x)
>    PRINT *,g(1)
> If f is of type character one could also imagine 3 pairs of parentheses:
>    PRINT *,f(x)(1:2)(3:4)
> to print characters 3 and 4 of elements 1 and 2 of the array f(x)

One ambiguity is just the one you mention: that between arrays
and substrings.  If you allow such, you might also allow substrings
of substrings, in which case there is definitely an ambiguity.

> Does some possible ambiguity I haven't thought of prevent allowing
> that sort of thing?

Note that in C, subscripting is an operator, and can be applied
to any pointer variable or pointer expression.  In that case,
an array name can be considered a pointer constant.  The return
value of a pointer valued function can be subscripted.  In C,
the () of a function call are also an operator, and can be
applied to function pointer valued functions, for example.

Using a function for substrings removes some of the ambiguity
and allows substrings of substrings in languages like PL/I.

-- glen

John Harper wrote:
> AFAIK if f(x) is an array-valued function one can't access an element
> by saying (for example)
>    PRINT *,f(x)(1)
> but must be more long-winded, by declaring an array g of the same shape
> as f, with elements of the same type, and then saying
>    g = f(x)
>    PRINT *,g(1)

> If f is of type character one could also imagine 3 pairs of parentheses:
>    PRINT *,f(x)(1:2)(3:4)
> to print characters 3 and 4 of elements 1 and 2 of the array f(x)

An equally upsetting non-feature is:

  TYPE :: atype
    INTEGER :: a
  END TYPE
  TYPE(a) FUNCTION f(a)

  print *, f(42)%a
                ^

which is not allowed (asked gfortran, ifort and f95). Accessing only a
single member of a returned type would come in handy at some times.

On Apr 24, 4:25 am, har@mcs.vuw.ac.nz (John Harper) wrote:

> AFAIK if f(x) is an array-valued function one can't access an element
> by saying (for example)
>    PRINT *,f(x)(1)
> but must be more long-winded, by declaring an array g of the same shape
> as f, with elements of the same type, and then saying
>    g = f(x)
>    PRINT *,g(1)

> If f is of type character one could also imagine 3 pairs of parentheses:
>    PRINT *,f(x)(1:2)(3:4)
> to print characters 3 and 4 of elements 1 and 2 of the array f(x)

> Does some possible ambiguity I haven't thought of prevent allowing
> that sort of thing?

If you need the idiom regularly, you can define (and possibly
overload) a function
TAKE(array,index) that simply returns array(index) and use
PRINT *,TAKE(f(x),1)

Such manipulation function like this TAKE (or SWAP and others) perhaps
could be added to the Fortran standard. Admittedly there is little
benefit; OTOH, the cost of adding intrinsics is really low.

On Apr 24, 12:21 pm, Daniel Franke <nos@nowhere.com> wrote:

Sometimes, yes, but is it worth the effort of modifying the language?
You can easily write an extracting function if you need the idiom
often, or use a temporary.

John Harper wrote:
> AFAIK if f(x) is an array-valued function one can't access an element
> by saying (for example)
>    PRINT *,f(x)(1)
> but must be more long-winded, by declaring an array g of the same shape
> as f, with elements of the same type, and then saying
>    g = f(x)
>    PRINT *,g(1)

> If f is of type character one could also imagine 3 pairs of parentheses:
>    PRINT *,f(x)(1:2)(3:4)
> to print characters 3 and 4 of elements 1 and 2 of the array f(x)

> Does some possible ambiguity I haven't thought of prevent allowing
> that sort of thing?

I don't think it is ambiguous, but it surely can become hard to
understand for a person.

A couple of thoughts.
1)  You're cheating by using "x" as an argument ;).  Try 42 instead
and then there are a ton of things that someone might try to write
(ch* is character, *f is function, *a* is an array):
      chf(42)          af(42)           cha(42)         a(42)
      chf(42)(1)       af(42)(1)        cha(42)(1)      a(42)(1)
      chf(42)(1:3)     af(42)(1:3)      cha(42)(1:3)    a(42)(1:3)
      chf(42)(1)(2:3)  af(42)(1)(2:3)   cha(42)(1)(1:3) a(42)(1)(2:3)
      chf(42)(1:3)(2:4)

I think everything is unambiguous, but it's a dog's breakfast and
likely to be error prone, especially if the function doesn't
have arguments.

2)  It's hard to limit this to functions.  A function is just an
expression with one term.  The regularity police will "demand"
that this be applied to general expressions.
(x(I)(J:K)+y(L)(2))(M:N)
just doesn't look worthwhile.

3)  This came up for a little discussion during the initial array
processing design in the late 80's and was discarded (I don't
remember why).  It hasn't been reproposed by anybody willing to
do the (hard?) initial design work.  I'd guess that the belief is
that the (perceived) problems outweigh the expected benefit.

Dick Hendrickson

On Apr 23, 10:25 pm, har@mcs.vuw.ac.nz (John Harper) wrote:

> AFAIK if f(x) is an array-valued function one can't access an element
> by saying (for example)
>    PRINT *,f(x)(1)
> but must be more long-winded, by declaring an array g of the same shape
> as f, with elements of the same type, and then saying
>    g = f(x)
>    PRINT *,g(1)

To slice an expression one could define a function

function slice(ivec,i1,i2) result(jvec)
! return the slice ivec(i1:i2), avoiding out-of-bounds
! array access
integer, intent(in)  :: ivec(:)
integer, intent(in)  :: i1,i2
integer, allocatable :: jvec(:)
integer              :: j1,j2,nj
j1 = max(lbound(ivec,dim=1),i1)
j2 = min(ubound(ivec,dim=1),i2)
nj = j2 - j1 + 1
allocate (jvec(nj))
jvec = ivec(j1:j2)
end function slice

and write

slice(f(x),i1,i2)

One can also write a function that gets a component of a derived type,
to which an expression could be passed. It would be convenient to make
such a function ELEMENTAL.

An advantage of writing a function is that one can check that the
slice is within the bounds of the array.

> If f is of type character one could also imagine 3 pairs of parentheses:
>    PRINT *,f(x)(1:2)(3:4)
> to print characters 3 and 4 of elements 1 and 2 of the array f(x)

> Does some possible ambiguity I haven't thought of prevent allowing
> that sort of thing?

Octave (and I assume Matlab) allow this, as does R, with slightly
different syntax. Here is an example.

octave:1> x = [10,20,30]
x =

  10  20  30

octave:2> y = x(2:3)(2)
y = 30

I agree it would be a convenient feature to have in Fortran if it does
not break something, but I don't deem it essential.

This sort of works, but it's not very convenient.
The lower bound of an assumed shape array, like IVEC(:), is
always 1.

So, if f(x) doesn't return a 1-based subscripted array, the
caller will have to pass in the lower bound, or do arithmetic on
i1 and j1 on the call side.

Dick Hendrickson

> j2 = min(ubound(ivec,dim=1),i2)
> nj = j2 - j1 + 1

PS:  I'd worry a little here about trying to get a zero sized slice.
I think everything works, but I'd probably stick in an
   nj = max(nj,0)
just to be sure.

Add to del.icio.us | Digg this | Stumble it | Powered by Megasolutions Inc