[Haskell-cafe] Why Haskell is beautiful to the novice

Richard A. O'Keefe ok at cs.otago.ac.nz
Tue Sep 1 23:34:32 UTC 2015


On 31/08/2015, at 8:27 pm, Alexey Muranov <alexey.muranov at gmail.com> wrote:
> 
> In my opinion, with such interpretation there can be no documented side effects: if some effect is documented, it is purported (an probably used by someone), so not secondary.

Let's see a piece of actual Java code, not written by me.

public class Record {
    private static final AtomicLongFieldUpdater<Record> VERSION =
        AtomicLongFieldUpdater.newUpdater(Record.class, "version");

    private volatile long version = 0;

    public long update() {
        return VERSION.incrementAndGet(this);  // THIS LINE IN JAVA
    }
}

For comparison, here's basically the same thing in C on OSX:

struct Record {
    volatile int64_t version = 0;
};

// Atomic this->version++
int64_t update(struct Record *this) {
    return OSAtomicIncrement64(&this->version);  // THIS LINE IN C
}

THIS LINE IN C has an effect.   It's obvious from the code
that the variable `version' may be affected.

THIS LINE IN JAVA doesn't as much as mention `version'.

Surely there is a qualitative difference here that *matters*?

Historic note:  Java forbade 'var' or 'reference' parameters
in the name of object-oriented purity.  i have never been able
to figure out what they meant.  What they have instead is, and
I kid you not, AtomicLongFieldUpdate is an official Java public
class, is POINTER ARITHMETIC.  (AtomicLongFieldUpdater basically
holds a reference to a class and an offset within that class,
which gets added to the argument to find the actual variable.)

I just learned about AtomicLongFieldUpdater yesterday and still
feel sick.  Java just moved from "I don't particularly like it
but it could be worse" to "heck, I might as well just use C" in
my estimation.  What I am still having difficulty swallowing is
the Java enthusiasts who think this feature is wonderful.

But this is a Haskell mailing list, not a Java or C one.
For *Haskell*, the type system doesn't encode *all* the
effects of an operation (although a functional language
type system *could* do so), but it forces you to reveal
that an operation has *some* effect other than returning
a value and *encourages* you to factor your state space
into chunks smaller than the whole world.  If you have two
state monads and you need to update both, you *know* you
have an issue.






More information about the Haskell-Cafe mailing list