]> git.donarmstrong.com Git - lilypond.git/blob - TODO
patch::: 1.1.26.jcn2: fixjes
[lilypond.git] / TODO
1 Features you cannot find in the doco as working, should be mentioned
2 here.
3
4 This is an assorted collection of stuff that will be done, might be
5 done, or is an idea that I want to think about
6
7 Most of the items are marked in the code as well, with full explanation. 
8 grep for TODO and ugh/ugr/urg
9
10 *In a piece such as the Zipoli piece in mutopia/... there is a stray
11 `8' over every bar line when processed by LilyPond 1.1.25.
12
13 TODO before 1.2
14
15         * junk Text_def, use G_text_item in stead.
16
17         * junk Script_def
18
19         * fix partial measures in meaningful way.
20
21         * fix AFM for BlueSky AFM files.
22
23         * working notehead style.
24
25         * add scripts to bars eg.  |^"bla" 
26
27         * relative mode for mi2mu
28
29         * uniformise recent feta contributions.
30         - use SCM and Molecules for {accordeon stuff, }
31         - bigger and fatter 4/4 C
32
33         * make a SMOB of Atom and Molecule
34
35         * use kerning for dynamics.
36
37         * sort out directory stuff.
38         - --prefix option?
39         - -I option per filetype?
40         - kpathsea?
41
42 **************
43 I also found a few bugs:
44
45 * The examples in input/test/bar-scripts.ly and score-bar-scripts.ly
46   don't work. The problem seems to be that you can't define a 
47   a score identifier and then use it in the \score block.
48
49
50         - make separate MF chars for endings of ledger lines, and calc rest of lines.
51
52         * support_l_arr_ empty in staff-margin's G_staff_side_item
53
54
55 ************
56
57 How can I specify a chord whose duration is longer than a whole note?
58
59  \type ChordNames { \chord{ A1*2-min } }
60
61 gives me a parse error.  And \times doesn't work either.  I can't use
62 a spacer note.  So it seems to be impossible to have long chords of
63 general length.  Of course, in the example above I can use \breve.
64 But what if I want a chord that lasts for 3 whole notes?  Or what
65 about 2.5 whole notes?  Is there a mechanism for getting this kind of
66 length?  
67
68
69 Why does my second extender request get junked in the following:
70
71 \score{
72 < \notes \relative c''{ 
73      a4()b()c()d c()d()b()a }
74    \type Lyrics \lyrics {
75      foo1 __  bar2. __ _4 }
76 > }
77
78 It seems that \cr and \decr don't work any more.  
79
80 \score{
81   \notes{
82     a \cr b \rc c }
83   \paper{linewidth=-1.;}
84 }
85
86 Gives me 
87
88 qq.ly:3:9: warning: can't find (de)crescendo to end:
89     a \cr
90           b \rc c }
91
92
93
94 Use of semicolons is still rather confusing.  They are obligatory
95 after some types of assignments and illegal after others.  
96
97   \property foo=bar               illegal
98   foo = 3 at top level            illegal
99   foo = 3 inside \paper           obligatory               
100   foo = \notes{ ...} top level    illegal
101   foo = \translator{ } in \paper  obligatory
102
103 As far as I can tell, the sole accomplishment of this syntactic
104 irregularity is to keep the user as confused as possible.  
105
106
107 I was trying to get interstaff beams to work and did this:
108
109 \score{
110 \type GrandStaff <
111 \type Staff=one \notes\relative c'{
112   \stemup
113   [c8 c \translator Staff=two \stemup c c]
114   \translator Staff=one
115   \stemdown 
116   [ b8 \translator Staff=two a8]
117   \translator Staff=one 
118   c4 
119   }
120 \type Staff=two \notes{ \clef bass; s1 }
121 >
122 \paper{
123                 \translator{
124                         \GrandStaffContext
125                         minVerticalAlign = 3.0*\staffheight;
126                         maxVerticalAlign = 3.0*\staffheight;
127                 }
128   linewidth = -1.;
129 }
130 }
131
132 The beams are at the right angle, but they aren't in the right place.
133
134
135
136 *******************
137
138
139         * fractional chord durs.
140
141         * hang Item on Spanner
142
143         * remove Interval dim_ from Dimension_cache and rename the struct.
144
145         * do --safe for PS output?
146
147         * convert-mudela --output
148
149         * Staff_margin (with a partial measure.)
150
151         * fix "I've been drinking too much"
152
153         * fix pletvisibility properties:
154           - bracket on/off/no-bracket-when-beam
155           - num on/off/no-num-when-beam
156
157         * fix: standchen.
158
159         * junk backlinks?
160
161         * junk text{sharp,flat,etc}
162
163         * fix convert-mudela manpage
164
165         * decimal point in \paper {}
166
167         *{  \voiceone <a'4.*2/3  d''4.*2/3 fis''4.*2/3>  [g''8 fis'' e''] d''4 |}
168          and=20
169          { \voicetwo  d'4 d'2.*2/3 } spacing
170
171         * tied notes for MIDI
172
173         * sharp /flat on trills (in MIDI ??)
174
175         * scm-ify \property values.
176
177         * move class Lookup {} into scm
178
179 BUGS:
180
181         * collisions/voices \voiceone \voicetwo are broken; see 
182           input/praeludium-fuga-E.ly
183           mutopia/J.S.Bach/wtk1-fugue2.ly
184
185         * fix: text on rests: rediculous dims
186
187         * ly2dvi
188           - bottomnote for ly2dvi
189           - deps for ly2dvi
190
191         * fix midi output:
192            - default duration?  duration must be not entered
193              explicitely on first note.
194
195         * turn slope-damping on/off
196
197         * c4 \! \> c4
198
199         * tremolo stuff
200
201         * gallina barlines.
202
203         * fix height of / collisions with lyrics (chords), 
204            see input/test/vertical-text.ly; input/test/repeat.ly
205
206         * latex bla.tex broken (titles / \lilyfooter stuff?)
207
208         * msgfmt -o check?
209
210         * \breathmark TeX macro 
211
212         * catch GUILE errors?
213
214         * add new glyphs to font.ly
215
216         * formatting of input stuff. 
217
218         * \notes{ a \< b \cr } vs \notes{ a \< b \! }
219
220         * if possible, it might be nice for a warning to appear if someone does
221         \translator with no name and without assigning it to an
222         identifier.  
223
224         * space after bars?
225
226         * 'hinterfleisch' before bar (e.g. wtk1-fugue2)?
227
228         * \type Voice \times 2/3 { [c8 c16 c16 c16 c16] }
229
230         * fix singleStaffBracket
231
232         * repeat bars: need distance after ":|" and before "|:"
233
234         Summary of minor spelling irregularities:
235         -  capitalization/use of underscores in property names
236
237         * fix SkipBars  -> skipBars
238
239         * \shape 1st dim skipped? 
240
241         * fix marks/barnumbers/marginal notes
242
243         * broken scripts:
244         lbheel = \script { "bheel" 0 0 -1  0 0 }
245         rbheel = \script { "bheel" 0 0 1 0 0 }
246         lbtoe = \script { "btoe" 0 0 -1 0 0 }
247         rbtoe = \script { "btoe" 0 0 1 0 0 }
248         lfheel = \script { "fheel" 0 0 -1  0 0 }
249         rfheel = \script { "fheel" 0 0 1 0 0 }
250         lftoe = \script { "ftoe" 0 0 -1 0 0 }
251         rftoe = \script { "ftoe" 0 0 1 0 0 }
252         
253         and also
254         
255         portato= \script { "portato" 0 -1 0 1 0 }
256
257 STUFF
258         * check out legal/(c) matters for scores.
259
260         * check out GCC signatures?
261
262         * Align_element::padding  ?
263
264         * uniformise property names...
265           - ydirection <-> yDirection
266           - rather allow '_' in identifiers first (i.e. junk ^ and _),
267             and do y_direction?
268           - typo checks on property names?
269
270         * use streambufs and iostream
271         to provide IO handling for TeX stream, mudela stream, data-file.
272
273         * seriously buffer TeX output (do profile of writing .5 mb TeX file.)
274
275         * strip EXEs before installing
276
277         * zip target for binary windows dist (JBR)
278
279         * junking \skip req in lyrics
280
281         * Language:
282         - \type -> \context ?
283         - \translator -> ?
284         - fix \partial 
285         - \bla {} vs \bla ; 
286         - mix engraver hacking with music ?
287         - \once\property  KEY = VAL
288         - \addtranslator, \removetranslator
289         - junk ^ and _ for scripts
290         - junk _ for lyrics.
291         - abstract grammar.
292
293         * percussion note heads
294
295         * mi2mu empty staffs.
296
297         * horizontal centering of dynamics 
298
299         * \font\fontA=feta20.afm (.afm?)
300
301         * gzip RH manpage
302
303         * stable make/config stuff
304
305         * $DEPENDENCIES_OUTPUT support
306
307         * Xdvi zooming ?! Try to understand GS garbage collection.
308                 gs: Error: /undefined in draw_beam
309                 gs: Operand stack:
310
311         * fix vertical alignment and stafflines
312
313         * GrandStaff needs more work -- I want a single word
314         `harpsichord' to the left of the grandstaff, not one on each
315         stave.  (Organ staff -- with separate pedal -- but common
316         properties may be something to think about.  Of course for
317         organ you want to be able to give stop indications on the way
318         through, so the \property Voice.Instrument would be a stop,
319         and \property GrandStaff.instrument would be PipeOrgan...)
320
321         * revise the Score_priority_align_engraver concept.  It sucks. 
322
323         * make new VoiceOne, VoiceTwo, VoiceThree contexts with
324 ydirection and hshift preset
325
326         * *.yo: fix pod manpage layout legacy
327
328         * text-items clash with stems/beams
329
330         * --include, -I option for ly2dvi (pass on to lily)
331
332         * fix placement of beam-less abbrev
333
334         * \meter 3/4;
335         <{\voiceone cis4. cis8 cis4 | cis4 cis cis | r1 }
336          {\voicetwo cis,4 r r | r2. | r1 }> |
337         }
338
339         * try to use template<Type> iso MACRO(Type)
340
341         - NEWS: ... Musical_pitch (analogous to Duration and Rhythmic_req)
342           think about, analogous to pitch: 
343            * { a4 a16 } c <-- duration of c?
344            * < a4 b8 > c <-- duration of c?
345
346         * \tempo 4. = 90;
347
348         * fix audio-items (don't use (input) requests, but copy data)
349
350         * make sure all ex's have a mudela-version
351
352         * do rest-collisions for Multi_measure_rests as well.
353
354         * split error/warning in error/warning/non_fatal_error
355
356         * add a Duration_convert member to Duration_iter to set parameters.
357         Junk global duration settings. 
358
359         * minimum length second part broken tie
360  
361         * en-,discouraged linebreaking: 
362           - handle DISALLOW < penalty > FORCE
363           - discourage breaking of slurs
364
365         * fix variable define/lookup parser global<->paper
366
367         * fix title/instrument placements; see input/test/title.ly
368
369         * <\voiceone c4. \voicetwo c4>
370
371         * add full cello suites to web site (kom op, Maarten!)
372
373         * Rethink Time_description
374           * \cadenza , \meter, \grouping should all be \properties
375
376         * rename
377           - measure -> bar
378           - abbrev -> tremolo
379           - abbreviation-beam -> (measured/unmeasured) tremolo
380           - partial -> anacrouse
381
382         * shared lib
383
384         * robustify Beam (in case of no stems, 32nd notes)
385
386         * decentralised spring factory
387
388         * move paper vars into engraver properties
389
390         * check for groff / troff/ nroff et
391
392         * more intelligent file searching
393
394         * make LilyPond RPM fully relocatable
395
396         * disable spaces in TeX stuff
397         
398         * handle ^C for tmp/file creation.
399
400         * dots & rest collisions.
401
402         * documentation
403         - introduction?
404         - info?
405         - LaTeX?
406         - more manpages?
407
408         * versioning for Feta
409
410         * the warning about the negative slur/tie length appears twice
411         which is irritating.
412
413         * The `3' in the meter key is a one or two pixels too thin (at 600dpi)
414         in the middle:
415
416         * the bracket is ugly (wings are too parabolic, should be more circular)
417
418         * better hshift (dots, distance, head dependent)
419
420         * clefs (AG): The "8" should appear closer to the actual clef,
421           touching it.
422
423         * put errorlevel in Input class
424
425         * junk nesting slurs
426
427         * integrate midi-elts from mi2mu and lily?
428
429
430 3RD PARTY BUGS:
431 ****************
432 /*
433 ICE
434 */
435 signature S {
436   int foo ();
437 };
438
439 signature V {
440   S * s();
441 };
442
443
444 V*v();
445 f ()
446 {
447   return v( )->foo ();
448 }
449
450 /*
451
452   egcs-1.1
453
454 foo.cc: In function `int f()':
455 foo.cc:6: label `b' used but not defined
456 */
457 void
458 f ()
459 {
460   bool b;
461   if (b && && b)
462          ;      
463 }
464 ***************
465
466         * make GCC warn about ctor that leaves member vars  uninitialised.
467
468         * GNU diff 2.7: diff -rN does not see a new directory with empty file
469
470         * glibc 2.0:
471
472           f = fopen ("/dev/null", "r")
473           assert (feof (f))
474
475 3RD PARTY PROJECTS:
476
477         * GNU patch 
478           - 'double-fix' mode: ignore identical fix, rather than suggest 
479             to revert patch direction when (more or less? exactly) the same 
480             thing is fixed
481
482 PROJECTS
483
484         * Scripts:
485         - fix position of bar number
486         - stack scripts in chords:
487           % fingering:        footing:
488             < a-4 c-2 g-1 >   < c-\ltoe e-\lheel >
489         - script-spacing
490         - slur parts as a script
491         - stack parameterised scripts for fingering and footing:
492
493         * convert-mudela:
494         - automatically add  a \version if not present.
495         - better parsing
496         - make smarter
497         - convert-mudela -e empty.ly
498
499         * emacs mudela-mode
500         -  should handle block comments too.
501         -  handle lexer modes (\header, \melodic, \lyric) etc.
502         -  indentation
503         -  notenames?
504         -  fontlock: \melodic \melodic
505
506         * use properties for:
507         - plet?
508         - Staff_sym size
509         - default tempo.
510         - font size
511         - bartypes (get rid of derived Span_bar_engravers)
512         - cadenza mode? 
513
514         * page handling:
515         - PS output
516         - optimal pagebreaking.
517
518         * Unicode support? -> man 7 unicode
519         - 16 bit Strings
520         - -u switch
521         - detect of 16/8 bit files
522         - examples to go with it.
523
524         * Spring_spacer:
525         - write a faster Spring_spacer (without matrices if possible)
526         - relate energybound to linelen unitspace fontsize etc.
527         - used fixed point fp?
528
529         * \header
530         - output header info to MIDI too.
531
532         * a musical dictionary. See Documentation/vocabulary-*, other
533         languages:
534         - explanations
535         - italian
536         - german
537         - dutch
538         - swedish
539          .. ?
540
541         * chords
542         - guitar chords (fret diagrams)
543         - other chord name styles (american(?) style)
544         - basso continuo
545         - MIDI output?
546
547         * Debug logs:
548         - derive lily_stream, Dstream, texstream from ostream?
549         - indentable stream as baseclass for TeX stream, lily stream, Dstream.
550         - use dstream feature in mi2mu
551         - integrate IO checking into stream class
552
553         * input converters
554         - NIFF?
555         - ABC? 
556         - SMDL?
557
558         * add to MIDI output:
559         - tempo change
560         - ornaments (and trills?)
561         - repeat/volta
562         - slurs
563         - accents
564         - dynamics
565         - account for rhythmic position in measure
566         - etc.
567
568         * grace notes
569         - make separate class for Grace_*_engravers 
570         (which is at Voice_gravs level)
571         - make encapsulated spacing problems.
572
573         * accidentals per Voice_group
574
575         * Output class, handles : (smallish)
576         - help text /(c) notice?
577         - version line
578         - warning /errors/progress
579         - abort on error/warning; exit status
580         - quiet/ignore-version options
581         - logfile output
582
583         * elaborate Staff_side baseclass:
584         - scripts
585         - text
586         - slur start/end
587
588         * PS 
589         - speed up PS code.
590         - PS lines to .eps files
591         - write custom prolog
592
593         * Output an output format independent (ofi) typeset file; and 
594           make ofi2 TeX, MusiXTex, Display PostScript, PostScript,
595           Ascii... interpreters. (difficult)
596
597         - NIFF ?
598         - Common Music Notation
599         - PostScript output (esp. Beams, Slurs, etc)
600         - Move all Score_elems, into libmutype.a
601         - SGML
602
603         * Documentation
604         - Doc (C) stuff of sheet music
605         - a better format?  SGML?  TeX?  Info?
606         - a better tutorial
607
608         * more spanners (smallish)
609         - Glissando
610         - trill
611
612         * Rewrite Stem, Beam and Rhythmic_grouping (hairy)
613         - [c8. c32 c32]
614         - doc on Rhythmic_grouping
615         - general shaving on Beam and Stem
616         - use plet grouping
617         - separate visual from rhythmic info even more
618         - beams over bars
619
620         * lines:
621         - Ledger lines, should be separate item: Ledger_lines, Ledger_lines
622         - set different line sizes / thicknesses
623         - beam stem showthrough, inter beam sizes (french vs german style)
624
625         * Collisions
626         - left/right note balls should be handled by Collision:
627         < \multi 2; { \stem 1; <b c> } { <f as b> } >
628
629         * Keys:
630         - merge key{item} & localkey{item}?
631         - spacing, national styles?
632
633         * Support for TAB
634         - redo Notehead to allow digits as heads
635         - add a \tablature {} lexer mode for easy entering
636
637         * should adjust stemlength for flag number.
638
639         * breaking:
640         - caching breakpoints
641         - saving them
642         - specify number of lines
643
644 INPUTLANGUAGE
645
646         * c4 4 4 4 for c4 c4 c4 c4?
647
648         * neatly (and readably) expressing concurrent
649         voices
650
651         * <c f a>4 ?
652
653         * Viola mode?
654
655                 @c c g e g 
656         for
657                 c g es g, 
658
659                 @A c g e g
660         for
661                 cis gis e gis
662
663         * relative mode for pitch entering
664
665         * configure pitch_byte
666
667         * rest name configurable
668
669 SMALLISH PROJECTS
670
671         * limit memory usage; the full coriolan takes up too much resources.
672
673         * fix confusing naming in Engraver vs Engraver_group_engraver (context)
674
675         * progress when creating MIDI elts.
676
677         * A range for context errors (eg. mark both { and }. )
678
679         * lyric in staff  (sharpsharp in staff, text below)
680
681         * half sharps/flats
682
683         * write Dynamic_line (to group dynamics horizontally)
684
685         * use Real for all y positions.
686         - use translate_axis( .. ,Y_AXIS)  iso separate variables.
687
688         * half-sharps, half-flats
689
690         * adaptive accidental spacing.
691
692         * handle EOF graciously in error messages.
693
694         * declare notenametab?
695
696         * midi esp.: use I32 iso int where 32 bits are needed (or assumed...)
697
698         * stafftypes: voice names/ instrument names.
699
700         * lily \tempo
701
702         * C meter iso 4/4, idem for alla breve, etc.
703
704         * textspanner: center position
705
706         *   % toe to bheel   four to five
707             %   ^_u            4_5  
708             %     -                           
709             %  --|x--         --|x--
710             %  --|---         --|---
711             %  --|---         --|---
712           (where "to" is a tiny bow)
713
714         * auxilliary file for caching info.
715
716         * Text_crescendo
717
718         * clean solution for staffsize in items.
719
720         * revise calcideal
721
722 IDEAS
723
724         * Output data structures of Mudela in XML/SGML.
725
726         * create libmudela, or liblily_frontend
727
728         * move MIDI stuff (including Quantization) to a ANSI C libmidi library.
729
730         * Spacing_request for manually adjusting spacing
731
732         * caching breakpoints
733
734         * used fixedpoint arithmetic for min. energy.
735
736         * move towards incremental algorithms.
737
738         * far fetched language ideas
739         - design meta-language like TeX and Metafont
740         - programming/macros input
741
742         * versioning stuff (cvt mudela, mudela, etc.)
743
744         * Klavarskribo?
745
746         * dynamic loading of engravers? 
747
748 SMOBS:
749
750 ****************************************
751 Han-Wen Nienhuys <hanwen@cs.uu.nl> writes:
752
753 > mcmanus@IDT.NET writes:
754 > > > I want different C++ objects (with scheme embedded) to be linked by
755 > > > C++ pointers.  I want to access these other objects from the Scheme
756 > > > code, and I want access to these pointers from C++.
757 > > 
758 > > You can do this with a  combination of smob's and primitive functions,
759 > > though it may not be  be exactly what you wanted.   You would have one
760 > > smob  for each class in  your application, and then  you would write a
761 > > primitive function that would return the objects  that are linked to a
762 > > base object.
763
764 > And the smob and the C++ class are interlinked?  Like
765
766 >       class Foo_class {
767 >               Foo_smob *smob_ptr_;
768 >       }
769
770 >       struct Foo_smob {
771 >               Foo_class *class_ptr_
772 >       }
773
774 Usually you can get away without having this interlinked structure.
775 One piece of information you need when exporting objects to scheme is
776 the smob tag for your class.  You might store this value (a long) into
777 a class static variable, or a file static variable.  I'll use a class
778 static variable in this example.
779
780 I typically use code that works like this (untested code ahead):
781
782 class Foo_class {
783     static long *Foo_smob_tag;
784     SCM obj; // representation as a scheme object, description comes later
785 }
786
787 // call this once on startup
788 void init_Foo_class {
789     static scm_smobfuns type_rec;
790
791     type_rec.mark = foo_mark;
792     type_rec.free = foo_free;
793     type_rec.print = foo_display;
794     type_rec.equalp = 0;
795     Foo_class::Foo_smob_tag = new int(scm_new_smob(type_rec));
796 }
797
798 When you want to export an object to scheme, you put a pointer to the
799 object itself in the cdr of the cell, and the tag in the car of the
800 cell.  The code looks like this:
801
802 // Is this a Foo?
803 static int
804 foo_p(SCM obj)
805 {
806     return(SCM_NIMP(obj) && SCM_CAR(obj) == Foo_class::Foo_smob_tag);
807 }
808
809 // given a Scheme representation, return, a C++ representation
810 static Foo_class *
811 foo_unbox(SCM obj)
812 {
813     return((Foo_class*)SCM_CDR(obj));
814 }
815
816 // the SCM representation of the object is stored inside itself
817 // this will become useful when destructor gets called
818 static SCM
819 foo_box(Foo_class *foo)
820 {
821     SCM_DEFER_INTS;
822     SCM_NEWCELL(foo->obj);
823     SCM_SETCAR(foo->obj, Foo_class::Foo_smob_tag);
824     SCM_SETCDR(foo->obj, (SCM)foo);
825     SCM_ALLOW_INTS;
826     return foo->obj;
827 }
828
829 > C++ determines life time, so what is the strategy?
830
831 What happens now when the destructor gets called?  Lets set the cdr to
832 NULL, and then check for that in all of the primitive functions that
833 use your smob.  We'll call this notion 'live'; a scheme object is
834 'live' if the C++ representation still exists, it's dead if the C++
835 object is gone.  You can still have references to dead objects in
836 scheme code; it's just an error to use them.  This idea is stolen from
837 Emacs's handling of buffers ('buffer-live-p' and friends).
838
839 Add another function, foo_live_p:
840
841 static int
842 foo_live_p(SCM obj)
843 {
844     return(foo_p(obj) && SCM_CDR(obj) != NULL);
845 }
846
847 In you destructor, you need to do:
848
849 ~Foo_class()
850 {
851     SCM_CDR(this->obj, NULL);
852 }
853
854 When writing new primitives, now just check foo_live_p().
855
856 I hope the above helps,
857
858 -russ
859
860
861 --
862 "Even if you are on the right track, you'll get run over 
863 if you just sit there."  
864              --Will Rogers (1879-1935)
865
866 ***************************
867
868 > I am still muddling along with integrating GUILE in LilyPond, and I
869 > have a question.  I want to replace an existing C++ implementation of
870 > identifier tables by GUILE's code.  I've managed to replace
871
872 >       Hash_table<String,Identifier*>
873
874 > by
875
876 >       Hash_table<SCM, Identifier*>
877
878 > and use interning and GUILE symbols for doing the identifier lookup.
879 > But I'd like to use GUILE's hash tables as well, and that's were my
880 > question comes in: is there an interface that allows me to iterate
881 > through the entries of a GUILE hash table?
882
883 I use the following, which should definitely be provided somewhere
884 in guile, but isn't, AFAIK:
885
886 (define (hash-table-for-each fn ht)
887   (do ((i 0 (+ 1 i)))
888       ((= i (vector-length ht)))
889     (do ((alist (vector-ref ht i) (cdr alist)))
890         ((null? alist) #t)
891       (fn (car (car alist)) (cdr (car alist))))))
892
893 (define (hash-table-map fn ht)
894   (do ((i 0 (+ 1 i))
895        (ret-ls '()))
896       ((= i (vector-length ht)) (reverse ret-ls))
897     (do ((alist (vector-ref ht i) (cdr alist)))
898         ((null? alist) #t)
899       (set! ret-ls (cons (fn (car (car alist)) (cdr (car alist))) ret-ls)))))
900
901 If you want a C version, you can run the above code through hobbit, or
902 tranlate it to C by hand.
903
904 -russ
905
906
907 --
908 "Whenever you find yourself on the side of the majority, it is time to
909 pause and reflect."
910              -- Mark Twain
911 ***********************