NYCJUG/2005-04-12

From J Wiki
Jump to navigation Jump to search

Save Work project reports, GUI event-loop, combining GUI with command-line, general organizing principles for learning J


Agenda

1. Group project: report on assignments
    a. Harteg - initial screen: we need this ASAP: everything else
       depends on it.
    b. Dan - persistence of information
    c. Jim - his own report
    d. John - date conversion
    e. Chris Lett unable to continue - may rejoin us later.
    f. Devon - short-term focus-> prototype sufficiently useable for
       everyone to start using it.

       Also: see Spolsky "Good Software Takes 10 Years"

       Design philosophy:
            Standalone, re-usable modules }
                                          } GUI + command line
            Built-in unit tests & doc     }

2. Assignments: going forward - what next?
    a. What unit tests?  Assertions?  WWHD? (What Would Hui Do?)
    b. Combining screen persistence with automating user input for testing;
       combining the power of GUI with the power of command line.

3. Learning and creating learning materials: look at Neville Holmes's
   letter to J forum:

naming convention suggestions: File:NamingConventionSuggestion.txt

   General organizing principles - main categories?
   e.g.
       Getting started 0: complete programming novice
       Getting started 1: J-novice, other programming experience
           -> Rosetta Stone?  e.g. VB->J?
       Utilities: what are general types?
       Web site?

4. Howard Peele's talk - date and format?
 Let's say early June.  How can we beef up attendance?

Bonus Fact:
NB. The 42nd Mersenne prime was recently discovered.  It took about
NB. 12 hours for my 2GHz desktop machine to calculate it:
   mp41=: ":<:2x^25964951
NB. (I keep the character-representation result because it's simpler to
NB. manipulate)
   $mp41
7816230
   +/'314159' E. mp41
11

Proceedings

Part 1: the Event-Loop Horizon

Members of the group who were present reported on their assignments. Harteg showed some code he'd found for doing some windows work but complained how little documentation there is on this. There is the typically bare-bones sketch presented on the "wd" command and some intro to the Form Editor in the User Manual but even this is very spare. He also mentioned wanting to use the directory browser but he was having trouble finding it: this was my cue.

I usurped some of Harteg's assignment because I had to design a window much like we needed: it is intended to be a stand-alone window to allow the user to specify a source and destination directory. The directory names may be typed in directly or specified using the directory browser "dirbrowse.ijs" which is in C:\Amisc\Jsys\System\Packages\Winapi. My module is called "SDDir.ijs" (for Source/Destination DIRectory): File:SDDir.ijs .

However, I was dissatisfied with the result because of a design flaw: I wanted to update a region on the input window while my process was churning through various steps. To do this, I chose to overwrite the event handler for the "OK" button in my application. Of course, this is a non-modular way to accomplish this task.

Harteg suggested perhaps separating the updated message to a status bar; this led to the idea of perhaps keeping the message updating in a separate window entirely. I gave him the task of re-designing SDDir to better accomplish the goal. We discussed the problems with doing this and John brought up the mysteriousness of the event loop - how we're never sure when and how it's being invoked. This seems to be at the root of the problem.

However, I regret to inform Harteg that I have yet again done his assignment - at least partially. In doing so, I have also laid bare some of the mystery of the event loop. To avoid Harteg doing any unnecessary work, I will attach the code I came up with but with only a little explanation. Also, to avoid wearing myself out on this report, I'll leave further meeting notes to another time.

One change I made of which I'm unsure was to rename the top-level entry point using the suffix "_handler_" (instead of "_run_"). I'm not sure this is required but this name appeared in the queue variable "wdq" so I took the hint. This top-level is the part I'll explain a little about. I've included it following just to have it handy.

Overarching Design Goal: GUI + Command Line

Before we get to the code, I'd like to explain what motivated me to do this work. One of the design goals I attempted to explain in this meeting was how a major problem with a GUI interface is that it interferes with automating code. So, if we want to test our code exhaustively, our testers must exhaust themselves typing variant inputs into windows. It would be much better if all GUI events could generate editable scripts which could be played back to accomplish the same thing as the GUI input.

So, as a tiny step toward implementing this notion, and because it made sense given the way I planned to use the SDDir code, I wrote a couple of opening lines like the following at the start of my application:

   if. ''-: y. do. 'src dest'=. sddir_handler_srcdest_ ''
   else. 'src dest'=. 2$boxopen y. end.

The idea here is that the function can be called with zero, one, or two elements in the right argument. If there are none, open the Source/Destination window to get user input. For a single directory, assume that the source and destination are the same. For two arguments, assume they are source and destination, respectively.

However, because of the event-driven nature of windows, the phrase     'src dest'=. sddir_handler_srcdest_ '' returns to immediate execution immediately - before the user has a chance to enter the directories. I can't call an event-driven script like I can any other function because the paradigm is different and it doesn't know to wait for the user to take action. Put another way, I want "sddir_handler_" to finish processing and return a result before I continue but the GUI world doesn't work that way.

The problem, as John had pointed out, is the invisibility of the event loop.

When I finally decided to read the "wd"-associated code (in ~system\main\winlib.ijs), I noticed that some of the standard status boxes behaved exactly as I desired. This behavior is apparent in the message box family of commands: "mb" and "mbopen".

Examining the code for "wdselect", I had my "Eureka!" moment: I found an explicit event-loop handler. The key is in the "wait" and "q" arguments to wd. The code I derived from this follows. The main trick is in the "keepWaiting" loop with the expression

       ({."1 wdq)=: {:"1 wdq

To understand what this does, consider that "wdq" is a 2-column table of name-value pairs. For instance, some entries might be:

   _3{.wdq_srcdest_
+--------------+--------------------------------+
|SDdestd_select|0 0                             |
+--------------+--------------------------------+
|SDsrcd        |<source directory with holdings>|
+--------------+--------------------------------+
|SDsrcd_select |0 0                             |
+--------------+--------------------------------+

Column 0 is a name and column 1 is its value. Putting the text of the name in parens and assigning it accomplishes an indirect assignment. Try it:

   nameholder=. 'flarb'
   flarb
|value error: flarb
   (nameholder)=. i. 10
   flarb
0 1 2 3 4 5 6 7 8 9

Dan used this method in his lexical closure code where he was dealing with name-value pairs.

So, without (much) further ado, here is the main event (-loop). Invoke the attached code by loading it and running

   sd=. sddir_handler_srcdest_ ''

You'll notice you can't reach your session window until you've exited the SDDir window: that's because it has assumed control of the event-loop. Also notice that you don't come right back to immediate execution upon exit of the SDDir window. I had to put    smoutput '' in my code for the "OK" and "Cancel" buttons in order to resume processing. Perhaps someone can explain why this is and how to avoid it?

sddir_handler=: 3 : 0
   wd SDDIR
NB.   SDHWNDP=: wd 'qhwndp;'
NB. Initialize entry fields here...
   if. 0>4!:0 <'SRCDIR' do. SRCDIR=: '<source directory with holdings>' end.
   if. 0>4!:0 <'DESTDIR' do. DESTDIR=: '<destination directory for Barra portfolio files>' end.
NB. Put current values or explanatory text in the entry fields.
   wd 'set SDsrcd "',SRCDIR,'"'
   wd 'set SDdestd "',DESTDIR,'"'
   wd 'setfocus SDsrcd'
   wd 'pshow'
NB. Our very own event loop.
   keepWaiting=: 1
   while. keepWaiting do.               NB. Wait until user exits...
NB. This is the key: assign the entire queue to "wdq" and
       wdq=: wd 'wait;q'
NB. assign every variable in 1st column to its value in the last column.
       ({."1 wdq)=: {:"1 wdq
       if. DEBUGON do.
           smoutput 'syschild is "',syschild,'"; systype is "',systype,'".'
       end.
       cxl=. (<'cancel') e. systype;syschild
       button=. systype -: 'button'
       if. button do.
           select. syschild
               fcase. 'enter' do.                 NB. Don't think this works.
               case. 'ok' do. sddir_ok_button ''
NB. Treat enter in an input field just like pressing OK.
               case. 'SDdestd' do. sddir_ok_button ''
               case. 'SDsrcd' do. sddir_ok_button ''
               case. 'brwsSrc' do.
                   wd 'set inpBoxMsg "Enter Directory or press OK"'
                   sddir_brwsSrc_button ''
               case. 'brwsDest' do. sddir_brwsDest_button ''
               case. 'cancel' do. sddir_cancel_button ''
           end.
       end.
   end.
)

Part 2

On the advice of Jim, I'm keeping these minutes to a single page. I already wrote at length about screen handling. Dan sent me a message telling me he's still looking at YAML for maintaining the state of data between sessions.

Jim presented a couple of pages on beginning an index for J. He covered some basic principles perhaps the most important of which was to focus on what to index. Also, we continue to bring up the idea of synonyms to help people locate things within a familiar vocabulary. Finally, Jim is proceeding with his APL/J Rosetta Stone. I agreed to publicize this to the J-Forum and urged that a VB/J version might be more widely useful. Jim's index ideas: File:NotesforJIndex050403.htm or File:NotesforJIndex050403.doc.

As for publicizing our work and making it available, we need to consider putting up a website for the group. "NYCJUG" is unavailable with any common prefix but NYCJuggernaut.[com|org|net] is available. I'd be willing to put up the money to get this going and help with the web work if someone else could shoulder the bulk of it.

John provided some preliminary work on date formats, focussing on something based on an integer Julian day, perhaps with an optional day fraction to denote time of day: 0->1 corresponding to midnight to midnight. In the interest of focus, I suggested he look mainly at dates likely to occur in the context of the "Save Work" project, i.e. DOS-format dates from 1980 to some point in the not-too-distant future. John's notes: NYCJUG/DateRepresentation.

Chris Lett has let us know he'll be unable to offer his services for the time being but may re-join us once things have calmed down at work.

We were joined by a new person who some of you may have known from the J-Forum: José Quintana. He uses J extensively in his work and has strong ideas about tacit programming (in favor) and Turing completeness.

I'm emphasizing a short-term focus for our project. I'd like to get a working prototype into the hands of all our members (and Vicki) so they can start using it. It's important to use and continually refine software to get something that works well. It's to buttress this notion that I passed out copies of a column by Joel Spolsky: "Good Software Takes Ten Years. Get Used To it."[1]

To re-iterate 2 important elements of design philosophy:

1) we want standalone, re-usable modules and
2) built-in unit tests and documentation.

Also, partly as a means to achieving this, we want to combine the strengths of both GUI and command line environments: the same code should run both. We should be able to capture and replay GUI action as scripts.

Going forward, we need to start incorporating unit tests, perhaps using assertions? WWHD? (What Would Hui Do?)

Also, combine data persistence and tracking with automating user input for testing; this is where we have to combine the power of GUI with the power of the command line.

Finally, I'm going to ask Howard Peele if he can talk to the group in early June - he may or may not be able to hit the 2nd Tuesday. Once he's committed, I'd like to make an effort to beef up attendance.