# Error: The leftmost part-ref in a data-ref cannot be a function reference

**URL:** <https://fortran-lang.discourse.group/t/error-the-leftmost-part-ref-in-a-data-ref-cannot-be-a-function-reference/4990>\
**Category:** Language enhancement\
**Created:** [January 7, 2023, 11:22pm UTC](https://fortran-lang.discourse.group/t/error-the-leftmost-part-ref-in-a-data-ref-cannot-be-a-function-reference/4990 "2023-01-07T23:22:35Z")\
**Posts on this page:** 1\
**Showing post:** 4

<div class="post-metadata">

**Author:** ![ivanpribec](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/ivanpribec/32/3290_2.png) [@ivanpribec](https://fortran-lang.discourse.group/u/ivanpribec)\
**Post date:** [January 8, 2023, 11:40am UTC](https://fortran-lang.discourse.group/t/error-the-leftmost-part-ref-in-a-data-ref-cannot-be-a-function-reference/4990/4 "2023-01-08T11:40:06Z")

</div>

Is there any notable benefit of postfix chaining to the more classic and arguably clearer “functional” alternative?

```auto
module num_m
    implicit none
    private
    public :: NumT, root, squared
    type :: NumT
        real :: x
    end type
contains
    function squared(T)
        type(NumT), intent(in) :: T
        type(NumT) :: squared
        squared % x = (T % x)**2
    end function
    function root(T)
        type(NumT), intent(in) :: T
        type(NumT) :: root
        root % x = sqrt(T % x)
    end function
end module

program test
    use num_m
    implicit none
    print *, NumT(x=10)
    print *, root(squared(NumT(x=10)))
end program

```

Edit: in this example I’d be compelled to use the standard names, why force the user to learn use `%squared()` and `%root()`, when `**` and `sqrt` are known to everyone:

```auto
module num_m
    implicit none
    private
    public :: NumT
    public :: operator(**)
    public :: sqrt
    
    type :: NumT
        real :: x
    end type
    interface operator(**)
        module procedure NumT_pow
    end interface
    interface sqrt
        module procedure NumT_sqrt
    end interface
contains
    function NumT_pow(T,p) result(Y)
        type(NumT), intent(in) :: T
        integer, intent(in) :: p 
        type(NumT) :: Y
        Y = NumT(T%x**p)
    end function
    function NumT_sqrt(T) result(Y)
        type(NumT), intent(in) :: T
        type(NumT) :: Y
        Y = NumT(sqrt(T%x))
    end function
end module

program test
    use num_m
    implicit none
    print *, sqrt(NumT(10)**2)
end program

```

This would be in line with C++ core guideline [C.162](https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Ro-equivalent):

> **C.162: Overload operations that are roughly equivalent**
> 
> Having different names for logically equivalent operations on different argument types is confusing, leads to encoding type information in function names, and inhibits generic programming.

---

_[View the full topic](https://fortran-lang.discourse.group/t/error-the-leftmost-part-ref-in-a-data-ref-cannot-be-a-function-reference/4990)._
