summaryrefslogtreecommitdiff
path: root/artima
diff options
context:
space:
mode:
authormichele.simionato <devnull@localhost>2009-06-11 03:55:22 +0000
committermichele.simionato <devnull@localhost>2009-06-11 03:55:22 +0000
commit6e250c8e4cd545d829f562242acafef06234f6b3 (patch)
treed7706df193bbe4f85a6a8a38346eea37de28dd01 /artima
parentda5a44c9e603325eeb0f954a84bb46e6d154ed71 (diff)
downloadmicheles-6e250c8e4cd545d829f562242acafef06234f6b3.tar.gz
Published version of scheme26
Diffstat (limited to 'artima')
-rw-r--r--artima/scheme/scheme26.ss168
1 files changed, 81 insertions, 87 deletions
diff --git a/artima/scheme/scheme26.ss b/artima/scheme/scheme26.ss
index 9e4960a..31aa3f3 100644
--- a/artima/scheme/scheme26.ss
+++ b/artima/scheme/scheme26.ss
@@ -1,19 +1,18 @@
#|Macros taking macros as arguments
============================================================
-There is no upper limit to the level of sophistication you can reach
-with macros: in particular it is possible to define higher order
-macros, i.e. macros taking other macros as arguments or macros
-expanding to other macros. Higher order macros allow an extremely
-elegant and compact programming style; on the other hand, they are
-exposed to the risk of making the code incomprehensible and pretty hard to
-debug. We already saw an example of macro expanding to a macro
-transformer in episode 22_, and explained the intricacies of the tower
-of meta-levels; in this episode instead I will consider a much simpler class
-of higher order macros, macros taking macros as arguments, but
-not expanding to macros (or macro transformers) themselves. Moreover,
-I will spend some time discussing the philosophy of Scheme and
-explaining the real reason why there are so many parentheses.
+There is no limit to the sophistication of macros: for instance,
+it is possible to define higher order macros, i.e. macros
+taking other macros as arguments or macros expanding into other
+macros. Higher order macros allow an extremely compact and elegant
+programming style; on the other hand, they are exposed to the risk of
+making the code incomprehensible and pretty hard to debug. I have already
+shown an example of macro expanding into a macro transformer in episode
+22_, and explained the intricacies of the tower of meta-levels; in
+this episode instead I will consider a much simpler class of higher
+order macros, macros taking macros as arguments. Moreover, I will spend some
+time discussing the philosophy of Scheme and explaining the real
+reason why there are so many parentheses.
.. _22: http://www.artima.com/weblogs/viewpost.jsp?thread=256848
@@ -23,78 +22,56 @@ Scheme as an unfinished language
Most programmers are used to work with a *finished* language. With
*finished*, I mean that the language provides not only a basic core of
functionalities, but also a toolbox of ready-made solutions making the
-life of the application programmer easier. Here I am not
+life of the application programmer easier. Notice that here I am not
considering the quality of the library coming with the language (which
is extremely important of course) but language-level features, such as
providing syntactic sugar for common use cases.
As a matter of fact, developers of the XXIth century take for granted a
-*lot* of language features that were unusual just a few years
+*lot* of language features that were uncommon just a few years
ago. This is particularly true for developers working with dynamic
languages, which are used to features like built-in support for regular
expressions, a standard object system with a Meta Object Protocol, a
-standard Foreign Function Interface, a sockets/networking interface,
+Foreign Function Interface, a sockets/networking interface,
support for concurrency via microthread *and* native threads *and*
multiprocesses and more; nowadays `even Javascript`_ has list
comprehension and generators!
-Finished languages spoil the programmer, and this is the
-reason why they are so much popular nowadays. Of course not all
-finished languages are equivalent, ans some are powerful or easy to
-use. Some will prefer Python over Java, others will
-prefer Ruby, or Scala, or something else, but the concept of finished
-language should be clear. Certainly Scheme, at least as specified
-in the R6RS standard - I am not talking about concrete implementations
-here - is missing lots of the features that modern languages
-provide out the box. Compared to the expectations of the
-modern developer, Scheme feels very much like an unfinished language.
-
-I think the explanation for the current situation in Scheme is more
-historical and social than technical. On one side, a lot of people in
+Modern finished languages spoil the programmer, and this is the reason
+why they are so much popular. Of course not all finished languages are
+equivalent, and some are more powerful and/or easier to use than
+others. Some programmers will prefer Python over Java, others will prefer
+Ruby, or Scala, or something else, but the concept of finished
+language should be clear. On the other hand Scheme, at least as specified in
+the R6RS standard - I am not talking about concrete implementations
+here - is missing lots of the features that modern languages provide
+out the box. Compared to the expectations of the modern developer,
+Scheme feels very much like an unfinished language.
+
+I think the explanation for the current situation is more
+historical and social than technical. On one hand, a lot of people in
the Scheme world want Scheme to stay the way it is, i.e. a language
for language experimentations and research more than a language for
enterprise work (for instance a standard object system would
effectively kill the ability to experiment with other object
systems and this is not wanted).
-On the other side, the fact that there are so many
+On the other hand, the fact that there are so many
implementations of Scheme makes difficult/impossible to specify too
much: this the reason why there are no standard debugging tools for
Scheme, but only implementation-specific ones.
-Finally, there is the infamous `bikeshed effect`_ to take in account.
-The bikeshed effect is typical of any project designed by a committee:
-when it comes to proposing advanced functionalities that very few
-can understand, it is easy to get approval from the larger community.
-However, when it comes to simple functionality of common usage, everybody
-has got a different opinion and it is practically impossible to get
-anything approved at all.
-
-.. image:: bikeshed.jpg
- :class: right
- :width: 400
-
-To avoid that, the standard does not provide
-directly usable instruments: instead, it provides general instruments
-which are intended as building blocks on that of which everybody can
-write the usable abstractions he/she prefers.
-
.. _even Javascript: https://developer.mozilla.org/en/New_in_JavaScript_1.7
-The difference between Scheme and its concrete implementations
---------------------------------------------------------------------
-
-While for many features there are objective reasons why Scheme it is
-the way it is and could not be different, for many other features
-Scheme has been left unfinished by choice, not by necessity: the language was
-left incomplete, but with a built-in mechanism enabling the user
-to finish the language according to his/her preferences. Such a
-mechanism of course is the mechanism of macros. Actually, one of the
-main use of macros is to fill the deficiencies left out by the
-standard. Most people nowadays prefer to have ready-made solutions,
-because they have deadlines, projects to complete and no time nor
-interest in writing things that should be made by language designers,
-so they dismiss Scheme immediately after having having read the
-standard specification.
+Even if the Scheme language has been left unfinished - it does not matter
+if by choice or out of necessity - it has been equipped with a
+built-in mechanism enabling the user to finish the language according
+to his/her preferences. Such a mechanism is of course the mechanism of
+macros. Actually, one of the main use of macros is to fill out the
+deficiencies left out by the standard. Most people nowadays prefer to
+have ready-made solutions, because they have deadlines, projects to
+complete and no time nor interest in writing things that should be
+made by language designers, so they dismiss Scheme immediately after
+having having read the standard specification.
However, one should make a distinction: while it is
true that Scheme - in the sense of the language specified by the
@@ -152,9 +129,10 @@ Two second order macros to reduce parentheses
A typical example of idle speculation is
the following question: can we find a way to reduce the number of
parentheses required in Scheme? Finding tricks for reducing parentheses
-is pointless, but it gives me a reason to teach a few other macro programming
-techniques: in particular, here I will discuss second order
-macros taking macros as arguments.
+is a pointless exercise per se, but it gives a reason to teach a few other
+macro programming techniques - in particular second order
+macros taking macros as arguments - and to explain why parentheses
+are actually good and should not be removed.
In episode 25_ I defined a recursive ``cond-`` macro taking
less parentheses than a regular ``cond``, using an accumulator. Here
@@ -194,20 +172,20 @@ The colon macro expects as argument another macro, the
``let-form``, which can be any binding macro such that
``(let-form ((patt value) ...) expr)`` is a valid syntax. For instance
``(let ((name value) ...) expr)`` can be rewritten as ``(: let name value
-... expr)``, by removing four parentheses. Here is a test:
+... expr)``, by removing four parentheses. Here is a test with ``let*``:
$$TEST-COLON
The latest version of the ``aps`` package provides a colon ``:`` form in the
``(aps lang)`` module. In the following Adventures I will never use
``collecting-pairs`` and ``:`` since I actually like parentheses.
-The reason is that parens make it easier to write macros, as I
-argue in the next paragraph.
+The reason is that parens make it easier to write macros with
+pattern matching techniques, as I argue in the next paragraph.
The case for parentheses
-------------------------------------------------------------
-Parens-haters may want to use ``collecting-pairs`` and the colon macro
+Paren-haters may want to use ``collecting-pairs`` and the colon macro
to avoid parentheses. They may even go further, and rant that the
basic Scheme syntax should require less parentheses.
However, that would be against the Scheme philosophy:
@@ -227,17 +205,15 @@ for instance Paul Graham's Arc_ uses less parentheses. This is
possible since it does not provide a macro system based on
pattern matching (which is a big *minus* in my opinion).
-Is it possible
-to have both? A syntax with few parentheses for writing code manually
-and a syntax with many parentheses for writing macros?
-The answer is yes:
-the price to pay is to double the constructs of the language, by
-using a Python-like approach.
-Python is a language with a two-level syntax: a
-simple syntax, limited but able to cover the most common case, and a
-fully fledged syntax, giving all the power you need, which
-however is used rarely. For instance, here a table showing
-some of the most common syntactic sugar used in the Python language:
+Is it possible to have both a syntax with few parentheses for writing
+code manually and a syntax with many parentheses for writing macros?
+Clearly the answer is yes: the price to pay is to double the
+constructs of the language. Python is an example of such a language
+with a two-level syntax: it provides both a simple syntax, limited but
+able to cover the most common case, and a fully fledged syntax, giving
+all the power you need, which however is used rarely. For instance,
+here a table showing some of the most common syntactic sugar used in
+the Python language:
==================== =================================
Simplified syntax Full syntax
@@ -248,18 +224,36 @@ c = C() c = C.__new__(C); c.__init__()
==================== =================================
In principle, the Scheme language could follow exactly the same route,
-by providing syntactic sugar for the common cases and a
-low level syntax for the generic case. For instance, in the case of the
+by providing syntactic sugar for the common cases and a low level
+syntax for the general case. For instance, in the case of the
conditional syntax, we could have a fully parenthesized ``__cond__``
syntax for usage in macros and ``cond`` syntax with less parens for
manual usage. That, in theory: in practice Scheme only provides the
low level syntax, leaving to the final user the freedom (and the
-burden) of implementing his preferred high level syntax.
-Since syntax is such a subjective topic, in practice I think it is
-impossible for a language designed by a committee to converge on
-an high level syntax. On the other hand Lisp-like languages
+burden) of implementing his preferred high level syntax. Since syntax
+is such a subjective topic, in practice I think it is impossible for a
+language designed by a committee to converge on an high level
+syntax. This is a consequence of the infamous `bikeshed effect`_.
+
+The bikeshed effect is typical of any project
+designed by a committee: when it comes to proposing advanced
+functionalities that very few can understand, it is easy to get
+approval from the larger community. However, when it comes to simple
+functionality of common usage, everybody has got a different opinion
+and it is practically impossible to get anything approved at all.
+
+.. image:: bikeshed.jpg
+ :class: right
+ :width: 400
+
+To avoid that, the standard does not provide
+directly usable instruments: instead, it provides general instruments
+which are intended as building blocks on that of which everybody can
+write the usable abstractions he/she prefers.
+On the other hand Lisp-like languages
designed by a BDFL_ (like Arc_ and Clojure_) provide a high level
-syntax. You may try it and see if you like it. Good luck!
+syntax, which is the one the BDFL like.
+You may try it and see if you like it. Good luck!
.. _Arc: http://www.paulgraham.com/arcll1.html
|#