(library 7DRL (import (rnrs))
7DRL
Some friends were discussing the upcoming 7 Day Roguelike contest and I thought it'd be a fun thing to do after completing a browser based game in a month contest just a week back. However, I wanted to use something besides something besides the PHP I've been using for so very long, and somehow in the same IRC channel Scheme came up.
Scheme is a LISP language that I learned back in college and very quickly grew a nice love/hate relationship. I love seeing the beauty of recursion expressed so easily, and I just hate to see so many parenthesis all over the place. Seriously they make your eyes bleed. But the idea hit me that it'd be fun to try to do the roguelike in Scheme, and I decided to enter. I most likely won't finish, and I'm not too happy with the idea I have, but it'll be fun nonetheless.
Flavors
To that end, I've been playing in Scheme for the past week to familiarize myself with a language I haven't touched in a few years and which has had some nice advances since that time. First job was getting it installed on Ubuntu. I'd recommend playing with various flavors and seeing what you like best. I tried Mit-Scheme, Chez Scheme, PLT Scheme (Dr Scheme), Tiny Scheme, and Gambit. These can all be installed under Linux (fairly) easily, and all have upsides and downsides.
- MIT Scheme - I had used this a tad during school, but sadly they're not supporting R6RS, and don't have a full implementation of R5RS, so its essentially useless.
- Chez Scheme - What my school used primarily. Has a copy of the Scheme Programming Language Version 4 free on their site which is a big plus. They support all three major OS's and include an RPM/instructions for Debian installation.
- PLT Scheme - The other product we used at school, it comes as a Scheme IDE with the ability to select from a variety of language subsets. The Ubuntu 9.04 package isn't up to date, but the package available on their site includes R6RS, so grab their install script and forgo synaptic. Big plus of being a fully featured IDE.
- Tinyscheme - From the command line I actually liked this flavor the best. Sadly its a subset of the R5RS standard so it won't do everything you need, but for small proof-of-concept or test code, its nice and fast. I know it'd defeat the purpose, but I wish there was an R6RS version.
- Gambit Scheme - This is a flavor I only came across this past week, had no prior experience with it. I love it. Again the version in the 9.04 Ubuntu repos is a bit old, so grab the newest version (4.6 as of now) here. If you just want to use Gambit as an interpreter/REPL you're good to go. If you want to use it to spit out C code as well, you may need to make sure your gambit.h file is in the right location.
Gambit
Yes, I said spit out C, as Gambit-C compiles your Scheme nicely into C files that gcc will then happily compile for you along with real C to use both languages. This is going to play greatly into my 7DRL as I wanted to use the NCurses library to handle my screen output and to I can easily include that now. An example of Hello World in Gambit Scheme with NCurses:
;;Hello World example for Gambit/NCurses ;;Include our headers (c-declare "#include <ncurses.h>") ;;Define the function (define hello-world ;;C lambda performs c commands, this is a basic ncurses ;;example that inits the screen, prints our string, waits ;;for input so it stays on the screen, and then kills the window (c-lambda () int "initscr(); printw(\"Hello World\"); refresh(); getch(); endwin();" )) ;;Gotta remember to call it! (hello-world)
Now link, compile, and run it:
snarky@Reaper$ gsc -link ncurses.scm snarky@Reaper$ gcc ncurses_.c ncurses.c -lgambc -lncurses -o ncurses snarky@Reaper$ ./ncurses Hello World
(Of course, the above output is slightly tweaked as I'm opting not to take a screenshot of a terminal empty save for one string)
It should be noted that once you start including C in your scheme you can no longer use the Gambit Scheme Interpreter to test your code, so I'd recommend breaking those bits out into other files if possible.
There are some other great additions within the Gambit system, such as the ability to have optional arguments in your functions, keyed variables passed to functions, and some random extensions like vector-copy, as well as, obviously, in-lining C in your Scheme. I highly recommend checking our their manual if you're at all interested.
Gotchas
I did get bit by a few things in Gambit, that I feel I should clarify. Even after reading through the manual, I missed that the compiler is spitting out linked files, not actual executables. To make sure you're getting an executable out of it make sure you do something akin to:
snarky@Reaper$ gsc -link file.scm snarky@Reaper$ gcc file_.c file.c -lgambc
I very quickly just made a make file to handle it to simply forget about what steps go into it.
The big thing that bit me, however, was when I got out of the nice usual functions and into some higher syntax, specifically define-syntax. Gambit has a bunch of functionality turned off by default and requires that you turn it all on to use it. However I didn't feel like the documentation beat that into my head enough, so here's what you have to do:
For the interpreter:
snarky@Reaper$ gsi -:s
And for the compiler:
snarky@Reaper$ gsc -:s -link file.scm OR snarky@Reaper$ gsc -link -e '(load "/usr/local/Gambit-C/lib/syntax-case.scm")' file.scm
The top example turns a whole bunch of syntactic sugar on, while the bottom I believe just turns on some of the syntax. I could be wrong there.
I'm quite looking forward to playing with Gambit more and getting to know Scheme as I used to. Hopefully someone else can find a new sadistic language out of this post.
February 23rd, 2010 at 11:50 pm
[...] My last post was about getting started picking up Scheme again for use in the 7 Day Roguelike contest. Of note I mentioned that I had decided on using Gambit as I could nicely tie Scheme and C libraries together, which I wanted so that I could use ncurses to do all my terminal control (output and reading user input). [...]