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 C6A0D7F0A6 for ; Thu, 20 Aug 2015 21:19:16 +0200 (CEST) Received-SPF: None (mail2-smtp-roc.national.inria.fr: no sender authenticity information available from domain of flux-caml@inside.org) identity=pra; client-ip=130.230.4.42; receiver=mail2-smtp-roc.national.inria.fr; envelope-from="flux@modeemi.fi"; x-sender="flux-caml@inside.org"; x-conformance=sidf_compatible Received-SPF: None (mail2-smtp-roc.national.inria.fr: no sender authenticity information available from domain of flux@modeemi.fi) identity=mailfrom; client-ip=130.230.4.42; receiver=mail2-smtp-roc.national.inria.fr; envelope-from="flux@modeemi.fi"; x-sender="flux@modeemi.fi"; x-conformance=sidf_compatible Received-SPF: None (mail2-smtp-roc.national.inria.fr: no sender authenticity information available from domain of postmaster@mail.cs.tut.fi) identity=helo; client-ip=130.230.4.42; receiver=mail2-smtp-roc.national.inria.fr; envelope-from="flux@modeemi.fi"; x-sender="postmaster@mail.cs.tut.fi"; x-conformance=sidf_compatible X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A0BzAQACJ9ZVnCoE5oJdFoNZRCWpbwaVYogDAQEBAQEBEgEBAQEBCBQJT4QkAQQBJ1cLCyElDwEEDQtEiBkDCggNyk8NhgOGIIUzgkUKhm4FjGNwh1aFBYJsgxGBbYFKRoNojQuDT4NpgXABCwGCKW4BgksBAQE X-IPAS-Result: A0BzAQACJ9ZVnCoE5oJdFoNZRCWpbwaVYogDAQEBAQEBEgEBAQEBCBQJT4QkAQQBJ1cLCyElDwEEDQtEiBkDCggNyk8NhgOGIIUzgkUKhm4FjGNwh1aFBYJsgxGBbYFKRoNojQuDT4NpgXABCwGCKW4BgksBAQE X-IronPort-AV: E=Sophos;i="5.15,716,1432591200"; d="scan'208";a="174342537" Received: from mail.cs.tut.fi ([130.230.4.42]) by mail2-smtp-roc.national.inria.fr with SMTP; 20 Aug 2015 21:19:15 +0200 Received: from amavis2.cs.tut.fi (amavis2.cs.tut.fi [130.230.4.70]) by mail.cs.tut.fi (Postfix) with ESMTP id 2AFBDF4F for ; Thu, 20 Aug 2015 22:19:14 +0300 (EEST) Received: from mail.cs.tut.fi ([130.230.4.42]) by amavis2.cs.tut.fi (amavis2.cs.tut.fi [130.230.4.70]) (amavisd-maia, port 10024) with ESMTP id 08984-26 for ; Thu, 20 Aug 2015 22:19:13 +0300 (EEST) Received: from modeemi.modeemi.fi (modeemi.modeemi.fi [130.230.72.134]) by mail.cs.tut.fi (Postfix) with SMTP id 65108F4D for ; Thu, 20 Aug 2015 22:19:13 +0300 (EEST) Received: from coffee.modeemi.fi (coffee.modeemi.fi [130.230.72.140]) by modeemi.modeemi.fi (Postfix) with ESMTP id 23D503AD7E for ; Thu, 20 Aug 2015 22:19:13 +0300 (EEST) Received: by coffee.modeemi.fi (Postfix, from userid 17990) id 13A892D6088; Thu, 20 Aug 2015 22:19:13 +0300 (EEST) From: Erkki Seppala To: caml-list@yquem.inria.fr References: <55BF75F6.1040006@bioquant.uni-heidelberg.de> <8E1A640CE3374EB492981ADB0A2DA5C6@erratique.ch> <20150804092633.GC5689@frosties> <5C2023F4AF0549F58F3E4C9A6F8ABE84@erratique.ch> <20150814105551.GD31364@frosties> <55CDD0F2.1090200@zoho.com> <20150818111134.GA11154@frosties> <55D4F1DB.5090906@polychoron.fr> <55D58A7F.5030009@inria.fr> Date: Thu, 20 Aug 2015 22:19:12 +0300 In-Reply-To: (Yotam Barnoy's message of "Thu, 20 Aug 2015 10:03:50 -0700") Message-ID: User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.3 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain X-Virus-Scanned: Maia Mailguard 1.0.2 Subject: Re: [Caml-list] destructive local opens Hi, Couple points I felt the need to address :). Yotam Barnoy writes: > A lot of great ideas here. I want to comment on many of them, so > please bear with me while I summarize some of the points in the > process. Hopefully this will also help anybody new to the discussion, > which has become extremely long. > > - Local opens are somewhat of an anti-pattern in OCaml, because they're > usually used in places where you have the same names defined in > multiple modules: While this is certainly a very popular use case in particular when dealing with operators, I find myself using the local 'let open' form very often in other contexts. In fact, I don't ever seem to find myself using it for redefining identifiers. Examples I grepped from my sources, admittedly some obsoleted by the new disambiguation feature: 2014/device-table/layout.ml: let open Containers_misc.PrintBox in hlist ~bars:false [box; text (String.make n ' ')] 2014/TinyGUploader/src/upload.ml: let open Gcode.Parser in match input with | Move { move_reg = (G0 | G1); move_pos = at } -> .. 2014/TinyGUploader/src/upload.ml: let open ANSITerminal in let progress = float n /. float input_nlines in move_bol (); let time_left = (Unix.gettimeofday () -. t0) /. progress in let time_finished = t0 +. time_left in if not common_options.co_verbose then ( printf [Bold; green; on_default] "%2.1f%%" (100.0 *. progress); printf [default] "complete, %d/%d, ETA " n input_nlines; printf [Bold; green; on_default] "%s (%s)" (Utils.human_eta (int_of_float time_left)) (Utils.string_of_time time_finished); erase Eol; ) 2014/TinyGUploader/src/align.ml: let render_gcode cairo mapping_matrix gcode = let open Cairo in set_line_width cairo (length_in_matrix mapping_matrix 3.0); set_line_cap cairo ROUND; set_line_join cairo JOIN_ROUND; .. 2014/TinyGUploader/src/align.ml: let open Bigarray in let open Array1 in let ba = create int8_unsigned c_layout (String.length str) in for c = 0 to String.length str - 1 do ba.{c} <- Char.code str.[c] done; ba Many of these would be more verbose without using a local open, the only non-verbose alternate being opening the modules for the whole remaining module. Using the local open gives the person reading the code a heavy hint that this code will be dealing a lot with the concepts of that module. > The problem is, if you ever change one of the modules to include > another function that wasn't expected originally (for example, N now > includes *), you now have subtle bugs breaking your code in completely > separate files from the ones you were editing, and the type system > can't necessarily do anything to catch these errors. I think this is an instance where theory and practice don't match: in practice, I don't ever remember having witnessed such a bug. > - Similar languages to OCaml (such as Haskell) outlaw having the same > name defined twice in the same scope. OCaml only issues a warning. > IMO, this warning should be turned into an error. I don't think these is such a warning in general. I referred to http://caml.inria.fr/pub/docs/manual-ocaml/comp.html . Do you mean only definitions, not expression scopes? I in fact find it quite convenient to be able to write: let furbulation = acquire_value () in let furbulation, brightness = process_step_1 furbulation in let furbulation, volume = process_step_2 (brightness / 2) furbulation in .. The alternative of renaming intermediate steps can result in mistakes if the order of steps is to be changed, as can happen when doing signal processing algorithms in an explorative fashion. Cheers, -- _____________________________________________________________________ / __// /__ ____ __ http://www.modeemi.fi/~flux/\ \ / /_ / // // /\ \/ / \ / /_/ /_/ \___/ /_/\_\@modeemi.fi \/