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 mail2-relais-roc.national.inria.fr (mail2-relais-roc.national.inria.fr [192.134.164.83]) by sympa.inria.fr (Postfix) with ESMTPS id 9DEFA80211 for ; Sun, 22 Oct 2017 15:08:17 +0200 (CEST) Authentication-Results: mail2-smtp-roc.national.inria.fr; spf=None smtp.pra=nathanjmoreau@gmail.com; spf=Pass smtp.mailfrom=nathanjmoreau@gmail.com; spf=None smtp.helo=postmaster@mail-io0-f170.google.com Received-SPF: None (mail2-smtp-roc.national.inria.fr: no sender authenticity information available from domain of nathanjmoreau@gmail.com) identity=pra; client-ip=209.85.223.170; receiver=mail2-smtp-roc.national.inria.fr; envelope-from="nathanjmoreau@gmail.com"; x-sender="nathanjmoreau@gmail.com"; x-conformance=sidf_compatible Received-SPF: Pass (mail2-smtp-roc.national.inria.fr: domain of nathanjmoreau@gmail.com designates 209.85.223.170 as permitted sender) identity=mailfrom; client-ip=209.85.223.170; receiver=mail2-smtp-roc.national.inria.fr; envelope-from="nathanjmoreau@gmail.com"; x-sender="nathanjmoreau@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-io0-f170.google.com) identity=helo; client-ip=209.85.223.170; receiver=mail2-smtp-roc.national.inria.fr; envelope-from="nathanjmoreau@gmail.com"; x-sender="postmaster@mail-io0-f170.google.com"; x-conformance=sidf_compatible IronPort-PHdr: =?us-ascii?q?9a23=3A1xl/ORbCBg0SE5ROxg/JeDP/LSx+4OfEezUN459i?= =?us-ascii?q?sYplN5qZpc2ybnLW6fgltlLVR4KTs6sC0LWG9f24EUU7or+/81k6OKRWUBEEjc?= =?us-ascii?q?hE1ycBO+WiTXPBEfjxciYhF95DXlI2t1uyMExSBdqsLwaK+i76xXcoFx7+LQt4?= =?us-ascii?q?IPjuUs6X1pzvlrOEwIDIewhDmBa6ZLpzKl328VSQ5YEqht5HI6I6zR/M6l5BZ+?= =?us-ascii?q?1SxmogcVeWlgr14sS51JFm+iVU/fkm8pgTf7/9evEeRKBYBTJuFmcv6cT2/U3F?= =?us-ascii?q?RBeP731aV2IMnxNVKw2Z/Ff9RJin4XiyjfZ0xCTPZZ6+drszQzn3qvoyRQ=3D?= =?us-ascii?q?=3D?= X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: =?us-ascii?q?A0AuAQDol+xZf6rfVdFcGwEBAQMBAQEJA?= =?us-ascii?q?QEBFQEBAQECAQEBAQgBAQEBhBhuJweDc5lcgXqCUYV6kAkjhAMBhUsHQxQBAQE?= =?us-ascii?q?BAQEBAQEBARIBAQkLCwgmMYI4BQEeBoI7AQECAgEjBBkBLQsBAwELAQUFCwMKA?= =?us-ascii?q?gIJHQICIQESAQUBChIGExIHiW8DDQgQnj9AjAyBbTqDCQWDeScDCoQDAgYSfYI?= =?us-ascii?q?fggeBUIUTgl6CC4MwgmEFiDcMmGc8gi+FNYgXhHmCcpAvjQyIXBQFH4EVNoF8N?= =?us-ascii?q?CEyUTUGgikJeYFLDgEcgWk+NokOgVUBAQE?= X-IPAS-Result: =?us-ascii?q?A0AuAQDol+xZf6rfVdFcGwEBAQMBAQEJAQEBFQEBAQECAQE?= =?us-ascii?q?BAQgBAQEBhBhuJweDc5lcgXqCUYV6kAkjhAMBhUsHQxQBAQEBAQEBAQEBARIBA?= =?us-ascii?q?QkLCwgmMYI4BQEeBoI7AQECAgEjBBkBLQsBAwELAQUFCwMKAgIJHQICIQESAQU?= =?us-ascii?q?BChIGExIHiW8DDQgQnj9AjAyBbTqDCQWDeScDCoQDAgYSfYIfggeBUIUTgl6CC?= =?us-ascii?q?4MwgmEFiDcMmGc8gi+FNYgXhHmCcpAvjQyIXBQFH4EVNoF8NCEyUTUGgikJeYF?= =?us-ascii?q?LDgEcgWk+NokOgVUBAQE?= X-IronPort-AV: E=Sophos;i="5.43,417,1503352800"; d="scan'208";a="297329936" Received: from mail-io0-f170.google.com ([209.85.223.170]) by mail2-smtp-roc.national.inria.fr with ESMTP/TLS/AES128-GCM-SHA256; 22 Oct 2017 15:08:16 +0200 Received: by mail-io0-f170.google.com with SMTP id 134so17495675ioo.0 for ; Sun, 22 Oct 2017 06:08:16 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:sender:in-reply-to:references:from:date:message-id :subject:to:cc; bh=EFggKaKXvDXkppj5tnVYwaoURwUMgB6C/V/tjj23YKc=; b=U0bPCsntInaZaqRZ3VLkVrgEx0O573mBqNvhXwXckjp6ADh+wycAsk4nAZkwg7HR0r ehob+xNAj3izvvACvPRYPjMIdHx0rK2n2SIXUec3DGj7izMQ2TN9lb/T7WioqVxSA/gT Z/6RrArQkay1fGzij+Ukwpl2gXLgv4Ic8ijDr5oxwH3gS2EcTOpPDcZXGvM77PtqJj5K uIw0sC4eVhQGsYjQABcfuiRZDPycfKfBa9P56I6+IP9FwW6S836dOOsfc7JZYHs5sTi9 RKvITakPAKoM8sSIhBqsVprtF2Vl7uch1pEydYMGvdaWbMpbI095qmgpUU4+LcG87AYe oFUw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:sender:in-reply-to:references:from :date:message-id:subject:to:cc; bh=EFggKaKXvDXkppj5tnVYwaoURwUMgB6C/V/tjj23YKc=; b=A0GBqUiBgzsd7qK1PrHfHnvX7Lg99BprY0WqXkkels8Tqr0dTmCXI9VVFY5awLDMT6 J4Ir/4q/pBpta5WCPoohlPygXkbkTA/WpCd2F5A2B7uqDodN/pWIX6YLbBsgGrEPh/Wn l5CdFDWABoNINjHHXfyEHdiW67F2AirXWDu9EyMsf3glfMN+gWAQ4j6D7qJg0nF40Kn4 /N2r6tOG0r4v9MbCk3ocbGwjBTPpzXVnDZRuxsqavA0VYupvV9I0SdQ6BpyvrXRn7WE/ hThqT4MXoyK4WUsj019n/carT7slcNjwE4WINiZ9aPJB9KPZM2BySGM0D8dm/cJvd3DD HN+A== X-Gm-Message-State: AMCzsaWJb4oT3dVQSN8utMDF1QL/vK6IZl6/VZAMVLyfqTWWTbTVpgHS IVZM6MzCNN6mBjzWaGRlEnUTDvhre/0R6vJO+2ejtA== X-Google-Smtp-Source: ABhQp+SwZ2hA6beUD3THf0JkjmM1z8nIzc7x2SBRCpw87/QAW9HTiLPqmtx8KISlRhft/k0ckWyLmUnZ8wN0dXdbts0= X-Received: by 10.107.162.7 with SMTP id l7mr12836577ioe.135.1508677695021; Sun, 22 Oct 2017 06:08:15 -0700 (PDT) MIME-Version: 1.0 Sender: nathanjmoreau@gmail.com Received: by 10.2.146.195 with HTTP; Sun, 22 Oct 2017 06:08:14 -0700 (PDT) In-Reply-To: <867evnz79e.fsf@gmail.com> References: <86o9p2ywgc.fsf@gmail.com> <867evnz79e.fsf@gmail.com> From: Nathan Moreau Date: Sun, 22 Oct 2017 15:08:14 +0200 X-Google-Sender-Auth: x8J0lmVyQyeXhEwkA5fm2YPV4UU Message-ID: To: Malcolm Matalka Cc: caml users Content-Type: text/plain; charset="UTF-8" Subject: Re: [Caml-list] What if exn was not an open type? > I'm one of those people that uses result everywhere + result monad where > the error case is a polymorphic variant. This lets me get the value of > an open type with power of an exhaustive pattern match check. No > strings needed. > My point is that I cannot avoid exceptions without being very defensive > in my code. A dependency can always start throwing an exception and I > have no tool to help me find that automatically. 1. Polymorphic variants have not always been in the language. 2. Of course you are free to design your APIs the way you want; however, when you accept a dependency, there is no work around reading the documentation to know if exceptions can be thrown. The kind of language that allow you to do that is not ocaml. >> Note that, as there is no break keyword in the language, you tend to >> use exceptions for control flow to avoid rewriting your for loops to >> while loops. > This is exactly what monads and applicatives give you: a way to short > circuit computation when it's no longer needed. Yes, just another tool, for other kind of situations. There are scenarios where exceptions are more appropriate than sophisticated type mechanisms. On 22 October 2017 at 14:39, Malcolm Matalka wrote: > Nathan Moreau writes: > >> Exceptions being an open type allows you to classify failures. >> >> from Unix.ml: >> >> let rec waitpid_non_intr pid = >> try waitpid [] pid >> with Unix_error (EINTR, _, _) -> waitpid_non_intr pid >> >> With a closed type, there is not much you can do to ensure that you >> catch the right type of exception here (matching on strings? seems >> much worse). > > I'm one of those people that uses result everywhere + result monad where > the error case is a polymorphic variant. This lets me get the value of > an open type with power of an exhaustive pattern match check. No > strings needed. > >> >> Note that, as there is no break keyword in the language, you tend to >> use exceptions for control flow to avoid rewriting your for loops to >> while loops. > > This is exactly what monads and applicatives give you: a way to short > circuit computation when it's no longer needed. > >> >> You can write some APIs without exposing exceptions, the same way that >> you can write an API without exposing a global hash-table. > > I'm not sure what you mean here, I have not had to expose exceptions in > any APIs I've written. I don't think they are bad APIs. > >> >> Exceptions are just a tool, that allow you to work around some >> limitations / performance issues / make your life easier. Removing >> them is impossible at this point for compatibility reasons, so all you >> can do is avoid using them if it makes you sad (the same way you avoid >> using some parts of the language when you program in c++ / ecmascript >> / whatever language du jour). > > My point is that I cannot avoid exceptions without being very defensive > in my code. A dependency can always start throwing an exception and I > have no tool to help me find that automatically. > >> >> Nathan >> >> >> On 20 October 2017 at 11:56, Malcolm Matalka wrote: >>> I have a question in two parts: >>> >>> 1. Would this be a good idea? Why? (I'll describe why I think it is) >>> >>> 2. If it were a good idea, is it feasible to do? >>> >>> Full question: >>> >>> Despite exceptions being a part of the language, there is a trend in >>> many libraries to try to avoid using them. While I cannot find it, I >>> recall someone (Daniel maybe?) saying that the standard API advice is >>> that exceptions should not cross API boundaries. >>> >>> The short reason for why people seem to want to avoid exceptions (which >>> I agree with) is that they side step the type system for helping you >>> understand if your code is correct and handles all situations the code >>> might experience. Since the exn type is open, it means that one can add >>> any exception they want so it's not even known what exceptions you might >>> get ahead of time. >>> >>> Another aspect of exceptions, which might be more of my personal >>> experience, is that exceptions tend to be pretty useless after the >>> fact. For example, forgetting to handle a Not_found exception is an >>> exercise in pain. Maybe I'm just bad at this, but many exceptions just >>> aren't that useful. End_of_file is another one that, IMO, makes the >>> program flow pretty awkward and if you have multiple files you're >>> reading from at the same time quite ugly. I tend to use wrappers that >>> give me an option based API. Maybe I just bad at solving these problems >>> though and I'm the problem. >>> >>> The consequence of this is that even though I put a lot of effort in my >>> code trying to avoid exceptions, I can never actually know that I have >>> succeeded unless I'm very defensive and wrap all foreign calls in some >>> exception handling code. There are APIs for this, but if I mess up then >>> I'm in a bad spot. >>> >>> My proposal is that exceptions becomes a closed type and they reflect >>> what Java calls "errors", which are things your program logic should >>> generally not handle but can choose to if it wants to (I think we call >>> these failures in Ocaml). The two specific exceptions I can think if >>> that should exist are: Assertion_failure and Out of Memory. Another one >>> that I think might be nice but is open for debate is a >>> Not_implemented_failure, I use something like this often while building >>> a system. I'm sure there are a few more that people can think of are >>> meaningful, but the point is these represent pretty bad situations that >>> the program logic shouldn't handle except in special situations. >>> >>> Thanks for reading, >>> /Malcolm >>> >>> -- >>> 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