Advertisement

Why lisp?

Started by January 31, 2004 10:00 PM
103 comments, last by Vlion 20 years, 11 months ago
Not sure that''s a great example I dont know a lot about SDL, but I see no reason that one could not do the same thing with C macros and have this:


WITHLOCKEDSURFACE( screen,
rl->update(t);
gl->update(t);
bl->update(t);
);

Which is more readable than your example for me. The C macro might be less readable than your macro, I don''t know, as I havent gotten too far into lisp macros yet, and you didn''t show what your macro looked like

A similar C macro could look something like this:
(havent tested this actual code, so i might have done it wrong, but i know the macro could be done correctly if i spent a few minutes on it)

#define WITHLOCKEDSURFACE( screen, commands ) \if (SDL_MUSTLOCK(screen)) \{  \   if (-1 == SDL_LockSurface(screen))  \   {    \      printf("Can''t lock hardware surface\n"); \      exit(1); \   } \} \commands;\if (SDL_MUSTLOCK(screen))\{  \   SDL_UnlockSurface(screen);\}


Or one could simply forget about macros and use functions:

Lock( screen );rl->update(t);gl->update(t);bl->update(t);Unlock( screen );


Which is still just as readable as your code, and the only area that makes it more bug prone is that a person could forget to unlock.

Peace
quote:
Original post by Krippy2k
Not sure that''s a great example I dont know a lot about SDL, but I see no reason that one could not do the same thing with C macros and have this:


WITHLOCKEDSURFACE( screen,
rl->update(t);
gl->update(t);
bl->update(t);
);

Which is more readable than your example for me.



I had no idea that C macros could do that

Do you have to pass a variable with the name ''screen'' to the C macro, or can it be any variable name, like ''screen-surface'' ?

quote:
Original post by Krippy2k

Or one could simply forget about macros and use functions:

Lock( screen );
rl->update(t);
gl->update(t);
bl->update(t);
Unlock( screen );
[/source]

Which is still just as readable as your code, and the only area that makes it more bug prone is that a person could forget to unlock.



In SDL, surface locks can be nested, with a 5 locks requiring 5 unlocks. Forcing the coder to manually match lock/unlock calls would be a potential source of bugs. Can the C macro be nested, for example if the call to lock the surface was in a recursive function ?
Advertisement
quote:
Original post by Krippy2k
Not sure that''s a great example I dont know a lot about SDL, but I see no reason that one could not do the same thing with C macros and have this:


WITHLOCKEDSURFACE( screen,
rl->update(t);
gl->update(t);
bl->update(t);
);



OK, Mr. Smarty-pants

Say you wanted to add a new IF conditional, so instead of having to do this:

SDL_Surface* pSurface =   SDL_SetVideoMode ( SCREENWIDTH , SCREENHEIGHT , SCREENBPP , SCREENFLAGS ) ;if (pSurface == null) {   // Videomode failed. Very Bad. Exit program}// Do something with pSurface  


You could do this:

aif (SDL_SetVideoMode ( SCREENWIDTH , SCREENHEIGHT , SCREENBPP , SCREENFLAGS ) != null) {   // Do something with *it*.   } else {     // Videomode failed. Very Bad. Exit program} 


I say // Do something with *it*. Where *it* is created by aif and automatically bound to the return value of SDL_SetVideoMode.
Not sure I understand you correctly, but that looks like something that C++ if statements already give you.

I would do it like this:
if ( SDL_Surface* it = SDL_SetVideoMode( SCREENWIDTH, SCREENHEIGHT, SCREENBPP, SCREENFLAGS ) ){  //*it* is in scope here, we can use it.}else{  //bad video mode}


Which would be a little different from what you state, it requires you to define the type of the return value yourself, but atleast you would be able to see what type of object *it* is at the relevent place.

Edit: Note that the above only works in C++, C requires all variables to be declared at the beginning of a function.

Peace


[edited by - krippy2k on February 24, 2004 3:42:44 PM]
Interesting.
The lisp macro is more readable than the core code, for sure.

C macros are not something particularly cool in general.

I would probably have some kind of locking class that locked in constructor and unlocked in destructor. Not knowing SDL I''m not sure how clean that would be.

~V''lion

Bugle4d
~V'lionBugle4d
quote:
Original post by flangazor
I don''t think this subtopic is going to bear any useful fruit. I think it should end here before it turns into a full-fledged battle of pedantry.

I agree, and I''ll not going to be adding any more to it.
Advertisement
quote:
Original post by Vlion

I still don''t see why lisp is conclusively better than a well-written imperative langauge with a good library behind it.



What makes you think that *any* language is conclusively better than another?

most languages have their good and bad points, and that includes Lisp as well as C++. Which one is better? Depends on your preferences. (And of course, on what you want to do with it)
(Sorry, just had to shoot that in here) :D

---------
Life is like a grapefruit. It''s sort of orangy-yellow and dimpled on the outside, wet and squidgy in the middle. It''s got pips inside, too. Oh, and some people have half a one for breakfast
quote:
Original post by Krippy2k
Not sure I understand you correctly, but that looks like something that C++ if statements already give you.

I would do it like this:
if ( SDL_Surface* it = SDL_SetVideoMode( SCREENWIDTH, SCREENHEIGHT, SCREENBPP, SCREENFLAGS ) ){  //*it* is in scope here, we can use it.}else{  //bad video mode}


Which would be a little different from what you state, it requires you to define the type of the return value yourself, but atleast you would be able to see what type of object *it* is at the relevent place.

Edit: Note that the above only works in C++, C requires all variables to be declared at the beginning of a function.

Peace


[edited by - krippy2k on February 24, 2004 3:42:44 PM]


The example given above was just one instance of a general style of macro programming referred to as anaphora in On Lisp (I don''t know if the term is in more widespread use, that''s the only place I''ve seen the term/feature used). Chapter 14 of On Lisp goes into more detail about how this can be used, although if you don''t have experience with Lisp/macros/functional programming you might have trouble understanding it. That chapter demonstrates for example how you can create unnamed function within whose body the symbol "f" is automatically bound to the function (so you can make unnamed, recursive lambda expressions).

Something I did with macros after a few months of hacking around in Lisp for fun - function currying. I had a macro which could take code declaring an arbitrary function* like this:

(defun f (x y z) (+ x y z))

into a form like this:

(defun f (x) (lambda (y) (lambda (z) (+ x y z))))

Then I wrote another macro which would take an actual call to f:

(f 1 2)

and turn it into:

(funcall (f 1) 2)

Voila, basic function currying. Not present in Lisp, but it''s a feature I like in SML and I hacked it into Lisp with relatively little experience.

* well not completely arbitrary, it doesn''t handle keyword arguments and fancy stuff like that.
quote:
Original post by HairyTroll
quote:
Original post by Krippy2k
Not sure that''s a great example I dont know a lot about SDL, but I see no reason that one could not do the same thing with C macros and have this:


WITHLOCKEDSURFACE( screen,
rl->update(t);
gl->update(t);
bl->update(t);
);

Which is more readable than your example for me.



I had no idea that C macros could do that

The C preprocessor does not provide anything like the abilities of the Lisp macro system. For starters, C macros cannot perform environment capture, which means WITHLOCKEDSURFACE is unlikely to be hygienic. This is really why people wishing to see the benefits of Lisp need to go and do some learning - it''s no good producing syntactic similarities and assuming that the semantics are the same.
The C++ idiom I would have chosen would be:

{
Lock lock(screen);
rl->update();
gl->update();
bl->update();
}//implicit dtor on lock releases lock.

But I agree with SabreMan that trying to think in C++ in order to describe Lisp will only show you the subset of what Lisp you can express in C++. You may like to think of it as the relation between normal speech and ''newspeak'' from 1984 (without the ominous overtones).

This topic is closed to new replies.

Advertisement