From: Romain Bardou <romain@cryptosense.com>
To: caml-list@inria.fr
Subject: Re: [Caml-list] Newbie comment on constructor syntax
Date: Tue, 10 Nov 2015 11:25:48 +0100 [thread overview]
Message-ID: <5641C62C.9000606@cryptosense.com> (raw)
In-Reply-To: <0F7D3B1B3C4B894D824F5B822E3E5A172CE3ED02@IRSMSX102.ger.corp.intel.com>
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. <type a> and <type b> 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
>
next prev parent reply other threads:[~2015-11-10 10:26 UTC|newest]
Thread overview: 47+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-11-06 9:33 Soegtrop, Michael
2015-11-06 10:04 ` Nicolas Ojeda Bar
2015-11-06 10:31 ` Francois Berenger
2015-11-06 12:20 ` Soegtrop, Michael
2015-11-06 12:34 ` Gabriel Scherer
2015-11-06 13:09 ` Soegtrop, Michael
2015-11-06 14:10 ` Ashish Agarwal
2015-11-06 15:19 ` Soegtrop, Michael
2015-11-06 15:21 ` Ashish Agarwal
2015-11-21 17:24 ` [Caml-list] Notation for currying Hendrik Boom
2015-11-21 17:41 ` Gabriel Scherer
2015-11-21 18:05 ` David Rajchenbach-Teller
2015-11-21 18:55 ` Gabriel Scherer
2015-11-06 12:29 ` [Caml-list] Newbie comment on constructor syntax Jonas Jensen
2015-11-06 12:46 ` Soegtrop, Michael
2015-11-06 12:54 ` Gabriel Scherer
2015-11-08 21:16 ` Florian Weimer
2015-11-08 22:50 ` Norman Hardy
2015-11-09 6:27 ` Florian Weimer
2015-11-09 13:27 ` Stefan Monnier
2015-11-09 8:09 ` Soegtrop, Michael
2015-11-09 10:00 ` Hendrik Boom
2015-11-09 10:16 ` Alain Frisch
2015-11-09 10:35 ` Andreas Rossberg
2015-11-09 12:28 ` Alain Frisch
2015-11-09 17:33 ` Alain Frisch
2015-11-09 18:08 ` Gabriel Scherer
2015-11-09 18:16 ` Andreas Rossberg
2015-11-09 21:11 ` Gabriel Scherer
2015-11-09 22:06 ` Alain Frisch
2015-11-09 22:27 ` Andreas Rossberg
2015-11-09 22:57 ` Jeremy Yallop
2015-11-10 0:11 ` Hendrik Boom
2015-11-10 8:27 ` Soegtrop, Michael
2015-11-10 10:25 ` Romain Bardou [this message]
2015-11-10 10:44 ` Alain Frisch
2015-11-10 10:55 ` Romain Bardou
2015-11-10 13:17 ` Alain Frisch
2015-11-10 13:41 ` Romain Bardou
2015-11-10 14:01 ` Alain Frisch
2015-11-13 15:36 ` Romain Bardou
2015-11-10 11:17 ` Soegtrop, Michael
2015-11-10 14:11 ` Hendrik Boom
2015-11-10 14:40 ` immanuel litzroth
2015-11-10 15:30 ` Soegtrop, Michael
2015-11-10 17:27 ` Gerd Stolpmann
2015-11-09 20:32 ` Alain Frisch
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=5641C62C.9000606@cryptosense.com \
--to=romain@cryptosense.com \
--cc=caml-list@inria.fr \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox