From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: weis Received: (from weis@localhost) by pauillac.inria.fr (8.7.6/8.7.3) id SAA13996 for caml-redistribution@pauillac.inria.fr; Sat, 18 Mar 2000 18:55:18 +0100 (MET) Resent-Message-Id: <200003181755.SAA13996@pauillac.inria.fr> Received: from nez-perce.inria.fr (nez-perce.inria.fr [192.93.2.78]) by pauillac.inria.fr (8.7.6/8.7.3) with ESMTP id BAA08248 for ; Sat, 18 Mar 2000 01:06:23 +0100 (MET) Received: from mailman.zeta.org.au (mailman.zeta.org.au [203.26.10.16]) by nez-perce.inria.fr (8.8.7/8.8.7) with ESMTP id BAA00593 for ; Sat, 18 Mar 2000 01:06:18 +0100 (MET) Received: from zeta.org.au (ppp21.dyn143.pacific.net.au [210.23.143.21]) by mailman.zeta.org.au (8.8.7/8.8.7) with ESMTP id LAA18640 for ; Sat, 18 Mar 2000 11:13:16 +1100 Message-ID: <38D2C806.219E784B@zeta.org.au> Date: Sat, 18 Mar 2000 10:04:22 +1000 From: Steven Thomson X-Mailer: Mozilla 4.61 [en] (Win95; I) X-Accept-Language: en MIME-Version: 1.0 To: caml-list@inria.fr Subject: Re: Syntax for label, ANOTHER NEW PROPOSAL References: <39ADCF833E74D111A2D700805F1951EF180144F2@RED-MSG-06> <20000315121549A.garrigue@kurims.kyoto-u.ac.jp> <20000315145830.22463@pauillac.inria.fr> Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Resent-From: weis@pauillac.inria.fr Resent-Date: Sat, 18 Mar 2000 18:55:18 +0100 Resent-To: caml-redistribution@pauillac.inria.fr Pierre Weis wrote: [part of long post omitted] > > $ ocaml > Objective Caml version 2.99+10 > > # let sum l = List.fold_right ( + ) l 0;; > val sum : int list -> int = > > Clearly application is denoted in ML with only one character: a space. > > Now, consider using the so-called ``Modern'' versions of these > functionals, obtained with the -modern option of the compiler: > > $ ocamlpedantic > Objective Caml version 2.99+10 > > # let sum l = List.fold_right ( + ) l 0;; > ^^^^^ > This expression has type int -> int -> int but is here used with type 'a list > > Clearly, there is something wrong now! We may remark that the error > message is not that clear, but this is a minor point, since error > messages are never clear enough anyway! > > The real problem is that fixing the code makes no good at all to its > readability (at least that's what I would say): > > # let sum l = List.fold_right fun:begin fun x acc:y -> x + y end acc:0;; > val sum : 'a -> int list -> int = > > It seems that, in the ``modern'' mode, application of higher order > functions is now denoted by a new kind of parens opening by > ``fun:begin fun'' and ending by ``end''. This is extremely explicit > but also a bit heavy (in my mind). > > For all these reasons, I would suggest to carefully use labels into > the standard libraries: > > -- remove labels from higher-order functional I don't think that merely omitting labels from higher-order functional arguments really solves the problem. Consider the following: $ ocaml -modern Objective Caml version 2.99 (99/12/08) # let add' :acc x = acc + x;; val add' : acc:int -> int -> int = # let rec fold_left' f accu l = match l with [] -> accu | a::l -> fold_left' f (f accu a) l;; val fold_left' : ('a -> 'b -> 'a) -> 'a -> 'b list -> 'a = # let sum' = fold_left' add' 0;; Characters 24-28: This expression has type acc:int -> int -> int but is here used with type 'a -> 'b -> 'a If the definition of fold_left' does NOT use a label, we still get a compile error whenever we try to use an argument that DOES have a label. My proposal is to introduce an operator that can be used to tell the compiler to ignore labels when type-checking a higher-order functional argument. This could be thought of as a pragma which locally switches the compiler from modern to classic mode. Some possible variations: 1. A prefix operator, here shown as "~", that causes only the following expression to be evaluated in classic mode: let sum = List.fold_left fun:~(+) acc:0 let sum' = fold_left' ~add' 0 2. A bracketing construct, here shown as [~ ~], that causes everything inside the brackets to be evaluated in classic mode. let sum = List.fold_left fun:[~(+)~] acc:0 let sum' = fold_left' [~add'~] 0 option 2 is not as visually lightweight, but might be more useful if there are several arguments that need to be altered: let aaa = bbb ccc:~ddd eee:~fff ggg:~hhh ~iii jjj versus let aaa = bbb [~ ccc:ddd eee:fff ggg:hhh iii ~] jjj