freenode/#lisp - IRC Chatlog
Search
18:10:34
stacksmith
Bike: what does it mean if the form is not a top level form? I am confused. Could you elaborate on how lexical function bindings affect setf bindings?
18:23:50
stacksmith
Yikes. Call me dense, but what the heck happens if a defining macro is inside another definition? It appears that there are no compile-time effects for that form (or the rest of the file), but at some later time - like the next file?
18:25:18
jasom
the compiler need not store the definition of it, so strange things can happen. Ultimately just don't do that
18:27:17
jasom
stacksmith: from a practical point of view, your analysis tool could be free to reject code with non-toplevel defmacros
18:28:15
stacksmith
jasom: is there a reason the spec doesn't just say that defining macros _should_ be toplevel? Is there a situation where it is useful otherwise, or would be problematic if so stipulated?
18:28:22
jasom
non-toplevel DEFUNs have some uses (e.g. a defun inside a let), but I'm strugging to think of any use for a non-toplevel defmacro
18:30:37
Bike
stacksmith: if it's not toplevel it doesn't have the effects described if it's toplevel, namely, being done at compile time. the same as any other form, its effects will occur when it's executed. so if it's in a function body, the global macro binding will be made when the function is called and control reaches the defmacro form.
18:40:52
stacksmith
Usually you don't macroexpand at runtime, I suppose. But binding a global function at runtime is valid, isn't it? CLHS states that there are no compile-time side effects for defun and the definition is not even available. So a defun deep inside another function body will get compiled with the surrounding function but bound when the surrounding function is executed, correct?
18:42:53
stacksmith
I mean when the inner defun is reached, of course, not just the surrounding function.
18:44:27
jasom
there are limitations to redefining functions though, related to the rules of when it is permissible to inline
18:45:23
jasom
but yes, (funcall 'foo) (defun foo () ...) (funcall 'foo) ;; <-- the second funcall will get the new definition of foo
18:48:24
jasom
you provably cannot do a lot of useful static analysis on unrestricted CL code, so you'll need to determine a subset you are going to work with
18:56:57
stacksmith
Ideally I would restrict the subset to thing actually defined by the standard, but sometimes it's a little hard to figure out as I am only an egg.
19:02:54
stacksmith
jasom: I am assuming modern compilers know that you are fiddling with a global function binding, whether it's by setfing fdefinitions or defunning inside a function body, and compile an indirect call. It seems in some cases you can make it impossible to figure out, which should also default the compile to a runtime-safe behaviour. But is there a CLHS restriction of where defun may be located, if not at toplevel?
19:15:52
stacksmith
Is there a static analysis library for CL? I haven't found much - and I can see why...
19:19:37
stacksmith
There are more problems than I ever imagined. A walker almost does the trick, but the walkers I've seen do not correlate source forms to walked forms or provide adequate hooks to definitively walk a form and identify every subform.
19:24:16
pfdietz
A source object can occur more than once in a form, so any such linkage would require some representation of the path down to the objecr.
19:26:48
stacksmith
Ideally, the walker would literally walk the source tree with a callback on every cons, providing environmental info and data about the car. I don't care about macroexpansions other than the side-effects such as new bindings, etc.
19:28:28
stacksmith
One would think in the last 60 years or so someone - anyone - would want something like that.
19:37:57
jasom
You not only lose source locations, but also things like #+/#- and comments when you operate on code already processed with READ
19:38:45
jasom
stacksmith: well it's not *just* that nobody's done it, but doing it in the general case is impossible so there is no general purpose tool.
19:39:18
jasom
most lisp code includes macros not part of the standard that implement new bindings, so you can't not care about macroexpansions
19:40:03
jasom
and you can't just macroexpand the code because implementations are free to macroexpand standard forms to code that includes non-standard special operators
19:40:51
stacksmith
jasom: yeah, I understand. As for macros - by not caring I mean I don't want to see/get callbacks for macroexpansions, but just get a report about new bindings.
19:46:48
Bike
walkers exist. compilers are walkers. some implementations include a more general mapping interface.
19:50:18
stacksmith
I came across HTML library that had a walker, now can't remember which. Saw lizard, dwim, damnit...
19:54:26
stacksmith
Right. Most of the time those who walk don't mind transforming what's ahead/abandoning what's behind...
19:55:12
stacksmith
Bike: does the intermediate representation maintain references back to original forms?
19:59:31
dlowe
maybe so, but when you output the results of your analysis, your poor human needs to find the spot in their (text) codebase.
20:00:50
stacksmith
Right. I often wish there was a way to extend conses to stash extra data and yet have everything work.
20:04:29
stacksmith
dlowe: does that really work? I thought conses are subject to black magic inside.
20:05:12
dlowe
(defclass cons () ((car :accessor car :initarg :car) (cdr :accessor cdr :initarg cdr) (text-location :accessor text-location))
20:05:16
aeth
You can write your own custom conses out of structs. You'd lose about 30% performance, though.
20:06:54
stacksmith
SBCL's cons is a primitive object... Do you think that walkers don't mind walking shit conses as long as car and cdr work and the class name is 'cons'?
20:08:02
Bike
if you want source code but with extra location information attached, beach's CST systems work for that
20:09:31
dlowe
stacksmith: I think at this point, you might as well just stop calling what you have conses and start calling them AST nodes
20:10:36
stacksmith
Binding information is largely available from walking, which includes looking into macros and such.
20:11:15
Bike
stacksmith: you could have somewhat freaky, but legal code like (progn #1=(print *x*) (let ((*x* 19)) #1#)). in this case there is one (print *x*) cons that refers to two different bindings.
20:11:17
stacksmith
AST nodes is fine - the interesting part is that you can actually compile these.
20:11:29
HighMemoryDaemon
Is Practical Common Lisp the best starting point for someone looking to learn the language?
20:13:21
HighMemoryDaemon
Bike: Very amazing that it is completely free online. I wish the physical book wasn't so expensive or I'd love to support the author by purchasing it.
20:33:30
scymtym
stacksmith: i second Bike's suggestion of using a non-s-expr representation and the eclector and concrete-syntax-tree libraries (now in quicklisp) specifically. this is a test i made using those in which the lexical variable X and a reference to it are correctly associated despite some obfuscation: https://techfak.de/~jmoringe/eclector-cst-toy-macrolet.png
23:14:56
sjl
ugh, reconsidering my redefining of /= as NOT= after I just lost 10m debugging why (\= n m) was returning t when n and m were both 1
23:43:17
pjb
sjl: I sympathize. Having used MS-DOS and MS-Windows leaves your brains so deteriorated for life. Poor little guy!
23:44:15
sjl
pjb: yeah, it's similar to how prologed emacs use leaves you illiterate, able to communicate only in monosyllabic grunts of "ctrl, meta, meta h"
23:49:19
White_Flame
\= is the Prolog syntax for "does not unify", so maybe that was in your history somewhere
23:52:10
sjl
White_Flame: damn, I didn't even think of that. I'm in the middle of the Prolog class SWI is doing this summer.
4:02:48
stylewarning
CopyLeft could have cool things like recursive structures and parametric polymorphism and jump tables
4:10:40
PuercoPop
What I would like is an extensible environment to develop in similar to Smalltalk. McCLIM is the best FLOSS alternative in that direction that I know of. But as they say, "Write the code you want to see in the World"
4:14:38
stylewarning
parjanya: I want to DEFSTRUCT A and B with them referring to one another with :type and not have CL croak