libera/#commonlisp - IRC Chatlog
Search
16:22:25
MichaelRaskin
macroexpand and macroexpand-1 perform the expansion but do not evaluate the result of the expansion
16:23:06
gin
beach: I have a macro add-key-value to add a key value pair to an alist. I wrote a macro for this because that is the only way I see to implement something like (add-key-value "name" "Harry" alist) type of calls.
16:23:07
beach
gin: Macros are usually compile-time features. It doesn't make much sense to "invoke" them at run time.
16:23:59
gin
beach: So the problem I have having is that if I have another function that takes alist and uses add-key-value, this function should also become a macro now to avoid alist being copied by value to this function.
16:25:26
gin
beach: how can I implement function add-key-value so that (add-key-value "name" "Harry" alist) works then. With a function, I see the alist I pass never sees the change done within add-key-value
16:27:33
beach
gin: So you don't mean that you add things to an alist. You mean that you modify the place that contains the alist.
16:28:13
gin
beach: yes. but I was originally looking to modify the alist itself. when I could not do that I modified the place containing the alist using defmacro
16:29:42
beach
gin: I suggest you turn your alist into an abstract data type that you can then modify with a function.
16:30:25
beach
gin: Alists and lists in general, are not abstract data types. They should mostly be used as building blocks for abstract data types. Not so much be used by themselves for things like this.
16:30:42
beach
gin: If you insist on using alists, then use the return value of your addition function.
16:33:40
beach
gin: Then (defun add-key-value (key value dictionary) (push (cons key value) (contents dictionary)))
16:55:40
pjb
gin: notice how (let ((a '())) (values (setf (aget a :key) 42) a)) #| --> 42 ; ((:key . 42)) |# (setf aget) both returns the new value 42, and mutates the place A (which could be more complex than just a mere variable reference, and still handled correctly thanks to get-setf-expander and define-setf-expander).
16:56:37
pjb
gin: of course, you can s/aget/key-value/g and (setf (key-value person-alist :name) "Harry")
17:34:12
char
hyperspec says set is depricated. It also seems that both set and symbol-value cannot access the lexical value of a symbol
17:36:51
Xach
char: that means it's time to think about a different approach, like maybe having a lookup table keyed by symbols instead.
17:43:38
char
it is for my tailrec macro, someone told me to stop using destructuring-bind and set the variables manually (to avoid code duplication in macroexpandsion). So I have quoted symbols (that were present in the original lambda list and used in the body of the function, and I have their values stored in a list in a (gensymed) symbol. I was thinking "just (mapc 'set ',params ,args)", but since the params are lexically bound, it is almost as
17:51:11
char
keep in mind that paramas is a list of symbols at macro time, and args is the gensym containing the list of values at run time.
17:56:07
char
my thought was that I can't map over args at compile time because the list doesn't exist yet, but is should be the same length as params, so maybe I can expand a bunch of (setq ,param (elt ,args n).
19:01:18
mfiano
ELT is a good choice if the intent to the reader is that it is operating on a more generic sequence
19:01:37
char
shka: right, of course, but I don't have much of a choice in my situation. Also the list will be fairly short
19:05:47
shka
however, usually people will rather use with-gensyms instead of explicit (gensym) in let
19:08:21
pranavats
And you might also consider using mapcar instead of (map 'list ...) given that more specific forms are easier to read.
19:09:57
shka
however, it's utility stems from the fact that it is very useful when you may otherwise need to write code walker
19:13:31
shka
then you may simply defmacro... `(defun ,function-name (,@arguments) (tagbody ,!start (macrolet ((,function-name (,@!generated-arguments) `(progn arguments-handling-goes-here (go ,',!start)...
19:26:36
shka
char: take a look at this https://gist.github.com/sirherrbatka/10c7631f502272fc55a66bc75973ac27
19:54:36
char
shka: That took me a bit to understand, but I think I get it now. It is neat, but I don't think it is right for this project, since once of the goals is that non-tail-recursive functions should still function properly.