In the last installation of this series, we started using Java iterators to decompose the monolithic REPL (read-eval-print-loop) into modular compoments. This let us start decoupling the semantics of the REPL from the mechanisms that it uses to implement read, evaluate, and print. Unfortunately, the last version of rpncalc only modularized the command prompt itself: the ‘R’ in REPL. The evaluator and printer are still tightly bound to the main command loop. In this post I’ll use another kind of custom iterator to further decompose the main loop, breaking out the evaluator and leaving only the printer itself in the loop.
Up to now, the calculator’s main command loop has been a straightforward implementation of a REPL, or ‘read-eval-print-loop’. If you’re unfamiliar with the term, REPLs are the traditional means that interactive programming languages use to provide their interactivity. REPL’s provide a command prompt that a user can use to explore and manipulate the programming environment. In this way, a REPL makes it possible to work more quickly than traditional environments that require a program to be recompiled and restarted to test code changes.
While REPLs can become very complex in the details, the core idea is quite simple. As the name implies, REPL’s read a command from the user, evaluate that command, print the result of that evaluation, and loop back to start again. In rpncalc, all four of these steps are clearly evident in the code of the REPL. This is useful for explanatory purposes, but it closely couples the REPL to specific implementations of ‘read’, ‘evaluate’ and ‘print’. For this post, we’ll look into another way to model a REPL in code that offers a way to break this coupling.
Throughout the last four parts of this series, the common theme has been that the state of the calculator program has been managed globally. This requires the main command loop to directly update global data after each command, to prepare the state for the next command. While this works, it would be nice to remove the need for the global update. This post talks about how that’s done in the functional version of rpncalc.
In the last installment of this series, I built a basic undo facility on top of the command pattern. One of the problems with that implementation is that the Command class has to know too much about how to save and restore the overall state of the calculator. In this post, I’ll introduce a way around this problem.
One of the reasons given in the GoF book for the use of the command pattern is to support undo. By recording the commands executed by a user, and giving the commands the ability to reverse themselves, a user interface can be designed to allow users to undo mistakes they make. For this post, I’ll talk about how this is done in the undoable version of rpncalc.
If you’ve played around with the basic version of the Java calculator, you may have tried to enter multiple commands on the same prompt line:
> 1 2
This is a convenient way to enter calculator commands, but it doesn’t work for two reasons. This post discusses why it fails, and how to fix it:
The first implementation of the RPN calculator I’m going to look at is the basic Java implementation. The link takes you directly a a view of the source file for this version, but if you’d like to play with the code, you can also clone the whole project with git: https://github.com/ksmpartners/blog-rpncalc. Cloning the git project will bring down all the versions of the calculator, and also let you compile and run the software locally. I’ll discuss more about how the implementation works, after the jump:
One of the things I remember most about middle school math class is that I went through it in a perpetual state of disorganization. During one particularly bad spell, I lost two calculators within a week. The loss, and the reaction of my parents, drove me to try to fix the problem once and for all. My plan was simple: buy an expensive calculator with the hope that it’d serve as an incentive to keep track of my stuff. The next weekend, I took weeks of allowance money to the local Service Merchandise and bought a new HP-11C pocket calculator. Almost 30 years later, I still have both the calculator and a fascination for its unusual Reverse Polish Notation (RPN) user interface. Over those decades, I’ve also found out that RPN provides a good way to explore a number of fundamental ideas in the field of software design.
A friend recently invited me to compete in a shooting match where the targets are hardened half-inch steel plates. Speed counts: the faster you hit them all, the better your score. I had only ever practiced on paper bulls-eye targets and an occasional tin can lineup, and I never shot for time. To me, shooting required careful aiming and controlled squeezing, and lots of trudging to mark or replace the target. I enjoyed what I called “target practice” for at most 20 minutes at a time, but I wasn’t sure I could blow an entire Saturday at it.
I understand it now: it’s the nearly instantaneous, oddly musical, and immensely satisfying sound of lead striking steel. I have a new hobby.
The best developers love short code-to-test cycles. They obsess over the performance of their compiler and test framework. They divide their code base into smaller sub-projects that build independently. They consider code-to-test speed when choosing languages, frameworks, and application servers. They fight like cornered rats for their own dedicated full-stack environment, including a local application server and data store. To reduce startup and redeployment times, they strip both the application server and the data store down nearly to the metal, and they build lightweight unit tests that require neither. They can deploy and test their code in seconds.
They build their own equivalent of what shooters call “reactive targets.” Continue Reading…
For a variety of reasons (some good, some bad) I tend to fall into the school of developers that debugs primarily with log messages and printf statements. (What can I say… It works for me.) As part of this style of working, I’ve developed a quick mechanism for instrumenting TestNG to print a log message at the beginning and ending of each test method that it executes. This makes it easier to make sense of the other log messages that get issued during a test cycle.