guile-user
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: SRFI-37: option


From: Daniel Hartwig
Subject: Re: SRFI-37: option
Date: Wed, 26 Dec 2012 09:18:08 +0800

On 26 December 2012 04:03, Nikita Karetnikov <address@hidden> wrote:
> Hello,
>
> I have some questions about the '%options' variable. [1]
>

Hello

Your questions are mostly answered by an understanding of lambda and
fold, which are common concepts.  I only give brief responses below.
If you have further questions regarding these expressions I recommend
to read one of the many fine tutorials available.

> 1. According to the documentation, 'option' accepts four arguments:
>    'names', 'required-arg?', 'optional-arg?', 'processor' and
>    "processor is a procedure that takes at least 3 arguments..." [2]
>
>    So why do some options (e.g., 'version') only accept a single
>    argument? Does it mean that the above quotation is incorrect?

 (option '(#\V "version") #f #f
         (lambda args
           (show-version-and-exit "guix-package")))

Here the inner procedure accepts any number of arguments and ARGS will
be a list containing those arguments, however many they be.  In the
section (guile)Lambda is documented the various ways to specify a
procedure's arguments (FORMALS).  This procedure uses the second kind.
 Procedures with a fixed set of arguments specify those as a list,
such as:

  (lambda (opt name arg result) …

It does not matter to “option” whether a procedure accepts a fixed or
variable number of arguments as long as it is valid to call it with
the three base arguments and additional seed values.

>
> 2. How does 'processor' work?
>

It is a typical fold-like handler, as used frequently in Scheme and
other Lisps.  On encountering each option, the relevant processor
procedure is called with at least three arguments:
- the definition of the current option;
- it's name as used on the command line; and
- any argument that was present;
and also the seed/accumulated values, however many they be.  The
processor determines how to handle that option and must return one
value for each seed value it received.  How the return values are
determined depends upon how the program handles the options.

To truly understand how processor works, please refer to an indepth
tutorial on using “fold” in Scheme.

>    For instance, 'version' creates a procedure that accepts a single
>    argument (i.e., 'args'), but it doesn't use that argument, does it?

The processor for version does not need to consider the command line
further, neither does processing of the command line arguments
continue after “--version”, so ARGS can be safely ignored in this
case.

Typically with args-fold, at least the seed values must be returned.
These are the fourth and subsequent arguments to processor, such as
“result” with many of the other options in that same file.

> 3. Could you elaborate on 'list-available'?
>
>    What will happen if I run 'guix-package -A nano'?

In terms of program logic:
- args-fold is applied to the list ("-A" "nano"), using %options, and
with %default-options as the initial seed:
  * the first option, “-A” is encountered;
  * the option definition matching “-A” is located in %options;
  * it is noted that there can be an optional argument, and indeed
there is one (“nano”);
  * the processor for this option is called with the appropriate arguments:
    + it prepends (query list-available "nano") to RESULT (which is
%default-options) and returns this value;
  * no more options, so args-fold finished, returning the value it
received from the processor;
- the result from args-fold is handled by process-query, defined later.

> What values will
>    be assigned to 'opt', 'name', 'arg', and 'result'?

A small experiment makes clear :-)

opt: (option '(#\A "list-available") #f #t
             (lambda (opt name arg result)
               (cons `(query list-available ,(or arg ""))
                     result)))))
name: #\A
arg: "nano"
result: %default-options



reply via email to

[Prev in Thread] Current Thread [Next in Thread]