From: Chanwoo Yoo
Subject: A question of curiosity
Date: 
Message-ID: <1e5df385-0d78-41af-b843-e42b922a7f37@m34g2000hsf.googlegroups.com>
I'm always thankful to be helped by this group. I'm a student in
software engineering lab. Other members of lab are familiar with
OCaml, but I'm not. When I tell them about the power of Lisp macro,
they tell me that OCaml can do the same thing. Is it true that OCaml
or Haskell can do the same thing that Lisp macro does? I can't imagine
that a language without parentheses can have macros which power is
equivalent to one of LIsp.

From: ·············@gmail.com
Subject: Re: A question of curiosity
Date: 
Message-ID: <dfd52866-a6f4-4a49-9fc4-0d0efe245597@v4g2000hsf.googlegroups.com>
On Jan 4, 10:07 am, Chanwoo Yoo <·········@gmail.com> wrote:
> I'm always thankful to be helped by this group. I'm a student in
> software engineering lab. Other members of lab are familiar with
> OCaml, but I'm not. When I tell them about the power of Lisp macro,
> they tell me that OCaml can do the same thing. Is it true that OCaml
> or Haskell can do the same thing that Lisp macro does?

Short answer: no, however the distinctions are sometimes subtle and
complex.  Elaboration below.

> I can't imagine
> that a language without parentheses can have macros which power is
> equivalent to one of LIsp.

It's possible to have Lisp style macros without having a Lisp-like
syntax, Dylan being the example.  Dylan macros are semantically
equivalent to Lisp, although they are much harder to use than in Lisp
due to needing to work with more of the abstract syntax of Dylan
rather than directly manipulating the Lisp forms in the body of the
macro call.

Elaboration from the "no" answer above.

Take a look at Shriram Krishnamurthi's book "Programming Languages -
Application and Interpretation" available at:

http://www.cs.brown.edu/~sk/Publications/Books/ProgLangs/

Specifically, chapter 36 discusses that the 3 most important things
that macros do are

- Alter order of evaluation (a very important thing)
- Introduce binding constructs that act like LET or LET* without
having to use them
- Provide a clean syntax for DSLs or data languages (ala like CLOS or
LOOP)

The advantage that Lisp macros have is that they have direct access to
the forms that appear in the macro call (this is what people mean when
they talk about the parentheses and lists).  Languages where the
syntax that the programmer uses is the same syntax the macro sees make
this pretty easy.  Languages where the programmer syntax is different
than the abstract syntax can still have macros (like Dylan), but the
programmer usually has to manipulate the abstract syntax in the macro
body rather than the direct syntax.  That's why Lisp macros are so
much easier to use.

Ocaml has Caml4p which is a macro preprocessor for Ocaml and allows
macro-like things to occur.  Haskell has a similar preprocessor called
Template Haskell.  These macro preprocessors work in a stage before
the compiler and allow the preprocessor macros to manipulate the
abstract syntax in much the same way as Lisp macros manipulate the
macro body forms.  In this sense, the preprocessors are similar to
Lisp macros as macro expansion is part of the compilation process.

Haskell has the additional advantage over Ocaml in that it is pure
lazy and you can write Haskell functions that manipulate the order of
evaluation as discussed above.  Monads that implement things like back-
tracking, continuations, etc are examples of this.

You can investigate for yourself the differences between the
approaches:

http://www.venge.net/graydon/talks/mkc/html/index.html (a very easy to
understand presentation discussing Campl4p to build a DSL comparable
to make & makefiles)

http://www.gigamonkeys.com/book/practical-parsing-binary-files.html
(Chapter 24 of Peter Siebel's Practical Common Lisp, discussing a
super use of macros to parse binary files).

As you are "in Lisp" all the time, even when writing macros, the Lisp
approach is significantly easier.  The functional programming crowd
will tell you that they are more or less equivalent, but if you press
them hard enough, they'll admit that even with the preprocessors
above, the nature of their type systems can *sometimes* get in the way
even in their macro preprocessors.

I studied Haskell pretty intensively for a couple of years, having
already been a Lisp user for many, many years.  One of the complicated
things I was looking at doing in Haskell (a discrete event simulation
DSL) wound up being hamstrung by the typing which required breaking
out to Template Haskell, whereas I didn't need to break out to macros
when implementing the same DSL in Common Lisp.  This experience
matches similar academic research when defining hardware description
language DSLs in Haskell also requiring Template Haskell.

The point is that even the FP crowd recognizes the need for macros in
their individual languages.  My point, and the one Lispers will tell
you, is that the Lisp macros are easier to use.  The FP'ers will say
that their preprocessors give you the same kinds of static type
guarantees in the macro preprocessing stage as in the normal language,
and this is true, however my argument is that it's still more
convenient to use Lisp macros, even if you have the potential of doing
bad or wrong things in the macro.  To each his own.

For these reasons, I switched back to Lisp from Haskell and have been
a happy camper ever since.  Common Lisp is *not* Blub to Haskell.

Glenn
From: Chanwoo Yoo
Subject: Re: A question of curiosity
Date: 
Message-ID: <609909ee-31ea-4ccb-b6cd-6c2eaa2b3e61@s12g2000prg.googlegroups.com>
I appreciate your detailed explanation. I don't have a clear idea of
how consistent infix notation and seamless integration between macro
code and base language make Lisp graceful. But I'm trying to learn
more and be enlightened. Thanks!

--
> I'm always thankful to be helped by this group. I'm a student in
> software engineering lab. Other members of lab are familiar with
> OCaml, but I'm not. When I tell them about the power of Lisp macro,
> they tell me that OCaml can do the same thing. Is it true that OCaml
> or Haskell can do the same thing that Lisp macro does?

Short answer: no, however the distinctions are sometimes subtle and
complex.  Elaboration below.

> I can't imagine
> that a language without parentheses can have macros which power is
> equivalent to one of LIsp.

It's possible to have Lisp style macros without having a Lisp-like
syntax, Dylan being the example.  Dylan macros are semantically
equivalent to Lisp, although they are much harder to use than in Lisp
due to needing to work with more of the abstract syntax of Dylan
rather than directly manipulating the Lisp forms in the body of the
macro call.

Elaboration from the "no" answer above.

Take a look at Shriram Krishnamurthi's book "Programming Languages -
Application and Interpretation" available at:

http://www.cs.brown.edu/~sk/Publications/Books/ProgLangs/

Specifically, chapter 36 discusses that the 3 most important things
that macros do are

- Alter order of evaluation (a very important thing)
- Introduce binding constructs that act like LET or LET* without
having to use them
- Provide a clean syntax for DSLs or data languages (ala like CLOS or
LOOP)

The advantage that Lisp macros have is that they have direct access to
the forms that appear in the macro call (this is what people mean when
they talk about the parentheses and lists).  Languages where the
syntax that the programmer uses is the same syntax the macro sees make
this pretty easy.  Languages where the programmer syntax is different
than the abstract syntax can still have macros (like Dylan), but the
programmer usually has to manipulate the abstract syntax in the macro
body rather than the direct syntax.  That's why Lisp macros are so
much easier to use.

Ocaml has Caml4p which is a macro preprocessor for Ocaml and allows
macro-like things to occur.  Haskell has a similar preprocessor called
Template Haskell.  These macro preprocessors work in a stage before
the compiler and allow the preprocessor macros to manipulate the
abstract syntax in much the same way as Lisp macros manipulate the
macro body forms.  In this sense, the preprocessors are similar to
Lisp macros as macro expansion is part of the compilation process.

Haskell has the additional advantage over Ocaml in that it is pure
lazy and you can write Haskell functions that manipulate the order of
evaluation as discussed above.  Monads that implement things like
back-
tracking, continuations, etc are examples of this.

You can investigate for yourself the differences between the
approaches:

http://www.venge.net/graydon/talks/mkc/html/index.html (a very easy to
understand presentation discussing Campl4p to build a DSL comparable
to make & makefiles)

http://www.gigamonkeys.com/book/practical-parsing-binary-files.html
(Chapter 24 of Peter Siebel's Practical Common Lisp, discussing a
super use of macros to parse binary files).

As you are "in Lisp" all the time, even when writing macros, the Lisp
approach is significantly easier.  The functional programming crowd
will tell you that they are more or less equivalent, but if you press
them hard enough, they'll admit that even with the preprocessors
above, the nature of their type systems can *sometimes* get in the way
even in their macro preprocessors.

I studied Haskell pretty intensively for a couple of years, having
already been a Lisp user for many, many years.  One of the complicated
things I was looking at doing in Haskell (a discrete event simulation
DSL) wound up being hamstrung by the typing which required breaking
out to Template Haskell, whereas I didn't need to break out to macros
when implementing the same DSL in Common Lisp.  This experience
matches similar academic research when defining hardware description
language DSLs in Haskell also requiring Template Haskell.

The point is that even the FP crowd recognizes the need for macros in
their individual languages.  My point, and the one Lispers will tell
you, is that the Lisp macros are easier to use.  The FP'ers will say
that their preprocessors give you the same kinds of static type
guarantees in the macro preprocessing stage as in the normal language,
and this is true, however my argument is that it's still more
convenient to use Lisp macros, even if you have the potential of doing
bad or wrong things in the macro.  To each his own.

For these reasons, I switched back to Lisp from Haskell and have been
a happy camper ever since.  Common Lisp is *not* Blub to Haskell.

Glenn
From: Maciej Katafiasz
Subject: Re: A question of curiosity
Date: 
Message-ID: <3e98323f-1924-4d31-bd9d-64dc657b72c8@e6g2000prf.googlegroups.com>
On Jan 5, 2:56 pm, Chanwoo Yoo <·········@gmail.com> wrote:
[snip]

*PLEASE* trim your quotes, and especially do that if you're going to
top post over a completely unmarked, verbatim quote of a full, long
post. That, and a proper separator is "-- \n" (notice the space), not
"--".

Maciej
From: Paul Tarvydas
Subject: Re: A question of curiosity
Date: 
Message-ID: <flr4v6$e0q$1@aioe.org>
Chanwoo Yoo wrote:

> I appreciate your detailed explanation. I don't have a clear idea of
> how consistent infix notation and seamless integration between macro
> code and base language make Lisp graceful. But I'm trying to learn
> more and be enlightened. Thanks!

Sometimes, saying the same thing in different ways can help understanding. 
So, here's a different take on lisp macros, for your consideration:

Think in terms of compiler construction.  You need a lexer, a parser and a
convenient data structure to represent the "concrete" parse.

Lisp has all of these (see discussion below).  From this perspective, Lisp
is a source-to-source tree transformation language.

If you want to kill the counter-arguments you face, simply ask the following
questions: Where is Lex in your language?  Where is Yacc in your language?
Where are the tree transformation primitives (semantic transformation
operators) in your language?


discussion:

In lisp, the "reader" is the lexer.  It tokenizes input (according to Lisp
rules) and inserts the tokens into a global symbol table (e.g. "symbols"
and name-space hash tables).

In lisp, lists are trees = concrete parse data structures.  The most
primitive lisp operations operate on these trees.

In lisp, the prefix notation is a concrete parse, without the "syntactic
sugar" found in most other languages.  When you parse some other language
and represent the concrete parse as trees, you end up with lisp prefix
notation.  Lisp skips the "syntactic sugar" phase and insists that
programmers directly write parse trees.  

There are "pros" and "cons" to the above approach.

The "con" to this approach is that many people have very strong prejudices
against prefix notation.  They dismiss the power of lisp's built in lexer
and yacc'er without recognizing their existence.

The "pro" of this approach is that working in this paradigm has allowed lisp
programmers to have greater imagination about what they can achieve.  I
don't know of many languages that have Lex and Yacc built into them (TXL is
the only language that comes to mind, but it isn't as flexible as lisp). 
Lisp has had this facility (lexer, parser, tree-to-tree transformations)
since the 1950's.  Lisp macros were "discovered" because of lisp's
flexibility and "low" level syntax and it's ability to express its own
grammar reflexively (lisp grammar expressed in lisp).

Lisp was naturally chosen for A.I. work in the '70's and '80's (e.g.
Planner) because it allowed easy development of new syntax and new
paradigms.  

Lisp macros allow you to develop new syntax gradually.  If you wanted to do
this with most other languages, you would have to pull out Lex and Yacc. 
Most people don't consider themselves to be compiler-writers and, hence,
never use Lex and Yacc.  Because of this fact, there is hard ceiling on
what they can achieve.  Their solutions to problems are always limited by
this ceiling.

The barrier-to-entry for syntactic change is much, much lower in lisp than
with other languages.

Why is it important to allow syntactic changes?  If you examine the fields
of science and mathematics, you will see that advances in science are made
by creating new notations.  As you research and develop an understanding of
a field of research, you develop a notation to express the problem space. 
The new notation then allows you to explore and "solve" new problems in the
problem space.

This has been the importance of Lisp to the programming community.  Lisp
cannot be replaced, until someone invents a language with Lex and Yacc and
tree-to-tree transformations built into it.

pt
From: D Herring
Subject: Re: A question of curiosity
Date: 
Message-ID: <BLqdndrUqZiSHOPanZ2dnUVZ_uGknZ2d@comcast.com>
Chanwoo Yoo wrote:
> I'm always thankful to be helped by this group. I'm a student in
> software engineering lab. Other members of lab are familiar with
> OCaml, but I'm not. When I tell them about the power of Lisp macro,
> they tell me that OCaml can do the same thing. Is it true that OCaml
> or Haskell can do the same thing that Lisp macro does? I can't imagine
> that a language without parentheses can have macros which power is
> equivalent to one of LIsp.

But that's a side question.

Whether you use macros to transform source text or closures and 
higher-order-functions, both languages are powerful.  I prefer tagged 
data and the personal feel of macros; so I vote Lisp.  Others prefer 
the structure of static types and a less direct use of side effects; 
so they like ML.

Any language can support full lisp-like macros; all major compilers 
parse text into syntax/semantic trees; in a sense, macros merely 
modify these trees.  Dylan did this, there are Java preprocessors 
which do this, ...  But the uniform syntax of Lisps does make it 
easier (less mental work to "see" the syntax tree).

In the end, no human-designed language will be perfect; each has its 
tradeoffs.  (perfect-lang:generate-and-run-awesome-code :time :now)

- Daniel
From: Chanwoo Yoo
Subject: Re: A question of curiosity
Date: 
Message-ID: <efb955b1-53af-4d84-b49d-04590934df5f@i12g2000prf.googlegroups.com>
On 1¿ù5ÀÏ, ¿ÀÀü3½Ã55ºÐ, D Herring <········@at.tentpost.dot.com> wrote:
> Chanwoo Yoo wrote:
> > I'm always thankful to be helped by this group. I'm a student in
> > software engineering lab. Other members of lab are familiar with
> > OCaml, but I'm not. When I tell them about the power of Lisp macro,
> > they tell me that OCaml can do the same thing. Is it true that OCaml
> > or Haskell can do the same thing that Lisp macro does? I can't imagine
> > that a language without parentheses can have macros which power is
> > equivalent to one of LIsp.
>
> But that's a side question.
>
> Whether you use macros to transform source text or closures and
> higher-order-functions, both languages are powerful.  I prefer tagged
> data and the personal feel of macros; so I vote Lisp.  Others prefer
> the structure of static types and a less direct use of side effects;
> so they like ML.
>
> Any language can support full lisp-like macros; all major compilers
> parse text into syntax/semantic trees; in a sense, macros merely
> modify these trees.  Dylan did this, there are Java preprocessors
> which do this, ...  But the uniform syntax of Lisps does make it
> easier (less mental work to "see" the syntax tree).
>
> In the end, no human-designed language will be perfect; each has its
> tradeoffs.  (perfect-lang:generate-and-run-awesome-code :time :now)
>
> - Daniel

Thanks for the reply. I'm slightly disheartened that any language can
do lisp-like macros, especially, Java. ;) Members of my lab discussed
which language to use in the project about context aware software. In
the discussion, my advocate of Lisp was based on macro and contextL of
P. Constanza. But opposition was very strong, more than I thought it
would. Maybe it seems that computer languages are like religion. Of
course my trivial macro example might make them think Lisp macro is
trivial. Anyway, It is sure that I need to learn more.