Friday, February 4, 2011

Attumi (email Batch A) - A Java-like Language with default immutability

This is the second in a series of 5 posts:

Early last November (not December like I said in my "Why?" post), I had lots of things rolling around in my head about what to do "next" after Java. I wanted to complete my board game rules model in Java. I toyed with doing the UI. I was just not at all attracted to the tonnage of boilerplate required to do a Java UI with any tool. And I was already getting sick of Java boilerplate anyway even with all the help from the numerous tools Eclipse provides.

And it looked like Objective-C was just going to be tons more boilerplate, only I had to also learn and become competent in Objective-C and the IOS libraries, first. Not at all attractive, either. I had immersed myself in the C#/.NET books and was actually looking forward to some change and some new things (like LINQ, real properties, etc.) which put C# significantly less long in the tooth as Java (I know, I know, it's coming in Java 7, or 8...or whenever the hell Oracle says it will...eff Oracle).

I didn't plan the thought avalanche. I never do. They come to me completely unbidden. I already have several programming projects and business I wanted to start. And I had at least two business completely unrelated to technology (use, but are not driven by) I was playing with building. My creative juices were flowing in those other areas. And then on the way to work during my commute, it hit me like a lightening bolt in the form of a question...

"What if I was to modify Java until it's default state aligned with my primary use case pathways? What if I made Java immutable by default, and then made mutability a pain to get to and if used?"

What if being mutable had to be defined as "the unsafe side-effecting dangerous malicious memory leaked thread-deadlocking code is here" via copious annotations assisting the compiler (which would complain vociferously if the code writer were to forget the slightest "thar be dragon har" indications)? And that was just the start. Once I had the seed idea to take Java and shift it about until it suited me, I could then make it mean the removal of lots of boilerplate, re-prioritize things that mattered, rip out legacy crap (like raw collections) and then like. It was like a fantastic thought experiment all in my own private programmer's fairy-land.

I then began to privately email myself. Anytime I was coding on any project, home or work, I would just jot down some thoughts around the "pain point" and solution like notions that would come to me. That way, I would just continuously have the stream of thoughts and be able to adapt and play with them as needed. It was so much fun. I could now sit back and just enjoy writing Java code while my brain solved both the current coding problems the "Java" way and another part of my brain was off playing with how it really should work. And the modifications were all the way from very low level implementation efficiencies to very high level pattern extractions/abstractions.

So, what did those thoughts look like? Well, I was going to do tons of clean up on my notes and make them all spiffy. However, I would rather do more fun things like read more about Scala, and code in Scala, and make suggestions/requests to the Scala team around things that burped up for me during the last three months. I made all these notes before venturing out to start researching existing JVM alternatives. I had not investigated a single JVM language until AFTER I wrote all these notes. So, in a way, it was quite pleasant to have a strong sense of what I wanted before I actually took the leap and started researching other languages which might fill the bill. Besides, it's not my style. I like problem solving, even problems that have already been solved. It's why I love to play Go. It's why I do Sudoku, it's why I dig little puzzle games like Osmos and Chime.

Here is the first batch (of four) notes, mostly unedited:
Consider an OO language design where immutability was the default:
  1. immutability assumed unless otherwise explicitly called out and specified (use marker interface mutable in similar way abstract is used on abstract classes)
  2. reduce security issues via content changing unexpectedly in deeper structures
  3. create basic method parameter checks (i.e. simplified preconditions for null, ranged values, size, etc. - most all the pre-conditions typically used to validate basic parameters to a constructor)
  4. use builders to have mutable content until ready to build immutable instance (like StringBuilder for strings, include ArrayBuilder for arrays)
  5. all "primatives" are formal Objects and optimized internally for performance value (including arrays)
  6. add option execution suggestion plan to help structure CPU and memory layout for optimally executing
    • can allow array of Integer to be grouped internally into a memory block of ints[] which are then accessed via pointer arithmetic
    • enables faster iterators where boundary checks can be disabled
    • separates the code abstraction definition (i.e. design) from the actual instruction and memory layout generation (i.e. implementation)
  7. optimized relationship with Collections library (allowing for internal implementation to eliminate unnecessary boundary checks)
  8. consider partial construction and lazy instantiation of additional immutable state as important (so as to only engage in CPU and memory for the execution pathways actually used)
  9. ensure only an immutable instance may be passed from one thread to another (reduces memory coordination/collaboration/optimization issues substantially)
  10. an immutable object is state whereas a mutable object has state
  11. when designing Collection builders, ensure specification of requirements (i.e. read heavy, write heavy, etc.) which then interprets and selects implementation (i.e. ArrayList for lots of random access reading, LinkedList for lots of insertion and sequential traversing)
  12. within implementation of actual compiled code, consider a reference to be more than just a memory pointer, but an actual object representing data
    • for an array of Integer, it could be type, count, size of single entry, pointer to start of a memory block
    • for a specific instance of Integer in the array, it could be type, container reference (above), index (and if immutable, the operation for this fetch only has to occur once to the locality needed to operate on it)
  13. Review Java and Eiffel design for other possible ways to add semantics

    And that was the first brain-storm. Depending upon interest, I will consider diving into some/all of these and exploring my thoughts and reasoning. If there's no interest (and mine wanes such that I don't bring it up on the Scala mailing lists), it will just dissipate into the Internet ethers. I'm just glad to have had those thoughts pass through my head, get dumped out and can let them go. {smirk}

    No comments:

    Post a Comment