Return Styles: Pseud0ch, Terminal, Valhalla, NES, Geocities, Blue Moon.

Pages: 1-

Common Lisp interpreter

Name: Anonymous 2011-12-29 15:02

I'm reading Land of Lisp and the guy uses CLISP (and CLISP specific extensions), so I'm using it for now. But I've heard good things about SBCL and others. Which one would you recommend? Should I stick with CLISP?

Name: Anonymous 2011-12-29 15:05

I can't say cause I'm not a programmer but:

Racket is good for hand-holding and guis I think

I like Chicken because it can hook to mingw and both interpret and compile, and it does have some 'egg' libraries. I liked it the most because it's words were the same as SICPs, for Racket and others I needed to do shit like defun and whatever.

Lush looks neat but I guess it's more for AI and math.

Emacs is difficult to set up, but I'm not Autistic so your mileage may vary.

Name: Anonymous 2011-12-29 15:09

Finish the book and switch then, if you wish.

I would, though. JEWLISP is just silly:

(PRC () (values -8
                     (error "Timezone for PRC not implemented -
Don't forget that 10000 students were murdered by the government
of the \"People's Republic of China\" in June 1989!"
     )       )       )

Name: Anonymous 2011-12-29 15:19

>>1
Use SBCL. The reason for this is because

Name: Anonymous 2011-12-29 15:34

>>3
Is that part of CLISP source code? I can't believe that code is real.

Name: Anonymous 2011-12-29 15:41

>>5
Not anymore. They took it out sometime after this incident: http://groups.google.com/group/comp.lang.lisp/msg/ea3786d9844f125b

You can still dig out the old version from CVS, though.

Name: Anonymous 2011-12-29 17:29

Trivia: clisp turned GPL because of readline.
Wtf is up with that readline thing? Why they chose GPL, and why does everything (like PHP) apparently have an option for it?

Name: Anonymous 2011-12-29 17:39

>>7
What problem does readline actually solve? Who in their right mind would still use a crappy imitation of a crappy dumb terminal in the fucking 21st century? It's not like Acme and M-x shell have been around for, like, forever.

Name: Anonymous 2011-12-29 17:40

They're mostly compilers

Name: Anonymous 2011-12-30 12:07

>>1
CLISP aims to be an efficient interpreter, while most other implementations are compilers (while also providing an interpreter). I would suggest trying out SBCL and ClozureCL from the public-domain and LLGPL ones (CLISP is LGPL), they are much faster as far as the generated code is concerned, and have fairly interesting features which CLISP doesn't (but CLISP does have some nice features too, such as arbitrary precision floats).

Name: Anonymous 2011-12-30 12:42

>>10
SBCL doesn't provide an interpreter.
from the public-domain and LLGPL ones (CLISP is LGPL)
Shut up.

Name: >>10 2011-12-30 13:57

>>11
SBCL doesn't provide an interpreter.
False:

(defparameter *evaluator-mode* :compile
  #!+sb-doc
  "Toggle between different evaluator implementations. If set to :COMPILE,
an implementation of EVAL that calls the compiler will be used. If set
to :INTERPRET, an interpreter will be used.")

Shut up.
It's a widely known fact that most (Common) Lispers prefer public-domain, MIT, BSD, LLGPL to GPL. This is not an invitation to start a flame-war about licenses, merely a statement of facts (which you could find out by polling c.l.l, or merely looking at the licenses used by most CL libraries, GPL ones are a very small minority).

Name: Anonymous 2011-12-30 15:00

>>12
False:
Did you read the source?

(defun eval-in-lexenv (exp lexenv)
  #!+sb-eval
  (if (eq *evaluator-mode* :compile)
      ([b]simple-eval-in-lexenv[/b] exp lexenv)
      (sb!eval:eval-in-native-environment exp lexenv))
  #!-sb-eval
  (simple-eval-in-lexenv exp lexenv))


;;; [b][o][u][i]Pick off a few easy cases, and the various top level EVAL-WHEN[/i][/u][/o][/b]
;;; magical cases, and call %SIMPLE-EVAL for the rest.
(defun [b]simple-eval-in-lexenv[/b] (original-exp lexenv)
...
[b]%simple-eval[/b] ...


;;; general case of EVAL (except in that it can't handle toplevel
;;; EVAL-WHEN magic properly): Delegate to #'COMPILE.
(defun %simple-eval (expr lexenv)


Now, where's the interpreter?

It's a widely known fact that most (Common) Lispers prefer public-domain, MIT, BSD, LLGPL to GPL. This is not an invitation to start a flame-war about licenses, merely a statement of facts (which you could find out by polling c.l.l, or merely looking at the licenses used by most CL libraries, GPL ones are a very small minority).
Yeah, I'm one of them. Most people just don't care. Just shut up already.

Name: 13 2011-12-30 15:01

Alright, I forgot how much BBCode sucks, but you get the idea.

Name: >>12 2011-12-30 15:10

Now, where's the interpreter?
sb!eval:eval-in-native-environment is SBCL's interpreter, not the other case, you were looking at when (eq *evaluator-mode* :compile), not the other possibility.

Now look at the sb-eval package contained in full-eval.lisp:

;;;; An interpreting EVAL

;;;; This software is part of the SBCL system. See the README file for
;;;; more information.
;;;;
;;;; This software is derived from the CMU CL system, which was
;;;; written at Carnegie Mellon University and released into the
;;;; public domain. The software is in the public domain and is
;;;; provided with absolutely no warranty. See the COPYING and CREDITS
;;;; files for more information.


And there you will see code handling each special form in full:


(defun %%eval (exp env)
  (cond
    ((symbolp exp)
     ;; CLHS 3.1.2.1.1 Symbols as Forms
     (multiple-value-bind (value kind) (get-variable exp env)
       (ecase kind
         (:variable value)
         (:expansion (%eval value env)))))
    ;; CLHS 3.1.2.1.3 Self-Evaluating Objects
    ((atom exp) exp)
    ;; CLHS 3.1.2.1.2 Conses as Forms
    ((consp exp)
     (case (car exp)
       ;; CLHS 3.1.2.1.2.1 Special Forms
       ((block)                (eval-block (cdr exp) env))
       ((catch)                (eval-catch (cdr exp) env))
       ((eval-when)            (eval-eval-when (cdr exp) env))
       ((flet)                 (eval-flet (cdr exp) env))
       ((function)             (eval-function (cdr exp) env))
       ((go)                   (eval-go (cdr exp) env))
       ((if)                   (eval-if (cdr exp) env))
       ((labels)               (eval-labels (cdr exp) env))
       ((let)                  (eval-let (cdr exp) env))
       ((let*)                 (eval-let* (cdr exp) env))
       ((load-time-value)      (eval-load-time-value (cdr exp) env))
       ((locally)              (eval-locally (cdr exp) env))
       ((macrolet)             (eval-macrolet (cdr exp) env))
       ((multiple-value-call)  (eval-multiple-value-call (cdr exp) env))
       ((multiple-value-prog1) (eval-multiple-value-prog1 (cdr exp) env))
       ((progn)                (eval-progn (cdr exp) env))
       ((progv)                (eval-progv (cdr exp) env))
       ((quote)                (eval-quote (cdr exp) env))
       ((return-from)          (eval-return-from (cdr exp) env))
       ((setq)                 (eval-setq (cdr exp) env))
       ((symbol-macrolet)      (eval-symbol-macrolet (cdr exp) env))
       ((tagbody)              (eval-tagbody (cdr exp) env))
       ((the)                  (eval-the (cdr exp) env))
       ((throw)                (eval-throw (cdr exp) env))
       ((unwind-protect)       (eval-unwind-protect (cdr exp) env))
       ;; SBCL-specific:
       ((sb!ext:truly-the)     (eval-the (cdr exp) env))
       ;; Not a special form, but a macro whose expansion wouldn't be
       ;; handled correctly by the evaluator.
       ((sb!sys:with-pinned-objects) (eval-with-pinned-objects (cdr exp) env))
       (t
        (let ((dispatcher (getf *eval-dispatch-functions* (car exp))))
          (cond
            (dispatcher
             (funcall dispatcher exp env))
            ;; CLHS 3.1.2.1.2.4 Lambda Forms
            ((and (consp (car exp)) (eq (caar exp) 'lambda))
             (interpreted-apply (eval-function (list (car exp)) env)
                                (eval-args (cdr exp) env)))
            (t
             (multiple-value-bind (function kind) (get-function (car exp) env)
               (ecase kind
                 ;; CLHS 3.1.2.1.2.3 Function Forms
                 (:function (%apply function (eval-args (cdr exp) env)))
                 ;; CLHS 3.1.2.1.2.2 Macro Forms
                 (:macro
                  (let ((hook *macroexpand-hook*))
                    ;; Having an interpreted function as the
                    ;; macroexpander hook could cause an infinite
                    ;; loop.
                    (unless (compiled-function-p
                             (etypecase hook
                               (function hook)
                               (symbol (symbol-function hook))))
                      (error 'macroexpand-hook-type-error
                             :datum hook
                             :expected-type 'compiled-function))
                    (%eval (funcall hook
                                    function
                                    exp
                                    (env-native-lexenv env))
                           env)))))))))))))

(defun %eval (exp env)
  (incf *eval-calls*)
  (if *eval-verbose*
      ;; Dynamically binding *EVAL-LEVEL* will prevent tail call
      ;; optimization. So only do it when its value will be used for
      ;; printing debug output.
      (let ((*eval-level* (1+ *eval-level*)))
        (let ((*print-circle* t))
          (format t "~&~vA~S~%" *eval-level* "" `(%eval ,exp)))
        (%%eval exp env))
      (%%eval exp env)))

(defun %apply (fun args)
  (etypecase fun
    (interpreted-function (interpreted-apply fun args))
    (function (apply fun args))
    (symbol (apply fun args))))

(defun interpreted-apply (fun args)
  (let ((lambda-list (interpreted-function-lambda-list fun))
        (env (interpreted-function-env fun))
        (body (interpreted-function-body fun))
        (declarations (interpreted-function-declarations fun)))
    (call-with-new-env-full-parsing
     env lambda-list args declarations
     #'(lambda (env)
         (eval-progn body env)))))

Name: Anonymous 2011-12-30 15:16

>>15
What the fuck did I just write... I shouldn't post to /prog/ while drunk, although I never do otherwise.

Name: Anonymous 2011-12-30 15:19

>>16
To be fair, most people don't actually use SBCL's interpreter much(eval compiles by default), but it is there.

Name: Anonymous 2011-12-30 15:22

>>17
But still, I had thought they had figured out that interpreting was a stupid idea and pulled that crap out, just until now. :(

Name: Anonymous 2011-12-30 15:25

>>18
Interpreting is mostly useless, unless you have code that's heavily littered with eval calls, but we all know that's bad form (of the same type as fexprs), however SBCL's compiler would be slower than the interpreter in such cases.

Name: Anonymous 2011-12-30 15:29

>>19
Catering for such cases is just silly. There are a thousand ways to shoot yourself in the leg in CL. Why would eval be sanctified, of all of them?

Name: Anonymous 2011-12-30 15:36

>>20
I don't think it's why SBCL has an interpreter, it's probably just for completeness-sake, not like writing one is that difficult.

Name: Anonymous 2011-12-30 15:52

>>21
You can hardcode compiled-function-p to t while staying compliant. I'm surprised that absolutely everyone hasn't been doing this for the last ten years. Apparently I need to roll my own compiler.

Name: Anonymous 2011-12-30 16:00

>>19
why are fexprs/first-class macros/eval "bad form"
who is "we" in "we all know"?

I really have never heard a good argument against interpretation except for "it's slow" or "it's not idiomatic in my particular favorite language."

Please enlighten me.

Name: Anonymous 2011-12-30 16:05

>>23
Well, it's really slow, and no one has been able to come up with a way to make it not really slow. Unless you have something that proves me wrong, why are you still asking?

Name: Anonymous 2011-12-30 16:07

>>24
see
>>23
except for "it's slow"

Name: Anonymous 2011-12-30 16:14

>>25
Isn't that enough? They're all features that don't fundamentally provide anything that isn't accomplishable by a decent programmer via other means, and are known to be slow as fuck until someone proves otherwise. Just what else you need? Common Lisp isn't about ``ABSTRACT BULLSHITE'', it's about getting things done with proven 1994-era solutions. If you want to advance the state of lisp, look elsewhere.

Name: Anonymous 2011-12-30 16:14

>>23
Slowness is one problem, the other is understandability and debuggability. At least I find macros easier to understand cognitively, but I may be biased.

Name: Anonymous 2011-12-30 19:05

>>26
If you want to advance the state of lisp, look elsewhere.

I had already come to this conclusion myself, thanks.

They're all features that don't fundamentally provide anything that isn't accomplishable by a decent programmer via other means

Hey Mr Blub, languages aren't about capability, they're about idiom and elegance. I find the fact that I cant say (mapcar #'if '(t nil t) '(1 2 3) '(a b c)) in CL and others to be inelegant.

>>27
second-class macros are only easier to understand given the huge armature of "compile-time(s)". Eval and apply ain't half as complicated as that.

Name: Anonymous 2011-12-30 19:31

>>28
Hey Mr Blub, languages aren't about capability, they're about idiom and elegance. I find the fact that I cant say (mapcar #'if '(t nil t) '(1 2 3) '(a b c)) in CL and others to be inelegant.
You're missing the point. No one said that the fact that CL doesn't do them means that they're not useful. I think that fexprs would be nice to have, but until someone figures out how to make them not so incredibly slow, they're useless. CL has other (arguably less wieldy) means to accomplish the same task, and the people who came up with CL decided not to include them, most likely due to the bad perceived performance of such structures.

Name: Anonymous 2011-12-30 21:13

>>28
(mapcar #'if '(t nil t) '(1 2 3) '(a b c))

You could do that if you just write a wrapper against the special-form/macro. I was going to post here a generic wrapper-generator for just what you wanted, but then half-way through me writing it, I found a pretty annoying bug in SBCL's internals (which I don't feel like reporting at this moment) with how it handles obtaining the argument list of special forms (macro-expansion time vs run-time). It wasn't too difficult to write, but I'm sure my own code isn't absolutely bug-free either (it calls alexandria's lambda-list parser and generates a form from there), if I wasn't lazy, I could probably spend a few more hours and make it good enough for my own standards, but unfortunately I don't really need the macro for most of my needs, so it'll have to wait for another day. I also think that someone else on c.l.l has already written something similar in the past, if you can't find their post, you just need swank-backend:arglist (de-facto portable arglist grabber, but unfortunately there's a bug in SBCL which makes it fail when doing it at macroexpansion time for special forms, but works at run-time) and alexandria:parse-ordinary-lambda-list (if you don't want to write your lambda list parser, it's not too pleasant).

Name: Anonymous 2011-12-30 22:18

>>30

yeah, just do a:

(defun if-function (condition true-value false-value)
  (if condition
    true-value
    false-value))

and then you can map that around. Unless you want lazy evaluation of true-value and false value. Then that is kind of a different can of worms. It's complicated, because mapcar would need to know to not evaluate the lists the operator is being applied to until the operator needed them evaluated, which isn't the default behavior in lisp. mapcar would need to be something special.

Don't change these.
Name: Email:
Entire Thread Thread List