How to access "two" in (("one" . "two")) in elisp - emacs

I'm very new to elisp and I'm trying to adapt some existing code.
While looping over a table (generated by the orgmode function org-clock-get-table-data) I try the following:
((equal column "Project") (insert (cdr row)))
which yeilds the following in the Messages buffer:
cond: Wrong type argument: char-or-string-p, (#("Verify CalTime accruals for vacation/sick" 0 41
(fontified t org-category #("Admin" 0 5 (fontified t org-category "Admin" org-category-position 32
line-prefix nil wrap-prefix nil ...)) org-category-position 32 line-prefix #("*" 0 1 (face org-
hide)) wrap-prefix #(" " 0 4 (face org-indent)) ...)) nil 30 (("wps" . "Administration")))
The value that I want to insert is "Administration" so I try this
((equal column "Project") (insert (nth 4 row)))
which yeilds the following in the minibuffer
Wrong type argument, char-or-string-p, (("wps" . "Administration"))
Can someone tell me how I can insert the string "Administration"?
EDIT
Thanks Wes and Drew:
(cdar row)
Doing the above yields the first element of the complex list that I saw in the Messages buffer earlier:
Verify CalTime accruals for vaction/sick
row seems to be a complex list of lists:
((equal column "Project") (insert (car row))); yeilds ^B
((equal column "Project") (insert (cdr row)))
yields:
cond: Wrong type argument: char-or-string-p, (#("Verify CalTime accruals for vacation/sick" 0 41
(fontified t org-category #("Admin" 0 5 (fontified t org-category "Admin" org-category-position 32
line-prefix nil wrap-prefix nil ...)) org-category-position 32 line-prefix #("*" 0 1 (face org-
hide)) wrap-prefix #(" " 0 4 (face org-indent)) ...)) nil 30 (("wps" . "Administration")))
I think each "#" in the output above represents a list item. The fact that (nth 4 row) gives the error output shown above supports this and suggests that something like this might work:
((equal column "Project") (insert (nth 2 (nth 4 row))))
;yeilds wrong type argument, char-or-string-p, nil
So there is probably some function that I need to use to decode that 4th list item....
That 4th element is the orgmode property that has been assigned to the clocktable entry on the row we are parsing. This list of properties is defined in my .emacs:
(setq org-global-properties
;; WPS = Web Platform Services. Time tracking for Google Sheet begun with CalTime Migration
'(("wps_ALL".
"Administration
ASG-Consulting
Chanc-Office-Website
")))

Instead of the assoc + cdr combination, you can also use assoc-default:
ELISP> (assoc-default "one" '(("one" . "two")))
=> "two"

Note that lists of the form (("wps" . "Administration") ("foo" . "bar")) are typically "alists", and so you may need to handle the situation where there is more than one item in your list.
Read: C-hig (elisp) Association Lists RET
and also: (elisp) Dotted Pair Notation
You may obtain a keyed item from an alist with (assoc) or (assq) depending on the form of equality needed for the test. Equivalent strings are not equal objects in elisp, so in this case you want assoc rather than assq.
That gives you the entire (KEY . VALUE) form as a result, and you obtain the cdr of that as usual; hence:
(let ((my-alist '(("wps" . "Administration") ("foo" . "bar"))))
(cdr (assoc "wps" my-alist)))
yields: "Administration"

Lists are complex to think about in elisp. Until you've done enough of them that you stop thinking about them. Ha ha. But read up on the functions like car (picks the first element in a list) and cdr (picks the rest of the rest) to get started. And then you can chain things by combining letters in short sequences at least. So the answer you want is:
(cdar row)

Related

How do I correctly iterate through symbols as keys for creating a hash table?

In short: (gethash 'PARIS pandemic-hash-table) is returning nil, despite 'PARIS being a key in the table; this seems to be related to quoting/evaluation of symbols during the hash-table creation in some way but I can't figure it out.
I'm playing with a graph search (testing for the shortest route between cities in the board game Pandemic; just for fun - trying to find optimal research lab placement in a way more sophisticated than 'has the most edges'). I'm using a hash table to hold the route data (nodes and edges), and, needed to input the data as a preliminary:
(defvar *nodes* '('San-Francisco 'Chicago 'Atlanta 'Washington 'Montreal 'New-York 'Madrid 'Paris 'London 'Essen 'Milan 'St-Petersburg))
(defvar *edges* '(('Chicago 'St-Petersburg)
('San-Francisco 'Atlanta 'Montreal)
('Chicago 'Washington)
('Atlanta 'Montreal 'New-York)
('Chicago 'Washington 'New-York)
('Montreal 'Washington 'Madrid 'London)
('New-York 'London 'Paris)
('Madrid 'Essen 'London 'Milan)
('Madrid 'Essen 'London 'New-York)
('London 'Paris 'Milan 'St-Petersburg)
('Paris 'Essen)
('Essen 'Chicago)))
(defvar *pandemic-node-hash* (make-hash-table))
(loop for node in *nodes*
for edges in *edges*
do (setf (gethash node *pandemic-node-hash*) edges))
If I look at the resulting hash table:
CL-USER> (loop for key being the hash-keys of *pandemic-node-hash*
do (print key))
'SAN-FRANCISCO
... ;other keys removed for brevity
'PARIS
NIL
So it's making the table (and the edges show up similarly), but, (gethash 'PARIS *pandemic-node-hash*) returns nil. If I then add another 'PARIS node directly (setf (gethash 'paris *pandemic-node-hash*) 'somevalue), and check the keys, I get:
(loop for key being the hash-keys of *pandemic-node-hash*
do (print key))
'other keys
'PARIS
PARIS
NIL
So, the problem has something to do with the evaluation of the symbols ('PARIS and friends) in the initial hash table creation loop, but I can't quite figure out what's going on or how to do that correctly. I'm guessing node evaluates to the un-evaluated symbol, passing that to gethash ... but what's the right way? Surely not (eval node)? Backtick the list, with commas in front of the symbols? (ugh).
Remember: 'foo is the short form for (quote foo). It's a list with two elements: the symbol CL:QUOTE and the symbol FOO.
(defun show-it (arg)
(print (list arg (type-of arg)))
(values))
Above is a smaller helper function for this answer.
CL-USER 37 > (show-it 'hamburg)
(HAMBURG SYMBOL)
Above shows that the function sees the symbol hamburg and not the value of a variable hamburg.
Not
CL-USER 38 > (show-it '('hamburg))
(((QUOTE HAMBURG)) CONS)
Above: the function sees a nested list, with a list, which has quote as a symbol.
Note: ((quote hamburg)) can be written shorter as('hamburg).
CL-USER 39 > (show-it (first '('hamburg)))
((QUOTE HAMBURG) CONS)
Above: if we get the first element, we get the list with the quote symbol.
Better
CL-USER 40 > (show-it '(hamburg))
((HAMBURG) CONS)
Above provides a list with one symbol, the symbol hamburg.
CL-USER 41 > (show-it (first '(hamburg)))
(HAMBURG SYMBOL)
Above gets the first element, which is the symbol hamburg.
Evaluation
Make sure that you understand evaluation in Lisp. quote blocks evaluation for the whole quoted expression and on all levels of those. Thus it makes no sense to quote contents inside a quoted list.
When passing arguments in a function call, then quoting is used to prevent lists and symbols to be evaluated. Thus quote creates literal data: literal symbols, literal lists, literal vectors, etc.
Thus quoting is a mechanism of code, not of data.
Code:
(first '(hamburg)) vs. (first (hamburg))
getting the first element of a literal list vs.
getting the first element of the result
of calling the function `hamburg`.
Data:
(paris hamburg berlin rome) vs. ('paris 'hamburg 'berlin 'rome)
A list of city names vs. a list of city names,
each nested in a list (quote ...)
Thus:
('paris 'hamburg 'berlin 'rome) makes no sense.
Why not
(dolist (node *nodes*)
(dolist (edges *edges*)
(setf (gethash node *pandemic-node-hash*) edges)))
But also you've double quoted your symbols (as someone else commented)
Why:
'(('Chicago 'St-Petersburg) ...)
when it should probably be just this (don't quote the list and each symbol)
'((Chicago St-Petersburg) ...)
You would see this if you evaluated: *edges*

Define a syntax error in Lisp function

I am bad at Lisp. Help me please to find a syntax error. I need to write a function which swaps two elements in list. This function must consist loop-cycle. Here is what if have so far.
(defun swap-two-element(z x y)
(let ((newlist nil) (newlist2 nil) (copyz z) (copyz2 z) (newx nil))
(loop
(when (= (- (length z) (length copyz2)) y)
(return (set newx car z)))
(setq newlist2 (append newlist2(car copyz2))
copyz2 (cdr copyz2)))))
Call example: (swap-two-element '(a b c d) 2 3)
Replace the word set with the word values and you are good to go.
PS. You need to address the warnings though, and explain what the function is supposed to do so that we could help you with the algorithm.
You really need to tidy up your question. The title says nothing, the code is badly formatted and you really need to play around with loop to get started. I won't give you your solution since you need to learn this by trying. Here is an example you can make use of to do your assignment.
;; this orders a list by their odd index
;; NB: index starts at zero so first element is even
(defun order-odd-index (list)
(loop :for element :in list ; iterates your list
:for index :from 0 ; starts from 0 and goes on
:if (oddp index) ; if in a loop
:collect element :into odd-list ; variable is automatically created
:else ; else in a loop
:collect element :into even-list
:finally (return (append odd-list even-list)))) ; what to do in the end
(order-odd-index '(4 67 3 2 7 9)) ; ==> (67 2 9 4 3 7)
I use keywords (like :for instead of for) to indicate what symbols are loop keywords and what are not. It's optional but I think it looks a lot cleaner.
Now your problem can be solved with collecting element into 5 variables. Two of them is when index is equal to one of the places (given as arguments) to be switched the other 3 are before, in between and greater. In the finally you can just append those variables in the correct order and you're done.

How to define symbols that will work like ( and ) by symbol macro?

I am trying define symbols a and b in following way
a + 1 1 b
2
I am trying to do this by using define-symbol-macro
(define-symbol-macro a '( )
(define-symbol-macro b ') )
but this way is not working.
What Lisp does with source code
Common Lisp is an incredibly flexible language, in part because its source code can be easily represented using the same data structures that are used in the language. The most common form of macro expansion transforms the these structures into other structures. These are the kind of macros that you can define with define-symbol-macro, define-compiler-macro, defmacro, and macrolet. Before any of those kind of macroexpansions can be performed, however, the system first needs to read the source from an input stream (typically a file, or an interactive prompt). That's the reader's responsibility. The reader also is capable of executing some special actions when it encounters certain characters, such ( and '. What you're trying to do probably needs to be happening down at the reader level, if you want to have, e.g., (read-from-string "a + 1 1 b") return the list (+ 1 1), which is what you want if you want (eval (read-from-string "a + 1 1 b")) to return 2. That said, you could also define a special custom language (like loop does) where a and b are treated specially.
Use set-macro-character, not define-symbol-macro
This isn't something that you would do using symbol-macros, but rather with macro characters. You can set macro characters using the aptly named set-macro-character. For instance, in the following, I set the macro character for % to be a function that reads a list, using read-delimited-list that should be terminated by ^. (Using the characters a and b here will prove very difficult, because you won't be able to write things like (set-macro-character ...) afterwards; it would be like writing (set-m(cro-ch(r(cter ...), which is not good.)
CL-USER> (set-macro-character #\% (lambda (stream ignore)
(declare (ignore ignore))
(read-delimited-list #\^ stream)))
T
CL-USER> % + 1 1 ^
2
The related set-syntax-from-char
There's a related function that almost does what you want here, set-syntax-from-char. You can use it to make one character behave like another. For instance, you can make % behave like (
CL-USER> (set-syntax-from-char #\% #\()
T
CL-USER> % + 1 1 )
2
However, since the macro character associated with ( isn't looking for a character that has the same syntax as ), but an actual ) character, you can't simply replace ) with ^ in the same way:
CL-USER> (set-syntax-from-char #\^ #\))
T
CL-USER> % + 1 1 ^
; Evaluation aborted on #<SB-INT:SIMPLE-READER-ERROR "unmatched close parenthesis" {1002C66031}>.
set-syntax-from-char is more useful when there's an existing character that, by itself does something that you want to imitate. For instance, if you wanted to make ! an additional quotation character:
CL-USER> (set-syntax-from-char #\! #\')
T
CL-USER> (list !a !(1 2 3))
(A (1 2 3))
or make % be a comment character, like it is in LaTeX:
CL-USER> (set-syntax-from-char #\% #\;)
T
CL-USER> (list 1 2 % 3 4
5 6)
(1 2 5 6)
But consider why you're doing this at allā€¦
Now, even though you can do all of this, it seems like something that would be utterly surprising to anyone who ran into it. (Perhaps you're entering an obfuscated coding competition? ;)) For the reasons shown above, doing this with commonly used characters such as a and b will also make it very difficult to write any more source code. It's probably a better bet to define an entirely new readtable that does what you want, or even write a new parser. even though (Common) Lisp lets you redefine the language, there are still things that it probably makes sense to leaveĀ alone.
A symbol-macro is a symbol that stands for another form. Seems like you want to look at reader macros.
http://clhs.lisp.se/Body/f_set__1.htm
http://dorophone.blogspot.no/2008/03/common-lisp-reader-macros-simple.html
I would second Rainer's comment though, what are you trying to make?
Ok so I love your comment on the reason for this and now I know this is for 'Just because it's lisp' then I am totally on board!
Ok so you are right about lisp being great to use to make new languages because we only have to 'compile' to valid lisp code and it will run. So while we cant use the normal compiler to do the transformation of the symbols 'a and 'b to brackets we can write this ourselves.
Ok so lets get started!
(defun symbol-name-equal (a b)
(and (symbolp a) (symbolp b) (equal (symbol-name a) (symbol-name b))))
(defun find-matching-weird (start-pos open-symbol close-symbol code)
(unless (symbol-name-equal open-symbol (nth start-pos code))
(error "start-pos does not point to a weird open-symbol"))
(let ((nest-index 0))
(loop :for item :in (nthcdr start-pos code)
:for i :from start-pos :do
(cond ((symbol-name-equal item open-symbol) (incf nest-index 1))
((symbol-name-equal item close-symbol) (incf nest-index -1)))
(when (eql nest-index 0)
(return i))
:finally (return nil))))
(defun weird-forms (open-symbol close-symbol body)
(cond ((null body) nil)
((listp body)
(let ((open-pos (position open-symbol body :test #'symbol-name-equal)))
(if open-pos
(let ((close-pos (find-matching-weird open-pos open-symbol close-symbol body)))
(if close-pos
(weird-forms open-symbol close-symbol
`(,#(subseq body 0 open-pos)
(,#(subseq body (1+ open-pos) close-pos))
,#(subseq body (1+ close-pos))))
(error "unmatched weird brackets")))
(if (find close-symbol body :test #'symbol-name-equal)
(error "unmatched weird brackets")
(loop for item in body collect
(weird-forms open-symbol close-symbol item))))))
(t body)))
(defmacro with-weird-forms ((open-symbol close-symbol) &body body)
`(progn
,#(weird-forms open-symbol close-symbol body)))
So there are a few parts to this.
First we have (symbol-name-equal), this is a helper function because we are now using symbols and symbols belong to packages. symbol-name-equal gives us a way of checking if the symbols have the same name ignoring what package they reside in.
Second we have (find-matching-weird). This is a function that takes a list and and index to an opening weird bracket and returns the index to the closing weird bracket. This makes sure we get the correct bracket even with nesting
Next we have (weird-forms). This is the juicy bit and what it does is to recursively walk through the list passed as the 'body' argument and do the following:
If body is an empty list just return it
if body is a list then
find the positions of our open and close symbols.
if only one of them is found then we have unmatched brackets.
if we find both symbols then make a new list with the bit between the start and end positions inside a nested list.
we then call weird forms on this result in case there are more weird-symbol-forms inside.
there are no weird symbols then just loop over the items in the list and call weird-form on them to keep the search going.
OK so that function transforms a list. For example try:
(weird-forms 'a 'b '(1 2 3 a 4 5 b 6 7))
But we want this to be proper lisp code that executes so we need to use a simple macro.
(with-weird-forms) is a macro that takes calls the weird-forms function and puts the result into our source code to be compiled by lisp. So if we have this:
(with-weird-forms (a b)
(+ 1 2 3 a - a + 1 2 3 b 10 5 b 11 23))
Then it macroexpands into:
(PROGN (+ 1 2 3 (- (+ 1 2 3) 10 5) 11 23))
Which is totally valid lisp code, so it will run!
CL-USER> (with-weird-forms (a b)
(+ 1 2 3 a - a + 1 2 3 b 10 5 b 11 23))
31
Finally if you have settled on the 'a' and 'b' brackets you could write another little macro:
(defmacro ab-lang (&rest code)
`(with-weird-forms (a b) ,#code))
Now try this:
(ab-lang a let* a a d 1 b a e a * d 5 b b b a format t "this stupid test gives: ~a" e b b)
Cheers mate, this was great fun to write. Sorry for dismissing the problem earlier on.
This kind of coding is very important as ultimately this is a tiny compiler for our weird language where symbols can be punctuation. Compilers are awesome and no language makes it as effortless to write them as lisp does.
Peace!

Should I call add-to-list in Emacs Lisp a destructive function?

add-to-list is often used to add an element to a list if the element is not in the list.
(let* ((aa (list 1 2 3))
(bb aa))
(add-to-list 'aa 0)
(list :aa aa :bb bb))
=> (:aa (0 1 2 3) :bb (1 2 3))
Should one call add-to-front a destructive function because it changes the meaning of name aa? Or should it be called non-destructive because the list that aa used to point to is intact?
(let* ((cc (list 1 2 3))
(dd cc))
(add-to-list 'cc 0 t)
(list :cc cc :dd dd))
=> (:cc (1 2 3 0) :dd (1 2 3))
For Emacs newbies wondering why bb and dd equals (1 2 3), feel free to open a separate stackoverflow question for that and leave a link with "add comment" button. For Emacs newbies wondering why some fellow newbies would wonder that, replace (add-to-list 'aa 0) with (setcar aa 111) and see.
For Lispers who don't use Emacs, here's a simplified definition of add-to-list
(defun simple-add-to-list (list-var element &optional append)
"Add ELEMENT to the value of LIST-VAR if it isn't there yet.
If ELEMENT is added, it is added at the beginning of the list,
unless the optional argument APPEND is non-nil, in which case
ELEMENT is added at the end.
The return value is the new value of LIST-VAR."
(let ((lst (symbol-value list-var)))
(if (member element lst)
lst
(set list-var
(if append
(append lst (list element))
(cons element lst))))))
If it's capable of modifying the list passed to it, then it's destructive.
If a function takes a list via a symbol, it should be automatically assumed to be destructive, no? Otherwise why not just take the list itself?

something confusing about define-key (and the issue of when to quote an argument)

It seems one is not supposed to quote KEYMAP when using define-key.
(define-key org-remember-mode-map "\C-c\C-r" 'org-remember-kill)
I'm confused because I think that all arguments of a function that is not quoted are evaluated, and according to the help, define-key is a function, not a macro. I don't see why the value of KEYMAP can be modified after a call of define-key.
(defun increment-value (a)
(setq a (+ 1 a)))
(setq my-num 10)
(increment-value my-num)
my-num ; ===> 10
Update: The answers explain everything, but for those still confused, let me clear up with more examples.
My increment-value example above is equivalent to this:
(let ((n 0))
(print n) ; prints 0
(let ((a n))
(setq a (+ 1 a))
(print a) ; prints 1
)
(print n) ; prints 0
)
What's going on above is, I think, similar to what's going on in this some-map example:
(let ((some-map '(1 2)))
(print some-map) ; prints (1 2)
(let ((a some-map))
(setq a (list 4 (second a)))
(print a) ; prints (4 2)
)
(print some-map) ; prints (1 2)
)
What's going on in define-key is similar to this second some-map example:
(let ((some-map '(1 2)))
(print some-map) ; prints (1 2)
(let ((a some-map))
(setcar a 4)
(print a) ; prints (4 2)
)
(print some-map) ; prints (4 2)
)
Now read the answers again with these three examples in mind and you will get it. Read also http://www.emacswiki.org/emacs/ListModification
You aren't actually changing what 'org-remember-map is (a pointer to a particular list structure), you are modifying the actual structure. Read this info page for details on modifying lists.
Specificially, if you take a look at the documentation for 'make-keymap:
(make-keymap &optional string)
Construct and return a new keymap, of
the form (keymap CHARTABLE . ALIST).
CHARTABLE is a char-table that holds
the bindings for all characters
without modifiers. All entries in it
are initially nil, meaning "command
undefined". ALIST is an assoc-list
which holds bindings for function
keys, mouse events, and any other
things that appear in the input
stream. Initially, ALIST is nil.
You'll see that keymap is a list with three elements. Let me draw that for you (yay M-x artist-mode):
org-remember-map
|
|
v
+----+----+ +----+----+
| | | --+--->+ / | \ |
+-+--+----+ +-/--+--\-+
| | |
v v v
keymap CHARTABLE ALIST
So, the value of the 'org-remember-map is something like the above structure, and when you define a key, what you are doing is changing what is pointed to in the ALIST blob part of the structure.
you're confusing value and name-value mapping.
in your increment-value function, you're not changing a's value as much as changing the mapping of the name a to a new value.
Fundamentally, there is no way to change the value of 10. 10 is 10!
But in the first case, you can either modify the mapping of the name org-remember-mode-map to a fully different map (set a new value), or you can alter the map pointed by that name (its current value). This is what define-key does.
Illustration:
(setq a '(1 2)) -> (1 2)
(setcar a 4) -> 4
a -> (4 2)
Everything you write is completely correct. The thing you are missing is that lists (keymaps are represented as lists) are not values themselves, but containers of values. Thus, you can pass a list to a function and have that function change the values of the list, but the list you have is still the same list.
All the details are in the Cons Cell Type section of the elisp manual.