(blog 'phoe)

phoe's lispy nest

Stallman's greatest achievement: being boring to death

[Tags: free-software, stallman]

Today's random thought: Richard M. Stallman's greatest achievement is that he'd become absolutely and utterly boring.

Think about it for a second. He's a man who has been speaking of the same thing for thirty years - that's longer than I have been alive. Look at his conference talks - it's the same old stuff over and over. Look at his mails on the mailing groups - it's all about freedom, again, again and again. Look at the essays he'd published - it's what free software is, what is free software, what free software isn't and what isn't free software. Literally, reading several different works of his allows you to predict the course of his whole remaining literary output. It is absolutely the same repetitive stuff over and over that has been said tens of thousands of times already, in the same tone of voice as he always speaks in.

That obstinance and single-mindedness had shaped the way contemporary people think of free software. He's a persona recognizable for exactly the fact that he says the same thing everywhere, no matter when or where or who he is talking to at the moment. His views stem from a very simple principle of freedoms that software needs to give to its users, and everything else from his beliefs is a consequence of that principle. He is consistent, he doesn't disapprove of things that do not violate these principles and doesn't approve of things that do not obey them.

The fact that he had been faithful to that point of view for thirty five years and counting are a proof of what humans are capable of. Inventing a principle as free as software freedom and standing firmly to such beliefs for decades is a great showcase of the capabilities of a human mind and will, both when it comes to organizing his own life around the principles he invented, and when it comes to predicting countless consequences for people who do not follow the same of them (see /r/StallmanWasRight for a small showcase).

While I consider RMS to be outright silly in some aspects, he is a very inspiring philosopher who actually lives true to his words to the point of it being painful to look at. The thing is, he'd already attained the liberty he's speaking of.

Indent IF CCL-style

[Tags: common-lisp, clozure, ccl, emacs]

In Emacs, evaluate:

(put 'if 'common-lisp-indent-function 1)

This will give you this indentation style:

(if foo
  bar
  baz)

A minimal hello world in USOCKET

[Tags: common-lisp usocket networking]

CL-USER> (ql:quickload :usocket)
To load "usocket":
  Load 1 ASDF system:
    usocket
; Loading "usocket"
[package usocket]..........
(:USOCKET)
CL-USER> (use-package :usocket)
T
CL-USER> (defvar *server* (socket-listen "127.0.0.1" 65432))
*SERVER*
CL-USER> (defvar *client-1* (socket-connect "127.0.0.1" 65432))
*CLIENT-1*
CL-USER> (defvar *client-2* (socket-accept *server*))
*CLIENT-2*
CL-USER> (print "hello world!" (socket-stream *client-1*))
"hello world!"
CL-USER> (finish-output (socket-stream *client-1*))
NIL
CL-USER> (read-line (socket-stream *client-2*))
""
NIL
CL-USER> (socket-close *client-1*)
T
CL-USER> (socket-close *client-2*)
T
CL-USER> (socket-close *server*)
T

Condition constructors in Common Lisp

[Tags: common-lisp clos conditions]

TIL that I can do:

(define-condition my-condition () ())
(defmethod initialize-instance :after ((warning my-condition) &key)
  (print "boo"))

The works on SBCL*, CCL, ECL, ABCL, CLISP.

*You need to use MAKE-INSTANCE instead of MAKE-CONDITION to make the constructor fire on SBCL. See https://bugs.launchpad.net/sbcl/+bug/1761735

Typing parentheses the Lisp Machine way

[Tags: lisp linux]

setxkbmap -option parens:swap_brackets

Running this command swaps typing the () and [] in your X session. Upsides: you no longer need to press Shift to type parens. Downsides: getting used to it.

Via Reddit. Putting this here so I don't forget.

shrug

[Tags: common-lisp shitpost]

CL-USER> (defclass shrug () ())
#

HOWTO: Emacs + ECL on Android

[Tags: common-lisp android emacs]

  1. Download F-Droid.
  2. Download Termux from F-Droid for a sane terminal emulator with downloadable packages.
  3. Download Hacker's Keyboard from F-Droid for a sane keyboard.
  4. Run apt install build-essential clang to install the compiler backend that ECL requires.
  5. Run apt install emacs. Install spacemacs or download your favorite emacs configuration.
  6. Add the its-pointless.github.io APT repository to /etc/apt/sources.list.
  7. If you are on 64-bits, run apt install ecl. If you are on 32 bits, run apt install ecl-ext to install ecl-ext, which is a 32-bit version of ECL with threads enabled.
  8. Configure your Emacs to use ECL by (setf inferior-lisp-program "ecl").
  9. Run emacs and M-x slime.
  10. Write some Lisp code.
  11. See the screenshot below.

If the above does not work for you, please drop me a line at phoe@teknik.io and I'll fix it.


Image Text

MULTIPLE-VALUE-MAPCAR

[Tags: common-lisp]

I had a function that returned multiple values.

I wanted to iterate over it while collecting all of the values, so I avoid losing any data.

And I found out that, welp, MAPCAR only works on primary return values.

And so, with some help from #lisp on Freenode and Bike doing an actual majority of the coding work, MULTIPLE-VALUE-MAPCAR was born.

(defun multiple-value-mapcar (function &rest lists)
  (assert (not (null lists)))
  (let* ((values (loop for l = lists then (mapcar #'cdr l)
                       until (some #'endp l)
                       collecting (multiple-value-list
                                   (apply function (mapcar #'car l)))))
         (max-values (loop for vl in values maximizing (length vl)))
         (lists (make-list max-values)))
    (loop for vl in values
          do (loop for i from 0 below max-values
                   do (push (nth i vl) (nth i lists))))
    (values-list (mapcar #'nreverse lists))))

(multiple-value-mapcar #'values 
                       '(1 2 3 4) 
                       '(a b c d e f) 
                       '(:q :w :e :r :t)) 
;;=> (1 2 3 4)
;;=> (A B C D)
;;=> (:Q :W :E :R)

(let ((hash (make-hash-table))) 
  (setf (gethash 'fuck hash) t 
        (gethash 'shit hash) nil)
  (multiple-value-mapcar (rcurry #'gethash hash) 
                         '(fuck shit stack))) 
;;=> (T NIL NIL)
;;=> (T T NIL)

Common Lisp Logotypes

[Tags: common-lisp logos]

A person on GitHub asked me recently about the Common Lisp implementation logos that I have created based on the original lizard by Manfred Spiller and suggested that I put them in a blog post. Sure, here they are.