/t/ - Technology

Discussion of Technology

Index Catalog Archive Bottom Refresh
Options
Subject
Message

Max message length: 12000

files

Max file size: 32.00 MB

Total max file size: 50.00 MB

Max files: 5

Supported file types: GIF, JPG, PNG, WebM, OGG, and more

CAPTCHA
E-mail
Password

(used to delete files and posts)

Misc

Remember to follow the Rules

The backup domains are located at 8chan.se and 8chan.cc. TOR access can be found here, or you can access the TOR portal from the clearnet at Redchannit 3.0.

Welcome Refugees!
Don't see your board? Register and create it!


8chan.moe is a hobby project with no affiliation whatsoever to the administration of any other "8chan" site, past or present.

You may also be interested in: AI

(843.36 KB 1920x1080 1697678950319.jpg)

(λ) - Lisp General Anonymous 04/19/2025 (Sat) 11:17:31 No. 18163
>Lisp is a family of programming languages with a long history and a distinctive parenthesized prefix notation. There are many dialects of Lisp, including Common Lisp, Scheme, Clojure and Elisp. >Emacs is an extensible, customizable, self-documenting free/libre text editor and computing environment, with a Lisp interpreter at its core. >Emacs Resources https://gnu.org/s/emacs https://github.com/emacs-tw/awesome-emacs https://github.com/systemcrafters/crafted-emacs >Learning Emacs C-h t (Interactive Tutorial) https://emacs.amodernist.com https://systemcrafters.net/emacs-from-scratch http://xahlee.info/emacs https://emacs.tv >Emacs Distros https://www.spacemacs.org https://doomemacs.org >Elisp Docs: C-h f [function] C-h v [variable] C-h k [keybinding] C-h m [mode] M-x ielm [REPL] https://gnu.org/s/emacs/manual/eintr.html https://gnu.org/s/emacs/manual/elisp.html https://github.com/emacs-tw/awesome-elisp >Common Lisp https://lispcookbook.github.io/cl-cookbook https://cs.cmu.edu/~dst/LispBook https://gigamonkeys.com/book https://lem-project.github.io https://stumpwm.github.io https://nyxt-browser.com https://awesome-cl.com >Scheme https://scheme.org https://try.scheme.org https://get.scheme.org https://books.scheme.org https://standards.scheme.org https://go.scheme.org/awesome https://research.scheme.org/lambda-papers >Clojure https://clojure.org https://tryclojure.org https://clojure-doc.org
[Expand Post]https://www.clojure-toolbox.com https://mooc.fi/courses/2014/clojure https://clojure.org/community/resources >Other https://github.com/dundalek/awesome-lisp-languages >Guix https://guix.gnu.org https://nonguix.org https://systemcrafters.net/craft-your-system-with-guix https://futurile.net/resources/guix https://github.com/franzos/awesome-guix >SICP/HtDP https://web.mit.edu/6.001/6.037/sicp.pdf https://htdp.org >More Lisp Resources https://rentry.org/lispresources
>>18163 Racket is great too
(38.10 KB 1024x1356 logo.webp)

fennel!
I'm trying to do something way above my head but here's the gist. - When you press F5 in C or Python some compiling options show up on the minibuffer, those change depending on the major mode you're in - After selecting one, another function is called that opens eshell, executes the command and switches back to the original window once it detects the process is done The following works on both C and Python, I'm not good with elisp at all so I kept iterating versions using deepseek, I'd like to know if there's no better way of implementing something like that. (defvar my/compile-options '((c-mode ("C with user input" . "make run") ) (python-mode ("Python with user input" . "python3 -u REPLACE") ))) (defun my/compile-choice () "Prompt for a compilation command and execute it in eshell." (interactive) (let (applicable-options) (dolist (entry my/compile-options) (when (derived-mode-p (car entry)) (setq applicable-options (append applicable-options (cdr entry))))) (if (not applicable-options) (message "No compilation options for current mode") (let* ((choice (completing-read "Compile option: " applicable-options nil t)) (command (cdr (assoc choice applicable-options)))) (my/run-in-eshell command))))) (defun my/run-in-eshell (command-str) "Run COMMAND-STR in eshell, replacing REPLACE with the current filename." (interactive) ;;delete existing eshell buffer (let ((buf (get-buffer "*eshell*"))) (when buf (when-let ((win (get-buffer-window buf))) (delete-window win)) (kill-buffer buf))) ;;replace REPLACE with the current filename and insert command (let ((filename (buffer-file-name))) (unless filename (error "Buffer is not visiting a file")) ;;new eshell (eshell) (switch-to-buffer eshell-buffer-name) (goto-char (point-max)) (insert (replace-regexp-in-string
[Expand Post] "REPLACE" (shell-quote-argument filename) command-str)) (eshell-send-input)) ;;switch back window when done (set-process-sentinel (get-buffer-process (current-buffer)) (lambda (process _event) (when (memq (process-status process) '(exit signal)) (previous-window-any-frame))))) (global-set-key (kbd "<f5>") 'my/compile-choice) A few notes: - I need eshell because it needs to work on both linux and windows - I could only manage to detect when a program terminates inside eshell using process-sentinel - i delete the existing eshell buffer before initiating because i was having issues sending new commands to the existing shell - My C program has a simple makefile that runs it (./main) - In my init.el I have a section to limit the height of the eshell and forces it to be displayed always at the bottom of the current frame - The way I'm sending the file name (like on python) is really stupid, but it works
>>18228 Any reason you don't use M-x compile?
>>18248 Whether it's compile or eshell doesn't change anything I've said. They have the same problems when trying to implement the behavior I want it to have. I picked eshell because I could expand these functions later on.
(145.40 KB 400x400 1739089728314468.png)

>>18163 My first thought was eshell is a lisp interpreter, so you could append switch-to-buffer after your compile command, and using pcase to select the command from the mode (defun mode-compile-command (file) (completing-read "> " nil nil nil (pcase major-mode ('c-mode "make run") ('python-mode (concat "python -u " file)) ('lisp-mode (concat "sbcl --load " file)) (_ "echo none")))) (defun mode-compile () (interactive) (let* ((buffer (buffer-name)) (file (buffer-file-name)) (command (mode-compile-command file))) (switch-to-buffer eshell-buffer-name) (insert (concat command "; (switch-to-buffer \"" buffer "\")")) (eshell-send-input)))
>>18254 Sorry misquote >>18228
>>18252 Well what *is* your problem? It seems to me you want a code review? Your code is pretty terrible ngl. I'd just wrap compile in your shoes.
>>18262 >>18254 I might have badly expressed myself. Look at the webm (i think its dark because HDR is turned on, sorry), it shows the function displayed in my question at work. 1. I press F5 2. The function checks the major mode I'm in 3. It displays compiling options that fit the major mode in the minibuffer, which I've set up beforehand in the function 4. After I select one compiling option it: - Spawns an eshell window (ideally i'd reuse one if it already exists but i was having issues with it) - Executes the command inside the eshell (for example: in the case of a C program and the option I've selected in the minibuffer, make run) - Switches back to the previous window once the program exits NOTE: I'd like to expand the "compiling options" later with more things to pick, so ideally I wouldn't attach the command I want to run directly to which major mode I'm currently in at the time. Is there a better way to make a function that does that in a simpler way? >code is pretty terrible Yes, I know. It does work like I wanted it to, but like I said, I needed to tard wrang deepseek to get there because I'm not experienced enough to do it alone. >code review If that's the only way I have to achieve what I want, sure, ideally I'd get some guidance (keep in mind that I'm new, most stuff go over my head) on what I should be doing instead. Or if the problem is interesting for you, your own implementation of it.
>>18267 >NOTE: I'd like to expand the "compiling options" later with more things to pick, so ideally I wouldn't attach the command I want to run directly to which major mode I'm currently in at the time. Let's say you wish to combine the major mode with the current day using this function: (defun day-string () (format-time-string "%a" (current-time))) For C maybe you have 'make run' on weekends and two 'test and debug' options on weekdays, while for Python test.py is added on any day that isn't Monday. The following list structure encodes that info (basically a more fancy alist): (compile-options (major-mode (day-string)) ((c-mode "Sat") "make run") ((c-mode "Sun") "make run") ((c-mode _) (("cc" file "-o /tmp/test") ("cc" file "-Drelease -o build"))) ((python-mode "Mon") ("python -u" file)) ((python-mode _) ("python -u" file "test.py"))) Where (major-mode (day-string)) could expand to (c-mode "Mon"), and matches ((c-mode _) ...) compile-options is just be a macro that expands to a pcase function: (defmacro compile-options (pattern &rest cases) `(defun compile-options-select () (pcase ,pattern ,@cases))) Which would be used like this: (completing-read "> " (compile-options-select)) How does that sound so far?
>>18277 The main issue with a date example is that it still wouldn't give me a list with options, but I tried remaking it as a simpler list, I couldn't for the life of me figure out how to switch back to the previous buffer with a simple hook, I don't understand why I couldn't do something simple like (add-hook 'after-make-frame-functions 'previous-window-any-frame). (defun my/compile-with-preset () "Prompt for a compilation preset then execute it." (interactive) (let* ((preset (completing-read "Select preset: " '("Run" "Release" "Test") nil t)) (cmd (pcase (list major-mode preset) (`(c-mode "Run") "make run") (`(c-mode "Release") "make release") (`(c-mode "Test") "make test") (`(python-mode "Run") (format "python -u %s" (buffer-file-name))) (`(python-mode "Release") (format "python -u %s" (buffer-file-name))) (_ (user-error "No compile option for %S" (list major-mode preset))))) (compilation-buffer (compile cmd t))) (pop-to-buffer compilation-buffer) (with-current-buffer compilation-buffer (add-hook 'compilation-finish-functions (lambda (_buffer _status) (previous-window-any-frame)) nil t)) (goto-char (point-max)))) (global-set-key (kbd "<f5>") 'my/compile-with-preset) One problem with this function that I'd like to solve is that, well, the list itself doesn't really change according to the major mode, all options are still displayed whether they exist or not. And if I'm being honest I really don't understand how else I'd do that other than making a list based on the major mode like I did before then calling it on the main function. I sent the function above on deepseek and after some trial and error I reached this: (defvar my/compile-presets '((c-mode ("Run" . (lambda () "make run")) ("Release" . (lambda () "make release")) ("Test" . (lambda () "make test"))) (python-mode ("Run" . (lambda () (format "python -u %s" (buffer-file-name)))) ("Module" . (lambda () (format "python -m %s" (read-string "Module name: "))))) "Alist mapping major modes to presets and their commands.")) (defun my/compile-with-preset () "Prompt for a compilation preset based on major mode, then execute it." (interactive) (let* ((mode-presets (alist-get major-mode my/compile-presets nil nil #'eq))) (unless mode-presets (user-error "No compile presets for %s" major-mode)) (let* ((preset (completing-read "Select preset: " (mapcar #'car mode-presets) nil t))
[Expand Post] (cmd-fn (cdr (assoc preset mode-presets))) (cmd (funcall cmd-fn)) (compilation-buffer (compile cmd t))) (pop-to-buffer compilation-buffer) (with-current-buffer compilation-buffer (add-hook 'compilation-finish-functions (lambda (_buffer _status) (previous-window-any-frame)) nil t)) (goto-char (point-max))))) (global-set-key (kbd "<f5>") 'my/compile-with-preset) But I really don't understand how that works, I wouldn't ever come up with that by myself and I don't know if that's a good way of achieving it or not. From reading I guess it works like - Listing the compatible modes listed in compile-presets and putting them in mode-presets - Using completing-read I list the available CAR - I pick the CDR of the selected car then... execute it? I think it has to work like that so I can evaluate buffer-file-name at runtime? - I send the result to compile, the rest works like the other one. Overall I quite like how the function works even though I didn't make it (I did add the "Module" option on python so you can see one of the potential uses of making it as a list) but my opinion doesn't matter much. What do you guys think? >why do you want it as a list?????? Because I want one...
>>18434 >The main issue with a date example is that it still wouldn't give me a list with options The idea was ((c-mode _) (("cc" file "-o /tmp/test") ("cc" file "-Drelease -o build"))) represented a case with two options (which would be expanded by the compile-options macro if you wanted me to continue writing it) >But I really don't understand how that works, I wouldn't ever come up with that by myself It's unusually written by deepseek for sure, I would rewrite the command selection part like: (defvar compile-presets '((c-mode ("Release" . "make release") ("Debug" . "make debug")) (python-mode ("Release" . (format "python -u %s" (buffer-file-name))) ("Debug" . (format "python -m %s" (read-string "Module: ")))))) (pcase (alist-get major-mode compile-presets) ((and (pred consp) list) (let ((command (eval (alist-get (completing-read "> " (mapcar #'car list) nil t) list nil nil #'equal)))) command)) (_ (user-error "No compile presets for %s" major-mode))) 'command' is then handed off to eshell or compile/compilation-buffer as you like
>>18443 Small revision: if you don't mind adding another function (of binding it locally with flet) this seems clearer: (defun assoc-read (list) (assoc (completing-read "> " (mapcar #'car list) nil t) list)) (pcase (alist-get major-mode compile-presets) ((and (pred consp) (app assoc-read `(,select . ,command))) command) (_ (user-error "No compile presets for %s" major-mode))) 'select' and 'command' are bound to the results of choosing from the alist, there's possibly a nicer way of writing assoc-read tho
If you were making a Lisp for serious use, what would you include? How would the base language be styled? Would you follow along with existing Lisps? Are there any nit-picks you have with the style of existing Lisps? Scheme uses a minimal but sufficient language as its base. Common Lisp does the opposite, and includes a fairly complete standard library. Clojure has a very particular standard library, advertises its sophisticated implementations of immutable data structures as its primary draw, but also includes many macros to yield its particular style. While I've always liked the Scheme approach, I often see Clojure devs boasting about how beautiful their language is. I feel I'm missing something there, since it's never looked as appealing to me. I'm looking to bike-shed a language I've been working on and particularly its macros sometime in the near future, and I wanted some general thoughts.


Forms
Delete
Report
Quick Reply