Skip to content

Instantly share code, notes, and snippets.

Created February 1, 2012 03:58
What would you like to do?
HJava: Imagining a (more) homoiconic Java
//HJava (HomoiconicJava): Imagining a (more) homoiconic Java
//In Java, the unit is the *class*
//So in HJava we will pretend that everything is a class (or, at least, an instance of a class).
//Obviously this won't compile in Java, because Java doesn't actually support homoiconic structures.
//But HJava does!
public class HomoiconicJava {
public static void main(String[] args)
//We can define a program using only Java *reserved words* and *literals*
System.out.println("The contents of this block will be executed");
//We can also use *variables* that evaluate to these values
boolean myBoolean = true;
System.out.println("This will also be executed!");
//We can also modify these values
//Let's call a mutator method
myBoolean.changeValue(false); //Won't actually work, because Java primitives aren't objects, but it's easy to pretend that this is valid
System.out.println("I can say whatever I want here, because it will never get executed!");
System.out.println("But this will get printed to the screen");
//Java also supports polymorphism. Let's say I have a BankAccount object.
BankAccount myAccount = new BankAccount("Jim");
System.out.println(myAccount); //This will work!
//This works because println implicitly calls the .toString() method on any object it receives.
/** Up until here, everything is valid Java. It would compile and run as expected.
* Simple, right?
* (But now let's get hypothetical
//Well, if Java were homoiconic, everything would be a class, including reserved words.
//If everything is a class/instance of a class, we can call methods on anything. For example:
String t = if.toString(); //If Java were homoiconic, keywords would be objects, and we could call methods on keywords!
//This would create a string representation of the keyword 'if', whatever that would be (again, if Java supported this).
//But this is kind of boring. What's the use? Well, we can do things like this:
Code myCode = new Code( " System.out.println( \"Homoiconicity is awesome!\" ); "); //This creates a new object, myCode, which is an instance of the Code class.
//Note that nothing is printed yet - the println statement is just the text of the string!
myCode.evaluate(); //*Now* the above statement is printed!
//So code is really just an object, and running a code is equivalent to calling .evaluate() on the code object. What about keywords?
//System.out.println is a lot to type. Let's create a shorter version, called printf.
Keyword printf = new Keyword(); //Again, keywords are just instances of classes
printf("That's much shorter"); //The same way println implicitly calls .toString() on its parameters, keywords implicitly call .evaluate() on their code when they are used.
//What did we just do?
//If everything is an instance of a class, then code is really just an instance of a class
//If everything is an instance of a class, then keywords are really just instances of classes.
//So, we can create new classes, and create new keywords.
//This allows us to extend the language really easily.
//All you have to do is define a few basic functions, and then you can build up new keywords/functions/statements recursively, the way we used println and .evaluate() to create a new statement called printf.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment