(j3.2006) Irksome not to be able to invoke type-bound function on an expression

Van Snyder van.snyder
Tue Sep 27 01:35:49 EDT 2016


Fortran programmers had figured this out fifty years ago, with respect
to subscripts.  A subscripted array reference is just a function
reference that the processor knows how to write and (hopefully) inline.

It also isn't vastly different from using a function reference as an
actual argument to another function.  Fortran programmers worked out
these performance implications half a century ago also.

I suggested I might want to do

  s = v%f1()%f2()

This isn't different from

  s = f2(f1(v))

On Tue, 2016-09-27 at 00:06 -0400, Rafik Zurob wrote:
> One thing to watch out for with v%geod()%h_geod is performance if you have 
> multiple instances of it.  C++ gets away with it because you typically 
> #include your inlinable member function definitions into the same 
> translation unit and the compiler frontend or low-opt backend inlines 
> them.  Fortran type-bound procedures will typically be in a separate 
> compilation unit (e.g. a module) and typically will not be inlined unless 
> you enable expensive whole program optimization / link time optimization. 
> If you're only accessing one component of v%geod(), and accessing it only 
> once, you probably don't care.  But if you're accessing multiple 
> components or bindings of it, the explicit temp is a much better choice 
> that's not dependent on compiler optimization.  Also, note that if you're 
> using virtual or non-const (*) functions, the optimizer might not be able 
> to inline, and you might call v%geod() every time it appears in the 
> source.  The temp is an even better approach if v%geod() is expensive.
> 
> Regards
> 
> Rafik
> (*) const in the C++ sense.  I think we had a proposal for adding a 
> "virtuous" procedure prefix with the same meaning.  Pure functions can 
> still access global data.  So you can't replace
> x = pure_foo()
> y = pure_foo()
> with
> x = pure_foo()
> y = x
> without seeing the definition of pure_foo.  Similarly, if you have:
> x = v%geod()%h_geod
> y = v%geod()%h_geod
> and v%geod() is non-virtuous, you'd still execute the code in v%geod() 
> twice.
> 
> j3-bounces at mailman.j3-fortran.org wrote on 26/09/2016 09:31:53 PM:
> 
> > From: Van Snyder <Van.Snyder at jpl.nasa.gov>
> > To: j3 <j3 at j3-fortran.org>
> > Date: 26/09/2016 09:32 PM
> > Subject: (j3.2006) Irksome not to be able to invoke type-bound 
> > function on an expression
> > Sent by: j3-bounces at mailman.j3-fortran.org
> > 
> > I have a type ECR_t that represents Earth-centered-rotating Cartesian
> > coordinates as 3-vectors.  It has type-bound functions and operators to
> > add, subtract, scale, compute 2-norm, and other stuff.
> > 
> > I'd like to compute
> > 
> >   s = ( ( myP + myH * myP%grad_geoid() - line(1) )%norm2()
> > 
> > but this is prohibited, so I need either to export norm2() as an
> > ordinary (not type-bound) function and use
> > 
> >   s = norm2( myP + myH * myP%grad_geoid() - line(1) )
> > 
> > or
> > 
> >   temp = ( ( myP + myH * myP%grad_geoid() - line(1) )
> >   s = temp%norm2()
> > 
> > One particularly important case is function composition.  I'd like to
> > use something like
> > 
> >   s = a%f1()%f2()
> > 
> > Is there a good reason we can't eventually allow to invoke a type-bound
> > function using an expression, and in particular using the result of
> > another type-bound function?
> > 
> > A related question is whether we can eventually select components from a
> > function result (or more general expression).  I have a function Geod()
> > bound to ECR_t that computes 3-dimensional geodetic coordinates
> > (longitude, geodetic latitude, and geodetic height), from
> > Earth-centered-rotating Cartesian coordinates.  The iteration (Either
> > Bowring's or Fukushima's) that does this necessarily computes both
> > geodetic latitude and geodetic height.  But sometimes all I want is
> > geodetic latitude.  My type H_V_Geod that represents 3-dimensional
> > geodetic coordinates is an extension of the one H_Geod that represents
> > only longitude and geodetic latitude.
> > 
> > If I have
> > 
> >   type(ECR_t) :: V
> >   type(H_Geod) :: Geod
> > 
> > I can't get the geodetic surface components (longitude and geodetic
> > latitude) of V using
> > 
> >   geod = v%geod()%h_geod
> > 
> > I need something like
> > 
> >   type(H_V_Geod) :: Temp
> >   temp = v%geod()
> >   geod = temp%h_geod
> > 
> > Is there a good reason we can't eventually allow to select a component
> > of an expression?
> > 
> > 
> > _______________________________________________
> > J3 mailing list
> > J3 at mailman.j3-fortran.org
> > http://mailman.j3-fortran.org/mailman/listinfo/j3
> > 
> 
> 
> _______________________________________________
> J3 mailing list
> J3 at mailman.j3-fortran.org
> http://mailman.j3-fortran.org/mailman/listinfo/j3





More information about the J3 mailing list