Skip to main content
GameDev.net gamedev.net
🔒 Locked

Anyone else using Common Lisp in their game?

Started by pTymN Jan 17, 2008 at 12:07 PM 29 replies 37.2k views
Original Post
pTymN
pTymN
My game is using Corman CL 3.0 for all the level layout, game object behaviors, and high level control of the graphical effects. I was interested in starting a discussion with any other developers who have discovered that modern hardware isn't finding a 40mb runtime overhead to be anything bad. It almost seems that the widespread adoption of .net for games in the indy community should make lisp also seem to be a more likely choice. Both have a GC and can generate code at runtime. Both can hot reload code in a running application. I've been delighted with the results in my game for rapid prototyping. About the only pain is having to constantly update my FFI interface for lisp to access more features of the C++ based libraries that I'm using. (Gamebryo, FMOD, FantastiqUI, Chipmunk)
 
Extrarius
Extrarius
Lisp isn't used for three reasons:

First, as far as I'm aware, there are no good IDEs that help make sense of the parenthesis. I'd love to use Lisp if I could find an IDE that made it as easy as other languages, but the huge level of nesting that necessarily occurs makes reading large code very difficult. 100 lines of Lisp code could be one expression or 100, and there isn't any easy way to tell which it is without dissecting the whole thing. Indentation helps, but not enough - it makes small sections of code easily readable, but it can only help so much.

Second, common lisp is a behemoth, and is way, way larger than it needs to be. Not only is it overly large, but it omits a lot of things considered standard these days (such as just about everything the .Net framework does). It's great that every modern implementation provides custom solutions, but that just fractures things worse. You could always import functions from elsewhere, but they won't ever mesh properly with the rest of the code because Windows API (for example) doesn't follow the same philosophy as Lisp.

Third, Lisp is difficult. Well, maybe not difficult, but easy to screw up. Being able to mix object-oriented, procedural, and functional code might be good for flexibility, but it's not so great on maintainability. Throw in that the code can rewrite itself (at your direction, but still...) and it's a scary thing for large projects.
"Walk not the trodden path, for it has borne it's burden." -John, Flying Monk
pTymN
pTymN
Your objections are silly. Perl has a difficult syntax, and it is highly used. .NET is a large runtime overhead, and it is used. C++ allows you to shoot yourself in the foot with a somewhat complex underlying system for virtual methods and vtables and this pointers that can change based on whether the code is in the base class's constructor or parent class's constructor, and people get work done with it.
 
Sneftel
Sneftel
Quote:
Original post by pTymN
Your objections are silly.
Were you actually interested in discussion, or is this thread just advocacy disguised as discussion?
Wan
Wan
As an experiment, I'm currently working on a simple game in Haskell (++ OpenGL/Glut). I have been playing around with Scheme before, but only for quick math related problems, not to create 'real' applications.
Since we're talking FP: I've heard some good things about F#, but I'll stick with Haskell for now.
Extrarius
Extrarius
Quote:
Original post by pTymN
[...]Perl has a difficult syntax, and it is highly used.[...]
That was not one of my objections. Perl is not difficult to visually parse, it is difficult to understand because there are many details. Lisp is very difficult to visually parse, which is something a good IDE could help considerably with. Unfortunately, there are no such IDEs that I am aware of.
Quote:
[...].NET is a large runtime overhead[...]
That was not one of my objections. .Net is large, but every feature in it serves a very specific purpose applicable to modern paradigms. Lisp is large, and half of it is no longer relevant, and the other half is pretty much only computational (meaning it has very limited functionality for communicating with outside world).
Quote:
[...]C++ allows you to shoot yourself in the foot [...], and people get work done with it.
That was not one of my objections, but of the three, it was closest. Plenty of people get work done in C++, but plenty of people also write horrible overcomplicated code that is impossible to read and even more difficult to maintain. All the Lisp code I've found that wasn't explicitly a tutorial was along the same lines, and even that horrible code doesn't even abuse Lisp to it's fullest. Mix in all 3 paradigms, code modifying itself, and DSLs that make a syntax completely change meaning, and you've got something difficult NOT to make horrible code with.
It's one thing to make it work, and quite another to make maintainable code that is pleasant to work on months later. I don't think it is impossible to write decent code in C++ or Lisp, but I haven't ever seen any in a large application.
"Walk not the trodden path, for it has borne it's burden." -John, Flying Monk
Rebooted
Rebooted
Quote:
Original post by Extrarius
First, as far as I'm aware, there are no good IDEs that help make sense of the parenthesis.
Not even SLIME or Lispworks?

Quote:
Being able to mix object-oriented, procedural, and functional code might be good for flexibility, but it's not so great on maintainability.
Why? I would have thought expressive languages lead to reduced code size and easier-to-understand programs that attack the problem more directly.

I'd imagine debugging a program that makes heavy use of procedural macros would be a nightmare though. Scheme's macros, which respect the semantics of programs they are operating on, are much better in this regard. Something I think is essential is an IDE that can tell you through highlighting which identifiers refer to variables and which to macros, though.

The problem with CL in my opinion is a lack of abstraction. No proper module system, macros don't respect bindings, raw symbols are used instead of ADTs, ... This is exactly the problem that typed FP languages like ML and Haskell attack. I don't think it's practical to do extensive higher-order programming or build combinator libraries without an expressive static type system either, and for me this is were much of the power of FP comes from.

I think F#, which is a dialect of ML targeting .NET, ought to be very suited to making a game.
Extrarius
Extrarius
Quote:
Original post by Rebooted
Quote:
Original post by Extrarius
First, as far as I'm aware, there are no good IDEs that help make sense of the parenthesis.
Not even SLIME or Lispworks?[...]
It's been a long time since I've used Lisp, but using google to locate some screenshots of each, I don't see how either is any better than a generic 'programming editor' with respect to making the onslaught of parenthesis more visually distinguishable from eachother. 5 black curves in a row doesn't exactly tell you much about what is going on. At the simplest, I think something like coloring the text's background based on the nesting depth would help tremendously with making code readable. I should be able to look at a block and tell where one expression/statement starts and the next one ends, as it is trivial to do in most language, but in Lisp, since everything is uniform in appearance, it all blends together.

Quote:
[...]
Quote:
Being able to mix object-oriented, procedural, and functional code might be good for flexibility, but it's not so great on maintainability.
Why? I would have thought expressive languages lead to reduced code size and easier-to-understand programs that attack the problem more directly.[...]
Because programmers get messy - few people have enough discipline to stick to ideals forever, and as soon as you start indiscrimintely mixing the many possibilities, it'll be hell to know what is going on. Big code is difficult enough to understand without having to also figure out what type of code it is.

Quote:
[...]The problem with CL in my opinion is a lack of abstraction.[...]
Even basic CL has a package system built in, and it uses : to dig down into them, which makes it fairly clear what is from where. Also, have you ever heard of CLOS or MOP?
"Walk not the trodden path, for it has borne it's burden." -John, Flying Monk
Zahlman
Zahlman
Quote:
Original post by Extrarius
5 black curves in a row doesn't exactly tell you much about what is going on. At the simplest, I think something like coloring the text's background based on the nesting depth would help tremendously with making code readable. I should be able to look at a block and tell where one expression/statement starts and the next one ends, as it is trivial to do in most language, but in Lisp, since everything is uniform in appearance, it all blends together.


In vim (and regardless of the language), moving the cursor next to a bracket will highlight it and its matching open/close.
Rebooted
Rebooted
Quote:
Original post by Extrarius
I should be able to look at a block and tell where one expression/statement starts and the next one ends, as it is trivial to do in most language, but in Lisp, since everything is uniform in appearance, it all blends together.

I also find Lisp syntax harder to read. I guess syntax is completely subjective though, some Lispers seem to love it.

Quote:
At the simplest, I think something like coloring the text's background based on the nesting depth would help tremendously with making code readable.
That sounds like a pretty good idea. I think I've seen something like that for emacs, maybe.

Quote:
Even basic CL has a package system built in

From what I remember/know about the CL package system it seems to just provide crude namespace management. I could be very wrong.

Quote:
Also, have you ever heard of CLOS or MOP?

Yes, but CLOS don't provide much in the way of data abstraction. If you want to represent, say, a colour in Lisp, you'll probably use a symbol. In ML/Haskell you'd almost certainly define a new type, building layers of abstraction and making program development more tractable.

A better example: if you were building a web app in Lisp, you'd represent HTML elements as symbols. In Haskell, you'd work at a higher level of abstraction, constructing and composing HTML documents as values of an algebraic data type with an interface that matches the DTD. As a result, you get a static guarantee that all constructed documents are well-formed and valid with respect to the DTD. Other things you could express include the invariant that GET requests don't modify the database.
Crazyfool
Crazyfool
I dont use LISP or similar blends of functional programming mostly because how difficult it is for me to grasp whats going on. Perhaps its because of my first couple languages I've dabbled in, or perhaps the way I'm genetically built, or whatever, it is just a very difficult thing for me.

I have been spoon-fed the basics of a few blends of the LISP family and I had to work 10x as hard to pass the project.

I think LISP in principle is awesome - so long as you can grasp it easily/quickly.
capn_midnight
capn_midnight
My thoughts are: I've got along fine thusfar without Lisp, what should compell me to try it *now*? I started using C++ because of C's lack of features, I started using Java because of C++'s irresponsible design, and I started using C# because of Java's bloat. What does Lisp get me from the deal, how quickly does it get it for me, and why wouldn't I just interop with F# instead?
Extrarius
Extrarius
Quote:
Original post by Zahlman
[...]In vim (and regardless of the language), moving the cursor next to a bracket will highlight it and its matching open/close.
Every programming editor I've ever used does something similar, and it helps a lot for C++ or PHP or other such languages.
Unfortunately, when staring at a screenful of Lisp code, knowing what a single parenthesis matches doesn't help. I need to be able to take it all in at once and just know from the appearance what the structure of the code is. In C++, for example, it's trivial to visually identify nested 'if' statements. In Lisp, using any of the many traditional conventions, it'd be a complete pain and entirely not intuitive based solely on the layout of the text.
Quote:
Original post by capn_midnight
My thoughts are: I've got along fine thusfar without Lisp, what should compell me to try it *now*? I started using C++ because of C's lack of features, I started using Java because of C++'s irresponsible design, and I started using C# because of Java's bloat. What does Lisp get me from the deal, how quickly does it get it for me, and why wouldn't I just interop with F# instead?
Lisp brings enlightenment.

At the very least, if you've never read the original Lisp paper, you should do so: RECURSIVE FUNCTIONS OF SYMBOLIC EXPRESSIONS AND THEIR COMPUTATION BY MACHINE

In my opinion, Lisp is amazingly elegant from a computer science point of view, but if your main concern is software development, it's only worth admiring from afar, much like lambda calculus or combinatory logic.
"Walk not the trodden path, for it has borne it's burden." -John, Flying Monk
capn_midnight
capn_midnight
Quote:
Original post by Extrarius
Lisp brings enlightenment.

You might as well have said "Lisp brings chips to the party;" it would be equally meaningless to me. Lisp has had the last 50 years to "take the world by storm" and I've yet to see a definitive argument for why. Saying, "you have to experience it" isn't enough. Be articulate enough to describe what you mean without resorting to hand-waivery. "I use C# over Java because the .NET class library is cleaner than Java's class library" is a reason to use C# over Java. "I use C# over Java because C# makes me feel like I'm on mushrooms" is NOT a reason to use C# over Java. I understand how to write recursive functions, I understand their importance, I understand all of that. What does Lisp bring to the table that I can't get elsewhere? Hell, even &#106avascript gives me functional programming these days. Dispense with the flowery language, please.<br><br>It's probably this very attitude, this exclusive "if you haven't experienced it, you wouldn't know anyway" mindset, that turns so many people off of Lisp. We might all be interested in how Lisp can help us, but damn, it's like pulling teeth getting any answers about it.
Ravuya
Ravuya
I fiddled with mzScheme for awhile as a scripting solution, but I was really looking for something that supported Haskell-style pattern matching. Vaguely considering seeing if you can move ML into scripting, but I'll be moving over to .NET pretty soon so I'll just use good ol' F#.

Pretty much any functional language should be capable of giving you a similar "enlightenment" to Lisp (code as data, metaprogramming into the language, Lambda expressions, etc).

Lisp made a lot more sense to me after I took a few compiler classes and realized that you're actually just writing a syntax tree.

I think Haskell and ML/OCaml/F# are probably much better for actual project development, though. I might be a bit biased by the several thousand lines of highly readable Haskell code I've done in my academic projects. F# is great, but the syntactic sugar for procedural constructs (such as while) requires you to know a bit about functional programming in order to understand its odd initial behaviour.
Spoonbender
Spoonbender
Quote:
Original post by capn_midnight
Quote:
Original post by Extrarius
Lisp brings enlightenment.

You might as well have said "Lisp brings chips to the party;" it would be equally meaningless to me. Lisp has had the last 50 years to "take the world by storm" and I've yet to see a definitive argument for why.

Learning a new programming paradigm?
I'd say learning new ways to think about and solve programming problems is always a good thing for a programmer.

I'd turn it around and say 'is there any reason not to learn Lisp? Or Ruby? Or &#106avascript? Or any other language you can think of'. By default, it's always a good thing to learn a new language (especially if it's radically different from the ones you're used to)<br/><br/>Of course there might be practical reasons (time constraints) for not learning a language, but you shouldn't need a reason to learn a language. For <i>not</i> learning a language, sure.<br/><br/>So what's your reason for <i>not</i> learning Lisp? [grin]<br/><br/>As for actually using Lisp, I agree with Ravuya, I'd prefer to use other functional languages in actual projects. Lisp is fascinating because you're manipulating the syntax tree directly, but it wouldn't be my preferred language to use in a game (or any other project)<br/>But that's just me.
capn_midnight
capn_midnight
No, see, you're still doing the hand waivery thing. You have yet to mention anything unique to Lisp that makes learning Lisp a constructive use of time. Sure, the proliferation of functional programming concepts may be due to some pioneering that Lisp did, but we don't learn ALGOL over C these days.

As it stands, I already do a *lot* of functional programming in &#106avascript. It's pretty much the only way to avoid breaking someone else's code when working on a large project with multiple people. I do *some* functional programming in C# 3.0 whenever I use Language Integrated Query, and the opportunity is there to use it in plenty of other instances. Ruby, Pythong, C#, &#106avascript, I could go &#111;n, all have functional programming built into them, without having the durned-all goofy syntax that Lisp has. Yes, yes, yes, you're manipulating the parse tree. A) Still not convinced that's even a good idea, and B) doing that doesn't require the syntax to suck so hard. Given that a good portion of software development tasks are procedural by their very nature (e.g. I/O), it probably makes more sense to make functional programming the exception rather than the rule in a programming language, just as all these other languages have done.<br><br>Like Extrarius said, give me something to break the code up some, so I can see what's going &#111;n.
AndyGeers
AndyGeers
Quote:
Original post by capn_midnight
No, see, you're still doing the hand waivery thing. You have yet to mention anything unique to Lisp that makes learning Lisp a constructive use of time. Sure, the proliferation of functional programming concepts may be due to some pioneering that Lisp did, but we don't learn ALGOL over C these days.


If you want some well articulated arguments for using Lisp, Paul Graham's essays are a great place to start

pTymN
pTymN
Interesting diversions aside, the original point of this thread was to ask people who are using Common Lisp and other functional languages to come forward and discuss what they've found when using those languages for games.
 
Extrarius
Extrarius
Quote:
Original post by capn_midnight
Quote:
Original post by Extrarius
Lisp brings enlightenment.

You might as well have said "Lisp brings chips to the party;" it would be equally meaningless to me. Lisp has had the last 50 years to "take the world by storm" and I've yet to see a definitive argument for why. Saying, "you have to experience it" isn't enough.[...]
In the last sentence in my previous post, I specifically said that Lisp isn't for software development, which kind of nullifies the rest of your post. It doesn't have a huge class library of relevant utilities, most of its functions are cryptically named (despite allowing more symbols in names than most languages and never having name length limits - they were cryptic from the start), it doesn't have basic features like threading or interprocess communication, it supports referencing external functions but won't mesh well with them due to its different paradigm, etc.

If you're not interested in things like Gödel's theorems, or Escher's paintings, or Bach's symphonies, you can happily ignore Lisp along with other beautiful things. If you enjoy beauty, it's worth learning (note that I didn't say using) because it is beautiful. It defines an amazingly elegant language that has features that modern languages just picked up in the last few years.

If you want me to play art critic: The idea behind Lisp's elegance is that "Everything is the Same". It reaches a level of uniformity that no other readable language I've seen approaches. For example, there are no infix or postfix operators - every operator is a function (or special form, in a few rare cases, but it has the same syntax). The only distinction between code and data is the way you treat it. You can use the extensive list processing functions to manipulate a list into just the right form and then execute it, because "Code Is Data".

Consider that "Lisp" is "List Processing" and that Lisp code is stored in lists. It's simple, elegant, powerful, and excessively flexible. It's an extensible programming language.

Sure, modern languages have reflection, but text processing is messy. Making a C# program that can load a C# source file and optimize all calls to Math::Sine (or whatever C# calls it) that specify a constant is possible, but it'd be a huge undertaking. In Lisp, which has significant list processing features and which stores code as lists, it is not nearly as difficult to do.

Other functional languages might support 'code is data', but without s-expressions that represent code as lists, the transformation between an easily modifiable representation and an executable statement gets messier and becomes more difficult to deal with. When you introduce infix and postfix operators, you have to start doing serious transformation in order to parse a language, but because Lisp only has functions and it parses the code from the tree-in-text representation to tree-in-memory for you (in a way that you can hook and modify, if desired), it's trivial to modify code in its native form.
Quote:
Original post by pTymN
Interesting diversions aside, the original point of this thread was to ask people who are using Common Lisp and other functional languages to come forward and discuss what they've found when using those languages for games.
Sorry to have broken your thread, but as you can tell, Lisp is a hot topic around here. I think Lisp is amazing, but it thwarted my attempts to do serious work in it, and after a lot of meditation on how something so amazing can be not-good, I came to the conclusions I've expressed in this thread.

[Edited by - Extrarius on January 18, 2008 9:16:28 AM]
"Walk not the trodden path, for it has borne it's burden." -John, Flying Monk

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.