<_death>
why wouldn't use-foreign-library work? one thing you need to watch for is not to load multiple libraries that export the same names (like, I had some sdl and sdl2 programs and loaded them all to the same image, and oops things started to break.. ended up porting everything to sdl2)
<mfiano>
I'm primarily interested in having libc and ncurses coexist in the same project/package
<mfiano>
I am wrapping APIs from both
<mfiano>
Though there could be more, though probably nothing incompatible (all libraries in a base install of FreeBSD)
<mfiano>
I'm just not sure what best practice is for a multiple library wrapper project is. I haven't seen it done before.
<_death>
nothing special that I can think of
epolanski has quit [Quit: Connection closed for inactivity]
<Nilby>
mfiano: Once libraries are "loaded", it acts like a flat namespace [even if it's not]. You can use as many as you want. I don't use the :library flag, which you'd probably only need in special cases. You don't even have to "use" libc, although you can.
<mfiano>
If two functions of the same name exist, but I disambiguate by specifying the :library argument to defcfun, could there still be dynamic linker errors?
<mfiano>
I'm not sure how the single namespace corresponds to linking in C
<Guest74>
dbotton: if you're strings are the same as your function names, you can probably just call INTERN on the strings or FIND-SYMBOL just make sure the case is the same.
<Nilby>
mfiano: Most implementations on unix use something like dlopen, dlsym, under the hood, so you can usually assume it works like that.
<Catie>
Nilby beat me to it
<Nilby>
mfiano: macOS is weirder because it has hierarchical libs in strange places, but you can mostly ignore it, and windows you might have to manage your own DLLs.
<mfiano>
Thank you. I am actually writing very OS-specific code (assuming a specific implementation of libc for a specific version of FreeBSD)
<dbotton>
thanks all for the help. For now just using a format and symbol lookup, eventually I'll properly handle it
<dbotton>
thanks Guest74 I used something similar in the end
rotateq has quit [Quit: ERC (IRC client for Emacs 27.2)]
<Guest74>
np, any chance to show my terrible grammar.
<dbotton>
no issue my poor typing and grammar is famous (stroke, many languages I use in a day etc) thankfully I am mostly tolerated
Guest74 has quit [Quit: Connection closed]
<jmercouris>
I don't understand why the Loop macro has ACROSS and IN
<jmercouris>
why can't this just be extracted from us?
<jmercouris>
why should I care whether I am dealing with an array or a list?
<jmercouris>
s/extracted/abstracted
<Bike>
i think the original loop predates the general sequence type
<Bike>
It is unfortunate
<jmercouris>
I see
<jmercouris>
that would make sense in that case
waleee has quit [Ping timeout: 252 seconds]
euandreh has joined #commonlisp
notzmv has joined #commonlisp
random-nick has quit [Ping timeout: 265 seconds]
<hayley>
LOOP would have to generate 2^n loops to handle n generic sequences, or it could generate iterator objects, which would hinder static analysis.
Jing has quit [Remote host closed the connection]
Jing has joined #commonlisp
<scymtym>
SBCL supports (loop :for x :being :the :elements :of '(1 2 3) :do (print x)) but as Bike said, the standard was probably too early for something like that
<scymtym>
(and that uses sequence iterators like hayley said)
<hayley>
Oh, another option for compilation, assuming that sequences are either only lists or vectors, would be to inline the code to grab the next element into the loop. Or you could inline, and fall back to an iterator protocol.
<etimmons>
mfiano: IIRC, the presence of cffi-features:flat-namespace on features means that loading the same symbol from multiple libraries (and the :library flag to defcfun) won't work
euandreh has quit [Ping timeout: 240 seconds]
Jing has quit [Remote host closed the connection]
Jing has joined #commonlisp
Lycurgus has joined #commonlisp
euandreh has joined #commonlisp
epolanski has joined #commonlisp
<mfiano>
etimmons: Thanks
kingofcsu has joined #commonlisp
Guest64873 has joined #commonlisp
Guest64873 has left #commonlisp [#commonlisp]
karlosz has quit [Ping timeout: 256 seconds]
akoana has joined #commonlisp
karlosz has joined #commonlisp
karlosz has quit [Ping timeout: 260 seconds]
Lycurgus has quit [Quit: Exeunt]
karlosz has joined #commonlisp
Jing has quit [Remote host closed the connection]
Jing has joined #commonlisp
Oladon has joined #commonlisp
taiju has quit [Ping timeout: 256 seconds]
<beach>
Good morning everyone!
anticomputer_ is now known as anticomputer
taiju has joined #commonlisp
kingofcsu has quit [Quit: kingofcsu]
Bike has quit [Quit: Lost terminal]
kingofcsu has joined #commonlisp
Bike has joined #commonlisp
semz has quit [Ping timeout: 265 seconds]
Guest74 has joined #commonlisp
semz has joined #commonlisp
kingofcsu has quit [Quit: kingofcsu]
peterhil_ has quit [Remote host closed the connection]
Oladon has quit [Quit: Leaving.]
Catie has quit [Quit: sQuit]
kingofcsu has joined #commonlisp
tyson2 has quit [Remote host closed the connection]
epolanski has quit [Quit: Connection closed for inactivity]
aartaka has joined #commonlisp
Jing has quit [Remote host closed the connection]
Jing has joined #commonlisp
<phantomics>
A question: say I have a macro that interns a symbol in a package: (intern-sym |foo|) interns the symbol foo in package :this-package
<phantomics>
I have another macro that builds a lexical variable assignment using the intern-sym macro: `(set (intern-sym |foo|) :something)
kingofcsu has quit [Quit: kingofcsu]
<phantomics>
Is there any way to make this work? (set) always sets a dynamic variable, but (setq) needs a quoted symbol, and I can't have the (intern-sym) macro quoted to expand it
Bike has quit [Quit: Connection closed]
kingofcsu has joined #commonlisp
Spawns_Carpeting has quit [Quit: WeeChat 3.3]
treflip has joined #commonlisp
<beach>
I don't know what counts as working, but why is the first macro a macro and not a function?
Colt has quit [Quit: Leaving]
<mfiano>
I have the same question. Given your description, I see no reason for the first macro to not be a function, as it doesn't provide any syntactical abstraction nor does it offer any evaluation control.
<mfiano>
Never use a macro when a function will do.
<mfiano>
Well actually that is a bit wrong. Is the first macro a macro simply to avoid quoting its symbol argument? I am curious why you are effectively interning it into two packages by not using a string.
<mfiano>
If the answer is yes, it is a syntactic abstraction, but it feels like a questionable one to me.
frgo has quit [Ping timeout: 265 seconds]
gaqwas has joined #commonlisp
kingofcsu has quit [Quit: kingofcsu]
Cymew has joined #commonlisp
notzmv has quit [Ping timeout: 240 seconds]
akoana has quit [Quit: leaving]
Algernon69 has joined #commonlisp
<frodef>
Good morning all. I'm setting up a web-application, using sbcl, git, emacs, linux. Does somebody have a pointer or two to setups/ideas for deployment? (meaning, having "finished" code on my laptop or wherever, having that code run on the server(S))
<frodef>
... preferrably keeping the server as a standard lisp image with full development REPL and such.
<jackdaniel>
frodef: make it a cli app with net.didierverna.clon (with options) and start a local swank server (listening only for local connections)
<jackdaniel>
then tunnel via ssh to your host
<jackdaniel>
people usually put (i.e hunchentoot) behind nginx
<jackdaniel>
for remote debugging you probably need to set slime source code path translations, otherwise M-. won't work (I don't remember how to do that though - only that it can be done)
<frodef>
jackdaniel: thanks!
<jackdaniel>
also if you want to restart the application after crash you may write a systemd unit
<jackdaniel>
alternative approach, somewhat easier, is to start emacs in tmux and start the from it, then detach from it
<frodef>
is nginx over hunchentoot for performance/scaling, or are there security concerns?
<jackdaniel>
I think that it is for both; I'm having nginx because I'm hosting other websites behind standard http ports
<frodef>
so public https to nginx and plain httb to hunchentoot behind that?
<frodef>
s/http
<jackdaniel>
yeah
<jackdaniel>
but if I weren't hosting "traditional" things I'd probably go straight to hunchentoot until it breaks :)
makomo has quit [Ping timeout: 265 seconds]
<frodef>
right.
<jackdaniel>
McCLIM is such a useful thing to help visualising things while working on them: https://i.imgur.com/wmSngTc.png
<beach>
Indeed.
<jackdaniel>
writing throwaway code is easy enough that you don't feel grief about throwing it away :)
<frodef>
jackdaniel: that image reminds me a lot of when I was using Franz' CLIM to visualize lisp objects in the "virtual" movitz image :-)
edgar-rft has quit [Quit: Leaving]
<jackdaniel>
heh, it is handy to see things
<frodef>
good morning beach
<jackdaniel>
often subtle mistakes are glaring obvious when put in a drawing
* frodef
is learning tmux...
shka has joined #commonlisp
xsperry has quit [Ping timeout: 240 seconds]
Alfr has quit [Killed (molybdenum.libera.chat (Nickname regained by services))]
Alfr has joined #commonlisp
treflip has quit [Remote host closed the connection]
<phantomics>
Inside the (in-pkg) macro, all symbols inside (inpkg) macros are interned in the 'foo package
<phantomics>
Because foo is the second argument to the (in-pkg) macro
<phantomics>
This functionality is needed for the compiler I'm building; problem is, (setq) will quote its argument, so '(inpkg |var|) is not expanded
<mfiano>
The reader is interning |var| into the package that form is in before macroexpansion time, so you are interning into two different packages?
<phantomics>
Yes
<mfiano>
Quite odd
<phantomics>
This is for the April compiler, in APL variables are dynamic or lexical depending on the context they're assigned, so it gets complicated assigning them
<lisp123>
phantomics: This is not an answer, but sometimes you can look at the macrofunction a macro calls (in this case setq), and call that directly
<mfiano>
Side note, you shouldn't use SETQ. Use the more generic SETF instead.
<phantomics>
lisp123: that's an option, could a custom setf method work here?
<mfiano>
What does inpkg look like?
<lisp123>
phantomics: And (sorry to ask the second time), this didn't work? `(set ',(intern-sym |foo|) :something-cool)?
<phantomics>
lisp123: That won't work because of when macroexpansion happens
<lisp123>
I guess it will macro expand INTERN-SYM and not evaluate right then (but I'm rusty on macros), so it might be better to write intern-sym as a function as noted earlier
<phantomics>
And (set) only sets dynamic vars correct? This is for lexical vars
<phantomics>
The irritating thing here is that the expansion must happen after the top-level (in-pkg) macro expands, before that the (intern-sym) macro doesn't know the package to intern into
<lisp123>
You could hack something in by using ,(eval ...), but you didn't hear that from me
<phantomics>
Yeah, not my favorite approach
<lisp123>
So I think you need to find the underlying functions of INTERN-SYM and access them directly vs. via a macro
<phantomics>
Oh, and this is inside a (let) form with lexical vars, so doing an (eval) in there won't assign them
<lisp123>
Good point
* mfiano
goes back to work since his help is not needed
<lisp123>
Is there any reason for keeping INTERN-SYM as a macro?
<phantomics>
The reason for (intern-sym) to be a macro is that I'm producing code that is supposed to be "package-neutral" except for that top-level (in-pkg) macro that specifies what package all the variables are in
<phantomics>
Otherwise the compiler has to know what package everything must be interned in and pass that package value down as it descends into the code it's compiling
<phantomics>
Perhaps that's a simpler way to do things after all, also not interning the symbols until the top-level macro expands makes for more elegant-looking code
<lisp123>
Can you use keywords for that purpose (package-neutral)?
<lisp123>
I guess the colon is pretty annoying
<phantomics>
I could, that's kind of neither here or there though, I need to wrap the variable symbols in a macro that will expand to intern them in the proper package as determined by the top-level macro, so they can be keywords or not, doesn't make much difference
<lisp123>
Can you use a wrapper of in-package?
<phantomics>
Hmm... I can see about that
<phantomics>
I'd have to bookend the compiled code with (in-package :compiled) and then (in-package :main) to go back to the main package right?
<lisp123>
Yes I think so
<phantomics>
Not the hardest thing to do
attila_lendvai has joined #commonlisp
<phantomics>
I can try that, see if there's any hidden pitfalls (there will be)
notzmv has joined #commonlisp
<phantomics>
One problem is that in the compiled code, I reference lots of functions that exist in the main :april package
<lisp123>
I am pretty bad at these things, but if there's a way to switch the current package to the one you do at READ time, that would be better
<phantomics>
So you've got stuff like (april:shape (inws a) (inws b)), the shape function belongs to the april package
<lisp123>
You can :USE :APRIL there?
<lisp123>
I think that kinda fits in with CL approach where packages generally :USE :CL
<phantomics>
I could use April in the workspace package, but the problem is what if someone assigns a function called SHAPE? Then the (shape) function in the main package is overloaded and it will be very hard for the user to figure out what went wrong
<lisp123>
Perhaps some form of package lock?
<phantomics>
Yeah, I could forbid them from it somehow, but then the SHAPE variable is not available for assignment and the reason why would be so confusing to an average user
<phantomics>
There is one other way to do this, but it's extremely inefficient: it requires re-consing every piece of April code that gets processed by the (in-pkg) macro
<lisp123>
Have a function streamlines the process for the user to shadow SHAPE
<phantomics>
That just seems like an extremely clumsy solution, there are a bunch of names like TURN, ENCODE and SCAN that would also be forbidden
<phantomics>
I may just have to re-cons the entire compiled code, at least it's happening at compile time and not runtime
<phantomics>
I can re-cons the code and replace instances of (inws ...) with appropriately interned variables, that way there's no fussing with these weird assignment cases
<lisp123>
Back to your original question, what if you tried something like this (let ((symbol (intern-sym |foo|)) `(set ',symbol :something))
<phantomics>
(set) only sets dynamic vars, not lexical ones
<phantomics>
One of the reasons lexical vars have tricky limitations (like you can't check them with (boundp)) is that the compiler can optimize them away, if you took away their limitations then a lot of potential compiler optimizations would be impossible
<lisp123>
Got it, thanks (learnt something new on SET)
<phantomics>
I suppose in the scheme of things, even as big as April code can get re-consing it won't cost that much in time or memory, and it's done at compile time so runtime is unaffected
treflip has quit [Read error: Connection reset by peer]
<lisp123>
That just seems like an extremely clumsy solution, >> You could store the user defined functions separately from normal functions and check for them first before checking for a normal function
<lisp123>
Sorry I haven't been able to help. Hopefully someone else does. But as a parting comment, I think the package system is very well designed, so IMO don't discount the idea of shadowing symbols too quickly
<lisp123>
Like if a user wanted to overload the SHAPE function, it would be confusing to someone else thinking it was April:Shape and Superuser:Shape
<lisp123>
So forcing that onto the user as an explicit consideration is not that bad of an idea. But I'll shut up now :)
<phantomics>
Oh, here's another issue with (in-package)
<phantomics>
April actually uses two different packages for every workspace, one for dynamic vars and one for lexical vars
<phantomics>
This is to maintain a needed distinction between the two for compilation purposes
xsperry has joined #commonlisp
<phantomics>
It's weird, I know, but some people have considered APL an uncompilable language because of its quirks. I have it compiling but my old method depended on undefined behavior (destructive modification of a form passed to a macro)
<lisp123>
Makes sense, that will make in-package not very useful to use
<phoe>
why destructive though?
<phantomics>
So remember how I said the brute-force solution is to re-cons the entire form?
<phoe>
were you depending on side effects?
<phoe>
like, you walked the form and mutated it?
<phantomics>
What I used to do was have the top-level (in-png) macro just destructively modify the form with (setf) to assign the interned vars
<phantomics>
Yes
<phoe>
oh
<phantomics>
*(in-pkg)
<phoe>
walk the (copy-tree form) and return this
<phoe>
should be a simple enough mitigation
<phantomics>
That's the brute-force solution, re-cons the entire form
<phantomics>
And April's generated code can get massive
<phoe>
still, there is never a need to mutate the form that was passed into the macro if you can mutate its copy and return this instead
<phoe>
same results, no UB
mrvdb has quit [Quit: WeeChat 3.3]
<phantomics>
Yeah, that's the simple way to avoid UB, I'll see how the overhead looks
<phoe>
or use a pure re-cons function to avoid walking the tree twice
<phoe>
like, instead of COPY-TREE + SETF use a function that walks the tree once and substitutes the proper things
<phantomics>
Yes, that's what I was thinking
<phantomics>
I already walk it so I'll just build as I do
<phoe>
yesss
treflip has joined #commonlisp
pjb has quit [Remote host closed the connection]
cage has joined #commonlisp
Jing has quit [Remote host closed the connection]
Jing has joined #commonlisp
cosimone has joined #commonlisp
cosimone has quit [Remote host closed the connection]
cosimone 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
beach has joined #commonlisp
kevingal has joined #commonlisp
amb007 has quit [Remote host closed the connection]
rotateq has joined #commonlisp
amb007 has joined #commonlisp
karlosz has quit [Ping timeout: 256 seconds]
random-nick has joined #commonlisp
<mfiano>
Dumb question, but I can't seem to get this to work: How do I define a condition that inherits from error, with no slots, but which can pass an arbitrary format string and arguments like cl:error?
<mfiano>
I've been away from code too long it seems. I keep getting a runtime error when signalling the condition: error: odd-length initializer list
VincentVega has joined #commonlisp
<mfiano>
Oh phoe is back in town. Save me please :)
<rotateq>
maybe he's busy at work day right now :)
<mfiano>
Very likely, because that's usually the time I am ready to go to bed.
<jackdaniel>
mfiano: the function error is more or less: (defun error (fmt-string &rest args) (signal 'error :format-control fmt-string :format-arguments args))
<jackdaniel>
+/- universal handlers, fancy datums and all that jazz
<mfiano>
jackdaniel: Similar to how I can do (error "foo ~d ~d" 42 43) I would like to know how, if possible, to be able to do (error 'my-condition-that-inherits-from-error "foo ~d ~d" 42 43) - I'm not quite sure how to define the lambda expression for the report.
<rotateq>
hm mfiano, are you from australia? ^^
<mfiano>
No
<jackdaniel>
mfiano: not really, but you can (error 'my-error :format-control "format string ~s" :format-arguments (list 42)) /if/ your condition subclasses both error and simple-conditino
<rotateq>
okay for this time i just have in mind that someone from australia is going to sleep
<jackdaniel>
mind that simple-error is the right superclass that has both simple-condition and error as its superclasses
<mfiano>
I see, so there would be no way to just pass a format string and variadic arguments with a regular report function
<jackdaniel>
you may define your own function, i.e my-error, but generally yes- without dipping into implementation-specific behavior you can't tweak error that way
<mfiano>
Fair enough, thank you.
<jackdaniel>
sure
<phoe>
mfiano: inherit from simple-error
<phoe>
it, in turn, inherits from simple-condition which necessarily has slots for format-control and format-arguments
<phoe>
welp, already answered, sorry
kevingal has quit [Remote host closed the connection]
<lisp123>
rotateq: now would be the time for most Australians to sleep
<rotateq>
lisp123: and not for us yet
<jackdaniel>
I wonder, can the result of compute-applicable-methods be also memoized by compute-discriminating-function (even when the generic function is not a standard-generic-function and c-a-m-u-c returns nil as a second value)?
<jackdaniel>
the name compute- suggests that it could; the thing is that the mop specification doesn't tell (at all) focusing only on the part that if c-a-m-u-c returns the second value as t then its result can be memoized
<lisp123>
rotateq: the day is young for us:)
<jackdaniel>
this is similar to compute-effective-method - it is not explicitly stated that we can memoize results, but earlier in the amop book compute-effective-method-function (predecessor of c-e-m) is invited precisely to allow that
<jackdaniel>
s/invited/invented/
<mfiano>
Thanks phoe. That is indeed better than inheriting from both
<scymtym>
but keep in mind the dual inheritance variant in case you ever want a warning with similar behavior
<mfiano>
Yeah sort of. Originally only needed to output a number to stdout for my statusbar to consume, but got carried away with terminal hacks^Wfun
<mfiano>
It uses varying width unicode vertical bars to give a more smooth animation illusion, instead of full-width character "frames"
<lisp123>
mfiano: Nicely done
<lisp123>
I need to get FreeBSD next year, might use it then
<phoe>
scymtym: cl:simple-warning
<phoe>
:D
<mfiano>
I am thinking about overengineering this into a htop-like thing though, with per-core usage and all
<jackdaniel>
I'm sure that he meant simple-style-warning, because that one is missing
<jackdaniel>
alexandria gives that
<mfiano>
Depends how bored I get before then :)
<phoe>
jackdaniel: yes, I see - alexandria also provides some others AFAIR like simple-program-error
<scymtym>
phoe: hm, i somehow thought that didn't exist. maybe it was SIMPLE-STYLE-WARNING
<jackdaniel>
but it is never that simple, is it? errors, warnings, all are a sign that something is not right
tyson2 has joined #commonlisp
<phoe>
yes, see jackdaniel's response
<phoe>
jackdaniel: actually, errors themselves can be and often are simple, it's their reasons that are complex
<jackdaniel>
perhaps I say too many random things so people start to skim over what I write (second time today!)
<phoe>
like, have you ever spent a while imagining how many complexities need to occur in a specific order for your code to finally go (error "it broke :(")
<scymtym>
it gets a bit complicated when you want to signal appropriate conditions, possibly with source location information, for problems detected at compile time, for example from macros or compiler macros
kingofcsu has joined #commonlisp
edgar-rft has joined #commonlisp
Posterdati has quit [Ping timeout: 250 seconds]
<beach>
jackdaniel: You are not allowed to memoize the result of COMPUTE-APPLICABLE-METHODS in general, because the AMOP does not explicitly say you are. However, there are situations where conforming code can not observe whether you have memoized anyway, so in those cases it is safe.
<jackdaniel>
thanks,
<jackdaniel>
I'm aware of the latter case. Regarding memoizing the result of COMPUTE-APPLICABLE-METHODS in general -- isn't this the same situation as with compute-effective-method ?
<jackdaniel>
amop doesn't explicitly say that you are allowed to memoize it
<beach>
I don't think it is the same.
<jackdaniel>
how so?
<beach>
The effective method can be defined to always call COMPUTE-APPLICABLE-METHODS-USING-CLASSES and COMPUTE-APPLICABLE-METHODS. Then it will never change. Or it can cache the result of COMPUTE-APPLICABLE-METHODS-USING-CLASSES but not COMPUTE-APPLICABLE-METHODS.
<beach>
And then it needs to change with COMPUTE-APPLICABLE-METHODS-USING-CLASSES.
<jackdaniel>
do you mean discriminating function by chance?
<beach>
Er, sorry, yes.
<beach>
The discriminating function can be defined to ....
<beach>
I don't see that there is anything that COMPUTE-DISCRIMINATING-FUNCTION could itself memoize that is not one of the other two.
<jackdaniel>
it could also memoize compute-effective-method (given that c-a-m-u-c is memoized) - we've talked about this a few days ago on #sicl
Posterdati has joined #commonlisp
<jackdaniel>
(I've suggested that you could add a "remark" to the mop specification on your website, but you've said that it is obvious so there is no need to add it)
<beach>
I do not understand what it means for one function to memoize the result of calling another function. To me "memoize" means look up, as opposed to compute, a result from a bunch of arguments. In this case, it would simply incorporate the result of calling COMPUTE-APPLICABLE-METHODS into its discriminating function. And that is fine as long as the discriminating function is recomputed when required.
attila_lendvai has quit [Quit: Leaving]
voltron has joined #commonlisp
<beach>
... and of course, given the same restrictions as before, that no conforming program can observe whether COMPUTE-DISCRIMINATING-FUNCTION is invoked.
<jackdaniel>
can the discriminating function look up, as opposed to compute, the effective method?
<beach>
It should, when it is allowed to.
<jackdaniel>
and when it is allowed to look up the effective method?
<beach>
When the classes of the arguments are such that COMPUTE-APPLICABLE-METHODS-USING-CLASSES are allowed to cache the result, and when no conforming program can observe that it may look up the effective method anyway.
<beach>
s/are allowed/is allowed/
attila_lendvai has joined #commonlisp
<jackdaniel>
compute-effective-method may be overriden, so compute-discriminating-function may look it up only when the function is exactly standard-generic-function then?
Bike has joined #commonlisp
<beach>
I haven't worked out all those details, but that sounds right.
<phoe>
jackdaniel: are eql specializers on C-E-M not going to be a problem? a function can be a direct instance of S-G-F but there can be a method with an eql specializer
<phoe>
like, (eql #'foo) where #'foo is a standard-generic-function
<jackdaniel>
I don't understand
<beach>
phoe: That would not be conforming.
<phoe>
beach: OK, that's a relief
<beach>
phoe: Conforming code is not allowed to add methods that would be applicable to arguments with only specified classes.
<beach>
And in fact, that's an implicit rule for any protocol.
<beach>
jackdaniel: I need to vanish for 30 minutes or so. I'll read up when I come back.
<phoe>
beach: is that ANSI CL or MOP? is that only for standard classes?
<phoe>
beach: OK
<beach>
phoe: It is for "specified classes" no matter which protocol does the specification.
<jackdaniel>
beach: on the other hand compute-effective-method-function was introduced earlier in the book in closette to allow memoizing the result (and later it was generalized and specified as compute-effective-method) - that's why I was arguing a few days back that compute-effecitve-method is memoizable by compute-discriminating-function
<jackdaniel>
at least that was rationale for exposing this part of the protocol
<beach>
I still don't understand what it means for the result of one function to be memoizable by another function.
<beach>
Anyway, off for real.
<jackdaniel>
well, that seems to be a communication barrier I can't force; I don't have much to add on the subject. thank you for bearing with me
<phoe>
beach: I need to figure this one out; 7.6.6.1.2, fourth paragraph, says that EQL-specializers cause precedence over methods without EQL-specializers, and I read your words that e.g. (defmethod foo ((x number)) nil) (defmethod foo ((x (eql 42))) t) would not be conforming code
<phoe>
even though in my understanding (foo 42) should return T
<jackdaniel>
I think that this is a communication barrier, this is conforming code
<phoe>
oh, OK
<jackdaniel>
you are not allowed to define a method add-method specialized on standard-generic-function
<phoe>
yes, since that is a standard GF with all standard specializers
<jackdaniel>
I think that this is what beach meant, but that's only a guess (I was once called for putting words in his mouth, so I'll leave it to him to explain)
<phoe>
but can I DEFMETHOD ADD-METHOD with the function being (EQL #'FOO) where FOO is something I've made myself?
<phoe>
my understanding is that I can
<jackdaniel>
I think that this wouldn't be conforming, because you define a method on an object of the class for which you can't define methods
<phoe>
hence my question, in case of (DEFMETHOD C-A-M ((GF (EQL #'FOO) ...)) ...)
<phoe>
if FOO is something I have defined myself, *even* if it is not a direct instance of class I have defined myself
<phoe>
how do we treat this case?
<jackdaniel>
the premise of standard-generic-function is that you may bypass usual mechanisms for computing the discriminating function and i.e use internal function (that is not generic) std-compute-discriminating-function
<jackdaniel>
this allows you to avoid some metastability issues
<jackdaniel>
and this function may not even call your c-a-m at all, so this specialization will have no effect
_73 has joined #commonlisp
<jackdaniel>
it is undefined behavior, you may end up in some kind of a strange place too
<phoe>
my question is less about S-G-F itself and more about CLHS 11.1.2.1.2 point 19
<phoe>
and I guess the wording is that EQL specializers also fall under this
<phoe>
like e.g. (defmethod print-object ((object (eql 42)) stream) ...)
<phoe>
that's obviously UB zone, and also describes what would happen if someone did a (defmethod c-a-m ((function (eql #'foo)) ...) ...)
<phoe>
because 42 is a direct instance of a standardized class, and so is a standard generic function #'FOO
<phoe>
and both print-object and c-a-m are standardized generic functions
<phoe>
OK, understood - thanks for the help
<flip214>
Is there a Hunchentoot-equivalent library for HTTP/3?
kingofcsu has quit [Quit: kingofcsu]
<_73>
how often does quicklisp pull changes from a projects master branch?
<flip214>
_73: by request, for some monthly.
<phoe>
every dist update, which happens monthly
<_73>
ok thanks
<phoe>
unless there's a request which warrants creating a separate non-monthly dist, e.g. for critical bugs in libraries
<phoe>
(widely used ones, that is)
voltron has quit [Remote host closed the connection]
waleee has joined #commonlisp
xsperry has quit [Remote host closed the connection]
<beach>
So let me say this without using the word "memoize" (or "memoization"). If the specification says that a function F, whenever invoked, must call a function G, then F can avoid calling G only if it has some other way of determining what G would return AND no conforming program can detect that G was not called in this situation.
<beach>
phoe: I think the AMOP states this rule explicitly, but the Common Lisp standard does not. And the AMOP is not entirely correct about it either as I recall.
<beach>
phoe: And it is a default rule, so the specification can obviously make explicit exceptions.
<phoe>
beach: I think CLHS 11.1.2.1.2 point 19 states this explicitly
<beach>
Good.
<beach>
So what's the problem?
<phoe>
none! I already got my answer
<beach>
Ah, OK.
<phoe>
thanks
<_73>
would G need to be referentially transparent?
s-liao has quit [Quit: Client closed]
<beach>
_73: F can use any technique it wants to determine what G would have returned, but referential transparency would be a sufficient (but not necessary) condition.
frgo has joined #commonlisp
<_73>
I see
<beach>
jackdaniel: Let me (*sigh*) go check the details of the generic-function invocation protocol.
<beach>
jackdaniel: The AMOP states that COMPUTE-DISCRIMINATING-FUNCTION is called whenever a generic function metaobject is initialized, reinitialized, or a method is added or removed.
<beach>
But it can be called for other reasons as well, apparently.
* beach
is still reading.
<beach>
jackdaniel: The specification says that the effective method is called by the discriminating function, and does not give any circumstances where this call can be avoided.
<rotateq>
discriminating sounds not so political correct ^^
<phoe>
rotateq: let's use the original meaning of that word
<Bike>
there's no way a serious clos invocation is going to call compute-effective-method on every discriminating function call.
<Bike>
a serious clos implementation*
<phoe>
beach: the effective method is called, but not computed
<phoe>
the question is about computing rather than calling, I think
<beach>
jackdaniel: So, it seems to me that the discriminating function is allowed to avoid calling COMPUTE-EFFECTIVE-METHOD only when the generic function is a STANDARD-GENERIC-FUNCTION.
<Bike>
that would make non standard generic functions very slow.
<beach>
Yes.
<beach>
I am just reading the specification here.
<Bike>
this is why i believe that compute-effective-method can be implicitly understood to be a pure function. if it is, its result can be memoized, similarly to how the result of compute-applicable-methods-using-classes can be memoized.
<Bike>
(the word "memoized" being used as it is in the mop page on compute-discriminating-function)
<jackdaniel>
beach: but in amop, earlier (page 126) a function compute-effective-method-function is introduced under the chapter "improving performance", and quoting "by constraining the context c-e-m-f (...) we make it memoizable"
silasfox has joined #commonlisp
<jackdaniel>
and this function was a stub that was later replaced by compute-effective-method in the final protocol
<jackdaniel>
imo it is a very strong indicator that this function was at least meant to be memoizable
<beach>
jackdaniel: I am reading only the specification.
silasfox has quit [Client Quit]
<beach>
It would seem silly to require the discriminating function to always call COMPUTE-EFFECTIVE-METHOD when the method combination and the applicable methods are known.
silasfox has joined #commonlisp
<Bike>
amop was billed as a work in progress, so i'm pretty willing to treat the specification as having flaws to be fixed
silasfox has quit [Client Quit]
<jackdaniel>
well, I'm also reading the rationale behind introducing operators
<beach>
Absolutely.
silasfox has joined #commonlisp
_73 has quit [Remote host closed the connection]
<beach>
jackdaniel: If I were you, I would just state that the ECL implementation is allowed to avoid calling COMPUTE-EFFECTIVE-METHOD.
<jackdaniel>
rather that it is allowed to remember the result
<beach>
jackdaniel: I think I'll do the following (at some point). I'll re-read the phrase on page 126, and stick that in as a note.
<beach>
How about that?
<jackdaniel>
sounds good, that's what I've tried to suggest the other day (but you've said that it is obvious, apparently it is not)
<beach>
It turns out not to be. I confused calling compute-applicable-methods-using-classes and compute-effective-method.
<beach>
Sorry about that.
<jackdaniel>
no problem
<beach>
jackdaniel: Yes, in trying to avoid the word "memoize" I shortened "avoid calling G and instead use whatever means it has at its disposal to determine what G would have returned, had it been called", to "avoid calling G".
<rotateq>
phoe: yes, this is much more a good intention :)
<jackdaniel>
I think that the word memoize is perfectly clear and I still don't have an idea why it didn't make sense to you earlier :|
<Bike>
incidentally, if anyone happens to know of any real system that specializes compute-effectiv-emethod, i would be interested in seeing it
<Bike>
custom method combinations can include totally arbitrary code, so it's hard to imagine why one would bother
<phoe>
Bike: closer-mop doesn't count I think
<beach>
jackdaniel: Because "memoize" is used about one single function to replace a computation by a lookup when its arguments have been seen before and the result of the computation is known to be the same as that last time.
<beach>
jackdaniel: So I don't know what it means for a function to "memoize" the result of a call to another function.
<jackdaniel>
yes, that's what I mean when I use this word
<beach>
"cache" OK, but "memoize" no.
<jackdaniel>
well, it means that it avoids calling that another function because it remembered results and may perform a lookup
<beach>
jackdaniel: Oh, but then COMPUTE-EFFECTIVE-METHOD would indeed have to be called and it, itself, would have to return the cached value.
<jackdaniel>
even in amop spec it is used in such context (i.e for compute-discriminating-function)
<beach>
I am sorry to hear that.
Jach has quit [Read error: Connection reset by peer]
<beach>
Another evidence that the AMOP is not as good as it should have been, perhaps.
<jackdaniel>
but oh well, I'll try to avoid this word when talking to you
<beach>
Thank you.
silasfox has quit [Quit: WeeChat 3.3]
<phoe>
Bike: can't see it on github yet, just implementation sources
<Bike>
eh?
<Bike>
oh, you mean you're searching.
<beach>
jackdaniel: The Wikipedia page on "memoization" seems to agree with my definition.
<jackdaniel>
I find your definition correct
<phoe>
Bike: yes
<jackdaniel>
I think that the problem with understanding is that I find use that "A memoizes the result of B" also clear and in line with this definition (in amop text and in my earlier utterances)
<jackdaniel>
either way what I've said earlier was trying to make a parallel that just as compute-effective-method has the qualities as closette's compute-effecitve-method-function we could draw a similar conclusion about compute-applicable-methods "inheriting" qualities of compute-applicable-methods-using-classes;; that said I'm much less convinced about the latter :)
attila_lendvai has quit [Ping timeout: 245 seconds]
<beach>
jackdaniel: Yes, I understand now.
<beach>
jackdaniel: Oh, I have a watertight proof that COMPUTE-EFFECTIVE-METHOD absolutely can not be called from the discriminating function each time.
<beach>
jackdaniel: Because COMPUTE-EFFECTIVE-METHOD is itself a generic function, so it would have to call itself each time it is invoked.
<beach>
It could still work by the usual exception to the rule for standard-generic-function of course.
<jackdaniel>
sure, but I think that we have estabilished that for instances whichc class is EQ to standard-generic-function we may do any number of things until the user doesn't notice
yewscion_ has joined #commonlisp
<jackdaniel>
I think that until isn't the right word, perhaps "unless the user can notice it"
<beach>
Right, that's what I meant to say by the "usual exception".
<phoe>
it's only missing an author/timestamp at the end if we want to follow the format set by the first remark
<beach>
Pleasure. Sorry again for being so dense.
<beach>
phoe: Good point. On it...
<phoe>
beach: not really dense, communication is as usual a hard problem
<jackdaniel>
I will also experiment a little with /doing the same thing as done for compute-applicable-methods-using-classes when the second value is t/ for compute-applicable-methods and see if it gets me somewhere
<beach>
phoe: It is, but I know for a fact I take a long time to understand things. But I know how to deal with it, so no problem.
<beach>
phoe: author/timestamp added.
<phoe>
beach: thanks!
<beach>
phoe: Sure. Important stuff.
Guest74 has quit [Quit: Connection closed]
jaimelm has quit [Ping timeout: 256 seconds]
pdietz has joined #commonlisp
Cymew has quit [Ping timeout: 250 seconds]
Cymew has joined #commonlisp
jaimelm has joined #commonlisp
attila_lendvai has joined #commonlisp
Spawns_Carpeting has joined #commonlisp
<rotateq>
beach: Accidentally I have been reading your cliki site yesterday again. We talked about the FFT implementation some months ago but I would be curious how to get it really fast, elegant AND still safe, like the FFTW with OCaml.
attila_lendvai has quit [Quit: Leaving]
<beach>
rotateq: I haven't worked on FFT for some time. But there are two aspects to it. The algorithmic aspect and the use of appropriate machine instructions.
<beach>
When I was still working on it, only the first aspect was necessary.
attila_lendvai has joined #commonlisp
<beach>
rotateq: Maybe you could use heisig's work on SIMD for the second aspect.
<rotateq>
I finally got something to work finally when I first asked, but must go on and from a simple to a generic-function. and substituted some *aweful* CL solution for it on a well-known code page :)
taiju has quit [Ping timeout: 252 seconds]
taiju has joined #commonlisp
<rotateq>
oh right, i told heisig to read more about SIMDs, but don't know how to start in a good way (ok, maybe wikipedia). and petalisp of course still more
<rotateq>
and right, getting correct things is most important. not "it doesn't work right, but it's fasta!"
<beach>
Sure.
<beach>
With some algorithms, you can completely unfold sub-computations of small-ish fixed sizes. Then you can minimize the number of operations for those.
<rotateq>
like I don't care when telling people I like figuring out things like rubik's cube and the first thing they are just interested in is the "speed". was never about speed for me
<rotateq>
oh nice, have much to learn and there are so many practical uses with such transforms too of course like image compression
Guest74 has joined #commonlisp
<beach>
And I had some insight at the time, where a fixed radix is not optimal, but it can be implemented using a preceding shuffle, whereas a radix of √n is optimal, but I never figured out a good way to implement it.
<rotateq>
okay no pressure on it as you do so many other very impressive things
<beach>
Given the cost of memory reads and writes, it would also be interesting to take into account such cost, compared to the cost of arithmetic operations.
<rotateq>
ah yes
<beach>
I actually taught the applied-mathematics people at the time about recursion, and was able to publish the by far fastest shuffle algorithm at the time, together with Anne Elster.
<beach>
It was surprising to me how ignorant the entire community was about recursion. And for shuffle, with recursion it was possible to avoid exchanging elements with themselves without any additional tests.
<rotateq>
can you point where to read about it?
<beach>
I think there is better stuff now.
<rotateq>
yes about 30min a friend called and we came to it and i had to explain a bit why recursion is such a powerful concept
<beach>
I showed this to Anne, and she handled the community stuff which I was unfamiliar with. But she then went on to publish even better algorithms.
<rotateq>
Ack beach, but this doesn't make the older things still interesting.
<beach>
I have this feeling that our paper is in one of those Elsevier journals or conferences, so that it is completely inaccessible.
<beach>
Let me check...
<rotateq>
Hm and about a site like scihub?
<rotateq>
but okay, there are still other papers of you i should read
<beach>
Look for the paper "A Super-Efficient Adaptable Bit-Reversal Algorithm for Multithreaded Architectures" by Anne C Elster and Jan C Meyer.
<beach>
The second entry in the bibliography is the paper by Anne and me that I was referring to. But I don't think ours is available anywhere.
<beach>
It was also presented at a SIAM conference.
<rotateq>
i saw an "Irene" is also co-author of you
<rotateq>
ok thx
<beach>
Sure idurand is my favorite coauthor. :)
<beach>
We worked on several ELS papers together.
<rotateq>
have it, from 2009
<rotateq>
that's cool, more women should go into computer science
makomo has joined #commonlisp
<rotateq>
Do you have a presentation for next ELS? maybe about SICL
<beach>
Me and idurand are going to submit a paper. Whether there will be a presentation or not is then up to the referees. :)
<rotateq>
maybe in some years I can too if something interesting comes to my mind
<beach>
But idurand is going to be added as a coauthor, and I will be marked as "unaffiliated".
<rotateq>
maybe some day doing this GeoGebra clone with McCLIM
<rotateq>
hehe unaffiliated
<beach>
Yes, I retire before the conference takes place.
<beach>
You seem to have lots of projects. I guess that's good.
Cymew has quit [Ping timeout: 256 seconds]
<rotateq>
you think so? it's often the case to wrap ideas to a final thing, and learning more stuff
<rotateq>
i meant i fail to finalize things and as having many interests often something new comes up
<beach>
That's the downside of having too many projects, sure.
<rotateq>
yes it can be a curse being like me :)
<rotateq>
but I sharp the parentheses swords (the left and right) every day more
<beach>
Good.
<rotateq>
Last week the FORMAT directive "~@r" helped me much solving a 20% Project Euler problem, was happy. but in at least SBCL the limit for it seems to be 3999
<rotateq>
Have to go, talk later.
<jackdaniel>
and how does 4000 looks in roman numerals? :)
<hobo>
MMMM?
<jackdaniel>
almost, MHMM ;)
<jackdaniel>
perhaps with unicode you could do something like IV with a line above
iquites has joined #commonlisp
<Nilby>
Ⅳ̅ or I̅V̅ ?
<jackdaniel>
the latter
lisp123 has quit [Read error: Connection reset by peer]
waleee has quit [Ping timeout: 252 seconds]
waleee has joined #commonlisp
peterhil has joined #commonlisp
waleee has quit [Ping timeout: 240 seconds]
Oladon has joined #commonlisp
waleee has joined #commonlisp
Colt has joined #commonlisp
Guest74 has quit [Quit: Connection closed]
djuber has joined #commonlisp
tyson2 has quit [Remote host closed the connection]
Inline has joined #commonlisp
Core8044 has joined #commonlisp
yewscion_ has quit [Ping timeout: 252 seconds]
treflip has quit [Quit: good night ✨]
Jing_ has joined #commonlisp
Posterdati has quit [Ping timeout: 252 seconds]
Jing has quit [Ping timeout: 252 seconds]
waleee-cl has joined #commonlisp
waleee has quit [Read error: Connection reset by peer]
waleee-cl has quit [Client Quit]
waleee has joined #commonlisp
karlosz has joined #commonlisp
tyson2 has joined #commonlisp
karlosz has quit [Quit: karlosz]
Posterdati has joined #commonlisp
pranavats has left #commonlisp [Error from remote client]
pranavats has joined #commonlisp
Algernon69 has quit [Ping timeout: 260 seconds]
shka has quit [Ping timeout: 256 seconds]
rain3 has quit [Ping timeout: 252 seconds]
yewscion has joined #commonlisp
Core8044 has quit [Ping timeout: 252 seconds]
_73 has joined #commonlisp
lisp123 has joined #commonlisp
lisp123 has quit [Ping timeout: 240 seconds]
notzmv has quit [Read error: Connection reset by peer]
yewscion has quit [Ping timeout: 252 seconds]
nature has joined #commonlisp
theothornhill has joined #commonlisp
anticomputer has quit [Ping timeout: 276 seconds]
anticomputer has joined #commonlisp
aartaka has quit [Ping timeout: 240 seconds]
roelj has joined #commonlisp
aartaka has joined #commonlisp
anticomputer has quit [Ping timeout: 276 seconds]
anticomputer has joined #commonlisp
azimut_ has quit [Ping timeout: 276 seconds]
thomaslewis has left #commonlisp [#commonlisp]
tyson2 has quit [Ping timeout: 265 seconds]
karlosz has joined #commonlisp
Algernon69 has joined #commonlisp
azimut has joined #commonlisp
varjag has joined #commonlisp
thomaslewis has joined #commonlisp
thomaslewis has left #commonlisp [#commonlisp]
gaqwas has joined #commonlisp
xsperry has joined #commonlisp
tyson2 has joined #commonlisp
theothornhill has quit [Remote host closed the connection]
Algernon69 has quit [Ping timeout: 260 seconds]
aartaka has quit [Ping timeout: 256 seconds]
thomaslewis has joined #commonlisp
thomaslewis has left #commonlisp [#commonlisp]
thomaslewis has joined #commonlisp
thomaslewis has left #commonlisp [#commonlisp]
aartaka has joined #commonlisp
ahc has joined #commonlisp
<rotateq>
jackdaniel: SBCL doesn't like it so i just had to preparse the numerals and wipe out the leading Ms with correct subtracting ^^
<jcowan>
11.1.2.1.2 point 19 says: "Except where explicitly allowed, the consequences are undefined if any of the following actions are performed on an external symbol of the COMMON-LISP package: [...] Defining a method for a standardized generic function which is applicable when all of the arguments are direct instances of standardized classes." What does that have to do with memoization?
pdietz has quit [Quit: Ping timeout (120 seconds)]
roelj has quit [Remote host closed the connection]
<phoe>
jcowan: nothing in particular, I was curious about a possible edge case
<phoe>
and that edge case does not conform to the standard, so I don't need to worry about it
* jcowan
nods
<jcowan>
The motivation seems peculiar.
<phoe>
in particular, (defmethod compute-applicable-methods ((gf (eql #'foo)) ...) ...) where FOO is a STANDARD-GENERIC-FUNCTION breaks this point
Algernon69 has joined #commonlisp
Algernon91 has joined #commonlisp
thomaslewis has joined #commonlisp
euandreh has quit [Ping timeout: 260 seconds]
Algernon69 has quit [Ping timeout: 250 seconds]
* jcowan
notes that there are only 4 standard generic functions that are not part of the CLOS machinery: describe-object, print-object, make-load-form, and documentation.
aartaka has quit [Ping timeout: 250 seconds]
<pjb>
it's not that they are not part of the CLOS machinery. It's that for those standard classes, CL is allowed to implement direct function calls instead of using those generic functions.
<pjb>
jcowan: ie. print can call a print-cons and a print-integer, instead of using print-object on conses and integers.
Oladon has quit [Quit: Leaving.]
<jcowan>
By machinery I mean functions that construct, query, and mutate the CLOS heterarchy
<jcowan>
add-method, allocate-instance, change-class, initialize-instance, etc. Oh, function-keywords is another non-machinery GF.
<jcowan>
roughly speaking the parts of the MOP that were standardized
jeffrey has joined #commonlisp
euandreh has joined #commonlisp
varjag has quit [Ping timeout: 256 seconds]
euandreh has quit [Ping timeout: 260 seconds]
cage has quit [Quit: rcirc on GNU Emacs 27.1]
nature has quit [Ping timeout: 260 seconds]
Inline has quit [Quit: Leaving]
ahc has quit [Quit: Client closed]
kevingal has joined #commonlisp
Inline has joined #commonlisp
karlosz has quit [Ping timeout: 260 seconds]
zacts has joined #commonlisp
varjag has joined #commonlisp
euandreh has joined #commonlisp
Krystof has quit [Ping timeout: 265 seconds]
ahc has joined #commonlisp
varjag has quit [Quit: ERC 5.4.1 (IRC client for GNU Emacs 29.0.50)]
gaqwas has quit [Ping timeout: 256 seconds]
poselyqualityles has joined #commonlisp
Algernon91 has quit [Read error: Connection reset by peer]
Algernon91 has joined #commonlisp
jeffrey has quit [Ping timeout: 252 seconds]
poselyqualityles has quit [Ping timeout: 250 seconds]