[racket] My PLT->Racket porting experience
A former Bootstrap student of mine asked me to help him get his game
running on his home PC. The last time I taught Bootstrap, Racket was
PLT Scheme, and the latest version was 4.2.4 or something, so I
decided to test his game with Racket 5.1, figuring it would work
without any real trouble. That was not the case. It took me about 6
hours of work to debug and port. Here's some feedback on Racket 5.1:
* On Mac OS X, there's a bug in play-sound: the meaning of the async
flag is inverted. If it's #t, the thread will pause until the sound
is finished playing. If it's #f, the procedure call will return
immediately.
* Window management on Mac OS X is broken. Dialog boxes will sometimes
appear behind the main window. When this happens, it appears to the
user that DrRacket is broken/hung, as there's no way to interact
with the app, or even to quit without using Force Quit from the
Finder -- all of the File menu options are inactive. This also
happens from time to time in DrScheme 4.2.x, but it may be more
frequent now in DrRacket: I encountered the problem several times
during the porting process. The easiest way to trigger it is to add
a teachpack that's already been added. The "overwrite?" pop-up
dialog box is often hidden behind the main window.
* Scrolling through a source code window in DrRacket 5.1 on Mac OS X
is very sluggish, quite a bit slower than it was in DrScheme
4.2.x.
* The main difficulty I had, and how I spent most of my porting
and debugging time, is that paths in Racket are now relative to the
module in which they're used, which is different than the way
they're interpreted in PLT.
I modified the Bootstrap teachpack to allow the students to override
the sounds that are played when various game events happen. I didn't
have time to do things the proper way, by making sounds a first-class
object in the DrScheme/DrRacket environment (which would be a great
enhancement, by the way), so the students have to define a couple of
variables whose values are strings, representing the file names of
the sounds they want to play. The sounds are placed in the same
directory as their game source code, and the variables are passed as
arguments to the Bootstrap teachpack's "start" procedure. The
Bootstrap teachpack then uses the file names as arguments to
play-sound.
In PLT 4.2.x, this works great: the file names are looked up
relative to the directory in which the *game source code* lives, and
they play back as intended. In Racket 5.1 (didn't try with earlier
versions), the file names are looked up relative to the *teachpack's
directory*, and therefore aren't found.
That's fine, except for a few key things:
- This change in behavior isn't very well documented, from the
perspective of someone porting code from PLT to Racket. I can't
find a "porting guide," or a list of important changes from PLT to
Racket. I only caught on to this new behavior when I found a
cryptic reference to define-runtime-path on the mailing list, in
response to a question about why play-sound wasn't working in
someone else's Racket program.
- As far as I can determine, this change means that there has to be
a (define-runtime-path ...) form in the game source code, so that
the game module can pass its working directory to the teachpack
for proper construction of path names. I don't like exposing the
Bootstrap students to any more "magic expressions" than
necessary. If someone has a clever way to avoid it, I'd love to
hear about it; I'm still a bit unclear on how paths are resolved
in Racket.
- Worst of all, on the Mac, at least, the runtime errors that are
raised by the teachpack when play-sound can't find the file are
not displayed in the Interactive window! This was the cause of
most of my frustration and wasted time. I had no idea why the game
was hanging when it was supposed to play a sound: no error
message, no pop-up, nothing in the log window... just a frozen
game window.
The good news is that I do have a working version of my modified
Bootstrap teachpack for Racket, now -- for Windows, at least. The Mac
version is still broken because of the play-sound bug.
d