You are correct that I don’t give “any good reason to think that they [Lisp, stream entry and entrepreneurship] are antimemes”. Thank you for your thoughtful response. This kind of quality feedback is why I post on Less Wrong.
So what allegedly makes these things antimemes, in lsusr’s view? I’ll hazard a guess: they are things whose merits seem clear to lsusr but that are widely neglected by others.
Good guess, but that’s not quite what I mean by the word “antimeme”. An antimeme is a meme whose information content provokes a self-suppressing response. In Lisp, this comes not from its nicheness (though nicheness is often a prerequisite) nor its syntax (though this helps keep Lisp unpopular) but rather from the defmacro operator.
Programming languages are distinguished from each other by their syntax. A programming language’s syntax is defined by its macros. Macros are the parts of a programming language you can’t write your own of. For example, Python’s if and not are macros. You can’t write your own ifnot macro to abbreviate if and not because you’re not allowed to write your own macros. You’re only allowed to write functions and variables.
In non-Lisp programming languages, macros are set in stone like a processor’s instruction set. Lisp is unique because it lets you define new macros with defmacro. Comprehending Lisp equals unlearning all the antipatterns you acquired from working from a tiny set of immutable macros. Defmacro is an antimeme due to an extreme case of the Blub paradox. The more rigid your understanding of computer science is, the harder it is to understand why Lisp matters because a conventional computer science education assumes macros are immutable. It’s this mountain of unlearning that makes Lisp an antimeme.
Stream entry is about unlearning self, attachment and object permanence.
Entrepreneurship means unlearning subservience.
To comprehend an antimeme you must unlearn information. The brain’s resistance to unlearning things suppresses the antimeme. But this a different kind of unlearning than replacing false facts with true facts. Error correction replaces facts with facts. Antimemetic unlearning is about replacing a fact with an equation. But not just any equation. Antimemes force you to generalize in a direction orthogonal to everything you know. It’s about replacing a specific equation with a general equation.
If all your experience belongs to a specific case then your specific model of the world is the best model according to Occam’s razor. The antimeme’s model of the world adds complexity without improving your model for the data collected so far. The antimeme would describe your data better if you had data outside your special case but you won’t collect that data until after you absorb the antimeme. This circular reasoning creates a chicken-and-egg problem.
I don’t think entrepreneurship is widely ignored at all; I think it’s very widely admired.
Once again, that’s an excellent point. I should have been more specific. The idea of startups as something “someone else” could do is not an antimeme. The idea of startups as something YOU (assuming you’re a programmer) could do is an antimeme. Many people could found profitable startups but have dismissed the idea without having performing a careful analysis.
I remain unconvinced that Lisp’s macro facilities are antimemetic. I am not sure exactly how to divide up my disagreement between “it’s not antimemetic, it’s something more mundane” and “I don’t think you should use the exotic-sounding term ‘antimeme’ for something so mundane” because I am not exactly certain where you draw the boundaries of the term “antimeme”.
At any rate, I think the main reasons why Lisp isn’t more popular are fairly mundane and don’t need an exotic-sounding term to describe them. I think (though I confess I don’t have solid evidence) that:
most programmers who don’t use Lisp never even really look at it;
most who look at it but still don’t use it are mostly put off by superficial things like the unusual syntax or the Lisp community’s reputation for smugness;
most who get past those things but still don’t use it are mostly put off by genuine drawbacks like the relatively poor selection of libraries available or the difficulty of finding good Lispers.
So if Lisp is tragically underused then some of the tragic underuse will be the result of defmacro (and also, I suggest, set-macro-character and set-dispatch-macro-character) being underappreciated, but I find it very hard to believe that it’s a large fraction. And even that doesn’t all qualify as antimemetic in the sense of “provoking a self-suppressing response”, again unless you’re meaning that so broadly that it covers everything whose merits are easy to underestimate. If someone is (say) used to C-preprocessor-style macros, and hears that expert Lisp programming makes a lot of use of macros, and imagines a codebase full of #defines, are you calling that antimemetic? Or if they don’t jump to that conclusion but do think something like “hmm, macros aren’t really all that powerful, so a language where macros provide a lot of the power must be pretty weak”, are you calling that antimemetic?
I think the mental process you have in mind is different from both of those, because you’re taking “macro” to include e.g. C’s “if” and “for”, even though those aren’t implemented with any sort of macrology in C, so the reaction you’re describing is more like “these people say that in Lisp you can redefine the language itself, but that doesn’t make any sense”. Again I have no concrete evidence, but I don’t think that’s a common reaction. After all, C does have macros (of a sort) and you canuse them to extend the language (kinda), and users of Ruby, which is at least mainstream-ish, are used to using and making what they call “domain-specific languages” within Ruby even though what you can do there is fairly restrictive compared with Lisp’s macros.
I think you’re overdramatizing how people react to Lisp. “Lisp is an antimeme!” makes a great story, but I don’t think it fits the evidence as well as “Lisp is unfamiliar in various ways, and people are bad at seeing the merits of unfamiliar things”.
… Again, unless that or something like it is actually all you mean by “antimeme”.
It seems, at least some of the time, as if you’re using the term to describe anything whose widespread appreciation is limited by the fact that widespread beliefs or habits of mind get in the way. (Assuming that programming languages can’t have adjustable syntax; seeing a clear boundary between one’s self and the rest of the universe; being willing to have a boss and do what they say.) With that definition, I’m still not sure Lisp counts (as I said above, I think there are other reasons why many programmers don’t use Lisp, and they aren’t all antimemetic even in this very broad sense), but there’s certainly a case to be made that it does—but to me, “antimeme” doesn’t seem like an appropriate term, for two reasons.
It implies that the offputting-ness lies primarily in the thing itself, when in fact it seems much better to see it as a property of the people being put off.
It makes “being an antimeme” sound like some exotic SCP-ish property, when in fact a large fraction of underappreciated things are “antimemes” in this sense.
For example, Python’s if and not are macros. You can’t write your own ifnot macro to abbreviate if and not because you’re not allowed to write your own macros.
Here’s how you do it with the C preprocessor.
#define ifnot(x) if(!x)
You can apply this trick to any language with a textual representation, since preprocessing is a separate stage.
I considered putting in a footnote acknowledging the existence of this kind of textual macro in languages like C and Bash. Demonstrating the uniqueness of defmacro requires a more sophisticated example, like embedding Haskell.
Edit: I replied to the wrong comment. This was supposed to be a reply to TAG’s parent comment.
I considered putting in a footnote acknowledging the existence of this kind of textual macro in languages like C and Bash. Demonstrating the uniqueness of defmacro requires a more sophisticated example, like embedding Haskell. Even if you can do this in C, you shouldn’t.
I was being a bit tongue in cheek about the macro thing. You can apply macros, in the sense of a preprocessor expanding text, to anything.
Defmacro isn’t unique,but not just because of preprocessors. Less vaunted languages such as Forth can also define fundamental new keywords.
The uniqueness claim, apart from being false, is an unnecessary restriction. There are ways of achieving the things that lisp can achieve that dont have its downsides.
I think a relevant difference between Lisp macros and textual macros of other languages is that in Lisp, the program is in the form of a datastructure (a list) that has relevant structure. So the macro is manipulating data at a level that is more relevant than text.
Thinking that there is not such a relevant difference might contribute to antimeminess of Lisp imo.
Aside:
I think what would be even better would be macros in a language where not only is the program in the form of a datastructure with relevant structure, but the language is also statically typed (with a suitably complex type system) with any program or subprogram having a type. The compiler could then provide protection against mistakes, allowing more complex stuff to be done in practice. Haskell partially does this by defining types for functions and allowing you to make functions that spit out other functions, but (afaik) doesn’t apply this to other aspects of Haskell programs which seems to me a huge wasted opportunity.
I think both Template Haskell and MetaOCaml have some typechecking of macros.
Though I haven’t found macros very useful or exciting. To me the most fun way to program is with simple code, but relying on a lot of implicit understanding. Something like what Kragen describes here:
Also, sometime around 1993, I read Robert Sedgewick’s textbook, “Algorithms in C”, which I borrowed from my father, Greg Sittler. It opened a whole new world to me. The programs in the book are all concise crystals of beauty, showing how a few lines of code can transform a pile of structs of integers and pointers into a binary search tree, or a hash table, or the minimal spanning tree of a set of points. It used only the basics of C, and did not rely on any libraries.
This was a revelation to me; there was beauty and magic in these programs, and it wasn’t because they were calling on powerful libraries hidden, Wizard-of-Oz-style, behind curtains. They were just plain C code, and not very much of it, that “developed a set of operations that were not obviously implicit in the original set,” to borrow Bruce Mills’s phrase.
Yes. There’s nothing magic about a list as a data structure that allows you to do implement type-safe macros. In fact, since any code can be represented as an abstact syntax tree, a tree-like data structure would be more general. I beleive the Nim language works that way.
You are correct that I don’t give “any good reason to think that they [Lisp, stream entry and entrepreneurship] are antimemes”. Thank you for your thoughtful response. This kind of quality feedback is why I post on Less Wrong.
Good guess, but that’s not quite what I mean by the word “antimeme”. An antimeme is a meme whose information content provokes a self-suppressing response. In Lisp, this comes not from its nicheness (though nicheness is often a prerequisite) nor its syntax (though this helps keep Lisp unpopular) but rather from the
defmacro
operator.Programming languages are distinguished from each other by their syntax. A programming language’s syntax is defined by its macros. Macros are the parts of a programming language you can’t write your own of. For example, Python’s
if
andnot
are macros. You can’t write your ownifnot
macro to abbreviateif
andnot
because you’re not allowed to write your own macros. You’re only allowed to write functions and variables.In non-Lisp programming languages, macros are set in stone like a processor’s instruction set. Lisp is unique because it lets you define new macros with
defmacro
. Comprehending Lisp equals unlearning all the antipatterns you acquired from working from a tiny set of immutable macros. Defmacro is an antimeme due to an extreme case of the Blub paradox. The more rigid your understanding of computer science is, the harder it is to understand why Lisp matters because a conventional computer science education assumes macros are immutable. It’s this mountain of unlearning that makes Lisp an antimeme.Stream entry is about unlearning self, attachment and object permanence.
Entrepreneurship means unlearning subservience.
To comprehend an antimeme you must unlearn information. The brain’s resistance to unlearning things suppresses the antimeme. But this a different kind of unlearning than replacing false facts with true facts. Error correction replaces facts with facts. Antimemetic unlearning is about replacing a fact with an equation. But not just any equation. Antimemes force you to generalize in a direction orthogonal to everything you know. It’s about replacing a specific equation with a general equation.
If all your experience belongs to a specific case then your specific model of the world is the best model according to Occam’s razor. The antimeme’s model of the world adds complexity without improving your model for the data collected so far. The antimeme would describe your data better if you had data outside your special case but you won’t collect that data until after you absorb the antimeme. This circular reasoning creates a chicken-and-egg problem.
Once again, that’s an excellent point. I should have been more specific. The idea of startups as something “someone else” could do is not an antimeme. The idea of startups as something YOU (assuming you’re a programmer) could do is an antimeme. Many people could found profitable startups but have dismissed the idea without having performing a careful analysis.
I remain unconvinced that Lisp’s macro facilities are antimemetic. I am not sure exactly how to divide up my disagreement between “it’s not antimemetic, it’s something more mundane” and “I don’t think you should use the exotic-sounding term ‘antimeme’ for something so mundane” because I am not exactly certain where you draw the boundaries of the term “antimeme”.
At any rate, I think the main reasons why Lisp isn’t more popular are fairly mundane and don’t need an exotic-sounding term to describe them. I think (though I confess I don’t have solid evidence) that:
most programmers who don’t use Lisp never even really look at it;
most who look at it but still don’t use it are mostly put off by superficial things like the unusual syntax or the Lisp community’s reputation for smugness;
most who get past those things but still don’t use it are mostly put off by genuine drawbacks like the relatively poor selection of libraries available or the difficulty of finding good Lispers.
So if Lisp is tragically underused then some of the tragic underuse will be the result of defmacro (and also, I suggest, set-macro-character and set-dispatch-macro-character) being underappreciated, but I find it very hard to believe that it’s a large fraction. And even that doesn’t all qualify as antimemetic in the sense of “provoking a self-suppressing response”, again unless you’re meaning that so broadly that it covers everything whose merits are easy to underestimate. If someone is (say) used to C-preprocessor-style macros, and hears that expert Lisp programming makes a lot of use of macros, and imagines a codebase full of #defines, are you calling that antimemetic? Or if they don’t jump to that conclusion but do think something like “hmm, macros aren’t really all that powerful, so a language where macros provide a lot of the power must be pretty weak”, are you calling that antimemetic?
I think the mental process you have in mind is different from both of those, because you’re taking “macro” to include e.g. C’s “if” and “for”, even though those aren’t implemented with any sort of macrology in C, so the reaction you’re describing is more like “these people say that in Lisp you can redefine the language itself, but that doesn’t make any sense”. Again I have no concrete evidence, but I don’t think that’s a common reaction. After all, C does have macros (of a sort) and you can use them to extend the language (kinda), and users of Ruby, which is at least mainstream-ish, are used to using and making what they call “domain-specific languages” within Ruby even though what you can do there is fairly restrictive compared with Lisp’s macros.
I think you’re overdramatizing how people react to Lisp. “Lisp is an antimeme!” makes a great story, but I don’t think it fits the evidence as well as “Lisp is unfamiliar in various ways, and people are bad at seeing the merits of unfamiliar things”.
… Again, unless that or something like it is actually all you mean by “antimeme”.
It seems, at least some of the time, as if you’re using the term to describe anything whose widespread appreciation is limited by the fact that widespread beliefs or habits of mind get in the way. (Assuming that programming languages can’t have adjustable syntax; seeing a clear boundary between one’s self and the rest of the universe; being willing to have a boss and do what they say.) With that definition, I’m still not sure Lisp counts (as I said above, I think there are other reasons why many programmers don’t use Lisp, and they aren’t all antimemetic even in this very broad sense), but there’s certainly a case to be made that it does—but to me, “antimeme” doesn’t seem like an appropriate term, for two reasons.
It implies that the offputting-ness lies primarily in the thing itself, when in fact it seems much better to see it as a property of the people being put off.
It makes “being an antimeme” sound like some exotic SCP-ish property, when in fact a large fraction of underappreciated things are “antimemes” in this sense.
Here’s how you do it with the C preprocessor.
#define ifnot(x) if(!x)
You can apply this trick to any language with a textual representation, since preprocessing is a separate stage.
Pedantic note: you should do
#define ifnot(x) if (!(x))
(with extra parens around the second instance of “x”) because otherwise you will get probably-unexpected results if x is something like a==b.
You’re right, I’m rusty.
I considered putting in a footnote acknowledging the existence of this kind of textual macro in languages like C and Bash. Demonstrating the uniqueness of
defmacro
requires a more sophisticated example, like embedding Haskell.Edit: I replied to the wrong comment. This was supposed to be a reply to TAG’s parent comment.
I considered putting in a footnote acknowledging the existence of this kind of textual macro in languages like C and Bash. Demonstrating the uniqueness of
defmacro
requires a more sophisticated example, like embedding Haskell. Even if you can do this in C, you shouldn’t.You shouldn’t do this in C.
I was being a bit tongue in cheek about the macro thing. You can apply macros, in the sense of a preprocessor expanding text, to anything.
Defmacro isn’t unique,but not just because of preprocessors. Less vaunted languages such as Forth can also define fundamental new keywords.
The uniqueness claim, apart from being false, is an unnecessary restriction. There are ways of achieving the things that lisp can achieve that dont have its downsides.
I think a relevant difference between Lisp macros and textual macros of other languages is that in Lisp, the program is in the form of a datastructure (a list) that has relevant structure. So the macro is manipulating data at a level that is more relevant than text.
Thinking that there is not such a relevant difference might contribute to antimeminess of Lisp imo.
Aside:
I think what would be even better would be macros in a language where not only is the program in the form of a datastructure with relevant structure, but the language is also statically typed (with a suitably complex type system) with any program or subprogram having a type. The compiler could then provide protection against mistakes, allowing more complex stuff to be done in practice. Haskell partially does this by defining types for functions and allowing you to make functions that spit out other functions, but (afaik) doesn’t apply this to other aspects of Haskell programs which seems to me a huge wasted opportunity.
I think both Template Haskell and MetaOCaml have some typechecking of macros.
Though I haven’t found macros very useful or exciting. To me the most fun way to program is with simple code, but relying on a lot of implicit understanding. Something like what Kragen describes here:
Yes. There’s nothing magic about a list as a data structure that allows you to do implement type-safe macros. In fact, since any code can be represented as an abstact syntax tree, a tree-like data structure would be more general. I beleive the Nim language works that way.