Feeds:
Posts
Comments

Archive for the ‘Emacs’ Category

Of the languages I know, emacs-lisp is unusual in that when you need to access the field of a structure, you need to know the name of the type1.

(defstruct person age name)
(defvar dave (make-person))
(setf (person-age dave) 20) ;; getter specifies the type!
(setf (person-name dave) "David Jones")
(message (person-name dave)) ;; -- David Jones

Notice I can’t say (age dave) here, it has to be (person-age ...).

The underlying reason for this is that structures are really vectors. (person-age object) translates into (aref object 1) which should hopefully be pretty fast. Another structure doesn’t need to keep its age member at an offset of 1, so I can’t say it is (generic-structure-age object).

In basic perl objects, because they are really just a hash reference, I don’t need to specify the type. When it is needed, the VM figures it out at runtime.

package Person;

sub new
{
    bless {}, $_[0];
}

package main;

my $dave = Person->new(); # Type specified here
$dave{'age'} = 20;        # but not here
$dave{'name'} = 'David Jones';

print $dave{'name'}, "\n";
$ perl t.pl
David Jones

In many statically typed languages, the fact that the compiler knows what the type is enables it to generate efficient code. I still don’t need to specify it explicitly.

#include 
#include 

using namespace std;

struct person
{
    int age;
    string name;
};

int main()
{
    person dave;

    dave.age = 20;             // No type explicitly specified here
    dave.name = "David Jones"; // or here

    cout << "Name: " << dave.name << "\n";
}
$ g++ t.cpp
$ ./a.exe
Name: David Jones
$

For objects created using the new version of defstruct* I’ve defunned a get-field and set-field that don’t require the type to be specified. Error checking is, as usual, elided

(defsubst get-index (object field)
  (cdr (assoc field (symbol-value (aref object 1)))))

(defun get-field (object field)
  (aref object (get-index object field)))

(defun set-field (object field value)
  (setf (aref object (get-index object field)) value))

(get-field dave 'name)
(set-field dave 'name "Simon Smith")

Although by this time we’re probably both wondering why I didn’t just use a hash like all the (other) scripting languages.


1. To be more accurate, you need to tell the computer what the type is. Obviously, if you want to do something useful with an object, you generally need to know what type it is anyway.

Read Full Post »

I made a complete mess of my earlier recursive macros post. I hadn’t surrounded the two function calls with progn so only the last one was called. Not only that, but I hadn’t fixed up defstruct* to work with the function instead of the macro.

It is all fixed up now. Take a look.

What happened?

Obviously I tested it before I posted (although I admit it was rushed). What went wrong?

I’ve actually been caught out by the convenience of the REPL.

During testing, one of my iterations managed to create a struct--params variable and subsequent tests just worked.

Oops, I’ll need to take more care in the future.

Read Full Post »

and why you probably won’t need them

I was thinking it would be nice to have a type of structure that would know in what index each of its parameters is stored. Why might this be useful? Because then you don’t need to know the name of the type to access its data.

It is simple enough to make a wrapper around defstruct. First define a constant that stores a map of parameter name to index, and then keep a reference to that constant at a fixed position in the structure.

(defmacro defstruct* (struct-name &rest params)
  (let ((constant (intern (format "%s--params" struct-name))))
    `(progn
       (defconst ,constant (_params-indices-map 2 ,@params))
       (defstruct ,struct-name (param-indices ,(list 'quote constant)) ,@params))))

For the map, we’re going to use an association list, and something like a b c should expand to ((a . 2) (b . 3) (c . 4)). As the first two slots in the vector are taken up by the structure name and the map itself, indices start at 2.

(defmacro _params-indices-map (counter &rest params)
  (if params
      `(cons (cons ,(list 'quote (car forms)) ,counter)
             (_params-indices-map (1+ ,counter) ,@(cdr params)))
    nil))

But we didn’t really need a recursive macro here at all. And they are painful to debug.

(macroexpand '(_params-indices-map 2 a b c)) ;; expands to
(cons (cons (quote a) 2) (_params-indices-map (1+ 2) b c))

We could have used a function much more easily.

(defun _params-indices-map (params)
  (let ((counter 2) retval)
    (dolist (var params)
      (push (cons var counter) retval)
      (setq counter (1+ counter)))
    retval))

defstruct* needs to be fixed up slightly. We no longer need to pass the counter in to _params-indices-map.

(defmacro defstruct* (struct-name &rest params)
  (let ((constant (intern (format "%s--params" struct-name))))
    `(progn
       (defconst ,constant (_params-indices-map '(,@params)))
       (defstruct ,struct-name (param-indices ,(list 'quote constant)) ,@params))))
(defstruct* struct a b c)
(cdr (assoc 'a struct--params)) ;; --> 2
(make-struct) ;; --> [cl-struct-struct struct--params nil nil nil]

Now of course, this won’t work correctly for more complex structures that initialise their parameters. Fixing that is left as an exercise for the reader :)

Read Full Post »

Recently I have been adding more and more functionality into emacs using comint. And as there are more and better perl libraries for hooking into other systems (such as DBI, SOAP, HTTP…), I often start with a script that reads commands from stdin and writes the result to stdout. That is the comint way.

use strict;
use warnings;

use 5.010;

init(); # -- some initialization that takes a while

# ...

while (defined(my $command = <STDIN>)) {
    chomp $command;

    given (lc($command)) {
        when (/^\s*exit\s*$/)    { exit 0; }
        when (/^\s*send\s*$/)    { say 'send' }
        when (/^\s*receive\s*$/) { say 'receive' }
        default { say "Error: unrecognized command $command"; }
    }
}

If initialisation takes a long time, it is a big saving to only do it once for many commands.

As emacs has full control over the process, I can control what gets sent and filter what is received before display. However, I prefer to be a little bit flexible with what the perl process receives for when I am testing it from the command line. That is why I allow surrounding spaces.

when (/^\s*exit\s*$/)    { ... }
when (/^\s*send\s*$/)    { ... }
when (/^\s*receive\s*$/) { ... }

Those matching regexes look pretty similar. I almost feel like I’m violating DRY.

Unfortunately, the subroutine references only take a single parameter.

sub cexit { return $_[0] =~ /^\s*exit\s*$/ }
sub csend { return $_[0] =~ /^\s*send\s*$/ }
sub creceive { return $_[0] =~ /^\s*receive\s*$/ }

# ...

when (\&cexit)    { exit 0; }
when (\&csend)    { say 'send' }
when (\&creceive) { say 'receive' }

But there is a way of storing data along with a subroutine – a closure. However, the following strangely doesn’t work.

sub match_command
{
    my $command = shift;
    return sub {
        my $input = shift;
        say "Input is [$input]";
        return $input =~ /^\s*$command\s*$/;
    }
}

while (defined(my $command = <STDIN>)) {
    chomp $command;

    given (lc($command)) {
        when (match_command('send')) { say 'send' }
        when (match_command('exit')) { exit 0; }
        when (match_command('receive')) { say 'receive' }
        default { say "Error: unrecognized command $command"; }
    }
}

Whereas storing the closures in a variable before smart matching does work. Unfortunately it looks like smart matching isn’t smart enough for my needs.

my $send = match_command('send');
my $exit = match_command('exit');
my $receive = match_command('receive');

# ...

when ($send) { say 'send' }
when ($exit) { exit 0; }
when ($receive) { say 'receive' }

And the result:

c:\home\juang>perl t.pl
send
Input is [send]
send
exit
Input is [exit]

Read Full Post »

Terse Hashes Miscellany

This is part 4 in my terse hashes in emacs lisp series

Okay, time to wrap up with the terse hashes.

The built-in hash tables have equivalents to the perl exists and delete, but again, the argument order does not feel right to me.

Having looked at ruby a bit over the past few months, I’ve decided I like predicates ending with a question mark1 rather than a p.

(defsubst exists? (hash key)
  (not (eq (gethash key hash 'missing-key) 'missing-key)))

(defsubst del-hash! (hash key) (remhash key hash))

And the other thing I rely on a lot in perl is keys so I can choose the traversal order with sort.

(defun keys (hash)
  (let (keys)
    (maphash (lambda (k v) (push k keys)) hash)
    keys))

I need a decent less than method

(defun generic/less (val1 val2)
  (if (and (numberp val1) (numberp val2))
      (< val1 val2)
    (let ((v1 (prin1-to-string val1))
          (v2 (prin1-to-string val2)))
      (string< v1 v2))))

and then this sort of thing just works

(defvar %hash (_h { 1 2 'a 'x 5 6 10 "lemon" }))
(sort (keys %hash) #'generic/less) ;; --> (1 5 10 a)

1. Was this first in scheme?

Read Full Post »

This is part 3 in my terse hashes in emacs lisp series

Since emacs 23.2 was released the hash creation part of my _h macro is now obsolete. (or maybe not – perhaps allowing nested braces would make usage cleaner at the cost of significant complexity)? However, I suspect that is only one part of what would make emacs lisp nested data structures pleasant to use.

The other piece of the puzzle is dereferencing.

We don’t need a macro to implement the set and get functionality that _h includes so far. It was only required to prevent the braces from being evaluated.

Previously I mentioned extending the _h macro to allow for easier, or at least terser, nested hash dereferencing. The syntax I suggested would still need a macro. And I might as well leave the braces hash creation. It is unlikely my firm will upgrade to 23.2 in the next few months.

Given this nested %hash

(defvar %hash)
(setq %hash (_h { 1 2
                  'h (_h { 3 4
                           5 6
                           'h2 (_h { 1 2
                                     3 [5 6 7]
                                     'vh (vector (_h { 1 2 })
                                                 (_h { 3 4 }))
                                   })
                         })
                }))

I want (_h %hash -> 'h 'h2 'vh [1] 3) to return 4.

(It might be nice to add a nested assignment such as

(_h %hash -> 'h 'h2 'vh [1] 3 := "hello")

but the dereference will do for now.)

(defsubst h/vref (num)
  (cons 'vecpos num))

(defmacro _h (arg1 arg2 &rest args)
  (declare (indent defun))
  (cond ((eq arg1 '{) ...)
        ((eq arg2 '->)
         (let (str new-args)
           (dolist (elem args)
             (setq str (prin1-to-string elem))
             (if (string-match "\\[\\([0-9]+\\)\\]" str)
                 (let ((pair (h/vref (string-to-number
                                      (match-string 1 str)))))
                   (push (cons 'quote (list pair)) new-args))
               (push elem new-args)))
           (setq new-args (reverse new-args))
           `(h/get-value (quote, arg1) ,arg1 ,@new-args)))
        ((null args) ...)
        (t ...)))

That might be a little over the top, but it demonstrates that the macro facility does pretty much have access to the full power of the language.

The new functionality relies on a helper function, h/get-value.

(defun h/get-value (var-name variable &rest args)
  (let (retval param previous-param)
    (when (<= (length args) 0)
      (error "(_h %s -> ...) was not passed any arguments" var-name))
    (setq retval variable)
    (while args
      (setq param (pop args))
      (cond ((and (consp param) (eq 'vecpos (car param)))
             (let ((ref (cdr param)))
               (setq param (intern (concat "[" (number-to-string ref) "]")))
               (if (vectorp retval)
                   (setq retval (aref retval ref))
                 (error "%s not a vector @ %s (%s)"
                        var-name param previous-param))))
            ((hash-table-p retval)
             (setq retval (gethash param retval 'missing-key))
             (when (eq retval 'missing-key)
               (error "Can't find nested hash value %s in %s (%s)"
                      param var-name previous-param)))
            (t (error "value %s returned for param %s is not a hash in %s"
                      retval previous-param var-name)))
      (setq previous-param param))
    retval))

(macroexpand '(_h %hash -> 'h 'h2 'vh [0]))
--> (h/get-value (quote %hash) %hash (quote h) (quote h2) (quote vh) (quote (vecpos . 0)))

The problem with extending syntax like that is what if we want to use a variable to reference the vector rather than hardcoding a value like [0]. The obvious solution doesn’t work.

(defvar test-var)
(setq test-var 1)

(defsubst vec-ref (num)
  (intern (concat "[" (number-to-string num) "]")))

(_h %hash -> 'h 'h2 'vh (vec-ref test-var))

Debugger entered--Lisp error: (error "value [#<hash-table 'eql nil 1/65 0x1438680> #<hash-table 'eql nil 1/65 0x1438200>] returned for param vh is not a hash in %hash")
  signal(error ("value [#<hash-table 'eql nil 1/65 0x1438680> #<hash-table 'eql nil 1/65 0x1438200>] returned for param vh is not a hash in %hash"))

(the error message indicates there is a problem with h/get-value too but no time to fix before we went to press)

It is easier to go down to the next level – the code that the macro generates. The following performs as required.

(_h %hash -> 'h 'h2 'vh (h/vref test-var) 3)

Hopefully I didn’t offend too many senses of aesthetics there.


For reference, the full _h

(defmacro _h (arg1 arg2 &rest args)
  (cond ((eq arg1 '{)
         ;; check for empty case
         (if (eq arg2 '})
             (make-hash-table)
           ;; (_h { k1 v1 k2 v2 ... })
           (let ((rest (cons arg2 args))
                 elem tmp)
             (while (not (null rest))
               (setq elem (pop rest))
               (when (not (or (eq elem '}) (eq elem '=>)))
                 (push elem tmp)))
             (setq tmp (reverse tmp))
             `(literal-hash ,@tmp))))
        ((eq arg2 '->)
         (let (str new-args)
           (dolist (elem args)
             (setq str (prin1-to-string elem))
             (if (string-match "\\[\\([0-9]+\\)\\]" str)
                 (let ((pair (h/vref (string-to-number
                                      (match-string 1 str)))))
                   (push (cons 'quote (list pair)) new-args))
               (push elem new-args)))
           (setq new-args (reverse new-args))
           `(h/get-value (quote, arg1) ,arg1 ,@new-args)))
        ((null args)
         `(gethash ,arg2 ,arg1))
        (t (let ((val (car args)))
             `(puthash ,arg2 ,val ,arg1)))))

Read Full Post »

This is part 2 in my terse hashes in emacs lisp series

Another thing I like about Perl data structures, is that once I have stuffed all my data in there, I can easily see what it looks like with Data::Dumper.

my $data = {
    list1 => [
        { x => 'y' },
        { a => 'b' },
        # etc ...
    ],
    # etc ...
}

print Dumper($data);

And the result is:

$VAR1 = {
          'list1' => [
                       {
                         'x' => 'y'
                       },
                       {
                         'a' => 'b'
                       }
                     ]
        };

This is a big help with Exploratory Programming as you can see if you’re stuffing values in the right place.

You might be surprised to learn that I want the same functionality in Emacs Lisp.

(defun hash-dumper (hash &optional indent)
  (when (null indent) (setq indent 0))
  (let (lines indent-string)
    (setq indent-string "")
    (dotimes (i indent) (setq indent-string (concat " " indent-string)))
    (maphash (lambda (k v)
               (if (hash-table-p v)
                   (push (format "%s =>\n%s"
                                 k (hash-dumper v (+ indent 2))) lines)
                 (push (format "%s => %s" k v) lines)))
             hash)
    (concat (format "%s{" indent-string)
            (mapconcat #'identity lines (format "\n%s " indent-string))
            "}")))

And the result…

(defvar %hash)
(setq %hash (_h { 1 2
                  'h (_h { 3 4
                           5 6
                           'h2 (_h { 1 2
                                     3 [5 6 7]
                                     'vh (vector (_h { 1 2 })
                                                 (_h { 3 4 }))
                                   })
                         })
                }))

;; (insert (format "\n%s" (hash-dumper %hash)))
{h =>
  {h2 =>
    {vh => [#<hash-table 'eql nil 1/65 0x17cce80> #<hash-table 'eql nil 1/65 0x16f0a00>]
     3 => [5 6 7]
     1 => 2}
   5 => 6
   3 => 4}
 1 => 2}

Not bad, but not quite right. Fixing the problem with lists of hashes is left as an exercise for the reader.

Read Full Post »

This is part 1 in my terse hashes in emacs lisp series

One thing I really love about Perl is the easy and natural syntax for deeply nested data structures. I can make a hash of lists of hashes without a second thought.

(Okay, okay, Ruby and Python are equally good or even slightly better here, but I’m thinking about in comparison with emacs lisp, and C++ and Java…)

my $data = {
    list1 => [
        { x => 'y' },
        { a => 'b' },
        # etc ...
    ],
    # etc ...
}

In contrast, the syntax for dealing with hashes in emacs lisp is extremely verbose. Not only that, but for me, the arguments are the wrong way round. In object based programming, the object is always the first argument.

(make-hash-table)
(puthash <key> <value> <hash-table>)

When I came across the Clojure syntax for hash sets using #{ ... } I thought what a good idea. Unfortunately, emacs lisp doesn’t have reader macros. Let’s see what happens when I try it with a function.

(defun hash-set (opening-brace &rest args)
  nil)

(hash-set { 1 2 3 4 })

The result tells us that emacs is trying to evaluate the value of { as a variable before passing it to the function.

Debugger entered--Lisp error: (void-variable {)
  (hash-set { 1 2 3 4 })
  eval((hash-set { 1 2 3 4 }))
...

Fortunately, in emacs lisp, we can delay the evaluation of the arguments using a macro. I use the same macro to make setting and retrieving individual hash values easy too.

(defun literal-hash (&rest args)
  (let ((hash (make-hash-table)))
    (while args
      (let* ((key (pop args))
             (val (pop args)))
        (puthash key val hash)))
    hash))

(defmacro _h (arg1 arg2 &rest args)
  (cond ((eq arg1 '{)
         ;; check for empty case
         (if (eq arg2 '})
             (make-hash-table)
           ;; (_h { k1 v1 k2 v2 ... })
           (let ((rest (cons arg2 args))
                 elem tmp)
             (while (not (null rest))
               (setq elem (pop rest))
               (when (not (or (eq elem '}) (eq elem '=>)))
                 (push elem tmp)))
             (setq tmp (reverse tmp))
             `(literal-hash ,@tmp))))
        ((null args)
         `(gethash ,arg2 ,arg1))
        (t (let ((val (car args)))
             `(puthash ,arg2 ,val ,arg1)))))

Even nested hashes work nicely (I might be betraying my perl biases here!)

(defvar %hash (_h { 1 2 3 (_h { 1 2 3 4 } )))
(_h (_h %hash 3) 1) ;; ==> 2

Okay, retrieval is a little awkward, but I could add some more syntax to _h to make the following work.

(_h %hash -> 3 1)

That is left as an exercise for the reader.

Update: Hi atomicrabbit, I couldn’t figure out how to do the syntax highlighting in the comment so I have included my reply below.

I didn’t know about the #s(make-hash ...), so that looks pretty cool. I found a mention in the Elisp Cookbook. I couldn’t get it to work though unfortunately. Any ideas?

(emacs-version)
;; "GNU Emacs 23.0.60.1 (i386-mingw-nt6.0.6000)
;;  of 2009-01-12 on LENNART-69DE564 (patched)"
(read (prin1-to-string (make-hash-table)))
(read "#s(hash-table data ('key1 'val1 'key2 'val2))")
Debugger entered--Lisp error: (invalid-read-syntax "#")
  read("#<hash-table 'eql nil 0/65 0x143c880>")
Debugger entered--Lisp error: (invalid-read-syntax "#")
  read("#s(hash-table data ('key1 'val1 'key2 'val2))")

Read Full Post »

Removed from Planet Emacsen

Now that I write mainly about p.erl I had considered not publishing this post, but I’m curious to know the reason if any and email to the planet emacsen maintainer, Edward O’Connor, has gone unanswered.

A couple of years ago when I started blogging about emacs I asked to be included in planet emacsen. And now I have been removed. What can be the reason for that I wonder.

Well, I have just come back from a blogging break. Between my post on sorting records with emacs in August 2009 and my post on Enablers and Obstructors in March 2010, there were almost 7 months. But the latest post in Amortized Analysis (a blog that hasn’t been removed from planet emacsen) was 4th January 2008. That is more than 2 years ago.

Maybe I’m not that relevant anymore. I have posted mainly P.erl posts since my break. But I do still do emacs stuff, e.g. Directory Aliases Revisited and Programming with Types. And Alexandre Vassalotti’s most recent Emacs post was September 2007.

Or was it the back and forth with Ian Eure (and to a lesser extent, Aaron Hawley) about my Emacs Database Mode. Did someone ask for me to be removed?

Anyway, whatever the reason, it has been done. What solution do I have? I have created a yahoo pipe called Better Planet Emacs which you can subscribe to. It filters a lot of the non-emacs related posts out so for me at least it is better than stock planet emacs. If you want to copy it and customise it for your own use you should go here.

Read Full Post »

Emacs Has QWAN

The Preamble

I enjoy programming in Perl. There, I said it. And, although a lot of the stuff I write could easily be written in Emacs Lisp, I generally reach for Perl to solve most of my programming problems. However, if I had to choose between Perl and Emacs disappearing, I’d choose Perl any day of the week and twice on Sunday.

The reason is that there isn’t any competition in the emacs space1. Vim, Visual Studio and Eclipse are not acceptable substitutes. But if I want a dynamically typed langugage with good syntactical support for arrays, hashes and regular expressions and loads of libraries I know where to find Ruby or Python.

Q. Why not switch to Ruby today?
A. I enjoy programming in Perl

What makes Emacs so great?

(or what would I need to switch from Emacs to another editor)

Many people put it as Emacs has QWAN (the quality without a name), but that doesn’t really help to quantify things. Saying that all of the features work very nicely together is true, but also not that helpful. Let me try and point out a few things.

(If the c2 link above isn’t working, try the Bing cache).

Keystrokes are bound to functions

…and it is all very discoverable. If I want to know what a given keystroke does, I just press C-h k <key> and it tells me the function that calls. For example, arrow key calls forward-char. Now, say I want to make a function that needs to move forward a number of characters, I know what the function is called.

The utility of this discoverability in making composite functions cannot be overstated. You might think that macros are equally good, but what if I want a function that persists between sessions. For my line duplication function I glued together functions found with C-h k.

Okay, new utilities, great but not that impressive.

What about fixing stuff with the editor that you just don’t like. For example, recently I had a problem where <page down> went to the beginning of the line rather than remembering the current column position. You might be thinking a proper editor wouldn’t do that, or it isn’t really a problem, but you can’t imagine how annoying that was after the first ten times.

Anyway, what I did was… I fixed it. With C-h k I found that the command was scroll-up and I wrote a wrapper function that remembered the current column (alternatively I could have used advice). Saved my blood pressure and took around 5 minutes.

To summarise:

  • Key strokes / key chords call functions (which can be user-defined)
  • New functions can be created within the editor at any time
  • any key / key chord can call any function
  • information about the function can be viewed

Okay, you’re not convinced. Vim can do that, albeit with a much less pleasant language (or with perl, ruby, python, etc. if you’ve compiled a fat vim)

Editor Tabs

Tabs are not the right mechanism to deal with hundreds of open files. Emacs (together with ido) works beautifully. Generally I’ll have a couple of hundred files open with different file types and I’ll use progressive filtering to first find the perl files and then narrow down the file I wanted. Very quick and very nice. I’ve spent hours scrolling through tabs in Visual Studio and it was not fun.

Keymaps

So all your keys are bound to various useful commands. M-e steps forward to the next sentence nicely. But then you’re editing lisp (or perl) and sentence doesn’t mean much. What does emacs do?

In this case it has a keymap hierarchy. The global keymap defines a bunch of keys which can be overridden by keys defined in the major mode keymap. These can be added to with keys defined in one or more minor mode keymaps.

Comint

Comint is an awesome bit of kit. Out of the box, Emacs provides fantastic support for interacting with asynchronous processes. Comint codifies a lot of the functionality you would want to make a decent REPL for an external interpreter. Because this is one of the more tricky interactions to manage, it is an excellent API for dealing with any external process.

A while ago I wrote an article about a comint based stock price subscriber which demonstrates a few comint features.

Take a look at the interaction with gdb following M-x gdb-many-windows. It looks like an IDE no?

Emacs Applications

Some people have developed some impressive applications in emacs.

  1. Org Mode
  2. Emacs Muse
  3. SLIME (A full-featured Lisp IDE)

And my own Emacs Database Mode

Which in turn is based on the excellent sql-mode.


1. Apart from XEmacs of course.

Read Full Post »

« Newer Posts - Older Posts »

Follow

Get every new post delivered to your Inbox.