(j3.2006) Irksome not to be able to invoke type-bound function on an expression
Clune, Thomas L. GSFC-6101
thomas.l.clune
Tue Sep 27 08:23:13 EDT 2016
> On Sep 27, 2016, at 1:35 AM, Van Snyder <Van.Snyder at jpl.nasa.gov> wrote:
> ?
> s = v%f1()%f2()
>
> This isn't different from
>
> s = f2(f1(v))
Van,
I would argue that there is a an absolutely crucial difference between those two. v%f1() could be returning a polymorphic entity. As such, the compiler does not directly ?know? which f2() will be invoked at compile time. Of course with our strict single-inheritance approach, it is a constant offset in a procedure table, which minimizes the performance implications. But it is important to keep in mind the differences.
- Tom
>
> 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
>
>
> _______________________________________________
> J3 mailing list
> J3 at mailman.j3-fortran.org
> http://mailman.j3-fortran.org/mailman/listinfo/j3
More information about the J3
mailing list