From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Original-To: caml-list@sympa.inria.fr Delivered-To: caml-list@sympa.inria.fr Received: from mail3-relais-sop.national.inria.fr (mail3-relais-sop.national.inria.fr [192.134.164.104]) by sympa.inria.fr (Postfix) with ESMTPS id 6F6307EE89 for ; Wed, 25 Oct 2017 18:38:18 +0200 (CEST) Authentication-Results: mail3-smtp-sop.national.inria.fr; spf=None smtp.pra=ivg@ieee.org; spf=Pass smtp.mailfrom=ivg@ieee.org; spf=None smtp.helo=postmaster@mail-yw0-f176.google.com Received-SPF: None (mail3-smtp-sop.national.inria.fr: no sender authenticity information available from domain of ivg@ieee.org) identity=pra; client-ip=209.85.161.176; receiver=mail3-smtp-sop.national.inria.fr; envelope-from="ivg@ieee.org"; x-sender="ivg@ieee.org"; x-conformance=sidf_compatible Received-SPF: Pass (mail3-smtp-sop.national.inria.fr: domain of ivg@ieee.org designates 209.85.161.176 as permitted sender) identity=mailfrom; client-ip=209.85.161.176; receiver=mail3-smtp-sop.national.inria.fr; envelope-from="ivg@ieee.org"; x-sender="ivg@ieee.org"; x-conformance=sidf_compatible; x-record-type="v=spf1" Received-SPF: None (mail3-smtp-sop.national.inria.fr: no sender authenticity information available from domain of postmaster@mail-yw0-f176.google.com) identity=helo; client-ip=209.85.161.176; receiver=mail3-smtp-sop.national.inria.fr; envelope-from="ivg@ieee.org"; x-sender="postmaster@mail-yw0-f176.google.com"; x-conformance=sidf_compatible IronPort-PHdr: =?us-ascii?q?9a23=3Az3mLjhfymZBlFNBpP3xBCDm5lGMj4u6mDksu8pMi?= =?us-ascii?q?zoh2WeGdxc67YB7h7PlgxGXEQZ/co6odzbGJ4+a9ASQp2tWojjMrSNR0TRgLiM?= =?us-ascii?q?EbzUQLIfWuLgnFFsPsdDEwB89YVVVorDmROElRH9viNRWJ+iXhpRZbIBj0NBJ0?= =?us-ascii?q?K+LpAcaSyp3vj6HhzabOeB1FjyaRZrZ7LRP+7VmA95pevYw3YJwwwRvAuHcARK?= =?us-ascii?q?JzgytKIlSehFy0st2x955L+iJWtuIg/ohHS6qsLIoiSrkNLSovNSga49HsqxLD?= =?us-ascii?q?TBeUri8dTGo+kxdFDk7C9h6sDcS5iTfzqucogHrSBsbxV71hHGn74g=3D=3D?= X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: =?us-ascii?q?A0BoAACBvfBZhrChVdFbGQEBAQEBAQEBA?= =?us-ascii?q?QEBBwEBAQEBFAEBAQEBAQEBAQEBBwEBAQEBgwaBEm4nB4NzgTaXdIF6glGVGwN?= =?us-ascii?q?cCiOEAwGBFAKEZgdDFAEBAQEBAQEBAQEBEgEBAQgLCwgoL4I4BQEeBoI7AQEBA?= =?us-ascii?q?wEjBBkBASYGCwEECwsLDQ0dAgIiEgEFAQoSBhMSCYltAwgFCBCcfkCLIWuBbTq?= =?us-ascii?q?DCAEBBYQtA4M5AQEBAQYBAQEBAQEBARgIEoMcggeBUIRiMYUygmeCYYg8DJAzi?= =?us-ascii?q?H2HZY0SgnKQNJVtFAUfgRUPJ4F8gQcISTUGgikJghoqDxAMggMkNgGKNIFVAQE?= =?us-ascii?q?B?= X-IPAS-Result: =?us-ascii?q?A0BoAACBvfBZhrChVdFbGQEBAQEBAQEBAQEBBwEBAQEBFAE?= =?us-ascii?q?BAQEBAQEBAQEBBwEBAQEBgwaBEm4nB4NzgTaXdIF6glGVGwNcCiOEAwGBFAKEZ?= =?us-ascii?q?gdDFAEBAQEBAQEBAQEBEgEBAQgLCwgoL4I4BQEeBoI7AQEBAwEjBBkBASYGCwE?= =?us-ascii?q?ECwsLDQ0dAgIiEgEFAQoSBhMSCYltAwgFCBCcfkCLIWuBbTqDCAEBBYQtA4M5A?= =?us-ascii?q?QEBAQYBAQEBAQEBARgIEoMcggeBUIRiMYUygmeCYYg8DJAziH2HZY0SgnKQNJV?= =?us-ascii?q?tFAUfgRUPJ4F8gQcISTUGgikJghoqDxAMggMkNgGKNIFVAQEB?= X-IronPort-AV: E=Sophos;i="5.43,432,1503352800"; d="scan'208,217";a="242362753" Received: from mail-yw0-f176.google.com ([209.85.161.176]) by mail3-smtp-sop.national.inria.fr with ESMTP/TLS/AES128-GCM-SHA256; 25 Oct 2017 18:37:45 +0200 Received: by mail-yw0-f176.google.com with SMTP id l32so506145ywh.13 for ; Wed, 25 Oct 2017 09:37:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ieee-org.20150623.gappssmtp.com; s=20150623; h=mime-version:in-reply-to:references:from:date:message-id:subject:to :cc; bh=MaV2zLWk+fB+BfAoetW05j3kvGjvuOnljsyfJj+XILE=; b=YUxgUeqXqUXTYtIZFqKXjYKeHIjxiEH1PO/T7HMvri7u/IEzV/RO5JT3bs//mqVd+Y zysFYXTJrPGuZM6BBvT9nJx4KYhlMhH+24fLFmdrXjhWR3Ex6Ju0amAk1y9yi1JkxOn6 dwY4JkEBY5jcv5nWEPfQJDqPQpd0mlAciP/aDwkT60WHcG6RggoTCqR3YlANWIbyb5u8 FIqbYXtp9bTH50dasye5kSmsMpjaqIjVRWWNFSQo41BEMZWTPHj17HzsunbDEn4yI8XX ldCNNVaEw48NwGwKFy560X4O/o1qM5Ydk+ykFKZpLn5AhjxcldbhFVdzd3WulenyHJQD jeoQ== 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=MaV2zLWk+fB+BfAoetW05j3kvGjvuOnljsyfJj+XILE=; b=nG+vathmH22UpDfdDJGcCSm3+mkBWDa9HqMmmQN2IChLOM5b/ziMMJcOL2oNDIbGz/ rxxCVPN6Y78nic3wnv9wf2UPPvAGEVBSWgRBJNQs28m3TJTts8ml1zA/cRcWtjnf2G/Y s5Mf/YN1aEGRw1MpvDvY77WIxq6sW+yFrYQr5+sawVPjJLiKJEAJwOyb1zVhqfygZ9F/ qnERK+1bZDiXSrq1fBXKbceBlJNtgOxx1h8er97KEod8TjH4PyMc4eAm21oy5MSlNj4J DiQFQK8NnIGHK3VGZNyq8c2noE+17tv/EKNQ+qzaDSdjygCZCmrF2eImOTG3Ox994jo9 AAGQ== X-Gm-Message-State: AMCzsaVHkS8MiEJUEXSaM45IF5BEImdmJurWmi4CC3IaR3vUSoWlInVy PIeEg0x+/CWT50hlD5BRm27dGtr1OwOtp2c7R1e2Mg== X-Google-Smtp-Source: ABhQp+Q1G5ceUZ6TN2xpdc/nwOVyzFM4I/lj1t68iXZxnw3esbdtHgytal6A/tuMppgiy7PVI1AUrWfsu/zIwIrxS/E= X-Received: by 10.37.199.204 with SMTP id w195mr1635705ybe.168.1508949464121; Wed, 25 Oct 2017 09:37:44 -0700 (PDT) MIME-Version: 1.0 Received: by 10.129.174.33 with HTTP; Wed, 25 Oct 2017 09:37:43 -0700 (PDT) In-Reply-To: <20171025145247.5rxad7qixivzn4vj@annexia.org> References: <86o9p2ywgc.fsf@gmail.com> <20171020113815.GD32138@nunchakus.loria.fr> <20171024133026.uovvzdbnamnzoknv@annexia.org> <20171025083530.gvggcenrgxolduse@annexia.org> <20171025145247.5rxad7qixivzn4vj@annexia.org> From: Ivan Gotovchits Date: Wed, 25 Oct 2017 12:37:43 -0400 Message-ID: To: "Richard W.M. Jones" Cc: Philippe Veber , "Petter A. Urkedal" , ptoscano@redhat.com, caml users Content-Type: multipart/alternative; boundary="94eb2c1480eacb4262055c61ace1" Subject: Re: [Caml-list] What if exn was not an open type? --94eb2c1480eacb4262055c61ace1 Content-Type: text/plain; charset="UTF-8" Well, we have the same constraint, as we are trying to write code, that is understandable by students, who may not know OCaml. However, we are also trying to enforce pure functional programming, that, we believe, teaches the right thinking and produces programs that are easier to understand. When you need to write system code or any code that deals with effects, monads become inevitable sooner or later unless you're willing to use the escape hatch of mutability. The monadic code usually scares people (and the Continuation monad usually scared even the bravest). However, there are ways to deal with it. You can use different syntax extensions, like the [ppx_let][1], that is very light, [ppx_monadic][2], that provides a real do-notation so that you can write your code in the true imperative style. You can even rely on camlp4 or camlp5 do provide you a full support for the do-notation. I, myself, do not really like the do-notation (even in Haskell, or F#) because I believe, that it hides the real notion of computation. So, we stick to the regular syntax of OCaml. I'm always explaining the concept of Monad using the imperative C-like language, by pointing that a monad is just a way to parametrize your semicolon operator. So the idea is not really from functional programming and should be understandable by someone who has only an imperative programming background. With all this said, I think, that your code should rely on exceptions, not the monads. Since libguestfs is totally imperative library, that deals with imperative primitives, using OCaml exceptions is a perfectly valid solution. You are already dealing with primitives that bear hidden effects, so your computations are not pure on the first hand, thus adding exceptions will not add anything more to it. The essence of each monad is the `run` function, that evaluates monadic operations (orders) and produces an explicit state. Since you can't really reify the run function in your case, using monads will only obscure things. To make the long story short, you should use monad only with pure code in cases when you can represent effects as an OCaml value. Mixing imperative code with monadic code is the worst thing one can imagine - as you will deal with wolves in lamb's skins, functions that pretend to be pure while in fact, they are inherently effectful. [1]: https://blog.janestreet.com/let-syntax-and-why-you-should-use-it/ [2]: https://bitbucket.org/camlspotter/ppx_monadic On Wed, Oct 25, 2017 at 10:52 AM, Richard W.M. Jones wrote: > On Wed, Oct 25, 2017 at 11:12:26AM +0200, Philippe Veber wrote: > > isn't that a context where error monads do a pretty decent job? > > > > check_some_problem () >>= fun () -> > > check_some_other_problem () >>= fun () -> > > expect_something () >>= fun something -> > > finally_do something > > Right, but the main problem with monads is they scare off ordinary > programmers :-/ > > When writing open source code in OCaml we have two -- conflicting -- > goals. Goal #1 is to write elegant, short, fast, safe code, and OCaml > really wins there. Goal #2 is to attract outside programmers to work > on the project, and that's pretty hard with OCaml code, but we manage > it. But it gets much much harder if we use any concept which strays > too far from imperative/C-like code. You will see if you look through > our codebase that it's pretty imperative and -- quite deliberately -- > avoids doing strange stuff with modules, functors or really anything > which is "excessively functional" (sorry for the loose term, but I > hope you know what I mean :-). > > However when I have the time after my current conference I will try > to rewrite the code I linked to with monads to see if I can make > something which is both simple and readable. > > Thanks, > > Rich. > > -- > 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 > --94eb2c1480eacb4262055c61ace1 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
Well, we have the same constraint, as we are trying to wri= te code, that is understandable by students, who may not know OCaml. Howeve= r, we are also trying to enforce pure functional programming, that, we beli= eve, teaches the right thinking and produces programs that are easier to un= derstand. When you need to write system code or any code that deals with ef= fects, monads become inevitable sooner or later unless you're willing t= o use the=C2=A0escape hatch of mutability. The monadic code=C2=A0usually sc= ares people (and the Continuation monad usually scared even the bravest). H= owever, there are ways to deal with it. You can use different syntax extens= ions, like the [ppx_let][1], that is very light, [ppx_monadic][2], that pro= vides a real do-notation so that you can write your code in the true impera= tive style. You can even rely on camlp4 or camlp5 do provide you a full sup= port for the do-notation.=C2=A0

I, myself, do not really= like the do-notation (even in Haskell, or F#) because I believe, that it h= ides the real notion of computation. So, we stick to the regular syntax of = OCaml. I'm always explaining the concept of Monad using the imperative = C-like language, by pointing that a monad is just a way to parametrize your= semicolon operator. So the idea is not really from functional programming = and should be understandable by someone who has only an imperative programm= ing background.=C2=A0

With all this said, I think,= that your code should rely=C2=A0on exceptions, not the monads. Since libgu= estfs=C2=A0is totally imperative library, that deals with imperative primit= ives, using OCaml exceptions is a perfectly valid solution. You are already= dealing with primitives that bear hidden effects, so your computations are= not pure on the first hand, thus adding exceptions will not add anything m= ore to it. The essence of each monad is the `run` function, that evaluates = monadic operations (orders) and produces an explicit state. Since you can&#= 39;t really reify the run function in your case, using monads will only obs= cure things. To make the long story short, you should use monad only with p= ure code in cases when you can represent effects as an OCaml value. Mixing = imperative code with monadic code is the worst thing one can imagine - as y= ou will deal with wolves in lamb's skins, functions that pretend to be = pure while in fact, they are inherently effectful.=C2=A0

=


On Wed, Oct 25, 2017 at 10:52 AM, Richard W.M. Jones <rich@annexia.or= g> wrote:
= On Wed, Oct 25, 2017 at 11:12:26AM +0200, Philippe Veber wrote:
> isn't that a context where error monads do a pretty decent job?
>
> check_some_problem () >>=3D fun () ->
> check_some_other_problem () >>=3D fun () ->
> expect_something () >>=3D fun something ->
> finally_do something

Right, but the main problem with monads is they scare off ordinary programmers :-/

When writing open source code in OCaml we have two -- conflicting --
goals.=C2=A0 Goal #1 is to write elegant, short, fast, safe code, and OCaml=
really wins there.=C2=A0 Goal #2 is to attract outside programmers to work<= br> on the project, and that's pretty hard with OCaml code, but we manage it.=C2=A0 But it gets much much harder if we use any concept which strays too far from imperative/C-like code.=C2=A0 You will see if you look through=
our codebase that it's pretty imperative and -- quite deliberately -- avoids doing strange stuff with modules, functors or really anything
which is "excessively functional" (sorry for the loose term, but = I
hope you know what I mean :-).

However when I have the time after my current conference I will try
to rewrite the code I linked to with monads to see if I can make
something which is both simple and readable.

Thanks,

Rich.

--
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

--94eb2c1480eacb4262055c61ace1--