From mboxrd@z Thu Jan 1 00:00:00 1970 Received: (from majordomo@localhost) by pauillac.inria.fr (8.7.6/8.7.3) id LAA17561; Tue, 3 Apr 2001 11:28:38 +0200 (MET DST) X-Authentication-Warning: pauillac.inria.fr: majordomo set sender to owner-caml-list@pauillac.inria.fr using -f 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 LAA17571 for ; Tue, 3 Apr 2001 11:28:37 +0200 (MET DST) Received: from psyche.kaba.or.jp (psyche.kaba.or.jp [202.249.19.1]) by nez-perce.inria.fr (8.11.1/8.10.0) with ESMTP id f339SYP04899 for ; Tue, 3 Apr 2001 11:28:34 +0200 (MET DST) Received: from vortex.kaba.or.jp (vortex.kaba.or.jp [202.249.19.21]) by psyche.kaba.or.jp (8.9.3/3.7Wpl2-psyche) with ESMTP id SAA50071; Tue, 3 Apr 2001 18:28:01 +0900 (JST) Received: from localhost (pmdhcp06.kaba.or.jp [202.249.19.118]) by vortex.kaba.or.jp (8.9.3/3.7W) with ESMTP id SAA28418; Tue, 3 Apr 2001 18:28:01 +0900 (JST) To: patrick@watson.org Cc: caml-list@inria.fr Subject: Re: [Caml-list] Future of labels, and ideas for library labelling In-Reply-To: References: <20010403125314Q.garrigue@kurims.kyoto-u.ac.jp> X-Mailer: Mew version 1.94.2 on Emacs 20.7 / Mule 4.0 (HANANOEN) Mime-Version: 1.0 Content-Type: Text/Plain; charset=us-ascii Content-Transfer-Encoding: 7bit Message-Id: <20010403183050B.garrigue@kurims.kyoto-u.ac.jp> Date: Tue, 03 Apr 2001 18:30:50 +0900 From: Jacques Garrigue X-Dispatcher: imput version 20000228(IM140) Sender: owner-caml-list@pauillac.inria.fr Precedence: bulk Hi Patrick, This is only a point by point answer. On labels vs. extensible records: > > I'm not really convinced of that. SML for instance has structural > > records, and uses them in its basis library. You can look at the result > > for yourself. For me it's only half the way. [...] > I think that we're in agreement here. Structural records like SML is a > start, but light-weight extensible records would address most of these > issues. > > - Labeled arguments are included in a record, and unlabelled arguments > are outside of the record. And since they are light-weight, there is no > need to declare a type definition for the record. That's exactly what I was pointing as a weaker form of commutation: labeled arguments commute between themselves, but they do not commute with non-labeled arguments. > - Labels and currying do give a nicer syntax. On the other hand, not > having good support for records is a detriment to the syntax. Most > programmers coming to Caml will have an expectation that fields can belong > to more than one record. Luckily, labelled arguments removes at least one > reason for light-weight records. I know the lack of light-weight records is a pain, but we have already two record-like structures in OCaml, and tuples. Predefined records have their advantages, so this would mean adding yet another structure. This may happen someday, but I'm not all that enthusiastic. > - Optional arguments can be addressed by having a value which > contains the default arguments which is modified by a record update > syntax. This handles only default arguments, optional arguments are more powerful since their value may be computed at call time. On proper labellings: > > I have also eta-expanded more than necessary, to make the code more > > readable. > > We can write something shorter if we use labels as they were in ocaml > > 2.99, before their trimming: > > List.fold_left lists ~acc:IntSet.empty > > ~f:(List.fold_left ~f:(fun ~acc item -> IntSet.add acc ~item)) > > Now, which is the more readable program, this one or yours. > > Hmm... hard to say. Using this API, I would wonder why isn't there a label > for the list? It would be much simpler if every argument to a function had > to have a label. I know this presents its own problems, but it adds to > the things one must remember for coding. I think this is explained in the tutorial: you should not label the object of the operation. Normally one learns that in elementary school, but forgets it soon after, so it can be a bit difficult. Requires some practice before it comes out naturally. > Regarding Haskell, what you say is surprising since I would classify > a common use of monadic binding as a folding function. For the operator > (>>=) which has type > > (>>=) :: m a -> (a -> m b) -> m b > > if a and b are the same type than it is a folding over computation state. > This is certainly a common use in real programs. I was only talking of list folding functions. Labels are not the only way to improve readability. Infix operators can also help. On type errors in label mode: > Forgetting to use the label in commuting mode can lead to incredible > cryptic error messages. The situation has improved a bit with 3.01. Give it a try to see the difference. This is not perfect yet, but if you see something clearly wrong you can send a bug report. > As discussed above, I like to use a variant of > list folding that gets the arugments in the "right" order and is > tail-recursive. I tried adding labels to the arguments to see what would > happen when they were omitted. The result was pretty surprising: > > val listFold : f:('a -> 'b -> 'b) -> l:'a list -> acc:'b -> 'b > > let cons x l = x :: l > > listFold cons (listFold cons [5;4;3] []) [];; > > While this is a contrived example to reverse a list twice, not including > the labels gave this impressive type back from the compiler: [monstruous type] This problem is specific to functions returning a polymorphic type: if your arguments match none of the labels in the function type, they will be seen as arguments to the result of the function, producing a huge type by unification. If you had tried on an instanciated typed, you would have got a more reasonable answer. # let rec listFold ~f ~l ~(acc : int) = match l with [] -> acc | x :: l -> listFold ~f ~l ~acc:(f x acc);; val listFold : f:('a -> int -> int) -> l:'a list -> acc:int -> int = # let cons x l = x :: l;; val cons : 'a -> 'a list -> 'a list = # listFold cons (listFold cons [5;4;3] []) [];; Expecting function has type f:('a -> int -> int) -> l:'a list -> acc:int -> int This argument cannot be applied without label When there is enough information, one can produce accurate error messages. > I think this is more than enough to frighten me from using commuting label > mode. The classic mode seems to give more sensible error messages. In practice, I do not bump into this kind of errors very often. In real programs, functions returning a polymorphic variable as result are not so frequent. > Another language that I'm very familiar with that has labelled arguments > (in some sense) is Verilog. Instantiation by named connection is > really crucial to using the language safely. Some observations though: > > 1) There are no structures in the language, so some need of labelling is > needed. Indeed, you will fell more directly need for labels in dynamically typed languages. But, while this may be true that labels are less needed from the point-of-view of type safety, for documentation the need is identical. Particularly in ML you don't write type annotations, and it is often hard to follow the role of a variable in a program. Ocamlbrowser can give you this information, but this does not replace information about the role of an argument, which appears to be most needed when reading a program. > 2) There is no partial application which makes it easier to give > intelligent error messages. But partial application makes commutation more interesting :-) Thanks for all these good points. Jacques ------------------- To unsubscribe, mail caml-list-request@inria.fr. Archives: http://caml.inria.fr