From owner-sc22wg5+sc22wg5-dom8=www.open-std.org@open-std.org  Thu Sep 28 01:16:33 2017
Return-Path: <owner-sc22wg5+sc22wg5-dom8=www.open-std.org@open-std.org>
X-Original-To: sc22wg5-dom8
Delivered-To: sc22wg5-dom8@www.open-std.org
Received: by www.open-std.org (Postfix, from userid 521)
	id 556C13588D5; Thu, 28 Sep 2017 01:16:33 +0200 (CEST)
Delivered-To: sc22wg5@open-std.org
Received: from esa2.cray.iphmx.com (esa2.cray.iphmx.com [68.232.143.164])
	(using TLSv1 with cipher RC4-SHA (128/128 bits))
	(No client certificate requested)
	by www.open-std.org (Postfix) with ESMTP id 2AD28358708
	for <sc22wg5@open-std.org>; Thu, 28 Sep 2017 01:16:28 +0200 (CEST)
DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple;
  d=cray.com; i=@cray.com; q=dns/txt; s=cray1024;
  t=1506554192; x=1538090192;
  h=from:to:cc:subject:date:message-id:references:
   in-reply-to:content-id:content-transfer-encoding:
   mime-version;
  bh=3TC2WhU1XE9YrAcysKMZgdyt+ArUBisNWjPrSYX8sl4=;
  b=MdUdUhphuyny62/ZgIu1LmWK2x3dnD+qRFFnL3JbdxLXsBRfDvoqYn3e
   8Z4k7KxRgK0QV8jQeOKEBYTY7Mo4uy7RAbsMwu/eIbLv4a4z91lzCWF5/
   aP5YCm6F1ykXzGXe+yW+J/sYvlaBWoGju3iC7FMwKSslXW11dkc0lWnDB
   w=;
X-IronPort-AV: E=Sophos;i="5.42,447,1500937200"; 
   d="scan'208";a="15741331"
X-Cray-OBMMKR: 1433258124 15741331
Received: from cray-smtp-2.cray.com (HELO CFWEX01.americas.cray.com) ([136.162.34.11])
  by esa2.cray.iphmx.com with ESMTP/TLS/AES256-SHA; 28 Sep 2017 00:16:26 +0100
Received: from CFWEXHYBRID.americas.cray.com (172.30.88.178) by
 CFWEX01.americas.cray.com (172.30.88.25) with Microsoft SMTP Server (TLS) id
 14.3.319.2; Wed, 27 Sep 2017 18:16:25 -0500
Received: from NAM01-BY2-obe.outbound.protection.outlook.com (216.32.181.179)
 by mail.cray.com (172.30.88.178) with Microsoft SMTP Server (TLS) id
 14.3.319.2; Wed, 27 Sep 2017 18:16:25 -0500
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
 d=crayinc.onmicrosoft.com; s=selector1-cray-com;
 h=From:Date:Subject:Message-ID:Content-Type:MIME-Version;
 bh=qyBGqDCgXIUXTstK4nKqwafNCW4f5REoU0D7W1d0lNY=;
 b=d+TrcUZP5lAT+AlZ7+Tmehm++Z697M4rXf2gEXKt30KgTFrdFmYCTisMibC8AT0SHlEP6/lLgsZCgUTeqGlZswDSZ1A7wc4spkQjATMQ0oV4Ivs/ZXwNz+DbLpknhKYwPcWXq8CUUDCfB3X1aBfb2ODV0BRaeS+wJ/WrxnJjQvY=
Received: from DM5PR11MB1930.namprd11.prod.outlook.com (10.175.88.7) by
 DM5PR11MB1930.namprd11.prod.outlook.com (10.175.88.7) with Microsoft SMTP
 Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P256) id
 15.20.77.7; Wed, 27 Sep 2017 23:16:23 +0000
Received: from DM5PR11MB1930.namprd11.prod.outlook.com ([10.175.88.7]) by
 DM5PR11MB1930.namprd11.prod.outlook.com ([10.175.88.7]) with mapi id
 15.20.0077.016; Wed, 27 Sep 2017 23:16:23 +0000
From: Bill Long <longb@cray.com>
To: Van Snyder <Van.Snyder@jpl.nasa.gov>, fortran standards email list for J3
	<j3@mailman.j3-fortran.org>
CC: sc22wg5 <sc22wg5@open-std.org>
Subject: Re: (j3.2006) (SC22WG5.5973) Generic programming examples
Thread-Topic: (j3.2006) (SC22WG5.5973) Generic programming examples
Thread-Index: AQHTN8zlyFkA0qmUlEueg/v0cn0vWKLJXakA
Date: Wed, 27 Sep 2017 23:16:22 +0000
Message-ID: <CEB03336-C898-4C72-9BB9-C533DBDFC4C8@cray.com>
References: <20170927201113.6D137358742@www.open-std.org>
In-Reply-To: <20170927201113.6D137358742@www.open-std.org>
Accept-Language: en-US
Content-Language: en-US
X-MS-Has-Attach:
X-MS-TNEF-Correlator:
authentication-results: spf=none (sender IP is ) smtp.mailfrom=longb@cray.com; 
x-originating-ip: [136.162.2.1]
x-ms-publictraffictype: Email
x-microsoft-exchange-diagnostics: 1;DM5PR11MB1930;6:CTFDAYtk1J8j6D85CTk+zz6iAae0vOeoMFxmgXRHVOnSv1fDjFaWcoH5Tk5/DfGiJriGSwMmsVkjCpQWaFek61PUa4cHUckuiB5iNFY4D8xxngWQvG2I0e3Xuo8NxLo4hMr0mLJ5Ftc7GgxO+oMq1B1yq/fFqqiZAqu2KQCKN/xgNBaTHmbOS4TPCOaimf70qZaAcLiLnudpBfj7xOO2r3oIVl3QDkrLsmOfP4SnEyemvN2LgCqqI1jiUsp1uYdVMuQj67+3s8Fz9J7wcF7mfBkdqhgnKauUEhIjWt6dpJJGKhDaodH8slIwIvlX0g55EGyumFRXZbkTJH1C2C5Fdg==;5:/+8szUHxvtGjPZpex+BJG26+M4y8bUZRsXZtH3ZV7bAWdvqQvXFz+e47pr9TrFKNIRPffmVTtQ5CxHRDAvjvNH3hnzR4M+yaxIOQsZoLk6QDmxFWVqLZtoi3TzlgJH6hFEL2nmOFEo9N3tSFYKBC2Q==;24:Ug1cwJKRrb6Tuw/PG8BJj00MbyP6ac4lkb/ox+I4QxFOnqXDXHQPn96zv2x5ICjL00/sqmrpjMdDr8aG0oo2jX7ed3bZWofcfSdZBJvBimE=;7:7LFZAbZWuvQUzoaUvDm7JqVcHR0pJeYXkEvElAozAIuq8+kpsBguEuVYBp+iziOfcnP99ph3QSmJT5UsPwfopTjSLs9OEX/wyowS2jaQcSv6UvYLLGb2jvMoE2iGW3poUC9TRjV1iT7RCM5RCzEU72IvwnRL9YPEjao1chV74jNYSiGd8SST/PM/QlXUeyBa7q+XsRzcYn9LQSnuderxdgYXy387LSHJb5bLcQxmN3E=
x-ms-exchange-antispam-srfa-diagnostics: SSOS;SSOR;
x-forefront-antispam-report: SFV:SKI;SCL:-1;SFV:NSPM;SFS:(10019020)(6009001)(346002)(376002)(199003)(189002)(377454003)(24454002)(6506006)(3280700002)(99286003)(6436002)(3660700001)(189998001)(82746002)(2950100002)(3846002)(6116002)(102836003)(8936002)(305945005)(8676002)(81156014)(101416001)(316002)(81166006)(86362001)(33656002)(77096006)(25786009)(53546010)(6486002)(6246003)(110136005)(1720100001)(2900100001)(14454004)(7736002)(4326008)(6512007)(6306002)(5660300001)(229853002)(478600001)(66066001)(36756003)(53936002)(966005)(54356999)(2906002)(68736007)(76176999)(50986999)(106356001)(97736004)(105586002)(83716003)(41533002);DIR:OUT;SFP:1102;SCL:1;SRVR:DM5PR11MB1930;H:DM5PR11MB1930.namprd11.prod.outlook.com;FPR:;SPF:None;PTR:InfoNoRecords;A:1;MX:1;LANG:en;
x-ms-office365-filtering-correlation-id: 93a8826d-5070-48fb-7345-08d505fdc4db
x-microsoft-antispam: UriScan:;BCL:0;PCL:0;RULEID:(22001)(2017030254152)(2017052603199)(201703131423075)(201703031133081)(201702281549075);SRVR:DM5PR11MB1930;
x-ms-traffictypediagnostic: DM5PR11MB1930:
x-exchange-antispam-report-test: UriScan:;
x-microsoft-antispam-prvs: <DM5PR11MB193060F486D6F3C926F8682ED4780@DM5PR11MB1930.namprd11.prod.outlook.com>
x-exchange-antispam-report-cfa-test: BCL:0;PCL:0;RULEID:(100000700101)(100105000095)(100000701101)(100105300095)(100000702101)(100105100095)(6040450)(2401047)(8121501046)(5005006)(10201501046)(93006095)(93001095)(100000703101)(100105400095)(3002001)(6041248)(20161123562025)(20161123560025)(20161123564025)(20161123558100)(20161123555025)(201703131423075)(201702281528075)(201703061421075)(201703061406153)(6072148)(201708071742011)(100000704101)(100105200095)(100000705101)(100105500095);SRVR:DM5PR11MB1930;BCL:0;PCL:0;RULEID:(100000800101)(100110000095)(100000801101)(100110300095)(100000802101)(100110100095)(100000803101)(100110400095)(100000804101)(100110200095)(100000805101)(100110500095);SRVR:DM5PR11MB1930;
x-forefront-prvs: 04433051BF
spamdiagnosticoutput: 1:99
spamdiagnosticmetadata: NSPM
Content-Type: text/plain; charset="us-ascii"
Content-ID: <4CFE2E033AB3EA4FA3448EEEAF1E65BB@namprd11.prod.outlook.com>
Content-Transfer-Encoding: quoted-printable
MIME-Version: 1.0
X-MS-Exchange-CrossTenant-originalarrivaltime: 27 Sep 2017 23:16:22.9280
 (UTC)
X-MS-Exchange-CrossTenant-fromentityheader: Hosted
X-MS-Exchange-CrossTenant-id: e7b8488a-c0cd-4614-aae1-996bfabec247
X-MS-Exchange-Transport-CrossTenantHeadersStamped: DM5PR11MB1930
X-OriginatorOrg: cray.com
Sender: owner-sc22wg5@open-std.org
Precedence: bulk

Or maybe just

module Splines
  type :: Coefs (rk)
     integer,kind :: rk
     real,allocatable :: a(:), b(:), c(:), d(:)
  end type Coefs
contains
  template subroutine eval (c, x, y)
     type (coefs(rk=3D*)) :: c
     real(*), intent(in) :: x
     real(*), intent(out) :: y
    <computation part here>
  end subroutine eval
end module Splines

For simple cases, generics are unnecessary if you have templates.  And the =
complication of type-bound procedures seems unnecessary as well.  Simple, c=
lean code is almost always better.=20


Cheers,
Bill



> On Sep 27, 2017, at 3:11 PM, Van Snyder <van.snyder@jpl.nasa.gov> wrote:
>=20
> Consider a module for spline interpolation:
>=20
>  module Splines
>    type :: Coeffs ( RK )
>      integer, kind :: RK
>      real, allocatable :: A(:), B(:), C(:), D(:)
>    contains
>      procedure :: Eval_D, Eval_S, ...
>      generic :: Eval =3D> Eval_D, Eval_S
>      ! And more procedures to compute A, B, C, D, etc.
>    end type Coeffs
>    integer, public, parameter :: DK =3D kind(0.0d0), SK =3D> kind(0.0e0)
>  contains
>    subroutine Eval_D ( C, X, Y )
>      integer, parameter :: RK =3D dk
>      class(coeffs(rk)), intent(in) :: C
>      real(rk), intent(in) :: X
>      real(rk), intent(out) :: Y
>      include "Eval_Body.f9h"
>    end subroutine Eval_D
>=20
>    subroutine Eval_S ( C, X, Y )
>      integer, parameter :: RK =3D sk
>      class(coeffs(rk)), intent(in) :: C
>      real(rk), intent(in) :: X
>      real(rk), intent(out) :: Y
>      include "Eval_Body.f9h"
>    end subroutine Eval_S
>    ....
>  end module Splines
>=20
> Now I need single, double and Q-precision splines:
>=20
>  use Splines, only: Coeffs, DK, SK
>  integer, parameter :: QK =3D selected_real_kind ( 1 + precision(1.0d0) )
>  type(coeffs(dk)) :: C_D
>  type(coeffs(sk)) :: C_S
>  type(coeffs(qk)) :: C_Q
>  real(dk) :: Y_d
>  real(sk) :: Y_S
>  real(qk) :: Y_q
>  call c_d%eval ( 1.5_dk, y_d )
>  call c_s%eval ( 1.5_sk, y_s )
>  call c_q%eval ( 1.5_qk, y_q )
>=20
> Notice that Splines doesn't define a Q-precision Eval_* subroutine, and
> Coeffs doesn't provide a generic binding for one.  So the code won't
> even compile.  Generic resolution fails because there is no Q-precision
> generic to match c_q%eval.  This is a problem if all you have for your
> spline library is .o and .mod files, and the company that provided it no
> longer exists to give (or sell) you source to upgrade to your
> requirements.
>=20
> This is what Richard Maine warned about twenty years ago -- when Ada
> generic packages had already been in use for fourteen years, and had
> been part of the Ada requirements since before FORTRAN 77.
>=20
> Let's do it using a parameterized procedure without a parameterized
> module (the syntax extensions should be obvious):
>=20
>  module Splines
>    type :: Coeffs ( RK )
>      integer, kind :: RK
>      real, allocatable :: A(:), B(:), C(:), D(:)
>    contains
>      procedure :: Eval_D, Eval_S, ...
>      generic :: Eval =3D> Eval_D, Eval_S
>    end type Coeffs
>    integer, public, parameter :: DK =3D kind(0.0d0), SK =3D> kind(0.0e0)
>    procedure :: Eval_D =3D> Eval ( dk )
>    procedure :: Eval_S =3D> Eval ( sk )
>  contains
>    subroutine (rk) Eval ( C, X, Y )
>      integer :: RK
>      class(coeffs(rk)), intent(in) :: C
>      real(rk), intent(in) :: X
>      real(rk), intent(out) :: Y
>      ... (don't need Include "Eval_Body.f9h")
>    end subroutine Eval
>  end module Splines
>=20
> Now I need single, double and Q-precision splines:
>=20
> Assume I got only .o and .mod files from a vendor, so I don't have
> source to upgrade.  So first, I need to extend Coeffs and define a
> Q-precision evaluator:
>=20
>  module Splines_Q
>    use Splines, only: Coeffs, Eval
>    type, extends(coeffs) :: Coeffs_Q
>    contains
>      procedure :: Eval_Q
>      generic :: Eval =3D> Eval_Q
>    end type Coeffs_Q
>    integer, public, parameter :: QK =3D selected_real_kind ( 1 + precisio=
n(1.0d0) )
>    procedure :: Eval_Q =3D> Eval ( qk )
>  end module Splines_Q
>=20
>  use Splines_Q, only: Coeffs_Q, DK, SK, QK
>  type(coeffs_q(dk)) :: C_D
>  type(coeffs_q(sk)) :: C_S
>  type(coeffs_q(qk)) :: C_Q
>  real(dk) :: Y_d
>  real(sk) :: Y_S
>  real(qk) :: Y_q
>  call c_d%eval ( 1.5_dk, y_d )
>  call c_s%eval ( 1.5_sk, y_s )
>  call c_q%eval ( 1.5_qk, y_q )
>=20
> Now let's do it using a parameterized module:
>=20
>  module Splines ( RK )
>    integer, public, kind :: RK ! Module parameter
>    type :: Coeffs ! Doesn't have a type parameter
>      real(rk), allocatable :: A(:), B(:), C(:), D(:)
>    contains
>      procedure Eval
>    end type Coeffs
>  contains
>    subroutine Eval ( C, X, Y )
>      class(coeffs), intent(in) :: C
>      real(rk), intent(in) :: X
>      real(rk), intent(out) :: Y
>      ... (don't need Include "Eval_Body.f9h")
>    end subroutine Eval
>  end module Splines
>=20
> Now I need single, double and Q-precision splines:
>=20
>  use Splines ( kind(1.0d0) ), only: Coeffs_D =3D> Coeffs, DK =3D> RK
>  use Splines ( kind(1.0e0) ), only: Coeffs_S =3D> Coeffs, SK =3D> RK
>  use Splines ( selected_real_kind ( 1 + precision(1.0d0) ), only: Coeffs_=
Q =3D> Coeffs, &
>    & QK =3D> RK
>=20
>  type(coeffs_d) :: C_D
>  type(coeffs_s) :: C_S
>  type(coeffs_q) :: C_Q
>  real(dk) :: Y_d
>  real(sk) :: Y_s
>  real(qk) :: Y_q
>  call c_d%eval ( 1.5_dk, y_d )
>  call c_s%eval ( 1.5_rk, y_s )
>  call c_q%eval ( 1.5_qk, y_q )
>=20
> This works, even if you don't have source code for the module.  It's
> easy to construct a type and consistent related type-bound procedures.
> You can't do that nearly so easily using parameterized procedures
> without parameterized modules.  If you have a parameterized EVAL
> procedure but you don't have the source for the Splines module, you need
> to extend the type to add a binding for the Q-precision Eval subroutine.
> It's not impossible, but it's ugly and requires more labor expense for
> development and maintenance.
>=20
> To make things a little bit smoother, we should allow declarations
> before USE statements, so long as they depend only upon things declared
> earlier (an already-ubiquitous requirement in the Fortran standard):
>=20
>  integer, parameter :: DK =3D kind(0.0d0)
>  integer, parameter :: SK =3D kind(0.0e0)
>  integer, parameter :: QK =3D selected_real_kind ( 1 + precision(1.0d0) )
>=20
>  use Splines ( dk ), only: Coeffs_D =3D> Coeffs
>  use Splines ( sk ), only: Coeffs_S =3D> Coeffs
>  use Splines ( qk ), only: Coeffs_Q =3D> Coeffs
>=20
> This was all laid out in much greater detail in 04-383r1, with many more
> use case examples.
>=20
>=20
> _______________________________________________
> J3 mailing list
> J3@mailman.j3-fortran.org
> http://mailman.j3-fortran.org/mailman/listinfo/j3

Bill Long                                                                  =
     longb@cray.com
Principal Engineer, Fortran Technical Support &   voice:  651-605-9024
Bioinformatics Software Development                      fax:  651-605-9143
Cray Inc./ 2131 Lindau Lane/  Suite 1000/  Bloomington, MN  55425


