close

(This is a repost of an old blog post of mine from Teknik.)

#common-lisp #clozure #ccl #emacs

In Emacs, evaluate:

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

It will give you this indentation style:

(if foo
  bar
  baz)

(This is a repost of an old blog post of mine from Teknik.)

#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
  • person chevron_right

    Condition constructors in Common Lisp

    Michał "phoe" Herda – Sunday, 23 December, 2018 - 12:04 edit

(This is a repost of an old blog post of mine from Teknik.)

#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

(This is a repost of an old blog post of mine from Teknik.)

#common-lisp #shitpost

CL-USER> (defclass shrug () ())
#<STANDARD-CLASS COMMON-LISP-USER::SHRUG>
CL-USER> (defmethod print-object ((object shrug) stream)
           (print-unreadable-object (object stream)
             (format stream "¯\\_(ツ)_/¯")))
#<STANDARD-METHOD COMMON-LISP:PRINT-OBJECT (SHRUG T) {1006DC7743}>
CL-USER> (make-instance 'shrug)
#<¯\_(ツ)_/¯>

Thanks to zaquest for a quick bugfix.

(This is a repost of an old blog post of mine from Teknik.)

#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.

(This is a repost of an old blog post of mine from Teknik.)

#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)

(This is a repost of an old blog post of mine from Teknik.)

#common-lisp #shitpost

I have been recently thinking about the issues inside Common Lisp library ecosystem. According to Michael Fiano, there is an issue with people who do not contribute to already existing libraries and instead create their own standard libraries that are then pulled around in all of their code. I agree with that issue and consider it serious, but I am also guilty in this case - I committed the same sin with phoe-toolbox.

One of the ideas that emerged in my mind that both terrified me and scared me to no avail at once was that I could simply change the name of my library and boom, suddenly it's canon. After all, I can name it after a famous ancient library, like Alexandria, Cesarum, Serapeum, Pergamum, Constantia already are.

And, you know, the Persian library of Ashurbanipal has a very nice vibe to its name... Or maybe Ebla, from Syria?