You stop writing programs. You start writing programs that write programs. It's a lever that multiplies the power of the programmer. That can be both good and bad. For a hacker coding in earnest on her own, it can be extremely good.
Yes, if you are the type of beginner or intermediate programmer that still struggles to just write programs, advanced metaprogramming in any language is not for you. If you're an intermediate programmer looking to become an expert programmer, learn Lisp, where metaprogramming is easy, and take the lessons on to whatever other languages you eventually end up using.
That's what people mean.
And whenever you get dropped into the debugger, you can edit and reevaluate the broken code or values or whatever -- and then continue on with the task.
In other words, you can begin a task with imperfect code -- and refine it as you go along -- figuring out how to handle corner cases as you go. All without starting the task over from the beginning.
I know of only one other language that allows you to explore a problem space like that.
Besides, the parentheses make the code less jagged looking and jagged looking code imo, is more tiring to look at. Lisp is simply prettier.
I have edited my comment to account for smalltalk.
It's an incredibly flexible system that makes exception handling much more useful.
Regarding the learning curve: we rewrote the first half of the Metaprogramming section of the manual a few months ago to try to provide a more gradual introduction, especially for people without a Lisp background. Objectively I don't know if the change has helped, but I tell myself that the number of macro-related questions has gone down :)
We would really like to make these tools accessible to people both with and without a formal CS background (probably the majority of Julia users will fall in the latter category). So, if you have any suggestions for doc/pedagogy improvements in this area, I would be very happy to hear them!
I am actually looking at the Converge documentation on macros now, and I found the perfect quote to highlight the problem I see with those approaches:
Quasi-quotes allow ITree's to be built using Converge's normal concrete syntax. Essentially a quasi-quoted expression evaluates to the ITree which represents the expression inside it. For example, whilst the raw Converge expression 4 + 2 prints 6 when evaluated, [| 4 + 2 |] evaluates to an ITree which prints out as 4 + 2. Thus the quasi-quote mechanism constructs an ITree directly from the users' input - the exact nature of the ITree is of immaterial to the casual ITree user, who need not know that the resulting ITree is structured along the lines of add(int(4), int(2)).
That is, quasi-quotes take some code and turn it into a tree object. This tree object can then somehow get compiled into actual code later. Compare that with Lisp approach, in which code is data. You don't think about the code as something separate from the tree that represents it. The code is the tree. There is no ITree object.
It may seem like just "semantics", but I find this to be a significant cognitive difference.
It's not any different. It does not matter if your `(,a ,b) is compiled into (list a b), or your ` \a\ = \b\` is compiled into make_binary('=',a,b) - both are constructors, essentially.
Take a look at what I'm doing with just a quasiquotation here: https://github.com/combinatorylogic/clike
Smalltalk source code does not appear to be expressed in terms of a Smalltalk data structure. Whereas Lisp source code is expressed as lists of lists.
As a practical matter, methods also have a textual representation, but that's not strictly necessary. Ten or fifteen years ago, the Squeak method browser had a mode where you could write Smalltalk code using tiles, kind of like in Etoys, no parsing necessary. That was a hassle to use, though, so people stuck with writing methods using text.
By the way, Lisp has the same sort of "impurity". S-expressions are very simple, but they are syntax. It's surely possible to create a tool that would let one construct cons cells in memory directly, but that would be a hassle. Instead we use parentheses.