[mercury-users] Problem with mmake
Richard A. O'Keefe
ok at atlas.otago.ac.nz
Fri Jun 8 10:27:47 AEST 2001
Concerning the way environment variables have metastasised in Mercury,
Fergus Henderson <fjh at cs.mu.OZ.AU> wrote:
I'm afraid I remain unenlightened.
Sigh. It seems that everyone is out of step except Mercury.
I don't see how changing N environment variables into N
configuration file commands would reduce complexity. I also
remain unconvinced that it would increase convenience.
How can anyone argue with the brute fact that it *IS* much more convenient
to create and run Haskell programs using GHC than to create or run Mercury
programs? I don't recall when I've _ever_ had so much trouble with the
compilation interface for some programmung language on UNIX.
The core of the problem is that environment variables are promiscuous.
If you set MERCURY_OPTIONS, then _every_ Mercury program you run will be
affected, presumably including the Mercury compiler itself. For things
like $USER, $TERM, $HOME, $SHELL, $TERM, locale, timezone, and so on,
things can reasonably be taken as constant for this-user-at-this-terminal-
this-session, environment variables make sense. For things like "what
directories should be searched for libraries", environment variables do
NOT make sense, and LD_LIBRARY_PATH has abundantly proved this in practice.
Fortunately, ld(1) has an option "-R" (some UNIX systems) or "-rpath" (some
other UNIX systems) to enable that information to be bound with the program,
as it should be. Basically, good design has it that
- stuff which is the same for almost every program can go in
environment variables
- stuff which depends on the program but is the same for almost every
execution of that program is bound into the executable or can go in
runtime configuration files (.mailrc, .indent.pro, and so on)
- stuff which depends on the program but is only used as compile time:
makefiles
- stuff which is likely to be different for different executions can go in
command line options and arguments.
The complexity I am alluding to is not the complexity of *setting up*
a configuration, but the complexity of *selecting* a configuration.
At the implementation level I think it might well *increase*
complexity. Environment variables are very easy to access from
shell scripts. Any other mechanism is likely to be more complex.
I am writing as a Mercury *user*. My concern is not with the difficulty
of implementing Mercury, but the difficulty of *using* it. Having written
a configuration file parser (you could write sh, csh, Prolog, or even Lisp
configuration files that it could read, with a little care), I am totally
unimpressed by the argument that this might be complex; it wasn't.
More generally, all you need is something like
mmconfig {program} {key}
and then a shell script (in any shell dialect) can do
FOO_OPTION=`mmconfig $thisprog whatsit`
using the syntax appropriate to the shell.
(Hmm... I guess we could use configuration files in shell syntax,
and parse them using the shell's source command (`.' in Bourne shell).
That would be simple enough. But I'm still not convinced that doing
this would be worth the hassle that such a change would entail.)
What hassle? More to the point, *whose* hassle?
> The mechanism is already groaning in every joint with some variables
> having more-or-less simple values and other variables having structured
> values (complete with rather pointless, given the context, double dashes).
For the Mercury runtime system we use the getopt_long() routine
to parse the runtime options.
Once again, *whose* hassle?
It seemed pointless to invent a new options syntax and to write
a parser for it, just because we were passing options via an
environment variable rather than on the command line.
But that is an argument for using the UNIX standard "getsubopt()" syntax!
(Free versions of getsubopt() are available, including one from me.)
In fact, in terms of "whose hassle", it would be noticeably easier for the
Mercury implementors to use getsubopt() than getopt_long() there.
> It is the simplest thing that can possibly work.
> Amongst other things, if I want to flip from one configuration to
> another, there is *ONE* thing to change; there is no possibility
> of an "incomplete edit" leaving me part way between two configurations.
OK, that is one thing that would be more convenient with the approach
that you suggest.
Right, and it is the major thing, because if you have a collection of
Mercury programs, they will want different configurations and you want
to give each program its correct configuration as easily as possibhle.
But the drawback of your approach is that changing a single configuration
parameter while leaving the others unchanged is more difficult.
And that is in my experience a significantly more common operation.
All I can say as a Mercury user, not implementor, is that it isn't mine.
Apparently if I want GC to work, I am going to have to switch LD_LIBRARY_PATH
every time I switch grade.
I have already pointed out that switching a single parameter need not be
hard. Is there room for a compromise?
(1) Let there be configuration files.
(2) Let mld/mmake be able to bind a particular program to either a particular
configuration file or the contents of a particular configuration file at
build time.
Then people can deploy and use their Mercury programs without any environment
variable setting whatsoever, and what could be less complex or more
convenient than that?
(3) Let the programs still check whether the environment variables are
defined, and if they are, heed them.
Then people who want to frob one parameter the same way for a dozen
programs can do so the same way they do now.
> I am really confused that anyone would find this a difficult concept to
> grasp. The more knobs there are, and the more places they are, the harder
> it is to get them right.
But we're not talking about reducing the number of nobs,
or even about reducing the number of places where they are,
just about moving them!
We _are_ talking about the number of places they are. Instead of being in
.cshrc or .login or .profile or this shell script or that shell script or
typed in by hand or in the sh command line, I was proposing that they would
all be set in a single configuration file (one per program).
And we are most definitely talking about the reducing the number of knobs
*that have to be set by Mercury users*.
> A quick check turned up fourteen MERCURY_ environment variables:
...
> Netscape gets by with one.
I don't think counting the number of environment variables
is always the best way to measure complexity.
It is when you're talking about the complexity of setting up the right
configuration of environment variables!
Netscape probably has more than fourteen different configuration files,
each of which contain many different configuration settings.
It has more configuration _settings_ that one, but as far as I can tell by
poking around in ~/.netscape they are in one _file_.
I don't think that changing environment variables into configuration
commands will by itself reduce complexity, unless you choose to
measure complexity simply be the number of environment variables.
I am measuring complexity by the number of inconsistent states I can get
into and by the number of things I as a Mercury user have to worry about.
But the Mercury runtime system's use of MERCURY_OPTIONS isn't an example of
the "one variable *points to* a complete configuration" approach.
Rather, it is a "one variable *contains* a complete configuration" approach.
I have no problem with that. Put _everything_ in there, and make it possible
to bind that into a program when it is built, and I'll be happy.
This is actually a quite significant difference, because this approach
makes it much easier to selectively override individual seetings.
Another approach which is about half way between what you are proposing
and what we use with MERCURY_OPTIONS would be to have a single environment
variable which contains that contained a *list* of configuration files.
That's very close to one of the alternatives I suggested.
FJH doesn't understand why I see the present interface as difficult.
I don't understand why it would be *common* to frob a single parameter.
This probably means I don't know how to use the Mercury tools anywhere
near as effectively as he does. Perhaps an example of why this is
a *commonly* useful thing to do would clarify matters.
It *is* possible to override a single configuration setting selectively
using MERCURY_OPTIONS, as explained above.
This was not obvious from reading the documentation. If it is a common
thing to do, perhaps it should be spelled out in the User's Guide with
an example.
> The claim that pointing-to-configuration-files would mean that there would
> be "no easy way to selectively override a single configuration setting" is,
> as I explained in a previous message, simply false. That's what a "source"
> mechanism is for.
That doesn't work, as I explained, because you don't know the name of
the previous configuration file to source:
So tell us, and then that problem disappears, no?
> You are assuming that it is common to twiddle one configuration parameter
> *in a way you'll never want again*.
No, just in a way that preserves the rest of the current environmen's
configuration parameter settings, whatever that environment is.
> In the unlikely event that this *shold* be common practice in the Mercury
> world, I have now spent the last 20 minutes writing and testing a UNIX
> utility
> setvar variable value command...
> that creates a temporary file, copies $CONFIG (if that exists) or
> ~/.config (if that exists) to it, adds
> export variable; variable="value"
> _with_ appropriate backslashes in "value", runs command, and then deletes
> the temporary file. It took just 70 SLOC. I don't call that hard.
Now *you're* kidding *me*, right? ;-)
No. There is something I have _never_ wanted to do, but you say it is
_common_. Wearing an implementor's hat, I proved that it is easy for me
as an implementor to provide a utility that lets you do what you want.
Note the difference between
set oldx="$MERCURY_x"
setenv MERCURY_x "new x value"
myprog <in >out
setenv MERCURY_x "$oldx"
which is how you temporarily change one environment variable in the C
shell, and
setvar MERCURY_x "new x value" myprog <in >out
which is how you'd do it using configuration files and my 70-SLOC C utility.
I don't call setvar hard to use, and I don't call a 70-SLOC C program hard
to write (once, as an implementor, and provide with Mercury).
Admittedly, if you use sh, the choice is between
MERCURY_x="new x value" myprog <in >out
and
setvar MERCURY_x "new x value" myprog <in >out
but the sh syntax doesn't work in csh.
--------------------------------------------------------------------------
mercury-users mailing list
post: mercury-users at cs.mu.oz.au
administrative address: owner-mercury-users at cs.mu.oz.au
unsubscribe: Address: mercury-users-request at cs.mu.oz.au Message: unsubscribe
subscribe: Address: mercury-users-request at cs.mu.oz.au Message: subscribe
--------------------------------------------------------------------------
More information about the users
mailing list