[parenscript-devel] A macro for integrating PS with Slime

Vladimir Sedach vsedach at gmail.com
Thu Jun 17 20:03:19 UTC 2010


That's a good way of doing things for now. I didn't realize
DEFMACRO+PS could be used that way either.

The hypothetical Parenscript-SLIME is supposed to do this (and more).
Andrey Moskvitin has a fork of SLIME that supports feature and
protocol extensions (http://github.com/archimag/slime-archimag -
strangely enough the current SLIME maintainers don't seem to be
interested in things like protocol versioning) and I'm planning to see
if I can do things like xref support for Parenscript forms there.

Vladimir

2010/6/17 Daniel Gackle <danielgackle at gmail.com>:
> Below is a DEFUN-JS macro for defining PS functions at the Lisp top-level.
> It creates a Lisp stub with the same signature whose body simply throws
> an error telling you that you tried to call a PS function from Lisp. Why is
> that
> useful? Because now your PS functions are fully integrated with Slime.
> You can jump around with M-., get arglist info in the minibuffer, and so on.
> After a week of using this, I can't believe how much of a difference it
> makes.
> In PS, DEFUN-JS translates trivially to DEFUN. Of course you still need a
> way to collect the JS emitted by all these forms, but PS is agnostic on how
> that should be done.
> A side note: we also converted nearly all our ps macros to DEFMACRO+PS
> forms at the toplevel. This has the neat property that you can now
> look at expansions using the highly convenient Slime macroexpand. I doubt
> that this is a perfect solution (no doubt you can trip yourself up on
> differences
> between the CL and PS macro environments), but it's sure handier than
> calling
> PS::PS-MACROEXPAND from the REPL.
> Daniel
> p.s. The following has been stripped of a couple of functions specific to
> our project. I tested it a bit, but if I missed anything, let me know.
>
> (defmacro defun-js (name lambda-list &body body)
>   (declare (ignore body))
>   (labels ((sym% (argspec) (if (symbolp argspec) argspec (car argspec))))
>     (multiple-value-bind (required optionals restp rest keyp keys allowp
> auxp aux morep more-context more-count beyond-requireds? key-object)
>         (ps::parse-lambda-list lambda-list)
>       (declare (ignore restp keyp allowp auxp aux morep more-context
> more-count beyond-requireds? key-object))
>       ;; get rid of init forms, which can't be evaluated in Lisp.
>       (setf optionals (mapcar #'sym% optionals) keys (mapcar #'sym% keys))
>       `(defun ,name (, at required ,@(when optionals `(&optional , at optionals))
>                      ,@(when rest `(&rest ,rest)) ,@(when keys `(&key
> , at keys)))
>          (declare (ignore , at required , at optionals ,@(when rest (list rest))
> , at keys))
>          (error "The ~s function is js-only and cannot be called from Lisp."
> ',name)))))
> (defpsmacro defun-js (name lambda-list &body body)
>   `(defun ,name ,lambda-list , at body))
> _______________________________________________
> parenscript-devel mailing list
> parenscript-devel at common-lisp.net
> http://common-lisp.net/cgi-bin/mailman/listinfo/parenscript-devel
>
>




More information about the parenscript-devel mailing list