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

Re: Several comments

This page is part of the web mail archives of SRFI 22 from before July 7th, 2015. The new archives for SRFI 22 contain all messages, not just those from before July 7th, 2015.



> Marc> Could you also respond to the rest of my comments, where I don't
> Marc> see a need for an entry point?
> 
> Ermh, there's been a somewhat misleading heading called "Implicit
> vs. Explicit Command-Line Parameter Access" in the SRFI from day 1
> which still holds.

Fine.  I reproduce it below.

> Implicit vs. Explicit Command-Line-Parameter Access
> 
> This SRFI specifies that the Scheme script interpreters will
> communicate the command-line arguments to the script as arguments to
> the procedur specified as the first command-line argument. Some Scheme
> implementations use a special global variable that holds the
> arguments. It is not clear that one alternative is inherently
> preferable to another. Neither is it clear whether a vector or a list
> is the more natural data structure.
> 
> However, explicitly specifying an entry point has the advantage that
> scripts are easier to debug with a REPL-type Scheme implementation -
> it is easily possible to call the script entry point explicitly from
> the REPL, demonstrably achieving the same effect as loading the script
> from the interpreter.

So the main advantage is to simplify debugging the shell script
interactively.  I can understand that.

However, this comes at the expense of "compilability", that is the
compiler must parse the header to discover what the entry point
procedure is and which command line arguments are to be passed to the
entry point procedure.  This is difficult and fragile at best, because
the compiler must know the shell parsing algorithm, and understand
"IFS=...", etc.  Moreover it means "load" ignores the entry point
information when loading a source file (so you can debug), but does
not ignore it when loading a "fasl" file.  This breaks the equivalence
between "interpreted" and "compiled" code.  Finally, that extra entry
point information eats at the 32 byte limit, when scheme-script is
used as the scripts interpreter (i.e. after the "#!" on the first
line).

My approach, which eliminates the need for an entry point information,
could be made to work for debugging if you make
"command-line-arguments" a parameter (in the sense of Chez Scheme's
and PLTScheme's "make-parameter").  To debug a script "S" such as

  #! /bin/sh
  "exec" "scheme-script" "$0" "$@"
  (define (main arg1 arg2)
    (write (+ (string->number arg1) (string->number arg2))))
  (apply main (command-line-arguments))

and call it with arguments "100" and "200" you would do:

  (parameterize ((command-line-arguments '("100" "200"))) (load "S"))

Alternatively the procedure "script-arguments" could be used instead
of "command-line-arguments" like this

  #! /bin/sh
  "exec" "scheme-script" "$0" "$@"
  (define (main arg1 arg2)
    (write (+ (string->number arg1) (string->number arg2))))
  (apply main (script-arguments))

and have that procedure return the command line arguments only when it
is loaded as a script, and signal an error otherwise.  So to debug the
file you simply (load "S") and the debugger gives an error saying
something like "Attempt to load a script in an inappropriate context",
and then you can simply call "main" directly (I'm assuming the "apply"
would be required to be the last line of the script).  This has the
additional advantage that you can be warned of the missuse of a script
as a plain source code file.

A third alternative, which is my least favorite is to pin down the
name of the entry point, for example "script-main".  A script would
look like this

  #! /bin/sh
  "exec" "scheme-script" "$0" "$@"
  (define (script-main arg1 arg2)
    (write (+ (string->number arg1) (string->number arg2))))

and "scheme-script" would always invoke "script-main" after loading a
script.

Marc