
Is it possible to have Lisp-like Macros in a language without s-expressions? - bhnmmhmd
For example, why not use indentation instead of parentheses?
======
such_a_casual
Lisp macros do not rely on S-expressions. They rely on the fact that arguments
are not evaluated, the code is passed in raw to the function, and then the
code is replaced by the result of the function. If macros existed in Python
for example, you could do this (sorry if my python isn't 100% correct. haven't
used it in a while):

    
    
      defmacro exists (code list):
        for x in ,list:
          if ,code:
            return True
        return False
    
      exists(x > 10, [1 5 333]) => t
    

Macros are great in Lisp, because lisp makes it easy to code your code. It
does this by treating your file of code like you might think of an array or a
list or another data structure in another language. This data structure is
really simple and is called a list. Lisp provides a bunch of help to make it
easy to work with lists, just like Python provides a bunch of help for working
with strings, lists, and tuples by giving you functions and variables for
manipulating, printing, and debugging these things. Because the code you write
is a list and lisp provides a bunch of help for dealing with lists, it's as
easy to manipulate a list of code as it is to manipulate a list of songs or
emails or zombies like you're probably already accustomed to doing.

In other words, macros are awesome and you could easily put them in another
language. Lisp isn't great because of macros, it's great because of how well
(mind blowingly well) macros play with with all of the other parts of lisp.
Macros are empowered by the rest of the langauge, and the rest of the language
is empowered by macros. And this is really the theme of lisp, it's not one
feature that makes the language impressive, it's how the features seem to
amplify one another.

~~~
bhnmmhmd
The Python example looks really inspiring, and could possibly be implemented
in future versions of Python.

But as for your statement that "macros don't rely on homoiconicity", I find it
hard to agree, because if that were the case, then why haven't Java or Python
implemented the macro feature by now?

~~~
such_a_casual
Perl 6 has macros:

Copied from:
[https://perl6advent.wordpress.com/2012/12/23/day-23-macros/](https://perl6advent.wordpress.com/2012/12/23/day-23-macros/)

    
    
        macro checkpoint {
          my $i = ++(state $n);
          quasi { say "CHECKPOINT $i"; }
        }
    
        checkpoint;
        for ^5 { checkpoint; }
        checkpoint;
    

No "homoiconicity". Just two operators: "macro" which will make a macro
instead of a normal function, and "quasi" which says the stuff in here is code
that shouldn't be evaluated. In lisp these two operators could be "defmacro"
and "quote".

Lisp has a lot of features that other languages haven't implemented. We could
spend all day asking why other languages haven't implemented them yet. And
it's unfortunate, because just adding the feature for macros would allow you
to add a lot of those other features. Indeed, macros are such a big deal that
they are probably the sole defining reason that lispers can add features from
other languages so easily.

However, we need to stop pretending that code substitution is some magical,
genius feature that can only exist in the utopian environment of a common lisp
system. It's a simple idea that's been used since before I was born. Macros in
lisp are nice because you have so much access to the language, as well as
(perhaps more so than any popular language) really smart tools for
manipulating the data structure your code is written in. If you have to code
code, if you have to write code that manipulates other code, it's nice if that
other code is in an easy to understand data structure. And even easier if you
already have a bunch of functions, classes, variables, etc given to you by the
language for changing that data structure. Which lisp does, and that's what
makes lisp lisp.

~~~
bhnmmhmd
Thank you. I never thought Perl 6 had macros. Plus, now I can see that
"homoiconicity" is not required for macro systems.

> However, we need to stop pretending that code substitution is some magical,
> genius feature that can only exist in the Utopian environment of a common
> lisp system.

I couldn't agree more.

------
Someone
Depending on what you call a "Lisp-like macro", Forth may have them, with its
immediate words that allow one to extend its syntax.

If you disagree because Forth is too minimalistic, look at Factor
([http://www.factorcode.org](http://www.factorcode.org)).

If with "Lisp-like macro", you mean "hygienic macros"
([https://en.m.wikipedia.org/wiki/Hygienic_macro](https://en.m.wikipedia.org/wiki/Hygienic_macro)),
look at Dylan
([https://opendylan.org/books/drm/Macros](https://opendylan.org/books/drm/Macros))
(which originally had a Lisp-like syntax), Julia, Perl6, or Rust.

~~~
bhnmmhmd
Thank you. I will definitely take a look at them.

------
timonoko
Musimp/Mulisp - pair of languages had one-to-one mapping between Pascal-like
syntax and Lisp syntax. Which means that you could use DEFMACRO in any which
way you feel convenient.

I do not remember details of course, but those two versions were something
like these:

DEFMACRO PLUS2(X,Y): BEGIN LIST('+,X,Y) END

(defmacro (plus2 x y) (list '\+ x y))

------
dragonwriter
It's easily possible to have lisp-like macros in a homoiconic language even if
it doesn't use S-expressions; a non-homoiconic language could probably have a
conceptually similar but more limited and/or awkward to use macro facility.

------
QuantumAphid
Sounds like you're talking about Red [http://www.red-
lang.org/2017/03/062-libred-and-macros.html](http://www.red-
lang.org/2017/03/062-libred-and-macros.html)

