Using libraries in CLISP scripts

Discussion of Common Lisp

Using libraries in CLISP scripts

Postby aidlt » Sun Jun 30, 2013 10:50 am

Hi all.

I'm trying to create a simple CLISP script and I'd like to find out what are the most efficient and common ways of loading a library.

The script should take a line from stdin and display a message box containing this line. I'm using LTK.

This is the Python prototype:
Code: Select all
#!/usr/bin/env python3

# show-message.py

from tkinter import *
from tkinter import messagebox

def show_message(txt):
    root = Tk()
    root.withdraw()
    messagebox.showinfo("", txt)
    root.destroy()

def main():
    show_message(input())

main()

It runs pretty well:
Code: Select all
$ time echo hello world | ./show-message.py

real   0m1.381s
user   0m0.132s
sys   0m0.020s

The `real' time doesn't matter as it depends on when the user press the OK button.

Basicly I'm not sure about what the Lisp counterpart of the import statements should be.

I use quicklisp, so the straightforward solution was as follows:
Code: Select all
#!/usr/bin/env clisp

(load (merge-pathnames "quicklisp/setup.lisp" (user-homedir-pathname)))
(ql:quickload :ltk)

(in-package :ltk)

(defun show-message (txt)
  (with-ltk ()
    (format-wish "wm withdraw .")
    (do-msg txt)
    (exit-wish)))

(defun main ()
  (let ((msg (read-line nil nil nil)))
    (when msg
      (show-message msg))))

(main)

The `load' doesn't look especially elegant, but let it be. Much worse is that there's a noticeable delay. Indeed,
Code: Select all
$ time echo hello world | ./show-message.lisp >> /dev/null

real    0m1.449s
user    0m0.508s
sys 0m0.080s

So user time is nearly four times greater compared to Python.

I also tried to use asdf directly. I copied asdf.lisp into the same directory as the script, compiled it, created the directory `asdf' in my home directory, and created a symlink to ltk.asd (sitting deep in the quicklisp dir) in `asdf'. My preamble became as follows:
Code: Select all
(load 'asdf)
(push (merge-pathnames "asdf/" (user-homedir-pathname)) asdf:*central-registry*)
(asdf:load-system 'ltk)

The performance improved (not drastically, but all the same):
Code: Select all
$ time echo hello world | ./show-message.lisp >> /dev/null
WARNING: Replacing method
          #<CLOS:STANDARD-WRITER-METHOD
            (#<BUILT-IN-CLASS T> #<STANDARD-CLASS TREEITEM>)>
         in #<STANDARD-GENERIC-FUNCTION (SETF TEXT)>
WARNING: Replacing method
          #<CLOS:STANDARD-WRITER-METHOD
            (#<BUILT-IN-CLASS T> #<STANDARD-CLASS TREEITEM>)>
         in #<STANDARD-GENERIC-FUNCTION (SETF IMAGE)>
0 errors, 2 warnings

real   0m1.277s
user   0m0.308s
sys   0m0.044s

Probably I could do with this script being two times slower than in Python (luckily I don't know Perl :D). However, I'm afraid my solution is rather awkward.
aidlt
 
Posts: 17
Joined: Thu May 16, 2013 1:42 pm

Re: Using libraries in CLISP scripts

Postby aidlt » Sun Jun 30, 2013 2:09 pm

So far SBCL wins, both in performance and in outlook. It's a pity it doesn't support shebang.
Code: Select all
(require 'asdf)
(push (merge-pathnames "asdf/" (user-homedir-pathname)) asdf:*central-registry*)
(require 'ltk)

$ time echo hello world | sbcl --script show-message-sbcl.lisp

real   0m1.202s
user   0m0.268s
sys   0m0.044s
aidlt
 
Posts: 17
Joined: Thu May 16, 2013 1:42 pm

Re: Using libraries in CLISP scripts

Postby Goheeca » Mon Jul 01, 2013 1:25 am

SBCL supports the shebang via the switch --script.
Code: Select all
#!/usr/bin/sbcl --script

(defun argv ()
  (or
   #+clisp (ext:argv)
   #+sbcl sb-ext:*posix-argv*
   #+clozure (ccl::command-line-arguments)
   #+gcl si:*command-args*
   #+ecl (loop for i from 0 below (si:argc) collect (si:argv i))
   #+cmu extensions:*command-line-strings*
   #+allegro (sys:command-line-arguments)
   #+lispworks sys:*line-arguments-list*
   nil))

(format t "~&~{~a~^ ~}~%" (argv))
cl-2dsyntax is my attempt to create a Python-like reader. My mirror of CLHS (and the dark themed version).
User avatar
Goheeca
 
Posts: 220
Joined: Thu May 10, 2012 12:54 pm

Re: Using libraries in CLISP scripts

Postby aidlt » Mon Jul 01, 2013 2:18 am

Thanks, Goheeca, that's great! Both the news and the function, I mean. :)

BTW apparently the most speedy approach is to put ltk.fas(l) in the script's directory and load it, then SBCL runs as fast as Python and CLISP is just a little bit slower. However, this is very ad hoc. Perhaps the right thing is to save an image containing quicklisp. The scripts become cleaner and the performance is decent.
aidlt
 
Posts: 17
Joined: Thu May 16, 2013 1:42 pm


Return to Common Lisp

Who is online

Users browsing this forum: No registered users and 1 guest

cron