From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail4-relais-sop.national.inria.fr (mail4-relais-sop.national.inria.fr [192.134.164.105]) by walapai.inria.fr (8.13.6/8.13.6) with ESMTP id q3BAQM6a014353 for ; Wed, 11 Apr 2012 12:26:27 +0200 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AmADAKNbhU/ZSMDyfGdsb2JhbABFuUYiAQELCQsHFAUkggkBAQQBJwsBSwsLISUPAQQoNId/AQkJsEcfiguOG4MkBJtLjUA X-IronPort-AV: E=Sophos;i="4.75,404,1330902000"; d="scan'208";a="139804804" Received: from fmmailgate04.web.de ([217.72.192.242]) by mail4-smtp-sop.national.inria.fr with ESMTP; 11 Apr 2012 12:26:27 +0200 Received: from moweb001.kundenserver.de (moweb001.kundenserver.de [172.19.20.114]) by fmmailgate04.web.de (Postfix) with ESMTP id 929B275C4ED5 for ; Wed, 11 Apr 2012 12:26:26 +0200 (CEST) Received: from frosties.localnet ([95.208.118.96]) by smtp.web.de (mrweb002) with ESMTPA (Nemesis) id 0M5Oql-1S68GT107r-00zXBI; Wed, 11 Apr 2012 12:26:26 +0200 Received: from mrvn by frosties.localnet with local (Exim 4.77) (envelope-from ) id 1SHukr-00030C-OB for caml-list@inria.fr; Wed, 11 Apr 2012 12:26:25 +0200 From: Goswin von Brederlow To: caml-list@inria.fr In-Reply-To: <91EB03E665BB4D7BB3CC65466956C79B@erratique.ch> ("Daniel Buenzli"'s message of "Thu, 5 Apr 2012 11:50:17 +0200") References: <874nsy1rcd.fsf@frosties.localnet> <91EB03E665BB4D7BB3CC65466956C79B@erratique.ch> User-Agent: Gnus/5.110009 (No Gnus v0.9) XEmacs/21.4.22 (linux, no MULE) Date: Wed, 11 Apr 2012 12:26:25 +0200 Message-ID: <87vcl6d0oe.fsf@frosties.localnet> MIME-Version: 1.0 Content-Type: text/plain; charset=iso-8859-1 Content-Transfer-Encoding: 8bit X-Provags-ID: V02:K0:RGnw0KxXNT8X4u8OM+bYu0KsF6yrY8+bFDBbVSPybBq zFj/FevWY3aLVUUqkseMFNoFhynha0eQstPnWeKIwcV51/bNNH WjrrwQuj/Leho8vTQRLcyYxV6ZtDl4Fp7XYtPzRBz0UiMF4LOI 8d2X0Bugw4rzXzuw2DaZTBfGCpFpYyyq9j7z1RkV37UlI9t3ak Y7mJzpIKIGaDbdjruFBGQ== Subject: Re: [Caml-list] exn vs option Daniel Bünzli writes: > Le jeudi, 5 avril 2012 à 11:05, Goswin von Brederlow a écrit : >> If you are writing a module then consider providing both flavours for >> functions, one with exceptions and one with options. Even if you only do >> something like this: > > > I don't think it's a rule that should be applied consistently, I don't like libraries that provide tons of convenience functions, too many names. If you stick with the option type (or variant cases) the user can quickly wrap the function if it needs an exception (or vice-versa but I prefer it that way since it's then documented by the function signature and is in my opinion better behaved in general). > > However in the particular case of finding something in a data structure where the user could be confronted with a situation where he can prove that the datum will be found I think it's justified to provide both flavours. For these cases, in my own code I settled on the following pattern : > > val find : 'a t -> key -> 'a option > (** [find d k] is the value bound to [k] in [d], if any. *) > > val get : 'a t -> key -> 'a > (** [get d k] is like {!find} but raises [Invalid_argument] if [k] is not bound in [d]. *) That pattern works well if you have just one or few such functions and can think of nice names to differentiate them. Otherwise submodules are usefull: module Foo = Foo.Options or module Foo = Foo.Exceptions Foo.do_things () or open Foo.Options do_things () The option and exception raising functions would be named the same and the user selects one or the other by selecting a submodule. As said, it is usualy a matter of taste and the users tastes might differ from the module authors taste. By providing an option and execption flavour of a function (by different names or submodules hardly matters) the user can use what he likes as opposed to what the modules author imposes on him. MfG Goswin