<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"><title>Alex's Adventures on the Infobahn - examples</title><link href="https://www.bennee.com/~alex/" rel="alternate"></link><link href="https://www.bennee.com/~alex/blog/tag/examples/feed" rel="self"></link><id>https://www.bennee.com/~alex/</id><updated>2011-04-13T16:27:00+01:00</updated><subtitle>the wanderings of a supposed digital native</subtitle><entry><title>completion-ignored-extensions</title><link href="https://www.bennee.com/~alex/blog/2011/04/13/completion-ignored-extensions/" rel="alternate"></link><published>2011-04-13T16:27:00+01:00</published><updated>2011-04-13T16:27:00+01:00</updated><author><name>alex</name></author><id>tag:www.bennee.com,2011-04-13:/~alex/blog/2011/04/13/completion-ignored-extensions/</id><summary type="html">&lt;p&gt;I've been using the rather spiffy &lt;a class="reference external" href="http://www.emacswiki.org/emacs/LustyExplorer"&gt;Lusty Explorer&lt;/a&gt; for some time for my buffer and file finding. However it (I thought) had a rather annoying bug where I could never tab directly into some of the repositories I was hacking on. Eventually I figured out that the problem was down …&lt;/p&gt;</summary><content type="html">&lt;p&gt;I've been using the rather spiffy &lt;a class="reference external" href="http://www.emacswiki.org/emacs/LustyExplorer"&gt;Lusty Explorer&lt;/a&gt; for some time for my buffer and file finding. However it (I thought) had a rather annoying bug where I could never tab directly into some of the repositories I was hacking on. Eventually I figured out that the problem was down to the way I name them.&lt;/p&gt;
&lt;p&gt;My naming scheme for any repository is generally to add the version control extension to the directory. This is more for my benefit than emacs as it's quite capable of working this out for itself in any given repo. However it turns out that Lusty was being a good emacs citizen and using the variable &lt;em&gt;completion-ignored-extensions&lt;/em&gt; which included the pattern &amp;quot;.git/&amp;quot; and duly hiding my repo directories from completion. In fact there are a number of patterns in there which should probably be more specific. I wrote this to fix the problem:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
(setq completion-ignored-extensions
      (mapcar '(lambda (ext)
                 (if (string-equal &amp;quot;/&amp;quot; (substring ext -1 nil))
                     (concat &amp;quot;^&amp;quot; ext)
                   ext)) completion-ignored-extensions))
&lt;/pre&gt;
&lt;p&gt;It still seems a little ugly to me so given the &lt;a class="reference external" href="http://www.bennee.com/~alex/blog/2010/08/10/looping-in-lisp/"&gt;last time I berated elisp's style&lt;/a&gt; gained so many useful suggestions I'd welcome improvements.&lt;/p&gt;
</content><category term="geek"></category><category term="code"></category><category term="elisp"></category><category term="emacs"></category><category term="examples"></category></entry><entry><title>Looping in LISP</title><link href="https://www.bennee.com/~alex/blog/2010/08/10/looping-in-lisp/" rel="alternate"></link><published>2010-08-10T09:04:00+01:00</published><updated>2010-08-10T09:04:00+01:00</updated><author><name>alex</name></author><id>tag:www.bennee.com,2010-08-10:/~alex/blog/2010/08/10/looping-in-lisp/</id><summary type="html">&lt;p&gt;Loops are a fairly important part of any programming language and fairly fundamental to a language that is purported to be all about manipulating lists. However it's not something I use that often in my .emacs code so I thought it might be useful to discuss the various options with …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Loops are a fairly important part of any programming language and fairly fundamental to a language that is purported to be all about manipulating lists. However it's not something I use that often in my .emacs code so I thought it might be useful to discuss the various options with some examples.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Problem:&lt;/strong&gt; I run emacs on a number of machines, each with a different set of sound sets. I want to set up set up a valid sound for erc but I don't want an overly verbose set of cases depending on what machine I'm on. Instead a given a list of sound files I want a function that will return the first one that actually exists.&lt;/p&gt;
&lt;p&gt;This problem can be easily generalised into return the first valid path from a list of paths.&lt;/p&gt;
&lt;div class="section" id="first-version-pure-emacs-lisp"&gt;
&lt;h2&gt;First version: pure emacs lisp&lt;/h2&gt;
&lt;pre class="literal-block"&gt;
; the 'elisp' way
(defun find-valid-file-elisp-way (list-of-files)
  &amp;quot;Go though a list of files and return the first one that is present&amp;quot;
  (let (r '())
    (mapc '(lambda (f)
             (if (file-exists-p f) (add-to-list 'r f)))
          list-of-files)
    (car r)))
&lt;/pre&gt;
&lt;p&gt;First impressions aren't good. The lisp parenthesis do seem to get in the way of making what is happening clear. However it's using one of common &lt;a class="reference external" href="http://www.gnu.org/s/emacs/manual/html_node/elisp/Mapping-Functions.html"&gt;mapping functions&lt;/a&gt; you see a lot of in lisp. A mapping function essentially takes a list, applies a function to each element of the list and eventually returns a result. The most common of the mapping functions is &lt;em&gt;mapcar&lt;/em&gt; which returns a modified list as a result. In this case that isn't what we want so we use &lt;em&gt;mapc&lt;/em&gt; where the only value that is built up is the result &lt;em&gt;r&lt;/em&gt; as we identify each valid file. The final return value is just the first entry in that list. This does mean we have processed the whole list of alternatives which is sub-optimal.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="second-version-common-lisp-version"&gt;
&lt;h2&gt;Second version: Common Lisp Version&lt;/h2&gt;
&lt;pre class="literal-block"&gt;
(defun find-valid-file-clisp-way (list-of-files)
  &amp;quot;Go though a list of files and return the first one that is present&amp;quot;
  (loop for path in list-of-files
        until (file-exists-p path)
        finally return path))
&lt;/pre&gt;
&lt;p&gt;This version probably is the easiest to read for people familiar with other programming languages. The intention of the code jumps out at you. However the actual implementation is done with a macro. If you look at the help for &lt;em&gt;loop&lt;/em&gt; you'll see it can take a number of different forms - follow that to the code and you'll see a fairly complex elisp implementation. However to my mind still easier to follow than the pure elisp version with mapc.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="third-version-using-the-dolist-macro"&gt;
&lt;h2&gt;Third Version: Using the dolist macro&lt;/h2&gt;
&lt;pre class="literal-block"&gt;
; using 'cl-macs
(defun find-valid-file-dolist-way (list-of-files)
  &amp;quot;Go though a list of files and return the first one that is present&amp;quot;
  (dolist (f list-of-files)
    (if (file-exists-p f)
        (return f))))
&lt;/pre&gt;
&lt;div class="line-block"&gt;
&lt;div class="line"&gt;This is yet another version using an LISP macro but this one has considerably less potential forms to cause confusion. It's fairly comprehensible what is going on and even follows the traditional parenthesis happy form. It also takes advantage of the common LISP &lt;em&gt;return&lt;/em&gt; to early return from the loop when we detect a valid file. If it makes it to the end of the list it evaluates the 3rd optional form to calculate the result which in this case will be 'nil.&lt;/div&gt;
&lt;div class="line"&gt;&lt;br /&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;So what do you think? What version do you prefer? Where does the balance lie between writing code is LISPy ways and for code comprehension? Are there any other ways to solve this particular problem? I'll be looking forward to your comments.&lt;/p&gt;
&lt;/div&gt;
</content><category term="geek"></category><category term="code"></category><category term="elisp"></category><category term="emacs"></category><category term="examples"></category><category term="lisp"></category></entry></feed>