Thread #108559798
File: 98802359_p0.png (49.3 KB)
49.3 KB PNG
>Lisp is a family of programming languages with a long history and a distinctive parenthesized prefix notation. There are many dialects of Lisp, including Common Lisp, Scheme, Clojure and Elisp.
>Emacs is an extensible, customizable, self-documenting free/libre text editor and computing environment, with a Lisp interpreter at its core.
>Emacs Resources
https://gnu.org/s/emacs
https://github.com/emacs-tw/awesome-emacs
https://github.com/systemcrafters/crafted-emacs
>Learning Emacs
C-h t (Interactive Tutorial)
https://emacs-config-generator.fly.dev
https://systemcrafters.net/emacs-from-scratch
http://xahlee.info/emacs
https://emacs.tv
>Browse imageboards in Emacs Org-Mode
https://github.com/eNotchy/4g
>Emacs Distros
https://github.com/caisah/emacs.dz
>Elisp
Docs: C-h f [function] C-h v [variable] C-h k [keybinding] C-h m [mode] M-x ielm [REPL]
https://gnu.org/s/emacs/manual/eintr.html
https://gnu.org/s/emacs/manual/elisp.html
https://github.com/emacs-tw/awesome-elisp
>Common Lisp
https://lispcookbook.github.io/cl-cookbook
https://cs.cmu.edu/~dst/LispBook
https://gigamonkeys.com/book
https://lisp-docs.github.io
https://awesome-cl.com
>Scheme
https://scheme.org
https://standards.scheme.org
https://go.scheme.org/awesome
https://research.scheme.org/lambda-papers
>Clojure
https://clojure.org
https://tryclojure.org
https://clojure-doc.org
https://clojure.land
https://www.clojure-toolbox.com
https://mooc.fi/courses/2014/clojure
https://jafingerhut.github.io/cheatsheet/clojuredocs/cheatsheet-tiptip -cdocs-summary.html
>Other
https://github.com/dundalek/awesome-lisp-languages
>Guix
https://guix.gnu.org
https://nonguix.org
https://systemcrafters.net/craft-your-system-with-guix
https://futurile.net/resources/guix
https://github.com/franzos/awesome-guix
>SICP/HtDP
https://web.mit.edu/6.001/6.037/sicp.pdf
https://htdp.org
>More Lisp Resources
https://lisp.nexus
https://rentry.org/lispresources
(set! prev-bread (quote >>108486131 ))
203 RepliesView Thread
>>
>>
File: ultralisp.png (70.9 KB)
70.9 KB PNG
>>108534003
I put my scraping library up on ultralisp. I just wanted to see how hard/easy it was. (It was shockingly easy. I didn't even have to prove I was the owner of ggxx/scraper. I just had to make an account and give them a URL to my project.)
https://ultralisp.org/projects/ggxx/scraper
If you're setup to use ultralisp, you should be able to type this into the REPL.(ql:quickload :scraper)
>>
>>
>>
>>108562360
For some reason I thought ultralisp automatically pulled in things in quicklisp too, so if you distribute on quicklisp then it's also on ultralisp without having to do anything. Is that actually the case? I only use quicklisp + cloning random projects locally when I need updates or something newer than 6 months (thanks xach)
>>
>>108562871
>For some reason I thought ultralisp automatically pulled in things in quicklisp too
I don't know if that's true or not, but I have wondered to what degree they overlap. There's probably something one could type into the REPL to figure this out, but I'm not familiar enough with the ql and ql-dist APIs.
>>
>>
>>
>>108559798
>has by far the most devoted and enthusiastic fans of any language, Rust included
>Lisp acolytes have lasted for over half a century now
Surely there has to be more use of Lisp in the future, right? Lisp fans have to become seniors and start making the choice to use Lisp eventually. Right? Right?
>>
In eshell, I found a new way to display JSON.# instead of
jq . data.json
# do
json-read-file data.json
# make it an alias
alias jrf "json-read-file \$@*"
# and use it
jrf data.json
It'd be cool if I could pipe the sexp into another command as a sexp instead of a string, but I don't know how to do that.
>>
>>108562360
One problem with quicklisp is that the releases are manual and you might get one or two releases per year.
http://blog.quicklisp.org/
=vs=
Ultralisp can release multiple times daily if it notices changes to any git repos it's tracking.
>>
>>
>>
>>
File: file.png (335.2 KB)
335.2 KB PNG
Still fukcing around with completion, I changed to 31.1 to experiment with elisp scope accurate completions via elisp-scope.el (from emacs 31.1): https://github.com/emacs-mirror/emacs/blob/master/lisp/emacs-lisp/elis p-scope.el
Had to hack together a an analyzer for defstruct so It could identify where completions where valid, and I manually defined docstrings for it just to test, but it kinda works.
>>
File: coalton-0.2.png (37.3 KB)
37.3 KB PNG
https://coalton-lang.github.io/20260312-coalton0p2/#the-future-of-coal ton
https://github.com/coalton-lang/coalton
I don't see an 0.2 tag yet. Does anyone know what they're blocked on?
>>
>>108565794
I've been following it too, the main changes, or most of what was talked about in the article, have already been applied to the master branch, it's mostly bugfixing right now that's why there's no 0.2 tag yet. But like I said, it's already there just not tagged.
He's also taken on some additional work for a non-customizable coalton specific IDE, the idea behind it is to have an ide that requires no additional setup for programming in Coalton and CL, you just install it and be done with it, to decrease onboarding time for newcomers and people that want to try it.
>>
>>
>>
>>
>>
>>108566092
Just setup quicklisp, then git-clone whatever doesn't quickload into ~/quicklisp/local-projects/ and you can quickload them like anything else, add them to asd dependencies, and so on. Works for you own projects too.
>>
>>108565794
https://github.com/coalton-lang/coalton/commit/9dc41b7c7230e540cd872f7 b04cd273e39efda80
Man he really got burned by fset
>>
>>108566092
This is actually really easy. It's just a matter of creating a symlink in ~/quicklisp/local-projects to wherever you cloned the repo.cd ~/quicklisp/local-projects
ln -s ~/path/to/cloned-project
Then from your REPL, you can say:(ql:quickload :cloned-project)
>>
>>
>>108566176
>>108566158
>>108566153
>>108566184
I see I see, thanks bros
>>
>>
File: screenshot271.png (18.9 KB)
18.9 KB PNG
>>108566225
Not just smart but also productive. And hasn't randomly rage-quit the CL ecosystem after years of molding a lot of it. (Though fare might come back if someone gives him enough money.)
>>
File: fare.png (349.7 KB)
349.7 KB PNG
>>108566319
>fare
This guy?
https://github.com/fare
>>
I've been having some fun with eshell prompts.;; https://www.emacswiki.org/emacs/EshellPrompt#h5o-4
;; replaced reduce with cl-reduce
(defun shortened-path (path max-len)
"Return a modified version of `path', replacing some components
with single characters starting from the left to try and get
the path down to `max-len'"
(let* ((components (split-string (abbreviate-file-name path) "/"))
(len (+ (1- (length components))
(cl-reduce '+ components :key 'length)))
(str ""))
(while (and (> len max-len)
(cdr components))
(setq str (concat str (if (= 0 (length (car components)))
"/"
(string (elt (car components) 0) ?/)))
len (- len (1- (length (car components))))
components (cdr components)))
(concat str (cl-reduce (lambda (a b) (concat a "/" b)) components))))
(cl-defun my/eshell-prompt-fn (&key (highlight-color "#f06543") (path-color "#e1b07e") (error-color "#edb230"))
"Return a function that defines an eshell prompt."
(lambda nil
(concat
(propertize (format-time-string "[%T] ") 'face `(:foreground ,highlight-color))
(propertize (shortened-path (eshell/pwd) 40) 'face `(:foreground ,path-color))
(propertize (format " [%d]" eshell-last-command-status) 'face (if (= 0 eshell-last-command-status)
`(:foreground ,highlight-color)
`(:foreground ,error-color)))
(propertize " λ " 'face `(:foreground ,highlight-color)))))
To try it out:;; save the original prompt in case you want to go back
(setq original-prompt-function eshell-prompt-function)
;; set new prompt
(setq eshell-prompt-function (my/eshell-prompt-fn :highlight-color "#7ebc89" :path-color "#607466" :error-color "#fe5d26"))
Play with the colors. https://coolors.co/
>>
>>
>>
>>108566092
I'll do you better than >>108566176
If you look at the ASDF manual C-h i m asdf, in chapter 4 you can find this:There are a number of different techniques for setting yourself up
with ASDF, starting from easiest to the most complex:
* Put all of your systems in one of the standard locations,
subdirectories of
* '~/common-lisp/' or
* '~/.local/share/common-lisp/source/'.
If you install software there, you don't need further
configuration.(1)
That is to say ASDF searches these directiories for asdf systems by default. So just git-clone to ~/common-lisp and then do (require 'asdf) (asdf:load-system :{system name ie the name of the .asd file})
See the manual for further instruction.
>>
File: 2026-04-09_18-08-32.png (271.5 KB)
271.5 KB PNG
>>108559798
>Browse imageboards in Emacs Org-Mode
>https://github.com/eNotchy/4g
Yotsuba & Yotsuba B themes for Emacs
https://github.com/Senka07/yotsuba-emacs-theme
>>
>>
>>108557372
> I can just use jupyter lab with a lisp backend?
Well well well
Look at this: https://github.com/yitzchak/common-lisp-jupyter
>A Common Lisp kernel for Jupyter along with a library for building Jupyter kernels, based on Maxima-Jupyter by Robert Dodier which was based on cl-jupyter by Frederic Peschanski.
>>
I came up with an eshell alias that one can use whenever you feel tempted to use a pager like less which doesn't work inside eshell. Since the eshell buffer is already scrollable, the only thing you need to do is move the cursor to the beginning of the command output and then scroll as usual.alias page "eshell-previous-prompt; eshell-next-prompt"
If you're an evil user, you might also want to switch to normal state.alias page "eshell-previous-prompt; eshell-next-prompt; evil-normal-state"
Usage:ls /usr/bin; page
# This is an alternative to `ls /usr/bin | less` .
>>
>>
I just wrote a little CL utility function that wraps pandoc. Maybe someone else will find it useful.(defun pandoc (input &key (from "html") (to "plain"))
"Convert `input' string using pandoc.
The default is to convert from html to plain(text)."
(with-input-from-string (s input)
(uiop:run-program (format nil "pandoc -f ~a -t ~a" from to) :input s :output :string)))
>>
>>108573000
Ah nice I was doing some stuff with the scraper code that was shared recently and wanted to convert it to org-mode.
I also have some stuff for those who want to test out futur.el in emacs or want some reference material on making stuff with it:
>https://github.com/gggion/futurama.el
Cleaned up some of my experiments into that repo, mainly 2 for now:
- ob-futur :: a futur-async header for elisp source blocks in org-mode. Main benefit is being able to get the callback results from futur sexps, another one is executing other elisp code asynchronously, with the caveat of not having access to current emacs context since all it does is wrap the elisp into a futur process.
>NOTE: requires ob-futur-mode to be enabled
example#+begin_src elisp :futur-async bind
(futur-elisp--funcall
(lambda ()
(let ((primes nil)
(n 2))
(while (< (length primes) 10000)
(when (cl-loop for d from 2 to (cl-isqrt n)
never (zerop (% n d)))
(push n primes))
(cl-incf n))
(format "Found %d primes, largest: %d" (length primes) (car primes)))))
#+end_src
First the sourceblock shows
>: Executing asynchronously...
then after a couple seconds the callback arrives
>: Found 10000 primes, largest: 104729
So it's useful for testing out futur code in org.
- futur-shell.el :: this is an attempt at getting the same functionality as in shell-command and async-shell-command but with futur.el, not that useful other than reference but I might expand it, still thinking about this.
>>
>>
>>
>>108575123
>MELPA
actually, via ELPA.
https://elpa.gnu.org/packages/futur.html
>>
File: file.png (146.3 KB)
146.3 KB PNG
>>108575123
>>108575131
Weird, maybe it's outdated?
futur-elisp was a rename from futur-client.el.
>>
>>108575252
Did you install futur from git?
I double checked the version on ELPA by downloading the tar ball, and it doesn't have the renamed version yet. A release was made on March 22nd, and the rename happened on March 28th.
>>
>>
>>
>>108565583
> run update one per second
I can’t wait to get my latest ‘cadr’ implementation with variadic polymorphic homomorphologies and heterogeneous set-associative transitive macros.
Why not just use npm/js if you like random shit written by internet randos continually dumped on your machine.
t. internet-rando
>>
>>
>>
File: 1768475775577098.png (33.9 KB)
33.9 KB PNG
Has anyone here used GNU Recutils? The Emacs mode for it seems pretty good. I'm thinking of using it for my goon collection.
>>
>>
>>
>>108576801
what the fuck
>Why is the logo depicting a pair of copulating turtles?
>Ask ams@gnu.org.
>What is the name of the turtles?
>They are called Fred and George. And yes, they are both male.
>Why those names?
> 16:40 <jemarch> How would you name two (paired) gay turtles?
>16:42 <someone> Fred & George?
>>
>>
File: 1750707083733449.gif (2.3 MB)
2.3 MB GIF
>>108576871
>>
>>
>>108576858
Now in v2, functions that used to return tuples will return multiple values instead, bypassing the need for a tuple explicitness. This is better imo, much of the time tuples like lists are a code smell outside of implementation details for a more meaningful data object.
>>
>>
>>108577542
>Damn, this looks exactly like what I need right now
https://www.youtube.com/watch?v=oaYSZbmc04Y
>>
File: tell-me-sir-mittens-160749.jpg (341 KB)
341 KB JPG
What's the public sentiment on Pantherx?
Anything terrible I should know about?
>>
>>
>>
>>
>>108570569
A convenient bundle:
https://github.com/Lisp-Stat/cl-jupyter-image
by:
https://lisp-stat.dev/blog/2026/03/09/getting-started/
>>
>>
>>
;; https://www.gnu.org/software/emacs/manual/html_node/eshell/Redirection .html
(info "(eshell) Redirection")
I learned about the virtual target /dev/clip the other day. Whatever that gets redirected there gets put in your systems clipboard. It's kinda handy sometimes.# Puts `uname -a` into your clipboard
uname -a > /dev/clip
# Puts `uname -a` into your clipboard without a trailing newline
s-chomp ${uname -a} > /dev/clip
The second example requires s.el to be installed.
https://github.com/magnars/s.el
>>
>>
>>
>>
File: file.png (5.5 KB)
5.5 KB PNG
(set-display-table-slot standard-display-table 4 (vector
(make-glyph-code ?⋰ 'error)
(make-glyph-code ?⋱ 'error)))
https://groups.google.com/g/gnu.emacs.help/c/4oT_T3coa6Q
>>
>>
>>
>>
>>
File: Screenshot_20260412-054958_Brave.png (530.8 KB)
530.8 KB PNG
>>108588933
It loads for me.
>>
>>
>>108588933
>>108589840
they might have blocked your ip desu since they are opting to manually root out ai scrapers instead of using glownigger cuckflare or the troony anubis
>>
How would you do this in Elisp?;; I want to turn this:
(setq input "This is some text [] more text [][] and a bit more []")
;; into this:
(setq output ("This is some text "
"[]"
" more text "
"[]"
"[]"
" and a bit more "
"[]"))
>>
File: 1376878274830.png (62.2 KB)
62.2 KB PNG
>>108590370(defun fuck (input string)
(with-temp-buffer
(insert input)
(goto-char (point-min))
(let ((len (length string))
(previous-pos (point))
(result nil))
(while (search-forward string nil t)
(push (buffer-substring-no-properties previous-pos (- (point) len))
result)
(push string result)
(setq previous-pos (point)))
(if result
(nreverse result)
(list input)))))
if you want nil instead of list of one element when there's no shit to search, modify the last if
it took me less time to write this than to find an image
>>
>>
>>
>>
>>
File: 1487632211054.png (452.2 KB)
452.2 KB PNG
>>108590533
this doesn't work on the input he provided; it gives two [] at the end
doesn't work on strings that don't have the separator either
>>108590533
you should, that's the approved way of doing text manipulation in emacs
strings are immutable, buffer text isn't
>>
>>108590491
>Do I need to master Emacs to enjoy Lisp?
On the flip side, I don't think you can master Emacs without being at least competent in Elisp. Using Emacs without learning Elisp is like moving to a foreign country without learning the language of the country.
I think Elisp competency begins with:
>Docs: C-h f [function] C-h v [variable] C-h k [keybinding] C-h m [mode] M-x ielm [REPL]
from the OP.
Learning to ask Emacs questions about itself is an important skill to develop. Some people substitute this by asking LLMs these days which does work to an extent, but it's not a complete replacement. Sometimes, you need to query the current state of your Emacs, and an LLM wouldn't be much help there. Anyway, when you start asking Emacs questions about itself, you'll find out that it can tell you a lot.
>>
>>108590370(defun string-split-with-delimiters (string separators &optional omit-empty)
(let ((acc nil)
(start 0))
(while (string-match separators string start)
(unless (and omit-empty (= start (match-beginning 0)))
(push (substring string start (match-beginning 0)) acc))
(push (substring string (match-beginning 0) (match-end 0)) acc)
(setq start (match-end 0)))
(unless (and omit-empty (= start (length string)))
(push (substring string start (length string)) acc))
(nreverse acc)))
>>
>>
>>108590370
how I woulda done it:(defun interpose (separator sequence)
(cdr (mapcan (lambda (elt) (list separator elt))
sequence)))
(defun fuck (str separator)
(thread-last
(regexp-quote separator)
(string-split str)
(interpose separator)
(seq-remove #'string-empty-p)))
(cl-assert (equal output (fuck input "[]")))
>>108590491
Clojure has very good support in VSCodium (Calva) and IntelliJ (Cursive), and okay support in neovim (Conjure)
>>
File: earth-can.jpg (199.3 KB)
199.3 KB JPG
>>108591443
>mapcan
>>
>>108590803
why prefix everything with (string-.... ...) ????
can't you just call it "split" and
(1) have it figure out whether it's a list, string, or whatever and split those?
(2) can't the "-with-delimiters" thing be replaced with optional flags/arguments?
I'm thinking that would be cleaner.
>>
>>108592147
>why prefix everything with (string-.... ...) ????
because he's using a regexp function to split a string? what kind of a question is that
>have it figure out whether it's a list, string, or whatever and split those?
that was not what op requested, it would run slower because of dispatching, and would require more code
>can't the "-with-delimiters" thing be replaced with optional flags/arguments?
he's calling it -with-delimiters because there is already a `string-split' function in emacs
>>
>>108589981
At one point the fsf was blocking 5 million IPs and ranges.
I'm pretty sure they're also getting DDoS'ed (in a plausibly-deniable way) by some big companies that have some politically or economical differences with free software.
At least one of the AI companies were getting employees to run internet slurping shit from their homes because their own IPs are permabanned.
They're still going down the chain and slowly getting the up-stream providers to block them but it takes time and obviously upstream providers don't want to do any work whatsover. I hope they start publishing the names and releasing the block lists so everyone else can use them too. win-win.
then we can implement a universal ban-list.
>>
>>108590467
>>108590553
>>108590803
>>108591443
I learned a few new things from all these different approaches. Thanks to all of you for coming up with solutions.
>>
>>
>>108593024
I've used it a few times for iteratively wrapping forms in macros, for example(defmacro my-plet* (varlist &rest body)
(declare (indent 1))
(cl-with-gensyms (success)
(named-let protect ((binding (car (last varlist)))
(rest (reverse (cons success (butlast varlist))))
(body `(prog1 ,(macroexp-progn body)
(setq ,success t))))
(pcase binding
('nil body)
(`(,var ,val ,cleanup)
(protect (car rest) (cdr rest)
`(let* ((,var ,val))
(unwind-protect
,body
(unless ,success ,@cleanup)))))
(_ (protect (car rest) (cdr rest)
(macroexp-let* (list binding) body)))))))
>>
>>
>>
File: 1755243212867525.jpg (1 MB)
1 MB JPG
>>108590370(defun f (&rest x)
(pcase x
(`(("[" "]" . ,b) "") (cons "[]" (f b "")))
(`(("[" "]" . ,b) ,c) (cons c (cons "[]" (f b ""))))
(`((,a . ,b) ,c) (f b (concat c a)))
(`(,_ "") '())
(`(,_ . ,c) c)))
(defun g (x)
(mapcar (lambda (x) (make-string 1 x)) (string-to-list x)))
(defun h (x)
(f (g x) ""))
(h "this is a test[] [] ok")
consmaxxing
>>
>want to generate an OPDS feed for my server to download books from my ereader
>calibre exists but it sucks and I don't need even a hundredth of its functionality
>look for alternatives
>they're all bad and overengineered
Alright I'll do it myself... the hardest part might be writing a script to migrate a Calibre library to it
Is Clack still the go-to HTTP server?
>>
File: guIDE_logo.png (3.2 KB)
3.2 KB PNG
Interesting.
>guIDE is a full-featured IDE for GNU Guile that runs entirely in the browser. It compiles and executes Scheme code via a Guile 3.0 WASM runtime (Emscripten + pthreads), so there's nothing to install — just open the URL and start coding.
https://guileide.dev
https://gitlab.com/superkamiguru/guile
>>
>>108590370
My humble generalization to all sequences(defun split-by-subseq (seq subseq &optional omit-subseq)
"Split SEQ using SUBSEQ as a delimiter, return the list of sub-sequences.
If OMIT-SUBSEQ is non-nil, the delimiters are omitted from the list of
split sub-sequences.
SUBSEQ cannot be an empty array; empty arrays don't have a 0th element."
(named-let iter
((s seq)
(indices (reverse
(mapcar (lambda (i) (cons i (+ i (length subseq))))
(seq-positions seq (seq-elt subseq 0)))))
splits)
(cond
;; nothing left to iterate over
((and (= (length s) 0) omit-subseq)
(seq-difference splits (list subseq)))
((= (length s) 0) splits)
((null indices) (iter nil nil (cons s splits)))
;; index is not the start of a SUBSEQ
((or (> (cdar indices) (length s))
(not (seq-set-equal-p
subseq (seq-subseq s (caar indices) (cdar indices)))))
(iter s (cdr indices) splits))
;; S ends with SUBSEQ
((= (cdar indices) (length s))
(iter (seq-subseq s 0 (caar indices))
(cdr indices)
(cons (seq-subseq s (caar indices)) splits)))
;; S contains SUBSEQ but doesn't end with it
(t
(iter (seq-subseq s 0 (caar indices))
(cdr indices)
(append (list (seq-subseq s (caar indices) (cdar indices))
(seq-subseq s (cdar indices)))
splits))))))
>>
>>108566170
FSet was innocent https://old.reddit.com/r/Common_Lisp/comments/1sk2nsl/fset_v242_champ_ bags_and_v10_of_my_book/ofw5wdg/
>>
>>
>>
>>
>>
>>
File: Screenshot_20260413-142552.Brave.png (136.2 KB)
136.2 KB PNG
>>108596089
what is it with these atrocious colors, AND the annoying theme chooser menu that follows you around everywhere.
Autismos need to work on gaining enough self-awareness to realize that from the perspective of most people, they have a very poor sense of aesthetics, and should leave this sort of design work to chatgpt.
>>
>>108594001
>Is Clack still the go-to HTTP server?
The combination of clack + woo is the most performant option by far.
https://github.com/fukamachi/woo
>>
>>
File: screenshot273.png (125.4 KB)
125.4 KB PNG
>>108596828
Mine is a nice green, no widget since I use noscript.
>>
>>108597627
That's his default light theme for that document.
https://gitlab.common-lisp.net/fset/fset/-/blob/master/Doc/Modern-CL/f set.css?ref_type=heads#L5-16 :root {
--bg: #CCDDCC;
--fg: #111111;
--link: #1a5c8a;
--link-visited:#5b3a8a;
--nav-bg: #b8ccb8;
--nav-border: #88aa88;
--code-bg: #ddeadd;
--code-border: #aaccaa;
--def-bg: #c4d8c4;
color-scheme: light;
}
>>
>>108596089
I'm trying to rebuild this documentation locally. Can anyone get this Makefile to work?
https://gitlab.common-lisp.net/fset/fset/-/blob/master/Doc/Modern-CL/M akefile?ref_type=heads
My texi2any is not happy with the content in the checked out texi files.
>>
File: dark.png (448.2 KB)
448.2 KB PNG
>>108597825
I made my own dark theme and applied it with the Stylus browser extension.:root[data-theme="dark"] {
--bg: #1c1b19;
--fg: #d8d0c0;
--link: #e08060;
--link-visited:#8a9868;
--nav-bg: #2e2d2a;
--nav-border: #c09058;
--code-bg: #222120;
--code-border: #7890a0;
--def-bg: #252422;
color-scheme: dark;
}
I based it off of these colors.
https://embertheme.com/
>>
>>
>>
>>
>>
>>108599028
>that's quite nice. More readable than gruvbox while retaining the same vibe.
I also thought it felt like a refined gruvbox. I was surprised by how much I liked the color combinations. Apparently, he used CIELAB color space to maintain a constant "Lightness" on all the colors. I started experimenting with the CIELAB color space too after that.
https://rufflewind.com/_urandom/colorpicker/
https://en.wikipedia.org/wiki/CIELAB_color_space
>>108599173
Same. I was hoping I could turn it into an info file I could read inside Emacs, but that will have to wait.
>>
>>
File: xahlee.png (1.1 MB)
1.1 MB PNG
>>108598696
>I'm going to start reading Xah's tutorial soon. What am I in for?
lots of sexp time
https://www.youtube.com/@XahLee/streams
He hasn't streamed in 2 weeks though. Is he OK?
>>
>>108596828
>>108597627
>>108597825
>>108598693
why not just use EWW
>>
>>
>>
>>108598693
>>108599028
I sent him a pull request, and he added the ember theme to his book.
https://gitlab.common-lisp.net/fset/fset/-/blob/master/Doc/Modern-CL/f set.css?ref_type=heads#L57-68
>>108599173
It turns out I had an old version of texinfo. I was on 6.8, but he was using 7.2. After using a newer version, everything worked. He also added the missing Afterword.texi.
>>
>>
>>108601186
I embraced Guix. It's nice. I've got some profiles for Lisp stuff and Emacs, and I can even make Guix compile an SBCL core with half of all Lisp packages in it, which is quite fun.
I still write everything in Common Lisp, of course. Scheme is just not that good.
>>
>>108601232
That's cool. I started on CL with SBCL but the language hasn't been updated in over 30 years. Scheme is the closest in simplicity to untyped lambda calc and is still being updated. It was the better choice for the modern day Lisp machines.
>>
>>108594351
>https://guileide.dev/try
Very nice. Impressive how it's looks better than my Emacs + Geiser setup.
>>
>>
>>
>>108601429
Implementations are free to take what they want from the revised standards. Is the modern day Lisp machine not real software? I all I write with it is real software. Algo trading programs, web apps with clientside code in Scheme with Hoot, etc.
>>108601450
Slime was cool for the introspection. Geiser works great for me.
>>
(defun sunlightp ()
(let* ((sr/sn (solar-sunrise-sunset (calendar-current-date)))
(sunrise (caar sr/sn))
(sunset (caadr sr/sn))
(time (decode-time (current-time)))
(fractional-hour (+ (float (caddr time))
(/ (float (cadr time)) 60.0))))
(< sunrise fractional-hour sunset)))
Requires calendar-longitude and calendar-latitude to be set. I was surprised at not being able to find something like this with a quick online search so enjoy.
>>
>>
>>
>>
I just spent a some time figuring out this basic use case for the CL verbose library. Basically, I wanted to log messages to stdout in a script context. (I'm not in a REPL.)
https://codeberg.org/shinmera/verbose
Inside the REPL, it was printing log messages as expected, but outside of the REPL (in a script) logging produced no output until I did something like:(v:define-pipe ()
(v:stream-faucet :output *standard-output*)
(v:level-filter :level :debug))
I'm not entirely sure, but I think this pipeline setup is done for you automatically in a REPL context but not elsewhere.
PS: It takes an unusually long time to POST a message. What happened to 4chan?
>>
>>
>>108604701
>>108604701
Not a lisp historian but I guess its unix cargo cult.
I honestly wish the Emacs (and lisp) world would try to get as far away from the unix paradigm as possible.
>>
>>
>>108604701
Emacs is only keyboard driven if you want it to be. It has first class mouse support.
I think the reason there's a keyboard centric culture around it is mostly convenience. Zmacs was a lot simpler and doing complex key combinations is easier than mouse when you get used to it
>>
>>
TIL that you can't write a recursive function with cl-flet*. When you try to recurse, the name of the function doesn't exist yet.
This works:(defun my-factorial (n)
"Calculate the factorial of N."
(cond ((<= n 1) 1)
(t (* n (my-factorial (- n 1))))))
(my-factorial 5)
This doesn't work.(cl-flet* ((flet-factorial (n)
(cond ((<= n 1) 1)
(t (* n (flet-factorial (- n 1))))))))
(flet-factorial 5))
...or am I doing something wrong with cl-flet*?
>>
>>108607219
The reason I used cl-flet* in the first place was because I wanted to define a function inside of an eshell script that didn't add a new global function to my running emacs instance. I wanted to keep some functions local to the eshell script.
>>
>>108607219
Another thing I couldn't do inside an eshell script is used named-let. It requires lexical scoping, and I have no idea how to turn on lexical scoping in an eshell script. In regular Elisp you can add a file local variable to the top of your file with:;; -*- lexical-binding: t; -*-
I don't know what would work for eshell scripts though.
>>
File: 1604904420645.png (532.7 KB)
532.7 KB PNG
>>108607219
well, you can't write a recursive function with flet in common lisp either
you should use labels, or in case of emacs lisp, cl-labels. it even tells you that in the docstring
>>
>>
>>
>>108605420
That actually does make sense, I hadn't thought that Stallman might be trying to ape something other than the normal Lisp text editors.
>>108606229
>It has first class mouse support.
In the same way that vim does, sure. But it's not really "first class" by any reasonable metric. I highly recommend trying out zmacs in opengenera if you haven't.
>>
>>
>>108608465
Mouse-centric interfaces suck. Keyboard-centric interfaces also suck. An interface should go to great lengths to make both input devices as highly polished as possible.
The only reason Emacs doesn't do this is because Stallman absolutely BEEFED the core abstractions of the system. Sanity would be object-presentation-interaction forming the philosophical basis of all structure. A foundation built entirely around buffers necessitated a regression into psuedo-modal editing. The end result is pretty good compared to actual toxic waste like vim and nano, but it lives in the shadow of things like zmacs.
>unless it's specifically some kind of graphical/spatial task.
Screen editing and working GUIs are both inherently graphical and spatial tasks. Go use ed and tell me how great that experience is. No? Exactly.
>>
>>
>>
>>108607403
I looked at so many docstrings last night, but I overlooked that one. I looked at the docstring for cl-flet* and didn't look at the docstring for cl-flet which was more informative. I ended up giving cf-labels a try, and it worked perfectly. (Thanks for the tip.)
>>
>>108609287
https://www.peter-herth.de/ltk/
You really should just use racket gui or something like that though, if you don't care what lispy language you're using.
>>
>>
>>108596089
I liked this section where he compared immutable data structures from other languages.
https://fset.common-lisp.dev/Modern-CL/Top_html/Critiques-of-Other-Lib raries.html
>>
>>108609947
tk has been running responsive GUIs in tightly constrained places since the 1990s and has only gotten faster with time. if you do end up running into performance issues, it's probably a sign you're better served by an immediate mode framework. lisp is one of the best candidates for rolling your own, you're basically just walking a tree to move a cursor around and issue commands to a renderer.
>>
>>
File: 2026-04-15_13-26-45.png (726.3 KB)
726.3 KB PNG
>>108590467
I ended up using a variation on this idea. I was originally going to take a more functional approach, but my end goal (which I didn't mention) was to create a buffer with images in it, and manipulating a buffer this way felt easier than constructing a buffer from pieces. The "[]" was how pandoc rendered images when converting from html to plain text. Instead of building a data structure, I replaced the match with "" and then inserted an image into the buffer.
I'm really enjoying being able to see graphics in eshell.
>>
>>108607257
Very strange, even when lexical-binding is activated, named-let gives an error.Welcome to the Emacs shell
~ $ echo $lexical-binding
t
~ $ (named-let test nil t)
‘named-let’ requires lexical binding
~ [1] $
Maybe it's the way eshell runs Lisp forms. I'll look into it.
>>
>>108611030
Dynamic binding seems to be baked in pretty deep. eshell-do-eval is where to look and it is making all its eval calls with the lexical binding argument nil and it handles let forms by pulling apart the binding forms, evaling the valueform and doing the bindings with cl-progv before recursing. Presumably the way it recursively walks the form is what makes it a pain to convert to lexical-binding.
>>
>>108611314
>eshell-do-eval
I thought so too, but the culprit is actually eshell-exec-lisp, which is the only other function in esh-cmd.el which uses eval. Simply redefining it by adding the LEXICAL arg to its eval form fixes the problem.Welcome to the Emacs shell
~ $ (named-let test nil t)
t
~ $ cat /tmp/eshell-script
(named-let factorial ((n 10) (acc 1))
(if (<= n 1)
acc
(factorial (1- n) (* n acc))))
~ $ source /tmp/eshell-script
3628800
~ $
>>
>>108611314
It's weird how there's no popular stand-alone shell that is lisp-based. It seems like an almost ideal language for shell scripting.
The 'rc' shell from plan9 (the "scheme" to bash's "CL" implementation) is pretty rare to see in the wild.
How hard would it be to provide a stand-alone execution environment for eshell.el?
>>
>>108609968
>>108609968
>>108609968
>>108609968
https://fset.common-lisp.dev/Modern-CL/Top_html/Clojure.html
>Clojure does not have as rich a collection of map-combining operators as FSet. Clojure’s merge is like map-union, except that there is no val-fn parameter to alter the behavior that pairs from the right operand shadow those from the left. So it’s less general than map-union
Author missed the existence of https://clojuredocs.org/clojure.core/merge-with
They are separate functions probably because Clojure merge can merge an arbitrary number of maps unlike fset which only takes two.
>>
>>108590370(defun my-split-string (str delim-regexp)
"Inefficient, buggy, not recommended"
(save-match-data
(let ((case-fold-search nil) ;; dunno if it does something
(delim-1st-ind (string-match delim-regexp str)))
(when delim-1st-ind
(let ((pre-match-substr (substring str
0
(match-beginning 0)))
(match-substr (substring str
(match-beginning 0)
(match-end 0)))
(post-match-substr (substring str
(match-end 0) nil)))
(if (string= "" pre-match-substr)
(cons match-substr
(my-split-string post-match-substr
delim-regexp))
(cons pre-match-substr
(cons match-substr
(my-split-string post-match-substr
delim-regexp)))))))))
(my-split-string
"This is some text [] more text [][] and a bit more []" "\\[]")
;; after c-j in scratch buffer and newlines for readability
("This is some text "
"[]"
" more text "
"[]"
"[]"
" and a bit more "
"[]")
took about a hour. i'm not a programmer, you see
>>
>>
>>
>>108611436
>the culprit is actually eshell-exec-lisp
Amazing job figuring that out. Do you think this should be communicated upstream? I feel like eshell scripts would be better off if lexical-binding were on by default.
>>
>>
>>
>>
File: cdn-cdp.png (104.1 KB)
104.1 KB PNG
I wrote some eshell commands to change to the previous and next siblings in a directory hierarchy.(defun list-directories-in-path (path)
"Return a list of directories in the given PATH."
(let ((all-files (directory-files path t))) ; Get all files with full path
(mapcar (lambda (p)
(concat p "/"))
(seq-filter #'file-directory-p ; Filter only directories
(seq-remove (lambda (dir)
(or (string= "." (file-name-nondirectory dir))
(string= ".." (file-name-nondirectory dir))))
all-files)))))
(defun next-directory (path)
(when-let* ((dirs (list-directories-in-path (concat path "../")))
(n (cl-position path dirs :test #'equal)))
(nth (+ 1 n) dirs)))
(defun prev-directory (path)
(when-let* ((dirs (list-directories-in-path (concat path "../")))
(n (cl-position path dirs :test #'equal)))
(when (> n 0)
(nth (- n 1) dirs))))
(defun eshell/cdn ()
"cd $next in same hierarchy"
(if-let ((next (next-directory default-directory)))
(progn (cd next)
nil)
(message "No next directory.")))
(defun eshell/cdp ()
"cd $previous in same hierarchy"
(if-let ((prev (prev-directory default-directory)))
(progn (cd prev)
nil)
(message "No prev directory.")))
>>
>>
>>
File: uhh.png (239.7 KB)
239.7 KB PNG
>>108605420
>I honestly wish the Emacs (and lisp) world would try to get as far away from the unix paradigm as possible.
I was never a Unix hater, but this post reminded me of the Unix Hater's Handbook which I enjoyed reading back in the day.
https://web.mit.edu/~simsong/www/ugh.pdf
How well has this book stood the test of time? I feel like the Unix ecosystem has improved a lot since the writing of this book. Unix might not be perfect, but it is resilient.
>>
>>108612285
any real programming language is ideal for scripting, but the point of the shell is that it prioritizes the bottom end of trivial interaction. scripting comes second, and any real programming language is better than a shell language for that.
lisp is infinitely better than most other general purpose languages for interactive usage, but its not quite as good as an explicit shell language ime. what makes a shell language good is that the grammar, evaluation and semantic model is optimized for that bottom end of trivial interaction.
>cat file1.txt file2.txt
now has to be
>cat "file1.txt" "file2.txt"
you might say, well that's not a big deal. it might not be, but it's one of the core reasons why stand-alone lisp shells aren't popular because there are other shittier languages whose grammar optimizes those quotes out. for everybody who doesn't mind, we're already using something like eshell. but we're also a tiny minority.
you might be interested in checking out tcl, which is surprisingly pleasant to use for both scripting and interaction.
>>
>>108617748
a lot of its criticisms are true but modern *nix is also tremendously improved over unix was in the 90s (and today). even back then it was very popular to install GNU stuff on a commercial unix box because it was just straight up better.
plus back then you weren't spoiled by the internet and had to rifle through manpages and docs yourself which seriously sucked ass, so there was a stronger argument to be made about the need for computer interfaces to be as intuitive as possible.
some of the complains have aged poorly though. particularly a lot of the hate wasn't about unix's implementation of a text-centric system so much as they had a bone to pick with the very concept of a text-centric system, which aged like piss.
>>
>>108618039
Just write a read macro implementing a shortened program command notation.
The real problem with Lisp shells is distinguishing between Lisp functions and Unix programs. That's why I gave up on my Lisp shell project.
>>
>>108612285
>a stand-alone execution environment for eshell.el
How would that even work?
>>108613775
I do want to send a patch but I first need to make sure that setting lexical-binding to t in eshell-mode doesn't break anything.
>>
>>108615346
I'm always impressed by the guys on here who use thread-last, so I rewrote the first function using it.(defun list-directories-in-path (path)
"Return a list of directories in the given PATH."
(thread-last
(directory-files path t)
(seq-remove (lambda (dir)
(or (string= "." (file-name-nondirectory dir))
(string= ".." (file-name-nondirectory dir)))))
(seq-filter #'file-directory-p)
(mapcar (lambda (p) (concat p "/")))))
>>
>>108617748
i remember it has a whole chapter dedicated to hating on usenet lol.
it makes a lot of good points about various technical deficits in unix. interestingly most of them were already fixed in plan 9, contemporaneous to when this book came out.
a lot of the points it makes though are mostly about ecosystem fragmentation, and that's not really caused by any of unix's problems really, just how mass adoption works when your audience are all programmers.
>>108618121
yeah you can do that, but you end up basically just reimplementing a shell language as you end up making more and more things expressible in that reader
>The real problem with Lisp shells is distinguishing between Lisp functions and Unix programs
i think there's a specific CL implementation that still lets you define an eval-hook, but otherwise it's tough yeah. when i made my own toy lisp shell my solution to this was i giving eval a "fallthrough", so if a function cell didn't exist it checked if it was a valid path to a binary and used a special apply on that, and only if that also failed was an undefined-function error sent out.
>>
>>
>>
>>
>>
File: file.png (30.1 KB)
30.1 KB PNG
>>108618371CHVN> (let ((a 0)) (asdf:map-systems (lambda (b) (declare (ignore b)) (incf a))) a)
238 (8 bits, #xEE, #o356, #b11101110)
CHVN> (length (list-all-packages))
355 (9 bits, #x163)
>>108618515
I thought the thumbnail was LLM-generated, too, but I was wrong. It's rare to see hand-drawn art in the West these days. There's a lot of hand drawn art in the UHH though:
>>108617748
>>
File: Screenshot_20260417-004717.Brave.png (263.3 KB)
263.3 KB PNG
>>108618515
well fug :DDDD
>>
>>
>>
>>
File: How one programmer's pet project changed how we think about software - 1-04-56.jpg (243 KB)
243 KB JPG
>>108618515
I just finished watching it. I knew the gist of a lot of the story from just being around all these years, but it filled in a lot of details that I wasn't privy too. I'm also happy for Rich and his retirement, and I hope he has a lot of fun creating things for years to come.
>>
I want to read ebooks and write I guess notes/annotations whatever they're called to them, flip around to my notes quickly and conveniently along with their context with the book, is there a package for that or is this one of the kind of things I have to "extend"? So like install nov and expand it's functionality?
>>
>>108619863
Look into org-noter.
https://github.com/org-noter/org-noter
https://github.com/fuxialexander/org-pdftools
>>
File: chat-with-rich.png (398.7 KB)
398.7 KB PNG
>>108618515
https://events.zoom.us/ev/Apqcp-NO_Trnb6g9nA7QbXl2E7YD3rAIk3Ur45-JNsYr Q7GrNABQ~AvQxs5XTZP6T6qdwZ3vD_Nqwst DUQECO8TYZJ7mtDrVmMm8zUfARyv4HSw
>>