freenode/#lisp - IRC Chatlog
Search
6:50:24
emaczen
phoe: I'm reading the definitions of sb-mop:ensure-class and sb-mop:ensure-class-using-class
6:52:10
emaczen
The reason why, is because the metaclass object in (defmethod ensure-class-using-class ((class null) name &rest args &key) ...) has type standard-class
6:53:02
emaczen
I put a break point in the call right above (apply #'make-instance metaclass :name name initargs)
7:12:34
emaczen
The problem is the metaclass argument in ensure-class-using class is a standard-class with the name of my metaclass
7:18:04
emaczen
Before, after I tried what I thought, then I tried make-instance like you originally said haha
8:32:18
schweers
I have a question about DECLAIM. If I put a toplevel form at the beginning of a file, it will affect the compilation of the rest of said file, correct?
8:33:53
jackdaniel
schweers: "As with other defining macros, it is unspecified whether or not the compile-time side-effects of a declaim persist after the file has been compiled. "
8:34:46
schweers
I can’t help it, but this seems like a bad idea. Do you know the reasoning behind this descision?
8:37:15
schweers
This seems to me as if the declaim forms in a library I load (might) affect how my code is optimized. Or did I get that wrong?
8:38:02
jackdaniel
it is unspecified, so they might (just as proclaim and changing reader settings will)
8:39:09
jackdaniel
as of rationale: I can imagine it is for consistency with other macros which are treated specially when toplevel
8:40:22
schweers
I’m not sure which others are treated this way, can you give an example off the top of your head?
8:43:04
jackdaniel
i.e defmacro, in-package and such, they affect compiler even without being put in eval-when
8:43:45
schweers
Ah, and there too it is unspecified when the effect ends? Well, I guess not for defmacro, but for in-package?
8:51:04
jackdaniel
this is a tricky one, in-package setf *package*, but package is bound for each file
9:03:35
makomo
"(...) nor is it specified whether they are available in subsequent compilation units or subsequent invocations of the compiler."
9:10:57
makomo
and then there's also "In particular, the information stored by the defining macros at compile time might or might not be available to the interpreter (either during or after compilation), or during subsequent calls to the compiler.", along with a surprising example
9:11:22
schweers
It seems to me that this is so that (say) defmacro causes effects which affect runtime, but not compilation. But I’m not sure.
9:20:54
pjb
No, it's just that you can compile the code in a different image than where you load it, and also where you run it.
9:21:51
pjb
ccl -x '(compile-file "foo.lisp")' -x '(ccl:quit)' ; ccl -x '(load-file "foo")' -x '(ccl:save-application "foo" …)' -x '(ccl:quit)' ; ./foo
9:22:07
pjb
It's compiled in the first process, loaded in the second process, and executed in the third process.
9:22:34
pjb
There is nothing in common between the first two process (compilation, load), and little in common between the second and the third.
9:23:13
pjb
And with ecl, it's even worse, since it doesn't save a lisp image, but reload the compiled files when you launch the run-time program.
9:24:03
schweers
Well, doesn’t your example also load the code twice? Once in the second step, and again in the third?
9:25:51
schweers
So if I added a (eval-when (:load-toplevel) ... ) with some visible side-effect (say, format), it would only show up once?
9:26:01
pjb
schweers: it's easy to see: (eval-when (:compile-toplevel) (print :compile-toplevel)) (eval-when (:load-toplevel) (print :load-toplevel)) (eval-when (:execute) (print :execute)) (defun main () (print :run-time))
9:27:21
pjb
Saving a lisp image, and restoring is neutral for non-live data. (and even for some live data, eg. clisp tries to re-open opened files if they're found at the same path).
9:27:29
schweers
Running such an executable does something similar to loading, right? Somehow the image has to be restored. But this is not considered load-time as far as the language is concerned?
9:29:17
pjb
This is why you have this development mode, called "in image", where you run a lisp image, mutate it (eg. at the repl), and save it for the next session, rinse and repeat until your lisp image contains your application.
9:29:39
schweers
Even though there are still some cases which I have not yes successfully wrapped my head around, I like how most implementations handle this image based approach.
9:29:53
pjb
The defect of this development mode is that it's not reproducible, unless you have very good introspection tools (not in standard CL implementations, but have a look at ibcl).
9:29:59
makomo
just to refresh my memory: :compile-toplevel corresponds to COMPILE-FILE, :load-toplevel to LOADing compiled files, and :execute to EVAL/LOADing source files, right?
9:29:59
pjb
Image Based Development http://www.informatimago.com/develop/lisp/com/informatimago/small-cl-pgms/ibcl/index.html
9:31:57
makomo
and what about COMPILE? i always forget how that fits into the picture. i guess COMPILE doesn't do top-level form processing so the only relevant situation is :execute?
9:34:16
makomo
hm yeah, only :execute is relevant, but the evaluation happens at run-time of course, once the compiled function is called
9:35:18
makomo
pjb: but even with all this EVAL-WHEN recap, is this line "nor is it specified whether they are available in subsequent compilation units or subsequent invocations of the compiler" not surprising?
9:35:42
pjb
(eval-when (:compile-toplevel) (compile foo)) But by definition compile doesn't compile toplevel forms.
9:36:24
makomo
pjb: i meant more like (compile nil '(lambda () (eval-when ...)), but yeah, not top-level form processing so that's settled
9:39:26
makomo
so let's say we have files A and B, and there's a macro M defined in A. subsequent forms in A use the macro M, and forms in B also use the macro M. does this mean that just compiling A is not enough in order to compile B?
9:39:38
makomo
i.e. you'd have to also load A in order to be sure that M is available when B is being compiled?
9:41:14
pjb
See the discussion about the environments at http://www.lispworks.com/documentation/HyperSpec/Body/03_ba.htm
9:42:34
pjb
M can be used in A, because the compiler will use what it has saved in the compilation environment of A to be used by the rest of the file.
9:43:00
makomo
yeah, i've read this a couple of times. now i see that it's actually quite a normal thing, but it was surprising to me because it regarded such a common macro, DEFMACRO (but i get that that makes no difference now)
9:43:04
pjb
On the other hand, M can be used in B, only because the compiler saved some information in the fasl file, that has been loaded into the compilation environment of B.
9:44:31
pjb
But notice that how the enviroments are segregated is entirely implementation dependent. But you find that you soon need to load A to compile B.
10:31:26
schweers
Given a class, I want to get all slots in it (to generate some code for every slot). Do I have to use MOP for this?
10:33:20
no-defun-allowed
You could write a macro which reads the defclass slot descriptions and generates code from them.
10:33:21
schweers
Now that I think about it, I could instead use a macro which defines both the class and the code per slot. This may be easier.
10:41:19
beach
schweers: Using the MOP is usually not a problem. There is the CLOSER-MOP library for that.
10:42:42
no-defun-allowed
Maybe https://stackoverflow.com/questions/40742048/is-there-a-way-to-get-the-slots-of-a-class is relevant for this use case.
10:44:14
no-defun-allowed
The stackoverflow post provides code to get slot names though, through slot-definition-name.
10:46:44
schweers
I’ll just create the class and the assorted per-slot code in a single macro. It also saves some work in defining the class.
10:48:41
schweers
But I’ll have to look at MOP someday. It’s a shame that I’m limiting my designs by not knowing MOP.
10:58:25
schweers
My guess is also that it will understand my CLOS and general OO understanding. So that alone is probably a good reason to learn more about MOP.
13:15:32
dim
beach: hi! I stumbled upon http://herpolhode.com/rob/utah2000.ps this morning and got to think about your LispOS project in that context again, so I though if you didn't read the piece from Rob Pike before, you might like it... the title is “Systems Software Research is Irrelevant” and it was publised Feb 21, 2000
13:34:11
heisig
If I remember correctly, Rob Pike once convinced Stephen Wolfram to write Mathematica in C instead of Lisp. His argument was that 'C is more modern'.
13:34:32
heisig
And the fun twist - Pike is now working on Go, which is basically C with GC and closures.
13:40:39
beach
My thesis advisor tried to convince Wolfram to use our very efficient rewrite engine as the core of Mathematica, but he declined.
13:43:52
heisig
The interesting part is how even very smart people like Wolfram can make software engineering decisions that are totally bonkers.
13:50:16
beach
And this is my dissertation, but no PDF is available: https://dl.acm.org/citation.cfm?id=59707
13:52:05
beach
My dissertation works is summarized here https://link.springer.com/chapter/10.1007%2F3-540-51081-8_125
13:52:47
beach
I have vague plans to typeset my dissertation using LaTeX, but I am too lazy I think.
13:55:42
lieven
Guy Steele convinced Knuth his typesetting system needed to be programmable. And then Knuth chose a macro rewriting system :(
13:57:14
beach
The book by O'Donnell describes the language and an interpreter for it. I generalized the class of programs that could be handled, and I showed how to write a compiler for it, rather than an interpreter. The compiler uses partial evaluation in an interesting way, in that part of the compiled code is generated from partial evaluation of the same code that is compiled.
13:58:46
shka__
beach: would same approach be usefull for creating lisp-embedded efficient logic programming language?
13:59:38
shka__
by that i mean something around the same order of magnitude fast as prolog implementations
13:59:54
beach
Yes, but not Prolog-style "logic programming". Equational logic programming, which is basically rewriting.
14:01:08
beach
But, yes, I have had plans to embed the engine in Common Lisp. The compiler that I wrote for my dissertation generated VAX assembly code.
14:02:16
lieven
ACTION started in between the 'all the world is a vax' and 'all the world is a sun' periods
14:05:11
shka__
authors even implemented basic prolog-like language in it using java, codebase was very compact and performance was more then decent
14:05:18
Ukari
the code `(funcall (lambda () (print "foo")) "bar")` will throw a `invalid number of arguments: 1` error, I know use `(lambda (&optional x))` could prevent from it, but is there anything equivalent to the `funcall` but which could auto decide between expression-A `(funcall (lambda (x) (print "foo")) "bar")` and expression-B `(funcall (lambda () (print "foo")))`, and not rely on a specific implementation?
14:06:10
Bike
Ukari: there's no function that will tell you how many arguments a function accepts, if that's what you mean.