caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
* [Caml-list] [ANN] ppx_monadic.1.0.2, ppx for monadic do, pattern guards and monadic comprehension
@ 2015-01-13 14:23 Jun Furuse
  2015-01-14  8:40 ` [Caml-list] [ANN] ppx_monadic.1.0.2, ppx for monadic do, pattern oleg
  0 siblings, 1 reply; 11+ messages in thread
From: Jun Furuse @ 2015-01-13 14:23 UTC (permalink / raw)
  To: caml-list

Hi,

I have OPAM-released ppx_monadic.1.0.2, a ppx extension for

* Monadic do notation:  do_;
* Pattern guards:  when p <-- e -> ..
* List and monadic comprehension:  [%comp x || p <-- e; ..]

These 3 extensions share the same do-sequence syntax sugar, which is a
sequence of the following phrases:

* Monadic bind : p <-- e
* Action: e
* Escape: (); e    (to write the normal sequential execution)
* let .. in .. and [%x .. ]

It is already available via OPAM: opam intall ppx_monadic. More
detailed documentation and source code is available at:
https://bitbucket.org/camlspotter/ppx_monadic

Enjoy!

Jun

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [Caml-list] [ANN] ppx_monadic.1.0.2, ppx for monadic do, pattern
  2015-01-13 14:23 [Caml-list] [ANN] ppx_monadic.1.0.2, ppx for monadic do, pattern guards and monadic comprehension Jun Furuse
@ 2015-01-14  8:40 ` oleg
  2015-01-18 14:47   ` Jun Furuse
  0 siblings, 1 reply; 11+ messages in thread
From: oleg @ 2015-01-14  8:40 UTC (permalink / raw)
  To: caml-list; +Cc: jun.furuse


Jun Furuse wrote:
> * Monadic do notation:  do_;
> * Pattern guards:  when p <-- e -> ..

This reminds me: MetaOCaml incorporates the let! notation suggested by
Nicolas Pouillard and implemented by Alain Frisch. The following is
the example of using the notation, excerpted from the file
        metalib/test/pythagorian_triples.ml
in the BER MetaOCaml distribution/source. 

(* The example uses left recursion and truly infinite streams! *)
(* Don't try this in Prolog or in Haskell's MonadPlus. *)

let rec numb () = 			(* infinite stream of integers *)
    yield (mplus (let! n = numb in ret (n+1))         (* left recursion! *)
	       (ret 0)) ()
;;

let pyth : (int * int * int) NonDet.stream =
  let! i  = numb in
  let! () = guard (i>0) in
  let! j  = numb in
  let! () = guard (j>0) in
  let! k  = numb in
  let! () = guard (k>0) in
  (* Just to illustrate the `let' form within let! *)
  let test x = x*x = j*j + k*k in
  let! () = guard (test i) in
  ret (i,j,k)
;;

let [(5, 4, 3); (5, 3, 4); (10, 8, 6); (10, 6, 8); (13, 12, 5); (13, 5, 12);
     (15, 12, 9); (15, 9, 12); (17, 15, 8); (17, 8, 15)]
 =
run 10 pyth;;


(The file also implements the non-determinism monad that is
illustrated in the example.)


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [Caml-list] [ANN] ppx_monadic.1.0.2, ppx for monadic do, pattern
  2015-01-14  8:40 ` [Caml-list] [ANN] ppx_monadic.1.0.2, ppx for monadic do, pattern oleg
@ 2015-01-18 14:47   ` Jun Furuse
  2015-01-19  7:33     ` [Caml-list] [ANN] ppx_monadic.1.0.2, ppx for monadic do, oleg
  2015-01-19  8:56     ` [Caml-list] [ANN] ppx_monadic.1.0.2, ppx for monadic do, pattern Alain Frisch
  0 siblings, 2 replies; 11+ messages in thread
From: Jun Furuse @ 2015-01-18 14:47 UTC (permalink / raw)
  To: oleg, caml-list

Thanks,

let! is not valid in the vanilla syntax therefore I guess you have
patched the compiler.

Current OCaml syntax has shortage of pattern binding expression and
only usable is let%xxx p = e in which is a bit pain for ppx writers.

The pattern part of   p <-- e  is actually an expression and you
cannot simply write real patterns like   (x, y) as z. You still can
write it using an extension like [%p? (x,y) as z] but it is lousy...

Jun


On Wed, Jan 14, 2015 at 4:40 PM,  <oleg@okmij.org> wrote:
>
> Jun Furuse wrote:
>> * Monadic do notation:  do_;
>> * Pattern guards:  when p <-- e -> ..
>
> This reminds me: MetaOCaml incorporates the let! notation suggested by
> Nicolas Pouillard and implemented by Alain Frisch. The following is
> the example of using the notation, excerpted from the file
>         metalib/test/pythagorian_triples.ml
> in the BER MetaOCaml distribution/source.
>
> (* The example uses left recursion and truly infinite streams! *)
> (* Don't try this in Prolog or in Haskell's MonadPlus. *)
>
> let rec numb () =                       (* infinite stream of integers *)
>     yield (mplus (let! n = numb in ret (n+1))         (* left recursion! *)
>                (ret 0)) ()
> ;;
>
> let pyth : (int * int * int) NonDet.stream =
>   let! i  = numb in
>   let! () = guard (i>0) in
>   let! j  = numb in
>   let! () = guard (j>0) in
>   let! k  = numb in
>   let! () = guard (k>0) in
>   (* Just to illustrate the `let' form within let! *)
>   let test x = x*x = j*j + k*k in
>   let! () = guard (test i) in
>   ret (i,j,k)
> ;;
>
> let [(5, 4, 3); (5, 3, 4); (10, 8, 6); (10, 6, 8); (13, 12, 5); (13, 5, 12);
>      (15, 12, 9); (15, 9, 12); (17, 15, 8); (17, 8, 15)]
>  =
> run 10 pyth;;
>
>
> (The file also implements the non-determinism monad that is
> illustrated in the example.)
>

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [Caml-list] [ANN] ppx_monadic.1.0.2, ppx for monadic do,
  2015-01-18 14:47   ` Jun Furuse
@ 2015-01-19  7:33     ` oleg
  2015-01-19  8:34       ` Alain Frisch
  2015-01-19  8:56     ` [Caml-list] [ANN] ppx_monadic.1.0.2, ppx for monadic do, pattern Alain Frisch
  1 sibling, 1 reply; 11+ messages in thread
From: oleg @ 2015-01-19  7:33 UTC (permalink / raw)
  To: jun.furuse, caml-list


> Current OCaml syntax has shortage of pattern binding expression and
> only usable is let%xxx p = e in which is a bit pain for ppx writers.

Indeed. One may wish that

        let rec p = e1 in e2

were treated as if it were
        let[@ocaml.let "rec"] p = e1 in e2

and likewise let module. Come to think of it, 'rec! or 'module' are
annotations on let. Then we can generalize so that

        let something p = e1 in e2
(where something is any reserved word or an operator -- something that
cannot be mistaken for a regular identifier) is parsed as if it were

        let[@ocaml.let "something"] p = e1 in e2

The type-checker will complain if it finds the ocaml.let attribute it
does not understand. (Therefore, Typedtree does not have to be changed
-- although one may wish for a specifically letrec node).  Thus we
can define let !, let >>=, let LWP, let struct, let when, let if and all other
potentially useful binding forms.



^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [Caml-list] [ANN] ppx_monadic.1.0.2, ppx for monadic do,
  2015-01-19  7:33     ` [Caml-list] [ANN] ppx_monadic.1.0.2, ppx for monadic do, oleg
@ 2015-01-19  8:34       ` Alain Frisch
  2015-01-19  9:06         ` Gabriel Scherer
  0 siblings, 1 reply; 11+ messages in thread
From: Alain Frisch @ 2015-01-19  8:34 UTC (permalink / raw)
  To: oleg, jun.furuse, caml-list

On 01/19/2015 08:33 AM, oleg@okmij.org wrote:
>> Current OCaml syntax has shortage of pattern binding expression and
>> only usable is let%xxx p = e in which is a bit pain for ppx writers.
>
> Indeed. One may wish that
>
>          let rec p = e1 in e2
>
> were treated as if it were
>          let[@ocaml.let "rec"] p = e1 in e2
>
> and likewise let module.

Please, no!  Attributes are intended to add meta-data for external tools 
(ppx, tools parsing .cmt files, etc), perhaps also to tweak the behavior 
of the compiler (trigger/control warnings, etc), certainly not to encode 
core language features (otherwise, let's use s-expressions instead of 
Parsetree).  Facilitating language experiments is also a good use for 
attributes, but not as a long-term solution for the official compiler.

> Come to think of it, 'rec! or 'module' are
> annotations on let.

"let module" has a different shape (module 
identifiers/types/expressions) than "let".  And it doesn't seem 
realistic to merge, say, core types and module types, or core 
expressions and module expressions.


Alain

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [Caml-list] [ANN] ppx_monadic.1.0.2, ppx for monadic do, pattern
  2015-01-18 14:47   ` Jun Furuse
  2015-01-19  7:33     ` [Caml-list] [ANN] ppx_monadic.1.0.2, ppx for monadic do, oleg
@ 2015-01-19  8:56     ` Alain Frisch
  2015-01-19 21:52       ` Drup
  1 sibling, 1 reply; 11+ messages in thread
From: Alain Frisch @ 2015-01-19  8:56 UTC (permalink / raw)
  To: Jun Furuse, oleg, caml-list

On 01/18/2015 03:47 PM, Jun Furuse wrote:
> Thanks,
>
> let! is not valid in the vanilla syntax therefore I guess you have
> patched the compiler.
>
> Current OCaml syntax has shortage of pattern binding expression and
> only usable is let%xxx p = e in which is a bit pain for ppx writers.

If it's a pain, it's rather for users of ppx, no?

Providing "alternative" forms of existing constructs (i.e. forms that 
look syntactically similar to these constructs) to be interpreted before 
they reach the type-checker, is indeed what extension nodes [%foo ...] 
were designed for.  For expression constructs starting with a keyword, 
the short form KEYWORD%foo ... makes the use of extension nodes very 
cheap syntactically.

I can appreciate that authors of tools that requires special syntactic 
support would love to have their new forms look completely native to 
users, but the counter-argument can be made that keeping an explicit 
syntax (through the '%' character) for features that are not part of the 
official language is a good property.  (Camlp4/campl5 are still 
available for people who want to play with the concrete syntax.)


With the short form, an alternative binding construct can be as short as:

  let%L p = e in ....

I'm not suggesting to reserve one-letter extension identifiers for 
specific projects, but each tool could let the user choose explicitly 
which letter to use:


   [%%Project1 alt_id = "L"]
   [%%Project2 alt_id = "A"]
   ...
   ...
     let%L p1 = e1 in ....
     let%A p2 = e2 in ....



Alain

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [Caml-list] [ANN] ppx_monadic.1.0.2, ppx for monadic do,
  2015-01-19  8:34       ` Alain Frisch
@ 2015-01-19  9:06         ` Gabriel Scherer
  2015-01-19  9:40           ` Alain Frisch
  0 siblings, 1 reply; 11+ messages in thread
From: Gabriel Scherer @ 2015-01-19  9:06 UTC (permalink / raw)
  To: Alain Frisch; +Cc: oleg, Jun Furuse, caml users

[-- Attachment #1: Type: text/plain, Size: 1612 bytes --]

(On the other hand, the remark that the existing uses of keyword-bang in
the language, namely (method!) and (open!), could now be represented as
annotations is fairly reasonable.)

On Mon, Jan 19, 2015 at 9:34 AM, Alain Frisch <alain@frisch.fr> wrote:

> On 01/19/2015 08:33 AM, oleg@okmij.org wrote:
>
>> Current OCaml syntax has shortage of pattern binding expression and
>>> only usable is let%xxx p = e in which is a bit pain for ppx writers.
>>>
>>
>> Indeed. One may wish that
>>
>>          let rec p = e1 in e2
>>
>> were treated as if it were
>>          let[@ocaml.let "rec"] p = e1 in e2
>>
>> and likewise let module.
>>
>
> Please, no!  Attributes are intended to add meta-data for external tools
> (ppx, tools parsing .cmt files, etc), perhaps also to tweak the behavior of
> the compiler (trigger/control warnings, etc), certainly not to encode core
> language features (otherwise, let's use s-expressions instead of
> Parsetree).  Facilitating language experiments is also a good use for
> attributes, but not as a long-term solution for the official compiler.
>
>  Come to think of it, 'rec! or 'module' are
>> annotations on let.
>>
>
> "let module" has a different shape (module identifiers/types/expressions)
> than "let".  And it doesn't seem realistic to merge, say, core types and
> module types, or core expressions and module expressions.
>
>
> Alain
>
>
> --
> 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
>

[-- Attachment #2: Type: text/html, Size: 2816 bytes --]

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [Caml-list] [ANN] ppx_monadic.1.0.2, ppx for monadic do,
  2015-01-19  9:06         ` Gabriel Scherer
@ 2015-01-19  9:40           ` Alain Frisch
  2015-01-19 16:10             ` Jeremy Yallop
  0 siblings, 1 reply; 11+ messages in thread
From: Alain Frisch @ 2015-01-19  9:40 UTC (permalink / raw)
  To: Gabriel Scherer; +Cc: oleg, Jun Furuse, caml users

On 01/19/2015 10:06 AM, Gabriel Scherer wrote:
> (On the other hand, the remark that the existing uses of keyword-bang in
> the language, namely (method!) and (open!), could now be represented as
> annotations is fairly reasonable.)

Indeed, these ! markers only affect warnings, and don't change the 
static or dynamic semantics otherwise, so I wouldn't be shocked if they 
were represented internally with attributes.  Unless perhaps if we 
consider that forcing users to mark method overrides, as in many other 
class-based OO languages, should become part of the language definition 
(i.e. turned into a strong error at some point).

-- Alain


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [Caml-list] [ANN] ppx_monadic.1.0.2, ppx for monadic do,
  2015-01-19  9:40           ` Alain Frisch
@ 2015-01-19 16:10             ` Jeremy Yallop
  0 siblings, 0 replies; 11+ messages in thread
From: Jeremy Yallop @ 2015-01-19 16:10 UTC (permalink / raw)
  To: Alain Frisch; +Cc: Gabriel Scherer, Oleg Kiselyov, Jun Furuse, caml users

On 19 January 2015 at 09:40, Alain Frisch <alain.frisch@lexifi.com> wrote:
> On 01/19/2015 10:06 AM, Gabriel Scherer wrote:
>>
>> (On the other hand, the remark that the existing uses of keyword-bang in
>> the language, namely (method!) and (open!), could now be represented as
>> annotations is fairly reasonable.)
>
> Indeed, these ! markers only affect warnings, and don't change the static or
> dynamic semantics otherwise, so I wouldn't be shocked if they were
> represented internally with attributes.  Unless perhaps if we consider that
> forcing users to mark method overrides, as in many other class-based OO
> languages, should become part of the language definition (i.e. turned into a
> strong error at some point).

A nit: for methods, at least, the ! already produces an error in the
case where the method is not previously defined:

   # object method! m = 3 end;;
  Characters 7-20:
    object method! m = 3 end;;
           ^^^^^^^^^^^^^
  Error: The method `m' has no previous definition

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [Caml-list] [ANN] ppx_monadic.1.0.2, ppx for monadic do, pattern
  2015-01-19  8:56     ` [Caml-list] [ANN] ppx_monadic.1.0.2, ppx for monadic do, pattern Alain Frisch
@ 2015-01-19 21:52       ` Drup
  2015-01-20  3:53         ` Jun Furuse
  0 siblings, 1 reply; 11+ messages in thread
From: Drup @ 2015-01-19 21:52 UTC (permalink / raw)
  To: Alain Frisch, Jun Furuse, oleg, caml-list


> I can appreciate that authors of tools that requires special syntactic 
> support would love to have their new forms look completely native to 
> users, but the counter-argument can be made that keeping an explicit 
> syntax (through the '%' character) for features that are not part of 
> the official language is a good property. (Camlp4/campl5 are still 
> available for people who want to play with the concrete syntax.)

I personally like the explicitness of the syntax a lot. The only issue 
in OCaml currently is that, given the need for retro compatibility, it 
goes sometimes against the terseness. For example the impossibility to 
do " x@foo" instead of "x[@foo]". That's unavoidable, though.

This is, by the way, a point I dislike a lot with ppx_monadic. It abuses 
the native syntax in completely alien ways and without annotations.

I like ppx_monad's syntax quite better due to the fact that it's always 
explicitly a ppx (thanks to %monad) and do not overload the "do_" 
identifier.


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [Caml-list] [ANN] ppx_monadic.1.0.2, ppx for monadic do, pattern
  2015-01-19 21:52       ` Drup
@ 2015-01-20  3:53         ` Jun Furuse
  0 siblings, 0 replies; 11+ messages in thread
From: Jun Furuse @ 2015-01-20  3:53 UTC (permalink / raw)
  To: Drup; +Cc: caml-list, Alain Frisch, oleg

[-- Attachment #1: Type: text/plain, Size: 2995 bytes --]

I know what you wrote, since I always asked myself "isn't it too bizarre?"
when I was writing ppx_monadic. Here are some justifications I made:

The first intension of ppx_monadic is to port my code with pa_monad without
pain. Unfortunately ppx_monad required too many small fixes due to the
following reasons:

·       "perform" needed to be replaced by "begin%monad .. end" or "[%monad
.. ]" which requires closing, which is really pain. Ppx_monad provides
"fun%monad", "match%monad" without closing but they were not always helpful
for me.
·       The pattern "p" of "p <- e" is limited to a variable, since it
overrides the syntax of object member mutation. In addition, I use lots of
monadic binds inside my class methods. Therefore this override is not
acceptable for me.

Secondary, I see the monadic syntax sugar is to reduce the number of key
types, and I accepted some alien syntax weirdness for the purpose. If the
number of key types would not matter, I would be happy with the good old
bind (>>=) chains and would not use "do" at all. People think bind chains
are hard to read but my experience with Jane Street Async tells me it it
not quite. Ppx_monad does not really gain in this point unfortunately: I
was often forced to write "let%monad (x,y) = e in" just for "(x,y) <-- e;".
I write Haskell do-notations daily and wanted to have something comparable
in OCaml.

Anyway, the current OCaml syntax is limited to have do-notation which makes
everyone happy. If there would be a way in OCaml to write "foo e" for some
keyword "foo" which is like "begin" but does not require "end", I would be
pretty happy to change the weird "Option.do_; e" to "foo%Option e". Before
implementing "do_; e", I tried a bit of "[%do] e" but it did not work well
since "[%do] p <-- e" is parsed as "([%do] p) <-- e", not "[%do] (p <-- e)".

Best,
Jun
On 20 Jan, 2015 5:53 am, "Drup" <drupyog+caml@zoho.com> wrote:

>
>  I can appreciate that authors of tools that requires special syntactic
>> support would love to have their new forms look completely native to users,
>> but the counter-argument can be made that keeping an explicit syntax
>> (through the '%' character) for features that are not part of the official
>> language is a good property. (Camlp4/campl5 are still available for people
>> who want to play with the concrete syntax.)
>>
>
> I personally like the explicitness of the syntax a lot. The only issue in
> OCaml currently is that, given the need for retro compatibility, it goes
> sometimes against the terseness. For example the impossibility to do " x@foo"
> instead of "x[@foo]". That's unavoidable, though.
>
> This is, by the way, a point I dislike a lot with ppx_monadic. It abuses
> the native syntax in completely alien ways and without annotations.
>
> I like ppx_monad's syntax quite better due to the fact that it's always
> explicitly a ppx (thanks to %monad) and do not overload the "do_"
> identifier.
>
>

[-- Attachment #2: Type: text/html, Size: 3808 bytes --]

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2015-01-20  3:53 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-01-13 14:23 [Caml-list] [ANN] ppx_monadic.1.0.2, ppx for monadic do, pattern guards and monadic comprehension Jun Furuse
2015-01-14  8:40 ` [Caml-list] [ANN] ppx_monadic.1.0.2, ppx for monadic do, pattern oleg
2015-01-18 14:47   ` Jun Furuse
2015-01-19  7:33     ` [Caml-list] [ANN] ppx_monadic.1.0.2, ppx for monadic do, oleg
2015-01-19  8:34       ` Alain Frisch
2015-01-19  9:06         ` Gabriel Scherer
2015-01-19  9:40           ` Alain Frisch
2015-01-19 16:10             ` Jeremy Yallop
2015-01-19  8:56     ` [Caml-list] [ANN] ppx_monadic.1.0.2, ppx for monadic do, pattern Alain Frisch
2015-01-19 21:52       ` Drup
2015-01-20  3:53         ` Jun Furuse

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).