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/>
jmd_ has joined #commonlisp
tyson2 has quit [Remote host closed the connection]
jeosol has joined #commonlisp
ec has quit [Remote host closed the connection]
ec has joined #commonlisp
fosskers has joined #commonlisp
<fosskers> What are the runtime costs of the `&rest` arguments? From the function's perspective they're wrapped in a list. If the function then calls something else on that list via `apply` and the called function also accepts `&rest`, will there be a lot of wasteful list wrapping or is the compiler smart enough to optimize all that away?
<bike> implementations are allowed to do that (and often do) but it is not required
<bike> part of the problem is that the callee function has to be compiled in the same unit with the caller in order for the compiler to really know that the callee takes &rest, unless it's a standard function
<fosskers> So if the functions were in the same package it would probably work out?
<aeth> if you apply rest it's not good, otherwise potential optimizations afaik
<aeth> probably, anyway
nij- has left #commonlisp [Using Circe, the loveliest of all IRC clients]
tyson2 has joined #commonlisp
sloanr has joined #commonlisp
<bike> fosskers: it's a bit closer of a coupling than that. usually implementations allow you to recompile individual functions. So say you have (defun a (&rest r) (apply #'b r)) (defun b (&rest r) ...). the compiler optimizes A to pass the rest list directly to B - ok. but then you redefine b as, i don't know, (defun b (x) ...). now B isn't prepared to receive a &rest list and everything goes wonky.
<bike> so the implementation may elect to not do the optimization in order to prevent you from shooting a foot off.
<bike> but if B is an flet within A there's no problem, and there may be other options, like sbcl's "block compilation"
<fosskers> I see the issue
thuna` has quit [Remote host closed the connection]
<bike> now, with how implementations work these days, it's common to not really pass around lists at all. instead the function with the &rest parameter will receive arguments in a generic fashion (like registers or sequential stack locations) and then cons a list itself
<bike> in which case structure sharing through APPLY doesn't matter so much
<fosskers> That's what I was hoping to hear
<bike> but the consing can still be expensive. you can avoid that by declaring the &rest list dynamic-extent (assuming it actually is), or the implementation can sometimes optimize things such that there's no actual list
<fosskers> I haven't heard of dynamic-extent
<bike> in SBCL, if you have a &rest parameter, and the list is only used in certain ways (passed to car, cdr, etc) then sbcl will actually compile it in such a way that there's no actual list at runtime
<bike> dynamic-extent means that a value only needs to exist within some dynamic contour - which in practice means that it can be stack allocated
<fosskers> I think that would be the case in my scenario
<bike> it's pretty common for &rest parameters
<fosskers> Thanks for the explanation
<fosskers> Unrelated: what's the go-to web server these days?
tyson2 has quit [Remote host closed the connection]
waleee has quit [Ping timeout: 245 seconds]
nij- has joined #commonlisp
<nij-> How does (defun .. (&environment e)) work? Does it really make a snapshot of the environment E at runtime?
<bike> it doesn't work. &environment is not valid in ordinary lambda lists.
<edgar-rft> nij-: it probably doesn't work at all because DEFUN uses ordinary lambda-lists which have no &environment parameter
<edgar-rft> &environment is described in CLHS 3.4.4 Macro Lambda Lists and as far as I understand it only captures the environment at compile-time but there are better specialists here than me
<nij-> Oh, I see. And in the case of a macro lambda list, does it make a copy of the env at compile time?!
<nij-> (Isn't that inefficient?)
<Alfr> nij-, what do you intend to do with it?
<nij-> I'm trying to understand what's happening in the back.
Demosthenex has quit [Ping timeout: 246 seconds]
<beach> nij-: There would not be a copy made. The compilation environment is passed as is.
047AABTH5 has joined #commonlisp
<beach> nij-: There is basically almost never any implicit copying in Common Lisp.
<047AABTH5> Can anyone recommend a good example of interacting with a complex REST API in cl? My day job involves working on a large Go system that exposes an http api, and I'd like to experiment with using lisp to interact with that--just for fun
bilegeek has joined #commonlisp
<047AABTH5> mainly want to see what's common/good practice for e.g. unpacking the JSON response, making modifications, and POSTing it back
047AABTH5 is now known as jfloren2
Demosthenex has joined #commonlisp
nij- has quit [Ping timeout: 246 seconds]
Demosthenex has quit [Remote host closed the connection]
Demosthenex has joined #commonlisp
<patrix> the docs for drakma and dexador would be a good starting point. The ebook "Loving Common Lisp" also has a few chapters dedicated to using drakma to query pages and APIs and parsing the data
habamax has quit [Remote host closed the connection]
habamax has joined #commonlisp
earl-ducaine has joined #commonlisp
<jfloren2> thanks
sloanr has quit [Remote host closed the connection]
nij- has joined #commonlisp
<nij-> beach thanks
<beach> nij-: Sure. What gave you the idea that the environment would be copied?
bilegeek has quit [Ping timeout: 246 seconds]
johnjaye has quit [Ping timeout: 246 seconds]
<nij-> If not, I'd expect there's a dynamic variable that points to the environment. If this were true, they didn't have to allow &env in defmacro lambda list.
<beach> I see. There is no such variable suggested by the standard.
<beach> The compilation environment is entirely handled by the compiler at compile time, so when the compiler calls the macro function, it passes that environment as the second argument to the macro function. The first argument being the form to expand.
<nij-> Got it. Is there any practical example that does use env?
<beach> Oh, sure. I just don't remember any by heart.
<beach> Let me see if I can find some...
<beach> Well, you can look at phoe's portable condition system.
<beach> Basically, whenever you need to call macroexpand at compile time, you need to pass the environment.
<beach> Otherwise, things like MACROLET won't be taken into account, because macro expansion would then be done in the global environment.
johnjaye has joined #commonlisp
johnjaye has quit [Ping timeout: 260 seconds]
fosskers has quit [Ping timeout: 246 seconds]
edgar-rft has quit [Ping timeout: 246 seconds]
edgar-rft has joined #commonlisp
dcb has quit [Quit: MSN Messenger 4.0.2]
azimut has quit [Ping timeout: 240 seconds]
pve has joined #commonlisp
rtypo has quit [Ping timeout: 245 seconds]
fosskers has joined #commonlisp
johnjaye has joined #commonlisp
fosskers has quit [Remote host closed the connection]
fosskers has joined #commonlisp
nij- has quit [Ping timeout: 245 seconds]
markb1 has quit [Ping timeout: 260 seconds]
pranavats has left #commonlisp [Error from remote client]
markb1 has joined #commonlisp
kenran has joined #commonlisp
igemnace has joined #commonlisp
fosskers has quit [Ping timeout: 245 seconds]
fosskers has joined #commonlisp
shka has joined #commonlisp
Lycurgus has joined #commonlisp
ec has quit [Ping timeout: 240 seconds]
ec has joined #commonlisp
Lycurgus has quit [Quit: Tschüss]
speskk9 has joined #commonlisp
speskk has quit [Read error: Connection reset by peer]
speskk9 is now known as speskk
Gleefre has joined #commonlisp
pranavats has joined #commonlisp
Gleefre has quit [Remote host closed the connection]
Gleefre has joined #commonlisp
johnjaye has quit [Ping timeout: 245 seconds]
johnjaye has joined #commonlisp
scymtym has joined #commonlisp
Demosthenex has quit [Ping timeout: 250 seconds]
nij- has joined #commonlisp
<nij-> beach: thank you..
Demosthenex has joined #commonlisp
<beach> Pleasure.
habamax has quit [Quit: ERC 5.5.0.29.1 (IRC client for GNU Emacs 29.1)]
fosskers has quit [Ping timeout: 260 seconds]
Equill has quit [Quit: KVIrc 5.0.1 Aria http://www.kvirc.net/]
dino_tutter has joined #commonlisp
ec has quit [Ping timeout: 240 seconds]
ec has joined #commonlisp
kopiyka has quit [Remote host closed the connection]
nij_ has joined #commonlisp
nij- has quit [Killed (NickServ (GHOST command used by nij_))]
nij_ is now known as nij-
kopiyka has joined #commonlisp
Demosthenex has quit [Ping timeout: 245 seconds]
luna-is-here has joined #commonlisp
surabax[m] has quit [Quit: You have been kicked for being idle]
jmd_ has quit [Ping timeout: 250 seconds]
jeosol has quit [Quit: Client closed]
theBlackDragon has quit [Ping timeout: 260 seconds]
theBlackDragon has joined #commonlisp
Demosthenex has joined #commonlisp
Lord_of_Life_ has joined #commonlisp
Lord_of_Life has quit [Ping timeout: 250 seconds]
Lord_of_Life_ is now known as Lord_of_Life
mi6x3m has joined #commonlisp
<mi6x3m> hey friendos! how can I capture the (obj (&key test key)) in (defmacro foo ((obj (&key test key) &body clauses) as a single var?
<mi6x3m> i wanna pass this unchanged to another macro
<mfiano> One way would be to do your own destructuring with destructuring-bind, making the signature (bar &body clauses)
<mfiano> But there are others, depending on your use-case
Demosthenex has quit [Ping timeout: 246 seconds]
igemnace has quit [Ping timeout: 246 seconds]
habamax has joined #commonlisp
<beach> mi6x3m: The macro lambda list can take the &WHOLE lambda-list keyword.
<beach> ::clhs 3.4.4
<ixelp> CLHS: Section 3.4.4
<mi6x3m> interesting, what does it do beach?
<beach> It contains the whole form that was given to the macro. Just what you want, if I understand you correctly.
<mi6x3m> i see
<mi6x3m> so
<mi6x3m> defmacro foo ((&whole whole obj (&key test key) &body clauses)
<beach> No
Demosthenex has joined #commonlisp
<beach> (defmacro foo (&whole form obj (&key ...)...))
<mi6x3m> I mean it does say " &whole can appear at any level of a macro lambda list"
<beach> Yes, but then you get only that part of the invoking form.
<mi6x3m> well that's exactly what i need
<beach> Oh, right. I misread. Sure.
igemnace has joined #commonlisp
<mi6x3m> tnx beach that's really helpful
<beach> ywlcm
Demosthenex has quit [Ping timeout: 246 seconds]
nij- has quit [Ping timeout: 246 seconds]
tyson2 has joined #commonlisp
Demosthenex has joined #commonlisp
OlCe` has quit []
OlCe has joined #commonlisp
Gleefre has quit [Remote host closed the connection]
Gleefre has joined #commonlisp
attila_lendvai has joined #commonlisp
hayley has joined #commonlisp
mi6x3m has quit [Ping timeout: 245 seconds]
Krystof has joined #commonlisp
tetsuo9_ has quit [Remote host closed the connection]
tetsuo9_ has joined #commonlisp
scymtym has quit [Ping timeout: 250 seconds]
Brucio-61 has quit [Ping timeout: 245 seconds]
kenran has quit [Remote host closed the connection]
Gleefre has quit [Remote host closed the connection]
Gleefre has joined #commonlisp
amb007 has quit [Ping timeout: 260 seconds]
amb007 has joined #commonlisp
Brucio-61 has joined #commonlisp
MajorBiscuit has joined #commonlisp
tertek has joined #commonlisp
mi6x3m has joined #commonlisp
mi6x3m has quit [Client Quit]
jonatack1 has joined #commonlisp
jon_atack has quit [Ping timeout: 246 seconds]
rtypo has joined #commonlisp
amb007 has quit [Ping timeout: 244 seconds]
amb007 has joined #commonlisp
liminality has joined #commonlisp
attila_lendvai has quit [Read error: Connection reset by peer]
attila_lendvai_ has joined #commonlisp
<liminality> hi all~ i'm struggling with jumping between quoted and unquoted code when i write a macro, but essentially i'm trying to elt an item in a form passed to the macro, using an index defined in a quoted loop in that macro. though, i'm struggling to access it and not just a symbol.
<liminality> where could i paste some code to show y'all?
<beach> plaster.tymoon.eu
<liminality> ty
<liminality> hi beach
<beach> wy
<beach> yw I mean
<liminality> the issue is on line 4, i'm doing ,(elt plist index) knowing that index is undefined in the macro, though saying 'index evals to (elt <the-plist> <the-symbol-'index>)
<ixelp> (elt plist index) ERROR: Unbound variable: PLIST
<liminality> index *is* defined in the expanded code though, but i'm wondering how to access vars defined in the expanded code, in the macro itself. is that possible?
<bike> the expanded code isn't running at the time the macro is expanding, obviously. how could you access anything defined by the expansion while producing that expansion?
<beach> You can't do (elt plist index) at macro-expansion time if index is not known until the expansion has happened. So you need to evaluate that form in the expansion.
<bike> what is this macro supposed to do?
<liminality> aaah i see
<liminality> i'm trying to write a macro that takes a property-list, and returns that same property list but the values of each property are wrapped in lambdas
<liminality> so for example: (plist-nonsense (list :x 100 :y (current-time))) => (:x (lambda () 100) :y (lambda () (current-time)))
<liminality> i need to store the code written in a plist's values for later evaluation, basically
<Josh_2> (alexandria:doplist ..) might come in handy
<bike> macro arguments aren't evaluated, and you seem to have written this as if they are
<bike> like, that LIST call will not happen
<beach> Perhaps it shouldn't be a macro at all.
<bike> well, if (current-time) is supposed to be evaluated later it would have to be
<liminality> the goal is for the user to be able to type out code without wrapping it in a lambda, and have that code be evaluated later. though, each value of each property needs to be evaluated separately, i can't just wrap the whole plist in a lambda since i want to be able to funcall individual properties.
cage has joined #commonlisp
<bike> you'd have to give it something constant, e.g. (plist-nonsense (:x 100 :y (current-time)))
<bike> and then that would expand into (list :x (lambda () 100) :y (lambda () (current-time))), presumably
<bike> also, plist-nonsense isn't very descriptive. how about plist-delay
<liminality> @bike >macro arguments aren't evaluated, and you seem to have written this as if they are // it's moreso that i expect the input to the macro to look like that, and i later make sure i'm working with a correctly-formed plist based off the given form
<liminality> plist-delay then
<bike> you should not expect the input to the macro to look like that
<bike> that makes it look like the form will be evaluated, but it will not be
<bike> something like (plist-delay (some-call-that-produces-a-list)) is impossible, for example
<Josh_2> liminality: you can do what you want without a macro
<Josh_2> (let ((x ()))
<liminality> hmmmm
<liminality> ah i see, bike, i see. i didn't consider that.
<liminality> Josh_2, i'm not sure i understand what you're suggesting
<beach> liminality: I suspect it is not a macro at all, but an ordinary function.
<Josh_2> liminality: (loop :for (key val) :on (list :a (format nil "WEEEEE") :b (local-time:now)) :by #'cddr :appending (list key `(lambda () ,val)))
lucasta has joined #commonlisp
<Josh_2> -> (:A (LAMBDA () "WEEEEE") :B (LAMBDA () @2023-08-02T13:52:05.443112+01:00)) You can then go through the plist and #'compile the plists vals
<beach> liminality: Also, are you sure you want lambda expressions in there (which would need to be evaluated to create functions) rather than the functions themselves?
<Josh_2> But as beach just suggested, in my example if you remove the ` and , you will have functions instead
<beach> liminality: It is a common mistake, especially with newbies (not sure whether you are one) to attempt to create a macro where a function should be created instead.
<Josh_2> The append method combination is my favourite (not relevant to this convo)
<liminality> compile
<liminality> hmm
<Josh_2> (compile nil (getf <my example plist> :A)) -> #<FUNCTION ...>
<liminality> ah i am a newbie, beach
<liminality> there's lots i don't understand from what y'all have told me
<liminality> hmm
<bike> if you want to be able to call the :y value later and get a different current time, you need a macro. if you're okay with getting the current time when plist-delay-the-function is called you don't.
<Josh_2> The 'lambda' in my example is a proper list whose first element is the symbol lambda and the second an empty list etc. With the function #'compile you can ya know compile that list
<liminality> nawh i need to get a different current-time
<liminality> you can compile lists? geez
<Josh_2> lisp is homoiconic ya know
<liminality> woh
<liminality> WOAH
<liminality> THAT'S SO COOL
<liminality> i thought compile only accepted like, names of functions, but passing nil means i can just pass lists
<liminality> omfg
<bike> code is data, etc.
<Josh_2> ^
<liminality> Josh_2 i've heard it's homoiconic, but i've never really understood what it meant. is there some place i can read up on what the implications are?
<bike> it is cool, but i don't think compile is what you want here.
tyson2 has quit [Remote host closed the connection]
<liminality> ahh
<bike> it depends on the context of this thing, of course, which i don't know. but it's pretty rare that you really want to compile or eval things.
<bike> at runtime, i mean
<Josh_2> I've made heavy use of #'compile with metaclasses, but thats about it
jeffrey has joined #commonlisp
<liminality> sometimes i run into an issue where um. mmm. i end up returning symbols instead of code
<liminality> like i'll write a macro that creates a lambda, but when i funcall the lambda it returns a symbol of the code, instead of running that code
<liminality> but i could use compile in this sorta situation, right?
<bike> i'm not sure what you mean.
<bike> do you have an example?
<liminality> yyyyes, one sec
<beach> liminality: By the way, there is no such thing as "a lambda". There is a "lambda expression" which is just data, and there is a (perhaps anonymous) function resulting from the evaluation of a lambda expression. It is important to know the difference, or you will make mistakes like you just mentioned.
<liminality> here
<liminality> i'm binding the symbol X to 100, though the macro ends up returning the symbol X instead of reading the value of the symbol X in that frame and returning the value
<liminality> beach: i'm not quite sure i understand. so, (lambda () 'foo) is a lambda expression, and the return of calling (lambda () 'foo) => <#FUNCTION-DGADKFLGJ> is an object of type function. yes?
<beach> liminality: In that paste, it is just that you quoted the entire list, including the symbol. Try (list 25 50 x) instead.
<beach> liminality: Not quite. (lambda () 'foo) is indeed a lambda expression. But only if it is a context of evaluation is it turned into a function. You can't "call" the lambda expression because it is not a function. You can call only the resulting function.
<liminality> beach: > Try (list 25 50 x) instead. // oh wow that worked
<beach> liminality: I should let you know about #clschool. This channel is not really meant for newbie questions, though they are tolerated to some extent, especially if it otherwise quiet here. But there are people who hang out in #clschool who are not present here.
<liminality> should i ask these sorts of things there?
<beach> Yes.
<beach> liminality: Same thing with the paste. With the '(25 50 x), X is just data because it is in a context where it is not evaluated.
<liminality> i see
<liminality> i managed to get what i was working on to work, thanks everyone
<Josh_2> can show?
echos- has joined #commonlisp
markasoftware has quit [Remote host closed the connection]
wheeler has quit [Quit: cheerio]
markasoftware has joined #commonlisp
Gleefre has quit [Remote host closed the connection]
Gleefre has joined #commonlisp
markb1 has quit [Ping timeout: 246 seconds]
markb1 has joined #commonlisp
habamax has quit [Quit: ERC 5.5.0.29.1 (IRC client for GNU Emacs 29.1)]
azimut has joined #commonlisp
amb007 has quit [Read error: Connection reset by peer]
amb007 has joined #commonlisp
Lycurgus has joined #commonlisp
Demosthenex has quit [Ping timeout: 246 seconds]
Gleefre has quit [Remote host closed the connection]
Demosthenex has joined #commonlisp
MajorBiscuit has quit [Ping timeout: 246 seconds]
Josh_2 has quit [Quit: Gotta go fast!]
Demosthenex has quit [Ping timeout: 246 seconds]
Gleefre has joined #commonlisp
azimut_ has joined #commonlisp
Demosthenex has joined #commonlisp
azimut has quit [Ping timeout: 240 seconds]
Posterdati has joined #commonlisp
zxcvz has joined #commonlisp
zxcvz has quit [Client Quit]
Lycurgus has quit [Quit: Tschüss]
ym has joined #commonlisp
liminality has quit [Ping timeout: 250 seconds]
rtoy has joined #commonlisp
tyson2 has joined #commonlisp
Demosthenex has quit [Ping timeout: 246 seconds]
xaltsc has joined #commonlisp
liminality has joined #commonlisp
Demosthenex has joined #commonlisp
liminality has quit [Quit: Leaving]
lucasta has quit [Quit: Leaving]
akonai has quit [Quit: Quit.]
cage has quit [Quit: rcirc on GNU Emacs 28.2]
akonai has joined #commonlisp
igemnace has quit [Ping timeout: 246 seconds]
markb1 has quit [Ping timeout: 260 seconds]
attila_lendvai_ has quit [Ping timeout: 246 seconds]
igemnace has joined #commonlisp
markb1 has joined #commonlisp
notzmv has joined #commonlisp
cosimone has joined #commonlisp
igemnace has quit [Ping timeout: 260 seconds]
tyson2 has quit [Remote host closed the connection]
jeffrey has quit [Quit: Client quit]
tyson2 has joined #commonlisp
igemnace has joined #commonlisp
Josh_2 has joined #commonlisp
tyson2 has quit [Ping timeout: 245 seconds]
amb007 has quit [Read error: Connection reset by peer]
amb007 has joined #commonlisp
tyson2 has joined #commonlisp
jmdaemon has joined #commonlisp
dcb has joined #commonlisp
tyson2 has quit [Remote host closed the connection]
notzmv has quit [Read error: Connection reset by peer]
dino_tutter has quit [Ping timeout: 246 seconds]
semz has quit [Quit: ZNC 1.8.2+deb2build5 - https://znc.in]
semz has joined #commonlisp
notzmv has joined #commonlisp
morganw has joined #commonlisp
Brucio-61 has quit [Ping timeout: 250 seconds]
Brucio-61 has joined #commonlisp
tasty_ has quit [Quit: rebooting for kernel updates]
famicom_guy_ has quit [Quit: ZNC 1.8.2 - https://znc.in]
Brucio-61 has quit [Ping timeout: 246 seconds]
famicom_guy has joined #commonlisp
attila_lendvai_ has joined #commonlisp
Brucio-61 has joined #commonlisp
akoana has joined #commonlisp
tasty has joined #commonlisp
tasty has joined #commonlisp
tasty has quit [Changing host]
igemnace has quit [Quit: WeeChat 4.0.2]
waleee has joined #commonlisp
dino_tutter has joined #commonlisp
attila_lendvai_ has quit [Ping timeout: 245 seconds]
alcor has joined #commonlisp
cosimone has quit [Ping timeout: 245 seconds]
OlCe has quit [Read error: Connection reset by peer]
OlCe has joined #commonlisp
Brucio-61 has quit [Remote host closed the connection]
pve has quit [Quit: leaving]
Brucio-61 has joined #commonlisp
shka has quit [Ping timeout: 246 seconds]
tyson2 has joined #commonlisp
{1234} has joined #commonlisp
alcor has quit [Remote host closed the connection]
{1234} has quit [Remote host closed the connection]
rtoy has quit [Quit: rtoy]
dtman34 has quit [Quit: ZNC 1.8.2+deb3.1 - https://znc.in]
dtman34 has joined #commonlisp
blackshuck has joined #commonlisp
thuna` has joined #commonlisp
habamax has joined #commonlisp
habamax has quit [Remote host closed the connection]
blackshuck has quit [Remote host closed the connection]
habamax has joined #commonlisp
dino_tutter has quit [Ping timeout: 246 seconds]
morganw has quit [Remote host closed the connection]
cmack has joined #commonlisp
thuna` has quit [Remote host closed the connection]
habamax has quit [Remote host closed the connection]
habamax has joined #commonlisp
Lycurgus has joined #commonlisp
hineios0 has joined #commonlisp
hineios has quit [Ping timeout: 264 seconds]
hineios0 is now known as hineios