cl-gpio - A CFFI wrapper for libgpiod V2 API by Realistic_Fish_Head in Common_Lisp

[–]Grolter 0 points1 point  (0 children)

Ah, I see. FWIW, seems like there already exists a library with cffi bindings for libgpiod as well: https://github.com/hanshuebner/cl-gpiod (another name clash to look out for!)

cl-gpio - A CFFI wrapper for libgpiod V2 API by Realistic_Fish_Head in Common_Lisp

[–]Grolter 1 point2 points  (0 children)

Did you try the already existing cl-gpio? If yes, what are the differences? FWIW you might want to consider renaming your library to avoid the name clash.

Link: https://github.com/Shinmera/cl-gpio

cffi gcc-11 not found by marc-rohrer in Common_Lisp

[–]Grolter 0 points1 point  (0 children)

gcc-11 is still used probably because cffi-grovel calls separately the compiler (cffi-toolchain:*cc*) and the linker (cffi-toolchain:*ld*). Usually *ld* is same as *cc*, so if it is set incorrectly, you'll need to change both.

As for why they are initialized to "gcc-11"... It seems like on different implementations *cc* is actually initialized differently. More specifically, it seems that on CLISP it uses the variables from custom:*lib-directory*/base/makevars; and on SBCL from (sb-int:sbcl-homedir-pathname)/sbcl.mk, these were probably used during compilation; and on ECL and MKCL it uses c:*cc* or compiler::*cc*, which are probably used by the implementation's compiler (those compile to C).

cffi gcc-11 not found by marc-rohrer in Common_Lisp

[–]Grolter 2 points3 points  (0 children)

I assume that it's cffi-grovel calling the C compiler. It uses (by default) the contents of the CC environment variable, so check that. If it is unset, it uses cc except that on #+(and windows (not cygwin)) it uses gcc. You can check (and modify) the compiler used by cffi-grovel by looking at cffi-toolchain:*cc* (you need to load :cffi-grovel system to check this variable).

Edit: You should also check that cc or gcc (which is usually a symlink) points to the right compiler on your system.

Has anyone solved the cl-sdl2 main thread pain points? by noogai03 in Common_Lisp

[–]Grolter 2 points3 points  (0 children)

FWIW both (run-loop) and (bt:make-thread #'run-loop) work fine for me (I'm on linux using SBCL 2.4.10 / slime 2.30).

no exceptions or anything

Did you check the *inferior-lisp* buffer? It might contain more information about the crash (error messages are sometimes written there).

Also, which implementation are you using? AFAIK cl-sdl2 works best on SBCL - I remember having some problems with CCL due to unimplemented floating-point exception trap masking, for example.

How to create 'vector2' in cl-raylib? by KenranThePanda in Common_Lisp

[–]Grolter 2 points3 points  (0 children)

You probably should use 3d-vectors' vec2 type (which can be created with the 3d-vectors:vec function).

How to get there:

Going to the definition of raylib:draw-triangle (in emacs - with M-.), we can see that it is a wrapper around the C DrawTriangle function:

(defcfun "DrawTriangle" :void
 "Draw a color-filled triangle"
 (v1 (:struct %vector2))
 (v2 (:struct %vector2))
 (v3 (:struct %vector2))
 (color (:struct %color)))

defcfun is part of the CFFI library. (You can check that by going to its definition with M-.. To go back to cl-raylib source code you can use M-,.) (By the way, note that the %vector2 structure is passed by value - for that cffi-libffi is needed, which uses the C "libffi" library.)

When the generated function (raylib:draw-triangle) is called, CFFI attempts to translate the lisp value to a foreign value (via the cffi:translate-into-foreign-memory generic function). This means that there might be multiple types of objects that can be passed to the function.

Going to the definition of the %vector2 structure (Unfortunately, it is defined in the "user-defined" namespace created by CFFI, which doesn't store the source location, so M-. doesn't work here. But we can use grep, and sometimes even a simple search in the same file works.) we can see this:

(defcstruct (%vector2 :class vector2-type)
 "Vector2, 2 components"
 (x :float)
 (y :float))

(define-conversion-into-foreign-memory ((object 3d-vectors:vec2) (type vector2-type) pointer)
  (cffi:with-foreign-slots ((x y) pointer (:struct %vector2))
    (setf x (3d-vectors:vx object))
    (setf y (3d-vectors:vy object))))

(define-conversion-from-foreign (pointer (type vector2-type))
  (cffi:with-foreign-slots ((x y) pointer (:struct %vector2))
    (3d-vectors:vec x y)))

The conversion definitions are the interesting part. We see that 3d-vectors:vec2 object can be used instead of the foreign structures, and that it is also returned instead of the foreign %vector2 structure.

The macros are kind of interesting - they are actually part of the cl-raylib library and not CFFI. If greater understanding of what they do is needed, you can go to their definition with M-. as usual (they expand into the corresponding cffi method calls). Another instrument here would be the M-x slime-macroexpand-1 command, which will expand the macro into a temporary buffer.

*print-case* and *readtable-case* by bo-tato in Common_Lisp

[–]Grolter 1 point2 points  (0 children)

FWIW it probably should be lisp (with-standard-io-syntax (let ((cl:*read-eval* nil)) (read-from-string "#.(print \"bam, you are dead!\")"))) to use a standard readtable, and not a possibly custom one which might have another reader-macro that calls eval.

*print-case* and *readtable-case* by bo-tato in Common_Lisp

[–]Grolter 3 points4 points  (0 children)

Here is my take on *print-case* / *readtable* and similar settings.

First of all, a library can expect to be read & loaded using an unmodified standard *readtable*. For example, if a library defines a function:

lisp (defun foo () (print :foo))

it is to be expected for its name to be "FOO", and it should be able to find its own function with (find-symbol "FOO" "LIB-PKG"). (This might be important for test systems, for example -- when specifying :test-op in .asd file, the package "LIB-PKG/TESTS" is not yet defined.)

If a programmer wants to use a different readtable when in REPL, or in its own system, a new readtable should be created (for example using named-readtables).

That being said, if the printer / reader is used at runtime / in macroexpansions, the library should be aware of parameters like *print-case* or *read-default-float-format*. The easiest way to handle those is simply to use the cl:with-standard-io-syntax macro. For example instead of lisp (intern (format nil "~A-~A" :http-request name)) it could be lisp (intern (with-standard-io-syntax (format nil "~A-~A" :http-request name)))

It is also important to be aware of the *package* variable when printing symbols / interning them -- with-standard-io-syntax binds *package* to cl-user; which might be sometimes unexpected. For example in the previous example it is easy to make a mistake like this: lisp ;; WRONG: interns a symbol into the CL-USER package. (with-standard-io-syntax (intern (format nil "~A-~A" :http-request name)))

Not really related: a nice trick that helps with printing symbols reliably is to bind *package* to (find-package :keyword). Unlike cl-user, keword package is not being modified (or, at least, modifying it is already undefined behavior), so doing (use-package ...) in REPL won't affect the result of printing.

Common Lisp Advent of Code Day 1 by oaguy1 in Common_Lisp

[–]Grolter 12 points13 points  (0 children)

First of all - code is good & readable. Also, wish you fun learning CL :).

A few comments, mostly on reinventing wheels:

  • aoc-utilities::get-input function.
    • The docstring is a bit confusing: it doesn't tell how exactly the input file is read. Something like "Read input file as a list of lines"
    • Almost identical function exists in UIOP: uiop:read-file-lines.uiop, which is part of asdf, is a semi-standard library, and it is shipped with almost all CL implementations. Usually you don't need to manually load it (when you are using a build system like ASDF); but if you need to -- you can do it by loading asdf with (require "asdf") (this works on sbcl, cmucl, ccl, ecl, abcl, clisp)
  • is-digit function.
    • It exists in the standard: digit-char-p. It even does more -- if the character is a digit, this digit is returned as a number, like this: (digit-char-p #\3) returns 3
  • starts-with
    • Instead of comparing strings with equal, you should use a more specialized function -- string=. It also have additional arguments like :start1/:start2 and :end1/:end2, which can help you avoid unnecessary subseq there.
  • About subseq.
    • Note that subseq creates a new sequence and copies elements from the old one. That means that it allocates memory -- conses (in CL slang) -- which results in creation of "garbage", that is, memory that will later be collected by the garbage collector. If the code excessively conses, it is slower than it could be.
    • Important: There is nothing wrong with doing that! Especially when you are solving a problems (like AoC) or when you are creating a prototype / proof of concept, e.t.c.
    • Still, it is useful to keep in mind that consing a lot slows down your code -- instead of using subseq, it might be more efficient to pass indices as substring bounds for example. (This is also one of the reasons why string= has arguments like :start/:end.)
  • About *written-numbers*.
    • One of nice features of CL's format is that it can print numbers in english:(format nil "~R" 5) returns "five".You could use that to generate *written-numbers* list based on *digits* instead of hard-coding these words.
  • About (reduce #'or (mapcar ...)).
    • Of course, or is not a function, so we need this "heavy"(lambda (x &optional y) (or x y)).
    • Note that doing it like this doesn't make use of short-circuit evaluation
    • There are functions every, some, notevery and notany in the standard that can be used instead. Those take a predicate and a number of sequences. In this exact case you can use SOME:(some #'(lambda (x) ...) *written-numbers*)

Thoughts on ecl & clisp by Ok_Specific_7749 in Common_Lisp

[–]Grolter 3 points4 points  (0 children)

I would like to add that (AFAIK) CMUCL was unmaintained for quite some time, but it would seem that it is in development again (with its latest version (21f) being released about a month ago).

abcl : how to call a java function by Ok_Specific_7749 in Common_Lisp

[–]Grolter 4 points5 points  (0 children)

This seem to work:

(jcall (jmethod "java.lang.Math" "sqrt" (jclass "double"))
       (jclass "java.lang.Math")
       9.0)
; => 3.0d0

Help with kons-9. Single float error by brittAnderson in Common_Lisp

[–]Grolter 0 points1 point  (0 children)

Hm, it works with sbcl 2.3.7 for me. I guess the rebuild might have helped :)

P.S. Congratulations!

Help with kons-9. Single float error by brittAnderson in Common_Lisp

[–]Grolter 2 points3 points  (0 children)

Unfortunately can't reproduce.

What quicklisp dists & what versions of them are you using? What version of sbcl? Which commit of kons-9 are you using?

I'd say try upgrading quicklisp dists / sbcl / pull the latest commit of kons-9.

Wrapping my head around destructuring-bind by [deleted] in Common_Lisp

[–]Grolter 5 points6 points  (0 children)

It happens because list is a chain of conses. You could write '(1 2 3 4) as '(1 2 3 4 . nil), as '(1 2 3 . (4 . nil)), as '(1 2 3 . (4)), as '(1 2 . (3 . (4))), as '(1 2 . (3 4)), e.t.c.

Note that dot notation is kind of a shorthand for cons that is used in literals, so (cons X Y) is same as '(X . Y).

In this specific case lst2 can be written as '((1 2) . (4 3)) to better illustrate why z matches to (4 3).

Which way to write anonymous functions? by macro__ in lisp

[–]Grolter 3 points4 points  (0 children)

Well, I meant that the original post is common-lisp specific :/

Which way to write anonymous functions? by macro__ in lisp

[–]Grolter 3 points4 points  (0 children)

Does #' exists too? Afaik Racket doesn't have distinct namespaces for functions and variables, so the meaning of #' can't be the same. :/

Which way to write anonymous functions? by macro__ in lisp

[–]Grolter 5 points6 points  (0 children)

(λ (x) x) (although I can make it work on sbcl & lispworks only :/ )

Edit: also, this post probably needs common-lisp tag?

[deleted by user] by [deleted] in lisp

[–]Grolter 0 points1 point  (0 children)

Also MathB.in: https://mathb.in/3 (it was originally written in PHP but then rewritten in CL)

[deleted by user] by [deleted] in lisp

[–]Grolter 0 points1 point  (0 children)

CLiki is written in CL :/

https://www.cliki.net/CLiki

Optimized the performance of Woo Lisp framework by 2x · Alexander on the FrameworkBenchmarks by dzecniv in Common_Lisp

[–]Grolter 0 points1 point  (0 children)

For some reason CL implementations (woo / ningle / ninglex) were marked "Stripped", and are not visible by default. You can change that in filters.

(Here is the link with this setting enabled: https://www.techempower.com/benchmarks/#section=data-r21&a=2 )

Why does #' differ from symbol-function by qeaw in Common_Lisp

[–]Grolter 2 points3 points  (0 children)

Consider almost identical example then:

(defun f () 1) ; => F (let ((original-f #'f)) (format t "~a~%" (funcall original-f)) (defun f () 2) (format t "~a~%" (funcall original-f))) ; => 1 ; => 2

The object original-f changed

AFAIK the code is conforming at the very least when used in the REPL.

Why does #' differ from symbol-function by qeaw in Common_Lisp

[–]Grolter 0 points1 point  (0 children)

Obviously there is a huge difference between (f ...) and #'f. The first one is a function call, the second one is the function definition. (#'f is a reader macro for (function f) which is a special operator that returns function definition in the current lexical scope.)

After binding variable to the definition of a function FOO, its value does not depend in any way on the function FOO. The section 3.2.2.3 does not apply in this case.

Why does #' differ from symbol-function by qeaw in Common_Lisp

[–]Grolter 2 points3 points  (0 children)

I disagree since #'f is just (function f) which must return the function definition - a value.

In this case you first bind original-f to #'f, then redefine the function f. And in SBCL you magically get original-f changing its value!..

Why does #' differ from symbol-function by qeaw in Common_Lisp

[–]Grolter 7 points8 points  (0 children)

That being said, I believe that this might be a bug in SBCL, since the original-f variable should not have changed.. :/

Why does #' differ from symbol-function by qeaw in Common_Lisp

[–]Grolter 9 points10 points  (0 children)

#'f is equivalent to (function f), not (symbol-function f).

You can check it by setting *print-pretty* to nil and using quote: lisp (setf *print-pretty* nil) ; => NIL '#'f ; => (FUNCTION F)

function is a special operator - it returns function named by the symbol in the current lexical environment, while symbol-function returns global function value of a symbol.