freenode/#lisp - IRC Chatlog
Search
9:08:28
jackdaniel
maybe when break is caught outside the swank debugging environment it should create one?
10:55:23
smokeink
I want to write a function that transforms some code (checks the cdr of each subtree and when it encounters certain symbols, replaces them with some data). Should I write it all by hand or should I use a code walker? what are code walkers used for?
10:56:51
no-defun-allowed
A code walker is used when one has to respect lexical scoping while replacing code.
10:56:54
pjb
(defun foo (some-code) (subst '(some data) 'certain-symbol some-code)) #| --> foo |# (foo '(if certain-symbol (print 'certain-symbol))) #| --> (if (some data) (print '(some data))) |#
10:57:38
no-defun-allowed
For example, it might be okay to substitute X in (+ x 2) but the client would expect a their own value for X in (let ((x 4)) (+ x 2))
10:57:44
pjb
smokeink: yes, you need to code walk. (foo '(list certain-symbol (let ((certain-symbol 2)) (+ certain-symbol certain-symbol)))) #| --> (list (some data) (let (((some data) 2)) (+ (some data) (some data)))) |#
10:58:21
no-defun-allowed
And, yeah, as pjb says, for respecting the meanings of symbols in special forms too.
11:12:48
smokeink
I need to replace only symbols at certain positions, for example in (* * *) I'd like to replace only the 2nd and 3rd '* . I was thinking to improve #'trec from http://lib.store.yahoo.net/lib/paulgraham/onlisp.lisp , to make it record the current position for each leaf
11:14:49
smokeink
Then i want to make something more complicated : for symbols starting with i! to add (declare (ignorable ...)) at the right position , so I need this ability to modify things at certain positions in the tree
11:18:48
smokeink
I was curious if there are utilities to assist such tasks. why do people write so many macroexpand-dammit, macroexpand-all code walkers?
17:02:39
pfdietz63
smokeink: the problem is that it's not possible to portably write a code walker that works in all cases.
17:03:34
pjb
The proof it's possible to write a portable (conforming) code walker, is the existance of actual compilers written in conforming Common Lisp, such as eg. sicl.
17:05:07
pjb
pfdietz63: by noting that you cannot do anything with environments, but pass them to macroexpand.
17:05:36
pjb
pfdietz63: therefore you can give your macros and macrolets whatever you want, (and catch it back when it calls your macroexpand).
17:07:16
pjb
Ok, I may accept the argument that as for a lot of other things, once you start, you have to implement your own CL to do it… But it is not an argument proving impossibility.
17:11:51
pfdietz63
Raskin says it's not fully possible: https://users.mccme.ru/raskin/code-walking-slides.pdf
17:12:23
pfdietz63
I do not consider layering another CL on top of your CL to be a workable solution.
17:15:25
pjb
pfdietz63: also, note the very important specification item of a code walker: you want to interpret conforming code in a conforming way. You don't necessarily want to interpret it the way the implementation interprets it. The code walker can provide its own standard macros (and macros for special operators).
17:19:32
pjb
pfdietz63: if you use impossible specifications, of course it will be impossible! If you use reasonable specifications, it'll be very possible.
17:21:40
beach
I should examine the argument by MichaelRaskin and see whether it is correct. I suspect he is making assumptions that might sound reasonable but that are not necessarily correct.
17:22:25
pjb
For example, he wants to call macroexpand-all outside of the lexical context, or without rebuilding it. This is a silly specification.
17:23:27
edgar-rft
apropos pedantic: pfdietz63 said it's not possible to portably write a code walker that works in all cases. Please note that "all casess" includes all impossible cases.
17:31:48
pfdietz63
I have written code where macroexpand-1 is called manually, in macros. It's not an unreasonable thing to do. A particular macro style uses macrolets to pass information down to nested macro forms, in the envirornment.
17:32:39
pfdietz63
If you want your code walker to leave the macrolets in the code, you can't do it in general.
17:34:20
pfdietz63
You can write a code walker that fully expands everything and removes all macrolets and symbol-macrolets, I think. But if you (say) want a code walker that allows manipulation of the code closer to the source level, and gives something that's not fully expanded, it can't work portably in general.
17:35:00
pfdietz63
Actually... I'm not even sure one can do that. What does the code walker do when it gets to a macrolet?
17:36:10
pfdietz63
I am talking about doing this in the lisp one is given, not doing a "Lisp is Turing complete so I can layer an entire new implementation on it that does what I want".
17:42:11
pfdietz63
One way to add that constraint is that it must handle macros that are "opaque", in the sense that for those macros all you can do with them is macroexpand them. You cannot go and recompile them yourself.
17:43:13
pfdietz63
That means you cannot reimplement your own version of environments; those opaque macros need the system environment.
19:20:09
jackdaniel
HiRE: both are used to return from a block. return-from is used to return from a named block, while return is equivalent to (return-from nil :result) (that is to return from block named NIL)
19:22:39
HiRE
asdf_asdf_asdf: I am reading that chapter. In ANSI Common Lisp Graham used `return`, PCL seems to like `return-from`
19:22:41
jackdaniel
HiRE: if you want to look up some operator, it is worth to check out l1sp.org (note that second character is a digit)