Skip to content

Evolving Flying Fish, Running Birds, and Swimming Lizards: Resolving Paradigm Shifts

June 8, 2011

Approximately two weeks ago, on Wednesday, May 25, 2011, I posted the following question on the Haskell Beginners Mailing List:

Subject: question for advice on packages for a retro-style pocket money ledger program

For some time, I have been considering rewriting my original pocket money ledger program in Haskell, but am not sure as to which packages would be most useful. My original pocket money ledger program was first written in circa 1983 in N80-BASIC (a JIS-compatible ROM-based line BASIC) on an NEC PC-8001 mkII [1].

The main difficulty is that I would like to preserve the original look and feel of my original program while still rewriting it in Haskell. However, my original program ran in an age before any kind of Macintosh-style or Windows-style GUI had become common, and used basic built-in ROM-based graphics and sound commands to draw a double-line colored graphical border on a centered-colored-text screen, and saved files to a floppy disk drive (floppy disks were actually considered advanced for that age, since most personal computers then used a cassette tape drive for external file storage).

As a result, I am uncertain as to which packages would be useful for preserving the original look and feel of my program. At minimum, I would like my program to exhibit the following behavior:

1. Start out by drawing a lime-green-colored double two-pixel wide box surrounding the screen, with the title and author name displayed as separately-colored text centered in the screen.

2. If possible, play a suitable music file while on this screen. Also, display an option to mute this music, and if this music is once muted, save this option for future runs of this program, so that the program will start out with the music muted as the default option. Also, display an option to control the volume of this music, and if possible, also display a separate option to choose a different tune to play. The tunes should be selectable from a selectable, expandable menu.

3. If possible, include a suitable screen saver to be displayed automatically, separate from the GUI screen saver, upon a user-defined period in which there has been no user input. The screen saver should be configurable in a separate configuration menu.

4. Upon the user hitting the Return key, stop playing the music (if playing), and move to the main menu screen.

5. The options displayed in the menu screen should include, at minimum, the following:

a. Create a new ledger book.

b. Load a ledger book (preferably from floppy disk).

c. Add an entry to the ledger book.

d. Delete an entry from the ledger book.

e. Erase the ledger book.

f. Save the current ledger book (preferably to floppy disk).

g. Tabulate and display income and expenditures (leads to a separate
screen requesting a time period for tabulation). (The income and
expenditures should be displayed in detail both as numerical charts
and as colored graphs in a preferred form (pie chart, bar graph,
etc.).)

h. Set configuration options (leads to a separate screen for
configuring default background music, default volume, default
application screen saver, default theme, default fonts, default menu
behavior, default keyboard remappings, default screen height/width
ratio, etc.).

i. Exit the application.

5. For each option (except for option i), move to a separate sub-menu screen. When input/output and processing have been completed on the separate sub-menu screen, return to the main menu screen.

Most of the functionality of this program is related to some form of input and output: colored formatted combined graphical and textual title screen with background music, manual data entry by a user, saving files to a floppy disk, reading files off a floppy disk, deleting files from a floppy disk, configuring various default music/volume/screen saver/theme/font/menu behavior/keyboard remapping/screen height and width ratio options, and combined numerical and graphical representation of statistical ledger information. Most of the computation involves only simple arithmetic (mainly addition and subtraction, with perhaps some multiplication and/or division, and no matrix manipulation).

The main point of this program is that program usage should be interactive, and not require a separately entered file. The idea is that the program will play the role of an interactive personal ledger assistant.

However, I am not sure as to how to implement this program in Haskell easily. Because most of the program is mainly concerned with side effects, it is difficult to write it easily while preserving referential transparency. This type of program seems relatively straightforward to write in N80-BASIC (which is no longer available in the original version), but is relatively less trivial in a purely functional programming language such as Haskell. However, I am tired of spaghetti code, and although writing each line of code in N80-BASIC is trivial, managing control flow is not. It is very difficult to manage control flow without writing spaghetti code in a dialect of line BASIC. However, most of the associated graphics and sound commands are proprietary and implementation-dependent, and I am not sure how to rewrite that part of the functionality in an implementation-independent language without spending lots of time on API-related issues.

— Benjamin L. Russell

[1] _OLD-COMPUTERS.COM Museum ~ NEC PC 8001 MK 2_. NYI (New York Internet). n.d. Web. May 25, 2011. .

Unfortunately, so far, nobody has replied, and I have a nagging suspicion that nobody will. The problem is that my question concerns translating a program originally written in N80-BASIC into Haskell, a language usually used for entirely different purposes. The original program used a number of language-specific, platform-dependent features (such as superimposing colored line graphics around the borders of a textual screen, and reading from and saving to a floppy disk).

For some languages, such features translate into corresponding features in the target language. However, Haskell is a purely functional programming language; as such, it is designed to eschew side effects, while my original program focused almost entirely on side effects. Therefore, translating my solution actually involves a paradigm shift.

This is not the first time that I have encountered a paradigm shift. In an earlier entry on this blog, entitled “Paradigm Shift: Back to the Past, and No Small Talk About Smalltalk,” dated August 25, 2009, I had to deal with another paradigm shift, that one involving a transition from the functional paradigm of Haskell to the message-passing paradigm of Smalltalk (a problem with which I am still struggling).

The problem is that most programmers who feel comfortable in one paradigm do not seem very eager to deal with paradigm shifts. For example, I have not read many writings by hardcore C++ programmers who enjoy translating C++ systems programming code into referentially transparent Haskell code. Neither have I read many papers by Prolog programmers about translating concurrent thread-manipulation Erlang code into pure Prolog code. Similarly, I have not read many papers by Smalltalk programmers about translating referentially transparent implementations of arrows in Haskell into Smalltalk code for which proofs of correctness can be written.

Most fish don’t seem to enjoy flying. Most birds don’t seem to enjoy running. Most lizards don’t seem to enjoy swimming.

However, exceptions exist: Flying fish fly, ostriches run, and marine iguanas swim. Evolution is possible.

The same can hold true, with varying degrees of adaptation, for programming languages. It is possible to push the proverbial cart from its side across town without ever using its wheels.

I, for one, think that there is a novel dimension of exhilaration associated conquering a paradigm shift which is of a different quality from that achieved by solving a programming problem. I have encountered a number of paradigm shifts in my life: imperative BASIC to pseudo-functional Scheme, pseudo-functional Scheme to functional Haskell, and functional Haskell to message-passing Smalltalk. Such shifts resemble the cultural shocks that I encountered when first moving from California to Tokyo, then from Tokyo to New Haven, and finally from New York back to Tokyo again.

To draw an analogy:

N80-BASIC:Haskell:Smalltalk::Tokyo:New Haven:Palo Alto

For some reason, I have never felt truly comfortable in any programming language. When programming in N80-BASIC, I struggled with spaghetti code. When programming in Scheme, I felt frustrated at not knowing how to draw colored superimposed lines around colored text on a screen specifically designed to allow superposition of graphics onto text. When programming in Haskell, I felt frustrated at not knowing how to write reflective programs that did not compute any value and that dealt only with side effects. When programming in Smalltalk, I felt frustrated at not knowing how to write referentially transparent functions for computing arrows.

What I would really wish for is a programming language that could do ALL OF THE ABOVE.

For the time being, I would be willing to settle for an easy way to translate my original N80-BASIC personal checkbook program into something that is algorithmic, referentially transparent, reflective, cross-platform portable, equipped with a rich set of libraries, and easily makes use of platform-specific features: a combination of Scheme, Haskell, Smalltalk, Clojure, and N80-BASIC.

Essentially, I need the artificial, programming language counterpart to a natural duck-billed platypus. Any ideas?

2 Comments
  1. Mr Web permalink

    Not sure if this helps, but one could implement your UI using SDL and maybe for “fun” even use this embedding of “basic” in Haskell: http://augustss.blogspot.com/search/label/BASIC

    • > Not sure if this helps, but one could implement your UI using SDL and maybe
      > for “fun” even use this embedding of “basic” in Haskell:
      > http://augustss.blogspot.com/search/label/BASIC

      Interesting … can the two be combined? What I would really prefer is to be able to write such N80-BASIC code such as the following:

      100 REM Set up screen parameters.
      110 SCREEN 0, 25, 0, 1
      120 WIDTH 80, 25
      130 REM Beep to greet the user.
      140 BEEP 1
      150 FOR I=0 TO 1000
      160 BEEP 0
      170 REM Print a formatted, colorful title screen.
      180 COLOR 4
      190 LOCATE 33, 10
      200 PRINT "The Excellency"
      210 COLOR 3
      220 LOCATE 34, 11
      230 PRINT "Version 2.0"
      240 COLOR 5
      250 LOCATE 31, 12
      260 PRINT "Copyright (C) 2011"
      270 COLOR 6
      280 LOCATE 29, 13
      290 PRINT "by Benjamin L. Russell"
      300 COLOR 7
      310 LOCATE 23, 14
      320 PRINT "Based on The Excellency, Version 1.0"
      330 LOCATE 19, 15
      340 PRINT "Copyright (C) 1983, by Benjamin L. Russell"
      350 COLOR 2
      360 LOCATE 27, 17
      370 PRINT "Press any key to continue."
      380 WHILE 1
      390 A$=INKEY$
      400 IF A$"" THEN GOTO 420
      410 WEND
      420 CLS:SCREEN 0, 25, 1, 1:WIDTH 40, 25

      This is a quick example of implementation-specific N80-BASIC spaghetti code that first sets the screen mode for 25 text rows and hides the function key display, sets the screen width to 80 columns by 25 rows, beeps and displays the title screen, then clears the screen and shows the function key display, then sets the screen width to 40 columns by 25 rows.

      I would also like to display an overlaid double green graphical line border. This border should display on an overlaid graphical layer independent from the textual layer.

      The problem is that many of these settings are specific to the NEC PC-8001. Although they also work on the NEC PC-8001 mkII, and probably also on the NEC PC-8801, and maybe even on the NEC PC-9801, they are unlikely to work on most other non-NEC personal computers.

      It is important to keep in mind that my original program was written in 1983, just before the release of the Apple Macintosh computer in 1984, and two years before the release of Microsoft Windows 1.0 in 1985. As such, the programming language in which it was written, N80-BASIC (the sequel to N-BASIC for the NEC PC-8001), was designed on the assumptions that the environment would not be a GUI environment, and that the language would be running from ROM in an OS that supported certain machine-specific functions, such as overlaying a graphical screen layer independently over a textual screen layer.

      These assumptions are usually violated on most modern OSs.

      Basically, my program would either need to run on some version of a machine specifically designed to be compatible with either the NEC PC-8001 or the NEC PC-8001 mkII (actually, NEC specifically announced such a machine, the PC-9821, on June 20, 2003, but the machine is no longer being manufactured), or would need to run within an emulator that somehow faithfully reproduced the functionality of the original OS. However, my research results have shown that because of copyright issues, any such emulator would need to be validated with a ROM module from an original machine. Unfortunately, I personally have no desire to purchase any pre-owned machine, and do not know where to purchase a new machine, since the machine is no longer being manufactured and has been off the market for many years. Every once in a while, a new machine crops up on an online auction site; I would probably need to save money to purchase such a machine in order to provide an environment for running such a program.

      Would you happen to know how to incorporate such commands in your version of BASIC? The easiest conceivable ways of running an updated version of my original program that preserves the original functionality are either to save funds to purchase a new copy of the machine somehow on some online auction site, or simply to design my own computer with a built-in BASIC interpreter coded in ROM; however, that would probably infringe NEC copyrights; nevertheless, the personal computer model that used to be able to run these instructions is no longer being built. As mentioned above, I have a personal preference against purchasing pre-owned products….

Leave a comment