<mi6x3m>
so I wanna process the :cache opts and then splice <forms>
<pve>
mi6x3m: how about defining you own with-first-middle-last macro, like (with-first-middle-last (first middle-guys last) all-the-arguments ...)?
<mi6x3m>
I could do that yeah
<mi6x3m>
is a defun equivalent to assigning a lambda to a defvar?
<beach>
No.
<mi6x3m>
what would be?
<beach>
(setf (fdefinition <name>) (lambda ...))
<beach>
and there is no such thing as "a lambda".
<beach>
There is a lambda expression and there is an anonymous function.
<mi6x3m>
right
<beach>
You don't assign the lambda expression with FDEFINITION, you assign a function, possibly, but not necessarily, created using the operator LAMBDA.
<mi6x3m>
well for the cache mechanism above I need 2 functions to share state
<beach>
Create a closure.
<mi6x3m>
so I thought to define them in the same lexical scope capturing some vars
<mi6x3m>
yeah
prokhor has quit [Remote host closed the connection]
<beach>
the <function1> and <function2> should be lambda expressions.
<Shinmera>
You didn't hear this from anyone at all and least of all me, but Charles managed to read a file and print its contents on the Nintendo Switch.
<Shinmera>
from lisp!
kevingal has joined #commonlisp
<mi6x3m>
I just wanna say thanks to everyone that support me with lisp fu for last weeks :)
<mi6x3m>
CL could be quite deep but you friends entangle it
<beach>
Common Lisp has relatively simple semantics (compared to most languages), but there are a lot of tools built upon the simple core.
<Shinmera>
beach: the compile-file/load-time-value/eval-when semantics are pretty hairy :)
<beach>
Nah, it's just a bit hard to understand why they must exist.
<Shinmera>
Anyway, I have a question for MOP experts: I have a metaclass that, right now, provides an involved slot-value-using-class method to do the actual value lookup. Most of its logic could be optimised away if it could be inlined, so my question is: how would I go about generating accessor methods?
<hayley>
I liked being able to tell someone that, per the standard, a compiler may just write macroexpanded Lisp forms to a file as a FASL (and that SICL isn't far off).
habamax has quit [Quit: ERC 5.5.0.29.1 (IRC client for GNU Emacs 29.0.92)]
<beach>
hayley: Close, yes, provided the literals in the code can be handled by READ.
cage has joined #commonlisp
<beach>
Shinmera: They are just instances of STANDARD-ACCESSOR-METHOD.
<beach>
You can give your object a method function that does direct access to the slot if you can compute it at compile time.
notzmv has quit [Ping timeout: 240 seconds]
<Shinmera>
OK, but, and forgive my ignorance on this, when would I compute this (during finalize-inheritance?) and *how* would I actually hook that up? using (setf find-method) or something?
mi6x3m has quit [Remote host closed the connection]
<Shinmera>
It's one thing I've never done, so I don't know the correct way to go about it
<beach>
q3cpma: That will return a function that, when called, returns a function of one argument that has the macrolet taken into account.
<q3cpma>
Yeah, I had beach's version (after trying (macrolet (lambda)) first
<q3cpma>
Will probably do that, don't want to polute the global env
<q3cpma>
ogamita: would be slow, no? Guaranteed call to the interpreter or not?
<ogamita>
The point here is that COMPILE can only compile lambda expressions or a function. So you either need to wrap your form into a lambda form, or you need to evaluate your form to produce a function (probably interpreted), that compile may compile.
<ogamita>
q3cpma: the interpreter doesn't need to work, since it only has to macroexpand the macrolet, and evaluate the lambda form to build an interpreted function.
<ogamita>
On the other hand, if eval calls compile, then it compiles twice (the second time, doing nothing since the function is already compiled).
<q3cpma>
Ah, I see your point, misread your snippet; but as beach's example shows, it doesn't look necessary unless your macro itself is dynamic, no?
<q3cpma>
Nah, even that can be taken care of, unless I'm wrong
<mi6x3m>
can anyone spot the error here
<ogamita>
q3cpma: anything in the let can be computed at run-time. It's about the same complexity (you could benchmark it on your specific cases). (funcall (funcal (compile nil (lambda () … (lambda …))))) vs. (funcall (compile nil (eval (… `(lambda ,…)))))
<mi6x3m>
using it with (def-indicator foo :cache-for (5 :seconds) nil) reports :cache-for is not a list
<beach>
mi6x3m: Probably that you put the &key inside a list.
<beach>
mi6x3m: Your macro lambda list looks strange.
<mi6x3m>
I changed it to (defmacro def-modeline-indicator (name &key ((:cache-for (duration units)) nil cache-for-p) (cache-invalidation-fn nil cache-invalidation-fn-p) &body body) but now the "body is misplaced"
<ogamita>
Yes, you cannot have both &key and &body. more precisely, &body = &rest so you can have it but it will take also the &key.
<ogamita>
and the body will need an even number of elements!
<mi6x3m>
hmmm I was afraid it's the case
<mi6x3m>
but what is the solution
<mi6x3m>
design change maybe
<ogamita>
(defmacro moo (&body body &key a b &allow-other-keys) `(list ',a ',b ',body)) (moo :a 1 and this is all) #| --> (1 nil (:a 1 and this is all)) |#
<ogamita>
Alternatively, you may introduce the body with: :cache-for (5 :seconds) :body ((print 'hi) (do-something)) but it's probably worse to wrap bodies in parentheses than key arguments.
<mi6x3m>
sec you're going too fast
<mi6x3m>
yeah maybe i'll settle for the kw args wrapped
<ogamita>
You may also have just (defmacro def-indicator (name &body options-and-body) …) and parse options-and-body: (if (eql :cache-for (first options-and-body)) (let ((cache-for (progn (pop options-and-body) (pop options-and-body))) (body options-and-body)) …) (let ((cache-for '(5 :seconds)) (body options-and-body)) …))
<ogamita>
this last option is nice syntax-wise, but you must work more (parse yourself), and it's less integrated into IDE, such as emacs, (it cannot complete the arguments since it doesn't know [:cache-for (duration units)] . body
<ogamita>
Sometimes it's possible to instruct the IDE about the syntax of such operators.
<mi6x3m>
thanks ogamita, this is a fantastic break down
<mi6x3m>
i'll roll with (def-indicator (:cache-for (5 :seconds) :cache-invalidation-fn moo) body)
<mi6x3m>
still quite readable
sunarch has quit [Quit: WeeChat 3.8]
pranavats has left #commonlisp [Error from remote client]
<ogamita>
mi6x3m: you may also define a macro or macrolet to do it with the body. (defindicator foo (cache-for 5 seconds) (* 4 2)) with https://termbin.com/lbr20
<ogamita>
<ogamita>
mi6x3m: ie. you define a DSL with a set of flet and macrolet around the body.
dcb has joined #commonlisp
<mi6x3m>
let's not go quite that far
dcb has quit [Ping timeout: 245 seconds]
dcb has joined #commonlisp
<mi6x3m>
one more q, how to convert a macro argument to a symbol to be used with fdefnition
<mi6x3m>
e.g. the name in def-indicator
<mi6x3m>
(fdefinition ,name) reports an erorr
euandreh has quit [Remote host closed the connection]
<mi6x3m>
I want to define a global function with (setf (fdefinition .. like beach suggested
<beach>
You can also use DEFUN as in (let ((state ...)) (defun ...) (defun ...))
<beach>
DEFUN takes into account the lexical environment.
theBlackDragon has quit [Server closed connection]
theBlackDragon has joined #commonlisp
pranavats has joined #commonlisp
euandreh has joined #commonlisp
<mi6x3m>
last thing beach, how to specify the name to defun through a symbol?
<mi6x3m>
defun (xyz ,symbol-arg) ...
<beach>
You can't when DEFUN is in an ordinary position of evaluation. DEFUN does not evaluate its function-name argument. You would have to do (setf fdefinition) then.
<mi6x3m>
ok, so 1 usage of defun, 1 fdefiniton, seems to be working actually...
<mi6x3m>
(def-indicator foo (:cache-for (5 :seconds) :cache-invalidation-fn 'no-foo) "foo123") epic it works
<mi6x3m>
maybe :cache-invalidator would be better because -fn would expect an expression but hey
notzmv has joined #commonlisp
<mi6x3m>
changed to :invalidate-by
<phoe>
How does ~// behave in face of package deletion/recreation/renaming/renicknaming? Is this specified anywhere?
dmho has quit [Server closed connection]
dmho has joined #commonlisp
mi6x3m has quit [Remote host closed the connection]
Gleefre has joined #commonlisp
<beach>
Good question.
<beach>
I don't think it is specified, but if I were to implement it, I would use the package name and the symbol name each time FORMAT is called, but in FORMATTER, I might look it up once.
sloanr has quit [Remote host closed the connection]
<phoe>
this approach contradicts CLHS Macro FORMATTER which describes the equivalence relation between the two
tyson2 has quit [Remote host closed the connection]
<phoe>
mi6x3m: try :INVALIDATE-BY NO-FOO
<phoe>
so, with the unquoted symbol
<beach>
Yes, you are passing it (quote ...)
<phoe>
the literal 'NO-FOO is a cons, not a symbol
<mi6x3m>
what would be a symbol literal?
<mi6x3m>
actually (symbolp 'foo) returns T
<mi6x3m>
just in the macro body it returns nil
<phoe>
FOO is a symbol literal
dino_tutter has quit [Ping timeout: 245 seconds]
<phoe>
'FOO is (QUOTE FOO), so, a list literal
<phoe>
the macro has access to unevaluated arguments, hence when you call it with 'FOO you get 'FOO, not FOO, as an argument
<mi6x3m>
how do I use 'foo with the macro and still have the assertion work?
<mi6x3m>
I want to signify to the user that the thing doesn't already exist and they are naming it
kevingal has quit [Ping timeout: 264 seconds]
<mi6x3m>
hence the ' in the notation
<phoe>
you have (DEFUN FOO ...), not (DEFUN 'FOO ...)
<phoe>
even though the function FOO might not exist
<phoe>
same with DEFVAR, DEFCLASS, DEFTYPE, and literally almost every defining macro
shka has quit [Read error: Connection reset by peer]
<phoe>
so I'd skip the quote
shka has joined #commonlisp
<phoe>
otherwise the user might think that this argument is evaluated and be tempted to do something like (let ((thing 'foo)) (def-indicator ... :invalidate-by thing))
<phoe>
which will majestically explode if you do some sort of attempt at manual unquoting or (worse) maybe-unquoting
markb1 has quit [Ping timeout: 246 seconds]
shka has quit [Ping timeout: 246 seconds]
Gleefre has quit [Remote host closed the connection]
Gleefre has joined #commonlisp
parjanya has joined #commonlisp
markb1 has joined #commonlisp
<mi6x3m>
sounds good to me!
mi6x3m has quit [Remote host closed the connection]
waleee has joined #commonlisp
rainthree3 has joined #commonlisp
<phoe>
I still wonder about the ~/ behavior wrt package removal/renaming because it kind of follows the same pattern as when local nicknames change
<phoe>
and I'm reviewing Gleefre's draft of a PLN CDR now and attempting to find some prior art
pranavats has left #commonlisp [Error from remote client]
pranavats has joined #commonlisp
pranavats has left #commonlisp [#commonlisp]
parjanya has quit [Ping timeout: 246 seconds]
pranavats has joined #commonlisp
jeosol has joined #commonlisp
<jeosol>
Good morning all!!!
<jeosol>
Looking to update my SBCL and QL combo given the new QL release (June 19), anyone updated their QL yet? experienced any issues?
<q3cpma>
Hi again, anyone wanna explain to me why I need the in-package call in that function (and not the in the let, but at the function's toplevel): https://pastebin.com/evLvHUu7
<ixelp>
;; Run via sbcl --eval '(asdf:load-system "test")' --eval '(pkg:main)' s(defpa - Pastebin.com
<q3cpma>
Whoops, I use `sbcl --load test.lisp --eval '(pkg:main)' s` to run the script
grolter[m] has joined #commonlisp
<bike>
assuming the asdf system includes just this file
<bike>
when you load the asdf system, it uses cl:load or cl:compile-file or whatever, and those rebind *package*
<bike>
so the in-package form on line 5 sets the package, but this set is undone as soon as load or compile-file is done
<bike>
by the time of --eval '(pkg:main)', you are back in the cl-user package
<bike>
when you call main the in-package form on line 8 sets *package* back to PKG, and so the read-from-string interns symbols in that package, etc
<bike>
it may be better to just bind *package* in main if you need the package to be something
<q3cpma>
Ahhh, that's the read yes
dcb has quit [Ping timeout: 246 seconds]
LW has joined #commonlisp
dcb has joined #commonlisp
<q3cpma>
Problem: if I were to pass the argument via main's parameters (so the symbol may actually be interned in any package), how would I go about making it work?
<q3cpma>
And I'm still not clear on the problem: why isn't the symbol-macro s working when calling main from cl-user? Is s somehow interned during read/compile?
<bike>
well the s in your code is interned in pkg, of course
<bike>
then, at runtime, you use read-from-string to get arg, so that's read in whatever *package* is when read-from-string is called
SetoTaisho has joined #commonlisp
<bike>
without the in-package on line 8, at the time of the read-from-string, *package* would be whatever it is when (main) is called, and from the command line like you're doing it would be cl-user
<bike>
so read-from-string would return cl-user::s, if the command line argument was "s"
<bike>
symbol-macrolet is basically unrelated here
<bike>
the context s appears in in your code does not affect what package it is read in
<bike>
reading happens before compilation and evaluation
<bike>
your code is read - it ends up as a list (CL:DEFUN PKG::MAIN ... (CL:SYMBOL-MACROLET ((PKG::S
<q3cpma>
Yes, but it's the (compile) call that is failing, not the file compilation (I think?)
<q3cpma>
Hmmm
<q3cpma>
I see
<bike>
if you mean the compile is "failing" in that it is not finding the symbol macro, that's because the input to compile includes the value you got from read-from-string
<bike>
which, again, without the second in-package, will be CL-USER::S
<bike>
which is distinct from PKG::S, so it's an unbound variable
<q3cpma>
Yes, I understand the problem now (not the first time that load time interning tripped me), but I'm still pained that this snippet doesn't work as expected =)
<bike>
you probably just need to bind *package* around any reads
<q3cpma>
Yes, I don't see any other solution to this
<bike>
depends on what the larger scale architecture is. you could work directly with strings or uninterned symbols or something
<q3cpma>
How would uninterned symbols work? For the symbol macro to work, it needs to refer to the same symbol as arg, no?
tyson2 has quit [Remote host closed the connection]
<bike>
dunno. maybe keywords would be better. i don't know what the ultimate goal here is.
Inline has joined #commonlisp
Gleefre has quit [Remote host closed the connection]
<q3cpma>
Well, hard to describe and I've already taken lots of your time; thanks a lot!
Gleefre has joined #commonlisp
<bike>
happy to be of assistance
rainthree3 has quit [Quit: Leaving]
<q3cpma>
I'll probably ask for counsel once my little tool is done (basically, always found find(1) hard to use once, so I made something that acts like AWK; arguments would be '(file print) (dir print walk)' for example)
LW has quit [Quit: WeeChat 3.8]
q3cpma has quit [Quit: nyaa~]
johnjaye has quit [Quit: WeeChat 4.0.0-dev]
n1to has joined #commonlisp
johnjaye has joined #commonlisp
tyson2 has joined #commonlisp
pranavats has left #commonlisp [Disconnected: Hibernating too long]
pranavats has joined #commonlisp
akoana has joined #commonlisp
morganw has quit [Remote host closed the connection]
lieven has quit [Server closed connection]
lieven has joined #commonlisp
McParen has joined #commonlisp
tyson2 has quit [Remote host closed the connection]
parjanya has joined #commonlisp
tyson2 has joined #commonlisp
cage has quit [Quit: rcirc on GNU Emacs 28.2]
<McParen>
if I have a list of exported symbols, how can i find out which one is an exported class name? is there a way to check for a class?
<McParen>
find-class seems to signal an error when a class doesnt exist, is there a function that just returns nil if it doesnt find a class?
<Gleefre>
There is an optional parameter that controls it
<Gleefre>
(find-class 'aaa nil) will return nil
msavoritias has quit [Remote host closed the connection]
<McParen>
thanks a lot!
<McParen>
(i now see that was an answer i could have found out by myself, but well)
SetoTaisho has quit [Ping timeout: 260 seconds]
avocadoist has quit [Ping timeout: 240 seconds]
<McParen>
Gleefre, I just updated sbcl and saw that you contributed to the last few sbcl releases, also thanks for that.
<Gleefre>
Heh, I didn't really
<McParen>
Well your name is mentioned, so you did _something_.
<Gleefre>
I just was able to build it for Android and set up build scripts for that
<McParen>
I get quite happy every time another sbcl release comes out, like a monthly birthday.
<Gleefre>
:)
shka has joined #commonlisp
scymtym has quit [Ping timeout: 264 seconds]
Brucio-61 has quit [Ping timeout: 260 seconds]
igemnace has quit [Ping timeout: 245 seconds]
Inline has quit [Ping timeout: 246 seconds]
igemnace has joined #commonlisp
Brucio-61 has joined #commonlisp
attila_lendvai has joined #commonlisp
McParen has left #commonlisp [#commonlisp]
johnjaye has quit [Ping timeout: 246 seconds]
johnjaye has joined #commonlisp
euandreh has quit [Ping timeout: 250 seconds]
zxcvz has joined #commonlisp
zxcvz has quit [Client Quit]
attila_lendvai has quit [Read error: Connection reset by peer]
attila_lendvai has joined #commonlisp
n1to has quit [Quit: Leaving]
tyson2 has quit [Remote host closed the connection]
azimut has joined #commonlisp
ec has quit [Ping timeout: 240 seconds]
rtypo has quit [Ping timeout: 264 seconds]
ec has joined #commonlisp
attila_lendvai has quit [Ping timeout: 246 seconds]
Mrtn[m] has quit [Server closed connection]
Mrtn[m] has joined #commonlisp
shka has quit [Ping timeout: 264 seconds]
akoana has quit [Quit: leaving]
kevingal has joined #commonlisp
ec has quit [Ping timeout: 240 seconds]
edgarvincent[m] has quit [Server closed connection]
edgarvincent[m] has joined #commonlisp
azimut has quit [Ping timeout: 240 seconds]
rgherdt has quit [Remote host closed the connection]
azimut has joined #commonlisp
tibfulv has quit [Remote host closed the connection]
tibfulv has joined #commonlisp
dino_tutter has joined #commonlisp
mingus has quit [Ping timeout: 250 seconds]
mgl has quit [Quit: Client closed]
igemnace has quit [Ping timeout: 250 seconds]
surabax[m] has quit [Server closed connection]
surabax[m] has joined #commonlisp
igemnace has joined #commonlisp
nij- has joined #commonlisp
<nij->
Many langs have statements as long as expressions, unlike lisp. I can't think of any benefit of having statements. Did I miss anything? Why do they need statements?
<aeth>
syntax
<aeth>
it's syntactically awkward to have expressions, especially in something with significant indentation like Python
<nij->
I see! It will be very awkward if python's `def` returns anything that can be passed to the next function call.
<nij->
So they better just ban it (i.e. making it a statement).
Gleefre has quit [Ping timeout: 246 seconds]
<aeth>
and most of the time you don't use the return value
<aeth>
it's a bit different in Common Lisp because of COND
<aeth>
in most languages you'd just set a value in an if/then/else block, but in Common Lisp and Scheme, you use the return value of COND and save a set
<nij->
I see; it also bans people from using nested code.
<nij->
(prevents)
pve has quit [Quit: leaving]
<nij->
I find thata if/then/else/cond/.. returning things to be very helpful though..
<aeth>
it doesn't seem obvious to want to use the return value of everything
<aeth>
unless you do
<aeth>
so you need to copy the right languages and not the wrong ones to see it
dino_tutter has quit [Ping timeout: 246 seconds]
haku has quit [Server closed connection]
haku has joined #commonlisp
<nij->
got it
<aeth>
seems to come more from the functional programming side of programming, too
<aeth>
because you do avoid some mutation/setting with implicit return values
<aeth>
even though CL isn't particularly FP
nij- has quit [Killed (NickServ (GHOST command used by nij_!~jin@2001-b400-e3d0-9ed3-a862-be98-be81-6e82.emome-ip6.hinet.net))]
nij_ has joined #commonlisp
nij_ is now known as nij-
<nij->
This is less likely to be an answer. An FP lang should prevent data to be mutated in the first place.
czy has quit [Remote host closed the connection]
<random-nick>
maybe they're a holdover from instruction-based programming like assembly/machine code
<random-nick>
where expressions were added to make writing calculations easier into such a paradigm
<random-nick>
instead of starting off from expressions like lisp
<aeth>
seems like you need a smarter compiler, too? probably nothing by today's standards, of course
<aeth>
but you need to be able to see that e.g. this expression's return value is not being used