Awesome Sauce Java and Lisp Macros for Java
I keep forgetting to remember to talk about macros in Awesome Sauce Java. Among the language features that are distinctly Lisp, that Lisp programmers point to as essential and powerful and differentiating? Macros are it. Making them available to a Java-based language, as fully-functional macros, will hopefully be a positive thing.
Lisp macros provide the means to transform code. They're often viewed as syntactic sugar, but that diminishes what macros are. This is how Graham describes Lisp macros:
Paul Graham goes on to say that macros are different than functions. They work differently than functions. Functions produce results. Macros produce expressions.
Trust me, if you think they're the same? They're really, really not. I wrote the first implementation of macros in Awesome Sauce Java like a kind of special case function. Now that I understand how they work? I realize why there's confusion and why they're different and, more importantly, how. I'm probably the only one confused, but now that I'm not, I can at least be certain that what they are is what they're supposed to be. Plus with Java.
As of today, Awesome Sauce Java has macros. This morning I decided I was going to evolve them. How? Practice, practice, practice on the core implementation of macros, read, and eval. Where needed, I'm going to pull out the dross, fix what's close but not quite right, and make sure that the implementation is 100% stable. Of all the exciting aspects of ASJ I've experienced, the way bugs get and stay fixed is one of the most unique I've experienced as a programmer.
I'd like to take credit for bugs getting and staying fixed. But it's a function of the Lisp/functional core. The internal design is really clean and the arguments to ASJ functions trend towards Atoms or Cons Lists. The logic to implement, fix, and/or extend functions becomes consistent such that, once the input cases are enumerated and addressed? The code tends to be working.
Awesome Sauce Java is Java, but it's based on a Lisp model that also includes Lisp. It's not a Lisp that provides Java as an extension language with special syntax to activate it. Not that implementing a language in a different way is good or bad. We're so early in the development and evolution of programming languages, that trying new things can only help to advance the state-of-the-art, hopefully.
But, and this is big, by allowing the language to evolve from a Lisp to a Java to a marriage of two languages with each maintaining their individuality while bound together? The language is different. Strangely, it's like a marriage of true love. It's seamless, collaborative, expressive. Each language completely brings strength to the others weakness or simply eliminates the weakness altogether. Each dialect or language can leverage the same mechanisms that provide expressive power. Both languages can combine to create new idioms. It's weird. But it's a good kind of weird.
Rather than defining a set of operators, methods, functions, interfaces, types and stuff for "my language"? This awesome "language of familiar languages" creates a foundation for exploration in familiar linguistic constructs that encourage evolution based on familiarity. I wish I could say I designed it like that. I didn't design it.
I didn't design it. I mean I started with designs based on example parsers from Peter Norvig and one other source (will find and reference). But, once the design started taking shape, I let my experience dictate the patterns I followed, but kept allowing the languages to show me how to bring them together. I didn't expect it to be like that.
I thought I'd get to the point in the prototype where I saw which operators to define so "my language" took shape as a unique set of operators. I had planned to build one to throw away, and build a unique dialect of some language that included Java & Lisp as "my language".
Thankfully, I just used the language without forcing my dogma on it. Because it turned out to work really well as Java and as Lisp. I didn't have to learn a new dialect, operators, and/or mode of working, Awesome Sauce Java actually started to enhance my knowledge as soon as I could start writing code. That was a kind of 'eureka' moment, because what I had was what I already knew, just faster to work, explore, and learn with and from.
What is growing is based on familiarity of existing languages that have wed, but not changed, except to bring the best, most familiar parts. The familiarity is akin to working in your shop, with tools on your workbench you've worked at forever. You know what you need, where it lives, and how to grab it, so you can keep looking at what you're working on. That can only lead to increased awareness about a lot of new detail your mind can grow into. Simply by allowing your vision to stay focused on your work.
One of the nicest features, the one I'm most excited about, are macros. Because having the ability to use two languages in macros has been exciting to make use of. I didn't expect that. But it's a nice discovery to have stumbled upon.
Have a great day!
Michael
2/19/18
Lisp macros provide the means to transform code. They're often viewed as syntactic sugar, but that diminishes what macros are. This is how Graham describes Lisp macros:
Lisp's macro facility allows you to define operators that are implemented by transformation. The definition of a macro is essentially a function that generates Lisp code - a program that writes programs. From these small beginnings arise great possibilities, and also unexpected hazards.Paul Graham, OnLisp, pg 82
Paul Graham goes on to say that macros are different than functions. They work differently than functions. Functions produce results. Macros produce expressions.
Trust me, if you think they're the same? They're really, really not. I wrote the first implementation of macros in Awesome Sauce Java like a kind of special case function. Now that I understand how they work? I realize why there's confusion and why they're different and, more importantly, how. I'm probably the only one confused, but now that I'm not, I can at least be certain that what they are is what they're supposed to be. Plus with Java.
As of today, Awesome Sauce Java has macros. This morning I decided I was going to evolve them. How? Practice, practice, practice on the core implementation of macros, read, and eval. Where needed, I'm going to pull out the dross, fix what's close but not quite right, and make sure that the implementation is 100% stable. Of all the exciting aspects of ASJ I've experienced, the way bugs get and stay fixed is one of the most unique I've experienced as a programmer.
I'd like to take credit for bugs getting and staying fixed. But it's a function of the Lisp/functional core. The internal design is really clean and the arguments to ASJ functions trend towards Atoms or Cons Lists. The logic to implement, fix, and/or extend functions becomes consistent such that, once the input cases are enumerated and addressed? The code tends to be working.
Awesome Sauce Java is Java, but it's based on a Lisp model that also includes Lisp. It's not a Lisp that provides Java as an extension language with special syntax to activate it. Not that implementing a language in a different way is good or bad. We're so early in the development and evolution of programming languages, that trying new things can only help to advance the state-of-the-art, hopefully.
But, and this is big, by allowing the language to evolve from a Lisp to a Java to a marriage of two languages with each maintaining their individuality while bound together? The language is different. Strangely, it's like a marriage of true love. It's seamless, collaborative, expressive. Each language completely brings strength to the others weakness or simply eliminates the weakness altogether. Each dialect or language can leverage the same mechanisms that provide expressive power. Both languages can combine to create new idioms. It's weird. But it's a good kind of weird.
Rather than defining a set of operators, methods, functions, interfaces, types and stuff for "my language"? This awesome "language of familiar languages" creates a foundation for exploration in familiar linguistic constructs that encourage evolution based on familiarity. I wish I could say I designed it like that. I didn't design it.
I didn't design it. I mean I started with designs based on example parsers from Peter Norvig and one other source (will find and reference). But, once the design started taking shape, I let my experience dictate the patterns I followed, but kept allowing the languages to show me how to bring them together. I didn't expect it to be like that.
I thought I'd get to the point in the prototype where I saw which operators to define so "my language" took shape as a unique set of operators. I had planned to build one to throw away, and build a unique dialect of some language that included Java & Lisp as "my language".
Thankfully, I just used the language without forcing my dogma on it. Because it turned out to work really well as Java and as Lisp. I didn't have to learn a new dialect, operators, and/or mode of working, Awesome Sauce Java actually started to enhance my knowledge as soon as I could start writing code. That was a kind of 'eureka' moment, because what I had was what I already knew, just faster to work, explore, and learn with and from.
What is growing is based on familiarity of existing languages that have wed, but not changed, except to bring the best, most familiar parts. The familiarity is akin to working in your shop, with tools on your workbench you've worked at forever. You know what you need, where it lives, and how to grab it, so you can keep looking at what you're working on. That can only lead to increased awareness about a lot of new detail your mind can grow into. Simply by allowing your vision to stay focused on your work.
One of the nicest features, the one I'm most excited about, are macros. Because having the ability to use two languages in macros has been exciting to make use of. I didn't expect that. But it's a nice discovery to have stumbled upon.
Have a great day!
Michael
2/19/18
Comments
Post a Comment