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 7ABCC7F168 for ; Thu, 27 Aug 2015 12:35:33 +0200 (CEST) IronPort-PHdr: 9a23:ngrRFRZin2rcKYGrYa5EJ4f/LSx+4OfEezUN459isYplN5qZpci6bnLW6fgltlLVR4KTs6sC0LqN9f68EjZZqb+681k8M7V0HycfjssXmwFySOWkMmbcaMDQUiohAc5ZX0Vk9XzoeWJcGcL5ekGA6ibqtW1aJBzzOEJPK/jvHcaK1oLsh7v0pcGYOVwArQH+SI0xBS3+lR/WuMgSjNkqAYcK4TyNnEF1ff9Lz3hjP1OZkkW0zM6x+Jl+73YY4Kp5pIYTGZn9Kq8xSLgdCDU9L0g04tfqvF/NV1ih/HwZB18RlxNJBUDv5Qv2WYq55jH9s+N83m+QNNf6Sq0cWDK47q4tRgW+23RPDCIw7GyC0p84t6lcuh/0/xE= Authentication-Results: mail2-smtp-roc.national.inria.fr; spf=None smtp.pra=romain.bardou@inria.fr; spf=None smtp.mailfrom=romain.bardou@inria.fr; spf=None smtp.helo=postmaster@9.mo68.mail-out.ovh.net Received-SPF: None (mail2-smtp-roc.national.inria.fr: no sender authenticity information available from domain of romain.bardou@inria.fr) identity=pra; client-ip=46.105.78.111; receiver=mail2-smtp-roc.national.inria.fr; envelope-from="romain.bardou@inria.fr"; x-sender="romain.bardou@inria.fr"; x-conformance=sidf_compatible Received-SPF: None (mail2-smtp-roc.national.inria.fr: no sender authenticity information available from domain of romain.bardou@inria.fr) identity=mailfrom; client-ip=46.105.78.111; receiver=mail2-smtp-roc.national.inria.fr; envelope-from="romain.bardou@inria.fr"; x-sender="romain.bardou@inria.fr"; x-conformance=sidf_compatible Received-SPF: None (mail2-smtp-roc.national.inria.fr: no sender authenticity information available from domain of postmaster@9.mo68.mail-out.ovh.net) identity=helo; client-ip=46.105.78.111; receiver=mail2-smtp-roc.national.inria.fr; envelope-from="romain.bardou@inria.fr"; x-sender="postmaster@9.mo68.mail-out.ovh.net"; x-conformance=sidf_compatible X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A0BdAQC55t5VnG9OaS5dh3u/GYM4AgiBKDsRAQEBAQEBAQEQAQEBAQEGDQkJIS6CHYIHAQEDASMPAQVABgsLGgIFFgsCAgkDAgECAUUTCAIQiBIMAbMTlQ4BCyCBIokagSWEInAxgjiBQwEElT2Mc4FKlSuDa4QngzwBAQE X-IPAS-Result: A0BdAQC55t5VnG9OaS5dh3u/GYM4AgiBKDsRAQEBAQEBAQEQAQEBAQEGDQkJIS6CHYIHAQEDASMPAQVABgsLGgIFFgsCAgkDAgECAUUTCAIQiBIMAbMTlQ4BCyCBIokagSWEInAxgjiBQwEElT2Mc4FKlSuDa4QngzwBAQE X-IronPort-AV: E=Sophos;i="5.17,422,1437429600"; d="scan'208";a="175037090" Received: from 9.mo68.mail-out.ovh.net ([46.105.78.111]) by mail2-smtp-roc.national.inria.fr with ESMTP/TLS/ADH-AES256-GCM-SHA384; 27 Aug 2015 12:35:32 +0200 Received: from mail138.ha.ovh.net (b6.ovh.net [213.186.33.56]) by mo68.mail-out.ovh.net (Postfix) with SMTP id 3EA7CFFA6CB for ; Thu, 27 Aug 2015 12:35:32 +0200 (CEST) Received: from localhost (HELO queueout) (127.0.0.1) by localhost with SMTP; 27 Aug 2015 12:35:32 +0200 Received: from amontsouris-652-1-157-244.w86-212.abo.wanadoo.fr (HELO ?192.168.1.15?) (romain@bardou.fr@86.212.76.244) by ns0.ovh.net with SMTP; 27 Aug 2015 12:35:27 +0200 Message-ID: <55DEE7E5.1020104@inria.fr> Date: Thu, 27 Aug 2015 12:35:17 +0200 From: Romain Bardou User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Icedove/31.7.0 MIME-Version: 1.0 To: caml-list@inria.fr References: <1C02B1E2-D17D-4008-998E-B17048C62DFA@gmail.com> In-Reply-To: Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 8bit X-Ovh-Tracer-Id: 16712576743594494496 X-Ovh-Remote: 86.212.76.244 (amontsouris-652-1-157-244.w86-212.abo.wanadoo.fr) X-Ovh-Local: 213.186.33.20 (ns0.ovh.net) X-OVH-SPAMSTATE: OK X-OVH-SPAMSCORE: 0 X-OVH-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrfeekfedrieegucetufdoteggucfrrhhofhhilhgvmecuqfggjfenuceurghilhhouhhtmecufedttdenuc X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: 0 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrfeekfedrieegucetufdoteggucfrrhhofhhilhgvmecuqfggjfenuceurghilhhouhhtmecufedttdenuc X-Validation-by: romain@bardou.fr Subject: Re: [Caml-list] We need a rich standard library distributed with OCaml, really > There remain the issue that having several "base libraries" risks > fragmenting the community in incompatible islands of software usage. > It is true that shoving stuff into the compiler distribution is a way > to resolve this excess of choice by authority, but it is manifest that > no one currently wants to bear this authority and the responsibilities > that come with it. (Except possibly on very localized issues, as the > `result` type that is being integrated in 4.03+dev). > > I think the way forward is to have smaller independent packages that > do not require so large a buy-in and consensus. We could have *one* > package that provides many useful functions for lists, and one > separate package with many useful functions for strings. In this style > Daniel Bünzli beautifully documented small packages, or David Sheets > doing-one-thing libraries would be role models to follow. This wasn't > an option when Batteries or Core were started, because the packaging > story was too confused, but it is now and we should take advantage of > it. Given time (and help?) I hope to evolve Batteries towards this > model. I agree about smaller, independent packages. This is a very general API design principle: avoid coupling (the fact that using a module implies using another). This may be the main reason I avoid external libraries. For instance, Martin Jambon's Yojson depends on biniou, cppo and easy-format. I believe Martin is an awesome programmer but this particular point just baffles me as there is absolutely no need for *any* external dependency to solve such a simple problem (JSON parsing, pretty-printing and AST constructors). I understand that Martin wants to reuse its own code and be able to integrate Yojson easily with other libraries of his, and that is great. For him and users of his other libraries. Not for those who just want a JSON parser and have had to install all dependencies manually on Windows. Lwt is another example. While it is obviously an awesome library, using it is not a decision to take lightly. There is something that I love about Yojson though: the main type (the JSON AST) uses polymorphic variants. This means that it is possible to write a library which is capable of integrating with Yojson without actually depending on it. You just copy-paste the type definition and use it. Then your user can use any JSON parser and printer. He can use Yojson, or another library which happens to use a supertype. Worst case scenario, he takes 5 minutes to write functions to convert the Yojson AST to and from another JSON library's type. Writing code which can integrate with another library without actually depending on it will scare users less and make more people use your library. Here are some more examples. - Use standard library types like option, list, or array instead of trying to generalize to some enumeration concept. - If the previous point is not possible because the enumeration is too big to be constructed before use, consider providing an iter function. Such a function can be easily used with a library such as Simon Cruanes' sequence library, but your library does not need to depend on it. - Functors allow your code to depend on any implementation. Unfortunately functors are a pain both to write and to use. One of the promises of the module system is to be able to replace a module with another one with the same signature, but how many times have you seen that being done in practice (without functors)? The build system and namespace issues do not help you to do that. Especially if you want to replace the dependency of a third-party library. Say, use a library which depends on Lwt but make it use your implementation of Lwt instead, without having to manually reconfigure and recompile the library, just by using the compiled version from opam. This is even harder if your Lwt implementation does not provide the same interface as Lwt except for the part which is used by the library. Coupling is not bad just between libraries. For instance, you may be tempted to write a function "split_list" to split a string into a list, by using another function "split_pair" which splits a string into a pair (at the first occurrence only). But an independent implementation of split_list is much more efficient (if split_pair copies the two substrings), can more easily be sent to the toplevel for testing, and can be copy-pasted easily between programs (until you decide to put it into a library). But more importantly, if you need to change "split_pair" for some reason, you will have to check all functions which use it, including "split_list". Yes, sharing code allows to share bug fixes. But it also makes it easier to break stuff accidentally. -- Romain Bardou