Current issue

Vol.26 No.4

Vol.26 No.4

Volumes

© 1984-2024
British APL Association
All rights reserved.

Archive articles posted online on request: ask the archivist.

archive/15/2

Volume 15, No.2

This article might contain pre-Unicode character-mapped APL code.
See here for details.

Dyalog APL/W 8.2: First Impressions

by Adrian Smith (causeway@csi.com)

Introduction

This review has much the same status as the “Dyalog APL for Windows 95” article in Vector 12.2 (October 1995). It is a surface skim over the new features which have not been fully explored elsewhere, and is based on the first beta release of the interpreter from the Dyalog DSS web site. Of course, bugs and major irritations will get fixed before it goes live, but the basic design and feature-list is now fixed.

Language Improvements

APL2 convergence continues with ...

N-wise reduction
Designed originally for moving averages (the replicate, rotate and add method being slow and heavy on workspace):

      vv„?365½12
      ½12+/vv
354

... but also very useful for bitmap manipulation. If you want to do edge-detection or smoothing on a bit-pattern (or run a fast ‘Life’ program):

      mm
0 0 1 1 0 0
0 0 1 1 0 0
1 1 1 1 1 1
1 1 1 1 1 1
0 0 1 1 0 0
0 0 1 1 0 0
      (3+/3+š0®(0,mm,0)®0)-mm
0 2 3 3 2 0
2 5 6 6 5 2
3 6 7 7 6 3
3 6 7 7 6 3
2 5 6 6 5 2
0 2 3 3 2 0

... neighbour-counting just got really easy, and a lot faster!

Scalar Functions with Axis
Really, this should have been in APL from the beginning! Row-wise addition of vectors to matrices was just about bearable, but anything else is a real pain, and again soaks workspace unnecessarily. Now we can say:

      mm„3 4½¼12
      mm+[1] 20 30 40
21 22 23 24
35 36 37 38
49 50 51 52

Hard to see how anyone could object to either of these (rather long overdue) extensions.

New Control Structures

:Hold is well covered elsewhere in the articles on threading, so just a brief mention for :with which is a nice alternative to ŒCS, and a lot safer:

:with obj
   instancevar+„1
:endwith

... is so much neater than the current alternatives of:

 obj–'instancevar+„1'

or

here„ŒCS obj ª instancevar+„1 ª ŒCS here

... which always leaves me feeling nervous if it is spread over several lines, as I may accidentally reuse here and lose track of where I came from. I expect that as we encounter more and more OLE servers with object trees yards deep, we will get used to :with excel1.application.sheet5.range and our APL code will look more like VB by the day. C’est la vie.

Environmental Stuff (mostly session changes)

Session Coolbars
Hmmmm. It took me about 3 sec to hate these and 10 sec to get into the WS Explorer and ŒEX the lot of them. Fortunately 8.2 happily loads your existing ŒSE so I am back on a black screen with nobbut a menu bar. However de gustibus non disputandum as they say in Basingstoke.

Permanent Session Log
Something the mainframe APLs had from the beginning, and APL2/PC showed the way with back in 1990. Very useful, particularly given the increased buffer size mentioned below.

Bigger Input Buffer
This one I really like, for a slightly oddball reason. For years, I have run with a version of WsLoc which echoes lines to the session, decorated fore and aft with characters ...

      Œse.WsLoc '38'
’onKeyPress[12]      :CaseList 38 40 © Up/Dn should work weekly’
’onKeyPress[13]        dte+„7ׯ1*ks=38’

This makes for a very efficient global replace operation (with manual verification) as you can simply whip down the session changing any required lines and then hit [Enter] to process the lot. The downside was that it was easy to fill the input buffer, in which case Dyalog just barked and rejected the whole stack. Now I can make the buffer so huge that I will never lose work this way again. Brilliant.

Strong Interrupts (System Tray Icon)
Interested to know why they did it this way! This will get more useful with multithreading, as the cheap way to implement :hold is simply to diamond up critical sections into single long lines. It then becomes more necessary to be able to break execution mid-line.

Existing Gui Stuff

The usual pot-pourri of minor updates to existing objects:

  • 24-bit bitmaps now report a CBits array which is the encoded RGB value for each pixel.
  • graphical objects tell you where the mouse hit them. Also you can use ('Drawmode' 6) on polys and rects to make DIY locators. Essential for stuff like the draggy line-charts in RainPro.
  • bitmaps can make uncompressed GIFs and compressed PNGs.
  • listviews have checkboxes, optional gridlines and (at last) you can select a row by clicking anywhere, not just on the left-hand column, in report view.
  • smooth progress bars are back in the frame!

The implementation of checkboxes looks somewhat half-baked – it is not at all clear how you set them and the recommended method for reading back the value:

      STATE„2 ŒNQ'Form.ListView' 'GetItemState' 11
      13œ²(32½2)‚STATE
1

... looks like a pretty serious loop if you have a few hundred items on your list. I think a ‘checked’ property might be in order here!

New Gui Objects

Just as the language is converging slowly on APL2, the Gui is gradually evolving towards the true Microsoft look-and-feel. However the usual caveats apply – use these new toys because you want to, not because you can!

Calendar
Probably the simplest of the new controls to describe, and likely to turn up as a ‘drop-down’ on many people’s date fields very quickly.

     ’Cal
[1]   © Simple Calendar
[2]    'ff'ŒWC'Form' 'Calendar'(400 100)(200 200)('coord' 'pixel')
[3]    :With 'ff'
[4]      ŒWS'event' 40 '#.onFocus'
[5]      'cal'ŒWC'calendar'('event' 22 '#.onKeyPress')
[6]    :End
     ’
calendar screenshot

Note the need for the fully-qualified callbacks if you use :with here – I spent a few moments wondering why I was getting VALUE ERROR error as soon as I clicked on the form. Of course it was looking for the callback functions in the namespace of the form!

The only serious snag with this one is the total lack of any built-in keyboard behaviour. As a well-known muriphobe, I was relieved to find that it did respond to keystroke events, so here is a first-cut handler for it:



     ’msg„onKeyPress msg;this;ks;ctrl;dte;ts
[1]   © Do some intelligent things with the Calendar keyboard
[2]   © Extend to taste!
[3]    (this ks ctrl)„msg[1 5 6]
[4]    :With this
[5]      dte„1œŒWG'SelDate'
[6]      ts„2 ŒNQ'' 263 dte
[7]      :Select ks
[8]       :Case 84  © t=today
[9]         dte„2 ŒNQ'' 264 ŒTS
[10]      :CaseList 37 39 © Left/right just roll the days
[11]        dte+„¯1*ks=37
[12]      :CaseList 38 40 © Up/Dn should work weekly
[13]        dte+„7ׯ1*ks=38
[14]      :CaseList 33 34 © PgUp/Dn
[15]        :Select ctrl
[16]          :Case 0 © ... roll months
[17]            ts[1 2]„1+0 12‚(¯1*ks=33)+0 12ƒ2†ts-1
[18]          :Case 2 © ... or years if Ctrl
[19]            ts[1]+„¯1*ks=33
[20]        :End
[21]        dte„2 ŒNQ'' 264 ts
[22]     :EndSelect
[23]     ŒWS'SelDate'dte
[24]   :End
     ’

You can also queue a ‘GotFocus’ on it, hence the handler on the parent form:

     ’msg„onFocus msg                                                                 
[1]   © Set focus to calendar                                                         
[2]    ŒNQ((œmsg),'.cal')40                                                           
     ’

... which makes quite a nice little mini-application out of it. If you click on the month, you get a month menu – click on the year and it magically becomes a spinner! Probably it does other party tricks too – neither of the above were documented anywhere. The calendar runs from 1600, and the last valid date is day 23242571, which is Dec 31st 65535.

The Splitter Object
This one leaves me feeling very relieved. Causeway has been faking splitters for some time, and I do this in a very non-Microsoft way by having the splitters at the same level as everything else on the form, and setting a property of the list of other objects the splitter should manage. This has the great advantage that you can add splitters retrospectively to existing designs very easily.

The Dyalog splitter works very much in this way, and provides ‘start’ and ‘end’ events so that you can totally ignore the built-in behaviour and use it in almost any way you please. The only thing to watch is that the order of creation is crucial:

     ’Split
[1]   © Simple Splitter
[2]    'ff'ŒWC'Form' 'Splitter'(400 100)(200 200)('coord' 'pixel')
[3]    'ff.s1'ŒWC'Splitter'('Posn' 40 «)
         ('Style' 'Horz')('bcol'(3/128))
[4]    'ff.s2'ŒWC'Splitter'('Posn'« 20)('bcol'(3/128))
[5]    'ff.s3'ŒWC'Splitter'('Style' 'Horz')('bcol'(3/128))
[6]    'ff.b'ŒWC'Button' 'Hello'(30 12)(28 72)
     ’
screenshot of splitter bars

Normally splitters are invisible, but the colour shows how they organise themselves in a series of smaller and smaller panes, working to the right and downwards. You can set the width of the line, and one element of the position, but a splitter never intersects a previous splitter.

As the example shows, splitters completely ignore objects which are not mentioned in any of their ‘splitobj’ properties. However they always resize each other to prevent crossovers.



Tab Controls and Tab Buttons
Referring back to Vector 12.2, I noticed that I prematurely celebrated the demise of the old TabBar and TabBtn when the property sheet arrived on the scene. Unfortunately, property sheets and property pages are far too specific in what they do, so we have mostly made do with the hand-crafted Dyalog tab-bars until now. The problem with this is that they do not look ‘quite right’ and that you are very limited in what you can do (e.g. adding and removing tabs) without creating ugly redraw problems.

The new tabs hook straight through to Windows95 common controls, so should look authentic and generally behave better when rebuilt on the fly.

     ’Tabs
[1]   © Top-aligned tabbar
[2]   'ff'ŒWC'Form' 'Simple Tabs'(400 100)(100 200)('coord' 'pixel')
[3]   'ff.tc'ŒWC'TabControl'
[4]
[5]   'ff.tc.t1'ŒWC'TabButton' 'One'
[6]   'ff.tc.t2'ŒWC'TabButton' 'Two'
[7]   'ff.tc.t3'ŒWC'TabButton' 'Three'
[8]
[9]   'ff.tc.s1'ŒWC'SubForm'('TabObj' 'ff.tc.t1')
[10]  'ff.tc.s2'ŒWC'SubForm'('TabObj' 'ff.tc.t2')
[11]  'ff.tc.s3'ŒWC'SubForm'('TabObj' 'ff.tc.t3')
[12]
[13]  © Get the second tab to the front ...
[14]   ŒNQ'ff.tc.t2' 30
     ’
tabbed subform screenshot

My only concern here is the lack of events reported by the tab buttons – only Create and Select. There are applications out there using right-mouse menus on tabs, and fielding drag-drop events to move items between pages of notebooks.

screenshot with scrollbar buttons

Otherwise these seem to work quite nicely, and the scroller you get when you make the form too small is very much less visually obtrusive than its predecessor:

There are plenty more party tricks here (like adding icons to the tabs), but for the moment I think the important thing is that the basics work well, and that the new-style tabs should be a very painless upgrade for most applications.

Tool Control and Tool Button
Note that both the tool control and ‘coolbar’ controls need a version of comctl32.dll which is more recent than the one shipped with Windows95 OSR2. This has implications for runtime installation, which you should consider very carefully before using them.

Again, these are a direct Windows-95 pass-through and so they also have the authentic Office-97 appearance and behaviour. Causeway has been faking these since Toronto (cunning use of mouse-enter/mouse-leave and much swopping of btnpix) and it will be a great relief to kick the code well into the long grass, and use a native Dyalog control here. It should build very much faster and be a touch more reliable.

     ’Tools cap
[1]   © Simple toolbar (cap is 0 or 1)
[2]   'ff'ŒWC'Form' 'Simple Toolbar'(400 100)(100 300)('coord' 'pixel')
[3]   'ff.tb'ŒWC'ToolControl'('Showcaptions'cap)('Style' 'buttons')
[4]
[5]   'ff.tb.il'ŒWC'ImageList'('Masked' 0)('Mapcols' 1)
[6]   'ff.tb.il.'ŒWC'Bitmap'('Comctl32' 120)
[7]   'ff.tb'ŒWS'ImageList' 'ff.tb.il'
[8]
[9]   'ff.tb.b1'ŒWC'ToolButton' 'Cut'('ImageIndex' 1)
[10]  'ff.tb.b2'ŒWC'ToolButton' 'Copy'('ImageIndex' 2)
[11]  'ff.tb.b3'ŒWC'ToolButton' 'Paste'('ImageIndex' 3)
[12]  'ff.tb.b4'ŒWC'ToolButton' 'Undo'('ImageIndex' 4)
[13]  'ff.tb.b5'ŒWC'ToolButton' 'Redo'('ImageIndex' 5)
[14]  'ff.tb.b6'ŒWC'ToolButton' 'Delete'('ImageIndex' 6)
[15]  'ff.tb.b7'ŒWC'ToolButton' 'New'('ImageIndex' 7)
[16]  'ff.tb.b8'ŒWC'ToolButton' 'Open'('ImageIndex' 8)
[17]  'ff.tb.b9'ŒWC'ToolButton' 'Save'('ImageIndex' 9)
[18]  'ff.tb.b10'ŒWC'ToolButton' 'Preview'('ImageIndex' 10)
[19]  'ff.tb.b11'ŒWC'ToolButton' 'Point'('ImageIndex' 11)
[20]  'ff.tb.b12'ŒWC'ToolButton' 'Help'('ImageIndex' 12)
[21]  'ff.tb.b13'ŒWC'ToolButton' 'Find'('ImageIndex' 13)
[22]  'ff.tb.b14'ŒWC'ToolButton' 'Again'('ImageIndex' 14)
[23]  'ff.tb.b15'ŒWC'ToolButton' 'Print'('ImageIndex' 15)
     ’

Somewhere in the Windows documentation, there must be a complete list of these built-in icons! Here is what this set looks like:

toolbar with icons

One of the nice touches is that you can turn captions on/off on the fly, which makes for a very easy ‘user preferences’ dialogue:

 'ff.tb'ŒWS 'Showcaptions' 1
icons with captions

To space the buttons into logical groups you add a button with style ‘separator’, which I never would have guessed – thanks to Dyadic for pointing out this undocumented facility!.

Again, these do several other party tricks, for example you can do see-through buttons like Explorer (but not the effect of grey shades which light up on mouse-over), and of course the default is the Office-97 style which are flat until they sense the mouse.

Coolbars and Coolbands
These are by far the least convincing of the new controls:

coolbar

As you can see, it has bad redraw problems (the mouse was over the ‘file open’ tool which has lost its lower edge, and the grippers cut an unpleasant notch in the upper groove), and the behaviour is unlike any Office tool I have seen, except for Internet Explorer.

     ’Cool cap
[1]   © Simple coolbar (cap is 0 or 1)
[2]    'ff'ŒWC'Form' 'Simple Coolbar'(400 100)(100 300)('coord' 'pixel')
[3]    'ff.il'ŒWC'ImageList'('Masked' 0)('MapCols' 1)
[4]    'ff.il.'ŒWC'Bitmap'('ComCtl32' 120)
[5]
[6]    'ff.cb'ŒWC'CoolBar' ª 'ff.cb.c1'ŒWC'CoolBand'
[7]
[8]    :With 'ff.cb.c1'
[9]     'tb'ŒWC'ToolControl'('ImageList' '#.ff.il')('Showcaptions'cap)
[10]    'tb.b1'ŒWC'ToolButton' 'New'('ImageIndex' 7)
[11]    'tb.b2'ŒWC'ToolButton' 'Open'('ImageIndex' 8)
[12]    'tb.b3'ŒWC'ToolButton' 'Save'('ImageIndex' 9)
[13]   :EndWith
[14]
[15]   'ff.cb.c2'ŒWC'CoolBand'
[16]
[17]   :With 'ff.cb.c2'
[18]    'tb'ŒWC'ToolControl'('ImageList' '#.ff.il')('Showcaptions'cap)
[19]    'tb.b1'ŒWC'ToolButton' 'Cut'('ImageIndex' 1)
[20]    'tb.b2'ŒWC'ToolButton' 'Copy'('ImageIndex' 2)
[21]    'tb.b3'ŒWC'ToolButton' 'Paste'('ImageIndex' 3)
[22]    'tb.b4'ŒWC'ToolButton' 'Undo'('ImageIndex' 4)
[23]    'tb.b5'ŒWC'ToolButton' 'Redo'('ImageIndex' 5)
[24]   :EndWith
     ’

You will also see that I have arranged the bars to hide the ‘Redo’ tool, but there is no visual indication that it is missing. Word-97 shows a tiny ‘>>’ symbol if this happens. My feeling here is that if we can’t have proper docking toolbars, which can detach into floating palettes, then better not to bother at all. These guys are just mightily confusing for the user and are best left in the box.

Dyadic rightly point out that the above may well be true, but it is hardly their problem if Microsoft produce a set of ‘standard’ tools and then proceed to ignore them with the entire Office suite, Visual Studio, etc. If we want to do true ‘Office’ look-alikes we will have to wait a little longer, which is probably just what Redmond intended.

Other Stuff

TCP ‘SendPicture’
Interested to know what this is for! I have been shoving GIFs and PNGs down raw sockets, apparently successfully; clearly there must be some circumstance when the simple-minded approach fails.

SQAPL Version 3
Lots of small improvements, some of which will remove installation problems (the hardwired registry key for SQAInit was a nuisance) and some of which will mean big speedups. Support for array update is very welcome.

Summary

Obviously, the main thrust of work in version 8.2 was towards OCX support, with a substantial investment in multithreading. There must be lots of Dyalog users around who wouldn’t know an OCX if it came up and bit them, and who are rightly running scared of multiple concurrent )SI stacks. Hopefully they will have gleaned enough from these notes to judge whether an upgrade to 8.2 is worth the trouble and expense.

My feeling is that it is a bit like Windows-98 – it rolls up a lot of minor improvements which have been filtering out of DSS, consolidates the documentation, and adds a couple of bonus goodies (like the Calendar) to make you feel good about it. It is also remarkably stable – I have not crashed it once while writing these notes, in spite of pushing the Gui around trying to find redraw problems and other minor irritations.

I think it is worth it for the language improvements alone, and I welcome the chance to take a bunch of code out of the Causeway splitters, picture buttons and tabbed dialogues. Forms should load faster, and look a touch more professional, which all helps to keep APL in the frame as a viable Gui development tool.


script began 9:23:50
caching off
debug mode off
cache time 3600 sec
indmtime not found in cache
cached index is fresh
recompiling index.xml
index compiled in 0.1739 secs
read index
read issues/index.xml
identified 26 volumes, 101 issues
array (
  'id' => '10008800',
)
regenerated static HTML
article source is 'HTML'
source file encoding is 'ASCII'
read as 'Windows-1252'
URL: calendar.gif => trad/v152/calendar.gif
URL: splitter.gif => trad/v152/splitter.gif
URL: tabs.gif => trad/v152/tabs.gif
URL: scroltab.gif => trad/v152/scroltab.gif
URL: toolbar.gif => trad/v152/toolbar.gif
URL: toolbar2.gif => trad/v152/toolbar2.gif
URL: coolbar.gif => trad/v152/coolbar.gif
completed in 0.2011 secs