freenode/#lisp - IRC Chatlog
Search
6:17:00
pillton
LdBeth: You should be able to run the inspector which is bundled with your CLIM implementation.
6:56:08
beach
LdBeth: Climacs has M-: as I recall, bit since it's a CLIM application, you would be much better off to start the CLIM listener instead.
6:59:40
beach
Well, the first thing to do then is to get rid of the idea that everything goes through the editor.
7:00:23
beach
With CLIM/McCLIM, you have the listener, so that Climacs can be used only for editing and not for the other tasks.
7:00:58
beach
So there is the listener for REPL interaction, Clouseau for inspecting objects, a "debugger" for inspecting backtraces, etc.
7:01:24
beach
You can run them separately or from the listener, but it would be unusual to run them from Climacs.
7:17:23
beach
You can call drawing primitives directly, for instance, and see the result immediately.
9:29:15
beach
I need some advice. In SICL, a heap-allocated object is either a CONS cell or a GENERAL INSTANCE. A CONS cell is represented as two consecutive words. A general instance is represented as a two-word header where the first word points to the class and the second one to a RACK. The rack contains all other information like the slots of a standard object, the elements of an array, etc. etc.
9:29:21
beach
I was thinking of representing the rack pointer as an untagged value, but this is problematic for the garbage collector in that I would have to have information in each stack frame concerning what stack location and register contain rack pointers. Plus, after various optimization tricks, there might be raw pointers to an ELEMENT of a rack and not only to the beginning of it.
9:29:22
beach
However, I currently have one unused tag. I could use it for all rack pointers (to the beginning or to an element). This way of doing it would also make it possible to recognize whether a particular 2-word item is a CONS cell or a general instance because only general instances contain a rack pointer in the second word. Is this a good idea or am I missing something?
9:33:15
beach
This recent conundrum, by the way, shows the intimate relationship between data representation and the constraints on the garbage collector.
9:37:45
beach
Yes, that's a frequent operation. But I think all RISC processor that don't have an offset in the instruction optimize this case.
9:37:55
flip214
my first reaction is "that is so low-level optimization that a special case in the compiler or a bit of assembly might fix that"
9:38:18
flip214
but I'm not that proficient about RISC -- not even sure whether eg. ARM would fall into that category
9:39:10
beach
Well, it is not "fixable". What I could do is to make sure all rack pointers have to be recomputed after a function call.
9:39:19
flip214
I guess that main memory access has such a big penalty already (on cold caches at least) that the one ADD wouldn't be a problem
9:39:48
beach
flip214: Yes, exactly. The addition would be a very fast operation compared to the memory access.
9:40:20
beach
And I presume such RISC machines are superscalar, so that they can do the addition in parallel with other stuff.
9:40:23
flip214
a stack frame _can_ contain rack pointers - as long as there's a visible reference to the _base_ of the rack too. then the other pointers could just be hidden
9:41:01
flip214
ie. as long as a _visible_ reference to the rack is on the stack, you can have any number of (GC-) _invisible_ pointers to the same rack as well
9:41:32
flip214
that would mean you have a bit more stack usage, but no register addressing or GC issues
9:42:10
flip214
well, how many racks will a tight loop access simultaneously? at most 3 or 4, else it wouldn't be a tight loop anymore, right?
9:43:29
flip214
well, the compiler needs to have a few local variables (or make them thread-local?!), where references to things addressed opaquely by registers are referenced
9:44:05
flip214
so you'd only need a few pointers in the TLA, and a store to them every now and then
9:44:51
flip214
for the easiest (and perhaps worst) case, have one pointer in the TLA for each addressing register
9:45:12
flip214
when a rack address is loaded into the register, emit a store of the rack base address to the corresponding TLA pointer
9:46:20
flip214
first of all, they'd only be _concurrently_ read on the start of a GC (fetch all roots), and never concurrently _written_ by another thread.
9:48:06
beach
You said "the compiler needs to have a few local variables... where references to things addressed opaquely by registers are referenced".
9:49:05
beach
Can I assume that you mean that those variables are not used during compilation, but that are needed so that the compiler can emit code using them?
9:50:50
beach
flip214: Sorry about all this. It's an occupational hazard. I was trained as an engineer and a scientist and I must understand every word.
9:52:14
beach
This happens to me so often that I wonder why I seem to be one of the few people who can't understand quick exchanges like this.
9:53:30
flip214
beach: the problem might as well be me, as I don't have formal training and so might have differences in my vocabulary.
11:14:32
jackdaniel
if you press `v` on the frame (given you use sldb) it should open a buffer with the source location in question
11:16:17
loke
I sometimes get expresment positively surprised when it comes to SBCL's ability to find the correct source line... Sometimes I get very disappointed too.
11:51:14
jackdaniel
loke: amusingly enough, in this lecture the speaker mentions how vovels and slips of a tongue are related to subconcious clash of words you could use: https://www.youtube.com/watch?v=n8m7lFQ3njk
11:59:46
dim
it doesn't mean extremely thou, like “actuellement” in French means “currently” in English, and other traps like that ;-)
12:24:00
beach
jackdaniel: I will definitely watch it at some point. I have read a few books by Douglas Hofstadter and I like his writing very much.
12:36:32
beach
Different question, but related to my previous one: Suppose I want to implement the SICL garbage collector in Common Lisp. Such a thing must obviously be able to handle arbitrary addresses and arbitrary machine data, let's say in the form of unsigned 64-bit integers. I can see two ways to do it.
12:36:40
beach
Way number 1 is to pretend that memory is a Common Lisp array with element type (unsigned-byte 64). Way number 2 is to provide two functions for accessing memory like MEMORY and (SETF MEMORY).
12:36:46
beach
Way number 1 has the inconvenience that any element of the array that represents an address would have to be shifted right by 8 positions before it can be used as an index. But then, the compiler would generate code to shift it left again to get an address. I would then have to make sure that the compiler is able to cancel the two.
12:36:53
beach
For way number 2, the two functions must be declared to use arguments and values of type (unsigned-byte 64), they would have to be written in machine code (easy), but they still would need to be inlined, so that the compiler does not have to emit code to tag and untag them or (worse) convert them to bignums and back.
12:40:25
heisig
beach: I have a better feeling about way number 2. The raw memory is semantically a different thing than a Lisp vector, and blurring this distinction might lead to confusion.
12:41:42
beach
heisig: I see, yes. The other thing with 2 is that one could add functions for accessing individual bytes if required.
12:45:49
flip214
and I guess that at some point you might need byte-addressing too - which would go against point 1
12:45:58
beach
Other than the potential problems I listed, can anyone think of other ways in which I could get into trouble, i.e., what would I have to make sure I can convince the compiler to do?
12:47:13
flip214
so a 64-bit-word "memory layout" means that even addresses as tagged integers go into a single register... that sounds like #1 would be much easier.
12:47:58
flip214
and for byte-addressing needs you might have a second "special" array -- which would be used very infrequently, so a few bignum operations won't matter.
12:48:26
flip214
(which are very unlikely, as the top half of 64bit memory is reserved for the kernel anyway (typically), so userspace wouldn't have such adresses)
12:48:59
flip214
the two functions sound much more better from an abstraction level... but does that really matter for such a low-level use?
12:50:05
flip214
will that have to deal with addresses of #x8000...000 and higher, or only smaller ones?
12:50:47
flip214
well, (AREF *MAIN-MEMORY* address) vs. (MEMORY address) sounds like a trivial difference
12:51:14
flip214
so I'd say go with the second, and if you find out you want the first make (DEFMACRO MEMORY (a) `(AREF *MAIN-MEMORY ,a))
12:55:54
froggey
I use option 2 in mezzano, with accessors for different element types. memref-t, memref-(un)signed-byte-{8,16,32,64}
13:01:21
flip214
beach: > Sometimes a majority simply means that all the fools are on the same side.
13:01:52
flip214
https://www.just-one-liners.com/whenever-you-find-yourself-on-the-side-of-the-majority-it-is-time-to-pause-and-reflect/
13:05:19
jackdaniel
it might be, that finding yourself on the side of minority is also a good time to pause and reflect
13:06:54
jackdaniel
I mean – strong convictions are suspicious whenever found in a majority crowd or in a minority group
13:09:05
beach
http://www.prosebeforehos.com/quote-of-the-day/12/28/bertrand-russell-quote-fools-fanatics-wise-men/
13:13:42
beach
flip214: Anyway, the more I think about tagged rack pointers, the more goodness I see.
14:12:07
Xach
shka: ql-progress! but it is not really a library, but part of quicklisp. you could rip it out though.
14:23:46
beach
flip214: I changed the SICL specification so that racks are tagged, using a single commit so that it can be easily undone if necessary. Let me know if you see any problems with it.
14:25:08
Xach
shka: thanks. i wrote a HTTP client that predated curl and wget, and put up a semi-joking comparison table when the others came around, and one of my plus features was "cool progress bar". but then curl and wget got really cool progress bars, too.
16:35:49
jmercouris
what I'm doing now is typing in "sbcl" and then within the repl typing the command to compile
16:37:20
jmercouris
well, I guess it works the way someone would imagine, I should have tried it before posting here
17:06:07
kenster
Hey, for anyone interested, I am streaming some Common Lisp/C++17 programming: https://youtu.be/-JWVx-W0rmA or https://www.twitch.tv/kingherring
17:39:51
kenster
does anyone know how I can associate the class with the struct value in that hash table
17:45:15
pjb
But the point is probably that "I want to pass in the upload-session class symbol and get 'upload-session" is not what you want.
17:47:46
pjb
Now, you need the *c-class-structs* table set up at macroexpansion time, in the compilation environment. The simpliest to fill it is to define a macro that expands to an eval-when setf gethash.
17:52:51
pjb
yeah, C compiler don't provide controled environments, which means that you must absolutely not have any crash. (sigsegv, or other).
18:01:05
pjb
A friend of mine is working on something similar: http://peerstorage.org https://www.linkedin.com/company/peerstorage/
18:04:14
Demosthenex
anyone seen a lib that helps make TUI apps for cl? yes, ncurses exists, but the forms portion never seems to be included in the libs. widgets/forms aren't the same as screenhandling.