What is a term in the context of cmdliner?

A term or expression is just something you evaluate to a value and that’s all you need to know (and what the tutorial tells you). I honestly don’t think that mixing in a notion of grammar or language or DSL or EDSL is going to make things clearer here.

1 Like

Maybe something like

Cmdliner provides some functions and values that enable describing command-line arguments/flags/options using expressions (called ‘terms’). Terms can then be evaluated to the final ‘parsed’ value of the command line.

And then maybe a small example to drive home the point.

1 Like

Well except that’s a complete mischaracterization of what terms are. You don’t evaluate terms to parsed values of command lines. You evaluate terms to the value returned by the function you lifted therein, which is exactly what the tutorial starts with.

It’s easy to react to this feedback by saying oh you should just do this, say it that way, add this etc. But people should also try to understand the design behind the current tutorial whose progression in fact shows a lot of things without introducing needless or shady terminology and which are important to understand.

Namely you start with the main function, you say what your main function is in a cmdliner program, then you show how you can invoke a function of your program via this new kind of main and then you show how some of the arguments of this invocation can be defined by command line arguments.

Now some people may not be happy with not understanding what a term is beyond the given observational semantics (i.e. an 'a Term is an expression that evaluates to a value of type 'a). That’s ok with me. I suspect it’s better to leave these people unhappy so that those who are ok with that definition don’t need to obscure their mind with an explanation that an 'a Term instruments function application to gather static information about how to go on to parse command line arguments in order to give them as arguments to the function invocation – which is an implementation detail.

1 Like

There’s some truth to that. However, the two main disagreements I have are as follows.

Firstly, for the reader, keeping some bit of terminology on hold is a mental burden. Keeping hearing this word and having to learn it by an accretion of “it can do this” and “use it like that” is much harder to do being given a one-line summary followed by some more information afterwards. The initial summary doesn’t even have to be correct because this is a tutorial (not a formal specification) and the aim is to get the reader to understand. You say “shady” I say “approximate or limited, but not so much as to be useless for didactic purpose.”

In the same line of reasoning, if “a term or expression is just something you evaluate to a value and that’s all you need to know”, why did you call it a term?

Second, maybe other devs have a different workflow, but at least one person here (me) doesn’t start with the main as a cmdliner term. I tend to add cmdliner once I have a basic prototype. In that way, the cmdliner tutorial introduces concepts in a strange order. And because there is no foreshadowing and I am asked to keep the central notion of term on hold as a partially defined mental construct, it is hard to read.

Based on these two points, here are some recommendations. I think you can make the tutorial easier to read even without providing a definition or introducing any GAN. You can just do a bit of foreshadowing. Foreshadowing can help the reader holding onto some partially defined concepts by giving some context to the on-going explanations. Basically, if you know where the explanations are going, they are easier to follow. Something along the lines of:

A term is composed of multiple sub-terms. Some sub-terms lift values from the rest of your program. Typically you lift the main entry point of your program so that cmdliner can call it. Other sub-terms describe command line parameters. These sub-terms allow cmdliner to parse the command line arguments and (typically) pass it to the main entry point of your program.

open Cmdliner
let t = Term.(const entry_point $ Arg.(…))
           (* ^^^^^^^^^^^^^^^^^             lifted main entry point *)
                               (* ^^^^^^^   command-line parameter  *)

This two part short explanation mirrors and signposts the tutorial structure. Specifically, it corresponds to “One way to create terms is by lifting regular OCaml values…” and “Terms corresponding to command line argument data that are part of a term evaluation implicitly define a command line syntax…”.

Also note that this short explanation stays vague (“composed” but how? “lifting” in what sense?) and limited (“typically” ok but what are other possible uses, Arg.(…)) but not incorrect. (Maybe it’s incorrect? Maybe I got it wrong?)

An alternative approach is to add more structure. Specifically, you there are three parts in this tutorial but they are not explicitly marked. By marking them explicitly, you make it easier for the reader to follow along. The three parts are

  • Lift the main entry point of your program.
  • Declare a command-line argument.
  • Define the main function.

And you can structure them by adding three h3 titles in the form of "Step <n>: <short description>". Or you can add three paragraph, one at the beginning of each part, addressing the reader directly. Either approach (or both if you feel verbose) would help.

5 Likes

It seems that we struggle with the same things. I’m glad there is someone with my same issues which is able to express them way better that I could.
Not knowing what a term exactly is was constantly keeping my mind busy with the idea that I was missing something or that I was not understanding something. It was bothering me that much that I had to open this topic to look for some peace of mind in the form of near answers :smile:
I even don’t have problems pushing forward the understanding of what a term is, I did already with some other complex abstractions and today I feel that I understand them. But at least I need that to be able to carry with it. A clear statement that a term is just an abstraction that I don’t need to worry about is more than enough to calm mi mind and continue using the tool. However, for some reason, the way it is used through the documentation was giving me the impression that the understanding of what a term is was key in order to use the tool, my mistake .

Maybe because that’s established terminology and that’s what you do with terms… you evaluate them. There’s no need to invent new concepts and terminology when they already exist.

I could have called that Something_you_evaluate_to_a_value.t but it wouldn’t have been very elegant I think.

There are certainly other worfklows or presentation orders. Whether you need to address all of them in the same tutorial is a question to which I assuredly answer negatively. The www is large enough for having other cmdliner tutorials if there’s the need for it.

I think it’s easier to show the basic mechanics of the library, starting from scratch on the simplest examples. I trust the intelligence of the reader to be able to adapt these simple example to her more complicated use cases.

Besides since the tutorial does show you how to define your main with a main that uses cmdliner I don’t see how it is particulary unfit for addressing your workflow.

I don’t think you made any mistake. You have to understand what terms are in terms of abstraction. That is values that you can construct using combinators and that your program ends up evaluating. Except for the fact that the word was unknown to you and which I plan to address, it’s still a bit unclear to me what tripped you out so much about these terms :–)

I would never suggest you write cmdliner tutorials for the multitude of possible development workflows. I didn’t even suggest that you should change the workflow used in your tutorial. I merely suggested that making the (existing, unchanged) tutorial workflow explicit (with a tiny amount of signposting) would help the reader.

2 Likes

In a PL-heavy audience, perhaps, but not I think for the majority of workaday developers who are looking to use command-line arguments. And especially if you consider that cmdliner introduces its own specific concept of a term, i.e. something which can model command-line flags/options.

1 Like

I think my issue was not that much with the term term (yes, pun intended), or at least that is what this thread made me realize.
Viewing cmdliner with a different mindset (as what is required with most FP things) made it easier to grasp its concepts and move the focus away from term.
The concept of it being a EDSL was really enlightening, and allowed me to take a different perspective on my problem.
As a node-js developer, I am used to import my CMD library, define a few arguments my tool will take and that will translate to arguments my function will take, or I will get back an object containing those arguments. It was basically a 1:1 mapping between the CMD options I was defining and my function arguments, there was nothing in between, and no new concepts were required. However, with CMDLiner it seems to be a totally different thing (or that is how I see it now). It requires a different mental model, and the fact that everything revolves around the term concept made me thought that what I was missing to completely understand cmdliner was “what the hell a term” is. That’s why I opened this thread. I understand that educating me in this required different way of thinking about cmd applications is not a task of the cmdliner documentation, and for that reason I’m glad this healthy community of helpful people exists, so I can ask for clarification on this kind of details. Now I feel that I have the concepts more clear and I feel more confident about using the library (before I was able to get away by the good old copy paste and guess work)
All that said, I thing one of my main confusing parts was that I was not understanding that there are not only the terms that I define myself, but also there are the built in terms, and that composing terms gives you back new terms. Then you need to tie those terms to a command, and finally execute that command. But I am no longer a newcomer to the library, so I may be just more familiar with the terminology.

4 Likes

sorry, what does PL stand for?

Programming Language

1 Like

Thank you for the clarification

@raphael-proust concretely, would you able to suggest a specific paragraph to be included at the head of the cmdliner tutorial?

I was also confused by this problem for a while. After some time with both Cmdliner and Core.Command. I just wrote a post to explain my thoughts : Understanding Core.Command and Cmdliner on my newly built OCaml blog.

Try Understanding two libraries help to under both of them.

  1. A primitive 'a Term.t is a full argument parser for string to 'a. The full means it also specifies other properties e.g. with a flag or not, positional or not.
  2. 'a Term.t can compose using Term.const and Term.($) (like an Applicative).
  3. 'a Arg.t is the parser (and printer) part in a 'a Term.t. 'a Term.t may not used a 'a Arg.t in flag-only case e.g. -v.
14 Likes

I know forums try to prevent posting in topics that are old or marked as solved, so thank you for overcoming those messages and publishing a very valuable message.
Thanks for sharing your findings/experience/knowledge.

I can understand many (all of my often-visited) forums have a similar policy on old topics due to timeliness. However, people(me) may use here as a knowledge base and search for topics and solutions.

This post is listed as the first search result of search?q=cmdline, and the topic is very relevant. I hope to discuss this with people who are more familiar with this topic and also want to share it with others who are a bit confused by the documents.

Do you think my message was rhetoric or ironic or something? Because it was not, was an honest thanks you

No no no no. I am so sorry if I make any inappropriate English (not my first language).

I hope to express my agreement with you and explain why I fight back with it.

1 Like

Not your fault, don’t worry. Because the way I write I sometimes face this kind od misunderstanding. I reread my message and I noticed that it could be misunderstood, so I just wanted to clarify.
I’m happy that we were both honest, and thank you again for your article and diagrams.