[Openmcl-devel] getting CCL ready for CS graphics courses

Alexander Repenning ralex at cs.colorado.edu
Thu Jan 8 09:33:02 PST 2009


I promise some technical questions, mostly aimed at Gary I assume, but  
first a motivational, short rant. Unlike some of the voices on  
comp.lang.lisp I do not think that CL is either doomed or is about to  
take off like crazy by adjusting itself (e.g., its syntax). Education  
is key. Get the CS undergraduates excited about CL somehow and CL  
could actually gain new ground instead of just holding on to its  
legacy developers. But how? Intro to CS courses, e.g., Scheme based on  
Abelson are probably doomed given that even Abelson himself is no  
longer using Lisp at MIT for that course. Instead, I claim, it makes  
more sense to have a compelling package fitting a course such a  
graphics course where students typically follow the OpenGL red book  
and do weekly programming assignments. The point of these courses it  
to learn about graphics and to have a nice tool. Running your event,  
animation loop and change your code on the fly -WOW. Yes, Lisp can do  
this. I have been teaching these kinds of course and I tell you a good  
percentage of  students started to really like to program Lisp because  
of this experience. At the time the MCL license and sales "strategy"  
became a show stopper. CCL could become this kind of tool. If it can  
be delivered in a way that I, as prof, have my students download Mac  
or Windows versions and they can open up OpenGL windows and start  
typing in OpenGL code right away. Then, when the projects become a bit  
more complex CL even delivers good speed in contrast to most scripting  
languages that typically used to make OpenGL programming simple.

Technical challenges:

In general I am not against the MCL/CCL #_<function_name> syntax to  
invoke system calls. For instance, with OpenGL, to make the obligatory  
RGB triangle your code would like this:

(defmethod DRAW ((Self opengl-view))
  (#_glBegin #$GL_TRIANGLES)
    (#_glColor3f 1.0 0.0 0.0)
    (#_glVertex3f 0.0 0.6 0.0)
    (#_glColor3f 0.0 1.0 0.0)
    (#_glVertex3f -0.2 -0.3 0.0)
    (#_glColor3f 0.0 0.0 1.0)
    (#_glVertex3f 0.2 -0.3 0.0)
  (#_glEnd))

but as it turns out most people prefer:

(defmethod DRAW ((Self opengl-view))
  (glBegin GL_TRIANGLES)
    (glColor3f 1.0 0.0 0.0)
    (glVertex3f 0.0 0.6 0.0)
    (glColor3f 0.0 1.0 0.0)
    (glVertex3f -0.2 -0.3 0.0)
    (glColor3f 0.0 0.0 1.0)
    (glVertex3f 0.2 -0.3 0.0)
  (glEnd))

Now one can argue why, at least in the case of OpenGL, this is  
preferable. Here are some reasons:

- the #_ function call mechanism establishes binding at read time via  
a DB. This is good for the program, perhaps, but not good for the  
programmer. Before Lisp reads a correct opengl function call Lisp does  
not have an interned symbol relating to this function name. As a  
consequence symbol completion cannot work. In an API with close to  
1000 functions/constants/  this makes a huge difference.

- the #_ syntax may not be cross platform or cross Lisp

- most OpenGL apps have concentrated OpenGL call where virtually ALL  
the function calls are GL function calls. Ergo you get just about each  
line of line of code containing some #_ which after a while starts to  
look awkward and redundant.

How could we address this? Here are some bad ideas:

1) define a function for each foreign function, e.g.,

(defun  glColor3f (R G B)
  (#_glColor3f R G B))

- not good: function call overhead

2) define a macro for each foreign function, e.g.,

(defmacro glColor3f (R B G)
  <call read-dispatch function via *readtable* to expand into same  
thing as (#_ glColor3f  ...) >

-> (%FF-CALL (%REFERENCE-EXTERNAL-ENTRY-POINT
            (LOAD-TIME-VALUE (EXTERNAL "_glColor3f")))
          :SINGLE-FLOAT R
          :SINGLE-FLOAT G
          :SINGLE-FLOAT B
          :VOID)

- as fast as #_ glColor3f  ...)


The biggest issue with both approaches is that I do not know the name  
of the function and its parameters to create a function or a macro.

In MCL and Allegro we used these LONG lists:

....

(foreign-function glvertex3f (float FLOAT FLOAT) VOID "glVertex3f")
(foreign-function glvertex3i (INT INT INT) VOID "glVertex3i")
(foreign-function glvertex3s (SHORT SHORT SHORT) VOID "glVertex3s")
(foreign-function glvertex4d (DOUBLE DOUBLE DOUBLE DOUBLE) VOID  
"glVertex4d")

...

to create bindings to OS X AGL and Windows WGL

Manually maintaining these kinds of lists is tedious and error prone.

What can we do? Could we have a function to parse the "/System/Library/ 
Frameworks/OpenGL.framework/OpenGL" framework to generate foreign  
interfaces. CCL must have some code to generate access framework  
entries and generate interfaces.


Alex


Prof. Alexander Repenning

University of Colorado
Computer Science Department
Boulder, CO 80309-430

vCard: http://www.cs.colorado.edu/~ralex/AlexanderRepenning.vcf





More information about the Openmcl-devel mailing list