Org 9.3.6

Bastien lets us know that Org 9.3.6 has been released:

It’s another bug release but the Org 9.4 with new features is coming soon.

Posted in General | Tagged , | Leave a comment

How To Start a Common Lisp Project

As I mentioned the other day, I haven’t been using Common Lisp much lately so I was a little rusty when I wrote my A Palindrome Predicate Coda post. It’s not that I forgot the Lisp itself, that’s sufficiently like Elisp, which I use all the time, that it’s easy to move between them. The problem is all the machinery you need to start a Common Lisp project: inscrutable things like ASDF and all that goes with it. It’s not that it’s hard, it’s just fussy and easy to forget the details if you don’t use it all the time.

As far as ASDF and dealing with libraries goes, Zach Beane’s Quicklisp goes a long way towards hiding all the complexity. If you’re writing in Common Lisp and not using Quicklisp, you’re working too hard. Beane has another package, Quickproject, that takes care of getting a Lisp project started by providing a template for the project. It’s also very nice and I use it whenever I’m starting a new CL project.

Baggers (Chris Bagley) has an excellent short video on using Quickproject to start a new project. The video is from 2013 but it’s still accurate and useful. Baggers walks you through loading Quickproject—with Quicklisp, of course—if you don’t already have it loaded and then making a trivial project. He also shows one of his real projects so you can see a more complex example.

The video is only 6 minutes, 37 seconds so it’s easy to find time for it. If, like me, you haven’t been using Common Lisp regularly and need a refresher on getting started, it’s 6 and a half minutes well spent.

Posted in General | Tagged , | Leave a comment

Emacs As a Terminal IDE

Palmer Cluff has an interesting post that makes the case for Emacs as a terminal-based IDE. We usually think of IDEs as having a GUI, lots of buttons and menus and of being mouse intensive. Cluff says it doesn’t have to be that way and that Emacs—even in terminal mode—can be a perfectly fine IDE.

His post discusses some of the packages that you’ll need to realize this and at the end he warns us to be ready to spend some time configuring our Emacs to make it the way we want it. Some people are put off by that, I guess, but I think of it as an enjoyable exercise in getting things just the way I want them. The key is that it’s an ongoing process not something that requires you to stop what you’re doing and devote a large block of time to configuring Emacs. I’ve been using Emacs for about 12 years and I’m still tweaking my environment regularly.

Cluff doesn’t make—or try to make—the case that you should prefer terminal Emacs over the GUI version. He merely says that sometimes—when you’re logged into a remote machine, say—it makes sense to use the lighter weight terminal version. Those of us who work with fast and reliable networks are incline to say, “Bah! Just use tramp.” but sometimes we’re using a slow network and the GUI version is just too painful. In those cases, it makes sense to SSH into the remote host and use a terminal Emacs, especially for small tweaks to a large file.

In any event, you’ll probably enjoy reading how Cluff gets his terminal Emacs as close as possible to an IDE.

Posted in General | Tagged | Leave a comment

Bastien’s Org-mode Tricks

If you follow the Emacs scene, you’ve probably seen some references to Bastien Guerry’s post on Org-mode Features You May Not Know. There’s been several tweets about it and, of course, Sacha covered it in her Weekly Emacs News. If you haven’t already seen it and you’re an Org user you should definitely take a look. There are a lot of useful tips that, as Guerry says, you may not know.

It doesn’t make any sense for me to repeat his list of tips but I do want to mention three that I found especially useful. Two of them I didn’t know before so I found them especially helpful. The first is that if you have speed keys enabled (setq org-use-speed-commands t), and the cursor is at the beginning of a headline, you can narrow to the headline’s subtree by typing s. I’ve already used this a couple of times and it really is useful, especially when you’re dealing with headlines that have nearly identical data.

The second tip I didn’t know about was applying filters to the agenda. If you have the an agenda up and want to look at only certain entries—say to save them to another file—you can type = and a regular expression to see only those entries that satisfy the regex. Another = or a | clears the filter.

Finally, there’s timestamped lists. I first learned about this in one of Rainer König’s videos in his OrgMode tutorial series. The idea is that you can make a list with each entry having a relative timestamp. That’s perfect for taking notes about a lecture or video where you want to refer to specific parts of the lecture or video. You start the list with Ctrl+c Ctrl+x - and new entries with the usual Meta+Return.

There are several other use tips in Guerry’s post so be sure to check it out if you’re an Org user. Some you may have no use for, some you may already know, but others may be both new and useful to you. Definitely recommended.

Posted in General | Tagged , | Leave a comment

Working Remotely at Ars Technica

Over the next few weeks, Ars Technica will be running a series of articles on the future of work. They’ve started off with a long and detailed article on working remotely at Ars Technica. Actually, working at Ars Technica means working remotely because they have an all digital newsroom. The entire editorial staff works remotely—there is no physical editorial office. Ars Technica is owned by Condé Nast, which does, of course, have offices and which takes care of the business side of things—things like sales, marketing, legal, and HR. That leaves the editorial staff free to concentrate on finding and writing stories. The folks at Ars Technica are used to the arrangement; They’ve been operating that way for 20 years.

The editorial staff at Ars Technica enjoys remarkable autonomy. Each member chooses his own technology and is not forced into using a company standard. Their choices do, of course, have to support the common applications that the staff uses but there aren’t very many of those. They use WordPress as their CMS so writers can use whatever tool they choose to write their copy and then upload it to WordPress.

Oddly, rather than use one of the shiny new communication apps, Ars Technica depends on email for most of its day-to-day communication. That has the advantage of providing a permanent record of “conversations” as well as not ripping a writer out of flow by demanding their immediate attention. They use Gmail because it works with all of the systems that the staff uses.

They also use Slack and spreadsheets to keep track of who’s doing what and stories in progress. The article has a long section on their workflow, which I found very interesting. There’s a lot more in the article so be sure to take a look if you’re interested in remote work.

The Ars Technica example is particularly interesting to me because they’re an edge case: they’re not an “also-remote workplace” or a “remote-first workplace”, they’re a “remote-only workplace.” My take is that all-in-all that makes things easier. There’s no “office people are more tuned in” problems or the other difficulties of that sort. It’s really matter of having some agreed upon technology for communication and some simple procedures to make everyone work for the common goal.

Posted in General | Tagged | Leave a comment

Zamansky 66: An Eshell Switcher

Mike Zamansky has another video up in his Using Emacs Series. The video is about his trying to use eshell more and building an eshell switcher so that he can easily switch among his active eshell instances. I really like this video because it offers another example of the joys and strengths of what I call “interactive programming.” By interactive programming, I mean the ability to try out small snippets of code, see what they return, and combine these into ever bigger pieces until you have the desired functionality.

Zamansky starts off by mentioning the exec-path-from-shell package, Steve Purcell’s excellent package to make Emacs aware of your PATH and other environment variables. If you’re running on MacOS, this package is pretty much mandatory if you don’t want Emacs to drive you crazy with “Not Found” messages. Zamansky’s use is the first time I’ve seen it used on a Linux system so it has wider applicability than I thought.

The rest of the video shows Zamansky building his switcher app. It’s a wonderful demonstration of how nice Elisp development can be. Even if your Elisp is rusty—as Zamansky says his is—you can experiment by trying various functions until you find one that returns what you need. He literally builds the function brick by brick by continually adding small snippets of code until he has a working function.

I’ve used eshell for a long time but I’ve never felt the need for multiple instances. Perhaps this video will inspire me to expand my horizons. The video is 23 minutes, 43 seconds long so you’ll probably need to schedule some time but if you’re interested in eshell or in Elisp programming, you should definitely find the time to watch it.

Posted in General | Tagged , | Leave a comment

Finding Intersections Redux

Last month, I published a post on Finding The Intersection of Two Lists. The impetus for the post was an Emacs Stack Exchange question asking if there was a better way to find the intersection of two lists than looping over both of them. I thought putting the entries of the first list in a hash table and checking the entries of the second list against it was a better solution and I wrote some code to check out that hypothesis. You can see the details in the original post.

I got some gentle pushback from two Elisp luminaries, Chris Wellons and Alphapapa. Wellons noted that I could get a small speed increase by using dolist instead of mapc. More importantly, he noted that I should have compiled my code with lexical mode as that makes a large difference in running time.

Alphapapa, commenting as NoonianAtall, noted that I wasn’t eliminating duplicates and pointed me at some macros that make benchmarking this type of thing easier. He published a gist that showed one of those macros in action.

Naturally, I had to check all this out. I wrote a new version of hash-intersection that used dolist instead of mapc and also made a small change (hash-intersection-dedup) to the algorithm so that duplicates were eliminated. Finally, I stole Alphapapa’s version of the code that uses the loop macro instead dolist.

Here’s all the code, including the bit to generate random lists, for reference:

(require 'epdh)
(require 'dash-functional)
(defun make-random-list (n)
  (let ((l nil))
    (dotimes (i n l)
      (push (random 1500) l))))

(defconst lst1 (make-random-list 1000))
(defconst lst2 (make-random-list 1000))

(defun hash-intersection-orig (l1 l2)
  (let ((ht (make-hash-table :test #'equal))
        (acc nil))
    (mapc (lambda (x) (puthash x t ht)) l1)
    (mapc (lambda (x) (if (gethash x ht nil)
                          (push x acc)))
          l2)
    acc))

(defun hash-intersection-dolist (l1 l2)
  (let ((ht (make-hash-table :test #'equal))
        (acc nil))
    (dolist (l l1)
      (puthash l t ht))
    (dolist (l l2)
      (if (gethash l ht nil)
          (push l acc)))
    acc))

(defun hash-intersection-dedup (l1 l2)
  (let ((ht (make-hash-table :test #'equal))
        (acc nil))
    (dolist (l l1)
      (puthash l t ht))
    (dolist (l l2)
      (when (gethash l ht nil)
        (puthash l nil ht)              ;only one to a customer
        (push l acc)))
    acc))

;; From Alphapapa
(defun hash-intersection-loop (l1 l2)
  (let ((ht (make-hash-table :test #'equal) ))
    (cl-loop for e1 in l1
             do (puthash e1 t ht))
    (cl-loop for e2 in l2
             when (gethash e2 ht)
             collect it)))

Now we’re ready to test Wellons’ claims. First, I used the bench-dynamic-vs-lexical-binding macro to measure the difference that compiling with lexical bindings made:

(bench-dynamic-vs-lexical-binding
  :times 100
  :forms (("hash-intersection-orig"   (progn
                                        (defun hash-intersection-orig (l1 l2)
                                          (let ((ht (make-hash-table :test #'equal))
                                                (acc nil))
                                            (mapc (lambda (x) (puthash x t ht)) l1)
                                            (mapc (lambda (x) (if (gethash x ht nil)
                                                                  (push x acc)))
                                                  l2)
                                            acc))
                                        (hash-intersection-orig lst1 lst2)))))
Form x faster than next Total runtime # of GCs Total GC runtime
Lexical: hash-intersection-orig 1.25 0.027208 0 0
Dynamic: hash-intersection-orig slowest 0.033979 0 0

Just as Wellons promised, the lexical version is 25% faster. Next, I compared all the implementations (as well as seq-difference) compiled with lexical bindings. There were a couple of surprises. First, the deduping version ran slightly faster than the dolist version. That was a pretty consistent result across several runs of the comparison. The only reason for it that I can see is that eliminates the push for all the duplicates.

A bit more surprising is that the dolist version ran 28% faster than the mapc version. That seems pretty high but the numbers did jump around a bit between different runs so perhaps it’s just an anomaly. If you want to play around with Alphapapa’s macros (they’re here) that would be a good experiment to run. There are more macros than I’ve mentioned here so they should meet whatever your benchmarking needs are.

(bench-multi-lexical
  :times 100
  :forms (("hash-intersection-orig"   (progn
                                        (defun hash-intersection-orig (l1 l2)
                                          (let ((ht (make-hash-table :test #'equal))
                                                (acc nil))
                                            (mapc (lambda (x) (puthash x t ht)) l1)
                                            (mapc (lambda (x) (if (gethash x ht nil)
                                                                  (push x acc)))
                                                  l2)
                                            acc))
                                        (hash-intersection-orig lst1 lst2)))
          ("hash-intersection-dolist"   (progn
                                          (defun hash-intersection-dolist (l1 l2)
                                            (let ((ht (make-hash-table :test #'equal))
                                                  (acc nil))
                                              (dolist (l l1)
                                                (puthash l t ht))
                                              (dolist (l l2)
                                                (if (gethash l ht nil)
                                                    (push l acc)))
                                              acc))
                                          (hash-intersection-dolist lst1 lst2)))
          ("seq-intersection" (seq-intersection lst1 lst2))
          ("hash-intersection-loop"   (progn
                                        (defun hash-intersection-loop (l1 l2)
                                          (let ((ht (make-hash-table :test #'equal) ))
                                            (cl-loop for e1 in l1
                                                     do (puthash e1 t ht))
                                            (cl-loop for e2 in l2
                                                     when (gethash e2 ht)
                                                     collect it)))
                                        (hash-intersection-loop lst1 lst2)))
          ("hash-intersection-dedup"   (progn
                                         (defun hash-intersection-dedup (l1 l2)
                                           (let ((ht (make-hash-table :test #'equal))
                                                 (acc nil))
                                             (dolist (l l1)
                                               (puthash l t ht))
                                             (dolist (l l2)
                                               (when (gethash l ht nil)
                                                 (puthash l nil ht) ;only one to a customer
                                                 (push l acc)))
                                             acc))
                                         (hash-intersection-dedup lst1 lst2)))))
Form x faster than next Total runtime # of GCs Total GC runtime
hash-intersection-dedup 1.02 0.021943 0 0
hash-intersection-loop 1.09 0.022341 0 0
hash-intersection-dolist 1.28 0.024367 0 0
hash-intersection-orig 315.94 0.031197 0 0
seq-intersection slowest 9.856230 0 0

Finally, I should mention that the macros are part of Alphapapa’s Emacs Package Developer’s Handbook, which has a wealth of useful information—even if you aren’t writing packages—and is definitely worth taking a look at if you haven’t already.

Update [2020-02-08 Sat 11:22]: NoonianAtall (Alphapapa) says that I should have included cl-intersection and -intersection in my comparisons. Fortunately, he’s already done that in the gist that I mentioned so you can check them out there. Cl-intersection is, of course, included with Emacs and -intersection is from Dash which you probably also have since it’s a dependency of many popular packages.

Posted in General | Tagged , | Leave a comment

Restoring the Elfeed Default Filter

I’m a very happy user of Chris Wellons’ excellent RSS reader, elfeed. It has a very powerful search/filter function that lets you control what entries will be displayed and to search for an older entry that you want to revisit. Elfeed has a useful default filter that displays unread items younger than six months old. You can configure the default filter, of course, but the built-in one works well for me so I use it.

The problem is that I can never remember the syntax for the default filter so when I do a search, I always have to look up the incantation to restore the filter to “unread items from the last six months.” A consequence of that is that I didn’t use the search function as often as I otherwise would have. I’ve just discovered that I’ve been doing things the hard way. It turns out that if you clear the current filter, the default is restored. I don’t know if this is a recent addition or if it’s always been that way and I just missed it when I was learning to use Elfeed.

In either case, you can call elfeed-search-clear-filter or use the shortcut c to clear the current filter and restore the default. It’s embarrassing to admit that I was ignorant of a feature that makes the Elfeed experience so much better for this long. If you’re an Elfeed user and didn’t know this, you’re welcome.

Posted in General | Tagged | Leave a comment

Thought of the Day

From Karl Voit, we have this bit of wisdom:

You can take this in two ways:

  1. Development of Emacs in ongoing and robust.
  2. Emacs is infinitely extensible so even in the absence of point 1, you can make it adapt to new situations.

Regardless, until there is a huge paradigm shift in computing, I expect Emacs will continue to be a relevant and useful tool.

Pouya Abbassi also has some appropriate words along the same lines:

Posted in General | Tagged | Leave a comment

Palindromes With a Sufficiently Smart Compiler

Those of you who enjoyed my post on palindrome predicates may also like Joe Marshall’s follow-up to his original post that inspired mine. In it, he considers the two implementations—recursive and iterative—and what it would take for a sufficiently smart compiler to generate code for the recursive algorithm that’s as efficient as that for the interative algorithm.

He does that by imagining a series of steps that such a compiler might take to transform the recursive solution into the iterative one. The lowest hanging fruit is, of course, to get rid of the string copying that the substring function does in most implementations of Scheme (and all conforming implementations of Common Lisp). The Guile Scheme implementation almost does this—see the discussion by Chris Wellons in my original post. That single optimization produces a dramatic improvement in performance. When I ran the same test with Chez Scheme, which does not implement copy-on-modify semantics for stringcopy the execution went from a little over 9 seconds to over an hour and a half.

Marshall doesn’t stop there. He continues with a set of more or less reasonable steps that a smart compiler might make until the two implementations are the same. (One of those steps is unlikely to be made by a compiler, regardless of how smart it is, but is nevertheless possible.) Marshall doesn’t mean for his post to be taken as a serious suggestion: it’s more of a thought experiment. It’s an interesting exercise in understanding how some simple steps can make code significantly better.

Posted in General | Leave a comment