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

How to "see" the implementation of a primitive function in Lisp?

45 views
Skip to first unread message

jfbaro

unread,
May 29, 2011, 9:40:43 PM5/29/11
to
Hi,

I am completly new to the world of functional languages and Lisp
dialects. I have been reading a few blogs and articles over the
internet (My SICP book is on its way!).

I was wondering if there is a simple way to see how primitive
functions (or even the ones I defined previously) are implemented. For
example, if I want to check how + function is implemented how could I
do that?

I am using emacs 23.2.1 (is that enough to know?).

Regards

Thomas Atkins

unread,
May 29, 2011, 9:58:42 PM5/29/11
to

It varies widely based on your dialect and implementation. If you're
using Common Lisp you can use disasseble
http://www.ai.mit.edu/projects/iiip/doc/CommonLISP/HyperSpec/Body/fun_disassemble.html.

e.g. to see to see the implementation of of + just type (disassemble
'+)

If you are using an open source implementation you can try downloading
the source and poking around.

vlionix

unread,
May 29, 2011, 10:13:59 PM5/29/11
to

In a coherently set-up emacs/Slime, you can M-. and jump to
definition. So we find that DEFUN in SBCL is implemented as follows:

(defmacro-mundanely defun (&environment env name args &body body)
"Define a function at top level."
#+sb-xc-host
(unless (symbol-package (fun-name-block-name name))
(warn "DEFUN of uninterned function name ~S (tricky for GENESIS)"
name))
(multiple-value-bind (forms decls doc) (parse-body body)
(let* (;; stuff shared between LAMBDA and INLINE-LAMBDA and NAMED-
LAMBDA
(lambda-guts `(,args
,@decls
(block ,(fun-name-block-name name)
,@forms)))
(lambda `(lambda ,@lambda-guts))
#-sb-xc-host
(named-lambda `(named-lambda ,name ,@lambda-guts))
(inline-lambda
(when (inline-fun-name-p name)
;; we want to attempt to inline, so complain if we can't
(or (sb!c:maybe-inline-syntactic-closure lambda env)
(progn
(#+sb-xc-host warn
#-sb-xc-host sb!c:maybe-compiler-notify
"lexical environment too hairy, can't inline
DEFUN ~S"
name)
nil)))))
`(progn
;; In cross-compilation of toplevel DEFUNs, we arrange for
;; the LAMBDA to be statically linked by GENESIS.
;;
;; It may seem strangely inconsistent not to use NAMED-LAMBDA
;; here instead of LAMBDA. The reason is historical:
;; COLD-FSET was written before NAMED-LAMBDA, and has special
;; logic of its own to notify the compiler about NAME.
#+sb-xc-host
(cold-fset ,name ,lambda)

(eval-when (:compile-toplevel)
(sb!c:%compiler-defun ',name ',inline-lambda t))
(eval-when (:load-toplevel :execute)
(%defun ',name
;; In normal compilation (not for cold load) this
is
;; where the compiled LAMBDA first appears. In
;; cross-compilation, we manipulate the
;; previously-statically-linked LAMBDA here.
#-sb-xc-host ,named-lambda
#+sb-xc-host (fdefinition ',name)
,doc
',inline-lambda
(sb!c:source-location)))))))

You will find this routine in SBCL's defmacro.lisp.

I am not sure how this will help you besides providing examples of
your Lisp implementation innards.

HTH

Pascal J. Bourguignon

unread,
May 29, 2011, 10:46:33 PM5/29/11
to
jfbaro <jfb...@gmail.com> writes:


If you're using emacs with a well configured slime and inferior lisp
(= Common Lisp implementation, emacs calls "inferior" its subprocesses),
then it should be enough to type M-. after the name of the function (in
a buffer with slime-mode activated, such as a .lisp file).

For example,

C-u M-x slime RET ccl RET
C-x C-f /tmp/a.lisp RET
(defun M-.

opens /data/src/languages/ccl/ccl-trunk-linuxx86/lib/macros.lisp on:

(defmacro defun (spec args &body body &environment env &aux global-name inline-spec)


"Define a function at top level."

(validate-function-name spec)
(setq args (require-type args 'list))
(setq body (require-type body 'list))
...

(I downloaded and compiled ccl myself).


On the other hand, with sbcl, I get:

cond: Error: failed to find the WRITE-DATE of /usr/lib64/sbcl/src/code/defboot.lisp: No such file or di

(I installed sbcl thru my distribution packages, and they didn't deem
the sources of sbcl worthwhile to install into /usr/lib64/sbcl/src).


But if you install them, slime can bring you to the mentionned file on:

(defmacro-mundanely defun (&environment env name args &body body)
"Define a function at top level."
#+sb-xc-host
(unless (symbol-package (fun-name-block-name name))
(warn "DEFUN of uninterned function name ~S (tricky for GENESIS)" name))
(multiple-value-bind (forms decls doc) (parse-body body)

...


You may also easily find the source of emacs lisp operators (or your own
emacs lisp functions), with: C-h f RET C-x o TAB RET

C-x C-f /tmp/a.el RET
(defun C-h f RET C-x o TAB RET

but then again, you need to have the sources of emacs around, including
the C sources, to see them. (Which again, means you cannot trust your
distribution to have done it, but that you have to donwload the sources
of emacs and compile them yourself).


--
__Pascal Bourguignon__ http://www.informatimago.com/
A bad day in () is better than a good day in {}.

jfbaro

unread,
May 29, 2011, 11:09:18 PM5/29/11
to
Wow! Thank you all for the quick replies!

I'll check these later today and let you know if I was able to
succeed :)

P.S.: I am quite impressed with how fast you guys answered my
question. I am really glad. Thanks again!

Regards

On 29 maio, 23:46, "Pascal J. Bourguignon" <p...@informatimago.com>
wrote:

0 new messages