So I'm working on an #OrgMode document that's probably about 2/3 #emacs #lisp code. I'm planning on releasing it shortly, but I'm not sure what to do about the licensing. Normally I use the #AGPL for my code, but since this isn't strictly code, I'm wondering if some version of the #CreativeCommons license might be a better fit. Do they have a #copyleft variant?
in reply to Jonathan Lamothe

CC-BY-SA is Creative Commons' answer to copyleft. CC-BY-SA-4.0 is one-way compatible into GPLv3. (The 4.0 is important!)

There's no CC license that forces code all the way to AGPLv3, but you can say "code blocks AGPLv3, the rest CC-BY-SA-4.0." You have to choose whether a single license or the Affero clause matters more.

Just spent a day and a half hunting down a bug that was making me question my sanity. As it turns out, #emacs #lisp's / function silently drops the decimal in its result if both of its inputs are integers... so (/ 1 2) evaluates to 0, not 0.5. Granted, this is also the way that C does it, but in my defense, #CommonLisp does not do this.
in reply to Jonathan Lamothe

As a first approximation, I suggest thinking of Emacs Lisp as closer to MacLisp than to Common Lisp.

A precise description of "closer" would be fairly long.
For example, Emacs Lisp acquired things like bignums and lexical bindings fairly late.

Again as an approximation, the descendancies are:
MacLisp → Emacs Lisp
MacLisp and others → Common Lisp
(Those others include, in alphabetical order, Interlisp, Scheme, Zeta Lisp, etc., but not Emacs Lisp.)

And then an important aspect of these approximations is the `cl' package, also a late addition that evolved quite a bit.

Transferring knowledge about C to Emacs Lisp is rather tricky, even though the implementation of a part of Emacs (including the Emacs Lisp virtual machine) is written in C.

#CommonLisp
#Elisp
#Emacs
#EmacsLisp

@me

in reply to Jonathan Lamothe

yup of course, but that's integer math, not floating point math

GNU Clisp and SBCL don't show decimals for integer division, but return fractions instead!

* (/ 1 2)
1/2

But of course if you use floating point representation for the parameters then the result is a floating point number as expected:
[1]> (/ 1.0 2.0)
0.5

Elisp, with floating point parameters, also works as expected:
(/ 1.0 2.0)
0.5

In C, with IEEE 754 double values, then 1.0/2.0 = 0.50, exactly, no rounding or epsilon comparison needed.

Are there any #Lisp programmers out there who use a #ScreenReader? Given how messy Lisp can be to read without proper indentation (which I imagne wouldn't translate well on a screen reader) I can't see it is being an easy language to work in without being able to see it.

I've been thinking about a way to make an editor that lets you explore a Lisp program by walking through the forms in the program in a manner similar to the way one might navigate in a MUD. Is this a crazy idea, or one with some merit?

in reply to Jonathan Lamothe

Seemingly plain (lambda () ...) is a macro that expands to (function (lambda () ...)). #'(lambda () ...) uses a reader macro to expand to the same (function (lambda () ...)).

clhs.lisp.se/Body/m_lambda.htm

Function is a special operator that returns a function. It takes either a function name or a lambda expression. The second case is what is happening here.

clhs.lisp.se/Body/s_fn.htm#fun…

A lambda expression is a list of the symbol lambda, a lambda list, and a body.

clhs.lisp.se/Body/26_glo_l.htm…

elisp
God, my tab completion function is a hacky mess:
(defun lambdamoo-tab-complete ()
  "Complete user input using text from the buffer"
  (interactive)
  (when (memq (char-before) '(?  ?\r ?\n ?\t ?\v))
    (user-error "Point must follow non-whitespace character"))
  (let (replace-start
        (replace-end (point))
        replace-text found-pos found-text)
    (save-excursion
      (backward-word)
      (setq replace-start (point)
            replace-text (buffer-substring replace-start replace-end))
      (when (or (null lambdamoo--search-text)
                (not (string-prefix-p lambdamoo--search-text replace-text t)))
        (setq-local lambdamoo--search-text replace-text)
        (set-marker lambdamoo--found-point (point)))
      (goto-char lambdamoo--found-point)
      (unless
          (setq found-pos
                (re-search-backward
                 (concat "\\b" (regexp-quote lambdamoo--search-text))
                 (point-min) t))
        (setq-local lambdamoo--found-point (make-marker))
        (user-error "No match found"))
      (set-marker lambdamoo--found-point found-pos)
      (forward-word)
      (setq found-text (buffer-substring found-pos (point))))
    (delete-region replace-start replace-end)
    (insert found-text)))

#emacs #lisp #moo #mud #LambdaMOO

reshared this

elisp question

I'm certain I have reinvented a wheel here, but for the life of me I can't find it. Have I?

(defmacro jrl-extract-list (vars list &rest body)
  "Split a list into indiviual variables"
  (let ((list* (gensym)))
    (append
     `(let ,(cons (list list* list) vars))
     (seq-map (lambda (var)
                `(setq ,var (car ,list*)
                       ,list* (cdr ,list*)))
              vars)
     body)))

#emacs #lisp #elisp

Edit: Of course it was pcase.

elisp question

I just put a call to eval in my code and I feel dirty now.

The context went something like this:

(eval (cons 'concat (my-function arg1 arg2)))

I had initially hoped to use
(concat . (my-function arg1 arg2))

...but this resulted in a call to
(concat my-function arg1 arg2)

Which was not what I expected.

Is there a better way I could've written this?
#emacs #lisp #elisp

Edit: Got my answer. I wanted:

(apply 'concat (my-func arg1 arg2))

Edit 2:
It turns out the code I really wanted was:

(string-join arg2 arg1)

I love reinventing the wheel because I didn't know it was already there.

Edit 3:
Here's the actual code:

(defun lambdamoo-run-text-replacements (str)
  "Perform text replacements on the string"
  (dolist (vals lambdamoo-text-replacements)
    (let* ((from (car vals))
           (to (cdr vals))
           (split (split-string str from)))
      (setq str (string-join split to))))
  str)

Let's see if there's anything else I've reinvented here.

I just wrote a bunch of #elisp code like this:
(catch :abort
  ;; do something
  (when condition
    (message "A bad thing happened")
    (throw :abort nil))
  ;; do something else
  )

When the functionality I really wanted was:
(progn
  ;; do something
  (when condition
    (user-error "A bad thing happened"))
  ;; do something else
  )

I knew the former felt sketchy, but I couldn't think of a better way to do it until just now.
#emacs #lisp
in reply to Jonathan Lamothe

As a Schemer (and formerly/sometimes still Objective-C), everything is pretty verbose, and my own functions even more so, so I can search by function name knowing the type and parameters. (vector-index vec searchfunc), (draw-rect-with-edge-color rect edge-width color), etc.

There's no excuse for hardcore Lisp functions like (wadsf w q) "wander down stack frames for word query" (fictional but not unlikely).
#lisp

#lisp

#Elisp logic:

All interned symbols can be found in a lookup table. This table is bound to the obarray symbol.

Hang on a minute...

I can only assume that the underlying C code has its own pointer to this table and the obarray symbol is only provided as a convenience for elisp functions that can't see this pointer?
#emacs #lisp

in reply to James Endres Howell

@James Endres Howell
I'm a little self-conscious about it as non-trivial is relative, but...
(defmacro lambdamoo-chatter-interact
    (func-name to msg docstring fmtstr &rest vals)
  "Define a function for interacting with another player"
  (let ((proc (gensym))
        (str (gensym)))
    `(defun ,func-name (,proc ,str)
       ,docstring
       (let ((,to lambdamoo-chatter)
             (,msg (substring-no-properties (lambdamoo-command-text ,str))))
         (if ,to
             (funcall lambdamoo-send-line ,proc
                      (format ,fmtstr . ,vals))
           (message "No chatter specified"))))))

This website uses cookies. If you continue browsing this website, you agree to the usage of cookies.