[erlang-questions] Updates, lenses, and why cross-module inlining would be nice
Richard A. O'Keefe
Wed Dec 2 05:36:27 CET 2015
I suppose I should explain some of the things that
trouble me about using headers (.hrl files with lots of -defines)
for, well, just about anything.
(1) Late syntax checking.
-define(foo(F,G), fun (X) -> F(G(X)) end).
passes all the checks that could be done at -define time.
But ?foo(1,2) isn't sensible.
This is much less of a problem in Lisp.
(2) Even when a -define *could* in principle be given a type
that could be checked, there is no way to actually do this.
OK, for much of its life Erlang didn't have any types anyway.
(3) INADVERTENT variable capture.
This is the one that caused me a lot of grief in Lisp,
but at least in Lisp I could do
(let ((X (gensym)) (Y (gensym)))
`(....macro body using ,X and ,Y as variables))
This is a problem that Scheme "hygienic macros" solved.
It's a problem that could be addressed with a slight
change to -define. Let
-define([Variables], Pattern, Replacement).
mean do what -define(Pattern, Replacement) would do
EXCEPT that each identifier in Variables is replaced
by a new variable throughout the replacement.
This was, for example, a real problem for me while writing
lens.hrl, and I am far from sure that I've got it right.
(4) INADVERTENT variable export.
I have no particular wish to change the way variable scope
works in Erlang. But when you are writing macros, and you
want to ensure that an expression is not evaluated twice,
and you write
case Expr of Var -> Body end
then it _is_ a pain in the proctologist's area of expertise
to be told about Var being exported, only matched by the
inadvertent variable capture issue when you're *not* warned...
None of these problems applies to function inlining.
More information about the erlang-questions