I love this. Learning a Lisp has been on my todo list for far too long. Once I saw what this was, I filed it away under "For later," but I stuck around for a bit to see if I could do a challenge first...
Totally got sucked in, and an hour or so later I had finished. Accounting for all those parens was really frustrating at first, but with the help of a good editor I eventually feel like I got into the "Lisp headspace."
I have played around with Haskell a bit. Scheme feels more verbose, but also closer to the metal^H^H^H^H^Hlambda calculus. The feature I missed the most was currying:
>>(define sum (foldr + 0))
[Error: too few arguments to function]
You can get around this somewhat:
; manually implement currying on a per-arity basis
(define curry2 (lambda (f)
(lambda (arg1) (lambda (arg2)
(f arg1 arg2)))
))
(define curry3 (lambda (f)
(lambda (arg1) (lambda (arg2) (lambda (arg3)
(f arg1 arg2 arg3))))
))
; now define a curried foldr:
(define cfoldr (curry3 foldr))
; and finally:
(define sum ((cfoldr +) 0))
The dynamic typing was also a bit foreign for me, so it took a while for me to wrap my head around "megasum." I can vaguely imagine how to implement it in Haskell, but it wouldn't be pretty!
Indeed. The first step to grokking Lisp, from Haskell (or any typed language), is to realize that Lisp's "list" is not equivalent to any single data type you've used before, but it's really a general weakly-structured representation of any and all structured types.
Even this solution is not completely equivalent to Lisp megasum -- it fails to compile on the list `('a)` ;-)
- The Scheme engine that this implements is really small -- about 10k of heap. (This is a Z-code game, and the Z-machine is a 16-bit architecture.) And the garbage collection sucks. So you can't do much with this beyond toy problems.
- You could port it to the Glulx VM (32-bit architecture) without too much trouble, and then you'd have a couple of gigabytes. Feel free. :)
- As an IF author, I never intend players to guess a verb. But I do expect players to be familiar with the common IF verbs -- the stuff on the PDF sheet, basically. This was more true in 1996, when the IF community was tiny and all read the same Usenet group. I wrote this thing for enthusiasts.
- Today, I'd put more emphasis in the help docs on the difference between the two input modes (">" and ">>"). And I'd check if the player typed a line starting with ">" -- display an appropriate explanation of why that's wrong.
- But I'm not going to update this thing, because yes, 1996 was a long time ago.
- The era of the text adventure is dead the way the era of home-brewed beer is dead. Nobody makes it and nobody drinks it, except the people who still do.
- Is it silly to write a text adventure in 2014? I put one up for sale a couple of months ago (hadeanlands.com) and it's doing pretty well. Yes, for actual money. No, it's not a gigantic indie success, but the niche still exists and there are still fans. So that's my past twenty years of work justified.
The only verbs I found on my own were 'help' 'info' 'I' 'exit' and 'quit', which all cause it to do useless or nonsensical things, including 'quit' which apparently caused it to finish the game. Game finished successfully, in one page. I completely don't get why people would want to spend time guessing what 'verbs' a command line interpreter recognizes. It's also very bad because when it does 'recognize' a verb, it doesn't take it as a command for it to do something, but seems to reinterpret it as having some ungrammatical relation to a fictional story.
I know. I saw that link and viewed it. I listed what verbs I figured out on my own (found within the game or guessed) as a comment on what the whole user experience of the game was like. It left me feeling like avoiding Lisp, even after I tried again and--only because of getting tips from the comments here--got into the Lisp interpreter part. It was still a frustrating guessing game with no point.
You are correct, but I don't know that the author is interested in fixing it, since the web page was published so long ago that the author could have since had a child who is now capable of writing something like
http://learnlispthehardway.org/try-lisp/
that is accessible to modern humans.
That seems better. However, the return values were almost too dark to read while there's daylight, and I got only eight commands into it before I found an error. (mod -3 5) returns -3. I don't know if that error is just in this implementation, or in many versions of Common Lisp, but a quick search shows there are versions of Common Lisp where mod is implemented correctly. (In mathematics, -3 = 2 modulo 5, or equivalently (-3 mod 5) = 2. Even Python knows that -3 % 5 == 2, where '%' is Python's modulus operator.)
White Room
This is a comfortably cluttered room. Cluttered with bookshelves, mostly. To one side is a large desk, on which a computer squats regally. A lumpy couch is the only other furniture of note.
Beside the computer is a small glass box.
Resting on the couch, and snoring in a manner which you suspect infringes copyrights owned by several local earthquakes, is a huge genie. Honest.
>eat the genie
(first taking the genie)
I don't suppose the genie would care for that.
>eat the computer
(first taking the computer)
That's hardly portable.
>eat the glass box
(first taking the small glass box)
That's plainly inedible.
>eat all the books
You can't use multiple objects with that verb.
finally somebody pushing me into trying lisp (scheme). Some honest questions to lispers... a) isn't 'eqv?' leaking abstractions? there are other parts of lisp where the explanation of the behavior is: "pointers"?
Lisp is historically less concerned with not exposing implementation details than more modern language traditions. The attitude is: the hacker might need it, throw it in! For example, the ability to compare pointers directly (rather than some expensive traverse-the-whole-datastructure comparison) makes it possible to implement hash-consing, a clever optimization technique.
(It's also no more of an abstraction leak than, say, Python's "is" operator.)
> Lisp is historically less concerned with not exposing implementation details than more modern language traditions.
This is a funny comment, because "refusing to leak abstractions" is the most famous reason for why Lisp never became broadly popular, in one of the most famous stories in all of computing: http://en.wikipedia.org/wiki/Worse_is_better
Worse is better is about much much more than exposing versus not exposing implementation details.
Exposing implementation details is also not quite the same thing as a leaky abstraction (although they can coincide). eqv? can be both, if you regard "cons" as an abstraction of a mathematical pair. OTOH, if you regard cons as allocating a mutable pair object, then it is neither.
Providing a function to trigger garbage collection is exposing an implementation detail, but not leaking abstraction.
It's harder to come up with examples of leaky abstractions that don't in some sense expose implementation details. I'm not sure they exist.
http://ifdb.tads.org/viewgame?id=zj3ie12ewi1mrj1t - you can get it from this link. You'll need a z-machine interpreter to run the game, there are ones written in JavaScript if you are interested in that.
Totally got sucked in, and an hour or so later I had finished. Accounting for all those parens was really frustrating at first, but with the help of a good editor I eventually feel like I got into the "Lisp headspace."
I have played around with Haskell a bit. Scheme feels more verbose, but also closer to the metal^H^H^H^H^Hlambda calculus. The feature I missed the most was currying:
You can get around this somewhat: The dynamic typing was also a bit foreign for me, so it took a while for me to wrap my head around "megasum." I can vaguely imagine how to implement it in Haskell, but it wouldn't be pretty!