[Ecls-list] ecl-standalone *feature* or similar?

Matthew Mondor mm_lists at pulsar-zone.net
Fri Aug 14 03:51:08 UTC 2009


The following example code builds and loads fine from both slime or

(eval-when (:compile-toplevel :load-toplevel)
  ;; XXX If ECL sockets are intended to be SBCL compatible, shouldn't
  ;;     they still load with :sb-bsd-sockets?
  #+sbcl(require :sb-bsd-sockets)
  #+ecl(require :sockets))

(defpackage :socket-test
  (:use :cl :sb-bsd-sockets) ; Also works with ECL
  (:export #:test))

(in-package :socket-test)

(defun test (host port)
  (let ((socket (make-instance 'inet-socket :type :stream :protocol :tcp))
        (hostent (get-host-by-name host)))
    (socket-connect socket (host-ent-address hostent) port)
    (format t "Connected~%")
    (socket-close socket))

And the following works at ECL/SBCL/slime REPL:

> (socket-test:test "somehost" someport)

However, if building a standalone executable, unless (test) is added at
the end, nothing is executed when invoking the executable from the OS
shell (as expected).  If I want to add ECL-specific and
standalone-executable specific code which checks/processes the
command-line arguments and then invoking TEST, they have to be at the
first level.

Yet if they are at the first level, C-c C-k at the slime REPL obviously
executes the first level as well, causing ECL to exit with an error
code if command-line parameters are required (slime obviously reports
loss connection to inferior-lisp then).  It also exits with code 0 on
success at (ext:quit 0) (standalone executables are generally expected
to exit at some point :)

So I tried writing an arguments processing function (standalone-main)
and passing '(socket-test:standalone-main) as :epilogue-code to
c::build-program, but this doesn't seem to work well (it appears that
the exceptions system is not yet initialized when the function is
invoked, so "Connected" gets printed even if an exception should occur
when attempting to connect to an unbound port, for instance).  Is this

A simple solution would probably be to have something like
an ecl-standalone *feature* which would only be present at
compile/execute when providing :system-p t to compile-file.  Grepping
the source yielded no such *feature* so far, is anyone aware of another
elegant way to handle this situation?  Of course, an inverse feature
like INTERACTIVE-REPL which would not be present when using :system-p t
would also be similar (I guess that a slime-specific one might exist,
but this couldn't be relied on at a native REPL)...

Using multiple files with ASDF for a complete project might be more
elegant, but it's nice being able to have working single-file tests at
both REPL and standalone (and for them to be portable between SBCL and
ECL when used at REPL).  But even with ASDF, wouldn't the module
handling the command line arguments also need such a condition so that
it's also possible to use the package at REPL?  Otherwise a separate
custom build script including the ECL-specific command line parsing
code would have to be used...

Also, I'm not sure if ECL can be used as script interpreter specified
via #! on unix, but if so, it's possible that an "ecl-standalone"
feature would not be general enough.  Perhaps others here having used
ECL or other lisps under similar circumstances know of previous art in
this area?


More information about the ecl-devel mailing list