jackdaniel changed the topic of #commonlisp to: Common Lisp, the #1=(programmable . #1#) programming language | Wiki: <https://www.cliki.net> | IRC Logs: <https://irclog.tymoon.eu/libera/%23commonlisp> | Cookbook: <https://lispcookbook.github.io/cl-cookbook> | Pastebin: <https://plaster.tymoon.eu/>
azimut has quit [Read error: Connection reset by peer]
cosimone` has joined #commonlisp
ebrasca has quit [Remote host closed the connection]
cosimone has quit [Ping timeout: 250 seconds]
azimut has joined #commonlisp
cosimone` has quit [Remote host closed the connection]
random-nick has quit [Ping timeout: 250 seconds]
cosimone has joined #commonlisp
jmdaemon has quit [Quit: ZNC 1.8.2 - https://znc.in]
son0p has joined #commonlisp
jolby has quit [Quit: Client closed]
jolby has joined #commonlisp
taiju` has joined #commonlisp
taiju` is now known as taiju
mmk2410 has quit [Quit: ZNC - https://znc.in]
mmk2410 has joined #commonlisp
kuao has quit [Quit: Connection closed for inactivity]
waleee has quit [Ping timeout: 268 seconds]
jmdaemon has joined #commonlisp
notzmv has quit [Ping timeout: 248 seconds]
jolby has quit [Ping timeout: 252 seconds]
eddof13 has joined #commonlisp
eddof13 has quit [Client Quit]
cosimone has quit [Quit: ERC 5.4 (IRC client for GNU Emacs 28.1)]
jolby has joined #commonlisp
jolby has quit [Quit: Client closed]
snits has joined #commonlisp
taiju has quit [Remote host closed the connection]
nij- has joined #commonlisp
<nij-> What magic does sbcl use to allow dumping core? That's perfect for making CL a scripting lang. And when I look for similar things for python, it doesn't seem python can do that natively (without the help of gdb).
<beach> lagash: Which paper?
<beach> nij-: Did you see my saying that you should use (let ((result '()))...). It even says so in the standard.
taiju` has joined #commonlisp
taiju` is now known as taiju
<beach> clhs 1.4.1.4.4
<beach> nij-: ^
<aeth> apparently specbot thinks that beach is NIL
<aeth> oh, no, it's just NIL-the-page
jolby has joined #commonlisp
<aeth> confusing message
<beach> nij-: Dumping core doesn't require anything particularly sophisticated. You just need to write the heap out into a file in such a way that it can be mmapped or read back in.
<nij-> hmmm so beach suggests using '() instead..
<beach> No, it is not my suggestion. It is what it says on that dictionary entry.
<nij-> (let ((result '(1 2 3))) (setf (car result) 4) ;; does this look alright for you, beach ?
<nij-> hmm
<beach> No, but '(1 2 3) is not '().
<beach> And (setf car) is not push.
<aeth> nij-: If it's a literal like '(1 2 3), then PUSH is safe, but (setf car) and (setf cdr) are not.
<mathrick> nij-: do NOT do that. You're modifying a literal object, which is undefined behaviour and will do very weird things in most implementations
<beach> mathrick: I think nij- knows that, and probably wanted me to say that it's OK, because it's the same case as '() and push.
<mathrick> oh, I see
<nij-> I think I'm still confused with when I'm modifying a literal object and when I"m not.
<beach> Yes, you are right.
<nij-> I know modifying literal objects is not good. But don't know when
<beach> Exactly.
<beach> nij-: Perhaps you think it is risky to use '() because you might mutate it. But neither PUSH nor (SETF CAR) can mutate NIL.
<aeth> nij-: it's because lists are weird because they're not "real"
<beach> You could UNINERN it, but not in conforming code.
<nij-> What would be an example to mutate '()?
<mfiano> You cannot
<beach> YOU CAN'T MUTATE IT.
<aeth> vector-push-extend actually extends the vector when you reach the internal size limit of it; by contrast, push doesn't extend the "list" because there is no list to extend, only (deftype list () `(or null cons))
<nij-> aeth they aren't real @@?
<nij-> oh you means lists are not of primitive type?
<mfiano> PUSH just constructs a new cons and attached it. The '() is still there unmodified.
<aeth> iirc (push 42 foo) is just (setf foo (cons 42 foo))
<aeth> the old foo is still there
<aeth> for the first one, (cons 42 '())
<beach> nij-: What aeth is trying to say is that there is no abstract data type LIST in Common Lisp. It is all CONS cells.
<nij-> (let ((result '())) (setf result 1)) ; this is ok?
<mfiano> Yes
<beach> nij-: Yes, that modifies the variable RESULT.
<beach> Er, its value, I mean.
<nij-> OK. I see.
<aeth> nij-: if you're familiar with a low-level language like C, it's very similar to pointers, except CL doesn't have pointers (* OK, there's CFFI, but let's ignore that for now), it has CONSes.
<nij-> And because '() is meant to use to denote an empty list, while NIL is meant to use to denote a boolean
<nij-> even they are mixed used in the community, it's still recommended to use the former?
<beach> Yes, a Boolean, or a default value.
<beach> nij-: Did you read the Common Lisp HyperSpec page?
<nij-> yes
<beach> nij-: The standard was written by highly experienced, very smart, and very knowledgeable people. I would trust them over most people who hang out here on IRC.
<aeth> '(1 2 3) is '(1 . (2 . (3 . ()))) is [1|-]->[2|-]->[3|/]
<aeth> PUSH is adding another CONS in front
<aeth> (technically, if you wanted to diagram better, the first part of the CONS cell should also be an arrow, pointing to 1, 2, 3, etc. Doesn't make a difference when they're immutable like here. Not IRC friendly, though.)
<nij-> Yeah I'm aware of how list is built.
<nij-> I got it now :D Thanks!
<aeth> if you were to build this (in reverse order, remember! 3 then 2 then 1), you start with this: result -> /; then after the first push you get result -> [3|/]; then you get result -> [2|-]->[3|/] etc
<beach> nij-: If LIST were an abstract data type in Common Lisp, then the following would return True: (let* ((x '()) (y x)) (push 234 x) (eq x y))
<beach> nij-: If you replace the list by an empty vector with fill pointer and use VECTOR-PUSH-EXTEND, you get True, so VECTOR *is* an abstract data type.
<beach> nij-: The minimum requirement for a type to be an abstract data type in an imperative language is that operations on its instances preserve identity.
<mathrick> beach: hmm, so number is not an abstract type?
<mathrick> abstract data type even
<aeth> did any Lisp machine use CONSes *as* pointers, btw? (cons tag pointer) ; should work for a lispm C, shouldn't it?
<beach> mathrick: Well, that's hard to say since there are no mutating operations on numbers.
<aeth> (although I guess pointer arithmetic would have to work on the lispm cons somehow)
<mathrick> aeth: LispMs had locatives
<mathrick> I think they were their own thing?
<mathrick> beach: so we're not counting INCF?
<nij-> lists are not abstract data type.. so what are they?
<nij-> something something data type?
<beach> mathrick: Correct, INCF does not mutate the number. Luckily!
notzmv has joined #commonlisp
<beach> mathrick: In early versions of FORTRAN, you could mutate numbers, but that was widely considered an implementation defect.
<mathrick> beach: but it doesn't mutate it in exactly the same way PUSH doesn't mutate the list :)
<mathrick> oh huh, that's freaky
<beach> *sigh*
<beach> Like I said, LIST is not an abstract data type in Common Lisp, so PUSH does not mutate the list. But if it were, then PUSH would add an element to the beginning of the lists while preserving identity.
tyson2 has quit [Remote host closed the connection]
<beach> nij-: Just a bunch of CONSes and some atoms. CONS is a (somewhat) abstract data type, with operations CAR, CDR, (SETF CAR), and (SETF CDR).
<mathrick> right. Which is the exact same deal with INCF. I'm not trying to argue anything here, just trying to make sure I get the intent behind your definition of an ADT in an imperative language
<aeth> (setf 0 1)
<beach> mathrick: (INCF <x>) is [as you know] sort of like (SETF <x> (1+ <x>)) just like (PUSH <y> <x>) is sort of like (SETF <x> (CONS <y> <x>)). If LIST were an abstract data type with PUSH as a mutating operation, then PUSH would not be defined that way.
<jcowan> If CONS is abstract, so is INTEGER.
<beach> mathrick: If INCF were an operation that could mutate a number, it would not be defined that way.
<beach> OK, I need to stop now.
<aeth> jcowan: the important thing is that integers are immutable. They could be complicated, who knows how bignums are done (fixnums are very simple, though)
<beach> I can see where this is going.
<jcowan> That's more than I do.
<jcowan> In any case, I'm going to bed in 3 minutes.
<beach> Of course.
<beach> nij-: I hope you got a bit wiser with this information.
<mathrick> I guess the real difference between PUSH and INCF is that CONS is actually mutable, whereas no number is
<beach> PUSH doesn't mutate any CONS cell.
<aeth> but PUSH doesn't mutate the CONS
<nij-> thanks beach
<mathrick> perhaps Scheme was right to make its conses immutable :)
<aeth> (except for the new CONS, the CDR)
<aeth> mathrick: that's Racket, not Scheme
<beach> aeth: That's not mutation. That's initialization.
<mathrick> I thought R6RS dud?
<mathrick> *did
<Bike> r6rs has set-car! and set-cdr! in a library (mutable-pairs), it seems.
<mathrick> beach, aeth: I know PUSH doesn't, but if CONS was by definition immutable, then PUSH would be exactly like INCF, and we could also say it's not clear whether LIST is an abstract data type, just as it's not clear for numbers
<beach> mathrick: That would be very surprising.
azimut has quit [Ping timeout: 258 seconds]
<mathrick> so it seems the answer is "they're immutable unless your program imports mutable-pairs"
<beach> mathrick: Wikipedia considers numbers to be abstract data types. And that's fine. But what important here is the case where lists in Common Lisp can be mutated, but you can't add an element to the beginning of a list (and in particular to the empty list) while preserving identity.
Jach has quit [Ping timeout: 255 seconds]
Jach has joined #commonlisp
<beach> mathrick: So if you eliminate EQ, (SETF CAR), etc., and you consider Common Lisp to be a purely functional language, then yes, you can consider LIST to be an abstract data type, just like numbers are.
<beach> But what I told nij- had to do with imperative languages and objects that can be mutated.
<mathrick> beach: I assume by "eliminate EQ" you mean "(eq-or-whatever-we-choose-instead (cons 1 2) (cons 1 2)) should hold"?
<beach> Yes.
<beach> But identity is a fundamental concept in imperative languages. It has to be the case that in (let* ((x <mumble>) (y x)) (mutate x) y) the mutation is visible in y.
<mathrick> ahh, I see, I finally got why your definition was the way it was. That makes sense
<beach> Whew!
<mathrick> I was really trying to get that this entire time, maybe I should've asked directly
<beach> What would the question have been?
<mathrick> "why is preserving identity the definition of being an abstract data type?"
<beach> I see.
<mathrick> we would probably have got here sooner if I did that
<beach> Possibly. It doesn't matter.
<beach> And it's preserving identity for mutating operations. Since numbers don't have any mutating operations, numbers are not covered by this restriction.
<mathrick> right
<mathrick> do purely functional languages tend to have the concept of identity?
<beach> No.
<beach> They can't, since every operation will conceptually create a new object.
<mathrick> that's a good point
<Bike> eq/eql make the semantics tricky even without mutations. (eql (cons 1 2) (cons 1 2)) is false, so the two conses are not equal in a philosophical indiscernability-of-identicals sense, even though there's no actual difference between them according to anything but eq/eql.
<Bike> so no, not a lot of identity in pure function land
<beach> Indeed.
<Bike> oops, i got it backwards. identity of indiscernibles.
<beach> We knew what you meant.
<mathrick> although identity of indiscernibles can have practical applications, if you need a sentinel value that's guaranteed not to be returned by any operation
* mathrick has written a fair share of not_found = object() in python
<Bike> sure, and that's why i'm writing common lisp and not idris.
prokhor has quit [Ping timeout: 252 seconds]
igemnace has joined #commonlisp
mfiano has quit [Ping timeout: 244 seconds]
pieguy128_ has joined #commonlisp
pieguy128 has quit [Ping timeout: 268 seconds]
nij- has quit [Ping timeout: 268 seconds]
mfiano has joined #commonlisp
rgherdt has joined #commonlisp
prokhor has joined #commonlisp
aartaka has joined #commonlisp
jmdaemon has quit [Quit: ZNC 1.8.2 - https://znc.in]
Cymew has joined #commonlisp
_cymew_ has joined #commonlisp
Duuqnd has joined #commonlisp
causal has quit [Quit: WeeChat 3.6]
anticomputer has quit [Remote host closed the connection]
anticomputer has joined #commonlisp
pve has joined #commonlisp
Oladon has quit [Quit: Leaving.]
shka has joined #commonlisp
<jackdaniel> can't this eq return T though? cons arguments are constants here
beach` has joined #commonlisp
beach has quit [Killed (NickServ (GHOST command used by beach`!~user@2a01:cb19:150:3400:dcd6:f06c:8ab:dc7c))]
beach` is now known as beach
frgo has quit [Ping timeout: 260 seconds]
Brucio-61 has quit [Ping timeout: 248 seconds]
scymtym has quit [Ping timeout: 248 seconds]
razetime has joined #commonlisp
Duuqnd has quit [Ping timeout: 252 seconds]
chimp_ has quit [Ping timeout: 252 seconds]
Duuqnd has joined #commonlisp
aartaka has quit [Ping timeout: 264 seconds]
cosimone has joined #commonlisp
Krystof has joined #commonlisp
Brucio-61 has joined #commonlisp
scymtym has joined #commonlisp
razetime has quit [Ping timeout: 268 seconds]
ttree has quit [Ping timeout: 264 seconds]
aartaka has joined #commonlisp
razetime has joined #commonlisp
bitspook[m] has quit [Quit: Bridge terminating on SIGTERM]
loke[m] has quit [Quit: Bridge terminating on SIGTERM]
acma has quit [Quit: Bridge terminating on SIGTERM]
sp has quit [Quit: Bridge terminating on SIGTERM]
Helmholtz has quit [Quit: Bridge terminating on SIGTERM]
char[m] has quit [Quit: Bridge terminating on SIGTERM]
Gnuxie has quit [Quit: Bridge terminating on SIGTERM]
ecocode[m] has quit [Quit: Bridge terminating on SIGTERM]
kakuhen has quit [Quit: Bridge terminating on SIGTERM]
jryans has quit [Quit: Bridge terminating on SIGTERM]
torhex-pasmul[m4 has quit [Quit: Bridge terminating on SIGTERM]
drdrjacobs[m] has quit [Quit: Bridge terminating on SIGTERM]
Mrtn[m] has quit [Quit: Bridge terminating on SIGTERM]
yitzi has quit [Quit: Bridge terminating on SIGTERM]
aartaka has quit [Ping timeout: 268 seconds]
ebrasca has joined #commonlisp
Mrtn[m] has joined #commonlisp
aartaka has joined #commonlisp
pjb has joined #commonlisp
Duuqnd is now known as Duuqnd_
skeemer has joined #commonlisp
rgherdt_ has joined #commonlisp
sander has quit [Ping timeout: 268 seconds]
rgherdt has quit [Ping timeout: 268 seconds]
scymtym has quit [Remote host closed the connection]
Brucio-61 has quit [Read error: Connection reset by peer]
m5zs7k has quit [Ping timeout: 248 seconds]
Duuqnd_ has quit [Quit: Client closed]
m5zs7k has joined #commonlisp
<jcowan> There is a limited amount of coalescence that can be done, yes. when forms are processed by COMPILE-FILE that does not apply to COMPILE or EVAL. The three aren't quite consistent.
Gnuxie has joined #commonlisp
yitzi has joined #commonlisp
sp has joined #commonlisp
Duuqnd has joined #commonlisp
kakuhen has joined #commonlisp
bitblit has joined #commonlisp
ecocode[m] has joined #commonlisp
char[m] has joined #commonlisp
dieggsy has joined #commonlisp
bitspook[m] has joined #commonlisp
hayley has joined #commonlisp
torhex-pasmul[m] has joined #commonlisp
iceman[m] has joined #commonlisp
jryans has joined #commonlisp
AadVersteden[m] has joined #commonlisp
loke[m] has joined #commonlisp
acma has joined #commonlisp
Helmholtz has joined #commonlisp
infra_red[m] has joined #commonlisp
drdrjacobs[m] has joined #commonlisp
scymtym has joined #commonlisp
dieggsy has quit [Quit: You have been kicked for being idle]
bitblit has quit [Quit: You have been kicked for being idle]
ebrasca has quit [Remote host closed the connection]
karlosz has joined #commonlisp
makomo has quit [Quit: WeeChat 3.5]
cosimone has quit [Remote host closed the connection]
cosimone has joined #commonlisp
cosimone has quit [Remote host closed the connection]
pjb has quit [Ping timeout: 268 seconds]
cosimone has joined #commonlisp
taiju has quit [Ping timeout: 264 seconds]
Brucio-61 has joined #commonlisp
karlosz has quit [Read error: Connection reset by peer]
karlosz has joined #commonlisp
Psybur has joined #commonlisp
random-nick has joined #commonlisp
<neominimum> Is it possible to define a method combinator that will acquire a lock before calling the the applicable methods? In this case I am hoping that the lock can be accessed through the first argument provided when the method is called. Is there a way to access the provided arguments?
jeosol has quit [Quit: Client closed]
<jackdaniel> neominimum: can't you define an around method for that?
<jackdaniel> i.e (defmethod foobar :around ((x secure-qux) y z) (with-qux-locked (x) (call-next-method)))
<jcowan> Around methods can do anything: you can put a wrapper around + to make do multiplication when the wind is in the West.
karlosz has quit [Read error: Connection reset by peer]
karlosz has joined #commonlisp
<jcowan> (well, almost)
<neominimum> Sure, although I may have many methods to define, which means I'll need to write an :around method for each one. I could write a macro to create the pair I guess, but ideally I would like to get away with the least amount of extra syntax.
<jackdaniel> you may subclass standard-generic-function and specialize compute-discriminating-function (eventually compute-applicable-methods-{using-}) to inject your method
jolby has quit [Quit: Client closed]
<neominimum> jackdaniel: cheers :D
azimut has joined #commonlisp
pillton has quit [Quit: ERC 5.4 (IRC client for GNU Emacs 28.1)]
tyson2 has joined #commonlisp
chipxxx has joined #commonlisp
Nilby has joined #commonlisp
dec0d3r has joined #commonlisp
dec0d3r has quit [Quit: Leaving]
perrierjouet has quit [Quit: WeeChat 3.6]
<jcowan> The idea is to add just enough syntax to remove the need for vast arrays of boilerplate. This is why it is said that there is only one design pattern in CL: "Use the language."
<jcowan> neominimum: ^^
taiju` has joined #commonlisp
taiju` is now known as taiju
tasty has quit [Quit: byebye]
thuna` has joined #commonlisp
tasty has joined #commonlisp
tasty has quit [Changing host]
tasty has joined #commonlisp
jolby has joined #commonlisp
chipxxx has quit [Remote host closed the connection]
chipxxx has joined #commonlisp
taiju has quit [Quit: rcirc on GNU Emacs 28.1]
lispm has joined #commonlisp
lispm has joined #commonlisp
lispm has quit [Changing host]
<Shinmera> :around has an issue in that the most specific around method goes first. Meaning you cannot generically provide the lock around client code's around methods, as they would fire before your generic method.
<Bike> one of the examples on clhs define-method-combination is actually exactly doing this, grabbing a lock around the methods
lispm has quit [Client Quit]
OlCe has quit [Remote host closed the connection]
szkl has quit [Quit: Connection closed for inactivity]
nij- has joined #commonlisp
perrierjouet has joined #commonlisp
tyson2 has quit [Remote host closed the connection]
attila_lendvai has joined #commonlisp
chipxxx has quit [Read error: Connection reset by peer]
<nij-> I just learned from #python that it's a tricky issue to replicate what we have for SBCL: to preload libs, dump core, and expect a fast start up anytime in the future.
<nij-> So.. what's the magic SBCL did :D? Is it due to the very nature of lisp?
rgherdt_ is now known as rgherdt
<hayley> Yes, John McCarthy waved his wand, and all the cons cells were imbued with magic dust, allowing them to be dumped nicely onto disk.
<nij-> Hmm.. I thought "being able to freeze at a certain state" must be a feature all modern langs have. But it doesn't seem to be the case!
eddof13 has joined #commonlisp
<hayley> To be pedantic Common Lisp does not specify image dumping. But it is still a strange omission in the programming world, yes.
<nij-> But does the nature of lisp makes it more easily dumpable?
<beach> No.
<hayley> Most languages are not interactive, or don't exploit it as much as Common Lisp does. Even, say, Python won't put you in a debugger without unwinding the stack, when an error is raised (if I remember Python words).
<hayley> It's probably harder, compared to, say, a language with only immutable data, or with fewer pointers (aeth can probably say something on ECS and OO and all that game programmer nonsense).
<hayley> In either case, dumping state doesn't require as much effort with pointers; either there are none, or there is no need for object identity to be preserved. But arguably those points are all theoretical - SBCL just copies memory word-by-word to core.
<nij-> beach I'd appreciate if you elaborate :) I was pretty confused what CL did right here to make it more interactive than most other langs (if not all).
tyson2 has joined #commonlisp
razetime has quit [Ping timeout: 265 seconds]
razetime_ has joined #commonlisp
<beach> nij-: I am not sure how to elaborate on something not being special.
thuna` has quit [Ping timeout: 264 seconds]
<beach> The main tricky part for any such dumping these days seems to be that some operating systems no longer guarantee the address that your code and data will be loaded into.
<beach> I am not sure what C does these days with data structures defined at compile time. Does it have to let the linker fix up all the references?
eddof13 has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
<hayley> There is heap relocation code in SBCL which can fix pointers in the heap, and thus put the heap at any location in memory.
<beach> I think I heard about that. It's pretty much equivalent to a full GC as I recall.
<nij-> beach huh. On those OS, even sbcl cannot fully dump core normally?
<hayley> Not from what I recall; it "just" walks the heap and adjusts pointers. But I didn't pay too much attention while fixing it to work with my new heap layout.
<jcowan> Pretty much any program with a C core makes image dumping difficult. I bet if SBCL had to be ported to a non-Posix, non-Windows OS today, it would be quite some time before image dumping worked.
<Nilby> Dumping state is only easy if there's nothing external, which is almost never the case. Even totally self contained programs, the hard things are handled by the O/S, which doesn't even always get it right.
<hayley> SBCL can dump core fine; it's loading it back in that gets you. And the latter is totally possible too.
<beach> nij-: It used to be the case that you could put absolute addresses of data in your executable, but nowadays, supposedly for safety reasons, the OS won't honor the address you say you want to load your data ino.
<nij-> beach Got it. Did sbcl work around that? Or its dumping functionality would also fail in those OSes?
<hayley> And, yes, the state of the C runtime is not dumped in that core; there is just enough in the core for the runtime to rebuild that state.
<jcowan> Emacs has image dumping, and the last I heard it depended on a hack in glibc put in just for that purpose.
<beach> nij-: As hayley says, it fixes up those addresses before starting.
<nij-> Wow, hayley really? Since which version? Doesn't that increase the startup time by a lot?
<jcowan> It shouldn't unless the image is huge (many GB), at a guess.
<jdz> GC also "fixes pointers" when data is moved.
<jcowan> The truth is that "files are the 1SOT" won; it's even true in Interlisp, which depends on image dumping a lot more than any CL
<jcowan> about the only holdout I know of is Squeak.
eddof13 has joined #commonlisp
<beach> nij-: It has to add some fixed amount to all pointers, so it has to scan every object in the heap. But that's still much better than (say) C++ which must re-create all data structures at startup time.
<jcowan> (there are bits in the Squeak image that were set before 1980 and aren't represented by any Smalltalk expression in the log.)
<nij-> got it, got it :D
<hayley> @[nij-]: I don't know, it's not a feature I've needed to use :)
Sose has joined #commonlisp
<jcowan> okay, sorry, geeksplaining is a fault of mine
<hayley> Though dumping the core involves some finessing, to GC absolutely everything. I managed to break SAVE-LISP-AND-DIE, but I didn't find out until I ran the SBCL test suite, as I hardly use that function!
<Nilby> I think they got rid of unexec like stuff from glibc. I'd rather they kept it and put it in posix or something. This issue is why smalltalk is so self contained, and why so many things can only work in a VM container now.
morganw has joined #commonlisp
<nij-> hayley cool
<beach> nij-: The rest is just a matter of creating a file that can be mmapped when the system starts up.
<nij-> So my conclusion so far is that dumping core isn't lang specific. It has nothing to do with the nature of lisp. But the lisp community wants that kind of thing, so some implementations (e.g. sbcl) implemented it, even on OSes that are unfriendly to this liking.
<beach> Sounds right.
<beach> For some reason, C++ people prefer extremely long startup times.
<nij-> Great! Thank you all :) Gotta leave for a while.
<nij-> It's clearer that CL is an amazing scripting lang.
<nij-> Given that it is harder to preload libs in other langs :)
<beach> I don't know what SBCL does, but I suspect they put the C libraries they need in the executable, and not in the core file that is then mmapped.
<jcowan> No doubt.
<beach> So the SBCL executable remains the same.
<beach> But I am only guessing. That's probably what I would have done in their place.
<jcowan> I note a historical connection between image dumping and bytecode machines (Smalltalk, Interlisp, Emacs)
<jcowan> This isolates the executable pretty well; indeed, the executable has been replaced multiple times in the history of Interlisp without requiring the images to be remade.
<jcowan> Indeed, until quite recently the capability of making an image from scratch had been lost.
<prokhor> question: i would like to make a hash-table consisting of list.
<hayley> beach: Right.
<prokhor> how would i push a new value onto that list?
<prokhor> how to initialize?
<prokhor> i always get this error: Error: Illegal car (PUSHNEW ENTRY-NAME (GETHASH TABLE-NAME *INVENTORIES*)) in compound form ((PUSHNEW ENTRY-NAME (GETHASH TABLE-NAME *INVENTORIES*))).
<prokhor> 1 (continue) Evaluate (PUSHNEW ENTRY-NAME (GETHASH TABLE-NAME *INVENTORIES*)) and ignore the rest.
<prokhor> 2 (abort) Return to top loop level 0.
<beach> prokhor: "consisting of", you mean the values in the table are lists?
<Bike> consisting of a list? what?
<beach> Heh.
<prokhor> beach: exactly
<Bike> it's a table. it consists of keys and values.
<hayley> You have one too many layers of parens.
<Bike> you're going to need to elaborate.
<prokhor> i would like to make sth like a who-calls table
<hayley> (push blah (gethash key table '())) is what I would write.
<prokhor> (setf myref (list '(a d g h))) ?
nij- has quit [Ping timeout: 252 seconds]
<hayley> Your first attempt was almost correct; just remove the outer layer of parens.
* hayley should know better than to talk about SBCL esoterica at 1am, off to bed
frgo has joined #commonlisp
frgo has quit [Remote host closed the connection]
<NotThatRPG> prokhor hayley : Don't both SLIME and SLY already offer the equivalent of who-calls with edit-callers?
frgo has joined #commonlisp
<beach> prokhor: What hayley said. You seem to have wrapped your form in additional layer of parentheses.
eddof13 has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
<beach> prokhor: Are you still here?
jolby has quit [Quit: Client closed]
Colere has quit [Ping timeout: 268 seconds]
eddof13 has joined #commonlisp
tyson2 has quit [Remote host closed the connection]
Sose has quit [Remote host closed the connection]
nij- has joined #commonlisp
Colere has joined #commonlisp
jolby has joined #commonlisp
Furor has joined #commonlisp
Colere has quit [Ping timeout: 264 seconds]
orestarod has joined #commonlisp
mathrick has quit [Ping timeout: 252 seconds]
NotThatRPG has quit [Ping timeout: 252 seconds]
mathrick has joined #commonlisp
OlCe has joined #commonlisp
Catie has joined #commonlisp
cage has joined #commonlisp
tyson2 has joined #commonlisp
Oladon has joined #commonlisp
jolby has quit [Quit: Client closed]
puchacz has joined #commonlisp
orestarod has quit [Ping timeout: 268 seconds]
jolby has joined #commonlisp
NotThatRPG has joined #commonlisp
prokhor_ has joined #commonlisp
aartaka has quit [Ping timeout: 264 seconds]
cage has quit [Remote host closed the connection]
aartaka has joined #commonlisp
nij- has quit [Ping timeout: 264 seconds]
attila_lendvai has quit [Ping timeout: 250 seconds]
azimut has quit [Remote host closed the connection]
azimut has joined #commonlisp
Dynom_ has joined #commonlisp
Dynom_ is now known as Guest8581
jmdaemon has joined #commonlisp
ttree has joined #commonlisp
razetime_ has quit [Remote host closed the connection]
jeosol has joined #commonlisp
tane has joined #commonlisp
tane has quit [Changing host]
tane has joined #commonlisp
tyson2 has quit [Remote host closed the connection]
<aeth> hayley: Dumping the state of an ECS just means that you write the arrays so you can just read back in those arrays later. If everything's in those arrays, it's simple. The key being that these are arrays of components so they should be flat or close to flat, rather than arrays of traditional objects, which can be anything and probably involve a lot of indirection. (Any indirection in an ECS is probably
<aeth> just an integer, an ID of some sort, rather than actually containing an object.)
<aeth> I don't actually have code for this in my ECS yet, but it shouldn't be hard. The main complication would be that I have some 2D arrays.
<aeth> But that's usually the kind of thing that game engines go for (hobbyist ones anyway... serious ones don't usually have ECSes) when they save state.
pranavats has left #commonlisp [Error from remote client]
cage has joined #commonlisp
pranavats has joined #commonlisp
<aeth> This is a language independent-technique, but it could combine well with things like MAKE-LOAD-FORM in COMMON-LISP.
<aeth> You could probably abuse some features like this to make a save game format from CL's built-in functionality, and in the '90s this sort of thing could have worked well and would have been done, but these days it would probably be seen as too insecure.
random-nick has quit [Ping timeout: 268 seconds]
cosimone` has joined #commonlisp
cosimone has quit [Ping timeout: 268 seconds]
Lord_of_Life_ has joined #commonlisp
igemnace has quit [Remote host closed the connection]
eddof13 has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
Lord_of_Life has quit [Ping timeout: 264 seconds]
Lord_of_Life_ is now known as Lord_of_Life
thuna` has joined #commonlisp
random-nick has joined #commonlisp
cage has quit [Remote host closed the connection]
cage has joined #commonlisp
cosimone` has quit [Quit: ERC 5.4 (IRC client for GNU Emacs 28.1)]
attila_lendvai has joined #commonlisp
<kagevf> aeth hayley : ECS means "entity component system"?
anticomputer has quit [Remote host closed the connection]
anticomputer has joined #commonlisp
<aeth> kagevf: yes
<aeth> it's easy to be confused over what it means. It's not an entity-component system (lots of games have entities and components), it's an entity-component-system (three nouns... system code doesn't live with component data... and entities don't even really exist, they're just components)
morganw has quit [Ping timeout: 244 seconds]
<kagevf> aeth: I see .... thank you for the explanation and pointing out that distinction
<aeth> a bit more indirection for an entity; less indirection if you just want to iterate over every position and velocity when both position and velocity are present for an entity
<aeth> because there is no entity having a position, just #((1.0 2.0 3.0) (0.0 2.0 -1.0) ...)
<kagevf> then how do you know which entity/component/thing the positions and velocities are associated with ...?
hashfunc has joined #commonlisp
<neominimum> Bike: Thank you, `(:arguments . lambda-list)` is what I was looking for
<aeth> kagevf: You either give them all the same entity-id array index (and e.g. make it 0'd or with garbage data when it doesn't have that component)
<aeth> kagevf: or you introduce one layer of indirection, associating an entity-id with an index
ec has quit [Quit: ec]
<aeth> which is less problematic than you think because position and velocity (frequently used together) could use the same index even if it doesn't line up with the entity-id... and that's the thing you're iterating over every frame
eddof13 has joined #commonlisp
cage has quit [Remote host closed the connection]
epony has quit [Remote host closed the connection]
<aeth> kagevf: since all CL access is commonly done through accessors, you could still have an entity class that's basically just (defclass entity () ((%id :initarg :id :accessor id))) and then (make-instance 'entity :id 42)
<aeth> then every other accessor would just call the functions that look up values from the arrays (e.g. position could return (values 1.0 2.0 3.0) when id=0 in the earlier example).
<aeth> You do risk having a lot of people saying "That's not a real ECS, real ECSes don't have entity objects at all!", though. Completely missing the point, imo, but ECS purists will argue over whether the existence of a functionally useless except for debugging entity class still makes it an ECS or not.
anticomputer_ has joined #commonlisp
<aeth> (An ORM doesn't (and can't) remove the SQLness of a relational database.)
anticomputer has quit [Ping timeout: 258 seconds]
<aeth> I suppose the entity class also needs some way of telling which ECS you're using if you have more than one. And if you want it to serialize properly, you might need an ecs-id for that rather than having the ECS in a slot in an ENTITY. You could just use a dynamic scope *ECS* variable for this, though.
<aeth> The actually-important entity is conceptually just an array, too. In this case, an array of integers-as-bits, where each bit is 1 if it has that component and 0 if it does not.
<aeth> But I think that's the only missing piece that I didn't describe yet. It's conceptually very simple (even down to the machine level if the array's :element-type is supported by the CL implementation), but it's also very different, which is what can make it confusing.
cosimone has joined #commonlisp
pve has quit [Quit: leaving]
epony has joined #commonlisp
cosimone` has joined #commonlisp
cosimone` has quit [Remote host closed the connection]
cosimone has quit [Ping timeout: 250 seconds]
Alfr has quit [Killed (molybdenum.libera.chat (Nickname regained by services))]
Alfr has joined #commonlisp
Brucio-61 has quit [Ping timeout: 244 seconds]
scymtym has quit [Ping timeout: 250 seconds]
<kagevf> aeth: was the #((1.0 2.0 3.0) (0.0 2.0 -1.0) ...) example a multi-dimensional array? I missed that and if it is that would make more sense to me ...
<aeth> sorry, yeah, #2A
<aeth> my bad
<aeth> ideally, you wouldn't want anything that can't be expressed by a 1D or 2D array with a more-specific-than-T UPGRADED-ARRAY-ELEMENT-TYPE
<aeth> things of different types can just go in parallel arrays
<aeth> At least, that would be the CL way to do it. Different languages will do it differently. Many don't have anything low-level at all, just the equivalent of T vectors.
ec has joined #commonlisp
attila_lendvai has quit [Ping timeout: 264 seconds]
Brucio-61 has joined #commonlisp
scymtym has joined #commonlisp
<aeth> The reason why ECSes are a thing in (some) games is because you usually have a lot of the same thing, in fairly simple data structures. Things like position vectors.
Guest8581 has quit [Quit: WeeChat 3.6]
<kagevf> aeth: interesting and thank you for explaining all that ... definitely will consider that the next time I (re-)write serialization code
aartaka has quit [Ping timeout: 250 seconds]
rgherdt_ has joined #commonlisp
rgherdt has quit [Read error: Connection reset by peer]
puchacz has quit [Quit: Client closed]
aartaka has joined #commonlisp
prokhor has quit [Ping timeout: 265 seconds]
shka has quit [Ping timeout: 265 seconds]
hashfunc has quit [Remote host closed the connection]
defaultxr has quit [Ping timeout: 244 seconds]
_cymew_ has quit [Ping timeout: 264 seconds]
<aeth> The idea is that to e.g. update everything with a position, you'd iterate everything with both a position and velocity (skipping things with a position that don't have a velocity)... serialization just comes (nearly) for free from this sort of data structure. And that this is easiest if there actually is no "thing" at all, just positions and velocities.
ec has quit [Quit: ec]
<aeth> If you want to serialize everything instead of just one thing, anyway.
defaultxr has joined #commonlisp
<aeth> Importantly, it's parallel because you can operate on an entity's position and velocity in one thread while operating on something else in another thread as long as it's entirely independent.
<aeth> If you (loop :for entity :in entities :do (update entity)) instead, you can't easily parallelize this because UPDATE can do anything, on any number of slots.
ldb has joined #commonlisp
NotThatRPG has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
<aeth> You might think to just split the entities into different chunks, which works... until you need to do something like collision that isn't just a simple in-order iteration between independent things. You could do FP and work on copies instead of mutating, but now you use a lot of memory and any kind of optimization would probably start to look like an ECS.
tane has quit [Quit: Leaving]
perrierjouet has quit [Quit: WeeChat 3.6]
perrierjouet has joined #commonlisp
ec has joined #commonlisp
<ldb> serious games?
<aeth> serious game *engines*.
ec has quit [Client Quit]
<aeth> Just because the game itself is fun, doesn't mean that the game engine can't be written exactly like how Oracle writes its DB software.
aartaka has quit [Ping timeout: 268 seconds]
<aeth> Except the pay's probably worse and the deadlines/crunch is probably terrible. So writing the Oracle DB might be more fun.
ec has joined #commonlisp
ec has quit [Client Quit]
ec has joined #commonlisp
Alfr is now known as Guest6105
Guest6105 has quit [Killed (sodium.libera.chat (Nickname regained by services))]
Alfr has joined #commonlisp
ec has quit [Remote host closed the connection]
sjl has joined #commonlisp
Oladon has quit [Quit: Leaving.]
ec has joined #commonlisp
ldb has quit [Ping timeout: 268 seconds]
nij- has joined #commonlisp
<nij-> In the manual of sbcl, it says that save-lisp-and-die only preseves "global states". What does that mean? What are the "local states" that are missing? https://www.sbcl.org/manual/#Saving-a-Core-Image
<Bike> for example, in (let ((x ...)) (save-lisp-and-die ...)), whatever x is is gone
orestarod has joined #commonlisp
* Nilby wrote Oracle DB apps in Lisp. The fun part was getting it done in %5 of the time expected, because stuff like CLSQL REPL made it easy, and doing other things [playing games] the rest of the time.
nij- has quit [Ping timeout: 250 seconds]
<aeth> Bike: but does it save global closures like the X inside of FOO in (let ((x ...)) (defun foo () ...)) ?
<Bike> presumably, since that's part of the state of foo, which is part of the global state
<aeth> Nilby: hopefully these games. https://dto.itch.io/
<aeth> (written in Common Lisp)
eddof13 has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
<kagevf> that's interesting about save-lisp-and-die ... only saving global states underscores how it's really meant to be used as the name implies ... as opposed to a "save the world to re-load later" type of feature ... still allows for some overlap, but the nuance is different and that piece of information makes it clearer to me now
leo_song has quit [Quit: ZNC 1.7.2+deb3 - https://znc.in]
leo_song has joined #commonlisp
orestarod has quit [Ping timeout: 264 seconds]
ec has quit [Quit: ec]
ec has joined #commonlisp
akoana has joined #commonlisp
jmdaemon has quit [Ping timeout: 250 seconds]
jeosol has quit [Quit: Client closed]
<Nilby> on pdp10 lisp it was easy, because the OS could save any program and resume it. if only modern OS's supported it without a whole separate VM
<aeth> or just rewrite every program in a Lisp that can do it?
<Nilby> aeth: how'd you guess what I'm doing :)
anticomputer_ has quit [Remote host closed the connection]
anticomputer has joined #commonlisp
Alfr is now known as Guest3901
Alfr has joined #commonlisp
Guest3901 has quit [Ping timeout: 265 seconds]
NotThatRPG has joined #commonlisp
Josh_2 has joined #commonlisp
NotThatRPG has quit [Ping timeout: 265 seconds]
thuna` has quit [Quit: out]
mitchconnor has joined #commonlisp
mitchconnor has quit [Client Quit]
waleee has joined #commonlisp
jolby has quit [Quit: Client closed]
edgar-rft has quit [Ping timeout: 260 seconds]
jmdaemon has joined #commonlisp
ccregor has joined #commonlisp
<ccregor> Hello! Question about variables and LISP
<aeth> yes
<ccregor> If I have (defvar child "someContent") and (defvar parent "child"), is there a way I can "someContent" from parent var?
<ccregor> Kinda one var flowing down to the next?
<ccregor> *I can get "someContent" from expanding "parent" var *typo :)
edgar-rft has joined #commonlisp
<dbotton> Not sure I understand you ccregor
<dbotton> perhaps be cause you phrased this as a relation ship and there is none
<ccregor> My use case is I'm trying to get time and doing a multiple-bind to parse out the vars as start-seconds and looking to map these into real vars. Hoping I can do something like (mult-bind (decodec-universal-time )(time stuff) (loop for x in (list of time stuff) do (defvar x start-x). So at the end of the function/macro(?) I'll have start-seconds and seconds as two diff vars but the same number from universal time
NotThatRPG has joined #commonlisp
edgar-rft has quit [Ping timeout: 265 seconds]
<ccregor> I'm pretty green in the lisp world :) and likely I may even have the wrong mentalities at this. Trying to parse out a date into individual date vars without a ton of duplicate code XD
prokhor__ has joined #commonlisp
<ccregor> (multiple-value-bind (start-second start-minute start-hour start-date start-month start-year start-day-of-week start-dst-p start-tz)
<ccregor> (decode-universal-time start-time)
prokhor_ has quit [Remote host closed the connection]
<ccregor> (loop for x in '(second minute hour date month year day-of-week dst-p tz)
<ccregor> do
<ccregor> (defvar x start-(x))))
<ccregor> (defvar start-time)
<ccregor> (setq start-time (get-universal-time))
<ccregor> that last two should be up top...
<dbotton> Not sure creating a ton of "globals" makes sense like ever...
<dbotton> and in this case mvb already gives you local vars
<saturn2> if you really want to assign multiple values to global variables, there's multiple-value-setq
random-nick has quit [Ping timeout: 250 seconds]
akoana has quit [Quit: leaving]
<saturn2> or (setf (values ...) ...)
<Nilby> ccregor: I'm not really sure what you're asking, or if this is the best way, but perhaps you mean something like this? https://plaster.tymoon.eu/view/3418#3418
<Nilby> ccregor: There's probaly a simpler way. progv is weird.
taiju has joined #commonlisp
<dbotton> ccregor (defmacro set-start (field value) `(setf ,(intern (string-upcase (format nil "start-~A" field))) ,value))
<dbotton> but I feel like I am creating a global criminal