Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Naggum's got some good points!

13 views
Skip to first unread message

IBMackey

unread,
Oct 22, 2002, 1:48:45 PM10/22/02
to
I've been away some time. Partially because I needed a break and part
because I'm starting a new business. Anyway, I wanted to set up and
learn something about web pages. I said to myself, "Well I ain't
playing with emacs, that's an eternal quest." Then I thought about
lisp, and said "That's old." So I looked into PHP. Damn nice. It took
about a day to learn. I wrote a neat little addressbook and figured I
could expand. That's when the trouble began.

Debugging was a nightmare. Always centered on a misspelled variable or
failure to close a function. No way to draft first and test
piecemeal.

So I said, maybe I'm looking at this wrong. PHP has "functions." I'll
just set it up like lisp. Don't do it, another weekend wasted. Even
harder to debug because of a "global" and "local" variable
mess.

So, what the other easy language to try. Oh yes, python. I thought
let's try it. Duh, who decided that functions involving time should
not be in the main language? Or that you need a separate library for
OS functions? And what's up with the macros?

Finally, I bit the bullet and said "What about lisp and the web." I
did some googling and noted that there were some special libraries and
wondered whether they were needed. I discovered an old Naggum letter,
wherein he stated that people learning lisp are surprised when they
tackle problems and realize how easy it is. I call it the "Aha"
factor. He also included a filter for getting the form variables from
an html post form. And also included some html form generation code.

Damn, in one letter, he showed just about everything I needed to
understand lisp and cgi and web publishing. In less time, than I
needed with the so-called easy languages, I was able to write a generic
program that generates code for any web-database oriented
application. Without php, without python, without templates, without
cut and paste, without hundreds of libraries all over the place.
Just plain lisp.

Naggum, I just wanted to say thanks. Like a bunch of other lispers, I
got it finally.

i.b.


Erik Naggum

unread,
Oct 22, 2002, 1:48:35 PM10/22/02
to
* IBMackey <ibum...@hotmail.com>

| Naggum, I just wanted to say thanks. Like a bunch of other lispers, I
| got it finally.

Good to hear! Congratulations!

--
Erik Naggum, Oslo, Norway

Act from reason, and failure makes you rethink and study harder.
Act from faith, and failure makes you blame someone and push harder.

Marc Spitzer

unread,
Oct 22, 2002, 1:55:45 PM10/22/02
to
IBMackey <ibum...@hotmail.com> wrote in news:87u1jei...@winny.home:

> Finally, I bit the bullet and said "What about lisp and the web." I
> did some googling and noted that there were some special libraries and
> wondered whether they were needed. I discovered an old Naggum letter,
> wherein he stated that people learning lisp are surprised when they
> tackle problems and realize how easy it is. I call it the "Aha"
> factor. He also included a filter for getting the form variables from
> an html post form. And also included some html form generation code.

Do you have the url for that post?

marc

IBMackey

unread,
Oct 22, 2002, 7:35:10 PM10/22/02
to
Marc Spitzer <mspi...@optonline.net> writes:

It's good stuff. Here's the article
i.b.

------------------

From: Erik Naggum (er...@naggum.net)
Subject: Re: Some more misc. Lisp queries
Newsgroups: comp.lang.lisp
Date: 2001-08-26 16:56:26 PST


* quas...@yahoo.com (Q u a s i)
> The reason I asked so many (perhaps stupid) questions is that people
> here (where I live) call it a vintage language with no future.

Yeah, _for them_. What they mean is that they are not part of Lisp's
future. That is their choice, not Lisp's.

> Also I was also surprised at the minimal quantity of internet resources
> related to Lisp. Being one of the oldest language, maybe I expected a
> little more.

I can easily see how this is disappointing. However, there is at least
one somewhat surprising reason for this: It is so easy to do things in
Common Lisp that people have no personal need to advertise it and make a
public nuisance of themselves. While Archimedes may have made the first
serious connection between nudity and marketing scientific discovery, I
think today's Common Lisp hacker goes "yeah!" and just smiles. In sharp
contrast, today's young punks go "HOLY SHIT! IT WORKS! GUYS! GUYS! IT
WORKS!" and rush off to get another cool domain name. That "yeah!" is
also probably worth a thousand times more money than the other Cool Hack,
which is why it is _not_ marketed -- the reward was right there to begin
with, with no need to attract attention from the crowds just to feel good
about your own work. Remember, Common Lisp people are about 10 years
older than Java people.

As for reimplementing things from scratch, I got so immensely frustrated
with the available "libraries" of web-design crap that an incredibly
incompetent moron had abused unintelligently for a week _not_ serving a
high-profile ultra-high-security project I am now working on that I sat
down and whipped up a new Lisp "scripting language", I added a handler to
Apache and used the support for CLISP "binaries" (.fas files) under Linux
to fire up an interpreter to deal with my pages, and instead of reams of
junk code produced by cut and paste and sloppy editing, I could use real
Lisp _macros_ in my source files, producing XML and Javascript and all
sorts of junk efficienctly, well-tested and _fast_. Designing that new
language took me about three hours, but I have saved at least 40 hours
dealing with the putrid fecal matter that some people actually spend
their days trying to shape into web pages. After working my butt off
long into the night and missing a Saturday party, I had completed more
_real_ work in a 16-hour stretch with a dimunitive Lisp tool like CLISP
than a supposed _professional_ had managed to get done in a whole week.
This pisses me off so much even hundreds of rounds of target practice
does not calm down. What I have done, highly inexperienced at web design
and not knowing one iota of Javascript on Friday morning, probably looks
clunky and is generally bells-and-whistles-free apart from functionality
we need, should have been a walk in the park for a professional web head.
It should have taken him mere hours to cobble up something from his vast
store of libraries and tools and have it ready for us the same day. If I
can fumble my way through huge tomes, copy stuff I do not fully grasp,
bumping into problems I had no idea would cause so many lines of logs in
the poor server, and generally feeling like an incompetent fool myself,
but I can still get it done in two days with Lisp as the underlying tool,
writing most of this from scratch while scratching my head and swearing,
god damn it, those imbecilic _frauds_ who claim to have "libraries" on
their side should be hanged at dawn.

People scream about CGI and how hard it is to prosess those things and
they load 100K+ Perl libraries and write HTML with code that is even more
verbose than HTML to begin with. I shall break the "rule" I laid down
above and tell you what I did. Below is how I make those pesky CGI
variables available to my code. It probably is not 100% correct, but it
works a lot better than the incredibly stupid Perl solutions I have seen,
and Perl is supposedly _good_ at this crap. Retch! Excuse me while I
barf in Larry Wall's general direction. (I use string streams because I
have no particular inclication to reinvent buffers. Those who hate loop
and format probably also hate string streams, but it is not _my_ fault
that their Lisp vendor did not make them fast enough for them back in
1980-whatever when their mind was set about what is Lisp and what is not.)

(defun 3ml-cgi-decode ()
(let ((stream (if (string-equal "get" request-method)
(make-string-input-stream query-string)
*standard-input*))
(symbols ()))
(with-open-stream (output (make-string-output-stream))
(loop for char = (read-char stream nil nil)
do (case char
(#\= (push (intern (string-upcase (get-output-stream-string output)))
symbols))
((nil #\&) (when symbols
(setf (symbol-value (first symbols)) (get-output-stream-string output))))
(#\+ (write-char #\space output))
(#\% (let* ((nib1 (read-char stream nil nil))
(nib2 (read-char stream nil nil))
(code (+ (* 16 (digit-char-p nib1 16))
(digit-char-p nib2 16))))
(write-char (code-char code) output)))
(t (write-char char output)))
while char))
(setf *cgi-variables* symbols)))

You get the symbols that were passed in in the *cgi-variables* list so
you can check for them with find or member, but you can use the symbols
without bothering to check, too, provided you have a restart around them
to get rid of the annoying unbound-variable error. (Tracking this stuff
down took me some time, as I have not needed to build interpreters that
should do this before. It may not be correct. Use with caution.)

(restart-case
(handler-bind ((unbound-variable
(lambda (ignore)
(declare (ignore ignore))
(use-value ""))))
...)
(use-value (&optional value) value))

In the end, my nifty little markup language has stuff like this in it:

<table <border 0><width 375>
<form <name registerform><action register.3ml><method post><onsubmit return validate()>
{:discard ; This {} form does not yield a value to be printed in its place.
(defun make-form (prompt type name &optional width)
(format nil "<tr <td ~@[<width ~A>~] <p <class header> ~A:>>~
<td <input <type ~A><name ~A><value {~A}><size 35>>>>"
width prompt type name name size))}
{(make-form "Given name" "text" "givenname" 120)}
{(make-form "Family name" "text" "familyname")}
{(make-form "E-mail" "text" "email")}
{(make-form "Phone" "text" "phone")}
{(make-form "Organization" "text" "organization")}
{(make-form "Username" "text" "username")}
{(make-form "Password" "password" "password1")}
{(make-form "Password (confirm)" "password" "password2")}
<tr <td <input <type hidden><name invitation><value {invitation}>>>
<td <input <type submit><name register><value Register>>
<input <type reset>>>>>>

I assume that this is immediately understandable apart from the use of
{~A} and {invitation}. Those result in expansions to the CGI variables
with the input field names. I also assume that any wreck who has had to
deal with the expanded HTML from something like this will appreciate its
relative brevity. Once I get more work done in this area, however, it
should like this, but the code that produces HTML/XML is too simple to
deal with it this late this weekend:

{(defun make-form (prompt type name &optional width)
<tr <td {(when width <width {width}>)} <p <class header> {prompt}:>>
<td <input <type {type}><name {name}><value {'{name}}><size 35>>>>)}
<make-form <prompt Organization><type text><name organization>>

There, I have posted both loop code, intricate format constrol strings, a
compact new syntax that saves a lot on typing (ewwww!), shown that I use
javascript (EWWWW!), and I have not even kept the fact that I designed
web pages a secret. No cats were harmed in the production of this code
or these web pages, however.

---------------
END OF ARTICLE

Marc Spitzer

unread,
Oct 22, 2002, 9:21:58 PM10/22/02
to
IBMackey <ibum...@hotmail.com> wrote in news:87d6q2r...@winny.home:

> Marc Spitzer <mspi...@optonline.net> writes:
>
>> Do you have the url for that post?
>>
>> marc
>
> It's good stuff. Here's the article
> i.b.
>

Yes it is, classic Erik.

marc

Abhijit Rao

unread,
Oct 31, 2002, 8:57:27 AM10/31/02
to
On 22 Oct 2002 12:48:45 -0500, IBMackey <ibum...@hotmail.com> wrote:

>[...]


>
>Naggum, I just wanted to say thanks. Like a bunch of other lispers, I
>got it finally.
>
>i.b.
>

O my Gosh!! It is to one of my earlierst posts at c.l.l. I never
understood anything at that time... but was sure impressed to stay on
;)


--
quasi
http://abhijit-rao.tripod.com/digital/lisp.html

"I slept with Faith, and found a corpse in my arms on awaking; I drank and danced all night with Doubt, and found her a virgin in the morning."
~ A. Crowley

0 new messages