Skip to main content

C'est la Z

Learning Elisp 5 - Rot13 parts 2 and 3

Rather than one long boring video, I thought it would be better to split up the remainder of the Rot13 project into 4 shorter boring ones :-).

Here are the first two.

Before we can really do anything interesting, we need to be able write programs that make decisions. For that we need conditionals or if statements. That's covered in the first video.

Like other languages, elisp has an if statement but it's more of an if function. Here's the outline:

  (if boolean
      evaluate_to_this_if_boolean_is_true
      evaluate_to_this_if_boolean_is_false)

In this basic form, it essentially has both the if and the else parts from languages like Python:

  if boolean:
      evaluate_to_this_if_boolean_is_true
  else:
      evaluate_to_this_if_boolean_is_false)

If you need more than one thing in either the true or false part you need another form which we'll cover later.

You can also leave out the false part but again, we'll deal with that when it comes up. For now, it's simpler for our application to have both.

The basic if will cover you in a lot of cases but if you've got more then a true/false decision the code can get ugly:

  (if boolean1
      true-part-1
      (if boolean2 ;; this is the false for boolean1
          true part-2
          (if boolean3 ;; this is the false for boolean 2
              true-part
            false-part)))

Instead, elisp and many other lisps give us the cond or conditional. The most similar construct in languages like Java or C++ would be the switch statement but the cond is much more general and much more powerful.

In a switch statement, you list multiple discrete values for a given variable and run some code based on that:

  switch (c) {
      case 1 :
          do-this-if-c-is-1;
          break;
      case 2 :
          do-this-if-c-is-2;
          break;
      case 3 :
          do-this-if-c-is-3;
          break;
       etc.

In a cond, you have multiple clauses with arbitrary conditions and what to do for each condition.

(let ( (grade 66) )
(cond ( (< grade 65) "F")
      ( (< grade 70) "D")
      ( (< grade 80) "C")
      ( (< grade 90) "B")
      ( t "A") ))

In the above example, there are four independent boolean expressions and then the final clause, which will always execute if the code gets there because t is always true.

For the cond, once it evaluates a boolean to true, it evaluates to the other part of its clause and returns so in the example above, "D" would be returned.

Here's the cond from the rot13 code:

   (cond ((and (>= c ?a) (<= c ?z)) (rotate c offset 97) )
	 ((and (>= c ?A) (<= c ?Z)) (rotate c offset 65) )
	 (t c))

The top clause tests for a lowercase letter, the next for upper case and the default t clause if it's neither - maybe a space or punctuation.

The second video posted here goes over making an interactive rot13 function using elisp's (interactive). If a function uses (interactive) it can then be called as a command using the M-x prefix. It can also be bound to a key combination.

In the next videos we'll see how to modify the (interactive) form so that we can pass what are known as prefix arguments and in the final installment of the rot13 project we'll see how we can rot13 a region.

Code

I finally got around to making a repo. All the code for this series will be made available here:

The rot13 code will be in the file rot13.el.

The videos

comments powered by Disqus