freenode/#lisp - IRC Chatlog
Search
10:21:55
random9899
an update for the package lift, not being able to locate it's own config http://dpaste.com/3JDZ8QD
12:00:25
beach
longshi: Usually, special variables are created using DEFVAR or DEFPARMETER, and they also proclaim the variable special.
12:02:35
phoe
this time I wanted to declare a variable special only locally, without creating a global binding
12:09:57
longshi
i'm still more used to (r6rs) scheme ways of doing things, but it's lisp after all, similar enough
12:10:37
beach
Is it just out of curiosity, or are you planning to write some code using Common Lisp?
12:14:25
longshi
beach: this wasn't to precise--yes, i think i will write code in CL once i know it well enough
12:17:59
beach
longshi: Wrong number of semicolons in comments. Parentheses by themselves on a line. Wrong indentation.
12:21:36
kenanb
longshi: if you are coming from scheme, you can probably just read some good library code along PCL to learn the language.
12:21:49
jackdaniel
random-nick: lsp was one of agreed extensions in the early CL days (think about MS-DOS for instance). now .lisp seem to have took over, but there are still codebases with .lsp
12:22:44
beach
Use of get- and set- prefixes. We have a few of those for historical reasons, but they should be avoided in new code.
12:27:13
beach
longshi: So if you want to look at the koans, you had better be careful not to pick up some of the bad habits in that code.
12:34:54
kenanb
longshi: also, maybe not many would agree with me, but I think Hyperspec is way more than a reference. It is a great resource to learn the language once you are familiar with the basics.
13:07:54
beach
In SICL, I plan to represent code in a code object, as written here: http://metamodular.com/code-object.pdf but I have some questions...
13:09:38
beach
In what situations should the NEXT debugger command go from the end of a form to the BEGINNING of the next form to be evaluated?
13:10:41
beach
I am thinking if two forms are just sequential like this: (form1 ...) (form2 ...) then from the end of (form1 ...) the NEXT command should go to the end of (form2 ...).
13:12:01
beach
But maybe if there is a big gap between the two forms, like in ((((.... (form1...)))) (form2 ...)) then perhaps go from the end of (form1 ...) to the beginning of (form2 ...).
13:12:28
phoe
beach: the three commands that I know from debuggers are STEP-INTO, STEP-OVER, STEP-OUT.
13:13:31
phoe
Every time, we're at the beginning of some form. STEP-INTO steps inside that form, STEP-OVER steps to the next form, and STEP-OUT steps out of the function we are currently in.
13:14:14
phoe
If you know where on the stack you are, you should be able to somehow infer information for STEP-OUT.
13:17:12
phoe
Hm. STEP-IN will put another function call on the stack and you can begin from there, i assume.
13:17:55
LdBeth
beach: if someone prefers directly working on code objects instead without any text format source code, there needs a way to print out these internal objects into human readable format, this is what I’m concerning
13:18:26
beach
phoe: That, and inlined stuff, like (F X). Computing F or X does not require a function call.
13:22:06
beach
LdBeth: Code objects are typically not used by the application programmer, so I don't see a use case for such a conversion. Plus, there is no good way to convert machine code to Common Lisp source code.
13:23:14
makomo
beach: i see that your document is just a small part of something much bigger. is this big document yet to be released?
13:23:43
beach
makomo: It is work in progress, namely the SICL specification. It is available in the repository.
13:27:10
beach
The document is not about the debugger, but about the support that the debugger needs from the implementation.
13:36:28
beach
phoe: Like if I have (f (g x) (h y)) and I am positioned between (g x) and (h y), I would expect STEP-OUT to stop after (f (g x) (h y))
13:39:42
MichaelRaskin
(if (complicated-condition) (complex-call-1) (complex-call-2)) — if the condition is false, and you are at the end of the of the condition evaluation, should there be a way to show next form to execute?
13:42:31
MichaelRaskin
Maybe not. Also, after being at the end of condition already, is there a command to go to the beginning of the next form?
13:43:55
beach
Yes, as I wrote in the document, I expect that if the current position is AFTER some form, then STEP-OVER should sometimes go AFTER the next form and sometimes BEFORE, and you have found a situation where it should stop BEFORE.
13:44:32
beach
But, yes, the table should contain an entry for each branch of the IF, so a single address should be sufficient.
13:45:17
kenanb
oh this is awesome, it provides great insight into details of a modern CL implementation.
13:46:23
beach
MichaelRaskin: Yeah, not obvious. But I think that, as far as the code object is concerned, I need three tables, one for STEP-IN, one for STEP-OVER and one for STEP-OUT.
13:48:30
kenanb
are the implementation decisions (close to/unfluenced by) a certain popular CL implementation?
13:48:55
beach
LdBeth: Yes, stepping is by forms. No, all the functions in a file share the same code object.
13:50:54
beach
kenanb: Right. Existing implementations date from several decades ago. We have better programming techniques nowadays.
13:52:12
kenanb
yeah, I was just wondering what kind of performance characteristics should etc. I should expect from SICL, I figured the answer is easy if there is a heavy influence. I don't mind ideas being new or old as long as they are good :)
13:52:17
Bike
also, i know you're asking about debugging, beach, but maybe the code object should have the load time values as well? if only for the gc.
13:52:46
Bike
though i guess if all the functions in a file have the same code object it can't be garbage collected very finely
13:54:01
beach
kenanb: In the Cleavir compiler framework, we hope to implement most of the good existing compiler optimizations from the literature, and a few of our own.
13:55:05
beach
Bike: Well, the LOAD-TIME-VALUEs are computed at, er, load-time and then they become part of the environment. That way, if they are dead, they will be garbage collected automatically.
13:56:14
beach
LdBeth: There is intermediate code if that is what you mean. But no byte codes at run time.
13:57:27
beach
kenanb: There are a few decisions that may be hard to optimize away, like the mandatory header indirection for all heap-allocated object (except CONS cells). But there are so many advantages to that representation that I am not willing to change that decision.
13:59:16
beach
LdBeth: AST and HIR are architecture independent, but MIR might have specific instructions in it.
14:02:58
drmeister
beach: When you say mandatory header indirection of all heap-allocated objects - you mean the pointer to the rack?
14:03:53
beach
drmeister: Yes, I mean that some implementations may represent things like symbols and simple arrays without a header object.
14:04:08
makomo
beach: i think there's a typo in "determine which registers contain Common Lisp objects* that should be traced"?
14:04:16
beach
drmeister: The header object in SICL is therefore an indirection that some implementations may not always have.
14:04:36
drmeister
Right - then Clasp does represent things like symbols and simple arrays without a header object. Got it.
14:05:55
makomo
beach: another observation that's interesting to me. i don't know whether it's valid, but bear with me while i try to formulate what i mean.
14:06:54
makomo
beach: so the code objects expose a certain interface for the debugger. in this approach, the code objects "know about the debugger" in a certain way, i.e. the only reason that interface exists in the first place is because of the debugger
14:07:24
makomo
does this in a certain sense "break the abstraction" or is this intentional? i.e. the code objects are just part of the whole compiler framework and it was expected all along for the debugger to exist in this context as well
14:08:18
beach
makomo: It is definitely intentional. I have already written a specification for a debugger that will use this information.
14:08:40
beach
makomo: The code object also contains information for the garbage collector, like the register map.
14:09:53
makomo
beach: btw, that document isn't searchable for me. i've tried both with Firefox and Okular.
14:10:30
makomo
oh hmm, trying to copy/paste it yields just a bunch of "diamond box with a question mark" signs
14:13:54
beach
makomo: The main thing with Clordane is that one thread is used to debug another thread, and the debugged thread can be the debugger.
14:16:07
beach
That makes it possible to set breakpoints in some standard Common Lisp functions as well, without causing the entire system to grind to a halt.
14:17:57
makomo
beach: typo in clordane.pdf "a volatile break point is also destroyed when the program control reaches is*"
14:18:46
makomo
hm, 1.2.2 says "the debugger thread can not debug itself", so i think i misunderstood what you said
14:23:10
beach
So if I am debugging some application, I can set a breakpoint in (say) FIND without affecting the compiler or any other system that might call FIND.
14:25:15
MichaelRaskin
makomo: and you need a new implementation even for a much weaker thing, like guarantees that (let ((x (+ 2 3))) (break) x) doesn't optimise x away
14:30:19
MichaelRaskin
Judging from the implementers' surprise when they learned that their implementation also optimises this away, yes debug 3 safety 3 speed 0, unless you plan the debugger beforehand, it is hard to make sure optimiser makes sucj decisions in a fully controllable way
14:30:55
MichaelRaskin
And yes, you can work around this by macros, but there is a slowdown, of course
14:34:11
MichaelRaskin
You want to say that it will never optimise this single-use variable away and never did?
14:43:58
kenanb
beach: oh I just read the relevant section. I can see the benefits (actually, I can read them) but it feels like that indirection makes certain optimizations rather impossible. Am I correct? Things like compile time method dispatch when type is known in advance ( I don't even know if that is possible with existing implementations either )
14:44:58
kenanb
beach: of course, I am not saying it is a bad idea, I am just trying to understand the implications of the decision.
14:45:13
beach
kenanb: You mean doing the optimization at the call site? That's tricky stuff anyway.
14:46:09
beach
It is tricky because methods can be added and removed after the caller has been compiled.
14:47:53
kenanb
hmm, you are correct, the method to dispatch over will indeed change as new methods are added to the generic function
14:49:18
phoe
you need to recompile a lot of code on each GF redefinition, and I don't know any implementations that do this
14:54:39
Bike
but beach's gf dispatch technique basically makes generic functions a JIT mechanism where dispatch is very fast, and doesn't involve putting methods together or anything. since the problem of method combination is made mostly static all a call cache gets you is a slightly shorter dispatch, which is probably not a huge win
14:57:48
drmeister
You can scroll around and zoom but not search (sigh). Maybe there is a better chrome PDF viewer.
14:58:14
Bike
i think one thing that would be interesting to do would be compiling accessors within method bodies as not having caches at all- since the dispatch caching could be extended to recompile things when necessary
14:59:30
makomo
beach: where should i look for this gf dispatch method that you described? i'm interested
15:01:45
kenanb
Bike: yeah, I don't know, it would probably only be significant in tight loops. It would probably be cool to be able to claim something like "inside this function, foo-method calls will always dispatch over the exact same function and I promise I will not redefine it before the end of the loop"
15:03:27
kenanb
letting compiler temporarily treat a certain method as a regular function via a claim, so it can grab a raw pointer to the function and work with it during the loop
15:05:20
kenanb
Bike: my reply was a reply to your earlier statement, I think the last one also makes sense tho
15:12:34
kenanb
of course, that optimization can usually be achieved by programmers being more specific about their intent, like refactoring that particular method body into a regular function and calling it directly when necessary, so its not a huge problem.
15:24:24
Bike
yeah i mean if the programmer is guaranteeing the method won't be redefined etc they're basically not using anything about clos
15:34:01
kenanb
well, they might still be dynamically dispatching over a gf, the claim was the dispatch is the same for calls in all iteration of that particular loop
15:35:51
kenanb
every time you hit that loop the dispatch would be done only once, but the arrays you are iterating over would hold different objects
15:46:20
Bike
it would be pretty easy for me to hook something up that fetched the effective method function for a given list of specializers. then you'd just call it. the rest is syntactic sugar
15:53:38
Bike
you could have like (with-fixed-gf (foo integer string (eql 'fazbar)) ...) expand into (let ((#:foo (effective-method-function #'foo (list (find-class 'integer) (find-class 'string) (intern-eql-specializer 'fazbar))))) (flet ((foo (&rest args) (apply #:foo args))) ...)) for a start
16:02:16
specbot
Naming of Compiler Macros: http://www.lispworks.com/reference/HyperSpec/Body/03_bbab.htm
16:02:32
phoe
Compiler macro definitions are strictly global. There is no provision for defining local compiler macros in the way that macrolet defines local macros.
16:05:21
makomo
how do you guys pronounce "macrolet"? ever since i read that about it in cltl2, i can't stop pronouncing it in a way that rhymes with chevrolet :-)
16:19:57
kenanb
Bike: yeah, that looks like a pretty elegant way to express such a thing. btw your ELS talk is very interesting.
16:23:31
alandipert
anyone have suggestions about how i could speed this up? it's currently about 2x slower than c. thanks in advance! https://github.com/alandipert/puzzles/blob/master/blackjack/sbcl/outcomes_optimized.lisp
16:28:53
alandipert
my guess is function call overhead (of PARTITIONS) is maybe the next slowest thing? but i don't know how to measure that. and i can't easily inline partitions because it's recursive
16:29:20
alandipert
so i was thinking maybe a next step would be a tail recursive version of partitions
17:01:52
kenanb
if you are really worried about performance, maybe you should stick to loops. making it tail-recursive will make the stack happy, but it will not decrease your call overhead.
17:01:54
slyrus2
Is there a way to "trace" ASDF such that one can actually see what the calls to the compiler are?
17:04:06
pfdietz
You could trace COMPILE-FILE, or maybe there's some generic function you could write an around method for.
17:04:34
slyrus2
pfdietz: yeah, I tried that but I don't seem to get any output. I must be doing something wrong.
17:05:18
kenanb
AFAIK asdf already provided an interface to access generated list of all tasks for a certain load-op.
17:10:26
kenanb
slyrus2: asdf:traverse is the function. as I said, that is only for getting the generated task list
17:21:43
slyrus2
aha! the with-muffled-compiler-conditions form in uiop.lisp was stealing my trace output.
17:39:22
Bike
compile-file is a standard function, so tracing it is undefined behavior and might do weird dumb thing.s
17:40:08
slyrus2
Hmm.. interesting. In this case it works fine once I unmuffle the conditions down inside UIOP:compile-file*
18:16:13
random9899
the interactive failure thing was annoying, throwing you into the debugger and stuff....