caml-list - the Caml user's mailing list
 help / Atom feed
* [Caml-list] cmdliner difficulties
@ 2018-07-27 18:11 Kenneth Adam Miller
  2018-07-27 19:26 ` Gabriel Scherer
  2018-07-28 22:44 ` Андрей Бергман
  0 siblings, 2 replies; 7+ messages in thread
From: Kenneth Adam Miller @ 2018-07-27 18:11 UTC (permalink / raw)
  To: caml users

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

Hello,


I have a task where I need to have command liner allow a sequence of
various different types compose a certain way without having to write a
small language for what belongs on the command line.

Basically, I am trying to color a graph with different operations on the
command line in such a way that different colors can be specified as the
target of results of set operations against names of sets. For example:

--color Red=(Feature1 MINUS Feature2)

There are a predefined set of colors and features, and some operations that
can be performed. However, because it's a grammar just like any language,
there might be arbitrarily deep expressions, and because the command line
won't have me constructing this in a straight forward way without writing a
dedicated type parser, which might not be so clean.

There are operations: difference, union, intersection, and cut. These can
recur, and there are predefined list of colors that can be the targets of
these results, which are calculated from sources that are features. In
addition, the specification of colorings can be multiple, as in --color ...
--color ...

Can anybody see where they would overcome some of these difficulties?

-- 
Caml-list mailing list.  Subscription management and archives:
https://sympa.inria.fr/sympa/arc/caml-list
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
Bug reports: http://caml.inria.fr/bin/caml-bugs

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

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

* Re: [Caml-list] cmdliner difficulties
  2018-07-27 18:11 [Caml-list] cmdliner difficulties Kenneth Adam Miller
@ 2018-07-27 19:26 ` Gabriel Scherer
  2018-07-28 22:44 ` Андрей Бергман
  1 sibling, 0 replies; 7+ messages in thread
From: Gabriel Scherer @ 2018-07-27 19:26 UTC (permalink / raw)
  To: Kenneth Adam Miller; +Cc: caml users

I would write a dedicated parser (typically using (ocamllex or sedlex)
and Menhir), and I don't think this is a problematic approach at all.
It would also turn out to be very useful if you later decided to also
be able to read these set expressions from other inputs, such as
configuration files.
On Fri, Jul 27, 2018 at 8:11 PM Kenneth Adam Miller
<kennethadammiller@gmail.com> wrote:
>
> Hello,
>
>
> I have a task where I need to have command liner allow a sequence of various different types compose a certain way without having to write a small language for what belongs on the command line.
>
> Basically, I am trying to color a graph with different operations on the command line in such a way that different colors can be specified as the target of results of set operations against names of sets. For example:
>
> --color Red=(Feature1 MINUS Feature2)
>
> There are a predefined set of colors and features, and some operations that can be performed. However, because it's a grammar just like any language, there might be arbitrarily deep expressions, and because the command line won't have me constructing this in a straight forward way without writing a dedicated type parser, which might not be so clean.
>
> There are operations: difference, union, intersection, and cut. These can recur, and there are predefined list of colors that can be the targets of these results, which are calculated from sources that are features. In addition, the specification of colorings can be multiple, as in --color ... --color ...
>
> Can anybody see where they would overcome some of these difficulties?

-- 
Caml-list mailing list.  Subscription management and archives:
https://sympa.inria.fr/sympa/arc/caml-list
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
Bug reports: http://caml.inria.fr/bin/caml-bugs

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

* Re: [Caml-list] cmdliner difficulties
  2018-07-28 22:44 ` Андрей Бергман
@ 2018-07-28 20:17   ` Kenneth Adam Miller
  2018-07-29  0:26     ` Martin DeMello
  0 siblings, 1 reply; 7+ messages in thread
From: Kenneth Adam Miller @ 2018-07-28 20:17 UTC (permalink / raw)
  To: vkni; +Cc: caml users

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

I understand other people have written those things before, and that it's
probably not so challenging to someone else, and I'm not saying I can't or
wouldn't write it, but I'm under deadline pressure, and I think it would
not be looked up on well if I had something with anywhere near so many
features or as much work to deliver since if they even exist. Since I have
to demonstrate this, the first question they are going to ask is "you spent
more than X minutes working on this when you could have been working on the
minimum viable product!! Unhappy!!" So I'm not disregarding the input I've
got, but I think that I can achieve a less robust working version with the
same set of features in a simpler fashion.

So, instead I think can get something very near to a full grammar, while
still allowing the fundamental operations I want. Here's what I've got:


type setop =
  | Intersection
  | Difference
  | Union
[@@deriving sexp]

let list_setops = [
    "Intersection", Intersection;
    "Difference", Difference;
    "Union", Union;
]
let setops_doc = List.(to_string ~f:fst (list_setops))
let setops =
  let doc = "." in
  Cmdliner.Arg.(
    value & opt_all (some (pair ~sep:'=' string & pair (enum (list_setops))
& pair string string)) []
    & info ["setop"] ~docv:setops_doc ~doc
  )


Instead of having an recursive variant instance in the type setop place to
allow the grammar to be recursive, I will fold over the setops, and add
each one to a map. For example, I might have:

--setop Red=Union (Feature1, Feature2) --setop Green=Intersection (Red,
Feature3)

So that, as I fold, I will add colors to the feature set. Then, for
whatever nested operations otherwise would have been required, I can just
manually unfold them on the command line.

I guess I've solved my problem, but I was hoping to get a recursive parsing
capability on the command line that would have supporting a type
declaration more like the following:

type setop =
  | Result of setop
  | Intersection of string * string
  | Difference of string * string
  | Union of string * string

The problem with this is, 1) the constructors are non-uniform so that there
isn't a clean way to specify to the Cmdliner.Arg.value function what the
converter should be 2) The list type of their resulting pairwise
sub-command specifications to the command line (the "enum list_setops"
part) becomes much harder to specify since those also need to be
constructible in the string - type pairs for the list_setops argument to
enum.

I suppose my thinking about how to deal with this would be to write a
custom conv to convert the command line input, but to do so it would have
to be recursive, and the Cmdliner.Arg.enum would have to support both
non-uniform constructors and an argument conv to be able to do this
correctly.

Does anybody have a better way to capture what I'm looking to do?

On Sat, Jul 28, 2018 at 10:54 AM Андрей Бергман <vkni@yandex.ru> wrote:

> Probably a parser combinator with a small language would be a better tool
> for that. Parser generators look too heavy, and comman-line parsers are too
> light (otherwise they become optparse-applicative, which is too specific to
> study it => everyone uses cookbook).
>

-- 
Caml-list mailing list.  Subscription management and archives:
https://sympa.inria.fr/sympa/arc/caml-list
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
Bug reports: http://caml.inria.fr/bin/caml-bugs

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

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

* Re: [Caml-list] cmdliner difficulties
  2018-07-27 18:11 [Caml-list] cmdliner difficulties Kenneth Adam Miller
  2018-07-27 19:26 ` Gabriel Scherer
@ 2018-07-28 22:44 ` Андрей Бергман
  2018-07-28 20:17   ` Kenneth Adam Miller
  1 sibling, 1 reply; 7+ messages in thread
From: Андрей Бергман @ 2018-07-28 22:44 UTC (permalink / raw)
  To: Kenneth Adam Miller; +Cc: caml users

Probably a parser combinator with a small language would be a better tool for that. Parser generators look too heavy, and comman-line parsers are too light (otherwise they become optparse-applicative, which is too specific to study it => everyone uses cookbook).

-- 
Caml-list mailing list.  Subscription management and archives:
https://sympa.inria.fr/sympa/arc/caml-list
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
Bug reports: http://caml.inria.fr/bin/caml-bugs

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

* Re: [Caml-list] cmdliner difficulties
  2018-07-28 20:17   ` Kenneth Adam Miller
@ 2018-07-29  0:26     ` Martin DeMello
  2018-07-29  6:25       ` Gabriel Scherer
  0 siblings, 1 reply; 7+ messages in thread
From: Martin DeMello @ 2018-07-29  0:26 UTC (permalink / raw)
  To: Kenneth Adam Miller; +Cc: vkni, caml users

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

How about "lexing" them into a list of operation tokens, then using the
shunting-yard algorithm to parse them into an expression tree? that would
allow arbitrary recursive expressions and still be relatively
straightforward to process.

martin

On Sat, Jul 28, 2018 at 2:16 PM, Kenneth Adam Miller <
kennethadammiller@gmail.com> wrote:

> I understand other people have written those things before, and that it's
> probably not so challenging to someone else, and I'm not saying I can't or
> wouldn't write it, but I'm under deadline pressure, and I think it would
> not be looked up on well if I had something with anywhere near so many
> features or as much work to deliver since if they even exist. Since I have
> to demonstrate this, the first question they are going to ask is "you spent
> more than X minutes working on this when you could have been working on the
> minimum viable product!! Unhappy!!" So I'm not disregarding the input I've
> got, but I think that I can achieve a less robust working version with the
> same set of features in a simpler fashion.
>
> So, instead I think can get something very near to a full grammar, while
> still allowing the fundamental operations I want. Here's what I've got:
>
>
> type setop =
>   | Intersection
>   | Difference
>   | Union
> [@@deriving sexp]
>
> let list_setops = [
>     "Intersection", Intersection;
>     "Difference", Difference;
>     "Union", Union;
> ]
> let setops_doc = List.(to_string ~f:fst (list_setops))
> let setops =
>   let doc = "." in
>   Cmdliner.Arg.(
>     value & opt_all (some (pair ~sep:'=' string & pair (enum
> (list_setops)) & pair string string)) []
>     & info ["setop"] ~docv:setops_doc ~doc
>   )
>
>
> Instead of having an recursive variant instance in the type setop place to
> allow the grammar to be recursive, I will fold over the setops, and add
> each one to a map. For example, I might have:
>
> --setop Red=Union (Feature1, Feature2) --setop Green=Intersection (Red,
> Feature3)
>
> So that, as I fold, I will add colors to the feature set. Then, for
> whatever nested operations otherwise would have been required, I can just
> manually unfold them on the command line.
>
> I guess I've solved my problem, but I was hoping to get a recursive
> parsing capability on the command line that would have supporting a type
> declaration more like the following:
>
> type setop =
>   | Result of setop
>   | Intersection of string * string
>   | Difference of string * string
>   | Union of string * string
>
> The problem with this is, 1) the constructors are non-uniform so that
> there isn't a clean way to specify to the Cmdliner.Arg.value function what
> the converter should be 2) The list type of their resulting pairwise
> sub-command specifications to the command line (the "enum list_setops"
> part) becomes much harder to specify since those also need to be
> constructible in the string - type pairs for the list_setops argument to
> enum.
>
> I suppose my thinking about how to deal with this would be to write a
> custom conv to convert the command line input, but to do so it would have
> to be recursive, and the Cmdliner.Arg.enum would have to support both
> non-uniform constructors and an argument conv to be able to do this
> correctly.
>
> Does anybody have a better way to capture what I'm looking to do?
>
> On Sat, Jul 28, 2018 at 10:54 AM Андрей Бергман <vkni@yandex.ru> wrote:
>
>> Probably a parser combinator with a small language would be a better tool
>> for that. Parser generators look too heavy, and comman-line parsers are too
>> light (otherwise they become optparse-applicative, which is too specific to
>> study it => everyone uses cookbook).
>>
>

-- 
Caml-list mailing list.  Subscription management and archives:
https://sympa.inria.fr/sympa/arc/caml-list
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
Bug reports: http://caml.inria.fr/bin/caml-bugs

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

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

* Re: [Caml-list] cmdliner difficulties
  2018-07-29  0:26     ` Martin DeMello
@ 2018-07-29  6:25       ` Gabriel Scherer
  2018-07-29  7:00         ` Viet Le
  0 siblings, 1 reply; 7+ messages in thread
From: Gabriel Scherer @ 2018-07-29  6:25 UTC (permalink / raw)
  To: Martin DeMello; +Cc: Kenneth Adam Miller, vkni, caml users

Just in case, Menhir has "demos", small examples of lexer+parser pairs
and an environment setup (example caller code, build script...). The
simplest demo is "calc"

  https://gitlab.inria.fr/fpottier/menhir/tree/master/demos/calc

a syntax for arithmetic expressions such as "(1 + 3) * 5 + 2".

It should be fairly easy to get a syntax for set operators by
replacing "*" with "Intersection" and "+" with "Union" in the Lexer,
and integer literals by feature names.
On Sun, Jul 29, 2018 at 2:27 AM Martin DeMello <martindemello@gmail.com> wrote:
>
> How about "lexing" them into a list of operation tokens, then using the shunting-yard algorithm to parse them into an expression tree? that would allow arbitrary recursive expressions and still be relatively straightforward to process.
>
> martin
>
> On Sat, Jul 28, 2018 at 2:16 PM, Kenneth Adam Miller <kennethadammiller@gmail.com> wrote:
>>
>> I understand other people have written those things before, and that it's probably not so challenging to someone else, and I'm not saying I can't or wouldn't write it, but I'm under deadline pressure, and I think it would not be looked up on well if I had something with anywhere near so many features or as much work to deliver since if they even exist. Since I have to demonstrate this, the first question they are going to ask is "you spent more than X minutes working on this when you could have been working on the minimum viable product!! Unhappy!!" So I'm not disregarding the input I've got, but I think that I can achieve a less robust working version with the same set of features in a simpler fashion.
>>
>> So, instead I think can get something very near to a full grammar, while still allowing the fundamental operations I want. Here's what I've got:
>>
>>
>> type setop =
>>   | Intersection
>>   | Difference
>>   | Union
>> [@@deriving sexp]
>>
>> let list_setops = [
>>     "Intersection", Intersection;
>>     "Difference", Difference;
>>     "Union", Union;
>> ]
>> let setops_doc = List.(to_string ~f:fst (list_setops))
>> let setops =
>>   let doc = "." in
>>   Cmdliner.Arg.(
>>     value & opt_all (some (pair ~sep:'=' string & pair (enum (list_setops)) & pair string string)) []
>>     & info ["setop"] ~docv:setops_doc ~doc
>>   )
>>
>>
>> Instead of having an recursive variant instance in the type setop place to allow the grammar to be recursive, I will fold over the setops, and add each one to a map. For example, I might have:
>>
>> --setop Red=Union (Feature1, Feature2) --setop Green=Intersection (Red, Feature3)
>>
>> So that, as I fold, I will add colors to the feature set. Then, for whatever nested operations otherwise would have been required, I can just manually unfold them on the command line.
>>
>> I guess I've solved my problem, but I was hoping to get a recursive parsing capability on the command line that would have supporting a type declaration more like the following:
>>
>> type setop =
>>   | Result of setop
>>   | Intersection of string * string
>>   | Difference of string * string
>>   | Union of string * string
>>
>> The problem with this is, 1) the constructors are non-uniform so that there isn't a clean way to specify to the Cmdliner.Arg.value function what the converter should be 2) The list type of their resulting pairwise sub-command specifications to the command line (the "enum list_setops" part) becomes much harder to specify since those also need to be constructible in the string - type pairs for the list_setops argument to enum.
>>
>> I suppose my thinking about how to deal with this would be to write a custom conv to convert the command line input, but to do so it would have to be recursive, and the Cmdliner.Arg.enum would have to support both non-uniform constructors and an argument conv to be able to do this correctly.
>>
>> Does anybody have a better way to capture what I'm looking to do?
>>
>> On Sat, Jul 28, 2018 at 10:54 AM Андрей Бергман <vkni@yandex.ru> wrote:
>>>
>>> Probably a parser combinator with a small language would be a better tool for that. Parser generators look too heavy, and comman-line parsers are too light (otherwise they become optparse-applicative, which is too specific to study it => everyone uses cookbook).
>
>

-- 
Caml-list mailing list.  Subscription management and archives:
https://sympa.inria.fr/sympa/arc/caml-list
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
Bug reports: http://caml.inria.fr/bin/caml-bugs

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

* Re: [Caml-list] cmdliner difficulties
  2018-07-29  6:25       ` Gabriel Scherer
@ 2018-07-29  7:00         ` Viet Le
  0 siblings, 0 replies; 7+ messages in thread
From: Viet Le @ 2018-07-29  7:00 UTC (permalink / raw)
  To: Gabriel Scherer; +Cc: Kenneth Adam Miller, Martin DeMello, caml users, vkni

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

You can wrap docopt C++ and use it:

https://github.com/docopt

Watch their short video (Python) for inspiration. Best cmd line parser ever

On Sun, 29 Jul 2018 at 07:26, Gabriel Scherer <gabriel.scherer@gmail.com>
wrote:

> Just in case, Menhir has "demos", small examples of lexer+parser pairs
> and an environment setup (example caller code, build script...). The
> simplest demo is "calc"
>
>   https://gitlab.inria.fr/fpottier/menhir/tree/master/demos/calc
>
> a syntax for arithmetic expressions such as "(1 + 3) * 5 + 2".
>
> It should be fairly easy to get a syntax for set operators by
> replacing "*" with "Intersection" and "+" with "Union" in the Lexer,
> and integer literals by feature names.
> On Sun, Jul 29, 2018 at 2:27 AM Martin DeMello <martindemello@gmail.com>
> wrote:
> >
> > How about "lexing" them into a list of operation tokens, then using the
> shunting-yard algorithm to parse them into an expression tree? that would
> allow arbitrary recursive expressions and still be relatively
> straightforward to process.
> >
> > martin
> >
> > On Sat, Jul 28, 2018 at 2:16 PM, Kenneth Adam Miller <
> kennethadammiller@gmail.com> wrote:
> >>
> >> I understand other people have written those things before, and that
> it's probably not so challenging to someone else, and I'm not saying I
> can't or wouldn't write it, but I'm under deadline pressure, and I think it
> would not be looked up on well if I had something with anywhere near so
> many features or as much work to deliver since if they even exist. Since I
> have to demonstrate this, the first question they are going to ask is "you
> spent more than X minutes working on this when you could have been working
> on the minimum viable product!! Unhappy!!" So I'm not disregarding the
> input I've got, but I think that I can achieve a less robust working
> version with the same set of features in a simpler fashion.
> >>
> >> So, instead I think can get something very near to a full grammar,
> while still allowing the fundamental operations I want. Here's what I've
> got:
> >>
> >>
> >> type setop =
> >>   | Intersection
> >>   | Difference
> >>   | Union
> >> [@@deriving sexp]
> >>
> >> let list_setops = [
> >>     "Intersection", Intersection;
> >>     "Difference", Difference;
> >>     "Union", Union;
> >> ]
> >> let setops_doc = List.(to_string ~f:fst (list_setops))
> >> let setops =
> >>   let doc = "." in
> >>   Cmdliner.Arg.(
> >>     value & opt_all (some (pair ~sep:'=' string & pair (enum
> (list_setops)) & pair string string)) []
> >>     & info ["setop"] ~docv:setops_doc ~doc
> >>   )
> >>
> >>
> >> Instead of having an recursive variant instance in the type setop place
> to allow the grammar to be recursive, I will fold over the setops, and add
> each one to a map. For example, I might have:
> >>
> >> --setop Red=Union (Feature1, Feature2) --setop Green=Intersection (Red,
> Feature3)
> >>
> >> So that, as I fold, I will add colors to the feature set. Then, for
> whatever nested operations otherwise would have been required, I can just
> manually unfold them on the command line.
> >>
> >> I guess I've solved my problem, but I was hoping to get a recursive
> parsing capability on the command line that would have supporting a type
> declaration more like the following:
> >>
> >> type setop =
> >>   | Result of setop
> >>   | Intersection of string * string
> >>   | Difference of string * string
> >>   | Union of string * string
> >>
> >> The problem with this is, 1) the constructors are non-uniform so that
> there isn't a clean way to specify to the Cmdliner.Arg.value function what
> the converter should be 2) The list type of their resulting pairwise
> sub-command specifications to the command line (the "enum list_setops"
> part) becomes much harder to specify since those also need to be
> constructible in the string - type pairs for the list_setops argument to
> enum.
> >>
> >> I suppose my thinking about how to deal with this would be to write a
> custom conv to convert the command line input, but to do so it would have
> to be recursive, and the Cmdliner.Arg.enum would have to support both
> non-uniform constructors and an argument conv to be able to do this
> correctly.
> >>
> >> Does anybody have a better way to capture what I'm looking to do?
> >>
> >> On Sat, Jul 28, 2018 at 10:54 AM Андрей Бергман <vkni@yandex.ru> wrote:
> >>>
> >>> Probably a parser combinator with a small language would be a better
> tool for that. Parser generators look too heavy, and comman-line parsers
> are too light (otherwise they become optparse-applicative, which is too
> specific to study it => everyone uses cookbook).
> >
> >
>
> --
> Caml-list mailing list.  Subscription management and archives:
> https://sympa.inria.fr/sympa/arc/caml-list
> Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
> Bug reports: http://caml.inria.fr/bin/caml-bugs

-- 
Kind regards,
Viet

-- 
Caml-list mailing list.  Subscription management and archives:
https://sympa.inria.fr/sympa/arc/caml-list
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
Bug reports: http://caml.inria.fr/bin/caml-bugs

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

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

end of thread, back to index

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-07-27 18:11 [Caml-list] cmdliner difficulties Kenneth Adam Miller
2018-07-27 19:26 ` Gabriel Scherer
2018-07-28 22:44 ` Андрей Бергман
2018-07-28 20:17   ` Kenneth Adam Miller
2018-07-29  0:26     ` Martin DeMello
2018-07-29  6:25       ` Gabriel Scherer
2018-07-29  7:00         ` Viet Le

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