[Haskell-cafe] Wow Monads!

Richard A. O'Keefe ok at cs.otago.ac.nz
Wed Apr 19 09:42:36 UTC 2017

> On 19/04/2017, at 7:23 PM, Joachim Durchholz <jo at durchholz.org> wrote:
>> However, having said "Lisp-style macros", Lisp is a tree with many branches.
>> How about Scheme-style macros?
> I can't tell the difference anymore,

MAJOR differences.

Lisp macros: run *imperative* *scope-insensitive* macros to do source to source
transformation at compilation or interpretation time.

Scheme macros: run *declarative* *scope-sensitive* macros to do source to source
transformation at compilation or interpretation time.

> The general finding, however, was what both were very, very heavy on enabling all kinds of cool and nifty features, but also very, very weak on making it easy to understand existing code.

With respect to Common Lisp, I'm half-way inclined to give you an argument.
Macros, used *carefully*, can give massive improvements in readability.
Let's face it, one bit of Lisp (APL, SML, OCaml, Haskell) code looks pretty
much like another.  The way I've seen macros used -- and the way I've used
them myself -- makes code MORE understandable, not less.

All it takes is documentation.

In Scheme, however, I flatly deny that macros in any way make it harder to
understand existing code than functions do.

> Essentially, each ecosystem with its set of macros, multiple-dispatch conventions, hook systems and whatnow, to the point that it is its own language that you have to learn.

And how is this different from each ecosystem having its own set of operators (with the same
names but different precedence and semantics) or its own functions (with the same name but
different arities and semantics)?

This is why Common Lisp has packages
and R6RS and later Scheme have modules.
Yes, different subsystems can have different vocabularies of macros,
just as different modules in Haskell can have different vocabularies
of types, operators, and functions.
They don't interfere, thanks to the package or module system.

> That's essentially why I lost interest: None of what I was learning would enable me to actually work in any project, I'd have to add more time to even understand the libraries, let alone contribute.

That *really* doesn't sound one tiny bit different from trying to work on
someone else's Java or Haskell code.

My own experience with Lisp was writing tens of thousands of lines to fit into
hundreds of thousands, and my experience was very different from yours.
Macros were *defined* sparingly, *documented* thoroughly, and *used* freely.
Result: clarity.

> The other realization was that these extension mechanisms could make code non-interoperable,

I fail to see how define-syntax encapsulated in modules could possibly
make Scheme code non-interoperable.

> and there was no easy way to find out whether there would be a problem or not.

Scheme answer: there isn't.  OK, in R5RS there _was_ a problem that two files
could both try to define the same macro, but that's not different in kind from
the problem that two files could try to define the same function.  In R6RS and
R7RS, the module system catches that.
> Java does a lot of things badly, but it got this one right. I can easily integrate whatever library I want, and it "just works", there are no linker errors, incompatible memory layouts, and what else is making the reuse external C++ libraries so hard.

Fell off chair laughing hysterically.  Or was that screaming with remembered
pain?  I am sick to death of Java code *NOT* "just working".
I am particularly unthrilled about Java code that *used* to work ceasing to work.
I am also sick of working code that gets thousands of deprecation warnings.

I am particularly tired of having to grovel through thousands of pages of bad
documentation, to the point where it's often less effort to write my own code.

I am *ALSO* sick of trying to match up Java libraries that only build with Ant
and Java libraries that only build with Maven.  (Yes, I know about just putting
.jar files in the right place.  I've also heard of the Easter Bunny.)

> Nowadays, the first step in any new project is to see what libraries we need. Integration is usually just a configuration line in the build tool (you don't have build tools in Lisp so that's a downside,

Wrong.  There are build tools for Common Lisp and have been for a long time.
I didn't actually know that myself until I saw a student -- who was using
Common Lisp without any of us having ever mentioned it to him -- using one.

Look, it's really simple.
If programmers *WANT* to write readable code
and are *ALLOWED TIME* to write readable code, they will.
Whatever the language.
If they have other priorities or constraints, they won't.
Whatever the language.

More information about the Haskell-Cafe mailing list