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

proper use of require

166 views
Skip to first unread message

Bigos

unread,
Jun 1, 2013, 9:13:58 AM6/1/13
to
Why this doesn't work?

;;; this is supposed to run on devel machine only
(if (not (sb-ext:posix-getenv "OPENSHIFT_INTERNAL_IP"))
(progn
(require 'swank)
(swank:create-server :port 4005)))


And why this one does?

;;; this is supposed to run on devel machine only
(unless (sb-ext:posix-getenv "OPENSHIFT_INTERNAL_IP")
(require 'swank))

(unless (sb-ext:posix-getenv "OPENSHIFT_INTERNAL_IP")
(swank:create-server :port 4005))

Bigos

unread,
Jun 1, 2013, 9:47:11 AM6/1/13
to
On 01/06/13 14:13, Bigos wrote:
> Why this doesn't work?
>
> ;;; this is supposed to run on devel machine only
> (if (not (sb-ext:posix-getenv "OPENSHIFT_INTERNAL_IP"))
> (progn
> (require 'swank)
> (swank:create-server :port 4005)))

I've found solution on Stack Overflow
http://stackoverflow.com/questions/12811198/can-i-load-swank-lazily

and this seems to work

;;; this is supposed to run on devel machine only
(if (not (sb-ext:posix-getenv "OPENSHIFT_INTERNAL_IP"))
(progn
(ql:quickload :swank)
(funcall (intern (string '#:create-server) :swank) :port 4005)

))

The problem is that now I prefer my old working solution. what should I do?

D Herring

unread,
Jun 1, 2013, 9:15:53 PM6/1/13
to
REQUIRE is a function. Functions are evaluated at run-time, not at
read-time or compile-time.

Try using the following clause to make it take effect more promptly.

(eval-when (:compile-toplevel :load-toplevel :execute)
(require 'swank))

- Daniel

Tamas K Papp

unread,
Jun 2, 2013, 1:41:59 AM6/2/13
to
REQUIRE & related functionality is deprecated, so I don't understand why
you prefer it. On many CL implementations (SBCL included) it just hooks
into ASDF anyway, so you might as well use ASDF:LOAD-SYSTEM, but using
Quicklisp should be fine too.

Best,

Tamas

Bigos

unread,
Jun 2, 2013, 4:22:01 AM6/2/13
to

Madhu

unread,
Jun 2, 2013, 4:33:17 AM6/2/13
to

* Tamas K Papp <878v2tn...@tamas.ihs.ac.at> :
Wrote on Sun, 02 Jun 2013 07:41:59 +0200:
| REQUIRE & related functionality is deprecated, so I don't understand
| why you prefer it. On many CL implementations (SBCL included) it just
| hooks into ASDF anyway, so you might as well use ASDF:LOAD-SYSTEM, but
| using Quicklisp should be fine too.

A lot of functions are "Deprecated", in the spec, but in retrospect it
is the "deprecation" is shortsighted. REQUIRE is in the CommonLisp
spec, but ASDF and QUICKLISP instruments of Satan, to take control of
your code through the middleware layers. The dependency conspiracy is
carefully thought out, but by the time you figure it out you will be
buried and forgotten, while Papp & Co. will be around using advertising
and marketing machinery [mis]leading a new generation of users that
ready and willing to suffer for the first time. ---Madhu

Bigos

unread,
Jun 2, 2013, 4:35:07 AM6/2/13
to
On 02/06/13 09:22, Bigos wrote:

>
> link to my code on github:
>
> https://github.com/bigos/lisp-openshift/blob/master/.sbclrc


It seems I need 2 exactly the same tests, is there way to re-factor it?
I'm asking out of curiosity, because I guess I could live with code I
have at the moment.

Madhu

unread,
Jun 2, 2013, 4:40:21 AM6/2/13
to

* Tamas K Papp <878v2tn...@tamas.ihs.ac.at> :
Wrote on Sun, 02 Jun 2013 07:41:59 +0200:
| REQUIRE & related functionality is deprecated, so I don't understand
| why you prefer it. On many CL implementations (SBCL included) it just
| hooks into ASDF anyway, so you might as well use ASDF:LOAD-SYSTEM, but
| using Quicklisp should be fine too.

A lot of functions are "Deprecated", in the spec, but in retrospect it
is the "deprecation" that is shortsighted. REQUIRE is in the CommonLisp
spec, but ASDF and QUICKLISP instruments are from Satan to take control
of your code through the middleware layers. The dependency conspiracy
is carefully thought out, but by the time you figure it out, you will be
buried and forgotten; while Papp & Co. will be around using advertising
and marketing machinery, [mis]leading a new generation of users that are

Pascal J. Bourguignon

unread,
Jun 2, 2013, 9:19:15 AM6/2/13
to
Abstract away:

{load-packages-from-system-and-eval (:swank) :swank
(swank:create-server :port 4005)}

so that you don't care what working solution is hidden below the API.





;;; Infrastructure for named reader macros. We'll introduce them with
;;; a #\{ followed by a symbol naming the reader macro function to ;;
;;; call.

(eval-when (:compile-toplevel :load-toplevel :execute)
(defvar *named-reader-macros* (make-hash-table)))

(defmacro define-named-reader-macro (name (stream) &body body)
(check-type name symbol)
(check-type stream symbol)
`(eval-when (:compile-toplevel :load-toplevel :execute)
(setf (gethash ',name *named-reader-macros*)
(lambda (,stream)
(block ,name ,@body)))))

(defun named-reader-macro (name)
(gethash name *named-reader-macros*))

(defun brace-reader-macro (stream ch)
(declare (ignore ch))
(let ((name (read stream)))
(if (symbolp name)
(let ((reader-macro (named-reader-macro name)))
(if reader-macro
(funcall reader-macro stream)
(error "No reader macro named ~S" name)))
(error "The reader macro should be a symbol, not the ~S ~S" (type-of name) name))))

(set-macro-character #\{ 'brace-reader-macro nil *readtable*)



;;; To implement {load-packages-from-system-and-eval …} we need a non-interning reader.

(ql:quickload :com.informatimago.common-lisp.lisp-reader)


(defstruct future-symbol
name
package
qualified
external)

(com.informatimago.common-lisp.lisp-reader.reader::defparser parse-symbol-token (token)
"symbol ::= symbol-name
symbol ::= package-marker symbol-name
symbol ::= package-marker package-marker symbol-name
symbol ::= package-name package-marker symbol-name
symbol ::= package-name package-marker package-marker symbol-name
symbol-name ::= {alphabetic}+
package-name ::= {alphabetic}+ "
(let ((colon (position-if
(lambda (traits) (com.informatimago.common-lisp.lisp-reader.reader::traitp
com.informatimago.common-lisp.lisp-reader.reader::+ct-package-marker+
traits))
(com.informatimago.common-lisp.lisp-reader.reader::token-traits token))))
(if colon
(let* ((double-colon (and (< (1+ colon) (com.informatimago.common-lisp.lisp-reader.reader::token-length token))
(com.informatimago.common-lisp.lisp-reader.reader::traitp
com.informatimago.common-lisp.lisp-reader.reader::+ct-package-marker+
(com.informatimago.common-lisp.lisp-reader.reader::token-char-traits
token (1+ colon)))))
(pname (subseq (com.informatimago.common-lisp.lisp-reader.reader::token-text token)
0 colon))
(sname (subseq (com.informatimago.common-lisp.lisp-reader.reader::token-text token)
(+ colon (if double-colon 2 1)))))
(when (position-if
(lambda (traits) (com.informatimago.common-lisp.lisp-reader.reader::traitp
com.informatimago.common-lisp.lisp-reader.reader::+ct-package-marker+
traits))
(com.informatimago.common-lisp.lisp-reader.reader::token-traits token)
:start (+ colon (if double-colon 2 1)))
(com.informatimago.common-lisp.lisp-reader.reader::reject
t "Too many package markers in token ~S"
(com.informatimago.common-lisp.lisp-reader.reader::token-text token)))
(if (zerop colon)
(com.informatimago.common-lisp.lisp-reader.reader::accept
;; Keywords always exist, so let's intern them before finding them.
'symbol (intern sname (load-time-value (find-package "KEYWORD"))))
(com.informatimago.common-lisp.lisp-reader.reader::accept
'symbol (make-future-symbol :name sname :package pname :qualified t :external (not double-colon)))))
(com.informatimago.common-lisp.lisp-reader.reader::accept
;; no colon in token, let's just intern the symbol in the current package:
'symbol (make-future-symbol :name (com.informatimago.common-lisp.lisp-reader.reader::token-text token)
:package (package-name *package*)
:qualified nil)))))


(defun parse-token-non-interning (token)
"
RETURN: okp ; the parsed lisp object if okp, or an error message if (not okp)
"
(let ((message nil))
(macrolet
((rom (&body body)
"Result Or Message"
(if (null body)
'nil
(let ((vals (gensym)))
`(let ((,vals (multiple-value-list ,(car body))))
;; (format *trace-output* "~S --> ~S~%" ',(car body) ,vals)
(if (first ,vals)
(values-list ,vals)
(progn
(when (second ,vals)
(setf message (third ,vals)))
(rom ,@(cdr body)))))))))
(multiple-value-bind (ok type object)
(rom (com.informatimago.common-lisp.lisp-reader.reader::parse-decimal-integer-token token)
(com.informatimago.common-lisp.lisp-reader.reader::parse-integer-token token)
(com.informatimago.common-lisp.lisp-reader.reader::parse-ratio-token token)
(com.informatimago.common-lisp.lisp-reader.reader::parse-float-1-token token)
(com.informatimago.common-lisp.lisp-reader.reader::parse-float-2-token token)
(parse-symbol-token token))
(declare (ignorable type))
(values ok (if ok object message))))))




;;; Now we can write it:

(eval-when (:compile-toplevel :load-toplevel :execute)
(defun ensure-list (object)
(if (listp object) object (list object))))

(define-named-reader-macro load-packages-from-system-and-eval (stream)
;; TODO: use FIND-SYMBOL and check the external qualification instead of INTERN.
(flet ((read-in-keyword (stream)
(let ((*package* (load-time-value (find-package "KEYWORD"))))
(read stream)))
(read-non-interning (stream)
(let ((com.informatimago.common-lisp.lisp-reader.reader:*readtable*
(load-time-value (com.informatimago.common-lisp.lisp-reader.reader:copy-readtable nil))))
(setf (com.informatimago.common-lisp.lisp-reader.reader:readtable-parse-token
com.informatimago.common-lisp.lisp-reader.reader:*readtable*)
(function parse-token-non-interning))
(com.informatimago.common-lisp.lisp-reader.reader:read stream)))
(end-of-brace-p (item)
(and (future-symbol-p item)
(string= "}" (future-symbol-name item))
(not(future-symbol-qualified item)))))
(let ((packages (ensure-list (read-in-keyword stream)))
(systems (ensure-list (read-in-keyword stream)))
(body (loop
:for sexp = (read-non-interning stream)
:until (end-of-brace-p sexp)
:collect sexp)))
(labels ((process-atom (atom)
(if (future-symbol-p atom)
(if (member (future-symbol-package atom) packages :test (function string=))
(values (if (future-symbol-qualified atom)
`(intern ,(future-symbol-name atom) ,(future-symbol-package atom))
`(intern ,(future-symbol-name atom)))
t)
(values (if (future-symbol-qualified atom)
(intern (future-symbol-name atom) (future-symbol-package atom))
(intern (future-symbol-name atom)))
nil))
atom))
(process-sexp (sexp)
(if (atom sexp)
(process-atom sexp)
(let ((operator (first sexp))
(arguments (mapcar (lambda (sexp)
(multiple-value-bind (object future) (process-sexp sexp)
(if future
;; a variable in a future loaded package.
;; Notice it cannot be a lexical variable.
`(eval ,object)
object)))
(rest sexp))))
(if (atom operator)
(multiple-value-bind (object future) (process-atom operator)
(if future
`(funcall ,object ,@arguments)
`(,object ,@arguments)))
`(,(process-sexp operator) ,@arguments))))))
`(progn
,@(mapcar (lambda (system) `(ql:quickload ,system)) systems)
,@(mapcar (function process-sexp) body))))))



{load-packages-from-system-and-eval (:swank) :swank
(print '(creating server on port 4005))
(swank:create-server :port 4005)}



(pprint '{load-packages-from-system-and-eval (:swank) :swank
(print '(creating server on port 4005))
(swank:create-server :port 4005)})

(progn (quicklisp-client:quickload :swank)
(print '(creating server on port 4005))
(funcall (intern "CREATE-SERVER" "SWANK") :port 4005))



--
__Pascal Bourguignon__ http://www.informatimago.com/
A bad day in () is better than a good day in {}.
You can take the lisper out of the lisp job, but you can't take the lisp out
of the lisper (; -- antifuchs

Dan Lentz

unread,
Jun 11, 2013, 5:40:19 PM6/11/13
to
Wow pascal does that qualify as a good day in {}?

Pascal J. Bourguignon

unread,
Jun 13, 2013, 5:10:19 PM6/13/13
to
Dan Lentz <DanL...@gmail.com> writes:

> Wow pascal does that qualify as a good day in {}?

A good hour in ().

Max Rottenkolber

unread,
Jun 14, 2013, 1:54:16 PM6/14/13
to
> Abstract away: [...]
> so that you don't care what working solution is hidden below the API.
> [...]
But WHY?

--
Max Rottenkolber
Rottenkolber Software Engineering
http://mr.gy

Pascal J. Bourguignon

unread,
Jun 14, 2013, 2:24:59 PM6/14/13
to
Because I've not had the time yet to come with a better hook into a CL
reader.

Indeed having just a readtable-parse-token hook is not enough, since
usually you just want to have a variation of a few tokens. But
providing parsers for lisp tokens requires revealing the character
traits API, lisp tokens are not just strings: "abc:def" could come from
abc\:def or from abc:def In the first case the default lisp reader
interns a symbol named "ABC:DEF" in the current package, while in the
second case, it interns a symbol named "DEF" in the package named "ABC".

With some time, hopefully before ELS2014, I should be able to come with
a good proposion and write a CDR.

Max Rottenkolber

unread,
Jun 16, 2013, 4:59:27 PM6/16/13
to
What I wanted to say is: This looks like a really complex solution for
something a simple macro could solve. I don't get why you need a new
reader?

Pascal J. Bourguignon

unread,
Jun 16, 2013, 6:08:11 PM6/16/13
to
Max Rottenkolber <m...@mr.gy> writes:

> What I wanted to say is: This looks like a really complex solution for
> something a simple macro could solve. I don't get why you need a new
> reader?

Read: http://www.nhplace.com/kent/PS/Ambitious.html

--
__Pascal Bourguignon__ http://www.informatimago.com/
A bad day in () is better than a good day in {}.
You know you've been lisping too long when you see a recent picture of George
Lucas and think "Wait, I thought John McCarthy was dead!" -- Dalek_Baldwin
0 new messages