From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail2-relais-roc.national.inria.fr (mail2-relais-roc.national.inria.fr [192.134.164.83]) by sympa.inria.fr (Postfix) with ESMTPS id 2C7DB800B6 for ; Wed, 4 Jan 2017 14:49:54 +0100 (CET) Authentication-Results: mail2-smtp-roc.national.inria.fr; spf=None smtp.pra=gabriel.scherer@gmail.com; spf=Pass smtp.mailfrom=gabriel.scherer@gmail.com; spf=None smtp.helo=postmaster@mail-qk0-f180.google.com Received-SPF: None (mail2-smtp-roc.national.inria.fr: no sender authenticity information available from domain of gabriel.scherer@gmail.com) identity=pra; client-ip=209.85.220.180; receiver=mail2-smtp-roc.national.inria.fr; envelope-from="gabriel.scherer@gmail.com"; x-sender="gabriel.scherer@gmail.com"; x-conformance=sidf_compatible Received-SPF: Pass (mail2-smtp-roc.national.inria.fr: domain of gabriel.scherer@gmail.com designates 209.85.220.180 as permitted sender) identity=mailfrom; client-ip=209.85.220.180; receiver=mail2-smtp-roc.national.inria.fr; envelope-from="gabriel.scherer@gmail.com"; x-sender="gabriel.scherer@gmail.com"; x-conformance=sidf_compatible; x-record-type="v=spf1" Received-SPF: None (mail2-smtp-roc.national.inria.fr: no sender authenticity information available from domain of postmaster@mail-qk0-f180.google.com) identity=helo; client-ip=209.85.220.180; receiver=mail2-smtp-roc.national.inria.fr; envelope-from="gabriel.scherer@gmail.com"; x-sender="postmaster@mail-qk0-f180.google.com"; x-conformance=sidf_compatible IronPort-PHdr: =?us-ascii?q?9a23=3A95Tc3Ra535XLSfWrRaVMSFf/LSx+4OfEezUN459i?= =?us-ascii?q?sYplN5qZpci9bnLW6fgltlLVR4KTs6sC0LuK9fm9EjFdqdbZ6TZZL8wKD0dEwe?= =?us-ascii?q?wt3CUeQ+e9QXXhK/DrayFoVO9jb3RCu0+BDE5OBczlbEfTqHDhpRQbGxH4KBYn?= =?us-ascii?q?br+tQt2ap42N2uuz45zeZRlTzHr4OOsqbUaAlhjKrsQdnadlL68wzFOJ/ioJKK?= =?us-ascii?q?xqwjZGP1uVEBH9/fCI+4J/8ilK86Yv7cdGWqL7ZOIgSqBEDTk8G2Ez/szi8xfZ?= =?us-ascii?q?G1ih/HwZB0ofmABJDgyN1xr6U438qGOuueN3wiiXOYvtRrA5Qzm4x6huQR7szi?= =?us-ascii?q?wAMmhqoynslsVsgfcD81qarBtlztuRPdiY?= X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: =?us-ascii?q?A0AwAAD6/GxYhrTcVdFeFgUBAQEDAQEBC?= =?us-ascii?q?QEBARcBAQQBAQoBAYMNAQEBAQFAPoEMB6IWgjWGOY48KoV4AoFJB0MQAQEBAQE?= =?us-ascii?q?BAQEBAQESAQEBCAsLCh0wgjMEARUFghcBBAEjHQEbEgsBAwwGBQsaHQICIgERA?= =?us-ascii?q?QUBChIGExKIQgEDEAgOolQ/jAOCAwUBHIMJBYNqChknAwpUghABAQEBAQUBAQE?= =?us-ascii?q?BAQEBGQIGEoYzg1uBBoRzgliCXgWHGQyIZop+gXqEXIprgkeOEkiGC4onFB6BF?= =?us-ascii?q?A8ngSlREoMfKSCCByA0hmOBTwEBAQ?= X-IPAS-Result: =?us-ascii?q?A0AwAAD6/GxYhrTcVdFeFgUBAQEDAQEBCQEBARcBAQQBAQo?= =?us-ascii?q?BAYMNAQEBAQFAPoEMB6IWgjWGOY48KoV4AoFJB0MQAQEBAQEBAQEBAQESAQEBC?= =?us-ascii?q?AsLCh0wgjMEARUFghcBBAEjHQEbEgsBAwwGBQsaHQICIgERAQUBChIGExKIQgE?= =?us-ascii?q?DEAgOolQ/jAOCAwUBHIMJBYNqChknAwpUghABAQEBAQUBAQEBAQEBGQIGEoYzg?= =?us-ascii?q?1uBBoRzgliCXgWHGQyIZop+gXqEXIprgkeOEkiGC4onFB6BFA8ngSlREoMfKSC?= =?us-ascii?q?CByA0hmOBTwEBAQ?= X-IronPort-AV: E=Sophos;i="5.33,459,1477954800"; d="scan'208,217";a="252836250" Received: from mail-qk0-f180.google.com ([209.85.220.180]) by mail2-smtp-roc.national.inria.fr with ESMTP/TLS/AES128-GCM-SHA256; 04 Jan 2017 14:49:53 +0100 Received: by mail-qk0-f180.google.com with SMTP id n21so400843288qka.3; Wed, 04 Jan 2017 05:49:53 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:in-reply-to:references:from:date:message-id:subject:to :cc; bh=4Y0FvxJyOieZZyMCfvoccJZe76Bj8v53vfYzVITZqUc=; b=fea2O9Lrzhu+3F1+LHEodvZbHycHLnkGDmQObRN6E7/8wn95hf2OTc6qUVHaxaEbaE PUwLwVfU/ucCiICEvVdWnSzPVaGMnqjL5eLRyWjrXcFeM8gONiehUpDuvfWa6436slIP ZYie7ESxCJSoh4imF1utgFYBqS8fevh0URJl7r0HjiW+e7f1dfmhuVl2YVgBJp2H2xN6 YEdo8F1Qo0iDSmw3zJRt7uCOFZ/m7sSLMJfBWHq7XPGLbAjjuTHwn/eVDVO4egV0Cm6b oOwixJfv6URmByazzMrxI4YmYtT2RK+bpuzZUUapZv1w9OY/MoNDy9Q0LXvA6t5sfyao 1EAg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:in-reply-to:references:from:date :message-id:subject:to:cc; bh=4Y0FvxJyOieZZyMCfvoccJZe76Bj8v53vfYzVITZqUc=; b=mQeAg0IPia/rD5NPh0LERr6O7bHCRlM03CjpFp989x2tvDrXopY8NsfbLBrdW7Rz4Y lpBRnrH0vvpfsDJfK78FqEaQ6BfX4GFmht1b61KdmNgXwcXGHhrduRlbb12LSNBJYqVt EU9ev6JI2sFnIek5KV/aXV09Ek5F9f2tjyxeEupWQmvKN0bP6XPSZogjZk4c/S+CQhtt 9zs7hyqFbWzJ4JDP7g4nfDgiBBURHDOvaac1a5GwO3AqFWczD9LcEjalwtcuVfH1tzV7 h/bX0wQCSvfA1I6OYll6Gnhkr0OxKB0S2GICkaE7AzccH58zC94Q9gykIn4+onL8VO5+ BCGg== X-Gm-Message-State: AIkVDXJPUaQYP9E3d80Emlp0SpNG0UZrLwLOO5D1DkzrFcQ+02HBHxJCFulIl7MRC4h/lbX5H+0RN/dg/eFVVw== X-Received: by 10.55.79.212 with SMTP id d203mr73320430qkb.110.1483537791668; Wed, 04 Jan 2017 05:49:51 -0800 (PST) MIME-Version: 1.0 Received: by 10.12.172.73 with HTTP; Wed, 4 Jan 2017 05:49:11 -0800 (PST) In-Reply-To: <9576980c-9aad-4af2-e512-dc9c42743cf2@inria.fr> References: <9576980c-9aad-4af2-e512-dc9c42743cf2@inria.fr> From: Gabriel Scherer Date: Wed, 4 Jan 2017 08:49:11 -0500 Message-ID: To: =?UTF-8?Q?Fran=C3=A7ois_Pottier?= Cc: Peter Zotov , caml users Content-Type: multipart/alternative; boundary=001a114a9a9c157cd10545450fc0 Subject: Re: [Caml-list] ppx_deriving question: deferring code generation? --001a114a9a9c157cd10545450fc0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable The semantics you propose is inherently stateful: delays accumulates some state and [@@visitors]'s meaning (nitpick: I think it should be a floating attribute, [@@@visitors]) depends on the current state. You could design a similar facility using names for references instead of implicit state: type foo =3D Bar | Baz let x : foo option ref =3D ref None [@@@deriving.for foo (visitors)] (If we had access to the type-checking environment, [@@deriving.for p] could be valid for any qualified identifier p that points to a transparent definition in the current environment. Given the current ppx pipeline, I suppose that would have to be restricted to being in the syntactic scope of an actual declaration.) Hongbo Zhang introduced a similar "deriving from a distance" feature in his preprocessor Fan, for the reason you give, and also to allow deriving boilerplate code of datatypes defined in third-party libraries without having to modify them directly. On Wed, Jan 4, 2017 at 8:08 AM, Fran=C3=A7ois Pottier wrote: > > Hello all, > > I am currently in the process of writing a ppx_deriving plugin, called > "visitors". Overall, this has been a pleasant experience; a few hundred > lines > of code have been sufficient to obtain nontrivial results. > > In normal use, the user writes something like this: > > type foo =3D > Bar | Baz > [@@deriving visitors] > > and some generated code is inserted just after the definition of the type > foo. > > However, I have reached a situation where the generated code cannot be > placed > just after the type definition. That is, I need to allow user-written code > to > appear after the type definition and before the generated code. > > For instance, this user-written code could be a declaration of a global > variable "x", whose type is "foo ref", and which the generated code uses. > The > declaration of "x" must appear after the definition of the type "foo", > because > the type of "x" mentions "foo". And the declaration of "x" must appear > before > the generated code, because the generated code (intentionally) refers to > "x". > > I am imagining that perhaps the user could write something like this: > > type foo =3D > Bar | Baz > [@@deriving visitors { delayed =3D true } > > let x : foo option ref =3D > ref None > > [@@visitors] > > The effect of the flag { delayed =3D true } would be to store the generat= ed > code > somewhere in memory (instead of emitting right away), and the effect of t= he > floating attribute [@@visitors] would be to fetch that code from memory a= nd > emit it. > > To me, this seems somewhat ugly, but workable. Does ppx_deriving offer a > better approach? Does anyone have a better suggestion? Comments are > appreciated. > > Best regards, > > -- > Fran=C3=A7ois Pottier > francois.pottier@inria.fr > http://gallium.inria.fr/~fpottier/ > > -- > Caml-list mailing list. Subscription management and archives: > https://sympa.inria.fr/sympa/arc/caml-list > Beginner's list: http://groups.yahoo.com/group/ocaml_beginners > Bug reports: http://caml.inria.fr/bin/caml-bugs > --001a114a9a9c157cd10545450fc0 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable
The semantics you propose is inherently stateful= : delays accumulates some state and [@@visitors]'s meaning (nitpick: I = think it should be a floating attribute, [@@@visitors]) depends on the curr= ent state. You could design a similar facility using names for references i= nstead of implicit state:

=C2=A0 type foo =3D
=C2=A0 =C2=A0 Bar | Baz

=C2=A0 let x : foo option ref =3D
=C2=A0 =C2=A0 ref None

=C2=A0 [@@@deriving.for foo (visitors)]

(If we had access to t= he type-checking environment, [@@deriving.for p] could be valid for any qua= lified identifier p that points to a transparent definition in the current = environment. Given the current ppx pipeline, I suppose that would have to b= e restricted to being in the syntactic scope of an actual declaration.)
=
Hongbo Zhang introduced a similar "deriving from a distance&= quot; feature in his preprocessor Fan, for the reason you give, and also to= allow deriving boilerplate code of datatypes defined in third-party librar= ies without having to modify them directly.


On Wed, Jan 4, 2017 at 8:08 AM, Fran=C3=A7ois Pottier <francois.pottier@inria.fr> wrote:

Hello all,

I am currently in the process of writing a ppx_deriving plugin, called
"visitors". Overall, this has been a pleasant experience; a few h= undred lines
of code have been sufficient to obtain nontrivial results.

In normal use, the user writes something like this:

=C2=A0 type foo =3D
=C2=A0 =C2=A0 Bar | Baz
=C2=A0 =C2=A0 [@@deriving visitors]

and some generated code is inserted just after the definition of the type f= oo.

However, I have reached a situation where the generated code cannot be plac= ed
just after the type definition. That is, I need to allow user-written code = to
appear after the type definition and before the generated code.

For instance, this user-written code could be a declaration of a global
variable "x", whose type is "foo ref", and which the ge= nerated code uses. The
declaration of "x" must appear after the definition of the type &= quot;foo", because
the type of "x" mentions "foo". And the declaration of = "x" must appear before
the generated code, because the generated code (intentionally) refers to &q= uot;x".

I am imagining that perhaps the user could write something like this:

=C2=A0 type foo =3D
=C2=A0 =C2=A0 Bar | Baz
=C2=A0 =C2=A0 [@@deriving visitors { delayed =3D true }

=C2=A0 let x : foo option ref =3D
=C2=A0 =C2=A0 ref None

=C2=A0 [@@visitors]

The effect of the flag { delayed =3D true } would be to store the generated= code
somewhere in memory (instead of emitting right away), and the effect of the=
floating attribute [@@visitors] would be to fetch that code from memory and=
emit it.

To me, this seems somewhat ugly, but workable. Does ppx_deriving offer a
better approach? Does anyone have a better suggestion? Comments are
appreciated.

Best regards,

--
Fran=C3=A7ois Pottier
francois.pot= tier@inria.fr
http://gallium.inria.fr/~fpottier/=

--
Caml-list mailing list.=C2=A0 Subscription management and archives:
https://sympa.inria.fr/sympa/arc/caml-list
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
Bug reports: http://caml.inria.fr/bin/caml-bugs

--001a114a9a9c157cd10545450fc0--