Posts tagged common lisp

Common Lisp: CCL on a raspberry pi

posted on 2015-04-28 00:12:21

A raspberry is n ARM-architecture based processor. Usually my common lisp implementation of choice is SBCL / Steel Bank Common Lips, but for ARM CCL / Clozure Common Lisp might be a better fit.

According to some sources on the internet, this is due to CCL's native threadingsupport.

download & compile & install

Head over to http://ccl.clozure.com/download.html and copy the download link.

wget <download-link>
tar xzvf ccl-<...>.tar.gz
mv ccl-<...> /usr/local/src
cd /usr/local/src/ccl/lisp-kernel/linuxarm
vi float_abi.mk
# uncomment FLOAT_ABI_OPTION = -mfloat-abi=hard and save, quit
make clean && make
ls -s /usr/local/src/ccl/armcl /usr/local/bin/armcl

Now you should have running armcl binary, which is at the right position according to the FHS (Filesystem Hierarchy Standard) and can be run from anywhere of your shell.

install quicklisp

cd /usr/local/src
curl http://beta.quicklisp.org/quicklisp.lisp > quicklisp.lisp
armcl
(load "quicklisp.lisp")
(quicklisp-quickstart:install)
(ql:add-to-init-file)
(quit)

Then vi ~/.ccl-init.lisp and wrap the generated code within (defun load quicklisp () ... ). That way you have an easy to call function if you really need ql loaded ((load-quicklisp) will do in the interpreter.), but initial startup is faster. This and the float config trick is something I found at lispm.de, thanks to Rainer Joswig.

quicklisp help

These might be helpful:

(ql:update-all-dists)
(ql:update-client)
(ql:system-apropos '<string>)
(ql:who-depends-on '<string>)

common lisp's 'format'

posted on 2014-09-08 21:50:28

Common Lisp swiss army knife of printing, format, shall be looked at in depth here.

usual layout

(format <destination_parameter> "<control_string>" <value_parameter>)

The format keyword starts the formatted string.

"control_string" is just a regular string in between double quotes, usually containing some control sequences.

Value parameters are the parts substituting the control sequences within the control string.

the destination parameter

Three possible values:

  • nil = just create a string, return the string as value, print nothing
  • t = print to console, function returns nil as value
  • stream = output to a stream

standard control sequences layouts

general layout:

~x,y,z,'p@a

where x, y, z are number-counts, 'p is a character, @ is optional, a could as well be an s or any other control sequence type.

x   : base count of characters
y   : if given, and base size is too small, increase in steps of y
z   : exact number of spaces added to string
'p  : padding character
@   : make the introduced value appear AFTER the padding



~a    absolute value, no delimiters
~s    string value, including delimiters
~5a   absolute value, size of 5, real string is leftbound
~5@a  absolute value, size of 5, real string is rightbound
~5,2a absolute value, size of 5, if value parameter is larger
      increase result in steps of 2 characters

float layout:

~a,b,cf

where a is the sum of integers, the comma and the amount of decimals possible. b is just the count of decimals to be shown. c scale number in factors of 10.

available number control sequences

~b  binary
~x  hexadecimal
~d  decimal
~:d decimal with 1000er dots in between
~f  floats
~$  currency control sequence

newlines

~%  terpri = hard newline, if number is given in front of it, it's the count of newlines
~&  fresh-line = soft newline, only newline if none has been inserted just before yet.

tables and justified output

The following part is not really easy at first, but this vanishes as soon as you grok the system. Have fun learning these...

~xt 

where x is an integer, at which position the current table column should start.

~< ... ~>

In between these the amount of spaces gets adjusted to be evenly distributed.

:@

Make the columns being adjusted right.

~x

x is an integer, and this describes the complete size of a column.

~{ ... ~} 

Use these to loop through a list.

~a,b:;

Break text into parts of equal length, print a only if there are more characters than a certain amount of integers b.

Common Lisp Aliasing

posted on 2014-08-22 01:00:32

To alias a function in common lisp, i.e. to shorten the builtin function documentation to something easier to write, i.e. 'doc', do this in the lisp console:

(setf (symbol-function 'doc) #'documentation)

To make this stick, put it into either the system-wide initfile, or the user one. So either into $SBCL_HOME/sbclrc (if this does not exist, try /etc/sbclrc), or $HOME/.sbclrc.

Another alternative would be to create a new lisp image, but YMMV.

Scripting in Common Lisp

posted on 2014-06-15 16:41:05

To use Common Lisp for scripts, there exist two approaches, depending on the common lisp implementation you use. The approaches for SBCL and CCL will be shown here, as these seem to be the most widely used ones.

  1. Either create an executable file just like you would for a bash script, and set to the shebang accordingly.
  2. Or create a sh script with an exec line, which in turn will call your lisp file, as a wrapper.
  3. You could as well just create a compiled executable.

on approach 1: SBCL / Steel Bank Common Lisp

The first one will work with SBCL / Steel Bank Common Lisp and some others, but not all implementations:

#!/usr/local/bin/sbcl --script

It's just the path to the executable binary, followed by the --script parameter. This line is put at the top of the executable file containing your common lisp code.

on approach 2: CCL / Clozure Common Lisp

touch run-lisp
chmod a+x run-lisp
vim run-lisp

Wrapper file content:

#!/bin/sh
ccl64 --no-init --terminal-encoding utf-8 --load $1.lisp --eval '(ccl:quit)'

Save, quit.

Put the wrapper somewhere where it will be referenced via the $PATH variable, so you can call it from everywhere.

The wrapper will then be called for running the lisp file in question via run-lisp </path/to/script>/<scriptname>.<ext>.

I.e. run-lisp ./helloworld.lisp.

on approach 3: create an self-sustained executable in SBCL

;; Make an executable Lisp image.  Execute with ./lisp-image
(save-lisp-and-die #p"lisp-image" :executable t)

More on this can be found here.

Blogging with Coleslaw

posted on 2013-10-14 10:34:44

Coleslaw is one of many static site generators and creates static HTML pages. It uses Common Lisp in the backend. In my case markdown is used as the post format. This post will cover issues I encountered during install and initial usage. My Server is running a headless CentOS 6 install.

As of October 2013 the SBCL version in the yum repo's is 1.0.38. When trying to run coleslaw a error occurs due to the cl-fad lib. Installing it via Quicklisp fails. As of SBCL 1.0.44 the missing functionality seems to be included: enhancement: new function: SB-EXT:DELETE-DIRECTORY is now provided.

I recall all this from memory. So I am not completely sure this was the line in question. Since latest version at the moment is 1.1.12, this does not matter much. Except for others encountering similar errors and finding this via google. :)

How to install the newest SBCL version and getting Quicklisp up and running, is already covered here.

Now first a description how my coleslaw setup works and what technologies are used, in case troubleshooting is needed later on. The blog runs on a hosted vserver, stored in a git repository served by gitolite (eventually gitlab will be put to use). Once changes are pushed into the git repo, via a post-receive hook the lisp code for converting the markdown posts is triggered. The .html files are copied to another folder which is served over an apache web server.

Posts have have the following structure, this is taken from this one here:

;;;;;
title: Blogging with Coleslaw
tags: coleslaw,sbcl,common lisp,lisp
date: 2013-10-14 10:34:44
format: md
;;;;;
Coleslaw is one of [many static site generators] (http://staticsitegenerators.net/) and creates ...

For convenience reasons posts have filenames like: 003-installing.coleslaw.post

Indicating content and having a prepended number for easier editing. The .post extension is needed. Posts are the only files that reside in the blogging repository that is checked out onto my client workstation. All conversion code is loaded via Quicklisp, no need to set anything up besides what will be covered here. To phrase it differently, in your blog repository NO additional directory structure is needed for post organization, NO additional code is needed. Things just work. I.e. this is what resides in my cloned repo called blog currently:

[sjas@lorelei ~/work/blog]% ls
_test.post.sample
001-first.post.post
002-installing.sbcl.post
003-installing.coleslaw.post

It will not be disclosed how long just this took me to find out about the non-existant directory structure. :)

On the server the repository is stored as a bare repo, nothing to take care of since gitolite will handle this by itself. Only thing to fix is the post-receive hook. Hooks in git enable bash actions to be triggered upon repository interactions. bash code to happen prior or after pushes, commits, etc. is defined in hook files. These are placed in the .git folder of the repository where they should act. Here this means, the post-receive file has to be put into /var/lib/gitolite/repositories/blog.git/hooks on the server. If it were put within the client-side repo it will not work.

In my case this is the content of the file called post-receive:

########## CONFIGURATION VALUES ##########

# TMP_GIT_CLONE _must_ match one of the following in coleslawrc:
#   * The :repo argument (for a single-site setup) _or_
#   * An alist key (for a multi-site setup)
TMP_GIT_CLONE=/var/lib/gitolite/repositories/blog.git/tmp/

# Set LISP to your preferred implementation. The following
# implementations are currently supported:
#   * sbcl
#   * ccl
LISP=sbcl

########## DON'T EDIT ANYTHING BELOW THIS LINE ##########

if cd `dirname "$0"`/..; then
GIT_REPO=`pwd`
cd $OLDPWD || exit 1
else
exit 1
fi

git clone $GIT_REPO $TMP_GIT_CLONE || exit 1

if [ $LISP = sbcl ]; then
sbcl --eval "(ql:quickload 'coleslaw)" \
--eval "(coleslaw:main \"$TMP_GIT_CLONE\")" \
--eval "(coleslaw::exit)"
elif [ $LISP = ccl ]; then
echo "(ql:quickload 'coleslaw)(coleslaw:main \"$TMP_GIT_CLONE\")(coleslaw::exit)" | ccl -b
else
exit 1
fi

rm -rf $TMP_GIT_CLONE
exit

TMP_GIT_CLONE must point to a temporal folder which is not used otherwise. This is not the folder where your repository resides, or where the html code will be pushed to. It is needed for generation purposes and will be deleted immediatly after posting.

Further on the server the .coleslawrc has to be placed in the home folder of the user being responsible for gitolite.

My .coleslawrc in /var/lib/gitolite on the server:

(:author "sjas"
 :deploy-dir "/var/www/html/sjas/blog/" ;; folder to be served
 :domain "http://blog.sjas.de"
 :feeds ("lisp")
 :plugins ((mathjax) (sitemap))
 :repo "/var/lib/gitolite/repositories/blog.git/tmp/" ;; tempfolder before stuff gets moved into DEPLOY, same as in post-receive
 :sitenav ((:url "http://blog.sjas.de/" :name "Home") 
            (:url "http://twitter.com/sjashc" :name "Twitter") 
            (:url "http://github.com/sjas" :name "Code"))
 :staging-dir "/tmp/coleslaw/"
 :title "A year and a smile."
 :theme "hyde")

Once all this is set, a virtual host entry in the apache config has to be created, maybe like this one here:

<VirtualHost blog.sjas.de:80>

    ServerName blog.sjas.de
    ServerAdmin sjas@sjas.de

    DocumentRoot /var/www/html/sjas/blog/.curr/

    <Directory />
        Options FollowSymlinks
        Order allow,deny
        allow from all
    </Directory>

    ErrorLog /var/log/blogsjas/error_log
    CustomLog /var/log/blogsjas/access common

    <IfModule mpm_itk_module>
        AssignUserId git git
    </IfModule>

</VirtualHost>

Trick here is to set the DocumentRoot pointing to the symlink .curr which is created by coleslaw.

The mpm_itk_module is an apache extension to let a vhost run under a different user. Since I have the blog und git running under the same user, I do not have to watch out for file permission errors. Last thing to note here is, I forgot to create the ErrorLog and CustomLog files. Because of that nothing was served except the apache standard page, beside all else being set up properly. Once this was fixed, things looked like this on my workstation:

[sjas@lorelei ~/work/blog]% git add -A && git commit -m "update coleslaw" && git push
[master c9a5] update coleslaw
 3 files changed, 11 insertions(+), 2 deletions(-)
 delete mode 100644 .003-installing.coleslaw.post.swp
 create mode 100644 .gitignore
Counting objects: 6, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (4/4), 688 bytes, done.
Total 4 (delta 2), reused 0 (delta 0)
remote: Initialized empty Git repository in /var/lib/gitolite/repositories/blog.git/tmp/.git/
remote: This is SBCL 1.1.12.14-b2ed34b, an implementation of ANSI Common Lisp.
remote: More information about SBCL is available at <http://www.sbcl.org/>.
remote:
remote: SBCL is free software, provided as is, with absolutely no warranty.
remote: It is mostly in the public domain; some portions are provided under
remote: BSD-style licenses.  See the CREDITS and COPYING files in the
remote: distribution for more information.
remote: To load "coleslaw":
remote:   Load 1 ASDF system:
remote:     coleslaw
remote: ; Loading "coleslaw"
remote: .......................
remote: ; compiling file "/var/lib/gitolite/quicklisp/dists/quicklisp/software/coleslaw-20131003-git/plugins/mathjax.lisp" (written 12 OCT 2013 12:59:42 AM):
remote: ; compiling (DEFPACKAGE :COLESLAW-MATHJAX ...)
remote: ; compiling (IN-PACKAGE :COLESLAW-MATHJAX)
remote: ; compiling (DEFVAR *MATHJAX-HEADER* ...)
remote: ; compiling (DEFUN ENABLE ...)
remote:
remote: ; /var/lib/gitolite/quicklisp/dists/quicklisp/software/coleslaw-20131003-git/plugins/mathjax.fasl written
remote: ; compilation finished in 0:00:00.016
remote: ; compiling file "/var/lib/gitolite/quicklisp/dists/quicklisp/software/coleslaw-20131003-git/plugins/sitemap.lisp" (written 12 OCT 2013 12:59:42 AM):
remote: ; compiling (DEFPACKAGE :COLESLAW-SITEMAP ...)
remote: ; compiling (IN-PACKAGE :COLESLAW-SITEMAP)
remote: ; compiling (DEFMETHOD DEPLOY ...)
remote: ; compiling (DEFUN ENABLE ...)
remote:
remote: ; /var/lib/gitolite/quicklisp/dists/quicklisp/software/coleslaw-20131003-git/plugins/sitemap.fasl written
remote: ; compilation finished in 0:00:00.006
remote: ; cp -R /var/lib/gitolite/quicklisp/dists/quicklisp/software/coleslaw-20131003-git/themes/hyde/css .
remote: ; ln -sfn 1.html index.html
remote: ; mv /tmp/coleslaw/ /var/www/html/sjas/blog/generated/3590675951
remote: ; rm -r /var/www/html/sjas/blog/generated/3590675441/
remote: ; ln -sfn /var/www/html/sjas/blog/.curr /var/www/html/sjas/blog/.prev
remote: ; ln -sfn /var/www/html/sjas/blog/generated/3590675951 /var/www/html/sjas/blog/.curr
To git@sjas.de:blog
   e895..c9a5  master -> master
[sjas@lorelei ~/work/blog]%

And the then the software was up and running and the result is what you see here.

All this seems like an awful lot of work, but I wanted a fast, clean-looking, self-hosted blogging solution, working with git and being LISP-based for learning purposes. Other options would have been the clojure-based ones listed here and here.

This grew longer than anticipated, questions please via twitter until I get DISQUS up in here.

This blog covers .csv, .htaccess, .pfx, .vmx, /etc/crypttab, /etc/network/interfaces, /etc/sudoers, /proc, 10.04, 14.04, AS, ASA, ControlPanel, DS1054Z, GPT, HWR, Hyper-V, IPSEC, KVM, LSI, LVM, LXC, MBR, MTU, MegaCli, PHP, PKI, R, RAID, S.M.A.R.T., SNMP, SSD, SSL, TLS, TRIM, VEEAM, VMware, VServer, VirtualBox, Virtuozzo, XenServer, acpi, adaptec, algorithm, ansible, apache, apachebench, apple, arcconf, arch, architecture, areca, arping, asa, asdm, autoconf, awk, backup, bandit, bar, bash, benchmarking, binding, bitrate, blackarmor, blockdev, blowfish, bochs, bond, bonding, booknotes, bootable, bsd, btrfs, buffer, c-states, cache, caching, ccl, centos, certificate, certtool, cgdisk, cheatsheet, chrome, chroot, cisco, clamav, cli, clp, clush, cluster, coleslaw, colorscheme, common lisp, console, container, containers, controller, cron, cryptsetup, csync2, cu, cups, cygwin, d-states, database, date, db2, dcfldd, dcim, dd, debian, debug, debugger, debugging, decimal, desktop, df, dhclient, dhcp, diff, dig, display manager, dm-crypt, dmesg, dmidecode, dns, docker, dos, drivers, dtrace, dtrace4linux, du, dynamictracing, e2fsck, eBPF, ebook, efi, egrep, emacs, encoding, env, error, ess, esx, esxcli, esxi, ethtool, evil, expect, exportfs, factory reset, factory_reset, factoryreset, fail2ban, fbsd, fdisk, fedora, file, filesystem, find, fio, firewall, firmware, fish, flashrom, forensics, free, freebsd, freedos, fritzbox, fsck, fstrim, ftp, ftps, g-states, gentoo, ghostscript, git, git-filter-branch, github, gitolite, global, gnutls, gradle, grep, grml, grub, grub2, guacamole, hardware, haskell, hdd, hdparm, hellowor, hex, hexdump, history, howto, htop, htpasswd, http, httpd, https, i3, icmp, ifenslave, iftop, iis, imagemagick, imap, imaps, init, innoDB, innodb, inodes, intel, ioncube, ios, iostat, ip, iperf, iphone, ipmi, ipmitool, iproute2, ipsec, iptables, ipv6, irc, irssi, iw, iwconfig, iwlist, iwlwifi, jailbreak, jails, java, javascript, javaws, js, juniper, junit, kali, kde, kemp, kernel, keyremap, kill, kpartx, krypton, lacp, lamp, languages, ldap, ldapsearch, less, leviathan, liero, lightning, links, linux, linuxin3months, lisp, list, livedisk, lmctfy, loadbalancing, locale, log, logrotate, looback, loopback, losetup, lsblk, lsi, lsof, lsusb, lsyncd, luks, lvextend, lvm, lvm2, lvreduce, lxc, lxde, macbook, macro, magento, mailclient, mailing, mailq, manpages, markdown, mbr, mdadm, megacli, micro sd, microsoft, minicom, mkfs, mktemp, mod_pagespeed, mod_proxy, modbus, modprobe, mount, mouse, movement, mpstat, multitasking, myISAM, mysql, mysql 5.7, mysql workbench, mysqlcheck, mysqldump, nagios, nas, nat, nc, netfilter, networking, nfs, nginx, nmap, nocaps, nodejs, numberingsystem, numbers, od, onyx, opcode-cache, openVZ, openlierox, openssl, openvpn, openvswitch, openwrt, oracle linux, org-mode, os, oscilloscope, overview, parallel, parameter expansion, parted, partitioning, passwd, patch, pdf, performance, pfsense, php, php7, phpmyadmin, pi, pidgin, pidstat, pins, pkill, plesk, plugin, posix, postfix, postfixadmin, postgres, postgresql, poudriere, powershell, preview, profiling, prompt, proxmox, ps, puppet, pv, pvecm, pvresize, python, qemu, qemu-img, qm, qmrestore, quicklisp, r, racktables, raid, raspberry pi, raspberrypi, raspbian, rbpi, rdp, redhat, redirect, registry, requirements, resize2fs, rewrite, rewrites, rhel, rigol, roccat, routing, rs0485, rs232, rsync, s-states, s_client, samba, sar, sata, sbcl, scite, scp, screen, scripting, seafile, seagate, security, sed, serial, serial port, setup, sftp, sg300, shell, shopware, shortcuts, showmount, signals, slattach, slip, slow-query-log, smbclient, snmpget, snmpwalk, software RAID, software raid, softwareraid, sophos, spacemacs, spam, specification, speedport, spi, sqlite, squid, ssd, ssh, ssh-add, sshd, ssl, stats, storage, strace, stronswan, su, submodules, subzone, sudo, sudoers, sup, swaks, swap, switch, switching, synaptics, synergy, sysfs, systemd, systemtap, tar, tcpdump, tcsh, tee, telnet, terminal, terminator, testdisk, testing, throughput, tmux, todo, tomcat, top, tput, trafficshaping, ttl, tuning, tunnel, tunneling, typo3, uboot, ubuntu, ubuntu 16.04, udev, uefi, ulimit, uname, unetbootin, unit testing, upstart, uptime, usb, usbstick, utf8, utm, utm 220, ux305, vcs, vgchange, vim, vimdiff, virtualbox, virtualization, visual studio code, vlan, vmstat, vmware, vnc, vncviewer, voltage, vpn, vsphere, vzdump, w, w701, wakeonlan, wargames, web, webdav, weechat, wget, whois, wicd, wifi, windowmanager, windows, wine, wireshark, wpa, wpa_passphrase, wpa_supplicant, x11vnc, x2x, xfce, xfreerdp, xmodem, xterm, xxd, yum, zones, zsh


Unless otherwise credited all material Creative Commons License by sjas