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

newbie question

2 views
Skip to first unread message

James

unread,
Jan 1, 2009, 12:45:57 PM1/1/09
to
I've banged my head against the wall on this for the past couple of
days, and haven't been able to figure it out. I know it's a newb
question, but hey - I'm a newb. I'm working with hunchentoot and cl-
who, working on a modified, webified version of the PCL cd library -
pushing message posts onto a list instead of cds. My problem comes
from a misunderstanding or a failure to understand macros in some way
(I think). When I try to run the following code, hunchentoot throws
back a 500 error.

(defun display-message ()
(cl-who:with-html-output-to-string (*+html-stream+*)
(:html
(:head (:title "Show a single message"))
(:body
(:div
(let ((msgid (hunchentoot:get-parameter "message")))
(cl-who:fmt "Slot value of 'subject: ~A" (slot-value (car (select
(where :message-id msgid))) 'subject))))))))


If I replace the last msgid with a number, it works fine. I know it's
something I'm missing with macros, but I can't figure it out on my -
any pointers?

Tamas K Papp

unread,
Jan 1, 2009, 12:53:50 PM1/1/09
to

I know little about the context of this, but I would first check that
msgid inside that let is what you want it to be, eg insert

(format t "msgid: ~a~%")

etc.

Tamas

James

unread,
Jan 1, 2009, 1:56:19 PM1/1/09
to
If I replace msgid inside the 'where' call with a number (not a
variable), the output is correct.If I do the following, the output is
correct:

(defun display-message ()
(cl-who:with-html-output-to-string (*+html-stream+*)
(:html
(:head (:title "Show a single message"))
(:body
(:div
(let ((msgid (hunchentoot:get-parameter "message")))

(cl-who:fmt "Message requested: ~A" msgid)))))))
;; (cl-who:fmt "Slot value of 'subject: ~A" (slot-value (car (select
(where :message-id msgid))) 'subject))))))))


Volkan YAZICI

unread,
Jan 1, 2009, 3:11:23 PM1/1/09
to
On Jan 1, 7:45 pm, James <human.ge...@gmail.com> wrote:
> (defun display-message ()
> (cl-who:with-html-output-to-string (*+html-stream+*)
> (:html
> (:head (:title "Show a single message"))
> (:body
> (:div
> (let ((msgid (hunchentoot:get-parameter "message")))
> (cl-who:fmt "Slot value of 'subject: ~A" (slot-value (car (select
> (where :message-id msgid))) 'subject))))))))

If you'd check TREE-TO-COMMANDS in who.lisp, it writes that:

;; (FMT form*) --> (FORMAT STREAM
form*)
(list* 'format stream (rest x)))))

Namely, there is nothing magical about FMT directive of CL-WHO. For
debugging, you can try partially expanding CL-WHO macros step by step.
(For this purpose, C-c C-m and C-c M-m keys can help you in SLIME.)


Regards.

Pascal J. Bourguignon

unread,
Jan 1, 2009, 3:11:41 PM1/1/09
to
James <human...@gmail.com> writes:

> If I replace msgid inside the 'where' call with a number (not a
> variable), the output is correct.If I do the following, the output is
> correct:
>
> (defun display-message ()
> (cl-who:with-html-output-to-string (*+html-stream+*)
> (:html
> (:head (:title "Show a single message"))
> (:body
> (:div
> (let ((msgid (hunchentoot:get-parameter "message")))
> (cl-who:fmt "Message requested: ~A" msgid)))))))
> ;; (cl-who:fmt "Slot value of 'subject: ~A" (slot-value (car (select (where :message-id msgid))) 'subject))))))))

Therefore problem is not with cl-who but with the (select (where ...))
form. I don't know what they are. Are you sure you can give a variable
to WHERE? What do you get if you type at the REPL something like:

(let ((msgid "some-id"))
(select (where :message-id msgid)))

?


--
__Pascal Bourguignon__

Don Geddis

unread,
Jan 1, 2009, 3:45:37 PM1/1/09
to
James <human...@gmail.com> wrote on Thu, 1 Jan 2009 :
> If I replace msgid inside the 'where' call with a number (not a
> variable), the output is correct.If I do the following, the output is
> correct:
> (let ((msgid (hunchentoot:get-parameter "message")))

Are you sure that get-parameter returns a number?

> (cl-who:fmt "Message requested: ~A" msgid)))))))

Try "~S" instead of "~A" in the format.

> ;; (cl-who:fmt "Slot value of 'subject: ~A" (slot-value (car (select
> (where :message-id msgid))) 'subject))))))))

Also start backing up to the next level. Print out the result of
(where :message-id msgid)
instead of just msgid itself.

-- Don
_______________________________________________________________________________
Don Geddis http://don.geddis.org/ d...@geddis.org
All brontosauruses are thin at one end, much MUCH thicker in the middle,
and then thin again at the far end.
-- New dinosaur theory by "Miss Anne Elk" (Monty Python)

Kenneth Tilton

unread,
Jan 1, 2009, 6:19:31 PM1/1/09
to
Tamas K Papp wrote:
> On Thu, 01 Jan 2009 09:45:57 -0800, James wrote:
>
>> I've banged my head against the wall on this for the past couple of
>> days, and haven't been able to figure it out. I know it's a newb
>> question, but hey - I'm a newb. I'm working with hunchentoot and cl-
>> who, working on a modified, webified version of the PCL cd library -
>> pushing message posts onto a list instead of cds. My problem comes from
>> a misunderstanding or a failure to understand macros in some way (I
>> think). When I try to run the following code, hunchentoot throws back a
>> 500 error.
>>
>> (defun display-message ()
>> (cl-who:with-html-output-to-string (*+html-stream+*)
>> (:html
>> (:head (:title "Show a single message")) (:body
>> (:div
>> (let ((msgid (hunchentoot:get-parameter "message")))
>> (cl-who:fmt "Slot value of 'subject: ~A" (slot-value (car (select
>> (where :message-id msgid))) 'subject))))))))
>>
>>
>> If I replace the last msgid with a number, it works fine. I know it's
>> something I'm missing with macros, but I can't figure it out on my - any
>> pointers?

OP: Apparently uou know more than Tamas.

>
> I know little about the context of this, but I would first check that
> msgid inside that let is what you want it to be, eg insert
>
> (format t "msgid: ~a~%")

TP: For the love of god, man, can you read?* He substituted the literal
value and got what he wanted and cleverly grokked it was a macrology issue.

From PCL: the definition of where:

(defmacro where (&rest clauses)
`#'(lambda (cd) (and ,@(make-comparisons-list clauses))))

OP: I want you to eat for the rest of your life, so please hack up where
and make-comparison-lists to print out the value of their inputs, and
then /compile/ (not run) display-message.

You can also just:(macroexpand '(where :msgid hi-mom)) I changed to
'hi-mom to reduce distractions.

Now meditate on your navel.

The issue is, with any given macro, when are the input forms evaluated?
If an input form is not evaluated at run-time (ie, if the form itself
gets processed at compile-time) you are doomed trying to use anything
other than a literal value (whose form, ny def, evaluates to itself).

"doomed", btw, means you are looking for some other tool that /does/
evaluate its input, possibly called select-query (I made that up). Then
you would do:

(select-query '(where :msgid 42)

...which is silly because 42 already works with select, or:

(select-query `(where :msgid ,hi-mom))

Left as an exercise: where-query, so you can (let's abrreviate, k?):

(select (whereq :msgid hi-mom))

hth, kzo

Tamas K Papp

unread,
Jan 1, 2009, 6:38:19 PM1/1/09
to
On Thu, 01 Jan 2009 18:19:31 -0500, Kenneth Tilton wrote:

> Tamas K Papp wrote:
>> I know little about the context of this, but I would first check that
>> msgid inside that let is what you want it to be, eg insert
>>
>> (format t "msgid: ~a~%")
>
> TP: For the love of god, man, can you read?* He substituted the literal
> value and got what he wanted and cleverly grokked it was a macrology
> issue.

The OP didn't post the macro, and it is surely not standard. A macro
can behave differently depending on whether it is passed literal
values or symbols (though that is not something I would usually design
when writing simple macros, but I don't know the example in question).

Generally people can get better help if they post all relevant code.
You did look it up instead of the OP, which is nice of you, but can't
be generally expected.

Tamas

Kenneth Tilton

unread,
Jan 1, 2009, 6:56:11 PM1/1/09
to

Oops, here and in the next bit (now deleted) I forgot that the issue
turned out to be with "where", not select, select being a normal
function. ie, Yeah, I am just typing over the keyboard.

Rather than try to salvage this mess, let's just leave it at your goal
being (and let's drive home the point):

(select (where-query :msg-id
(hunchentoot:get-parameter "message")))

..and then something like:

(let ((id (hunchentoot:get-parameter "message")))
(select (whereq :msgid id)))

...where the /function/ where-query is a modification of PCL's 'where'
macro and 'whereq let's you buy back the syntactic brevity. That sould
get interesting if one wants to limit evaluation to the value form and
not the key, by which I mean this would /not/ work:

(let ((key :msgid)
(id (hunchentoot:get-parameter "message")))
(select (whereq key id))

still just typing at keyboard,k

James

unread,
Jan 1, 2009, 8:44:14 PM1/1/09
to
Here's the original function, and the defuns for the select & where
(they are not macros). I'm thinking that it has something to do with
the cl-who:w-h-o-t-s macro, and the way it's interacting with the two
defun's and lambda:


(defun where (&key topic subject message-id parentid)
#'(lambda (msg)
(and
(if topic (equal (slot-value msg 'topic) topic ) t)
(if subject (equal (slot-value msg 'subject) subject) t)
(if message-id (equal (slot-value msg 'message-id) message-id)
t)
(if parentid (equal (slot-value msg 'parent-message-id)
parentid) t))))

(defun select (selector-fn)
(remove-if-not selector-fn *message-list*))

Kenneth Tilton

unread,
Jan 2, 2009, 12:08:50 AM1/2/09
to
James wrote:
> Here's the original function, and the defuns for the select & where
> (they are not macros).

F*ck, now I owe Tamas an apology! 2009 is off to a great start.

> I'm thinking that it has something to do with
> the cl-who:w-h-o-t-s macro, and the way it's interacting with the two
> defun's and lambda:
>
>
> (defun where (&key topic subject message-id parentid)
> #'(lambda (msg)
> (and
> (if topic (equal (slot-value msg 'topic) topic ) t)
> (if subject (equal (slot-value msg 'subject) subject) t)
> (if message-id (equal (slot-value msg 'message-id) message-id)
> t)
> (if parentid (equal (slot-value msg 'parent-message-id)
> parentid) t))))
>
> (defun select (selector-fn)
> (remove-if-not selector-fn *message-list*))
>
>
> (defun display-message ()
> (cl-who:with-html-output-to-string (*+html-stream+*)
> (:html
> (:head (:title "Show a single message")) (:body
> (:div
> (let ((msgid (hunchentoot:get-parameter "message")))

Right here ^^^ might be your problem. cl-who does its own form of macro
expansion and IIUC has no case to handle "Let". ie, it has things like
:head and :div and even fmt, so you have to lead with those. But once it
gets to (fmt this that the other thing) it just bungs in everything
after the fmt into a format statement, so you can do your let statement
just in time (and be grateful Lisp subsumes the functionale).

See below for a quickly edited untested possibility.

> (cl-who:fmt "Slot value of 'subject: ~A" (slot-value (car
> (select
> (where :message-id msgid))) 'subject))))))))

(defun display-message ()
(cl-who:with-html-output-to-string (*+html-stream+*)
(:html
(:head (:title "Show a single message"))
(:body
(:div

(cl-who:fmt "Slot value of 'subject: ~A"
(let ((msgid (hunchentoot:get-parameter "message")))
(slot-value (car
(select
(where :message-id msgid))) 'subject))))))))

hth,kt

Lars Rune Nøstdal

unread,
Jan 2, 2009, 7:42:09 AM1/2/09
to

You've probably solved this now, but for later you might try setting
TBNL:*CATCH-ERRORS-P* to NIL so you can debug the problem using the Lisp
debugger with a proper backtrace etc. instead of just getting a "HTTP
500 error" message in the browser.

http://www.weitz.de/hunchentoot/#debug


James

unread,
Jan 2, 2009, 1:58:01 PM1/2/09
to
Lars - Thanks for that - I now see that I'm getting the following
error:

(ERROR "~@<There is no applicable method for the generic function
~2I~_~S~\n ~I~_when called with arguments ~2I~_~S.~:>")
[:EXTERNAL]


Now I just have to figure out WHY I'm getting the error...

Lars Rune Nøstdal

unread,
Jan 2, 2009, 5:39:03 PM1/2/09
to
On Fri, 2009-01-02 at 10:58 -0800, James wrote:
> Lars - Thanks for that - I now see that I'm getting the following
> error:
>
> (ERROR "~@<There is no applicable method for the generic function
> ~2I~_~S~\n ~I~_when called with arguments ~2I~_~S.~:>")
> [:EXTERNAL]
>
>
> Now I just have to figure out WHY I'm getting the error...
>


Hmm, that's a pretty obscure error message. Something tells me you
haven't pasted the actual message itself here. You are looking at the
code or function call (some point in the stack/back-trace) which
_generates_ the error message.

The message itself should be at the top (in Slime), then the back-trace
should follow below.

James

unread,
Jan 3, 2009, 1:56:44 PM1/3/09
to
The message is: There is no standard applicable message for the
generic function
Message has been deleted

James

unread,
Jan 3, 2009, 2:49:09 PM1/3/09
to
Resolved (and I am an idiot!)!

Lars gave the thread that eventually unraveled the the issue,
Hunchentoot was returning:

"There is no standard applicable message for the generic function"

then it went on to tell me that msgid was nil.

What took so long to penetrate was WHY msgid was nil. After staring
at the Hunchentoot documentation, staring at my code, surfing the web,
banging my head bloody, I eventually realized that get-parameter
returns a string, and select using msgid needed an integer... add
(parse-integer (get-parameter "message")) and all my troubles went
away!

D'OH!

Message has been deleted
0 new messages