Thursday, August 11, 2011


The last few days I've been involved with a rewrite of the fltk- > haskell msg format, intended to fix some annoying focus issues, where haskell's idea of the current focused window is out of sync with the GUI.  The problem is that I was using the ViewId of a Context to indicate the "scope" of the msg, and then taking that to also be the current focused window.  But it's not true, because a close msg on one window is not an indication that that window has focus now!  I had some logic to ignore those cases but there were still nagging focus errors, so I decided to apply the lesson I learned with keyboard modifiers, which is to send the complete state explicitly on every single msg, rather than sending it only when "necessary" and assuming you caught all the necessary cases.  So I added a separate "focus" field that has the current focused window in it no matter what.

It's annoying work because it's all this low level peek/poke FFI stuff.  It would have been a lot less work if I had just added the new field, but I took the opportunity to factor the C++ UiMsg struct into a real union instead of an ad-hoc mess of optional fields.  I feel like effort spent here on clarity is worth it because this is one of the few places I can actually have a runtime error and the type system won't save me.

Going back to C++ for a while, it's really kind of amazing how many opportunities there are for runtime errors.  Every time you use an index, every time you assume a pointer is non-null, every time you read something from a possibly uninitialized field (and union fields can't have default constructors!).

It was a big hassle but it looks like it's working and no fishy focus confusion yet.  And every time I do an internal refactoring like this a stumble across another set of little things that could be cleaned up, small renamings, simplifications, etc.  Hard to tell how much good that stuff does, but it's fun.

It's kind of cool that ghc's case analysis will warn about missed cases for numbers:

    Warning: Pattern match(es) are non-exhaustive
         In a case alternative:
             Patterns not matched:
                 #x with #x `notElem` [1#, 2#, 3#, 4#, 5#, 6#, 7#]

Only it warns you about the elements you *did* match instead of the ones you missed.

Work has been slow lately because of other distractions.  Playing at a wedding on the weekend, so I have to practice.  Transcribing a piece for 婉昭, and learning lilypond while I'm at it.  This is sort of two birds with one stone because it would be interesting to make a lilypond backend for karya.  Staff notation is very good at showing vertical relationships in common practice music, better than my notation.  It would be nice to have it as an auxiliary display for the cases when it's faster to listen in your head.

No comments:

Post a Comment