I wrote a function to convert alist to hash:
(defun hash-alist (alist)
"Convert association list to a hash table and return it."
(let ((my-hash (make-hash-table :test 'equal)))
(dolist (entry alist)
(if (gethash (car entry) my-hash)
(error "repeated key"))
(puthash (car entry) (cdr entry) my-hash))
my-hash))
but when I run it as following, why I get nil at the end?
Run:
(setq a '(("a" . 2) ("b" . 1)))
(setq b (hash-alist a))
(maphash (lambda (x y) (princ (format "%s:%d " x y) t))
b)
Output:
a:2 b:1 nil
nil is the return value of maphash. Nothing more than that.
It is the way that you are evaluating the maphash sexp that causes the return value to be printed.
If you look in buffer *Messages* you might see something like this (depending on how you evaluate the expression):
Evaluating...
a:2 b:1
Buffer `*Pp Eval Output*' is in mode `Emacs-Lisp'. For info on the mode: `C-h m'.
nil
The return value is documented in the Elisp manual, node Hash Access. It should also be, but is not, documented in the doc string.
Every Lisp expression has a value.
c-x c-e evaluates an expression and prints the result.
If you evaluate (+ 1 2) you see that it evaluates to 3. If you evaluate a maphash expression, then it evaluates to NIL. So this is printed.
Since your code calls functions which produce output, you see that output printed before the return value. So there is no extra NIL. It is just the NIL that is the result.
Related
This function resets the value for each of the specified parts of speech to NIL using putp.
The first argument is a hashtable, for this example, lets call it word-dict.
There are a variable number of parts of speech passed to resetPartsOfSpeech.
Example:
(resetPartsOfSpeech word-dict 'subject 'verb 'prep 'directObj)
(defun resetPartsOfSpeech(word-dict &rest parts)
(do ((partsVar parts (cdr partsVar)))
( (null partsVar) T)
;;; procces the car
(putp NIL word-dict (car partsVar))
))
; here is the results of the function
#S(HASH-TABLE :TEST FASTHASH-EQL (NIL . VERB) (LICKED . VERB) (HAS . VERB) (ATE . VERB) (RAN . VERB) (TAUGHT . VERB)
As you see, it only adds the NIL variable to the list, not clearing them all out.
Helper Functions I Have, The job of these two functions is to put and get data from the hashtable created.
; creating the hash table
(setf word-dict (MAKE-HASH-TABLE))
(defun putp (symbol ht value)
(if (ATOM symbol)
(setf (gethash symbol ht) value)
(ERROR "~s is not a valid symbol for putp" symbol)
))
(defun getp (symbol ht)
(gethash symbol ht) )
(defun isa(word partOfSpeech) ; this function returns T if the specified word is that specified partOfSpeech,
; otherwise, NIL is returned.
(eql (getp word word-dict) partOfSpeech))
(defun set_isa (partOfSpeech &rest words) ; this function defines each
word in the list of words to the specified partOfSpeech
; in the dictionary (hard code word-dict).
(do ((wordVar words (cdr wordVar)) )
( (NULL wordVar ) T)
;;; proccess the CAR
(putp (car wordVar) word-dict partOfSpeech)
(print (car wordVar))))
What I am having trouble understanding is that how I should go about itterating thru each value in the hash table. What I was considering was doing a nested do or dolist loop but can't quite figure out how to go about that with the values from the table, or if that is even possible.
The fundamental problem is with:
(putp NIL word-dict (car partsVar))
When putp is called, nil is bound to symbol, word-dict is bound to ht, and (car partsVar), i.e. the next symbol in the list of parts of speech, is bound to value. Within putp the expression:
(setf (gethash symbol ht) value)
becomes:
(setf (gethash 'nil word-dict) (car partsVar))
Here, (gethash 'nil word-dict) is the place that is set to the value (car partsVar). Since there is no 'nil key in the hash table yet, a new key is created and given the value (car partsVar), which is 'verb in the OP example.
In the original putp expression, (car partsVal) should have been in the symbol position as that is the key which should be updated:
(defun resetPartsOfSpeech (word-dict &rest parts)
(do ((partsVar parts (cdr partsVar)))
((null partsVar) t)
(putp (car partsVar) word-dict 'nil)))
Although this solves the problem, there is a better solution.
(defun reset-parts-of-speech (word-dict &rest parts)
(dolist (part parts)
(putp part word-dict 'nil)))
When you want to do a simple iteration over a list of elements, symbols for parts of speech in this case, just use a simple dolist. Additionally, it would be good to get into better habits with respect to Lisp style. Prefer kebab-case to camel-case; put all closing parentheses on one line (almost always); use proper indentation to make program structure clear. A good lisp-aware text editor can be most helpful for the last two.
Here is some testing in the REPL using a set-isa function based on the previous question by OP:
SCRATCH> (defvar *word-dict* (make-hash-table))
*WORD-DICT*
SCRATCH> (set-isa 'verb 'eat 'sleep 'walk)
NIL
SCRATCH> (set-isa 'noun 'cake 'ice-cream 'pizza)
NIL
SCRATCH> (gethash 'verb *word-dict*)
(WALK SLEEP EAT)
T
SCRATCH> (gethash 'noun *word-dict*)
(PIZZA ICE-CREAM CAKE)
T
SCRATCH> (set-isa 'adjective 'delicious 'sweet 'crispy)
NIL
SCRATCH> (gethash 'adjective *word-dict*)
(CRISPY SWEET DELICIOUS)
T
SCRATCH> (resetPartsOfSpeech *word-dict* 'verb)
T
SCRATCH> (gethash 'verb *word-dict*)
NIL
T
SCRATCH> (gethash 'noun *word-dict*)
(PIZZA ICE-CREAM CAKE)
T
SCRATCH> (reset-parts-of-speech *word-dict* 'adjective 'noun)
NIL
SCRATCH> (gethash 'noun *word-dict*)
NIL
T
SCRATCH> (gethash 'adjective *word-dict*)
NIL
T
Update
The above was predicated on OP statement: "This function resets the value for each of the specified parts of speech to NIL...," which seemed to suggest that OP wants the hash table to store parts of speech as keys and lists of words as the associated values. This also seems to align with a previous question posted by OP. But, after an exchange of comments, it seems that OP may prefer a hash table with individual words as keys and parts of speech as the associated values. It is unclear how words which may be associated with multiple parts of speech should be handled.
The hash table shown in OP example code #S(HASH-TABLE :TEST FASTHASH-EQL (NIL . VERB) (LICKED . VERB) ;..., along with OP comments, supports this second interpretation. If this is the case, then what does it mean to "reset each value" in the hash table to 'nil? Perhaps the sensible thing to do is to remove each entry entirely which has a value that matches a provided part-of-speech argument.
This can easily be accomplished by using dolist to loop over the list of parts of speech, and subsequently mapping over the hash table with maphash and a function that removes any entry holding a matching value:
(defun remove-parts-of-speech (word-dict &rest parts)
(dolist (part parts)
(maphash #'(lambda (k v) (if (eql v part) (remhash k word-dict)))
word-dict)))
Here is another REPL demonstration using OP's current set-isa function which populates a hash table with words for keys and parts of speech for values. After populating the hash table with nine words which are 'nouns, 'verbs, and 'adjectives, the remove-parts-of-speech function is used to remove all entries which are nouns or verbs from *word-dict*. After this, only the three adjective entries remain in the hash table.
CL-USER> (defvar *word-dict* (make-hash-table))
*WORD-DICT*
CL-USER> (set-isa 'verb 'run 'jump 'climb)
RUN
JUMP
CLIMB
T
CL-USER> (set-isa 'noun 'hat 'shoe 'scarf)
HAT
SHOE
SCARF
T
CL-USER> (set-isa 'adjective 'salty 'spicy 'sour)
SALTY
SPICY
SOUR
T
CL-USER> *word-dict*
#<HASH-TABLE :TEST EQL :COUNT 9 {1003CE10C3}>
CL-USER> (hash-table-count *word-dict*)
9
CL-USER> (remove-parts-of-speech *word-dict* 'noun 'verb)
NIL
CL-USER> (hash-table-count *word-dict*)
3
CL-USER> (gethash 'spicy *word-dict*)
ADJECTIVE
T
How can I conditionally remove a let-binding in a defun created in a lisp macro? Here, I want to remove the first let-bound variable from the resulting function, but am running into a problem where I have a nil that sticks around in the let bindings, causing an error.
For example, the resulting function uses let or let* and should remove the first variable assignment depending on arg. But the way I have it written the problem comes from replacing var1 with nil. I'm not sure how to get rid of the nil.
(cl-defmacro mac (cmd &optional arg)
(let ((fn (intern (concat "fn-" cmd))))
`(defun ,fn ()
(interactive)
(,(if arg 'let* 'let)
(cons
,(when arg
'(var1 1))
(var2 (if (bound-and-true-p var1) (+ var1 1) 1)))
(message "%s" var2)))))
(mac "fun") ; Attempt to set constant: nil
(mac "fun2" t) ; no problem
;; (symbol-function 'fn-fun)
;; (symbol-function 'fn-fun2)
;; (fn-fun)
;; (fn-fun2)
The easiest workaround is probably to use ,#(when arg '((var1 1))). ,# is used to splice a list into the position. Since WHEN returns NIL if the condition fails, and NIL is the same as an empty list, the splice effectively ignores it. When the condition succeeds ((var1 1)) is returned, and (var1 1) is unwrapped by the splice.
I have various functions and I want to call each function with the same value. For instance,
I have these functions:
(defun OP1 (arg) ( + 1 arg) )
(defun OP2 (arg) ( + 2 arg) )
(defun OP3 (arg) ( + 3 arg) )
And a list containing the name of each function:
(defconstant *OPERATORS* '(OP1 OP2 OP3))
So far, I'm trying:
(defun TEST (argument) (dolist (n *OPERATORS*) (n argument) ) )
I've tried using eval, mapcar, and apply, but these haven't worked.
This is just a simplified example; the program that I'm writing has eight functions that are needed to expand nodes in a search tree, but for the moment, this example should suffice.
Other answers have provided some idiomatic solutions with mapcar. One pointed out that you might want a list of functions (which *operators* isn't) instead of a list of symbols (which *operators* is), but it's OK in Common Lisp to funcall a symbol. It's probably more common to use some kind of mapping construction (e.g., mapcar) for this, but since you've provided code using dolist, I think it's worth looking at how you can do this iteratively, too. Let's cover the (probably more idiomatic) solution with mapping first, though.
Mapping
You have a fixed argument, argument, and you want to be able to take a function function and call it with that `argument. We can abstract this as a function:
(lambda (function)
(funcall function argument))
Now, we want to call this function with each of the operations that you've defined. This is simple to do with mapcar:
(defun test (argument)
(mapcar (lambda (function)
(funcall function argument))
*operators*))
Instead of operators, you could also write '(op1 op2 op3) or (list 'op1 'op2 'op3), which are lists of symbols, or (list #'op1 #'op2 #'op3) which is a list of functions. All of these work because funcall takes a function designator as its first argument, and a function designator is
an object that denotes a function and that is one of: a symbol (denoting the function named by that symbol in the global environment), or a function (denoting itself).
Iteratively
You can do this using dolist. The [documentation for actually shows that dolist has a few more tricks up its sleeve. The full syntax is from the documentation
dolist (var list-form [result-form]) declaration* {tag | statement}*
We don't need to worry about declarations here, and we won't be using any tags, but notice that optional result-form. You can specify a form to produce the value that dolist returns; you don't have to accept its default nil. The common idiom for collecting values into a list in an iterative loop is to push each value into a new list, and then return the reverse of that list. Since the new list doesn't share structure with anything else, we usually reverse it destructively using nreverse. Your loop would become
(defun test (argument)
(let ((results '()))
(dolist (op *operators* (nreverse results))
(push (funcall op argument) results))))
Stylistically, I don't like that let that just introduces a single value, and would probably use an &aux variable in the function (but this is a matter of taste, not correctness):
(defun test (argument &aux (results '()))
(dolist (op *operators* (nreverse results))
(push (funcall op argument) results)))
You could also conveniently use loop for this:
(defun test2 (argument)
(loop for op in *operators*
collect (funcall op argument)))
You can also do somewhat succinctly, but perhaps less readably, using do:
(defun test3a (argument)
(do ((results '() (list* (funcall (first operators) argument) results))
(operators *operators* (rest operators)))
((endp operators) (nreverse results))))
This says that on the first iteration, results and operators are initialized with '() and *operators*, respectively. The loop terminates when operators is the empty list, and whenever it terminates, the return value is (nreverse results). On successive iterations, results is a assigned new value, (list* (funcall (first operators) argument) results), which is just like pushing the next value onto results, and operators is updated to (rest operators).
FUNCALL works with symbols.
From the department of silly tricks.
(defconstant *operators* '(op1 op2 o3))
(defun test (&rest arg)
(setf (cdr arg) arg)
(mapcar #'funcall *operators* arg))
There's a library, which is almost mandatory in any anywhat complex project: Alexandria. It has many useful functions, and there's also something that would make your code prettier / less verbose and more conscious.
Say, you wanted to call a number of functions with the same value. Here's how you'd do it:
(ql:quickload "alexandria")
(use-package :alexandria)
(defun example-rcurry (value)
"Calls `listp', `string' and `numberp' with VALUE and returns
a list of results"
(let ((predicates '(listp stringp numberp)))
(mapcar (rcurry #'funcall value) predicates)))
(example-rcurry 42) ;; (NIL NIL T)
(example-rcurry "42") ;; (NIL T NIL)
(defun example-compose (value)
"Calls `complexp' with the result of calling `sqrt'
with the result of calling `parse-integer' on VALUE"
(let ((predicates '(complexp sqrt parse-integer)))
(funcall (apply #'compose predicates) value)))
(example-compose "0") ;; NIL
(example-compose "-1") ;; T
Functions rcurry and compose are from Alexandria package.
Could someone explain to me what's going on in this very simple code snippet?
(defun test-a ()
(let ((x '(nil)))
(setcar x (cons 1 (car x)))
x))
Upon a calling (test-a) for the first time, I get the expected result: ((1)).
But to my surprise, calling it once more, I get ((1 1)), ((1 1 1)) and so on.
Why is this happening? Am I wrong to expect (test-a) to always return ((1))?
Also note that after re-evaluating the definition of test-a, the return result resets.
Also consider that this function works as I expect:
(defun test-b ()
(let ((x '(nil)))
(setq x (cons (cons 1 (car x))
(cdr x)))))
(test-b) always returns ((1)).
Why aren't test-a and test-b equivalent?
The Bad
test-a is self-modifying code. This is extremely dangerous. While the variable x disappears at the end of the let form, its initial value persists in the function object, and that is the value you are modifying. Remember that in Lisp a function is a first class object, which can be passed around (just like a number or a list), and, sometimes, modified. This is exactly what you are doing here: the initial value for x is a part of the function object and you are modifying it.
Let us actually see what is happening:
(symbol-function 'test-a)
=> (lambda nil (let ((x (quote (nil)))) (setcar x (cons 1 (car x))) x))
(test-a)
=> ((1))
(symbol-function 'test-a)
=> (lambda nil (let ((x (quote ((1))))) (setcar x (cons 1 (car x))) x))
(test-a)
=> ((1 1))
(symbol-function 'test-a)
=> (lambda nil (let ((x (quote ((1 1))))) (setcar x (cons 1 (car x))) x))
(test-a)
=> ((1 1 1))
(symbol-function 'test-a)
=> (lambda nil (let ((x (quote ((1 1 1))))) (setcar x (cons 1 (car x))) x))
The Good
test-b returns a fresh cons cell and thus is safe. The initial value of x is never modified. The difference between (setcar x ...) and (setq x ...) is that the former modifies the object already stored in the variable x while the latter stores a new object in x. The difference is similar to x.setField(42) vs. x = new MyObject(42) in C++.
The Bottom Line
In general, it is best to treat quoted data like '(1) as constants - do not modify them:
quote returns the argument, without evaluating it. (quote x) yields x.
Warning: quote does not construct its return value, but just returns
the value that was pre-constructed by the Lisp reader (see info node
Printed Representation). This means that (a . b) is not
identical to (cons 'a 'b): the former does not cons. Quoting should
be reserved for constants that will never be modified by side-effects,
unless you like self-modifying code. See the common pitfall in info
node Rearrangement for an example of unexpected results when
a quoted object is modified.
If you need to modify a list, create it with list or cons or copy-list instead of quote.
See more examples.
PS1. This has been duplicated on Emacs.
PS2. See also Why does this function return a different value every time? for an identical Common Lisp issue.
PS3. See also Issue CONSTANT-MODIFICATION.
I found the culprit is indeed 'quote. Here's its doc-string:
Return the argument, without evaluating it.
...
Warning: `quote' does not construct its return value, but just returns
the value that was pre-constructed by the Lisp reader
...
Quoting should be reserved for constants that will
never be modified by side-effects, unless you like self-modifying code.
I also rewrote for convenience
(setq test-a
(lambda () ((lambda (x) (setcar x (cons 1 (car x))) x) (quote (nil)))))
and then used
(funcall test-a)
to see how 'test-a was changing.
It looks like the '(nil) in your (let) is only evaluated once. When you (setcar), each call is modifying the same list in-place. You can make (test-a) work if you replace the '(nil) with (list (list)), although I presume there's a more elegant way to do it.
(test-b) constructs a totally new list from cons cells each time, which is why it works differently.
What is the proper way to do a setf for the variable below?
CG-USER(279): (defun LETTERSEARCH (string1 string2)
(let ((newString nil))
(let ((letterSearchOn nil))
(loop for i from 0 below (length string1)
always
(setf (letterSearchOn (char string1 i))
(print letterSearchOn))))))
LETTERSEARCH
CG-USER(280): (stringprod "abc" "abc")
NIL
Error: `(SETF LETTERSEARCHON)' is not fbound
[condition type: UNDEFINED-FUNCTION]
CG-USER(281):
That should be (setf letterSearchOn (char string1 i)).
The way (setf) works in Common Lisp is really cool; it's a macro, but the macro expander which is used depends on the argument. For example:
(defparameter a (list 1))
(setf (car a) 2)
a ; => (2)
(setf (cdr a) (list 3))
a ; => (2 3)
Does that seem strange? (car a) is a function... how can you "set" it to a new value??? The answer is that if the first argument to (setf) is a list which starts with car, it expands to code which sets the car of a cons cell. If the first argument is a list which starts with cdr, it expands to code which sets the cdr of a cons cell. And so on for vectors, hash tables, etc. etc.
You can even define your own (setf) macros, which can expand the range of things which (setf) knows how to set. In this case, you are passing (letterSearchOn (char string1 i)), so it thinks that you want it to use a special letterSearchOn macro expander, but no such setf macro expander has been defined.