Skip to content

Instantly share code, notes, and snippets.

@celadevra
Created November 28, 2011 07:39
Show Gist options
  • Save celadevra/1399498 to your computer and use it in GitHub Desktop.
Save celadevra/1399498 to your computer and use it in GitHub Desktop.
Code Examples and Exercises
; Write a function similar to `triangle' in which each row has a value which is the square of the row number. Use a `while' loop.
(defun square-triangle (number-of-rows)
"Calculate the total number of pebbles in a triangle where the number of
pebbles in each row is the square of the number of the row."
(let ((total 0)
(row-number 1))
(while (<= row-number number-of-rows)
(setq total (+ total (* row-number row-number)))
(setq row-number (1+ row-number)))
total))
; Write a function similar to `triangle' that multiplies instead of adds the values.
(defun factor-triangle (number-of-rows)
"Calculate the product of number of pebbles in each row of a triangle
with NUMBER-OF-ROWS rows."
(let ((total 1)
(row-number 1))
(while (<= row-number number-of-rows)
(setq total (* total row-number))
(setq row-number (1+ row-number)))
total))
; Rewrite these two functions recursively. Rewrite these functions using `cond'.
(defun recursive-square-triangle (number)
"Square-triangle in a recursive manner."
(if (= number 1)
1
(+ (* number number) (recursive-square-triangle (1- number)))))
(defun recursive-factor-triangle (number)
"Factor-triangle in a recursive manner."
(if (= number 1)
1
(* number
(recursive-factor-triangle
(1- number)))))
(defun cond-square-triangle (number)
(cond ((<= number 0) 0)
((= number 1) 1)
((> number 1)
(+ (* number number) (cond-square-triangle (1- number))))))
(defun cond-factor-triangle (number)
(cond ((<= number 0) 0)
((= number 1) 1)
((> number 1)
(* number (cond-factor-triangle (1- number))))))
; Write a function for Texinfo mode that creates an index entry at the beginning of a paragraph for every `@dfn' within the paragraph. (In a Texinfo file, `@dfn' marks a definition. This book is written in Texinfo.)
(defun make-paragraph-index ()
"Create an index entry at the beginning of a paragraph for every `@dfn' within the paragraph."
(interactive)
(save-excursion
(let ((number-of-dfns 0) (resumepos 0))
(progn
(forward-paragraph)
(setq eop (point))
(backward-paragraph)
(setq bop (point))
(goto-char eop)
(while (search-backward "@dfn" nil t)
(setq number-of-dfns (1+ number-of-dfns))
(setq resumepos (1- (point))) ; the resume position is 1 char before "@dfn"
(forward-char 4) ; go to the beginning of the actual word
(push-mark (point) nil t)
(copy-region-as-kill (mark) (search-forward "}" nil t 1))
(goto-char resumepos))
(goto-char bop)
(setq pos 1)
(while (<= pos number-of-dfns)
(setq kill-ring-yank-pointer kill-ring) ; reset the k-r-y-p so the next
; expression doesn't get confused
(yank pos)
(message "Inserting item %d" pos)
(insert "\n")
(setq pos (1+ pos))))))) ; kill the text in the dfn bracelets
; TODO: make the last defun work for multiple paragraphs, given as an arg
// func_ptr.c -- uses function pointers
// C Primer Plus 5th Edition, Listing 14.16
#include <stdio.h>
#include <string.h>
#include <ctype.h>
char showmenu(void);
void eatline(void); // read through end of line
void show(void (* fp)(char *), char * str);
void ToUpper(char *); // convert string to uppercase
void ToLower(char *); // convert string to lowercase
void Transpose(char *); // transpose cases
void Dummy(char *); // leave string unaltered
int main (void)
{
char line[81];
char copy[81];
char choice;
void (*pfun)(char *); // points a function having a
// char * argument and no return value
puts("Enter a string (empty line to quit):");
while (gets(line) != NULL && line[0] != '\0')
{
while ((choice = showmenu()) != 'n')
{
switch (choice ) // switch sets pointer
{
case 'u' : pfun = ToUpper; break;
case 'l' : pfun = ToLower; break;
case 't' : pfun = Transpose; break;
case 'o' : pfun = Dummy; break;
}
strcpy(copy, line); // make copy for show()
show(pfun, copy); // use selected function
}
puts("Enter a string (empty line to quit):");
}
puts("Bye!");
return 0;
}
char showmenu(void)
{
char ans;
puts("Enter menu choice:");
puts("u) uppercase l) lowercase");
puts("t) transposed case o) original case");
puts("n) next string");
ans = getchar(); // get response
ans = tolower(ans); // convert to lowercase
eatline(); // dispose of rest of line
while (strchr("ulton", ans) == NULL)
{
puts("Please enter a u, l, t, o or n:");
ans = tolower(getchar());
eatline();
}
return ans;
}
void eatline(void)
{
while (getchar() != '\n')
continue;
}
void ToUpper(char * str)
{
while (*str)
{
*str = toupper(*str);
str++;
}
}
void ToLower(char * str)
{
while (*str)
{
*str = tolower(*str);
str++;
}
}
void Transpose(char * str)
{
while (*str)
{
if (islower(*str))
*str = toupper(*str);
else if (isupper(*str))
*str = tolower(*str);
str++;
}
}
void Dummy(char * str)
{
// leaves string unchanged
}
void show(void (* fp)(char *), char * str)
{
(*fp)(str); // apply chosen function to str
puts(str); // display result
}

%Progn

Elisp 中的函数隐式地默认各条语句按顺序执行,在while等形式中也是如此,因此实际上需要显式地使用progn形式的场合并不多,只有and or等形式以及if形式的then部分等等。

progn返回列表中最后一个形式的值。与其副作用相同但返回值不同的还有prog1prog2,分别返回第一个和第二个形式的值。例如,可以用如下代码返回一个列表的第一个值并获得截短后的列表:

(prog1 (car x) (setq x (cdr x)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment