Proposal Summary: Add setEnv/unsetEnv to "base"

Simon Hengel sol at
Mon Nov 19 17:39:57 CET 2012

On Mon, Nov 19, 2012 at 08:54:11AM +0800, Conrad Parker wrote:
> On 19 November 2012 03:43, Simon Hengel <sol at> wrote:
> >> I propose to add setEnv/unsetEnv to System.Environment, so that it is
> >> easier to write applications that behave the same on POSIX and Windows
> >> systems.
> >
> > I finally prepared a patch for "base" [1].  Contrary to what I
> > originally assumed, getting it right on POSIX systems is much harder
> > than on Windows.
> >
> > Here is the summary of the discussion:
> >
> > As I understand it, Duncan Coutts, Gregory Collins, Edward A. Kmett and
> > Ben Millwood support the proposal.
> >
> > Gregory Collins noted that
> >
> >> you can get rid of unsetEnv if you make setEnv take a "Maybe String",
> >> which might be better.  Ultimately though, who cares what color the
> >> bike shed is painted :)
> >
> > And I explained that
> >
> >> on Windows, setEnv "FOO" "" will remove FOO from the environment.  I
> >> don't particularly like it, but as my stated goal was to provide the
> >> exact same behavior on all platforms and there is no way to work
> >> around this on Windows my implementation does the same thing.
> >>
> >> People who don't care for Windows support and want to set an
> >> environment variable to the empty string can still use "unix".
> >>
> >> So short answer: setEnv already supports removing.
> I don't understand why we need the same interface everywhere.

For me it's just a trade-off between "having an implementation with
consistent but somewhat odd semantics" and "having system dependent
semantics".  I do not really like any of those options, so I initially
choose what I think is easiest to deal with from both an implementers
and users point of view.

Personally, I'd prefer to have:

    setEnv   :: NonEmptyString -> NonEmptyString -> IO ()
    unsetEnv :: NonEmptyString -> IO ()

And I hope that we will have a commonly agreed upon way to express this
in the future.  But I think currently it's not an option (I'd love to be
convinced otherwise ;).

> and no-one wants to be stuck forever with a big difficult lump of code
> implementing legacy idiosyncrasies from Windows (which is about as
> relevant nowadays as VMS).

I still think that if you look at the whole implementation (code, tests,
documentation), an implementation with system dependent semantics is
more work to implement and maintain.

What really would help with simplifying things is if we could assume
that all Unix-like systems provide setenv/unsetenv, and that the return
type of unsetenv is always int.  It's hard to find reliable information
here, but AFAIK we would risk to drop support for HPUX, some (pretty
recent?) versions of Solaris, and some (not so recent?) versions of BSD.

That said, I'm not determined to do it exactly as I proposed it, the
things that I care about is:

 - documentation - it should be clear from the documentation how exactly
   the implementation behaves without looking at the implementation or
   trying it on different systems (including failure behavior!)
 - tests - if we have different behavior on different platforms, we
   probably need to make some tests conditional

So yes, feel free to make more clear what exactly you have in mind.
Ideally in the form of working code, documentation and tests.


More information about the Libraries mailing list