lainchan / λ
Lisp General: Save the Hard Decisions for Last
(princ tripcode) -| · 2023-08-29 15:17
This is the Lisp General, ask any and all Lisp questions here. Below is a link to the general's texts which contain many links to various books, documentation, websites, and other interesting information.
>Check the texts first:
http://verisimilitudes.net/lisp
>To foster discussion:
Which dialect do you prefer?
Do you use Emacs or a different lisp-based editor?
What was your first experience with lisp?
What have you made in lisp?
What is your favorite Lisp program?
What do you like about Lisp?
How do you think Lisp is (one of) the superior programming language(s)?
How long have you been programming in Lisp?
What are your favorite Lisp resources? Please share, preferably links!
Is Lisp your main programming language or not? Regardless, what do you primarily use it for?
What would you like to see in the Lisp general?
What was your favorite aspect of the Lisp machines?
Do you think we'll ever get something similar to the LispMs again?
What is your preferred method of documenting your code?
In the dialects that allow it, do you make many reader macros or not?
Do you use more than one dialect? What are they and which do you prefer?
What do you consider the criteria for what constitutes a Lisp to be?
What is your favorite function in your chosen dialect(s)?
How do you feel Lisp is weaker than other languages?
What is one aspect of other languages Lisp seems to ignore?
Backus · 2023-08-29 15:23
>>36956
I prefer the way it looks now.
Kay · 2023-08-29 23:51
Parallel garbage collection for SBCL
https://applied-langua.ge/~hayley/swcl-gc.pdf
>We describe a parallel garbage collector which we are implementing
>for Steel Bank Common Lisp. The collector reclaims memory and
>allows for bump allocation without the collector needing to move
>objects, using a mark-region heap based on Immix [8]. The heap is
>comprised of pages, and pages are comprised of lines. We exploit
>the design of Immix in two ways: (i) generations are implemented
>without the collector moving objects or recording the generation
>in each object, by associating generations with lines; and (ii) con-
>servative root finding is implemented by updating an object map
>only on demand, based on recording runs of contiguously allocated
>objects. The parallel garbage collector using one core usually is
>slower than the copying collector of SBCL, outperforms copying
>with two cores, and continues to scale with more cores.
Bobby Newmark · 2023-08-29 23:54
Really unfortunate placement of linebreaks there
>We describe a parallel garbage collector which we are implementing for Steel Bank Common Lisp. The collector reclaims memory and allows for bump allocation without the collector needing to move objects, using a mark-region heap based on Immix [8]. The heap is comprised of pages, and pages are comprised of lines. We exploit the design of Immix in two ways: (i) generations are implemented without the collector moving objects or recording the generation in each object, by associating generations with lines; and (ii) con-servative root finding is implemented by updating an object map only on demand, based on recording runs of contiguously allocated objects. The parallel garbage collector using one core usually is slower than the copying collector of SBCL, outperforms copying with two cores, and continues to scale with more cores.
Milner · 2023-08-30 07:43
>>36947
>WWW. It's just broken.
Broken how? Pls Explain.
Drifter · 2023-08-30 12:29
>>36971
Look into Project Xanadu, of which the WWW is a bastardization lacking features. Put simply, Project Xanadu is an idea for hypertext that properly uses the capabilities of computers, whereas the WWW is hypertext with the same basic kinds of constraints as paper. The WWW is ugly in idea and implementation. HTTP is a textual protocol with misspelled words. In theory, it's weak, and, in practice, this weakness is nicely tied up in inhuman complexity that effectively leaves Google as its arbiter. It is like kicking dead whales down the beach.
James K · 2023-08-30 13:22
>>36976
>look into Xanadu
Done that and it looks stupid and insane. It can't be a good idea if it took 40 years to get close to an implementation, and it doesn't seem to solve any of the actual issues with the modern web. Link stability is nice, but it seems thoroughly impractical – archiving the entire internet was probably a much simpler proposition in 1960.
>Google
So you wouldn't need Google on Xanadu? How would people search for things then? You could implement a page-rank algorithm for it at a protocol level (basically already done through bi-directional links), but then you'd just have Google. It would have all the same vulnerabilities as Google with the nice bonus that ads aren't even needed since you can directly charge for clickbait.
What are your actual issues with WWW? Because this post just spills a load of soykaf without saying much of anything. Apparently WWW is weak, ugly, misspelled, and like kicking dead whales down a beach. I don't understand what any of that means with respect to hypertext protocols.
Armitage · 2023-08-30 15:01
>>36976
You can listen to and even appreciate Ted Nelson, but you don't have to guzzle his Kool-Aid
>>36977
>Done that and it looks stupid and insane. It can't be a good idea if it took 40 years to get close to an implementation, and it doesn't seem to solve any of the actual issues with the modern web.
I suspect so much of this is to do with Mr Dolphin fuarrrker himself. He is a deranged bridge-burner who is mad that he was not appointed grand dictator of the global information infrastructure.
If his vision would've been fulfilled, it'd find some way to be fuarrrked up. Does anyone remember that he expected money transactions to be built into Xanadu? That is a good bullet dodged.
Don't get me wrong... I wish we had some Xanadu. In my free time I've even tried to figure out what a Xanadu network should look like. Alas, he's too protective of his trademark so nobody else can make their own, just him and his lazy team who jerk off all day to their prototypes.
The way he speaks about looking past limits is moving at least. You would expect him to have mastered the pitch after 40 years of all talk.
⍕ · 2023-08-30 21:58
>>36976
xanadu is a centralized system, unlike WWW which is ostensibly decentralized yet relies on a lot of centralized things
you cannot have real bidirectional links without a centralized database & centralized authentication
xanadu would never have allowed the brief period of genuineness & utility WWW had before the corpos and govt tightened their grip
by the centralized nature of it everything would've been suffocated the moment it became substantial
Zuse · 2023-09-01 09:02
>>36981
> you cannot have real bidirectional links without a centralized database & centralized authentication
Not that lainon, however I believe this is not true. Although a lot of blockchain work are memes, there have been advancement in heterogeneous consensus. Meaning that many parties can verify subsets of states. If we take it to this example, we could for example have many parties with overlapping verification verify both sides, thus ensuring both are up, and anyone can join at any round. Thus there are good ways for maintaing real bidirectional links with some kind of consensus mechanism. All that we really need is a distributed operating system, and this idea can be quite common place
DEBUG-CONTENTS · 2023-09-01 10:31
>>36981
>you cannot have real bidirectional links without a centralized database & centralized authentication
see magnet links for a practical counter-example
James K · 2023-09-01 11:06
>>36994
How are these bi-directional? You certainly could use DHTs to create a bi-directional linking system, but in an actual Xanadu implementation any kind of distribution without federation would be totally impractical. You need some way to limit who can publish to the network otherwise some smart guy in advertising will create an advert that links to every site on the network causing them all to back-link to this piece of content. The original job of Google is essentially to outsmart people doing stuff like that, and a few billion dollars later, they essentially gave up on it. I don't think it's a solvable problem (without manual curation).
I think Xanadu only makes sense in a centralised context. I suspect it was originally intended to be centralised. When you look at their 17 rules, a distinction is made between servers and service providers. I'm guessing they modelled their ideas on academic journals. A "journal" would be a service provider. You would submit your document to them and it would be stored on their servers if they chose to accept it.
I don't believe it was ever intended to be more than that, given the original design happened before anyone understood the eventual scale of the internet. The design and requirements of a set of academic journals are quite different from those of the internet as a whole.
Tequila · 2023-09-01 12:11
>>36977
>Done that and it looks stupid and insane.
Explain.
>It can't be a good idea if it took 40 years to get close to an implementation
This is fallacious reasoning similar to how UNIX is justified.
>and it doesn't seem to solve any of the actual issues with the modern web.
Ignore link stability, and there are still desirable elements. The WWW features only heavy-handed and retarded transclusion, as an example. Even a centralized cesspit like Wikipedia doesn't take advantage of any of these things, because the WWW well prevents it.
>How would people search for things then?
Perhaps a search engine is a bad interface.
>What are your actual issues with WWW?
It's disgustingly complicated and choking the rest of the Internet, which is enough for me. I fuarrrking hate using a WWW browser for so many things. It's a continuation of the worse-is-better disease; the WWW and JavaScript are a continuation of the same bad attitude we see with UNIX and the C language.
I still don't have a Memex, the hypothetical device which inspired Project Xanadu, and bad computers are most of the blame, alongside the copyright cartels.
>>36981
>xanadu is a centralized system
Internet money was also a centralized system, until it wasn't. The ingredients for something better are already here.
>>36995
>You need some way to limit who can publish to the network otherwise some smart guy in advertising will create an advert that links to every site on the network causing them all to back-link to this piece of content.
I dislike the solution, but proof-of-work seems to be the only known solution to preventing such in decentralized systems, by associating a cost with what would otherwise be free.
renames · 2023-09-01 14:14
>>36997
>It's disgustingly complicated and choking the rest of the Internet, which is enough for me. I fuarrrking hate using a WWW browser for so many things. It's a continuation of the worse-is-better disease; the WWW and JavaScript are a continuation of the same bad attitude we see with UNIX and the C language.
As if Xanadu was purpose-made to never be misused, and it's usage would have never changed over time! Undoubtedly if Xanadu underwent similar uses the web did (otherwise it wouldn't be the same thing), it too would have had endless feature creep which turn it into something it was never intended to be, and you'd still be here complaining about it. This is just how things go.
James K · 2023-09-01 14:25
>>36997
>proof-of-work seems to be the only known solution to preventing such in decentralized systems
You'd have to charge per link in this case, but at that point the linking system is entirely separate from the actual content delivery which could still be free (or at least as low cost as hosting a torrent). At this point, you have to wonder why you wouldn't just offer this back-linking feature through some kind of separate service on top of the existing web. You've basically just re-invented Google at that point. A decentralised and hugely inefficient version of Google.
>Explain.
It's asking for an incredibly complicated distributed system which involves a whole bunch of weird payments and clunky UI when I just want to read documents. I've never been reading something and wanted all the stuff it links to appear next to it, and I don't have the space on my laptop/phone screen to do that comfortably anyhow. Archiving the entire internet for free just isn't going to happen and they are insane to think you could distribute it. Requiring every piece of content be addressed by a hash would be the final nail in the coffin for readable links to things and would inevitably result in a bunch of difficult to spot phishing links. We already have a system for naming academic papers and it works fine. Xanadu also suggests that people can have an internet account with access controls. WTF does that mean? Who would I make an account with? I'll obviously have to give them my bank account details as well if they are going to charge me royalties for hyperlinks. I can see nothing of actual use in any of this.
>features only heavy-handed and retarded transclusion
This isn't really a good feature. Most websites don't need it, and those that do can just do can just wrap a quote with an "a" tag then have some information pop-up on hover. If users want parallel documents they can just click on the soykaf they wanna see and open it in a new tab. I don't see what having other documents appear and disappear along the sides of the page does, and those weird text highlights are distracting.
>Perhaps a search engine is a bad interface.
People still need to search for things. Type the thing you want and it shows up is pretty much the best interface you can do for that.
>It's disgustingly complicated
Xanadu is worse.
>JavaScript bad
At some point, after using a good amount of JavaScript, you have to realise that this isn't true. You are looking at all the bad software written in JavaScript and assuming that makes JS bad when all it really means is that JS is popular.
>I hate having to use a browser
The browser does its job very well. You can't blame it for the the stuff people have put on the internet.
>It's a continuation of the worse-is-better disease
But it actually is better than Xanadu. In fact, WWW is basically the best solution to the problem. There's nothing saying that all WWW documents have to be HTML, so we are really just talking about URLs and HTTP which are both pretty great all things considered. Many of the issues with Unix stem from its need to be portable, and plain-text is one of the unfortunate results of doing that. It doesn't make sense for a consumer operating system, but it really is the best thing for the web where you have no guarantee of client capabilities. HTTP is a fine protocol for transmitting this text and URLs are a good way of addressing it.
Changing to Xanadu would not fix the issues you have with the internet. Using a Xanadu browser to visit a bunch of crappy XanaduScript websites would be even worse than the JS ones you visit now. It would only fix a bunch of non-issues which don't really affect you. What web haters completely ignore is that the HTML stack is actually very good for creating websites. For all the pointless misfeatures of Xanadu, I think digital paper is all anyone ever wanted. I would like to be proven wrong here, but I just fail to grasp what the point of Xanadu is, even if you are ignoring all of the massive impracticalities of it.
藤原純一 · 2023-09-01 15:24
>>36998
>As if Xanadu was purpose-made to never be misused, and it's usage would have never changed over time!
That's a fair retort. Still, some systems are undoubtedly harder to misuse than others, by way of making such misuse harder to express.
>This is just how things go.
I don't accept this conclusion. We use Lisp, which has largely avoided the hordes of idiots and evil men destroying beautiful things.
>>36999
>A decentralised and hugely inefficient version of Google.
Decentralization almost implies inefficiency, when compared to centralized systems.
>I've never been reading something and wanted all the stuff it links to appear next to it, and I don't have the space on my laptop/phone screen to do that comfortably anyhow.
Yes, advertisements are much better, right?
>Requiring every piece of content be addressed by a hash would be the final nail in the coffin for readable links to things and would inevitably result in a bunch of difficult to spot phishing links.
Readable links are overrated, and phishing exists primarily because of our horrible computers. Referring to things by hash digest is a reasonable solution to the problem.
>At some point, after using a good amount of JavaScript, you have to realise that this isn't true.
JavaScript is a C-flavoured ALGOL clone, which alone makes it bad. Watching idiots use it as a data format makes it even worse.
>In fact, WWW is basically the best solution to the problem.
Oh, a terminal patient.
HTTP is the textual protocol with misspelled words. It is like kicking dead whales down the beach, but at least watching Google tear it to shreds is funny.
>You can't blame it for the the stuff people have put on the internet.
I can blame the Ouroboros for eating itself.
There's no such thing as plain text. Unicode and UTF-8 are a separate but related can of worms.
Perhaps we should make a separate thread for this conversation by now.
Joey · 2023-09-01 16:09
>>36999
>For all the pointless misfeatures of Xanadu, I think digital paper is all anyone ever wanted. I would like to be proven wrong here, but I just fail to grasp what the point of Xanadu is, even if you are ignoring all of the massive impracticalities of it.
Ted Nelson himself says that visible connection or parallelism is "the remaining radical concept of Xanadu" in Xanadu Basics 1a. So there you have it, the whole point of Xanadu.
Church · 2023-09-01 16:46
>>37000
>misspelled words
That's your beef against HTTP? Ortography? lame.
Nice trips, by the way.
James K · 2023-09-01 23:53
>>37002
>the remaining radical concept of Xanadu
And it's not very radical and not very good to the point it's not worth discussing.
>>37000
>We use Lisp, which has largely avoided the hordes of idiots and evil men destroying beautiful things.
By being unpopular.
>decentralisation is what you said it was
>false dichotomy about adverts
>phishing is just because computers are bad
>JavaScript is bad because it's like C and ALGOL (t. hasn't used JS or C)
>HTTP is bad and I still won't justify myself
>plain text isn't real
Amazing that you think this qualifies as a response to anything I've said.
>Perhaps we should make a separate thread for this conversation by now.
No. I think the conversation is over.
Leto Atreides I · 2023-09-04 09:13
I want to learn Clojure as my first lisp, but I recently saw that something like half of all clojure devs use emacs - however I know nothing about emacs and don't know where to begin learning it and configuring it. I'm a vim user and tried the vanilla keybindings but it just felt so odd. I want to learn emacs and start using it as my IDE but don't really know where to start. I can't even get a <10 line configuration working to support vim keys that is how lost I am.
Neo · 2023-09-04 12:20
>>37037
>I want to learn emacs and start using it as my IDE
Easy. Go through the tutorial (I recommend you install the GUI version of GNU Emacs). Then build your config incrementally by adding stuff that you need. You want to install at least these packages: SLY/Geiser/Cider/Company/rainbow-delimiters (probably also elfeed). You said you want vim keybindings? Then your options are to use Doom Emacs or just vanilla GNU Emacs + evil-mode.
If you choose to use vanilla GNU Emacs, install evil-mode package (M-x list-packages and type C-h m) and after you have installed evil-mode package, you need to follow the instructions from evil ReadMe file. So, add the following to your .emacs file:
(require 'evil)
(evil-mode 1) Your .emacs could look something like this: >>36382 (just add the evil-mode lines from above). Don't delete the lines there that Emacs automatically generates (append these changes to the .emacs file).
Also try:
M-x customize
M-x customize-group
M-x customize-themes
C-h ?
H.R. Giger · 2023-09-04 17:46
>>37041
Very informative and quick response, thank you so much this is just the pointer I needed!
HELIOS · 2023-09-08 04:51
I was trying to think about ways to test more and I realized that I could check desired properties on the output directly. For example, a common description of what it means to be sorted is that the output is a permutation of the input and that the output has elements in increasing order. Here's some code that implements permutation? increasing? sorted? and sort. Thoughts on this idea?
;public domain
;the output of a sorting procedure is a permutation of the input
;the output of a sorting procedure has elements in increasing order
(define (print . args) (for-each display args))
(define (foldl proc initial-value list)
(let rec ((list list) (acc initial-value))
(cond
((null? list) acc)
((pair? list) (rec (cdr list) (proc acc (car list)))))))
;(print
; (foldl
; (lambda (acc right-elem) (print right-elem " ") (+ acc right-elem))
; 0
; '(1 2 3))
; "\n") ;=> 1 2 3 6
(define empty-set '())
(define (in-set? elem set)
(foldl
(lambda (acc right-elem) (or acc (equal? elem right-elem)))
#f
set))
;(print (in-set? 5 '()) "\n") ;=> #f
;(print (in-set? 5 '(4 5 6)) "\n") ;=> #t
;(print (in-set? 5 '(4 6)) "\n") ;=> #f
(define (set-insert elem set) (if (in-set? elem set) set (cons elem set)))
(define (list->set list)
(foldl
(lambda (acc right-elem) (set-insert right-elem acc))
empty-set
list))
;(print (list->set '()) "\n") ;=> ()
;(print (list->set '(1)) "\n") ;=> (1)
;(print (list->set '(2 1)) "\n") ;=> (1 2)
;(print (list->set '(1 2 3 2)) "\n") ;=> (3 2 1)
(define (set-size set) (length set))
(define (set-map proc set) (map proc set))
(define (set-maximum set) (apply max set))
;A permutation has the same length, has the same unique elements, and has the
;same amount of each unique element.
(define (permutation? input-integers output-integers)
;compare list lengths
(define (same-length? list1 list2) (= (length list1) (length list2)))
;(print (same-length? '(1 2) '(3)) "\n") ;=> #f
;(print (same-length? '(1 2) '(3 4)) "\n") ;=> #t
(define (same-unique-elements? list1 list2)
(define (all-elements-of-first-set-in-second-set? set1 set2)
(foldl
(lambda (acc right-elem) (and acc (in-set? right-elem set2)))
#t
set1))
(let ((set1 (list->set list1))
(set2 (list->set list2)))
(and (all-elements-of-first-set-in-second-set? set1 set2)
(all-elements-of-first-set-in-second-set? set2 set1))))
;(print (same-unique-elements? (list->set '()) (list->set '())) "\n") ;=> #t
;(print (same-unique-elements? (list->set '(1)) (list->set '(1))) "\n") ;=> #t
;(print (same-unique-elements? (list->set '(1)) (list->set '(2))) "\n") ;=> #f
;(print (same-unique-elements? (list->set '(1 3 2)) (list->set '(1 2 3))) "\n") ;=> #t
;(print (same-unique-elements? (list->set '(1 2 3 2)) (list->set '(1 2 3))) "\n") ;=> #t
(define (same-amount-of-each-unique-element? list1 list2)
;count the number of times an element is in a list
(define (count-elem elem list)
(apply + (map (lambda (x) (if (= x elem) 1 0)) list)))
;(print (count-elem 5 '()) "\n") ;=> 0
;(print (count-elem 5 '(1 2 3 4)) "\n") ;=> 0
;(print (count-elem 5 '(1 2 3 4 5)) "\n") ;=> 1
;(print (count-elem 5 '(1 2 3 5 4 5)) "\n") ;=> 2
;make an alist mapping each unique element to its count
(define (make-unique-elem-to-count list)
(set-map
(lambda (set-elem) (cons set-elem (count-elem set-elem list)))
(list->set list)))
(define (get-unique-count unique-elem unique-elem-to-count)
(let ((pair (assoc unique-elem unique-elem-to-count)))
(if (equal? pair #f) 0 (cdr pair))))
;check for every pair if it has the same unique count
(let ((alist1 (make-unique-elem-to-count list1))
(alist2 (make-unique-elem-to-count list2)))
(foldl
(lambda (acc pair)
(let ((unique-elem (car pair))
(unique-count (cdr pair)))
(and acc (= unique-count (get-unique-count unique-elem alist2)))))
#t
alist1))
)
;(print (same-amount-of-each-unique-element? '(1 2 3) '(1 3 2)) "\n")
;(print (same-amount-of-each-unique-element? '(1 2 3) '(1 2 3 2)) "\n")
(and
(same-length? input-integers output-integers)
(same-unique-elements? input-integers output-integers)
(same-amount-of-each-unique-element? input-integers output-integers))
)
;(print (permutation? '() '()) "\n") ;=> #t
;(print (permutation? '(1) '(1)) "\n") ;=> #t
;(print (permutation? '(1) '(2)) "\n") ;=> #f
;(print (permutation? '(1 2 3) '(1 2 3)) "\n") ;=> #t
;(print (permutation? '(1 2 3) '(1 3 2)) "\n") ;=> #t
;(print (permutation? '(1 2 3) '(1 3 2 2)) "\n") ;=> #f
;If there's a first element then make the initial set have an element smaller
;than it by subtracting 1 from the first element.
(define (increasing? integers)
;For a list to be in increasing order every current element should be greater
;than or equal to everything in the set of elements that came before the
;current element.
(define (greater-than-or-equal-to-before? elem set)
;the empty set case is considered vacuously true
(if (equal? set empty-set) #t
;otherwise get the maximum of the set and compare
(>= elem (set-maximum set))))
(let rec ((integers integers) (acc empty-set))
(cond
((null? integers) #t)
((pair? integers)
(if (not (greater-than-or-equal-to-before? (car integers) acc)) #f
(rec (cdr integers) (set-insert (car integers) acc)))))))
;(print (increasing? '()) "\n") ;=> #t
;(print (increasing? '(1)) "\n") ;=> #t
;(print (increasing? '(1 3)) "\n") ;=> #t
;(print (increasing? '(3 1)) "\n") ;=> #f
;(print (increasing? '(1 2 2 3)) "\n") ;=> #t
(define (sorted? input-integers output-integers)
(and (permutation? input-integers output-integers)
(increasing? output-integers)))
(define (sort integers)
;remove the first matching element of the list
(define (remove-elem elem list)
(let rec ((list list))
(cond
((null? list) '())
((equal? (car list) elem) (cdr list))
(else (cons (car list) (rec (cdr list)))))))
(let rec ((integers integers) (acc '()))
(cond
((null? integers) (reverse acc))
((pair? integers)
(let* ((smallest (apply min integers))
(rest-of-list (remove-elem smallest integers)))
(rec rest-of-list (cons smallest acc)))))))
(define (test-sort input-list)
(let ((output-list (sort input-list)))
`(
input ,input-list
output ,output-list
sorted? ,(sorted? input-list output-list))))
(print (test-sort '()) "\n") ;=> (input () output () sorted? #t)
(print (test-sort '(1)) "\n") ;=> (input (1) output (1) sorted? #t)
(print (test-sort '(5 1)) "\n") ;=> (input (5 1) output (1 5) sorted? #t)
(print (test-sort '(3 2 1)) "\n") ;=> (input (3 2 1) output (1 2 3) sorted? #t)
(print (test-sort '(2 3 1 2)) "\n") ;=> (input (2 3 1 2) output (1 2 2 3) sorted? #t)
Miho Iwakura · 2023-09-08 04:58
>>37075
Ignore the comments:
;If there's a first element then make the initial set have an element smaller
;than it by subtracting 1 from the first element.
That was me trying to do something else and forgetting to change it.
James K · 2023-09-08 11:02
>>37075
>all-elements-of-first-set-in-second-set?
Try "subset?" instead.
>make-unique-elem-to-count
"make" procedures typically instance a new type of object. Better name would be "element-counts".
>A permutation has the same length, has the same unique elements, and has the same amount of each unique element.
You can skip the same-unique-elements? check. It is redundant given you also check same-amount-of-each-unique-element?.
>greater-than-or-equal-to-before?
Better name would be set-all->=?.
>increasing?
You don't need to do anything fancy here. Just check that each pair of integers satisfies <=. Or even just (apply <= list).
Unknown · 2023-09-08 17:33
>>37077
It's a fair point that I made increasing? more complicated than it had to be. I was too focussed on thinking about sets in regard to permutation that I didn't even notice the simple solution. Dropping the (same-unique-elements? list1 list2) check is also a good point. I ended up dropping make-unique-elem-to-count as well. Usually making more data structures helps but I think I was just overcomplicating things with the alists. I could've gone for (greater-than-or-equal-to-before? elem set) or (set-all-<=? elem set) although I'd probably do (for-all (lambda (x) (>= elem x)) (set->list set)).
Thanks for the help on the code side. The permutation? procedure is about as long as the sort procedure now which is nice. I wonder if I could keep up that 1:1 ratio for all of the code in a library and have extra checking with the predicates being what I expect the output to be.
;check if set1 is a subset of set2
(define (subset? set1 set2)
(foldl
(lambda (acc right-elem) (and acc (in-set? right-elem set2)))
#t
set1))
;(print (subset? (list->set '()) (list->set '())) "\n") ;=> #t
;(print (subset? (list->set '(1)) (list->set '())) "\n") ;=> #f
;(print (subset? (list->set '()) (list->set '(1))) "\n") ;=> #t
;(print (subset? (list->set '(1 2)) (list->set '(2 3))) "\n") ;=> #f
;(print (subset? (list->set '(1 2)) (list->set '(3 2 1))) "\n") ;=> #t
(define (set-equal? set1 set2) (and (subset? set1 set2) (subset? set2 set1)))
;(print (set-equal? (list->set '()) (list->set '())) "\n") ;=> #t
;(print (set-equal? (list->set '(1)) (list->set '())) "\n") ;=> #f
;(print (set-equal? (list->set '(1)) (list->set '(1))) "\n") ;=> #t
;(print (set-equal? (list->set '()) (list->set '(1))) "\n") ;=> #f
;(print (set-equal? (list->set '(1 2)) (list->set '(1 2))) "\n") ;=> #t
;(print (set-equal? (list->set '(1)) (list->set '(2))) "\n") ;=> #f
;(print (set-equal? (list->set '(1 2)) (list->set '(2 1))) "\n") ;=> #t
;(print (set-equal? (list->set '(1 2)) (list->set '(2 3))) "\n") ;=> #f
;A permutation has the same length and has the same amount of each unique
;element.
(define (permutation? input-integers output-integers)
;compare list lengths
(define (same-length? list1 list2) (= (length list1) (length list2)))
;(print (same-length? '(1 2) '(3)) "\n") ;=> #f
;(print (same-length? '(1 2) '(3 4)) "\n") ;=> #t
(define (same-amount-of-each-unique-element? input-integers output-integers)
;count the number of times an element is in a list
(define (count-elem elem list)
(apply + (map (lambda (x) (if (= x elem) 1 0)) list)))
;(print (count-elem 5 '()) "\n") ;=> 0
;(print (count-elem 5 '(1 2 3 4)) "\n") ;=> 0
;(print (count-elem 5 '(1 2 3 4 5)) "\n") ;=> 1
;(print (count-elem 5 '(1 2 3 5 4 5)) "\n") ;=> 2
(foldl
(lambda (acc right-elem)
(and acc
(= (count-elem right-elem input-integers)
(count-elem right-elem output-integers))))
#t
(set->list (list->set input-integers)))
)
;(print (same-amount-of-each-unique-element? '(1 2 3) '(1 3 2)) "\n") ;=> #t
;(print (same-amount-of-each-unique-element? '(1 2 3) '(1 2 3 2)) "\n") ;=> #f
(and
(same-length? input-integers output-integers)
(same-amount-of-each-unique-element? input-integers output-integers))
)
(print (permutation? '() '()) "\n") ;=> #t
(print (permutation? '(1) '(1)) "\n") ;=> #t
(print (permutation? '(1) '(2)) "\n") ;=> #f
(print (permutation? '(1 2 3) '(1 2 3)) "\n") ;=> #t
(print (permutation? '(1 2 3) '(1 3 2)) "\n") ;=> #t
(print (permutation? '(1 2 3) '(1 2 2)) "\n") ;=> #f
(print (permutation? '(1 2 2) '(1 2 3)) "\n") ;=> #f
(print (permutation? '(1 2 3) '(1 3 2 2)) "\n") ;=> #f
Dozer · 2023-09-12 18:52
How do I un-vim my brain? I'd much rather use the intended keys for emacs but the vim keys feel so comfortable after using it the last several years. I tried grinding the tutorial but feels like I'll never adapt
Judge Fang · 2023-09-12 19:27
>>37111
Adaptation is more of a priority than a skill. What I would do is instead of trying to do the whole tutorial learning features I don't care about I would skim the tutorial and write down a couple sentences describing how to do some of the new things I might actually want to do. Then whenever I was starting a long programming session I would reread those sentences to prime my brain. Then when I'm working on writing a program I can look for places to apply the new concepts. That way I could focus on building a toolset that my brain does without thinking instead of just crunching tutorial exercises without a goal.
Tequila · 2023-09-13 10:12
Hey all, I made a LISP.
Uniquely, a LISP that implements a full job control shell.
Less Uniquely, a LISP written from scratch in Rust, with novel parsing, lexing, and evaluation routines.
Even less Uniquely, a LISP that has an assload of tests across the codebase.
I am interested in what Lain thinks!
https://gitlab.com/whom/relish
Sample:
(def _batteries 'paths to batteries powering system'
(lambda ()
(let ((power-srcs-dir '/sys/class/power_supply')
(power-srcs
(split (load-to-string find /sys/class/power_supply -printf "%p ")
" "))
(pwr-list ())
(pwr-iter (pop power-srcs)))
(while (gt? (len pwr-iter) 1)
(let ((src (car pwr-iter))
(rem (cdr pwr-iter))
(match (substr? src "BAT")))
(if match
(set (q pwr-list) (cons pwr-list src))
())
(set (q pwr-iter) (pop rem))))
pwr-list)))
(def display-batteries 'display battery capacity'
(lambda ()
(let ((bat-iter (pop (_batteries)))
(display ""))
(while (gt? (len bat-iter) 1)
(let ((bat (car bat-iter))
(rem (cdr bat-iter))
(b-perc (load-to-string head -c -1 (concat bat "/capacity")))
(b-cap-raw (load-to-string head -c -1 (concat bat "/energy_full")))
(b-cap (div (int b-cap-raw) 1000000)))
(set (q display) (concat display "[" b-cap "Wh: " b-perc "%" "]"))
(set (q bat-iter) (pop rem))))
display)))
Zhora · 2023-09-14 06:46
>>37114
Pretty cool! Though I think implementing a sh DSL in CL (similar to https://www.tcl.tk/man/tcl/TclCmd/exec.html) is probably a more practical idea.
>Create a usable POSIX shell
You mean, one that understands Bourne shell syntax or just something you can use as login shell?
Any macros/fexprs?
Jet Black · 2023-09-14 09:16
>>37114
Interesting!
I made a quick PKGBUILD for relish (mainly interesting for Arch Linux and Artix Linux users). To build and install the package, you need to first install base and base-devel packages with pacman and then run makepkg -si in the same dir where you put the PKGBUILD.
#You can do whatever you want with this PKGBUILD. Consider this to be in Public Domain. You can remove/change the license if you want.
# Maintainer: Lain <lain@localhost>
pkgname=relish
pkgver=0.3.0
pkgrel=1
pkgdesc="Rusty Expressive LIsp SHell (beta)"
arch=('x86_64')
url="https://gitlab.com/whom/relish"
license=('GPL')
#depends=('rust') #not needed, since we already include rust in makedepends.
makedepends=('git' 'rust' 'cargo')
#checkdepends=()
#optdepends=()
options=('!lto' '!strip')
source=("${pkgname}-${pkgver}.tar.gz::https://gitlab.com/whom/${pkgname}/-/archive/v${pkgver}/${pkgname}-v${pkgver}.tar.gz")
sha256sums=("5a0785e475b587f0755a27b8021d514a54ba45d348f3722649ef103e6c86ff0f")
#validpgpkeys=()
build() {
cd "$pkgname-v$pkgver"
cargo build
}
check() {
cd "$pkgname-v$pkgver"
cargo test
}
package() {
cd "$pkgname-v$pkgver"
#install -D -m755 "target/release/relish" "$pkgdir/usr/bin/relish"
install -D -m755 "target/debug/relish" "$pkgdir/usr/bin/relish"
#TODO: install the snippets/userlib.rls file somewhere where relish can see it (probably under /usr/relish dir?)
#if it's not supposed to be installed, add a .INSTALL file that tells about its existence upon installation.
} You need to also generate .SRCINFO file before you can submit this to the AUR: https://wiki.archlinux.org/title/.SRCINFO
You can lint the PKGBUILD with namcap . Also, see https://wiki.archlinux.org/title/PKGBUILD
Elliot Alderson · 2023-09-14 09:46
>>37129
Well, my goal was to supplant bourne/shell syntax entirely.
The primary functionality I am concerned with is the foreground/background process management, command piping, and doing all the tty/pgrp management. (still some stuff left over to set up the linemode better).
I do feel you on extending CL. I was actually thinking about leveraging Clojure to do something similar. I wanted to be able to say I had done it from scratch, and to test a few interesting ideas with lexing and parsing. I have been dogfooding this at work and home for a few months now and there are a few quality of life edits I want to make, but its pretty functional.
>>37133
Thats awesome and I would love that in an MR if you feel like. (or Ill slap the rest together myself :) )
Koichiro · 2023-09-14 09:59
>>37129
> Any macros/fexprs?
I havent implemented those yet. Although, I think that they would be very easy to implement given that the function interface within the runtime allows to pass unevaluated branches of code into functions as arguments.
Its roughly how all control flow is implemented already, as well as lambda, let, etc.
Miho Iwakura · 2023-10-07 21:31
I wrote a Bencoding package in Common Lisp:
gopher://verisimilitudes.net/12023-10-07
http://verisimilitudes.net/2023-10-07
I wound up spending all of yesterday on it, and released it an hour ago. It was fun enough to write some Common Lisp again.
Turing · 2023-11-09 01:30
I've resumed an old torrent project from years ago
https://github.com/wohonajax/DHTiCL
Chan Siu Ming · 2023-11-10 06:37
Do Lisp people usually just run Lisp software from the REPL? I'm learning this language coming from a C-like background and my first thought was to just run my programs like `sbcl --script my-thing.lisp`. What does the preferred development cycle look like?
Morpheus · 2023-11-10 10:14
>>37632
Might write something out later but here's some ideas:
https://www.youtube.com/watch?v=jBBS4FeY7XM
https://www.youtube.com/watch?v=HI1PHUDN5As
https://www.youtube.com/watch?v=xzTH_ZqaFKI
Iverson · 2023-11-28 02:11
Great news!
>Doug Lenat's source code for AM and EURISKO (+Traveller?) found in public archives
https://white-flame.com/am-eurisko.html
Sipho Nkosi · 2023-11-29 17:25
I have a job interview (well a few) coming up and I need to get significantly better at both Clojure and programming under stressful conditions like people watching me.
I have about 2-3 hours a day to spend on this and maybe more at weekends, with about a week until the interview.
What is the best use of my time?
Miho Iwakura · 2023-11-30 09:29
>>37769
It depends how well you know Clojure to begin with.
If you know the basics but are shakey on the intermediate stuff, try writing a program that displays a running median graphically. This isn't the hardest task on earth, but it requires a decent amount of knowledge of the language you're working with, and is about as involved as you can get within the bounds of your timeframe and assumed skill level.
DEBUG-CONTENTS · 2023-12-01 14:42
>>37770
I know it quite well but I'm aiming for a much higher position with this next job so I'm a little worried. I think the main thing is programming in an interview is stressful.
word · 2023-12-02 06:03
>>37769
Why don't you post in the AoC thread, mate?
drop · 2023-12-02 09:19
>>37788
That's a good point, I'll mix it in with the various katas and problems from exercism I've been doing. Totally forgot about it this year. Thanks!
Dujour · 2023-12-08 12:46
>>37769
I know this isn't my blog but I totally bombed the interview. I'm definitely a lot better at clojure, but the nerves got to me and I couldn't problem solve with all the adrenaline.
Still, thanks for the advice friends.
John Doe · 2023-12-08 13:21
>>37879
Don't worry too much. It's a slow thread/board.
Keep your head up, friend. If you got better this quickly you've got what it takes to grow and can do it again for the next interview. Besides, even in my hardcore capitalist opinion it's the employer's job to learn to distinguish between candidates that have potential for the role versus those that just have too much confidence. If they can't see past your irrelevant characteristics they're at least a little incompetent and you're better off at whatever next place picks you up. Keep your AoC up and don't look back at them.
Yamaoto Toshi · 2023-12-08 16:56
I'm almost done with "a gentle introduction to symbolic computation", is this book any good? Somehow I feel that I still haven't learned a lot about Lisp
Any recommended Lisp books?
Rick Deckard · 2023-12-10 04:23
>>37882
Toretsky is an introductory text mostly meant to first present functional and list programming concepts (and to an audience that knew even less about them in the 90s), as well as the lisp syntax. There are plenty of books at all intensity levels to move to after you're done with it.
(Several of these are even officially available for free, so I'd suggest googling most or all of them. Also, I know for some reason the maker intentionally excluded scheme books, so we could add those, too. I've long been meaning to redo it to include a couple but have been too lazy to get around to it.)
Moore · 2023-12-10 09:44
>>37887
Thanks, is Land of Lisp any good?
Wintermute · 2023-12-10 10:00
>>37890
Maybe, but you're considering this section Practical Common Lisp is the one to start with.
⍕ · 2023-12-10 10:29
I think I'll complete one more book before I take on SICP
I'm deciding between Land of Lisp and ANSI Common lisp
Netrunner · 2023-12-12 09:04
I have a dirty secret!
Whenever I write my own Lisp code, I write it like this
(defun foo (bar biz)
(if (eq bar biz)
1
2
)
)
rather than this
(defun foo (bar biz)
(if (eq bar biz)
1
2))
I don't know why, I just find the former so much more readable, even when I'm working in a Lisp-friendly editor.
let · 2023-12-13 15:24
>>37893
Would you not read a Scheme or a Racket book instead? + I admire the determination to slay SICP
Wirth · 2023-12-13 18:11
>>37916
One guy said that he completed SICP in common lisp after only completing practical common lisp
limited · 2023-12-14 01:14
>>37908
:o but that is just writing C!
Colmerauer · 2023-12-14 17:09
>>37918
The irony is that Lisp was one of my first languages, and I learned it prior to any language with C-style braces.
Hopper · 2023-12-15 05:42
Project to decode ogg vorbis
https://github.com/wohonajax/ogg
stack · 2023-12-16 08:55
Was tired of lambdas being so verbose, so I cobbled together a cool read macro (ANSI CL):
(defun read-λ (stream char count)
"Read a lambda form shorthand accepting _ or _# (for the #th argument, starting at 1) as
implicit lambda list positional parameters.
Some examples:
> (format t \"~@{~A~%~}\"
(quote #λ(list _))
(quote #λ(list _2 _1))
(quote #λ(list _2)))
(LAMBDA (_) (LIST _))
(LAMBDA (_2 _1) (DECLARE (IGNORE)) (LIST _2 _1))
(LAMBDA (_1 _2) (DECLARE (IGNORE _1)) (LIST _2))"
(declare (ignore char count))
(let ((body (read stream)))
(labels ((iparam-p (sym)
(let* ((str (string sym))
(len (length str)))
(and
(char= #\_ (char str 0))
(or (= len 1)
(multiple-value-bind (int pos)
(parse-integer str :start 1 :junk-allowed t)
(and int (> int 0) (= pos len)))))))
(find-iparams (obj)
(if (atom obj)
(if (and (symbolp obj) (iparam-p obj))
(list obj))
(mapcan #'find-iparams obj)))
(iparam->int (sym)
(parse-integer (string sym) :start 1))
(int->iparam (int)
(intern (concatenate 'string "_" (write-to-string int)))))
(let ((iparams (delete-duplicates (find-iparams body) :test #'eq)))
(if (find '_ iparams :test 'eq)
(progn
(assert (= (length iparams) 1)
(iparams)
"Don't mix _ and _# in #λ forms (implicit parameters found: ~{~A~^, ~})~%"
iparams)
`(lambda (_) ,body))
(loop :with ip-ints := (sort (mapcar #'iparam->int iparams) #'<)
:while ip-ints
:for i :from 1
:for arg := (int->iparam i)
:collect arg :into lambda-list
:if (= (car ip-ints) i)
:do (pop ip-ints)
:else
:collect arg :into ignore-list
:finally (return `(lambda ,lambda-list
(declare (ignore ,@ignore-list))
,body))))))))
(set-dispatch-macro-character #\# #\λ #'read-λ)
Pretty sure it's been done dozens of time and I'm just adding fuel to the Lisp curse, but I still had fun and like to build my own autistic library of utilities.
Ivan Horvat · 2023-12-16 09:38
>>37935
Whoops, just have to switch the two `:test #'eq` to `:test #'string=`, symbols aren't interned yet. Also, added a way to ignore trailing parameters:
(defun read-λ (stream char count)
"Read a lambda form shorthand accepting _ or _# (for the #th argument, starting at 1) as
implicit lambda list positional parameters.
An optional count argument can be provided before λ to force the lambda's parameter count.
Some examples:
> (format t \"~@{~A~%~}\"
(quote #λ(list _))
(quote #λ(list _2 _1))
(quote #λ(list _2))
(quote #2λ(list _1)))
(LAMBDA (_) (LIST _))
(LAMBDA (_2 _1) (DECLARE (IGNORE)) (LIST _2 _1))
(LAMBDA (_1 _2) (DECLARE (IGNORE _1)) (LIST _2))
(LAMBDA (_1 _2) (DECLARE (IGNORE _2)) (LIST _1))"
(declare (ignore char))
(let ((body (read stream)))
(labels ((iparam-p (sym)
(let* ((str (string sym))
(len (length str)))
(and
(char= #\_ (char str 0))
(or (= len 1)
(multiple-value-bind (int pos)
(parse-integer str :start 1 :junk-allowed t)
(and int (> int 0) (= pos len)))))))
(find-iparams (obj)
(if (atom obj)
(if (and (symbolp obj) (iparam-p obj))
(list obj))
(mapcan #'find-iparams obj)))
(iparam->int (sym)
(parse-integer (string sym) :start 1))
(int->iparam (int)
(intern (concatenate 'string "_" (write-to-string int)))))
(let ((iparams (delete-duplicates (find-iparams body) :test #'string=)))
(if (find '_ iparams :test #'string=)
(progn
(assert (null count)
()
"#xλ is reserved for use with numbered implicit parameters~%")
(assert (= (length iparams) 1)
(iparams)
"Don't mix _ and _# in #λ forms (implicit parameters found: ~{~A~^, ~})~%"
iparams)
`(lambda (_) ,body))
(let* ((ip-ints (sort (mapcar #'iparam->int iparams) #'<))
(last (car (last ip-ints))))
(if count
(assert (< last count)
(last count)
"When using #xλ, x (~A) must be greater than the implicit parameter count (~A)~%"
count last)
(setf count last))
(loop :for i :from 1 :to count
:for arg := (int->iparam i)
:collect arg :into lambda-list
:if (and ip-ints (= (car ip-ints) i))
:do (pop ip-ints)
:else
:collect arg :into ignore-list
:finally (return `(lambda ,lambda-list
(declare (ignore ,@ignore-list))
,body)))))))))
(set-dispatch-macro-character #\# #\λ #'read-λ)
Guthrie · 2023-12-25 10:43
>>37880
Thanks, I appreciate it.
Joe Bloggs · 2023-12-30 19:17
>>37891
I haven't read all of these, but I don't think that's the way the list is sorted. It seems to be just by section. If I was sorting them linearly, I'd guess it should be land of lisp, then successful lisp/practical common lisp, then ansi common lisp/lisp 3rd edition, though again this is just roughly. For example, lisp 3rd edition is partially an easier introduction to the language than ANSI common lisp, but is also partially a description of the AI techniques of the time, which are naturally harder to learn than just more of the language. Land of Lisp also teaches less of the language than Practical Common Lisp, but they're both language tutorials and Land of Lisp intends to go a little deeper into what you can do with its more lispy focus under its "learn with games" shtick.
John Doe · 2024-03-05 10:45
Hi, I recently made a small image editing program for a school thing. I wrote it in Common Lisp, although I don't have much prior experience in it. I'm just posting if anyone wants to take a look and critique it. It would be really appreciated.
https://gitlab.com/tvrdosrz/iip-project
In particular, if anyone has a suggestion for how to expose a C array as a vector in a way that's efficient, and at least somewhat transparent (doesn't require me to constantly do things like (setf (cffi:mem-aref data :unsigned-char (+ (* 4 i) 0)) (svref new-rgb 0)) ). As far as I can see cffi doesn't have anything like this, but racket actually does have `cvector`, and it seems like I should have just picked Racket for the project, simply because I have to depend on foreign libraries so much.
Otto Normalverbraucher · 2024-03-18 06:39
>>36967
Nice.
It's amazing how SBCL continues to improve.
Ivan Petrov · 2024-03-21 08:06
I'm designing my own Lisp dialect, mostly to address the problems I have with Common Lisp.
I'm considering adding infix operators as syntactic sugar for standard prefix expressions. For example
(print 1 + 2) would translate to
(print (add 1 2))
Would there be any unforseen consequences of this in terms of expressive power? Would I still be able to do the sort of metaprogramming that Lisp is known for? Because as far as I can tell, so long as I treat it as syntactic sugar for standard sexprs, in the same way '(1 2 3) is syntactic sugar for (quote (1 2 3)) , it should be fine.
James K · 2024-03-21 15:23
>>38601
You can represent lists in any way you like by implementing a different reader. You'll notice, however, that this can't be implemented on top of the normal lisp reader. Indeed, if you try to implement a parser for it and compare to a normal lisp reader, you'll quickly find what the difference is.
Lisp expressions are LL(1), which means the reader only needs the current token to determine what to do. So for instance, if you call read and your input contains the tokens ("(" "a" ")" . REST) the reader doesn't need to look at REST to determine what is read. In general, this means lisp languages aren't even really worth tokenising. You can just handle all you need to in READ by peeking the input stream. Formally, we would say that the language is LL(1) because you can determine which read function to invoke based only on the next token in the input stream. From the input earlier, you know that you will need to call READ-LIST (or equivalent) from just looking at the first token of input.
Adding infix expressions increases the LL (lookahead) number, so the reader needs to look at a larger number of tokens to determine which function to invoke. Suppose you again have ("(" "a" ")" . REST), you can't tell if it needs to invoke READ-LIST or READ-+ without checking a token in REST to see if it contains a "+".
The most obvious impact of this would be that the REPL becomes more ambiguous. Suppose you type "(f x)\n" into the REPL. What should happen? In ordinary lisp, it will just read and eval the input. The reader in your lisp would hang, because it would need to check the next token of input to make sure it isn't "+". I think the best solution would be to disallow allow binary expressiosn across lines unless they are surrounded by brackets and so rejects "(f x)\n + y", but accepts "(f x \n + y)". More generally, this issue is solved by adding a terminator to expressions (eg ";" in C or "\n" in Python) to guarantee that the end of an expression can always be determined because the parser knows to stop looking ahead once it reaches a terminator.
James K · 2024-03-21 16:05
>>38601
Oh, and you may be interested in Julia. It looks like Python, but has macros which expose the AST like in lisp. Fundamentally, changes in the reader don't affect the power of macros, since macros are applied to the AST after it is read. The only reason macros in some languages (C) are less powerful is because they are applied to the input tokens directly rather than the generated AST. The only issue you'd have is with reader macros, which would have to be applied prior to tokenisation and so would have to work with and return lists of tokens rather than lisp objects (or they would work peculiarly). To resolve this you even go a step further and extend the language to include macros defined as grammars applied after tokenisation, which would allow the old style of reader macros to be defined.
But if you ask me, this is all quite unnecessary. Reader macros as a whole are a mistake in my eyes. They entangle the storage format of things with their display. In my view, all lisp objects should be stored as expressions in files. Then if you want to display them in some special way, that should be implemented as a part of the editor. That way each editor can display the code as the user would like it. It also means that you would be editing the code rather than its textual representation.
Yuki Nagato · 2024-03-25 03:35
>>38601
Why does it feel you're new to Lisp? Use Julia if you want the power of modern Lisp with a retarded Python-like syntax.
Operators being treated differently than functions is an historical baggage from mathematical notation.
Someone familiar with CL would tell you the real problems to solve are the lack of recursive and parametric deftype, the ugly hash tables (no default literal, thus no proper print/read roundtrip, no key/value typing, no way to use CLOS instances as keys, etc...), the lackluster stdlib (regexp, strings, paths, etc...) cobbled over by UIOP and co., the lack of iterators or equivalent (trivial-extensible-sequences is too cumbersome) and finally the object system being external to the stdlib (which means eq/eql/equal/equalp and all the type-specific versions when we only need two).
There are hundred of other rust spots (loop -> iterate, setf expanders are black magic, non-standard gray streams, non-standard threading, non-standard pattern matching, non-standard closer-MOP, non-standard named-readtables, etc...) but well...
overriding · 2024-03-25 10:16
>>38610
>Why does it feel you're new to Lisp?
I'm not. I've been using various Lisp dialects since 2017. There's definitely people who know them better than me, but I think six plus years is a long enough time for me to grok the important parts.
>Operators being treated differently than functions is an historical baggage from mathematical notation.
I agree to an extent. Operator precedence is objectively bad. But you don't need operator precedence to have operators; just look at Smalltalk.
The reason I want infix operators is really just to cut down on parens. I like to write code out on paper, thinking of it as mathematical notation first and instructions to a computer seccond, and its kind of annoying to juggle parens with a pencil and and eraser. It's not an essential feature by any means, which is honestly why I asked to begin with. If it causes problems, I'm fine with dropping it.
I agree with you on the problems with Common Lisp, by the way. My main goals are to trim the fat, backport the things that other Lisps and similarly high-level languages do better (Scheme's approach to recursion comes to mind), and include a Python-inspired batteries-included stdlib that does all the annoying stuff for you.
Agent Jones · 2024-03-25 11:12
>>38613
>Scheme's approach to recursion comes to mind
Care to explain what you mean? Except tail recursion being mandated by the standard, I don't see anything else.
Personally, CL without the warts I mentioned (and some others like standard Unicode support that's not just storing UTF-32) would be my dream language. I would especially dislike Scheme's retardation about macros and continuations.
James K · 2024-03-25 11:57
>>38613
I also thought you were new to it, or a little clueless. I think the main reason for me is you used the word "power". There is also the operator thing in general, but I suppose many people who should know better have fallen into the trap of "what if we made lisp without the parenthesis?".
>I like to write code out on paper
I would usually do this in my head or on a computer. I've never got why you would write code on paper when you could write out the definitions for the functions you want and leave their bodies blank. What kinds of benefits do you see from that approach?
>i don't want to write the parenthesis out on paper
>so i will alter the language to not need them
Or you could just write the code on paper without the parens, and then put them in when you write it on the computer. The beauty of lisp code is that its textual format is just a representation of a tree, there is no reason why you couldn't choose a different representation more suited to the medium of paper, while sticking to the one that works well for computers when typing it in.
Lunch · 2024-03-26 03:27
>>38617
>The beauty of lisp code is that its textual format is just a representation of a tree, there is no reason why you couldn't choose a different representation more suited to the medium of paper, while sticking to the one that works well for computers when typing it in.
Also, paredit.
Bobby Newmark · 2024-03-26 09:48
>>38614
Yeah, tail recursion.
To elaborate, I wanted to yoink the looping constucts, certain names and naming conventions (it should be obvious which ones I mean if you're experienced with CL), and numeric types from Scheme.
I also wanted to include constructs for optional macro hygine that are inspired by but distinct from Scheme's.
>>38617
>>38622
At that point I might as well use C. For me, what makes Lisp special is that it lets me describe a program in a way that's shaped like the problem it's attempting to solve.
James K · 2024-03-26 13:52
>>38631
>At that point I might as well use C. For me, what makes Lisp special is that it lets me describe a program in a way that's shaped like the problem it's attempting to solve.
At what point? I don't get how either of these sentences relate to each other or the posts to which they respond. Syntax is totally unimportant, and has nothing to do with the "shape" of a program. It's all just different ways to serialise the same tree. The difference between C and lisp is much more than how they are written down.
Y.T · 2024-03-28 01:01
>>38481 Just realised I had it set to private by mistake, fixed.
John Titor · 2024-03-29 04:01
How is the => keyword pronounced in scheme?
XERXES · 2024-03-29 18:04
>>38669
i dont think scheme has a => keyword it seems to a library binding or library/implementation specific thing
id read it as to, bind/binds, matches or implies in the contexts im thinking of but it could mean more a lot.
array · 2024-03-29 19:26
>>38669
equal or greater than
Marly Krushkhova · 2024-03-29 20:00
>>38673
It's part of the cond syntax.
(cond (<test> => <recipient>))
I was hoping to find an established name like the spaceship operator in perl or the various character names in the jargon file:
http://www.catb.org/~esr/jargon/html/A/ASCII.html
I guess "goes to" will have to do.
The Plague · 2024-03-30 21:14
>>36959
>What have you made in Lisp
I mess around with it alot but the first REAL program I made was a cute little Valentine's Day program for my girlfriend at the time. She ended up breaking up with me a month later, but I guess she just didn't like Lisp. Oh well lol
John Titor · 2024-03-30 22:28
I'm disappointed lisp was never used as a better preprocessor & build system with GCC.
It would have been a huge improvement without much effort, and there were lisp fans in the FSF at the time.
Lady 3Jane.. · 2024-03-31 00:37
>>38679
>cute little Valentine's Day program
I'm intrigued, what did it do?
Unsigned · 2024-04-06 13:27
When SICP refers to space complexity of tree processes like Fibonacci numbers being n, what are they specifically referring to? The number of REPL levels needed to evaluate the process?
Linda Lee · 2024-04-13 13:03
>>37111
why don't you use DOOM Emacs/evil mode? It's basically emacs with vim keybinds.
Dox · 2024-04-16 08:17
>>38819
Pic rel is a pretty good reason.
Sadly for lisp development, all the good tools are emacs based.
James K · 2024-04-16 15:54
>>38847
>Pic rel is a pretty good reason.
Is it? Input latency is certainly relevant in things like realtime videogames where small differences in timing can be the difference between a win and a loss, but you cannot win or lose in a text editor. A latency of even 100ms while typing seems like something a normal person can simply ignore without consequence. Perhaps it makes you slower typing, but I doubt this is by any substantial amount.
Hiro Protagonist · 2024-04-17 12:02
Does anyone here have much experience with Clojure maps? I have only used them sparsely, mostly in programming challenges to familiarise myself with the language.
I am wondering how Scheme record types fit into the design of a large program with regards to two extremes: Clojure maps and CLOS classes. I find they are in an awkward middle ground where they are too structured create and handle them ad-hoc, different subtypes are distinguished by existence of keys, etc. But they also don't have the completeness and multimethods to use them in a completely structured CLOS-style where each record type represents something concrete and functionality can be easily altered and extended by dispatching based on function argument type.
How should I be dealing with hierarchical record types?
Acid Burn · 2024-05-03 23:15
>>37922
How does one end up learning Lisp as a first programming language? All introductory resources point you as far away from Lisp as possible and towards more typical languages. Could you share how you begun, lainon?
car · 2024-05-04 10:10
>>39015
I learned Lisp by searching things like "lisp declare variable", "lisp control flow", and "lisp define function". I have no guarantees that this will work for you, but it did indeed work for me.
Resources on other dynamically-typed languages like Ruby and Python also help, provided you know how to translate them into Lisp. Lisp looks somewhat alien because of its syntax, but on a moment-to-moment basis, it actually works like a fairly conventional dynamically-typed language.
Hopper · 2024-05-06 08:16
>>39015
Oh, and as an addendum to >>39026, my very first experience "programming" was hand-writing HTML and CSS (no Javascript). Coming from markup, Lisp's highly regular parenthetical syntax felt very natural to me.
Joe Bloggs · 2024-05-06 09:26
>>38857
Pretty much any disconnect slows you down to an extent, and 100ms is on the border where even normal people might start noticing overtly (rather than it being silently compensated for by the brain), even if they don't have the words to describe it. Past 100ms is where you get into systems that random people will actively describe as laggy.
but 5-20ms is basically nothing (by modern standards at least) unless you already have a lot of latency elsewhere (keyboard, screen)
James K · 2024-05-06 09:27
>>39015
Racket is famously used as an educational tool, so I imagine there are a fair few that learned it that way.
Tank · 2024-05-15 03:41
>>39026
>>39044
I phrased my question wrong. I meant, why was Lisp your first language? Typically, people who are already programmers learn about Lisp after some time and become interested in it, it's rare to find somebody who knew nothing about programming and started doing it. How did it become your first programming language?
push · 2024-05-15 12:31
Lisp Game Jam starts 2morrow
https://itch.io/jam/spring-lisp-game-jam-2024
Also In General I would just like to say that the s7 scheme ffi for notcurses is godlike for tui dev
Dox · 2024-06-14 10:37
I want to sell software to local businesses, and I would ideally like to write this software in common lisp. My main concern in this regard is platform compatibility. I understand most people in my country still use Windows, yes, even business owners are stuck in the windows era. I don't even know which version they prefer, probably the latest ones?
Does Common Lisp have libraries that are compatible with Windows? If I make an application that interfaces with a database, I imagine there would be plenty of database options for windows, but are there common lisp libraries that interface with windows libraries for such kind of software?
What about GUI stuff? I imagine windows doesn't have the GUI library hell that exists in unix, but does common lisp support the windows environment?
Thank you.
Mario Rossi · 2024-06-14 21:48
>>39336
IME most libraries that I want to use either are compatible or trivially patchable (i.e. they assume a Unix-like FS layout). The only real offenders I find are those that rely on non-portable C libraries but that isn't common in the domains I normally work.
>most people in my country still use Windows
This is true globally.
>does common lisp support the windows environment?
The language does perfectly fine, NT is much more similar to Unixes than what CL was designed around. For GUI libraries the best I've found for cross platform development are Ltk and LW CAPI. If you're selling little GUI applications then I would seriously consider LW for CAPI and the tree shaker, they're pretty generous with evaluation licenses but it is quite pricy.
Shogun · 2024-07-10 21:45
>>36959
I write python for a living but for my own projects and purposes I can't find anything better than ruby and clojure.
Much like the database I build in ruby and to use in my own projects >>22910, I have a clojure project going on which has given birth to an idea for a "rails for clojure"
where basically instead of an entire ecosystem a rails on clojure would actually mean a grokkable-in-5-minutes 50 line MVC framework whose consequences would be basically having any clojure project with this framework have similar MVC structure
https://git.lain.church/apoc/railway
thoughts, anyone?
swap · 2024-08-11 21:26
I've written a Wordle solver in Common Lisp:
http://verisimilitudes.net/2024-08-08
gopher://verisimilitudes.net/12024-08-08
Here's the SUMMARIZE implementation used:
(defun summarize (sequence &key ((:key every) 'identity) ((:test get) 'eql) ((:size length)))
"Return a hash-table summarizing the input sequence as counts of each element.
The size argument is a performance hint determining the initial size thereof.
The test argument must be a valid hash-table test: EQ, EQL, EQUAL, or EQUALP."
(let ((hash-table (apply 'make-hash-table :test get (if length `(:size ,length)))))
(map nil (lambda (elt) (incf (gethash (funcall every elt) hash-table 0))) sequence)
hash-table))
I'm reasonably pleased with it. I like the idea I had to use SUMMARIZE to improve the time complexity. Regardless, this is fairly basic code, with fairly basic error handling and everything. I'll implement the same thing in different ways using Ada and APL later.
Molly Millions · 2024-09-04 05:21
Bad news: looks like this semester is the last time SICM will be taught at MIT. From ashes to ashes, from dust to dust. https://groups.csail.mit.edu/mac/users/gjs/6946/
Faye Valentine · 2024-09-04 08:21
>>39921
Good thing the books will continue to exist.
Gyula Kovacs · 2024-09-18 13:24
Do I have to use quicklisp? How do I avoid getting MITM using it.
FILLER · 2024-09-18 16:56
>>40067
I just go to the source site for the library I want and download it from there. Usually it's GitHub, except for Edi Weitz's stuff. This only takes a few minutes; it's not the hell you might expect with Python/Java.
Case · 2024-09-18 23:10
>>40067
https://github.com/rudolfochrist/ql-https
https://github.com/fukamachi/qlot
https://github.com/ocicl/ocicl
Ender · 2024-09-19 13:11
>>40067
Just use Guix.
>https://packages.guix.gnu.org/packages/cl-mcclim/
Guix is the package manager and Guix System is the distro. You can use the Guix package manager on any GNU/Linux distro.
nil · 2024-09-19 13:47
>>40079
You need to install the old SBCL in it to use it as package manager, no? Like Nix, the external world doesn't exist.
Lukasiewicz · 2024-09-21 12:16
So, I'm diving deep inside CL anew and just "finished" a static website generator using spinneret!
https://git.sr.ht/~q3cpma/make-website which powers https://world-playground-deceit.net/
During that, I obviously added stuff to my personal utils lib. Here are some that you may find cool/useful:
Pretty explicit, a generic print-object that puts every slot on its line and align them:
(defun slot-names (class)
"Get the slot names of a class"
(mapcar #'closer-mop:slot-definition-name
(closer-mop:class-direct-slots class)))
(defun print-any-object (obj stream &key show-nil-and-unbound-p (align-p t))
"Pretty print any CLOS objects"
(print-unreadable-object (obj stream :type t)
(iter
(with snames = (slot-names (class-of obj)))
(for sname in snames)
(if (slot-boundp obj sname)
(let ((sval (slot-value obj sname)))
(when (or show-nil-and-unbound-p sval)
(collect sname into fmtargs at start)
(collect sval into fmtargs at start)
(maximize (length (princ-to-string sname)) into width)))
(when show-nil-and-unbound-p
(collect sname into fmtargs at start)
(collect "UNBOUND" into fmtargs at start)
(maximize (length (princ-to-string sname)) into width)))
(finally
(format stream (str:concat "~@<~;~{~:_~"
(if align-p (format nil "~D" width) "")
"A = ~S~}~:>")
(nreverse fmtargs))))))
Since getf is unsafe (no way to different "not found" and a nil val), I made myself this cool macro I'm starting to use a bit:
(defmacro if-prop ((var plist indicator) then &optional else)
"Conditional evaluation with property value bound to a variable if said property is to be found"
(with-gensyms ($found-p $tail $block)
`(block ,$block
(multiple-value-bind (,$found-p ,var ,$tail) (get-properties ,plist `(,,indicator))
(declare (ignore ,$tail)
(ignorable ,var)) ;; declarations in macros aren't standard, but seem to work here
(when ,$found-p
(return-from ,$block ,then)))
,else)))
Discovered define-modify-macro thanks to Alexandria, and since it's missing a few versions:
(define-modify-macro sortf (pred &rest args)
sort
"Modify-macro for SORT")
(define-modify-macro stable-sortf (pred &rest args)
sort
"Modify-macro for STABLE-SORT")
This one is more macro-flexing than something I truly needed at the time, but I had fun making it. Similar to the much more complete https://github.com/ruricolist/serapeum/blob/af8e411f2cd33a59336803ff520a59e486ea883e/types.lisp#L442
(defmacro monomorphize (type-bindings &body body)
"Dispatch body according to the successive types of forms.
Example:
(defun float-sum (a b)
(monomorphize ((a (single-float double-float))
(b (single-float double-float)))
(+ a b)))"
(destructuring-bind (form types) (pop type-bindings)
`(etypecase ,form
,@(let ((clauses))
(dolist (type types (nreverse clauses))
(push (if type-bindings
(list type `(monomorphize (,@type-bindings) ,@body))
`(,type (locally ,@body)))
clauses))))))
My secret weapon when doing Advents of Code:
(defun read-repeat (count &key (input *standard-input*) (eof-error-p t) eof-value (reader #'read))
"Read count items from input (stream or filespec) and return the collected results"
...)
(defun read-until (pred-or-val &key (input *standard-input*) (eof-error-p t) eof-value
(reader #'read) (test #'eql) (exclude-end-p nil))
"Read items from input (stream or filespec) until a predicate is satisfied or a value matched
(via :test) and return the collected results"
...)
(defun read-all (&key (input *standard-input*) (eof-error-p t) eof-value (reader #'read))
"Read items from input (stream or filespec) until EOF and return the collected results"
...) including wrappers to use with read-from-string and iterate's (for x in-file|in-stream).
And finally, the thing I'm currently the most proud of. Not because it's complicated, because the API is so nice and a strict superset of CL. Basically, do you often use the result of position/search as value for :start/:end of other sequence functions? I do, so I augmented the syntax to be able to write:
(subseq str '(:from #\a) '(:until :last "bc")) instead of
(subseq str (position #\a str) (+ 2 (search "bc" str :from-end t)) With the format being "integer or (:from|:after|:before|:until [:last] element|subseq)". I applied it to subseq and read-from-string/make-string-input-stream for now, but plan on making wrapper for all relevant functions.
Eldon Tyrell · 2024-09-25 00:51
Symbolics Genera retrospective by David Moon, author of some versions of the Chine Nual and designer of syntax-divergent dialects Dylan, PLOT, and Luna: https://archive.org/details/genera-retrospective-1991
Void · 2024-10-05 12:00
THE SUSSMAN has spoken (with Abelson and Kiczales to racketcon): https://con.racket-lang.org/
dictionary · 2024-11-08 19:11
>>38617
a Lisp without parentheses is possible if you do not support variadic arguments
James K · 2024-11-09 06:40
>>40371
>a Lisp without parentheses is possible
The trap I was describing isn't that its impossible to write a lisp without parens, but that it's a bad idea. What you describe is backwards Forth. Lisp is much better because it has parentheses. The parentheses are the best feature of lisp. That's why trying to get rid of them is a trap.
Erik Johansson · 2024-11-09 07:13
>>40371
a lisp can have any syntax really, semantics of a language are orthogonal to the syntax (mostly, the syntax adapts to its semantics)
sizeof · 2024-11-09 17:53
>>40371
You would also (from what I understand about compilation which is rather limited) either have to require early binding or not be able to compile it to very efficient machine code.
James K · 2024-11-10 07:16
>>40376
Since the top level declarations are delimited to allow for statements in the body of various lengths, you can determine the arity of functions declared in the file. Then you also have the fact that it should be possible to statically trace any variable back to the point of its binding, so you can determine its definition. Your only issue then is higher order functions. You would basically have the lisp-2 thing where you need to explicitly say you are calling a value as a function (and how many arguments it has).
It's worth noting that the special case of a global function being re-assigned a new definition with a different arity at runtime isn't an issue, since you've already parsed the code structure by that point as you would have for regular lisp.
Vasya Pupkin · 2024-11-11 03:45
>>40378
>since you've already parsed the code structure by that point
And then what do you do? Keep track of the call sites and recompile them (in which case it is early binding with special tooling for redefinitions)? What do you do when the new arity results in an invalid program, just signal an error at the last call site that impacted it (in which case it is most definitely early binding)?
Though you are probably already implementing a reverse forth as >>40372 said, in which case my comment on compiling to efficient machine code still holds.
I think the project is interesting but chasing the moniker "its lisp without parens" might not be 100% practical because then you drag along all of the baggage that comes with "lisp". Even if you are only targeting Scheme-like levels of dynamism (as it seems).
James K · 2024-11-11 05:06
>>40381
>And then what do you do?
Nothing. The same as regular lisp.
(define (f x) ...)
(define (g x) (f x))
(set! f (lambda (x y) ...)) This wouldn't recompile the program, it would just create a runtime error if the call happens. Once you've written the code, you know how many arguments a function is being called with. This never changes at runtime, unless you actually change the underlying language to work off Forth semantics. The key insight is that the new bracketless syntax changes absolutely nothing about this because it's just a syntax translation into regular lisp code, which you can do mechanically based on the definitions in a file. Nothing about the underlying lisp needs to change, in other words.
Undisclosed · 2024-11-11 07:19
>>40382
>Once you've written the code, you know how many arguments a function is being called with.
Unless the definition hasn't been loaded yet, or an older definition is still present that has a different arity.
>Nothing about the underlying lisp needs to change, in other words.
Except you require some level of "early typing" on your global definitions, call it "early arity", because it is fixed at a call site once the call site has been compiled. A consistent defining feature of lisps is late binding which certainly can't be applied here.
James K · 2024-11-11 09:34
>>40383
>because it is fixed at a call site once the call site has been compiled
What are some lisps where the number of arguments supplied in compiled code change at runtime? There are none.
>Unless the definition hasn't been loaded yet, or an older definition is still present that has a different arity.
You can scan ahead for it. The edge case of a file which has multiple definitions of the same symbol with different arities can just produce an error. I can think of no good reason for a source file to be structured like that.
This can be implemented as a pre-processor which reads bracketless files and adds brackets. It changes nothing about the language at runtime.
Miho Iwakura · 2024-11-11 10:33
>>40384
>What are some lisps where the number of arguments supplied in compiled code change at runtime? There are none.
Huh? What about variadic functions?
James K · 2024-11-11 11:15
>>40385
Arguments are the things you supply at the call site, parameters are the number of arguments a function can take.
(lambda () (f 1 2 3)) If you look at this code, there is no way to change the number of arguments on the inside of the lambda. Even if f is variadic, or is assigned to another value, the code will still call it with 3 arguments. The parameter count can change at runtime, but the argument count cannot.
Donna Hawthorne · 2024-11-11 11:38
>>40372
it is not a backwards Forth. a Forth macro can strip any number of items from its stack during execution, in the no-paren Lisp, it can only receive its arguments when called.
>>40376
I do not compile to machine code, but just use a virtual machine to run bytecode (which are just slices). I do this because the language needs to be able to trivially serialize ASTs back to code representation (in fact, every data structure in the lang can be serialized to code representation, including green threads with populated callstacks, which is how I support portable "resuming" of programs across different machine architectures).
>>40381
>>40382
>>40383
>>40384
just don't redefine a function and change its arity lmao
James K · 2024-11-11 12:13
>>40387
>it is not a backwards Forth
IDK. It looks like backwards Forth. Practically speaking, most Forth words are gonna take a fixed number of arguments. So the code is going to be identical to backwards Forth. Just put the brackets back, it's so much easier with them. All of my existing lisp tooling won't work with it.
Switch · 2024-11-11 12:40
>>40386
Actually, CL has apply (https://www.lispworks.com/documentation/HyperSpec/Body/f_apply.htm#apply) so you can't statically determine the number of arguments passed at call sites.
How would you a
James K · 2024-11-11 12:54
>>40389
>so you can't statically determine the number of arguments passed at call sites.
You don't need to. The function called is APPLY, and a version of a APPLY that takes two arguments would work just fine for all cases. You are really struggling with this idea that the brackets are added back in and the code just turns into normal lisp, and that in normal lisp, the first item of the list is a function and the number subsequent items is the number of arguments to a that function. This number doesn't change during the execution of a program because you aren't allowed to directly mutate the source code of a compiled function.
↑ · 2024-11-11 14:23
>>40390
Well, I'm not the original guy, just piped up about the number of parameter thing.
To be honest, I agree with >>40372 and really don't understand wanting to remove Lisp's parentheses, they're its best feature. It will always look like baby duck syndrome gone wrong.
The result almost looks like Tcl.
Ivan Horvat · 2024-11-11 20:42
>>40384
>There are none.
And yet all of them allow function arity to arbitrarily change, as required by late binding.
>You can scan ahead for it.
Not always. What if I haven't written the new definition yet? Are you going to rescan the whole codebase every time new code is loaded just in case a definition has been altered?
>>40387
>just don't redefine a function and change its arity lmao
In which case you're moving further away from "lisp without parens" to "lisp inspired" or perhaps just "lisp influenced".
>which are just slices
Of.. the AST?
>trivially serialize ASTs back to code representation
The immediate AST is always trivially reversible but the reversing process becomes harder and less useful once you start introducing optimisations. Why not just keep around the initial AST or code for this purpose? It would be useful for indicating errors anyway.
>which is how I support portable "resuming" of programs across different machine architectures
Would you not get that "for free" by virtue of not using an architecture specific instruction set? What purpose does producing a Human readable/editable version serve if the purpose is to save and copy the program state?
Emmanuel · 2024-11-11 21:31
>>40392
>Of.. the AST?
>his abstract syntax tree is an actual tree
>his abstract syntax tree is not hallucinated at runtime via an xWaitingForYArguments stack
>Why not just keep around the initial AST or code for this purpose?
probably a good idea.
>Would you not get that "for free" by virtue of not using an architecture specific instruction set?
you still have to pick SOME format for serialization, code just makes sense.
I think I should point out that I was drunk out of my mind while writing the lang. anyway, its most important feature is that side effects are persisted immediately, which allows for resuming of the program upon reboot after a machine crash. note that threadly communication is considered a side effect, so you can spawn a bunch of threads, make them do random things, pull the plug on the machine, reboot and reach the same most recent state.
that is what the checksum in >>40371 is for.
Haruyoshi · 2024-11-11 23:05
>>40393
>you still have to pick SOME format for serialization
Which could fairly easily be some literal format for your bytecode, no?
>his abstract syntax tree is not hallucinated at runtime via an xWaitingForYArguments stack
Now I am even less clear on your design. So you basically just have a recursive descent evaluator?
>that is what the checksum in >>40371 is for.
Do you have resilience against data corruption?
John Rain · 2024-11-11 23:37
>>40394
>Which could fairly easily be some literal format for your bytecode, no?
code is just as easy to produce, and I simply dgaf (at all) about efficiency in this case.
>Now I am even less clear on your design. So you basically just have a recursive descent evaluator?
in >>40387
the "AST" is just a vector where "assert" is a keyword pointer element, next is the "and" keyword pointer element next is another "and" keyword pointer, then "areEqual", etc. it is the literal left-to-right, top-to-bottom vector representation of code.
custom names (capitalized "Map" and such) are name types, just pointers to strings in the vector (note that type assertion is used to differentiate name-strings from normal strings).
[] indicates strings (and also allows for the nesting of strings, a very nifty feature). every data structure has a string representation, and the literal representation of every data structure beyond the string is to run a "to<type>" keyword on a string. these too are just string pointers in the vector.
"+=", "_", and other *symbolic* names are also just keywords.
so, we have a vector. to "run" it, we go left to right. first, we find assert. we know assert takes a single argument, so we add x=0 (index of assert keyword in vector) and y=1 (number of arguments assert needs) to the xWaitingForYArguments stack. we do this for and (y=2), the next and. the areEqual (y=2). and so on. when we reach immediately evaluable expressions, we decrement the y of the last-in stack item and see if it is 0. if so, we go back to the x index, run the command with its arguments, and then add its result to the next item in the stack (if applicable).
recursion is actually not able to be used at all in the implementation of the language, because that would completely fuarrrk with the ability to reload state later on. this is also why loops are so funky (with the jumpIf command and recur). a while loop (for example) necessitates extra weird state to be added to callstacks. I could probably just make these macros, but to be honest I have not gotten that far. the language is far more focused on its side effects/reloading capabilties than its Lisp capabilities.
>>40394
>Do you have resilience against data corruption?
no idea what you mean. anyway the "resilience" of the system is quite high, and its implementation is a fair bit different from what is shown in that old screenshot, but I would prefer to keep that information more discrete.
Demeere · 2024-11-12 00:34
>>40395
>it is the literal left-to-right, top-to-bottom vector representation of code.
So tokenised. I believe it is sometimes alternatively called scanned.
>recursion is actually not able to be used at all in the implementation of the language, because that would completely fuarrrk with the ability to reload state later on
Maybe not literally but what you have described is equivalent, just you are handling the call stack manually. Also what you are describing would have no problem with changing function arity because it isn't checked until use so you do truly have late binding.
>no idea what you mean
I mean if you have anything to detect or handle data corruption on disk (or even in memory) of some form. Say a malformed write or corruption due to a faulty disk, etc.
Hououin Kyouma · 2024-11-12 00:56
>>40396
>Also what you are describing would have no problem with changing function arity because it isn't checked until use so you do truly have late binding.
if you look at my definition positions in >>40387
then it should not be difficult to imagine redefining a function amidst the arguments it is waiting for.
>I mean if you have anything to detect or handle data corruption on disk (or even in memory) of some form. Say a malformed write or corruption due to a faulty disk, etc.
yes, this is handled and your paranoia level is configurable.
James K · 2024-11-12 02:14
>>40392
>And yet all of them allow function arity to arbitrarily change, as required by late binding.
People keep saying this as if it has any relevance at all to the question of lisp without brackets. It does not.
>What if I haven't written the new definition yet?
Then it obviously will not work. If you want to load a set of two mutually recursive functions, you'll need to write both before submitting them to the system. This isn't much different to regular lisp, because you usually won't be trying to call a function with undefined references to other functions. But more generally, why do you bother asking this as a question? Surely you could figure out yourself what would happen in that case.
>Are you going to rescan the whole codebase every time new code is loaded just in case a definition has been altered?
Again, you ask this as a question but I think you'd be able to solve this problem yourself if you encountered it. You just query the number of arguments to a function that is already defined in the system (though I think CL lacks a standard way to do this).
Lain Iwakura · 2024-11-12 05:42
>>40397
>then it should not be difficult to imagine redefining a function amidst the arguments it is waiting for.
You could avoid this by only looking up the function definition once but its largely a non-issue considering most languages have an undefined order of evaluation of function parameters in a function call.
>this is handled and your paranoia level is configurable
Nice.
>>40400
>People keep saying this as if it has any relevance at all to the question of lisp without brackets. It does not.
Considering late binding is still a core idea of lisp I would argue it is very relevant.
>This isn't much different to regular lisp, because you usually won't be trying to call a function with undefined references to other functions.
But they may be undefined at compile time. Say, if I am writing them at a REPL.
>why do you bother asking this as a question?
To illustrate my point in a way that is open to solutions. So far in this post all you've done is claim that actually its not important and I shouldn't care which makes me think you don't appreciate the value that late binding gives (even if you disagree with its importance) in a programming environment.
>Again, you ask this as a question but I think you'd be able to solve this problem yourself if you encountered it. You just query the number of arguments to a function that is already defined in the system (though I think CL lacks a standard way to do this).
My mistake I should have been more thorough, I should have instead written
>Are you going to rescan the whole or a part of the codebase every time new code is loaded, just in case a definition in a file has been altered but has yet to be loaded into the system?
James K · 2024-11-12 08:57
>>40403
>To illustrate my point in a way that is open to solutions
Well to be quite frank, the solutions should be obvious to you and you don't have a point.
>all you've done is claim that actually its not important and I shouldn't care which makes me think you don't appreciate the value that late binding gives
Do you know what late binding is? It isn't just "use an undefined variable". The important part of late binding is dynamic dispatch. This proposed change to syntax has no effect on it. It is a semantic property of the language, independent of the syntax used. That's why it's irrelevant. Because this is a discussion of syntax and you are talking about something which has nothing to do with syntax.
>But they may be undefined at compile time. Say, if I am writing them at a REPL.
Okay, this is gonna be a thinking moment. Think about yourself typing into the REPL. Imagine the old syntax. You enter a function with an undefined reference. You usually can't call it until you enter the definition for that reference. Now imagine the new syntax. You enter a function with an undefined reference. You can't call it until you define that reference. Basically no difference.
>Are you going to rescan the whole or a part of the codebase every time new code is loaded, just in case a definition in a file has been altered but has yet to be loaded into the system?
Lisp already has this issue with macros, and its solution is to just not bother keeping things up to date if a macro definition changes. Likewise, not bothering to keep things up to date here makes sense and would rarely break anything. Even when it does, the solution from the users perspective would be trivial – reload the file with the changed definition (and this is necessary in both cases since you'll still need to reload the file so you aren't calling the old version of the function with the wrong count of arguments).
Once again, it is almost identical to lisp in every aspect because it is just a different syntax. You will never be able to find any substantive difference between the two. Of this I am certain.
Koos van der Merwe · 2024-11-12 17:52
>>40371
>a Lisp without parentheses is possible if you do not support variadic arguments
Or support Python-indentation instead and have your variadic arguments
Backus · 2024-11-12 18:07
>>40404
>important part of late binding is dynamic dispatch.
I don't understand how you reached this conclusion. Late binding refers purely to at what point function names are resolved to definitions. You can have either late binding or dynamic dispatch without the other.
>Now imagine the new syntax. You enter a function with an undefined reference. You can't call it until you define that reference.
But I can't because the compiler wouldn't know how many parameters to associate with the call and it can't scan ahead because the definition hasn't been written yet. Of course the act of relying on function definitions at compile time precludes late binding.
>makes sense and would rarely break anything
You're also dropping the façade of pretending to have late binding.
James K · 2024-11-13 03:33
>>40407
>Late binding refers purely to at what point function names are resolved to definitions.
What do you think dynamic dispatch is? It's the binding of function names to definitions at runtime. This is also the definition of dynamic dispatch. They are synonymous.
https://en.wikipedia.org/wiki/Late_binding
If late binding was just "you can use a function before it's defined without having to pre-declare it", it wouldn't be a very useful feature. Tell me, are you saying late binding is an important part of lisp because you have reached this conclusion by yourself, or because you have heard someone else say it?
>But I can't because the compiler wouldn't know how many parameters to associate with the call and it can't scan ahead because the definition hasn't been written yet
Again, can you write software? You'll have to solve problem like this all the time. Just have the reader wait for more input at a REPL when it encounters a missing identifier.
The Phantom Phreak · 2024-11-13 05:58
>>40409
>What do you think dynamic dispatch is? It's the binding of function names to definitions at runtime.
I would describe it as the selection of an implementation at runtime (or more accurately, call-time). Not the resolution of a name which could have happened at any time in the past.
>https://en.wikipedia.org/wiki/Late_binding
Ah yes
>This article is about associating a name with an operation. For the selection of an implementation of a polymorphic operation, see Dynamic dispatch.
The article does also state
>Currently, it is popular to use the term late binding in Java programming as a synonym for dynamic dispatch.
Which also doesn't imply equivalence, even in the specific context of Java.
>are you saying late binding is an important part of lisp
Yes. Are you claiming that its not?
>it wouldn't be a very useful feature
I am happy to discuss usefulness if you want but that was never my intention, only to point out that you would have to choose between it or performance in a theoretical, compiled, paren free lisp-like language.
>Just have the reader wait for more input at a REPL when it encounters a missing identifier.
Because you seem to dislike me highlighting problems in your "solutions" I will instead point out that instead of conceding or offering real compilation techniques to solve the problem you're just finding more ways to bend over backwards and get a definition at compile time.
>Again, can you write software?
Of course not this is the lisp thread. I can write macros, the most complex CLOS monstrosity you've ever seen and beautiful control flow designs using continuations but real software is beyond me.
James K · 2024-11-13 07:12
>>40410
>Because you seem to dislike me highlighting problems in your "solutions"
Every problem you point out is one an idiot could solve within a few seconds of thinking. This is why I dislike it. It's clear you aren't willing to put any effort into posting and expect me to do all the legwork of actual thinking.
>I will instead point out that instead of conceding or offering real compilation techniques to solve the problem you're just finding more ways to bend over backwards and get a definition at compile time
And? Every written lisp program makes this information available. Every sequence of inputs to the REPL makes this information available. This is information that is available at compile time. I am pointing that fact out, not "bending over backwards to make it available". I give you a perfectly reasonable solution to the non-problem you pointed out and you decide to call it a "solution" (in scare quotes) and cry "that's cheating". Well it's not cheating. It's exploiting an important invariant of all well-formed lisp programs: that a function should be defined before it is called. The definition is therefore available before calls to the function need to be compiled.
>Are you claiming that its not?
Late binding, as you define it, is an utterly useless feature. Under your definition, all it adds to the language is the ability to call a function with references to undefined functions in its body, which is something that I'm almost certain no real lisp program does because those undefined references will cause errors when evaluated. In fact I would go a step further and say that even if lisp required you to pre-declare the signature of every function (as you do with defgeneric), no significant difference would be made to the power or expressiveness of the language. You are perfectly welcome to demonstrate a useful program that wouldn't be possible in bracketless lisp to show the importance of the late binding which it apparently lacks.
Turing · 2024-11-13 09:00
>>40411
>invariant of all well-formed lisp programs: that a function should be defined before it is called
Of course.
>The definition is therefore available before calls to the function need to be compiled.
This does not follow. If I take a different approach: C-style dynamically linked libraries are the most common way of distributing libraries on any platform and dynamic linking is late binding. This process isn't common in the open source lisp community but it is still something the compilers support and the proprietary ecosystem makes heavy use of.
>in scare quotes
Lmao
>Under your definition
Considering the Wikipedia article you posted agrees with me, this is rather disingenuous.
>all it adds to the language is the ability to call a function with references to undefined functions in its body
Which I suppose is why (I dare say) most programming languages support it either optionally or by default. It is probably one of the most prevalent design choices, more popular than any single execution style or type system.
>if lisp required you to pre-declare the signature of every function (as you do with defgeneric)
At which point it would then be partially statically typed.
>no significant difference would be made to the power or expressiveness of the language
Perhaps not but those are both hard to quantify and not the only metrics available to judge a language.
>wouldn't be possible
As if possibility is the pinnacle of language design.
>wouldn't be possible in bracketless lisp to show the importance of the late binding which it apparently lacks
I can't produce a program that isn't possible without late binding just as how I can't produce a program that isn't possible without macros, dynamic typing, garbage collection or anything else that is core to lisp.
James K · 2024-11-13 09:38
>>40412
>Considering the Wikipedia article you posted agrees with me
If you agree with the Wikipedia article, then you agree that the bracketless lisp has late binding and this entire discussion was pointless.
>This does not follow
Yes it does. Lisp tends to use JIT (Just in Time) compilation, which means a function doesn't need to be compiled until its called.
>Perhaps not but those are both hard to quantify and not the only metrics available to judge a language.
Okay, and?
>At which point it would then be partially statically typed.
Okay, and? By this definition, a lisp with only generic functions would be partially statically typed and it would be more powerful than CL.
>As if possibility is the pinnacle of language design.
Nice pithy quip, but it is totally meaningless.
>just as how I can't produce a program that isn't possible without macros, dynamic typing, garbage collection or anything else that is core to lisp
Once again, you demonstrate a deficiency in thought. Do you think I was asking for a computation that could be achieved in one Turing machine but not another? Obviously that would be illogical, so obviously I am not asking for it. What I clearly want you to do is demonstrate with some code the actual effect of "the core of lisp" being removed. If this is one of the most important parts of the language, it should be easy to show the negative effects of it being taken out. Just as it's easy to show that lisp would be a much more complicated language without garbage collection, or that there are some programs which would be harder without macros.
To put this more mathematically, the mapping from lisp programs to bracketless lisp programs is trivial and has minimal effect on the input. By contrast, there is no mapping from lisp programs to lisp programs without garbage collection. You can tell that garbage collection is a core and important part of lisp because it is difficult to remove and doing so makes the structure of the resultant program substantially different. However we know that the bracketless syntax does not remove any important features because of the trivial and minimal mapping between the formats. So from this, we can conclude that either late binding is removed and it is an unimportant feature, or that late binding is an important feature and it is persevered.
progn · 2024-11-13 18:12
>>40413
>then you agree that the bracketless lisp has late binding
My point was always that you would have to choose between late binding or efficient execution.
>Lisp tends to use JIT (Just in Time)
I am not aware of any implementation that uses such a design.
>a lisp with only generic functions would be partially statically typed
It would not because forward declaration is not required to have generic functions just like how DEFGENERIC in CL is entirely optional.
>it would be more powerful than CL.
I don't understand how it would become more powerful after taking features away. What is your justification for this?
>Obviously that would be illogical
Then why bother asking for something that "wouldn't be possible" if it isn't your intention?
>"the core of lisp"
Has anyone in this thread used these words?
>What I clearly want you to do is demonstrate with some code the actual effect of "the core of lisp" being removed.
Then a better request would have been a program that cannot be directly translated.
>the mapping from lisp programs to bracketless lisp programs is trivial and has minimal effect on the input.
You can't claim this if the mapping isn't an injection, if you'll excuse my informal use of the term.
>there is no mapping from lisp programs to lisp programs without garbage collection
I assume you mean lisp programs without automatic memory management because otherwise the transformation is trivial.
>You can tell that garbage collection is a core and important part of lisp because it is difficult to remove and doing so makes the structure of the resultant program substantially different.
If it was just difficult to remove then there would be a mapping between the two.
Even with a JIT compiler you may not have all the information available until execution reaches the call site. For (a rather contrived but minimal) example,
(defun load-and-do-things ()
(unless (fboundp 'do-things)
(load "do-things.fasl"))
(do-things))
James K · 2024-11-13 18:41
>>40415
>Has anyone in this thread used these words?
Perhaps you are unaware of this, but the Ctrl+F key combination can be used to search for text in most web browsers.
>My point was always that you would have to choose between late binding or efficient execution.
And I suppose it is your right to believe that. I can see that I'm unable to convince you otherwise.
let · 2024-12-14 20:13
Anybody knows how to use GDB to debug a Guile script? I couldn't find anything about it.
Anonymous · 2024-12-19 08:50
After a few emacs fuarrrk-ups I think I've started to love the default color scheme. There's just something so vibrant and cozy about it
Nobody special · 2024-12-20 06:53
>Lisp tends to use JIT (Just in Time)
Is #'disassemble lying to me?
roll · 2024-12-20 10:24
>>40765
The distinction between JIT and "AOT on demand" is quite thin, but from my quite learned PoV, JIT isn't JIT if it compiles everything all the time, without dynamically profiling to choose when bytecode is run enough for compilation to matter; one level tiering, basically.
Dujour · 2024-12-21 10:56
How long is your init.el? I've been using Emacs for a while and with the currently 60 LOC in my initialization file, I don't feel like I'm taking full use of Emacs
Zuse · 2024-12-24 16:21
>>37769
>>37879
Got a decent job a few months after posting this, only just realised this is the same thread.
However, it isn't in a lisp, which is a bit frustrating given my last few jobs before this one were.
I found it much harder to get another lisp-based job this time round, are others here employed in lisp-based roles? How are you finding the market? Or do you just do side projects?
J.C. Denton · 2024-12-30 10:40
>>40775
`M-x count-line-pages` (C-x l) says I have 1015 lines in my init.el. Scanning through it... there's quite a bit I can get rid of though. There are some things I ended up never using (like the NES emulator).
https://github.com/gongo/emacs-nes
Debbie Charteris · 2025-01-02 02:03
Well, it looks like textboard.org is dead.
Sabo Engle · 2025-01-03 13:49
>decide to give GNU Guix SD a try
>sudo cp /etc/intial-working-sysconfig.scm /etc/test.scm
>test.scm doesn't work no matter how much I try
>go back to initial-working-sysconfig.scm
>sudo guix reconfigure /etc/initial-working-sysconfig.scm
>errors me out
>search the error up
>reddit post shows up as the only related result
>only comment is "lol guile errors are a mess"
I was really excited about a new gen lisp machine but this is a hot mess
Pris · 2025-01-03 15:56
>>40863
Nevermind I'm just retarded.
Switch · 2025-01-03 16:07
Hi Lains
I'm an ML Lain and am curious why I should use a lisp over an ML
Can anyone help me out? :)
John Titor · 2025-01-04 03:07
>>40865
The only inherent difference (and plus, IMO) is S-expressions. Beautiful, regular syntax that is in fact no syntax. Extremely simple and user-actionable parsing (in what other language can you change the comment character?).
And of course, for CL, the whole homoiconicity + unhygienic procedural macros + "everything can be used at compile time with exactly the same syntax" (lol at C++'s constexpr/consteval) + compiler available at runtime package that really makes for mind-bending power.
You'll miss recursive and parametric deftype, though.
Maybe you'll be more interested in Clojure?
Donna Hawthorne · 2025-01-04 06:42
>>40869
Thank you for your response!
I've used Clojure before for implementing an image board and enjoyed it although I felt like I wasn't using it correctly. I wasn't using macros very much and I wasn't being disciplined in defining interfaces.
No recursive deftype?
I've been working in dependently typed languages recently and I worry that moving to a lisp would be jarring due to the general lack of static typing and type-level programming that I've grown accustom to.
Finally, I worry about being forced to write code in CPS with a language that doesn't seem to support contexts/continuations natively.
I know it may sound like I'm being adversarial, but I'm really trying to sell myself on a lisp since I like the aesthetic of languages like Scheme :)
Pris · 2025-01-04 08:04
>>40870
>No recursive deftype?
No way to use a type being defined in its definition, so no way to statically type lists/trees or unknown length.
>I've been working in dependently typed languages recently and I worry that moving to a lisp would be jarring due to the general lack of static typing and type-level programming that I've grown accustom to.
It depends on how much type pilled you are. CL has "some" static typing including ADTs via type specifiers and/or, but that's it. No parametric typing except for the builtin array type.
>Finally, I worry about being forced to write code in CPS with a language that doesn't seem to support contexts/continuations natively.
Never understood the point of continuations beyond academic masturbation and compiler writing. Seems a very "Scheme" thing, along with their disgusting macros.
Anyway, Lisp is like Forth, it's really a matter of clicking or not. MLs aren't like that in my experience, you learn to appreciate it on objective basis very easily.
Joe Bloggs · 2025-01-04 10:02
What do I read after A Gentle Introduction?
For context, I'm not a normal programmer branching into Lisp, I'm learning programming using Lisp from the beginning (aka I don't already know what I'm doing).
I have ANSI Common Lisp, which is filling in many of the details that A Gentle Introduction glossed over, but I feel like I'm learning more Lisp, but not more programming, if that makes sense.
Is there something that goes over the more general principles of programming at a higher level than A Gentle Introduction?
The Phantom Phreak · 2025-01-04 10:55
>>40872
Practical Common Lisp all the way. It's one of the best "show, don't tell" books.
Emmanuel · 2025-01-04 15:04
I want to make an audio-only Lisp IDE from scratch, pre-built alternatives seem really soykafty
>Speech to text based commands to the IDE
>Text to speech based feedback from the IDE
>Commands are for reading and manipulating the IDE
>Manipulating the IDE includes defining functions, deleting them, editing their contents using voice commands to rapidly traverse the AST with for instance "left" and "right" to skip to the next s-expression, or "down" and "up" to recurse deeper or return back upwards
>Commands can trigger "inspection" of the AST which just reads it back to you, with a fine level of control over speed, you can tell it to read you back all the functions defined at a given scope or with a prefix in the name
>Audio feedback that tells you what level of depth you are using a different note for the voice that's higher pitched as you traverse deeper, little bells and dings each time you hit the end of an AST
Ideally it would be an audio-only REPL that you can just talk to, and this means you can code while you're walking down the street without needing vision or hand movement.
Does it seem practical from within Lisp itself, or maybe an Emacs plugin, or should it just be a simple standalone text manipulation tool?
The goal is that it can be used by someone with no eyes or hands to become a highly productive programmer
overriding · 2025-01-20 00:36
>>36959
I'm pretty new to common lisp. Should I use QuickLisp, Guix or ocicl for managining packages?
Sabo Engle · 2025-01-20 09:11
>>40990
Why don't you try each? It's not like it's a massive amount of work.
James K · 2025-01-20 10:08
>>40991
There are often flaws a technology which don't become apparent until you've used it for a while.
Chani · 2025-01-22 11:17
>>36959
>Which dialect do you prefer?
CommonLisp (SBCL)
>Do you use Emacs or a different lisp-based editor?
Lisp made me try Emacs, I didn't like it a lot. I use Vim more, but I will probably return to Emacs eventually.
>What was your first experience with lisp?
Like my first sex. Short and ugly in a lot of ways.
Yet, fascinating.
>What have you made in lisp?
Nothing in particular as of yet. Just simple scripts.
I was interested in Lisp to study it's concepts.
>What is your favorite Lisp program?
Probably Lisp itself.
>What do you like about Lisp?
Same things I like in C. Power and simplicity.
>How do you think Lisp is (one of) the superior programming language(s)?
I'd say there's a tool for every job. There's no "superior" languages. Just language and the thing you like to use it for. So the answer is "yes and no".
I actually find Lisp extremly useful for learning purposes and programming experiments.
>How long have you been programming in Lisp?
It's hard to calculate, maybe like half a year.
>What are your favorite Lisp resources?
General stuff everyone knows. LispCookbook. Some books. Documentation. Sourcecode.
>Is Lisp your main programming language or not? Regardless, what do you primarily use it for?
No, my main language is C. As I said learning purposes.
>What would you like to see in the Lisp general?
I actually don't know. It's kinda good as it is. Maybe some new cool projects. By new, I mean something that was never written at all in any language.
>What was your favorite aspect of the Lisp machines?
Knowledge and expertise it gave to researchers implementing them.
>Do you think we'll ever get something similar to the LispMs again?
Everything's possible, but I don't think so.
I think we will see completely new ways of HMI eventually. It will bring the demise of programming as we know it.
>What is your preferred method of documenting your code?
I didn't write anything that needed documentation.
I usually use anything generally accepted in the community of the language I use.
So it'll be something like atdoc or smth.
https://github.com/cl-doc-systems
>In the dialects that allow it, do you make many reader macros or not?
When it's needed. Which is rare for me.
>Do you use more than one dialect? What are they and which do you prefer?
Not really. I used Scheme and EmacsLisp a few times.
>What do you consider the criteria for what constitutes a Lisp to be?
That's a tricky question. Probably the core is in the original paper:
https://www-formal.stanford.edu/jmc/recursive.pdf
>What is your favorite function in your chosen dialect(s)?
No such thing.
>How do you feel Lisp is weaker than other languages?
It's not. It just doesn't have any critical codebase in use by big tech, that's why it appears somewhat obsolete. But it actually is extremely good for learning.
Probably it's weakness is same as for any other interpreted language. Type system is sometimes problematic it becomes irritating to debug or get into big projects with zero knowledge.
But nothing specific.
I really think one thing Lisp lacking are projects critical for big tech. That will create jobs and will make a positive loop.
>What is one aspect of other languages Lisp seems to ignore?
Proper IDE integration. So people wouldn't be forced to Emacs. All attempts to solve this failed.
Jet Black · 2025-01-26 20:48
Trying to learn lisp, I made a simple tic-tac-toe game. How could I improve it? I guess it's a bit too imperative-like.
(defun init-grid ()
(make-array '(3 3)))
(defun display-cell (num n)
(nth num (list n "O" "X")))
(defun display-grid (grid)
(destructuring-bind (n m) (array-dimensions grid)
(loop for i from 0 below n do
(loop for j from 0 below (- m 1) do
(format t " ~A |" (display-cell (aref grid i j) (+ 1 j (* n i)))))
(format t " ~A~%" (display-cell (aref grid i (- m 1)) (+ m (* n i))))
(if (< i (- n 1))
(or
(loop for j from 0 below (- m 1) do
(format t "---+"))
(format t "---~%"))))))
(defun prompt-read (query)
(format *query-io* "~a: " query)
(read-line *query-io*))
(defun ask-move (grid player)
(let ((move (parse-integer (prompt-read (format nil "Player ~a, choose where to play" player)) :junk-allowed t)))
(cond ( (not move)
(or (format t "Enter a number~%") (ask-move grid player)))
( (or (< move 1) (> move 9))
(or (format t "Enter a number between 1 and 9~%") (ask-move grid player)))
( t
(multiple-value-bind (r c) (floor (- move 1) 3)
(if (> (aref grid r c) 0)
(or (format t "Chose an empty cell~%") (ask-move grid player))
(setf (aref grid r c) player))))))
nil)
(defun move-possible (grid)
(some #'(lambda (e) (= e 0)) (make-array (array-total-size grid) :displaced-to grid)))
(defun p-won (grid player)
(some #'identity
(concatenate 'list
(mapcar
#'(lambda (n) (= (aref grid n 0) (aref grid n 1) (aref grid n 2) player))
'(0 1 2))
(mapcar
#'(lambda (n) (= (aref grid 0 n) (aref grid 1 n) (aref grid 2 n) player))
'(0 1 2))
(list (= (aref grid 0 0) (aref grid 1 1) (aref grid 2 2) player))
(list (= (aref grid 2 0) (aref grid 1 1) (aref grid 0 2) player)))))
(defun get-result (grid)
(cond ((p-won grid 1) 1)
((p-won grid 2) 2)
((not (move-possible grid)) 3)))
(defun play-turn (grid player)
(if (not (get-result grid))
(or (display-grid grid)
(ask-move grid player)
(play-turn grid (- 3 player)))
(get-result grid)))
(defun game ()
"Start a game of tic-tac-toe"
(let ((grid (init-grid)))
(case (play-turn grid 1)
(1 (format t "Player 1 wins~%"))
(2 (format t "Player 2 wins~%"))
(3 (format t "Draw!~%")))))
Yuki Nagato · 2025-01-28 09:02
>>41038
Would have made won-p take the last played piece to greatly simplify computation.
Also, use keywords (e.g. :p1-win :p2-win :draw) for get-result, these are free. I'd also use ecase for display-cell instead.
Jens Hansen · 2025-02-11 02:23
>>41060
Thanks for the tips. I also used nil instead of 0 for the empty cells, which simplified some tests.
The program works well when used from the REPL, but I have an issue when used directly from a shell using a script. The "prompt-read" function waits for user input before displaying the prompt message.
Here is how I call the program:
1. It's compiled from the REPL using (compile-file "tictactoe.lisp")
2. From the shell, I call a script containing
#!/usr/bin/env -S sbcl --script
(load "tictactoe.fasl")
(game)
Pulse · 2025-02-11 02:26
>>41060
>>41143
Btw, it was p-won for "player won", not "wonp" for "won predicate"
Morpheus · 2025-02-27 13:59
>>40873
>Practical Common Lisp
I've seen that recommended before and I've taken a look at it. It seems to be for exactly the person I said I'm not: someone who already knows how to program and just wants to learn how Lisp does X versus how Python does X.
It might be that this is just a stupid question, and I should "learn by doing" and googling each problem I run into, but I have a suspicion that will lead to spaghetti code and no true understanding of what I'm doing.
fsociety · 2025-02-27 14:36
>>41143
Don't use ".fasl", that's an implementation detail. For your prompt problem, you need to flush your stream via (finish-output *query-io*)
Mitnick · 2025-03-02 13:37
I am (unfortunately) a js dev in my dayjob. And one thing I do like is that we write a lot of very functional code, similar to fp-ts and using EffectJS.
I love lisp, but I find myself wanting to do the functional style stuff like:
fun1 = (arg) => arg.pipe(
then(either( StringOrElse(new TypeError)) )),
then(option filter( isASCII )),
then(option_map( fun2 )),
tap( log.info ),
catchType( TypeError, pipe( tryConvertToString, fun1 ) ) )
When I look up functional programming in lisp it seems like everyone is just like "yeah lisp is functional, first class functions" but what I want is this sort of fp-ts style functional programming and I dont know how to look for it.
Aside from elisp for emacs, I have used common lisp on a short personal project and found the map and filter to be strange, and the pipe/compose and named error infrastructure to be basically non existent.
Am I just stupid and missing very obvious things? Or should I just not try to think about lisp like this?
Sabo Engle · 2025-03-02 14:27
>>41319
You have Clojure if you want more ML style functional. Personally, I find that any lang that special cases mathematic operators when they're just functions not very "functional".
Anyway, CL has https://github.com/hipeta/arrow-macros for this kind of postfix chaining, https://gitlab.common-lisp.net/fset/fset/-/wikis/FSet/Tutorial for Clojure-like data structures and you can define the rest, e.g.
(defun map-maybe (fun &rest lists)
"mapcar then remove all NILs from the result"
(delete nil (apply #'mapcar fun lists))) I hope you'll grow out of this junior "fit everything into pipelines!" though. I know it feels good, but it should only be used when it makes things clearer.
over · 2025-03-02 14:48
>>41320
Thank you! I guess I should try clojure. The jvm kinda makes me uncomfortable, but I should probably get over that.
Also yeah, part of me knows you are right re fitting everything into pipelines, but I can't help it. It just feels so good when the pipelines line up just right. and I feel like they are very easy to modify and visualize, and it is a fun puzzle to figure out how to turn things into pipes sometimes. It also feels way more safe for some reason. Similar fun with tail recursion/scheme, although I have mostly grown out of that one.
Special Agent Bob · 2025-03-03 09:49
IS LISP THE ONLY CASE INSENSITVE LANGUAGE OF THE CHOICES THIS WIKIPEDIA ARTICLE RECCOMENDS?
ChurchOfTuring · 2025-03-05 14:54
https://churchofturing.github.io/landscapeoflisp.html
I wrote a post on the current landscape of Lisp - someone might find it useful so I'm posting it here.
Wintermute · 2025-03-06 04:46
>>41328
Good endeavour, but it should really have a bit more relevant info. For example, static typing (arguable the biggest thing in PLs this last decades), package manager situation, IDE/editor support (LSP/SLIME).
William Holtzer · 2025-03-11 01:25
Gambit v4.9.6 has been released~!
No changelog yet, but it's the first versioned release in almost 2 years, so there are plenty of changes and performance improvements.
https://github.com/gambit/gambit/archive/refs/tags/v4.9.6.tar.gz
James K · 2025-03-11 08:29
>>41328
>Paul Graham
This guy is such a pseud. Wouldn't have expected him to get brainrotted and start writing about woke though.
Stallman · 2025-03-11 09:27
>>41354
What's your argument, though, beyond your laughable political/ideological views?
His books "ANSI CL" and "On Lisp" are pretty well regarded (second one is interesting, in my opinion) and most of his essays are good; and short, "brevity is the soul of the wit" and also a mark of respect for the reader's time and energy.
Some of them I find relevant:
https://paulgraham.com/avg.html (the famous one, full of pearls like applying Orwell's "you can't conceive what you don't have words for" to the programming world)
https://paulgraham.com/diff.html (very much on point)
https://paulgraham.com/thist.html (nice early LISP archeology article)
https://paulgraham.com/usa.html (unrelated to programming, but I found it interesting)
Anyway, he clearly did things with Lisp, including some in the open. He's not an "Uncle Bob" who never anything but wrangle Entreprise^tm Java before writing a crappy book.
James K · 2025-03-12 03:44
>>41355
>most of his essays are good
This is the part I take issue with. I've not read his book and I don't intend to, but all his essays I've have all been thoroughly uninsightful exercises in navel gazing. Something to the effect of "I'm a mega hacker and this secret trick they don't want you to know about let's my achieve 10x productivity". The work of Paul Graham insists upon itself in a way little else manages to.
As I understand it, he is a salesman and venture capitalist and this permeates his writings. It's filled with generic codswallop about his brilliance and the great advancement of society and a million other things he has little understanding of but none-the-less feels at liberty to write about and draw conclusions from. His essays contain little research, so they are in essence overly long brain sharts. I've no issue with someone holding my head back and shoving their ideas down my throat if those ideas are good, but Graham's barely reach the standard of entertaining. He practices what I call "libertarian speak" where you make a sequence of grand statements (uncorroborated) about society in an attempt to seem smart.
>https://paulgraham.com/usa.html
>It sounds like making movies works a lot like making software. Every movie is a Frankenstein, full of imperfections and usually quite different from what was originally envisioned. But interesting, and finished fairly quickly.
>I think we get away with this in movies and software because they're both malleable mediums. Boldness pays. And if at the last minute two parts don't quite fit, you can figure out some hack that will at least conceal the problem.
Here is an excellent example. What the hell is he talking about? He's never made a movie. He knows f all about the process. What is he talking about in this whole article? Apparently he's trying to explain what a group of three hundred million people all have this same attitude that makes them good at making some things but bad at others. American houses are bad, American code is good, American cars are bad, American movies are good, American cities are bad, American innovation is good. That is so insanely reductive it's almost beyond parody but Paul is willing to blitz through a million different subjects he's totally clueless about and make some vague statement about each of them that ties back to his point. There are intimate and material reasons for everything he touches on but he's willing to totally ignore them in favour of his simple narrative about Americans being a certain way and Japanese being a different way. The funniest bit has to be where he describes the American attitude as "the clear winner for generating wealth and technical innovations (which are practically the same thing)". This is someone who knows nothing about American and Japanese macroeconomic policy imagining that the go-getting attitude of people is what leads a country to wealth. In his hyper-individualist world view, government policy could never have any influence on the wealth of a nation. Instead it is some proto-racist notion of "national sentiment" that might as well be saying "America is richer because we have better vibes".
Pretending to be an expert on everything is a great way to scam money out of investors, but I really don't want to read investment pitches. They make me wretch.
over · 2025-03-12 09:29
>>41358
>Something to the effect of "I'm a mega hacker and this secret trick they don't want you to know about let's my achieve 10x productivity"
I have no idea how you can apply that to anything else than "Beating the Averages".
>His essays contain little research, so they are in essence overly long brain sharts
These are indeed essays, not whitepapers. Specifically most of these focusing on aesthetics and other subjects that aren't a matter of "scientific research" anyway.
>Here is an excellent example. What the hell is he talking about? He's never made a movie. He knows f all about the process.
How do you know he knows "nothing"? I myself knows officially nothing about film making other than some informal lecture but enough to see that while this claim may be partially wrong or a generalization, it's not outlandish.
>Apparently he's trying to explain what a group of three hundred million people all have this same attitude that makes them good at making some things but bad at others
>That is so insanely reductive
Are you retarded enough to deny that culture (and its underlying roots) exists and shapes people? Oh wait, you're retarded enough to not see that generalization is the only sane way of speaking about "three hundred million people".
>In his hyper-individualist world view, government policy could never have any influence on the wealth of a nation.
And where does general government policy comes from? Culture, that's "where". I love how's he's at first too reductive because he considers whole nations then hyper-individualist, lol.
>Instead it is some proto-racist notion of "national sentiment"
It's so obvious you have an emotional axe to grind here. At worst, he isn't significantly stupider than similar figures and his claims certainly aren't devoid of sense.
I don't venerate the guy but armchair Reddit/HN intellectuals like yourself soykafting on him just because he isn't a leftist will never stop being funny.
Anyway, I'll let people make their own opinion about the guy.
James K · 2025-03-12 10:12
>>41360
>These are indeed essays, not whitepapers. Specifically most of these focusing on aesthetics and other subjects that aren't a matter of "scientific research" anyway.
I don't mean research in the scientific sense, but the historical. As in Googling the topic of the essay or reading a few books about it. Something that brings the information content above zero.
>How do you know he knows "nothing"? I myself knows officially nothing about film making other than some informal lecture but enough to see that while this claim may be partially wrong or a generalization, it's not outlandish.
Even if he does have secret deep knowledge of all these fields, he chooses to stick only to surface level observations that anyone could make. The most logical explanation for why he does this is because he lacks that knowledge.
>you're retarded enough to not see that generalization is the only sane way of speaking about "three hundred million people".
There are other more relevant things that apply to all Americans. Government policy being the prime example. You also assume that there must exist some uniting factor for all Americans' mindsets. This is unsubstantiated. If the only way to talk about three hundred million people is to be reductive to the point of making things up, then you shouldn't try to talk about that many people.
>And where does general government policy comes from? Culture
That's absurd, but even accepting it, Graham should then make the point in his argument that the Bretton Woods agreement and the Plaza accords stem from America's "just-do-it culture". These are only cultural artefacts if you expat the idea of culture to include any and all things that happen in a country. Government policy is, for the most part, cooked up by smallish groups of elite academics and civil servants, not from movies and TV.
>It's so obvious you have an emotional axe to grind here.
Good. I indented to communicate with my writing that I hate Paul Graham and people like him. This was why I compared his writings to excrement, rape, and said they made me want to vomit.
>armchair Reddit/HN intellectuals
So I'm an armchair HN intellectual because I call out the fact that Paul Graham, owner of HN, is pretending to be more intelligent than he is? I think you've got it backwards there.
>just because he isn't a leftist will never stop being funny
I'm soykafting on him because he's a clueless pseud. You just conveniently ignored the fact that I'm correct about this and projected all of PG's flaws onto me for some reason.
t · 2025-03-13 00:55
I'd like to interject with a radical centrist take: Paul Graham's work is never too brilliant or impressive, but it's not completely worthless either.
Something like the blob programming language analogy is unnecessary and boring for anyone with a functioning brain, but that's not a lot of people. Remember that "too many parentheses" is the most common criticism of lisp. Maybe we could all benefit from an essey by Paul on how syntax is less important than semantics, complete with colourful analogies, platitudes and the like.
>You also assume that there must exist some uniting factor for all Americans' mindsets. This is unsubstantiated. If the only way to talk about three hundred million people is to be reductive to the point of making things up, then you shouldn't try to talk about that many people.
I've heard so many people generalize over countries that I've kind of given up on being upset about it.
James K · 2025-03-13 03:03
>>41366
I think his work on programming can have merit because he has experience in that field, though perhaps I should have been more clear about that opinion.
Sipho Nkosi · 2025-03-14 10:40
>>41366
The Blub essay is retarded because Lisp is Blub and Paul was too stupid to see that. How much of the world does Java power compare to Lisp? Which language is actually more poweful?
The Fin · 2025-04-01 00:00
This is for any of you who use `M-x eww` in Emacs.
(defun my/eww-after-render ()
"Apply cosmetic modifications to eww pages after render.
Currently:
- highlight greentext
- highlight post links"
(interactive)
;; 4chan greentext
(unhighlight-regexp t)
(highlight-lines-matching-regexp "^\s*>" 'hi-green-b)
(highlight-regexp ">>[0-9]+" 'link))
;; https://coolors.co/e1ccb7-d6b89a-d0ad8b-2d3142-4f5d75
;; This is intended enhance shr header rendering in dark themes.
(defun my/eww-faces-headings ()
"Set shr-h[123] colors to off-white tan colors.
Also adjust heading sizes."
(interactive)
;; heading colors
(set-face-attribute 'shr-h1 nil :foreground "#e1ccb7")
(set-face-attribute 'shr-h2 nil :foreground "#d6b89a")
(set-face-attribute 'shr-h3 nil :foreground "#d0ad8b")
;; heading sizes
(set-face-attribute 'shr-h1 nil :height 2.5 :weight 'heavy)
(set-face-attribute 'shr-h2 nil :height 1.5 :weight 'heavy)
(set-face-attribute 'shr-h3 nil :height 1.2 :weight 'heavy))
(use-package eww
:ensure nil
:hook ((eww-mode . olivetti-mode)
(eww-mode . outline-minor-mode)
(eww-after-render . my/eww-after-render))
:config
(my/eww-faces-headings) ; INFO: Running this once seems to be enough.
(setq shr-bullet "✷ "))
Turing · 2025-04-01 04:19
>>41546
Interesting, I got a local mode for plain txts to do that:
(make-face 'yotsuba)
(make-face 'yotsuba-b)
(set-face-attribute 'yotsuba nil :background "#f0e0d6" :foreground "#800000")
(set-face-attribute 'yotsuba-b nil :background "#d6daf0" :foreground "black")
(defvar greentext-mode-hook nil)
(defvar greentext-mode-add-face-attrs nil)
(defvar greentext-mode-face 'yotsuba-b)
(define-minor-mode greentext-mode
"Mode to set an imageboard theme using auto-overlays and buffer-face-mode
Variables:
greentext-mode-hook explicit
greentext-mode-add-face-attrs a plist of additional face attributes
greentext-mode-face yotsuba or yotsuba-b (default)"
:init-value nil :lighter " imageboard"
(if greentext-mode
(progn
(cl-assert (member greentext-mode-face '(yotsuba yotsuba-b)))
(require 'auto-overlay-line)
(require 'auto-overlay-word)
(auto-overlay-load-definition
'im
'(word ("^>.*"
(face . (foreground-color . "#829f38")))))
(auto-overlay-load-definition
'im
'(word ("^<.*"
(face . (foreground-color . "#e0727f")))))
(let ((link-color (if (equal greentext-mode-face 'yotsuba-b) "#dd0000" "#000080")))
(auto-overlay-load-definition
'im
`(word (">>[0-9]+"
(priority . 1)
(face . '((foreground-color . ,link-color) (underline . t)))))))
(run-hooks 'greentext-mode-hook)
(font-lock-mode 0)
(buffer-face-mode t)
(buffer-face-set greentext-mode-face greentext-mode-add-face-attrs)
(auto-overlay-start 'im))
(progn
(font-lock-mode t)
(buffer-face-mode 0)
(auto-overlay-stop 'im)
(auto-overlay-unload-set 'im))))
(provide 'greentext-mode)
Zuse · 2025-04-01 11:51
>>41547
I gave this a try, and it worked. However, I was caught by surprise when my dark background suddenly turned light. Disabling greentext-mode restored everything to normal which was good.
Also, if anyone else wants to give this a try, note that you have to have auto-overlays from ELPA installed for this code to work.
http://elpa.gnu.org/packages/auto-overlays.html
----
I have not written a minor-mode for Emacs yet, but this looks like a good small example to learn from.
Frank Garza · 2025-04-02 18:31
I like Elisp.
if · 2025-04-03 21:04
>>41555
500 points youre goated
FILLER · 2025-04-04 15:24
>>41546
A small update:
✷ The heading colors may be done once. This will set default colors for shr-h[123] that will take effect for themes that don't customize this at all.
✷ The heading sizes should be set on every eww render to be safe, because some themes _do_ customize shr-h[123], but it's usually just the color. However, size tends to get reset in these cases, and it's usually back to small headings which is not what I want.
Mentat · 2025-04-16 05:19
>>41546
This makes markdown-live-preview-mode look a lot better. I didn't realize this used eww until today.
Von Neumann · 2025-04-17 18:32
Has anyone given this fork of Helix with an embedded Scheme a try? I believe he's trying to get it merged into the mainline, but I'm not sure what he has left to do.
https://github.com/helix-editor/helix/pull/8675
https://github.com/mattwparas/helix
Unnamed · 2025-04-19 00:31
>>36959
>(princ tripcode)
I remember you from many years ago on 4chan /g/. Why did you leave and come here?
t · 2025-04-20 02:30
https://itch.io/jam/spring-lisp-game-jam-2025
>Lisp Game Jam is a recurring game jam taking place for a full 10 days. After the jam has finished, 7 days are given to everyone to try out the game submissions and vote for their favorites. There is no theme for this jam.
Pris · 2025-04-24 08:26
Has anyone here gone through SICP recently? How long did it take you to get through the entire book?
This guy gave a talk a few years ago, and reported it took him 729 hours to get through the entire problem set.
https://www.youtube.com/watch?v=5ylf6Bg93hE
Colmerauer · 2025-05-07 09:20
>>41791
This starts tomorrow.
https://itch.io/jam/spring-lisp-game-jam-2025/community
Kay · 2025-05-12 09:13
https://lparallel.org/
https://github.com/lmj/lparallel
Archive:
https://web.archive.org/web/*/lparallel.org
I don't know where else the documentation exists. It might have to be scraped from the archives so that they could be put into git.
A Maintained Fork!!
https://github.com/sharplispers/lparallel/
Miho Iwakura · 2025-05-12 10:41
>>42100
>I don't know where else the documentation exists.
They're working on it slowly
https://github.com/sharplispers/lparallel/pull/9
but I'm already done
https://pastebin.com/sH10zWYM
thanks in large part to
https://github.com/kuanyui/copy-as-org-mode
They chose markdown, but I chose org.
(princ tripcode) -| · 2025-05-16 22:09
>>41777
>Why did you leave and come here?
I didn't like /g/ anymore, and wanted to support a smaller imageboard. I decided not to pick 8chan's /tech/ after I saw spam of sexualized cartoon little girls the first time I looked at it.
⍕ · 2025-05-19 03:10
https://git.muupi.com/gg/me
I recently made a small Emacs configuration meant for use on servers. It's Prot's Basic Config + a little bit more for sly and org-babel which was needed for a Common Lisp project I'm working on.
It's a literate config, so installation is:
- clone the repo
- open README.org in an Emacs
- M-x org-babel-tangle
This puts the following files on your system:
- ~/.config/me/init.el :: the emacs config
- ~/.local/bin/me :: a convenience script for launching this emacs config
This was my first time making a literate config, and I really like that it can be installed via tangling.
pop · 2025-05-20 11:19
May 19-20, 2025
https://european-lisp-symposium.org/2025/index.html
https://www.twitch.tv/elsconf
https://x.com/elsconf
Boris Grishenko · 2025-05-23 00:18
>>42144
Toward safe, flexible, and efficient software in Common Lisp
Robert Smith
European Lisp Symposium 2025
Zürich, Switzerland
https://x.com/killian_arts/status/1925029797438333420
'(:duration "1:10:26")
This was an amazing talk. Imagine Haskell, but make it:
- practical
- fast
- lispy
What surprised me the most about the optimizations he was able to achieve was that the code wasn't fugly. I was seriously impressed.
'(fast generic simple) ;; traditionally, choose only 2.
;; with coalton, choose all 3!
There are some smart people out there.
https://x.com/stylewarning
Mario Rossi · 2025-05-31 16:59
>>40085
I just started using spinneret. I like it a lot.
https://github.com/ruricolist/spinneret
Agent Smith · 2025-06-04 18:23
HTML form validation can be a pain in the ass, but I had some fun doing this.
;; This is an alist where each cons cell should contain (error-data . test-function).
;; - The shape of error-data can be anything you want.
;; + I usually do ("Error message" field-name).
;; - lambdas should take some data and return a boolean
;; + The shape of data in this case is `(name email password repeat-password)',
;; but it could be anything you want.
;; + returning a truthy value means the test passed
;; + returning nil means the test failed
(defparameter *registration-rules*
`((("Your username should be > 0 characters long." name)
. ,(lambda (form)
(let* ((name (car form)))
(> (length name) 0))))
(("Your username should be <= 64 characters long." name)
. ,(lambda (form)
(let* ((name (car form)))
(<= (length name) 64))))
(("This username has already been registered." name)
. ,(lambda (form)
(let* ((name (car form))
(user (mito:find-dao 'user :name name)))
(not user))))
(("This email address has already been registered." email)
. ,(lambda (form)
(let* ((email (nth 1 form))
(user (mito:find-dao 'user :email email)))
(not user))))
(("This email address is invalid." email)
. ,(lambda (form)
(let* ((email (nth 1 form)))
(valid-email-p email))))
(("The password should be > 5 characters long." password)
. ,(lambda (form)
(let* ((password (nth 2 form)))
(> (length password) 5))))
(("The passwords don't match." repeat-password)
. ,(lambda (form)
(let* ((password (nth 2 form))
(repeat-password (nth 3 form)))
(equal password repeat-password)))))
"These checks validate the data before registration is finalized.")
;; This is used for form validation.
;; - See the register route in handlers.lisp.
;; - See *registration-rules* .
(defun find-problems (rules value)
"Run rules over a value to find problems."
(loop for r in rules
when (let* ((test (cdr r))
(pass (if (equal test :todo)
t
(funcall test value))))
(not pass))
collect (car r))) Here's an example of how to use it.
CL-USER> (find-problems *registration-rules* '("name" "bad-email-address" "short" "short"))
(("This email address is invalid." EMAIL)
("The password should be > 5 characters long." PASSWORD))
PS: I just found out that If input type=email, the browser itself won't let it through. That's why I didn't type "bad-email-address" in the screenshot. My browser (currently Floorp) refused to submit the form.
DEBUG-CONTENTS · 2025-06-04 18:47
>>42277
Will anon's ominous prediction come true?
https://desuarchive.org/g/thread/105427501/#105477171
Cypher · 2025-06-05 20:18
https://cnbbooks.github.io/lfe-tutorial/index.html
This is one of the best language tutorials in the lisp world. I wish Lisp Flavoured Erlang (LFE) received more love, because it provides a great platform for building concurrent systems. It's something I wish I picked up earlier in my programming journey.
Wherefore art thou LFE - Robert Virding
https://www.youtube.com/watch?v=BvCBTpnlqs8
LFE Talks (Playlist)
https://www.youtube.com/playlist?list=PL86ouQm04Mtqdbldb2NL3DFblvCLeBpBz
Cereal Killer · 2025-06-07 02:08
>>42171
How long until the rest of the videos make it here?
https://www.youtube.com/@EuropeanLispSymposium/videos
Delilah · 2025-06-07 05:22
>>42277
http://beastie.sdf.org:4200/
I'm going to leave this running for a few days. Anonymous posting is allowed.
Crazy Jake · 2025-06-08 09:43
>>42304
SAL9000 in #commonlisp said he's editing them and preparing them for upload. He didn't give an ETA though.
Cereal Killer · 2025-06-08 10:37
Is lisp a good language for an absolute beginner to programming?
Lunch · 2025-06-08 12:20
>>42320
I think it is. The problem is that there aren't as many courses as for more classical procedural languages.
PDF related, with a somewhat formal approach.
Switch · 2025-06-08 17:30
>>42320
If I had to teach a beginner programmer Lisp, I'd start with Emacs Lisp, because Emacs provides a good environment for experimentation and playing around. I think these are important things to be able to do as a beginner. Also, once you know one Lisp, it's easy to learn another dialect of Lisp.
Emacs is also the most popular editor among Lisp programmers, so it's a good place to start.
BloodCat · 2025-06-08 17:38
>>42320
Any language is good to start with!
Starting with Lisp will probably be more difficult. But the thing is, with beginner languages you make a personal choice whether you start with an easier one, from which you learn less and more slowly, or a more difficult one, by which you will be more greatly rewarded.
You will probably want to stick to books more than videos and articles, they are the ruling resource of niche languages.
Terzibashjian · 2025-06-09 02:29
>>42326
Prot wrote a good primer on Elisp recently.
https://protesilaos.com/emacs/emacs-lisp-elements
If it were printed as a book, it would be a short pamphlet which I think is a perfect size for a beginner.
However, instead of reading the web version, I would recommend reading the org-mode version which can be found at this GitHub repo.
https://github.com/protesilaos/emacs-lisp-elements
The nice thing about reading it in org-mode is that:
- You get syntax highlighting.
- You can run the code by hitting `C-c C-c` while your cursor is in a code block.
I would also open up a REPL so that I could type Elisp code while reading the book.
- C-x 2 :: split the window in 2
- Make the bottom window shorter.
- Click on the bottom window.
- M-x ielm :: start an Elisp REPL.
Cereal Killer · 2025-06-09 16:01
How tf do I get Aserve portable to serve utf-8? I've tried everything, but it insists on sending windows-1252 to my browser (but it's correctly advertised as charset=utf-8 in the content-type header, which results in mangled text). I'm using both SLIME and SBCL, but the production environment uses SBCL.
(require :asdf)
(asdf:load-system :aserve)
(use-package :net.aserve)
(use-package :net.html.generator)
(start :port 8888)
(defun test-fun (request entity)
(with-http-response (request entity :content-type "text/html; charset=utf-8")
(with-http-body (request entity :external-format :utf-8)
(html (:html (:h1 "àïùéô"))))));)
(publish :path "/" :content-type "text/html; charset=utf-8" :function 'test-fun)
Mario Rossi · 2025-06-09 18:28
>>42337
This is way harder than it should be.
I found this
https://www.xach.com/lisp/allegro-cl/2001-3/964.html
but it doesn't work for me.
Project 2501 · 2025-06-09 18:48
>>42338
Yeah, I had found that in the AllegroServe tutorials, but I don't know from which package that crlf-base-ef function comes.
Bobby Newmark · 2025-06-09 18:52
>>42339
It possibly comes from the complete Allegro, but I only have the portable AllegroServe.
Jane Doe · 2025-06-09 21:07
>>42337
I came up with a terrible hack.
I saw this.
https://franz.com/support/tutorials/aserve-tutorial.htm#qs4-1
It didn't work, but I saw the :princ-safe and I was able to guess that a :princ also existed. That seems to be a way to send raw output, so here's one suboptimal approach.
(defun code-as-string-or-entity (code)
(if (<= code 126)
(string (code-char code))
(format nil "&#x~x;" code)))
(defun encode (string)
(let* ((codes (mapcar #'char-code (coerce string 'list)))
(letters (mapcar #'code-as-string-or-entity codes)))
(eval (append '(concatenate 'string) letters))))
(defun test-fun (request entity)
(with-http-response (request entity :content-type "text/html; charset=utf-8")
(with-http-body (request entity :external-format (crlf-base-ef :utf-8))
(html (:html
(:head (:title "Ridiculous."))
(:body (:h1 (:princ (encode "àïùéô"))))))))) I turn them into HTML entities with an encode function. It's a terrible hack.
Boris Grishenko · 2025-06-09 22:55
>>42342
Strangely, that :princ seems necessary. I initially tried to just give it the return value of (encode ...), but that wasn't enough.
Unsigned · 2025-06-10 09:29
how hard would it be to rewrite something like ranger fm but not in terminal but in SDL instead?
i've finished most of K&R and 1,5 chapters of sicp and done some leetcoding in school
not sure if i should start out with something simpler
synchronized · 2025-06-10 09:44
>>42342
The hack really is a hack. Thanks, but I don't think I will use that, lol.
It seems portable aserve doesn't support unicode at all https://sourceforge.net/p/portableaserve/bugs/2/ It doesn't support html5 either.
I'll be using hunchentoot and cl-who instead.
(require :asdf)
(asdf:load-system :hunchentoot)
(asdf:load-system :cl-who)
(use-package :hunchentoot)
(use-package :cl-who)
(start (make-instance 'easy-acceptor :port 8888))
(define-easy-handler (index :uri "/") ()
(setf (content-type*) "text/html")
(setf (html-mode) :html5)
(with-html-output
(*standard-output* nil :prologue t :indent t)
(:html (:h1 "àïùéô aiueo あいうえお"))))
Netrunner · 2025-06-10 13:15
>>42345
I wasn't sure if you were able to switch stacks. I thought that maybe you were working on a legacy system and were stuck with aserve, so I didn't suggest switching, but I totally would if I could.
I recently setup a stack that uses hunchentoot, and if you're going to use sessions, I would suggest setting up an :around advice on hunchentoot:handle-request like this:
https://git.vern.cc/gg/webapp-v1/src/branch/main/src/handlers.lisp#L15-L26
(defmethod hunchentoot:handle-request :around ((hunchentoot:*acceptor* easy-routes-acceptor)
(hunchentoot:*request* hunchentoot:request))
"Setup variables for every request handled by easy-routes-acceptor.
- Enable hunchentoot's session support for the current request.
- Make sure mito:*connection* is not shared between threads.
- If someone is currently logged in, provide a user object in *user*."
(hunchentoot:start-session)
(let ((mito:*connection* (connect-cached))
(*user* (load-user-from-session)))
(unwind-protect (progn
(call-next-method)))))
Gyula Kovacs · 2025-06-10 13:27
>>42344
If I were writing a file manager, I would focus on making sure I got all the file operations working correctly without any UI first. Then I'd worry about putting a UI on it afterward. Unfortunately, I don't know the state of the SDL bindings are in any of the lisps so I can't advise on how easy or hard it would be to create a UI using it. Which lisp are you using, btw?
t · 2025-06-10 14:03
>>42347
idk probably common lisp but i've never written anything, i'm pretty sure CL has the libraries
Motoko Kusanagi · 2025-06-10 14:41
AllegroServe net.html.generator
- https://github.com/sharplispers/portableaserve
cl-who
- https://github.com/edicl/cl-who
- https://edicl.github.io/cl-who/
spinneret
- https://github.com/ruricolist/spinneret
flute
- https://github.com/ailisp/flute
hsx
- https://github.com/skyizwhite/hsx
- https://code.skyizwhite.dev/paku/hsx
Are there any others?
Demeere · 2025-06-10 15:28
>>42348
If you haven't setup Emacs for Common Lisp development yet, I'd recommend this sly config.
https://github.com/joaotavora/sly/discussions/683
(use-package sly
:ensure t
:config
(let ((patterns '(("\\*sly-mrepl"
(display-buffer-in-side-window)
(side . bottom)
(slot . 0)
(window-height . 22))
("\\*sly-db"
(display-buffer-in-side-window)
(side . bottom)
(slot . 1))
("\\*sly-inspector"
(display-buffer-in-side-window)
(side . right)
(slot . 1)
(window-width . 80))
("\\*sly-description"
(display-buffer-in-side-window)
(side . right)
(slot . 0)
(window-width . 80)))))
(cl-loop for p in patterns
do (add-to-list 'display-buffer-alist p)))
(setopt inferior-lisp-program "/usr/bin/sbcl")
(setopt org-babel-lisp-eval-fn #'sly-eval))
- If your sbcl is somewhere other than /usr/bin/sbcl, set it appropriately.
- Any time you want to use sbcl, you can hit `M-x sly` to get a REPL.
- It is a lot more comfortable to use than the default sbcl REPL on the terminal.
- You can navigate history with M-n and M-p (next and previous).
- You can search history with C-r.
- You can inspect values by clicking on them.
- Results of previous evaluations are available in special variables: *, **, and *** .
- Most importantly, if you're editing a .lisp file, you can hit `C-c C-c` to recompile the current function and `C-c C-k` to recompile the whole file.
It's a huge quality-of-life improvement to have sly setup decently before you do any CL work.
Nell · 2025-06-10 15:39
>>42346
>around
https://lispcookbook.github.io/cl-cookbook/clos.html#method-qualifiers-before-after-around
Masami Eiri · 2025-06-10 16:31
>>42350
i love emacs as a concept and loathe its implementation so i imagine i'd use nvim
Acid Burn · 2025-06-10 16:41
>>42352
https://lispcookbook.github.io/cl-cookbook/editor-support.html#vim--neovim
Your options are slimv or vlime then.
Anonymous · 2025-06-10 18:45
>>42352
...or you could use evil and stay in Emacs.
(use-package evil
:ensure t
:init
(setq evil-want-integration t)
(setq evil-want-keybinding nil)
(setq evil-undo-system 'undo-redo) ;'
:config
(evil-mode 1))
(use-package evil-collection
:after evil
:ensure t
:config
(evil-collection-init))
(use-package which-key
:ensure t
:config
(which-key-mode)) https://github.com/noctuid/evil-guide
string · 2025-06-11 03:48
>>42350
What's that font? Looks really pleasing.
Debbie Charteris · 2025-06-11 08:55
>>42356
VictorMono Nerd Font
https://www.nerdfonts.com/
stack · 2025-06-11 11:05
>>42354
i dont have an issue with emacs, i have an issue with gnu emacs being convoluted slow bloated soykafty piece of garbage with god awful defaults and hard coded dogshit you cant get rid of
and i have used thinkpad x220 for 5 years as my only PC and on modern hardware emacs is still unusable that's how fuarrrking bad the performance is
if you need 100 pages of introduction to use a fuarrrking text editor that's when you know it's dogshit
fuarrrking dired and ranger clones are so fuarrrking slow i'd get something more usable after installing windows 11 on my thinkpad x60
nvim is a bloated piece of soykaf but at least the defaults are good enough that i dont need 500 LoC config copied over from 100 stackexchange posts of some esoteric 40 yo config variables to make fuarrrking ESC close the minibuffer or command line or whatever the fuarrrk it is
drop · 2025-06-11 11:57
>>42360
>my only PC and on modern hardware emacs is still unusable
What? I have x60 with Celeron processor and don't have an issue (thought LSP tend to crunch hard).
>100 pages of introduction
*manual
>to make fuarrrking ESC close the minibuffer
This one I can get behind (although C-g is forwarded directly and not interpreted), because ESC being M- is here only for no-GUI users.
list · 2025-06-11 14:14
>>42360
You're being dramatic. I use emacs on an x220.
fsociety · 2025-06-11 14:36
>>42361
>>42362
i spent like 10-20 hours trying to get that soykaf to work the way i want it to no avail fuarrrk that stupid soykaf i am not learning 50 shortcuts just to operate org-mode C-c C-x M-x suck-my-dick can't even display the fuarrrking minibuffer properly so i can have a list of keybinds and even if you get it good luck resizing it you just need to C-x C-n <n> 50 times to find what youre looking for because there is no fuzzy matching, fuarrrk that soykaf
Incognito · 2025-06-11 16:08
>>42363
If only there was a tutorial on the first screen you see in the program
>no fuzzy matching
What is flex completion style? Though this requires setting a variable. The partial completion (where you type something like `-foo` and emacs finds all the functions/whatever that contain `-foo`) works out of the box.
>i can have a list of keybinds
C-h m (mentioned in the TUTORIAL)
>>42362
I feel like this anon wants just to rage a bit.
Debbie Charteris · 2025-06-11 17:11
How much one enjoys Emacs is often proportional to how fluent in Elisp you are. It might be old and antiquated, but it's still a lisp that's quite capable and battle-tested. Emacs definitely has its flaws, but people stick with it, because Elisp has allowed people to mold Emacs into a system that fulfills their specific needs. The level of customization Emacs allows is unparalleled, and it's thanks to Elisp and the infrastructure around it.
Even if you don't like Emacs, there are important lessons to be learned from it, especially if you plan on creating an extensible system of your own in the future. There are things that they did right that haven't been replicated by others, and it's a bit of a shame.
James K · 2025-06-12 01:43
>>42365
>but it's still a lisp that's quite capable and battle-tested
It has no resizable arrays and all the code runs on the UI thread.
quote · 2025-06-15 12:55
I've been reading An Introduction To Programming In Emacs lisp but the book seems way too slow-paced for someone who has past experience in programming. Any alternative ways I could dive into Elisp?
Haruyoshi · 2025-06-15 14:32
>>42380
just dive into it, really. Have a manual at hand though (very well written).
Agent Smith · 2025-06-16 10:24
>>42381
"Just diving" into it is also pretty hard since I have no prior experience with lisp. However, if someone is also wondering the same thing I've come across this page:
https://www.emacswiki.org/emacs/LearnEmacsLisp
And what I used to learn the grasps of it was this:
https://steve-yegge.blogspot.com/2008/01/emergency-elisp.html
Kind of dated but the "syntax" is still the same so it didn't bother me that much, with heavy use of C-h* I'm sort of making my way through.
William Holtzer · 2025-06-16 13:32
>>42384
>I have no prior experience with lisp.
But there is no syntax init. If it starts with a ' then it's not evaluated, if it doesn't then it is evaluated. If it is evaluated and it's at the start of the list, then it's a function, if not then it's an argument (I am not touching macros with 10 foot pole).
>Tutoriels
This might help, I believe it was mentioned previously: https://protesilaos.com/emacs/emacs-lisp-elements
To ease yourself into elisp, I'd suggest just finding few configs that don't just set up stuff, but also write their own defuns and wade yourself through it. Something like prot's config or unpackaged.el:
https://github.com/protesilaos/dotfiles/tree/master/emacs/.emacs.d
https://github.com/alphapapa/unpackaged.el
Why like this? Because you will be forced to pick up common patterns used in buffer manipulation, etc.
Cowboy · 2025-06-19 11:00
>>42380
There is a playlist on youtube called "Little bits of Lisp" if you prefer video. It teaches the very basics of Common. It's mostly the same for Emacs Lisp.
Ender · 2025-06-21 07:28
>>42380
- Read the org-mode version of Emacs Lisp Elements by prot.
- https://github.com/protesilaos/emacs-lisp-elements
- While you read it, have `M-x ielm` open so you can experiment.
- Also, feel free to hit `C-c C-c` to execute the code blocks.
See the following post for more details.
>>42332
let · 2025-06-21 07:34
>>42371
>and all the code runs on the UI thread.
This doesn't have to be true. Elisp has cooperative threads which are often enough to avoid blocking the UI. However, this feature is severely underutilized. `M-x list-threads` is usually an empty list which is unfortunate.
>>41592
Iverson · 2025-06-21 07:56
>>42101
https://g-gundam.github.io/lparallel/ - mdbook-generated doc site for lparallel
Zhora · 2025-06-23 13:51
How good is Common Lisp for low level programming?
Specifically, to implement a relational database from scratch, with decent performance for a small server with low traffic.
Does lisp have the low level facilities to improve storage, caching, and access times?
How about for numerical applications, such as, for example, physics simulations?
In general, is it possible to write arbitrary software that is performance critical within a good threshold, not necessarily for large scale production software, but for small to medium business needs?
And if so, what are good examples of such performant software written with the required optimizations?
Thanks in advance.
() · 2025-06-24 05:52
>>42423
>Specifically, to implement a relational database from scratch, with decent performance for a small server with low traffic.
Endatabas was implemented in a combination of Common Lisp and Rust.
https://github.com/endatabas/endb
https://www.endatabas.com/
FILLER · 2025-06-24 07:07
>>42428
>rust
that's what I was wondering, perhaps the performance-critical bits have to be written in a lower-level language, or perhaps it's the low-level access operations.
Anyway that sort of answers my question.
Lunch · 2025-06-25 09:35
>>42429
CL has everything needed to be very performant
See this article:
https://pvk.ca/Blog/2014/03/15/sbcl-the-ultimate-assembly-code-breadboard/
in general the MOP gives you the flexibility of how to store data structures that you wouldn't be able to in most programming languages (I.E. do you want to back data structures by some foreign allocated memory? Perhaps sparsely allocated or backed by a DB?).
there are other nice things for tuning performance, like being able to call disassemble on functions and assert different safety regions as well for speed.
Chani · 2025-07-03 11:23
>>42360
To be fair, you have to have a very high IQ to understand Emacs. The keybindings are extremely subtle, and without a solid grasp of lambda calculus most of the configuration will go over a typical brogrammer's head. There's also Stallman's nihilistic outlook, which is deftly woven into his open source crusades- his personal philosophy draws heavily from Hegelian literature, for instance. The lisp weenies understand this stuff; they have the intellectual capacity to truly appreciate the depths of this software, to realise that it's not just an editor- it says something deep about LIFE. As a consequence people who dislike Emacs truly ARE idiots- of course they wouldn't appreciate, for instance, the humour in Stallman's existential catchphrase "I'd like to interject for a moment, what you're referring to as Linux is in fact GNU/Linux, or as I've taken to calling it, GNU plus Linux" which itself is a cryptic reference to Turgenev's Russian epic Kernels and Applications. I'm smirking right now just imagining one of those addlepated simpletons scratching their heads in confusion as Haskell Curry's genius wit unfolds itself on their television screens. What fools.. how I pity them. And yes, by the way, i DO have an Emacs tattoo. And no, you cannot see it. It's for the ladies' eyes only- and even then they have to demonstrate that they're within 5 IQ points of my own (preferably lower) beforehand. Nothin personnel kid
H.R. Giger · 2025-07-05 18:34
>>42332
What font is that in the screenshots? It's rather nice looking and readable.
Yamaoto Toshi · 2025-07-06 05:31
>>42542
VictorMono Nerd Font
https://www.programmingfonts.org/#victor-mono
https://www.nerdfonts.com/
My preferred download tool for these is getnf.
https://github.com/getnf/getnf
Elliot Alderson · 2025-07-09 05:51
>>40765
No, the post is incorrect.
>>40766
>is quite thin
Perhaps but that doesn't mean they're not distinct. AoT means the code is compiled at some prior time, before it is executed but JiT is compiled just before and only just before it is executed (typically before the first time but not always, such as famously for HotSpot).
swap · 2025-07-09 05:56
>>41325
>LISP
>CASE INSENSITVE
Most (by language count) are case sensitive. Also I'm not aware of any truly case-insensitive lisp, CL and its priors certainly are case-sensitive just they always convert input to uppercase unless specified which I guess comes off to most users as "case-insensitive".
Unidentified · 2025-07-28 09:18
Hello.
Does anyone have "original" ANSI Lisp Specification?
I know Hyperspec exists and all, but I would like to get a pdf or smth.
Neuromancer · 2025-07-30 21:01
>>42673
https://webstore.ansi.org/standards/incits/ansiincits2261994r1999
Attached is the 1994 version of the document.
Lord Nikon · 2025-07-31 03:47
>>42685
Thanks a lot, Lain! <3
Unspecified · 2025-08-18 07:44
Anybody know if it's possible to automatically exit the debugger at errors, without also quitting SBCL? I just want the error message without being dropped into the debugger to get to fixing the source code faster.
I'm not sure if it's the intended functionality, but if I run SBCL with --disable-debugger the entire thing poops itself and puts me back to shell. Which defeats the point. I guess that's what should happen if running a script, can't just hang, but then there's the separate --script option. Running 64bit 2.5.7 on windows.
Checked the manual and --disable-debugger is all I can find that would be relevant.
limited · 2025-08-18 08:42
Just clarifying >>42788 though maybe it's obvious
"but if I run SBCL with --disable-debugger the entire thing poops itself and puts me back to shell" if an error is encountered.
cond · 2025-08-19 18:39
>>42789
You could wrap your top level form with a handler-case that prints error info and quits.
Davis · 2025-08-21 06:02
Client-side Common Lisp?
https://turtleware.eu/posts/Using-Common-Lisp-from-inside-the-Browser.html
<!doctype html>
<html>
<head>
<title>Web Embeddable Common Lisp</title>
<link rel="stylesheet" href="https://turtleware.eu/static/misc/wecl-20250821/easy.css" />
<script type="text/javascript" src="https://turtleware.eu/static/misc/wecl-20250821/boot.js"></script>
<script type="text/javascript" src="https://turtleware.eu/static/misc/wecl-20250821/wecl.js"></script>
</head>
<body>
<script type="text/common-lisp" src="https://turtleware.eu/static/misc/wecl-20250821/easy.lisp" id='easy-script'>
(defvar *div* (make-element "div" :id "my-ticker"))
(append-child [body] *div*)
(dotimes (v 4)
(push-counter v))
(loop for tic from 6 above 0
do (replace-children *div* (make-paragraph "~a" tic))
(js-sleep 1000)
finally (replace-children *div* (make-paragraph "BOOM!")))
(show-script-text "easy-script")
</script>
</body>
</html>
cond · 2025-08-22 19:02
>>42101
https://sharplispers.github.io/lparallel/ was finally deployed yesterday.
Marly Krushkhova · 2025-09-05 09:47
>>42798
Thanks for the suggestion, wouldn't work very well in my usage though.
Send over expressions to the REPL and gradually build up functionality. Each of which I would need to wrap individually, leading to extra work for every expression rather than only the ones that break.
Drifter · 2025-12-08 09:52
ELS 2025
<Day 1
https://www.youtube.com/watch?v=UCxy1tvsjMs
<Day 2
https://www.youtube.com/watch?v=kiMmo0yWGKI
The official YouTube channel hasn't posted the videos yet, but killian_arts was kind enough to post his bootleg recordings on the twitch stream.
https://x.com/killian_arts
Mentat · 2025-12-09 02:53
https://cdegroot.com/programming/commonlisp/2025/11/26/cl-ql-asdf.html
> If there is one thing that confuses newcomers to Common Lisp, it is the interplay of built-in CL functionality, add-ons like Quicklisp and ASDF, and what all the words mean.
Joe Bloggs · 2025-12-09 15:26
Someone is working on an immediate mode UI library for CL.
https://kirankp.substack.com/p/a-common-lisp-ui-library
The demo looks promising, but he hasn't released source yet.
push · 2025-12-10 15:16
>>42831
Great news! Wouldn't want this pillar of CL to completely die.
John Titor · 2025-12-14 07:38
So, you want to go fast kid? **Save me, I've lost half my week-end on chasing milliseconds.**
https://world-playground-deceit.net/blog/2025/12/fast-sequence-iteration-in-common-lisp.html
Unspecified · 2025-12-14 10:07
>>43699
>chasing milliseconds
fuarrrk yeah.
Otto Normalverbraucher · 2026-06-11 14:45
>>43652
ELS 2026
https://www.youtube.com/playlist?list=PLpHdy7ydcZKf17kvGFPafbfxyA1cXWDAu
Credit to:
https://x.com/almighty_lisp
Linda Lee · 2026-07-01 06:16
>>36959
How do I get started with lisp? I suck at programming and I always heard that books like sicp help you think programs on a different way.
Mitnick · 2026-07-01 06:50
>>44405
my humble advice: get an idea and thug it out. unless you're unfortunate enough to not have autism in which case get a job I guess. either way books are great but you can't learn a new language without using it (this is just as true of computer languages)
Lord Nikon · 2026-07-01 06:57
>>44405
lurk the thread because the question has been asked by many including me
Elliot Alderson · 2026-07-02 04:42
>>44405
Read Almighty Lisp
https://almightylisp.com/
It's a very practical introduction to Common Lisp that also helps you find your way around Emacs in a Lisp development context.