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 201567FD27 for ; Tue, 10 Nov 2015 11:26:15 +0100 (CET) IronPort-PHdr: 9a23:codZqhYehHVAIMuz+sa+BrD/LSx+4OfEezUN459isYplN5qZpci6bnLW6fgltlLVR4KTs6sC0LqL9fy9EjVaqb+681k8M7V0HycfjssXmwFySOWkMmbcaMDQUiohAc5ZX0Vk9XzoeWJcGcL5ekGA6ibqtW1aJBzzOEJPK/jvHcaK1oLsh730p8CYOl8ArQH+SI0xBS3+lR/WuMgSjNkqAYcK4TyNnEF1ff9Lz3hjP1OZkkW0zM6x+Jl+73YY4Kp5pIYTGZn9Kq8xSLgdCDU9L0g04tfqvF/NV1ih/HwZB18RlxNJBUDv5Qv2WYq55jH9s+N83gGRJ9zuUbcvVDK54uFgTxq+23RPDCIw7GyC0p84t6lcuh/0/xE= Authentication-Results: mail2-smtp-roc.national.inria.fr; spf=None smtp.pra=romain@cryptosense.com; spf=None smtp.mailfrom=romain@cryptosense.com; spf=None smtp.helo=postmaster@14.mo4.mail-out.ovh.net Received-SPF: None (mail2-smtp-roc.national.inria.fr: no sender authenticity information available from domain of romain@cryptosense.com) identity=pra; client-ip=46.105.40.29; receiver=mail2-smtp-roc.national.inria.fr; envelope-from="romain@cryptosense.com"; x-sender="romain@cryptosense.com"; x-conformance=sidf_compatible Received-SPF: None (mail2-smtp-roc.national.inria.fr: no sender authenticity information available from domain of romain@cryptosense.com) identity=mailfrom; client-ip=46.105.40.29; receiver=mail2-smtp-roc.national.inria.fr; envelope-from="romain@cryptosense.com"; x-sender="romain@cryptosense.com"; x-conformance=sidf_compatible Received-SPF: None (mail2-smtp-roc.national.inria.fr: no sender authenticity information available from domain of postmaster@14.mo4.mail-out.ovh.net) identity=helo; client-ip=46.105.40.29; receiver=mail2-smtp-roc.national.inria.fr; envelope-from="romain@cryptosense.com"; x-sender="postmaster@14.mo4.mail-out.ovh.net"; x-conformance=sidf_compatible X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A0CGAADkxEFWnB0oaS5ehA5vwDcZhXcCCIE0PBABAQEBAQEBARABAQEBAQgLCQkhLoIugggBAQQjBAsBBREvEQsYAgIFFgsCAgkDAgECAUUTCAIVAogXAbFbkF8MASCBAYkoI4EGhDsBARxogjSBRAWHRIVXiS2OBJtoOIJSgV5xg22BQQEBAQ X-IPAS-Result: A0CGAADkxEFWnB0oaS5ehA5vwDcZhXcCCIE0PBABAQEBAQEBARABAQEBAQgLCQkhLoIugggBAQQjBAsBBREvEQsYAgIFFgsCAgkDAgECAUUTCAIVAogXAbFbkF8MASCBAYkoI4EGhDsBARxogjSBRAWHRIVXiS2OBJtoOIJSgV5xg22BQQEBAQ X-IronPort-AV: E=Sophos;i="5.20,270,1444687200"; d="scan'208";a="186900631" Received: from 14.mo4.mail-out.ovh.net ([46.105.40.29]) by mail2-smtp-roc.national.inria.fr with ESMTP/TLS/ADH-AES256-GCM-SHA384; 10 Nov 2015 11:26:14 +0100 Received: from mail170.ha.ovh.net (gw6.ovh.net [213.251.189.206]) by mo4.mail-out.ovh.net (Postfix) with SMTP id A0F391007C03 for ; Tue, 10 Nov 2015 11:26:13 +0100 (CET) Received: from localhost (HELO queueout) (127.0.0.1) by localhost with SMTP; 10 Nov 2015 12:26:12 +0200 Received: from alille-655-1-132-116.w83-198.abo.wanadoo.fr (HELO ?192.168.1.15?) (romain@bardou.fr@83.198.207.116) by ns0.ovh.net with SMTP; 10 Nov 2015 12:25:52 +0200 To: caml-list@inria.fr References: <0F7D3B1B3C4B894D824F5B822E3E5A172CE3E070@IRSMSX102.ger.corp.intel.com> <87pozk6vjp.fsf@mid.deneb.enyo.de> <0F7D3B1B3C4B894D824F5B822E3E5A172CE3E747@IRSMSX102.ger.corp.intel.com> <56407297.2060309@frisch.fr> <564076EA.7020805@mpi-sws.org> <5640D8E0.6060102@lexifi.com> <5640E2EF.7070400@mpi-sws.org> <0F7D3B1B3C4B894D824F5B822E3E5A172CE3ED02@IRSMSX102.ger.corp.intel.com> From: Romain Bardou Message-ID: <5641C62C.9000606@cryptosense.com> Date: Tue, 10 Nov 2015 11:25:48 +0100 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Icedove/38.3.0 MIME-Version: 1.0 In-Reply-To: <0F7D3B1B3C4B894D824F5B822E3E5A172CE3ED02@IRSMSX102.ger.corp.intel.com> Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 8bit X-Ovh-Tracer-Id: 14280914419884487200 X-Ovh-Remote: 83.198.207.116 (alille-655-1-132-116.w83-198.abo.wanadoo.fr) X-Ovh-Local: 213.186.33.20 (ns0.ovh.net) X-OVH-SPAMSTATE: OK X-OVH-SPAMSCORE: 0 X-OVH-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrfeekhedrgeehucetufdoteggodftvfcurfhrohhfihhlvgemucfqggfjnecuuegrihhlohhuthemuceftddtnecu X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: 0 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrfeekhedrgeehucetufdoteggodftvfcurfhrohhfihhlvgemucfqggfjnecuuegrihhlohhuthemuceftddtnecu X-Validation-by: romain@cryptosense.com Subject: Re: [Caml-list] Newbie comment on constructor syntax Hello, In the Mantis thread I proposed that #C or (C) would be the curried version of constructor C. I think #C is nice and does not create any parsing issue, as constructors are capitalized and if I'm not mistaken method names cannot be. And even if they can, # is in a prefix position here, it should not create any conflict. (C) was inspired by the syntax for symbols like (+), but I like it much less (too many parentheses, one extra keystroke, parentheses should just be used for grouping…). Let's assume that C has arity 2 and we write "C x". I think it would be rather confusing if it was not partial application but, instead, x was expected to be a pair. On the other hand, "C (x, y)" does look like C is an uncurried function. So I don't see any solution that is not confusing one way or another, unless we introduce new syntax such as #C. As a side-note, another wish I have is that one day I'm able to write something like #f where f is a field name, to convert it to a getter, i.e. (fun x -> x.f). It raises the question of setters as well: ##f to get (fun r x -> r.f <- x) or (fun r x -> { r with f = x }). Or, #f is a (get, set) pair and we have #?f for the getter only and #!f for the setter only. What I'm saying is that if new syntax for constructors is added, it would be nice if it were also usable for fields later. This is another reason why (C) is bad, as (f) for fields definitely does not work. I have often had to write (fun x -> C x) by hand, as well as (fun x -> x.f), (fun r -> r.f) and (fun r x -> { r with f = x }). In the constructor example, quite often C is Some. I do not often feel the need to write (fun C x -> x) however, except if C has arity 2. With arity 1 it already works, and with arity 3 or more I usually use a record to name my fields. This may change now that we have inline records. --------- (the rest is off-topic) ----------- By the way, aren't you annoyed to have to write: { r with f = { r.f with g = { r.f.g with h = x } } } especially when field names are long? In one of my programs, I have defined: type ('r, 'a) field = { get: 'r -> 'a; set: 'r -> 'a -> 'r } let (<.>) f g = { get = (fun r -> g.get (f.get r)); set = (fun r x -> f.set r (g.set (f.get r) x)); } If #f was a new syntax which built the field record above, we could write: (#f <.> #g <.> #h).set r x Instead of the nested { with ... } above. Of course it would be better to just be able to write { r with f.g.h = x } in the first place :) Cheers, -- Romain On 10/11/2015 09:27, Soegtrop, Michael wrote: > Dear Ocaml Users and Developers, > > as a beginner I cannot say much about the rather intricate implications of the various implementation choices. But since a constructor doesn't seem to be a function at all, neither a tuple taking nor a currying one, I would suggest that the constructor declaration syntax makes this clear. e.g. and as suggested by Gabriel Scherer. This most likely would avoid some confusion for beginners. > > Since both currying and tuple taking constructors can be handy, it would make sense to have "operators", which convert a constructor into a function of the one or the other type. Say if C is a constructor, then C' is a currying function and C" is a tuple taking function. A beginner who comes across this would immediately understand that a constructor is neither a currying nor a tuple taking function, but something else. I guess ' and " wouldn't be possible, but I guess one can find some nice syntax for this. I would prefer to make this conversion explicit rather than an implicit coercion. For beginners it would be a good documentation that there is a difference. As was pointed out in the mail thread, the difference can be hidden to a certain extent, but at some point it would show up and the confusion would be even greater. > > The question if the application of a constructor shall follow the tuple or the normal function call style is, as far as I can tell, a purely syntactic choice. Here I would definitely prefer the (C x y) syntax over the C (x, y) simply because I think it is more natural to put the () around an entity rather than at a place where the head symbol gets separated from the arguments. Maybe it be possible to have C of int*int with C (1,2) syntax and C of int and int with (C 1 2) syntax at the same time and promote the latter syntax in tutorials or even give a deprecation warning, but I guess these would then have to be different at the type level. > > Another note: it was suggested in this mail thread to enforce type specifications for function arguments to make the life of beginners easier. I would rather not do this. A functional language lives from function arguments and in many cases it is clear what it is and being forced to write this down would be just a nuisance. I enjoy the flexibility to give the types only at interface functions and to leave it away in internal functions where it is clear. People coming from C++, where functional style programming is turned done a lot by the heavy syntax required to write down what you want, will definitely enjoy this. What might help to make the life of beginners easier is to have a compiler option to print the types of all defined functions. I think many people don't start with ocamltop, but with the compiler. In my case I started a project where I thought it is likely easier to learn Ocaml and to write it in Ocaml than to write it in C++. Such projects you don't start with ocamltop . But for high reliability code, it would make sense to have a compiler option to enforce full type specifications of all arguments. > > Many thanks for the very interesting and educating discussion! > > Best regards, > > Michael > > Intel Deutschland GmbH > Registered Address: Am Campeon 10-12, 85579 Neubiberg, Germany > Tel: +49 89 99 8853-0, www.intel.de > Managing Directors: Christin Eisenschmid, Christian Lamprechter > Chairperson of the Supervisory Board: Nicole Lau > Registered Office: Munich > Commercial Register: Amtsgericht Muenchen HRB 186928 >