freenode/#lisp - IRC Chatlog
Search
21:08:12
rpg
Then this should be the fastest way to get it loaded. I don't know if there's any way to optimize the memory layout (e.g., to keep the hash table in contiguous memory) before dumping. I'd definitely suggest creating the hash table with a known-big-enough :size argument -- that might improve the initial memory layout.
21:08:41
rpg
I wonder if you can somehow shove it into old memory, since you are never going to want it garbage-collected.
21:17:06
rpg
jmercouris: You don't want the garbage collector to bother looking at this table -- you know it's going to stay around. It might help make your program more efficient to find a way (this would definitely be SBCL-specific) to tell the lisp environment that this is permanent memory so it can be hidden from the garbage collector.
21:27:17
whartung
Yea, mmap. Store it “off heap”, GC never even knows it exists, but you get to handle all the access and marshalling of stuff — which is a pain.
21:28:31
whartung
(and then you think “why not store it in a db and let it cache it anyway, isn’t that what they’re for?”)
22:56:50
didi
Decisions, decisions... should I start using ENDP, instead of NULL, to test for the end of a list?
23:04:40
pjb
whartung: if you use mmap, you may use com.informatimago.common-lisp.heap.heap to store lisp objects in it.
23:07:14
didi
In another news, I recently discovered LOOP's keyword NCONC. It took me long enough. :-P
23:07:23
pjb
Now, it's not native lisp objects, so it may be a draw back, but it allows to share lisp objects (using shared memory) with other implementations, so it may be an advantage.
23:18:54
didi
And a nitpick: LOOP's keywords for hash-tables are confusing. Using [each, the, in, of] makes no difference, but I was trained that using [in, on] with list does.
23:36:58
White_Flame
ugh, yet another (vector (unsigned-byte 8)) vs (simple-array (unsigned-byte 8)) mismatch, this time with cl-sqlite
23:48:37
aeth
destructuring-bind takes a while to get used to, but it has replaced almost all of my old ways of parsing lists because usually there's *some* structure
23:49:45
aeth
And for iterating, I usually use do-destructuring-bind (dolist with destructuring-bind) or a higher order function with destructuring-lambda (lambda with one argument, on which a destructuring bind is applied)
23:50:03
aeth
destructuring-bind gets annoying with iteration unless you build trivial abstractions like that to flatten it
23:50:32
aeth
Alternatively, there are general macros to flatten stuff, but it's probably more intended for with-foo, let, multiple-value-bind, destructuring-bind, etc., stacking together, rather than being used in an iteration
23:56:40
aeth
definitely an option but it's very heavyweight compared to a handful of trivial macros on top of built-in forms
0:18:35
didi
By using `destructuring-bing', I feel I won't be able to freely change a data structure implementation. So, If I say (destructuring-bind (a . b) foo ...), `foo' is set to be a cons, with `a' as the `car' and `b' as the `cdr'.
0:19:27
aeth
If you use destructuring-bind, you can usually tell if something doesn't match what you expect pretty quickly. If you use cadr or whatever, you might never refactor it properly
0:19:48
mfiano
If it's built out of conses, it is trivial to parse with destructuring-bind. You argument holds better for arrays or hash tables.
0:21:11
aeth
If you're calling (cadr foo) and (caddr foo) through inline accessor functions you're probably going through the list twice (and certainly if they're not inline), and you could have nonsense at the end unless you do another check.
0:27:10
aeth
Sometimes you have no choice, though, like in macros (okay, you can probably use a reader macro to create structs at compile-time and use make-load-form-saving-slots to save the compile-time object so it's handled as a constant at runtime... but why?)
0:32:56
aeth
I find that either accessor functions or destructuring-bind (assuming it's not in a macro) is usually the first step to replacing it with a data structure, though
0:34:50
pjb
and if at any time you're worried about evolutivity of an implementation choice, you can always wrap it in a macro. Don't use destructuring-bind, use your own macro, that could expand to either that, or a with-accessors or a with-slots or something else.
0:38:41
aeth
pjb: I usually hide complicated things behind symbol-macrolet or with-accessors or something similar
0:40:34
pjb
didi: that is, it's better if you have to use it several times, or if it has to have an implementation that should be consistent with some other such macro or operator.
0:40:58
pjb
it is easier to ensure consistency in a mechanism, when it is implemented independently and separately from the rest of the code.
0:41:31
pjb
Also having such abstractions helps when you need to debug, since you can easily instrument those abstractions (add checks).
0:43:02
pjb
Yes. There are quick and easy checks that you can add when debugging and leave in production, but you can also add heavy checks (things that walk whole data structures, or perform complex computations to validate).
0:44:00
pjb
Note that I speak generally, here, not specifically for CL. I'm currently working on FreeRDP written in C, and it's horrible.
0:44:09
aeth
I created a typed cons cell out of structs that's about 30% slower than the built-in cons, but it saves having to walk the data structure to verify things (just check the type in O(1))
0:45:42
pjb
note that clisp can be compiled with a clisp compilation time option to add a slot to cons cells for your own usage.
0:47:10
aeth
Using structs is mostly portable because :type on a slot is usually at least somewhat respected. Full portability would require testing implementation behavior and wrapping the or check-type in places where it isn't respected on various implementations.
0:48:20
pjb
check-type must not be used indiscriminately. Sometimes you must rely on the intrinsic type checking.
2:00:54
nowhere_man
I'm starting to understand the concept of delimited continuations in the basic theory, but now I wonder: what are their typical uses?
2:10:09
White_Flame
delimited continuations are basically registering an lambda event handler from within a closure, for example
3:15:48
didi
krwq: I dislike doc generators, so I have no recommendation. But, I like this article: http://stevelosh.com/blog/2013/09/teach-dont-tell/
3:40:16
jasom
krwq: somewhat out-of-date, but: https://sites.google.com/site/sabraonthehill/lisp-document-generation-apps
5:12:16
drmeister
Does anyone have insight into how to implement the optimization where functions that call each other within a compilation unit call each other directly?
5:43:18
mfiano
pillton: I got your message. I actually get a warning when quickloading specialization-store now
5:50:20
beach
drmeister: Instead of going through the function name, you do a relative jump since the two functions are in the same code body.
5:51:19
beach
But, if you do that, you can no longer redefine the callee by hitting C-c C-c in SLIME.
5:55:33
beach
Also, functions can have more than one entry point. You don't need to check the number of arguments for such a call.
6:05:19
drmeister
We are stuck on a couple of fronts. Inlining is still broken and so we can't bring the new cst compiler online. That is very frustrating.