caml-list - the Caml user's mailing list
 help / Atom feed
* [Caml-list] Syntax puzzle / suggestion
@ 2019-08-09 14:27 Richard W.M. Jones
  2019-08-09 14:39 ` Gabriel Scherer
                   ` (3 more replies)
  0 siblings, 4 replies; 9+ messages in thread
From: Richard W.M. Jones @ 2019-08-09 14:27 UTC (permalink / raw)
  To: caml-list

Let's imagine you have a list of named things, but you also want to
collect them up into a single list.  For example:

  let item1 = "hello"
  let item2 = "world"
  let all_items = [ item1; item2 ]

  let () =
    printf "item1 = %s\n" item1;
    printf "all_items = %s\n" (String.concat ", " all_items)

This is fine, but there's a danger that a programmer could add item3
but forget to add it to the "all_items" list.  (In the real world
problem to which this applies, my items are complex and lengthy
structures, and the "all-things-list" is well off the bottom of the
page when you're viewing the top item).

My idea to fix this was to write:

  let all_items = [
    ("hello" as item1);
    ("world" as item2);
  ]

Actually I was slightly surprised to find this doesn't compile.  I
guess because "as" can only be used like this in patterns, not
expressions.  Also the scoping is wrong because the "as item1" if it
worked probably wouldn't apply outside the list.

I haven't worked out if it's possible to write this in ordinary OCaml,
although I suppose ppx could solve it.  Any ideas if this is possible?

Rich.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [Caml-list] Syntax puzzle / suggestion
  2019-08-09 14:27 [Caml-list] Syntax puzzle / suggestion Richard W.M. Jones
@ 2019-08-09 14:39 ` Gabriel Scherer
  2019-08-09 14:45   ` Richard W.M. Jones
  2019-08-09 14:48 ` Martin Riener
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 9+ messages in thread
From: Gabriel Scherer @ 2019-08-09 14:39 UTC (permalink / raw)
  To: Richard W.M. Jones; +Cc: caml users

[-- Attachment #1: Type: text/plain, Size: 1545 bytes --]

If you have an interface file (.mli) for this module, then adding item3
without putting it in all_items or in the .mli will result in an "unused
value item3" warning (-w +32).
There is no such warning in absence of .mli because, in that case, item3
may a priori be used from the outside.

On Fri, Aug 9, 2019 at 4:28 PM Richard W.M. Jones <rich@annexia.org> wrote:

> Let's imagine you have a list of named things, but you also want to
> collect them up into a single list.  For example:
>
>   let item1 = "hello"
>   let item2 = "world"
>   let all_items = [ item1; item2 ]
>
>   let () =
>     printf "item1 = %s\n" item1;
>     printf "all_items = %s\n" (String.concat ", " all_items)
>
> This is fine, but there's a danger that a programmer could add item3
> but forget to add it to the "all_items" list.  (In the real world
> problem to which this applies, my items are complex and lengthy
> structures, and the "all-things-list" is well off the bottom of the
> page when you're viewing the top item).
>
> My idea to fix this was to write:
>
>   let all_items = [
>     ("hello" as item1);
>     ("world" as item2);
>   ]
>
> Actually I was slightly surprised to find this doesn't compile.  I
> guess because "as" can only be used like this in patterns, not
> expressions.  Also the scoping is wrong because the "as item1" if it
> worked probably wouldn't apply outside the list.
>
> I haven't worked out if it's possible to write this in ordinary OCaml,
> although I suppose ppx could solve it.  Any ideas if this is possible?
>
> Rich.
>

[-- Attachment #2: Type: text/html, Size: 2118 bytes --]

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [Caml-list] Syntax puzzle / suggestion
  2019-08-09 14:39 ` Gabriel Scherer
@ 2019-08-09 14:45   ` Richard W.M. Jones
  0 siblings, 0 replies; 9+ messages in thread
From: Richard W.M. Jones @ 2019-08-09 14:45 UTC (permalink / raw)
  To: Gabriel Scherer; +Cc: caml users

On Fri, Aug 09, 2019 at 04:40:48PM +0200, Gabriel Scherer wrote:
> If you have an interface file (.mli) for this module, then adding item3
> without putting it in all_items or in the .mli will result in an "unused
> value item3" warning (-w +32).
> There is no such warning in absence of .mli because, in that case, item3
> may a priori be used from the outside.

I wasn't very clear, but we're using both the individual items and the
list of all items elsewhere in the code.  But it raises another point
which is we'd like a list of all items, and maybe to selectively name
some of those items so they can be referenced elsewhere.

Rich.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [Caml-list] Syntax puzzle / suggestion
  2019-08-09 14:27 [Caml-list] Syntax puzzle / suggestion Richard W.M. Jones
  2019-08-09 14:39 ` Gabriel Scherer
@ 2019-08-09 14:48 ` Martin Riener
  2019-08-10  5:19   ` rixed
  2019-08-09 14:53 ` Josh Berdine
  2019-08-09 14:56 ` Frédéric Bour
  3 siblings, 1 reply; 9+ messages in thread
From: Martin Riener @ 2019-08-09 14:48 UTC (permalink / raw)
  To: caml-list

[-- Attachment #1.1: Type: text/plain, Size: 1700 bytes --]

I always found

  let [item1; item2] as all_items = ["hello"; "world" ]

readable but the compiler does does not infer that this match always works and
emits:

Warning 8: this pattern-matching is not exhaustive.
Here is an example of a case that is not matched:
(_::_::_::_|_::[]|[])

I've never touched the compiler so I don't have an idea how much effort it would
be to make the inference.

cheers,
Martin



On 8/9/19 4:27 PM, Richard W.M. Jones wrote:
> Let's imagine you have a list of named things, but you also want to
> collect them up into a single list.  For example:
> 
>   let item1 = "hello"
>   let item2 = "world"
>   let all_items = [ item1; item2 ]
> 
>   let () =
>     printf "item1 = %s\n" item1;
>     printf "all_items = %s\n" (String.concat ", " all_items)
> 
> This is fine, but there's a danger that a programmer could add item3
> but forget to add it to the "all_items" list.  (In the real world
> problem to which this applies, my items are complex and lengthy
> structures, and the "all-things-list" is well off the bottom of the
> page when you're viewing the top item).
> 
> My idea to fix this was to write:
> 
>   let all_items = [
>     ("hello" as item1);
>     ("world" as item2);
>   ]
> 
> Actually I was slightly surprised to find this doesn't compile.  I
> guess because "as" can only be used like this in patterns, not
> expressions.  Also the scoping is wrong because the "as item1" if it
> worked probably wouldn't apply outside the list.
> 
> I haven't worked out if it's possible to write this in ordinary OCaml,
> although I suppose ppx could solve it.  Any ideas if this is possible?
> 
> Rich.
> 


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [Caml-list] Syntax puzzle / suggestion
  2019-08-09 14:27 [Caml-list] Syntax puzzle / suggestion Richard W.M. Jones
  2019-08-09 14:39 ` Gabriel Scherer
  2019-08-09 14:48 ` Martin Riener
@ 2019-08-09 14:53 ` Josh Berdine
  2019-08-10 15:18   ` Oliver Bandel
  2019-08-10 20:34   ` Chet Murthy
  2019-08-09 14:56 ` Frédéric Bour
  3 siblings, 2 replies; 9+ messages in thread
From: Josh Berdine @ 2019-08-09 14:53 UTC (permalink / raw)
  To: Richard W.M. Jones

What about good old-fashioned state:

let all_items = ref []
let add_item item = all_items := (item :: !all_items, item)

let item1 = add_item "hello"
let item2 = add_item "world"

let all_items = List.rev !all_items


On 9 Aug 2019, at 15:27, Richard W.M. Jones wrote:

> Let's imagine you have a list of named things, but you also want to
> collect them up into a single list.  For example:
>
>   let item1 = "hello"
>   let item2 = "world"
>   let all_items = [ item1; item2 ]
>
>   let () =
>     printf "item1 = %s\n" item1;
>     printf "all_items = %s\n" (String.concat ", " all_items)
>
> This is fine, but there's a danger that a programmer could add item3
> but forget to add it to the "all_items" list.  (In the real world
> problem to which this applies, my items are complex and lengthy
> structures, and the "all-things-list" is well off the bottom of the
> page when you're viewing the top item).
>
> My idea to fix this was to write:
>
>   let all_items = [
>     ("hello" as item1);
>     ("world" as item2);
>   ]
>
> Actually I was slightly surprised to find this doesn't compile.  I
> guess because "as" can only be used like this in patterns, not
> expressions.  Also the scoping is wrong because the "as item1" if it
> worked probably wouldn't apply outside the list.
>
> I haven't worked out if it's possible to write this in ordinary OCaml,
> although I suppose ppx could solve it.  Any ideas if this is possible?
>
> Rich.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [Caml-list] Syntax puzzle / suggestion
  2019-08-09 14:27 [Caml-list] Syntax puzzle / suggestion Richard W.M. Jones
                   ` (2 preceding siblings ...)
  2019-08-09 14:53 ` Josh Berdine
@ 2019-08-09 14:56 ` Frédéric Bour
  3 siblings, 0 replies; 9+ messages in thread
From: Frédéric Bour @ 2019-08-09 14:56 UTC (permalink / raw)
  To: Richard W.M. Jones; +Cc: caml-list

[-- Attachment #1: Type: text/plain, Size: 1772 bytes --]

Abusing list notations and GADTs to keep track of length and ensure
exhaustive matching:

module M = struct type ('a, 'b) t = [] : (_, unit) t | (::) : 'a * ('a, 'b)
t -> ('a, unit * 'b) t end;;
let rec to_list : type a b. (a, b) M.t -> a list = function | M.[] -> [] |
M.(x :: xs) -> x :: to_list xs;;
let decompose x = (to_list x, x);;

# let all_items, M.[item1; item2] = decompose M.["hello"; "world"];;
val all_items : string list = ["hello"; "world"]
val item1 : string = "hello"
val item2 : string = "world"

On Fri, Aug 9, 2019 at 4:27 PM Richard W.M. Jones <rich@annexia.org> wrote:

> Let's imagine you have a list of named things, but you also want to
> collect them up into a single list.  For example:
>
>   let item1 = "hello"
>   let item2 = "world"
>   let all_items = [ item1; item2 ]
>
>   let () =
>     printf "item1 = %s\n" item1;
>     printf "all_items = %s\n" (String.concat ", " all_items)
>
> This is fine, but there's a danger that a programmer could add item3
> but forget to add it to the "all_items" list.  (In the real world
> problem to which this applies, my items are complex and lengthy
> structures, and the "all-things-list" is well off the bottom of the
> page when you're viewing the top item).
>
> My idea to fix this was to write:
>
>   let all_items = [
>     ("hello" as item1);
>     ("world" as item2);
>   ]
>
> Actually I was slightly surprised to find this doesn't compile.  I
> guess because "as" can only be used like this in patterns, not
> expressions.  Also the scoping is wrong because the "as item1" if it
> worked probably wouldn't apply outside the list.
>
> I haven't worked out if it's possible to write this in ordinary OCaml,
> although I suppose ppx could solve it.  Any ideas if this is possible?
>
> Rich.
>

[-- Attachment #2: Type: text/html, Size: 2498 bytes --]

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [Caml-list] Syntax puzzle / suggestion
  2019-08-09 14:48 ` Martin Riener
@ 2019-08-10  5:19   ` rixed
  0 siblings, 0 replies; 9+ messages in thread
From: rixed @ 2019-08-10  5:19 UTC (permalink / raw)
  To: caml-list

On Fri, Aug 9, 2019, at 16:48, Martin Riener wrote:
>   let [item1; item2] as all_items = ["hello"; "world" ]

Nice!

> Warning 8: this pattern-matching is not exhaustive.
> Here is an example of a case that is not matched:
> (_::_::_::_|_::[]|[])

let [item1; item2] as all_items = ["hello"; "world" ] [@@ocaml.warning "-8"]


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [Caml-list] Syntax puzzle / suggestion
  2019-08-09 14:53 ` Josh Berdine
@ 2019-08-10 15:18   ` Oliver Bandel
  2019-08-10 20:34   ` Chet Murthy
  1 sibling, 0 replies; 9+ messages in thread
From: Oliver Bandel @ 2019-08-10 15:18 UTC (permalink / raw)
  To: Josh Berdine; +Cc: Richard W.M. Jones, caml-list

Quoting  Josh Berdine <josh@berdine.net> (snt: 2019-08-09 16:51 +0200 CEST) (rcv: 2019-08-09 16:53 +0200 CEST):
> What about good old-fashioned state:
[...]

I guess you mean style, not state.
And I would agree that inventing just another syntax would not be
necessary,

> 
> let all_items = ref []
> let add_item item = all_items := (item :: !all_items, item)

This does not xomnpile, but thie here does:

let add_item item = all_items := (item :: !all_items); item


Ciao,
  Oliver


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [Caml-list] Syntax puzzle / suggestion
  2019-08-09 14:53 ` Josh Berdine
  2019-08-10 15:18   ` Oliver Bandel
@ 2019-08-10 20:34   ` Chet Murthy
  1 sibling, 0 replies; 9+ messages in thread
From: Chet Murthy @ 2019-08-10 20:34 UTC (permalink / raw)
  To: Josh Berdine, caml-list; +Cc: Richard W.M. Jones

[-- Attachment #1: Type: text/plain, Size: 1821 bytes --]

Slight fixups:

let all_items = ref ([] : string list)
let add_item item = (all_items := item :: !all_items ; item)

let item1 = add_item "hello"
let item2 = add_item "world"

let all_items = List.rev !all_items


On Fri, Aug 9, 2019 at 7:53 AM Josh Berdine <josh@berdine.net> wrote:

> What about good old-fashioned state:
>
> let all_items = ref []
> let add_item item = all_items := (item :: !all_items, item)
>
> let item1 = add_item "hello"
> let item2 = add_item "world"
>
> let all_items = List.rev !all_items
>
>
> On 9 Aug 2019, at 15:27, Richard W.M. Jones wrote:
>
> > Let's imagine you have a list of named things, but you also want to
> > collect them up into a single list.  For example:
> >
> >   let item1 = "hello"
> >   let item2 = "world"
> >   let all_items = [ item1; item2 ]
> >
> >   let () =
> >     printf "item1 = %s\n" item1;
> >     printf "all_items = %s\n" (String.concat ", " all_items)
> >
> > This is fine, but there's a danger that a programmer could add item3
> > but forget to add it to the "all_items" list.  (In the real world
> > problem to which this applies, my items are complex and lengthy
> > structures, and the "all-things-list" is well off the bottom of the
> > page when you're viewing the top item).
> >
> > My idea to fix this was to write:
> >
> >   let all_items = [
> >     ("hello" as item1);
> >     ("world" as item2);
> >   ]
> >
> > Actually I was slightly surprised to find this doesn't compile.  I
> > guess because "as" can only be used like this in patterns, not
> > expressions.  Also the scoping is wrong because the "as item1" if it
> > worked probably wouldn't apply outside the list.
> >
> > I haven't worked out if it's possible to write this in ordinary OCaml,
> > although I suppose ppx could solve it.  Any ideas if this is possible?
> >
> > Rich.
>

[-- Attachment #2: Type: text/html, Size: 2605 bytes --]

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, back to index

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-08-09 14:27 [Caml-list] Syntax puzzle / suggestion Richard W.M. Jones
2019-08-09 14:39 ` Gabriel Scherer
2019-08-09 14:45   ` Richard W.M. Jones
2019-08-09 14:48 ` Martin Riener
2019-08-10  5:19   ` rixed
2019-08-09 14:53 ` Josh Berdine
2019-08-10 15:18   ` Oliver Bandel
2019-08-10 20:34   ` Chet Murthy
2019-08-09 14:56 ` Frédéric Bour

caml-list - the Caml user's mailing list

Archives are clonable: git clone --mirror https://inbox.ocaml.org/caml-list

AGPL code for this site: git clone https://public-inbox.org/ public-inbox