[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
bug#27177: 26.0.50: Macroexpanding cl-loop and friends (make-symbol usag
From: |
Alex |
Subject: |
bug#27177: 26.0.50: Macroexpanding cl-loop and friends (make-symbol usage) |
Date: |
Thu, 01 Jun 2017 22:42:45 -0600 |
User-agent: |
Gnus/5.13 (Gnus v5.13) Emacs/25.1 (gnu/linux) |
Michael Heerdegen <michael_heerdegen@web.de> writes:
>> It would also be nice if instead of many --cl-var-- variables,
>> particular clauses would result in different symbol-names. For instance,
>> if the `repeat' clause made a symbol called --cl-repeat--. This would
>> further help readability.
>
> I'm not sure if that is doable without rewriting the implementation,
> since the macro expansion is automatically written code.
I'm not sure what you mean. Since they're uninterned symbols their
symbol-names shouldn't matter unless a procedure calls #'symbol-name on
them. In cl-macs.el I don't see any examples of that.
It appears that the code sometimes does use different names already in a
couple places. For example, see --cl-vec-- and --cl-idx-- at about line
1294 in cl-macs.el.
Actually, looking at the git-blame for those lines, it looks like Stefan
switched from gensym to make-symbol all the way back in e542ea4bed!
Stefan, why did you make the switch? Using cl-gensym would help a ton
with readability of cl-loop's macroexpansion.
>> Also, using gensym could help 3rd-party packages. I usually use
>> macrostep to expand macros and the value of print-circle has no effect
>> on its expansions. macrostep individually prints out each uninterned
>> symbol using prin1; can this approach be easily modified to get the same
>> result as macroexpand?
>
> AFAICT `print-circle' and `print-gensym' also control how `prin1'
> prints.
Does print-circle? Consider:
(prin1 `(cons ,(make-symbol "hello")
,(make-symbol "hello")))
print-gensym certainly makes a difference in the output, but
print-circle doesn't seem to.
However, I don't know how prin1 would keep track of the uninterned
symbols across many different procedure calls, which it would need to do
for it to know what is being shared.
> Note that when we changed the code to use `cl-gensym', we would not have
> a really clean solution for the readability problem: if you print with
> p-gensym and p-circle on, it would not look much different than now. If
> you print with those flags off, you (still) print to different (not
> equivalent) code: when you read (evaluate) it, all uninterned symbols
> would be replaced with interned symbols. Though, with numbered symbol
> names, you will be probably be lucky in most cases that the difference
> doesn't matter.
In the case with both flags off and with make-symbol calls changed to
cl-gensym, I got:
(cl-block nil
(let*
((--cl-var--248
'(1 2 3))
(x nil)
(--cl-var--249
'(a b c))
(y nil)
(--cl-var--250 nil))
(while
(and
(consp --cl-var--248)
(progn
(setq x
(car --cl-var--248))
(consp --cl-var--249)))
(setq y
(car --cl-var--249))
(push
(list x y)
--cl-var--250)
(setq --cl-var--248
(cdr --cl-var--248))
(setq --cl-var--249
(cdr --cl-var--249)))
(nreverse --cl-var--250)))
Which is equivalent code to the original cl-loop. I also believe it's
much more readable than the current macroexpansion as you can actually
differentiate between the different --cl-var-- variables. Using
different symbol names as discussed above would help a lot as well, but
I still think this part is important as well.
> But I see your point: the readability is a real problem. Maybe we could
> instead improve how things are printed? Unfortunately that lies beyond
> my knowledge.
I'm not sure what you mean, but improvement is certainly welcome.
>> PS: The first line of the documentation of print-circle only mentions
>> that it affects recursive structures. Perhaps it should mention the
>> "shared substructures" part in the first line for emphasis?
>
> I agree but somewhat hesitate because of the variable's name, which is
> even more a source of confusion.
Right, I was a bit confused as well, but according to the Hyperspec
*print-circle* also detects sharing in objects in Common Lisp as well.