Created
February 1, 2012 03:58
-
-
Save ChimeraCoder/1714998 to your computer and use it in GitHub Desktop.
HJava: Imagining a (more) homoiconic Java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//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* | |
if(true) | |
{ | |
System.out.println("The contents of this block will be executed"); | |
} | |
//We can also use *variables* that evaluate to these values | |
boolean myBoolean = true; | |
if(myBoolean) | |
{ | |
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 | |
if(myBoolean) | |
{ | |
System.out.println("I can say whatever I want here, because it will never get executed!"); | |
} | |
if(!myBoolean) | |
{ | |
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.setEvaluatedCode(printf_code); | |
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