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

Confusion over closure

64 views
Skip to first unread message

Tim Hawes

unread,
Dec 1, 2016, 6:38:50 PM12/1/16
to
So, I have been re-brushing my common lisp, and have been wanting to write some AWS api code in the process. Common Lisp has the aws-sign4 package that can be used to sign requests for their API.

The problem I am having is with a closure. aws-sign4 example code fails with the error message "Please bind *aws-credentials* to a function." It is initiated as nil, and the macro in the example is supposedly re-assigining the variable as a function, but it fails (and checking the output, *aws-credentials* is still nil).
https://github.com/copyleft/aws-sign4/blob/master/example/example.lisp

This code, is what I wrote on my own, and is identical (I think) to what aws-sign4 is suppose to be doing. This code works, and the global *foo* variable gets assigned to a function (within scope) using a macro: http://pastebin.com/ipzQHfj8

any insight as to what I am missing, and what helpful comments I might send to the maintainer of aws-sign4 to fix their example?

Kaz Kylheku

unread,
Dec 1, 2016, 7:38:40 PM12/1/16
to
On 2016-12-01, Tim Hawes <trh...@gmail.com> wrote:
> So, I have been re-brushing my common lisp, and have been wanting to
> write some AWS api code in the process. Common Lisp has the aws-sign4
> package that can be used to sign requests for their API.
>
> The problem I am having is with a closure. aws-sign4 example code
> fails with the error message "Please bind *aws-credentials* to a
> function." It is initiated as nil, and the macro in the example is
> supposedly re-assigining the variable as a function, but it fails (and
> checking the output, *aws-credentials* is still nil).
> https://github.com/copyleft/aws-sign4/blob/master/example/example.lisp

Are you using that example exactly, with example/package.lisp
being loaded, and the (in-package :aws-sign4-example) top and all?

I'm suspecting that maybe somehow your *aws-credentials* symbol is not
aws-sign4:*aws-credentials*, but some-other-package:*aws-credentials*.
Thus you're not actually binding the correct symbol.

The source code text which defines your with-aws-credentials macro has
to be read under a package in which the symbol
aws-sign4:*aws-credentials* is visible. This means that whatever
package is current at that point either has to be using aws-sign4
(without shadowing that symbol) or else be importing that symbol
individually from aws-sign4.

In the verbatim example, this is arranged because:

- the current package is aws-sign4-example, and that package
uses aws-sign4 (via the :use clause in its defpackage); and
- the aws-sign4 exports the *aws-credentials* symbol.

You can always have your macro refer to the fully qualified symbol,
like this:

(defmacro with-aws-credentials (&body body)
`(let ((aws-sign4:*aws-credentials* (credentials-from-file)))
,@body))

If this change makes the "Please bind ..." go away, it's a
package-related problem.

Tim Hawes

unread,
Dec 1, 2016, 11:26:45 PM12/1/16
to
Bingo! Thank you! I was not using the asdf system to test the example, so a definite namespace mismatch. Changing it aws-sign4:*aws-credentials* worked. Thanks again!
0 new messages