<pjb>
Devon: yes, sorry, I need to reinstall the server with new ssl/tls keys…
yauhsien has quit [Remote host closed the connection]
yauhsien has joined #commonlisp
yauhsien has quit [Ping timeout: 256 seconds]
livoreno has joined #commonlisp
dcx has quit [Ping timeout: 248 seconds]
dcx has joined #commonlisp
yauhsien has joined #commonlisp
igemnace has quit [Remote host closed the connection]
Inline__ has joined #commonlisp
Inline has quit [Ping timeout: 260 seconds]
yauhsien has quit [Ping timeout: 272 seconds]
yauhsien has joined #commonlisp
Bike has quit [Quit: Lost terminal]
Bike has joined #commonlisp
Spawns_Carpeting has joined #commonlisp
tyson2 has joined #commonlisp
gko has quit [Remote host closed the connection]
<contrapunctus>
o/
gko has joined #commonlisp
knusbaum- is now known as knusbaum
<contrapunctus>
I'm getting a "no applicable method" error and I can't figure out why /o\
<contrapunctus>
The generic function is defined in package A (which exports the GF name), and the method that I expect to be run is defined in package B (which exports the method name)...
<Devon>
contrapunctus: and you're sure it's the correct name and package?
<contrapunctus>
...and the generic function is called in package C, which imports package A...is it that C is not importing from B? (but the method name would cause conflicts with A...)
<contrapunctus>
Devon: mostly definitely 🤔️
<contrapunctus>
I think package C not importing from B is probably the issue - if I call the generic function in B, it works; if I call it in C, I get the "no applicable method" error. But B is an optional dependency, it doesn't make sense to hardcode it...
<Devon>
Does B import A? What if you use explicit package prefixes?
<contrapunctus>
Devon: ah, B wasn't importing some names from A (just fixed this). But it seems I have to import B in C, which seems problematic again, because B is an optional dependency... 🤔️
<beach>
Good morning everyone!
<beach>
contrapunctus: I think there is some confusion here.
<contrapunctus>
(A is the common library defining the protocol and other things, B is one of many backend implementations, C is the frontend.)
<contrapunctus>
good morning, beach ^^
<beach>
contrapunctus: As long as the method definition in B refers to the symbol naming the generic function in A, C does not have to even know about B.
<Devon>
When I hear Y is a dependency of X, I wonder if they're speaking English (Y needs X) or Un*x (X needs Y) so I say "requires" which is less ambiguous.
<beach>
contrapunctus: Also, you had two generic functions. You did not "call the function from B", you called the functinon B:fun rather than the function A:fun.
<beach>
contrapunctus: If you use DEFMETHOD on an unknown generic function (in your case B:fun), then a new generic function is implicitly created. You should have seen a warning to that effect, I hope.
<beach>
contrapunctus: And, the fact that both A and B export some name, does not mean that the symbols are the same. In your DEFMETHOD form, you should make sure you refer to the symbol A:fun.
<beach>
contrapunctus: And I highly recommend you not :USE any packages other than the COMMON-LISP package.
<contrapunctus>
beach: re: :USE, not even for my own packages? 😶️
<beach>
Yes.
<contrapunctus>
Yikes, that's going to be tedious :(
<beach>
It is not a question about who is the owner. It has to do with maintainability.
<beach>
First, you want the person reading the code in C to be able to tell from which package external symbols originate.
<beach>
This is especially true since a package typically defines some protocol, and you would want the function names and class names from functions and classes in that protocol to be clearly marked, as in PROTO:<function-name> and PROTO:<class-name>.
occ has joined #commonlisp
<beach>
Second, you want your protocol package to be separately maintainable. If you add functionality to the protocol package, A in this case, you might want to export more names in the future. If you :USE A, then new exports can cause name conflicts in other packages.
<beach>
It gets even worse, if A is meant to be used by others.
yauhsien has quit [Remote host closed the connection]
yauhsien has joined #commonlisp
<contrapunctus>
Hm...
<beach>
I mean, your experience shows that things get complicated otherwise. Not even you yourself understood that the name in B did not refer to the name of the generic function in A.
<beach>
So how do you expect other people reading your code to see that?
yauhsien has quit [Ping timeout: 256 seconds]
<contrapunctus>
I see 🤔️
<contrapunctus>
Also, the "no applicable method" issue is fixed - package C and B both import from A. C doesn't need to know about B, as beach said. Thanks Devon and beach .
<beach>
Sure.
* beach
has the impression that his advice will not be taken into account, and that, as a result, we will see similar questions in the future.
<contrapunctus>
beach: I just finished removing `:package-a` from any `:use` forms ;)
<pillton>
I stopped USEing packages for those reasons a long time ago.
<pillton>
CL packages are possibly my least favourite part of the standard.
<beach>
I think they are great, but if one tries to use them as modules, then they don't work so well. So the combination of packages and first-class global environments is the best.
<pillton>
That is my view as well. Packages are great of organising stuff. It is just a shame they have global consequences.
<beach>
I mean, I do use them as modules, because I don't have a choice in existing Common Lisp implementations, but I have to be careful about how I use them.
semz_ has joined #commonlisp
occ has quit [Ping timeout: 248 seconds]
semz has quit [Ping timeout: 252 seconds]
<beach>
Also, packages make possible this organization that has become my favorite: Define a protocol package PROTO, but have no code file with (IN-PACKAGE #:PROTO). Then define one or more implementation packages, say PROTO-IMPL1, PROTO-IMPL2, etc. Code with (IN-PACKAGE #:PROTO-IMPLn) then refers to names in PROTO with explicit package prefixes, possibly a package-local nickname.
<beach>
This organization is not possible in a language with only modules.
eddof13 has joined #commonlisp
<beach>
In the example of contrapunctus, A would be PROTO and B would be PROTO-IMPL, but then the DEFGENERIC would be moved to B and defined as (DEFGENERIC A:fun ...).
<pillton>
Why wouldn't you be able to do this in a language with only modules?
<beach>
Typically, a module would contain code and you can export that code, but a module can't define functions and classes in another module, the way this organization works.
<beach>
PROTO would be a module without any definitions which does not make sense in the module systems I know.
<pillton>
Ah ok. What do you do if a module requires a user to supply an argument which implements a certain protocol?
waleee has quit [Ping timeout: 252 seconds]
<beach>
I don't know what it means for an argument to implement a protocol.
<pillton>
My apologies. Have methods defined on certain generic functions.
rawley has quit [Remote host closed the connection]
rawley has joined #commonlisp
eddof13 has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
<beach>
Client code always refers to PROTO:<function-name>.
<beach>
All exported symbols are in PROTO.
<beach>
And PROTO contains no internal symbols.
<pillton>
Can you do (defmethod proto:<function-name> ((x client-class)))?
<beach>
Of course. Why would it not be possible?
Bike has quit [Quit: Connection closed]
<beach>
The main effect of the organization is that internal symbols exist only in the IMPL packages, and since there can be many of those, it is guaranteed that there is no conflict between them, which gives more freedom for code in the IMPL packages.
semz_ is now known as semz
hashfunc14a0 has joined #commonlisp
rawley has quit [Ping timeout: 246 seconds]
tyson2 has quit [Remote host closed the connection]
<pillton>
Oh just that adding methods to generic functions has global consequences. I am not sure this is a property that people want with modules.
<pillton>
For example, assume that module A defines methods on generic functions in module B. Module C also defines methods on generic functions in module B. Modules A and C may behave differently when loaded in to the same environment compared to when they are isolated.
<pillton>
Sure, you could argue that the interface is rubbish, but I think the point is worth considering from a scalability point of view.
<beach>
We have a solution for that situation too. These days, our protocol functions have a CLIENT parameter.
<beach>
Client code must supply an instance of a standard class as the argument, but the module itself does not specialize to this parameter.
<beach>
Then, modules B and C would each be required to supply an instance of its own standard class, and define methods that specialize only to its own standard class.
<beach>
The reason for this organization is precisely what you mention. We want to be able to have arbitrarily many clients to a module in the same image.
<beach>
So for instance, Eclector, Clostrum, Trucler, etc. all use this technique.
<beach>
Though, Eclector must of course respect the interface to standard functions such as READ, and then client code will instead bind a special variable ECLECTOR:*CLIENT* to an instance of its standard class. Eclector then calls documented internal functions, like READ-INTERNAL which take a CLIENT argument.
<pillton>
Yeah ok. I need to look at the CLIENT examples.
<beach>
Again, client code can define methods on those internal functions, specialized to its own client class.
<beach>
This organization is perfect for bootstrapping, because I can have Eclector do different things for reading code meant for the host Common Lisp implementation, and for code meant for the target Common Lisp implementation.
<beach>
pillton: I suggest you look at Eclector then, because it probably has the best documentation of the systems I mentioned.
<beach>
And, scymtym has had the time to iron out all kinds of issues, so it should be fairly complete.
<pillton>
beach: Thanks I will take a look. I feel like this is probably worth writing up as a web page.
<beach>
That sounds like a good idea.
<beach>
I think we have written things down somewhere. Perhaps in the SICL specification.
Josh_2 has quit [Remote host closed the connection]
lisp123 has quit [Remote host closed the connection]
occ has quit [Ping timeout: 268 seconds]
lisp123 has joined #commonlisp
attila_lendvai has joined #commonlisp
attila_lendvai has quit [Read error: Connection reset by peer]
rgherdt_ has joined #commonlisp
<lisp123>
hooks are the greatest thing since sliced bread, but the are basically just CLOS before/after methods for the most part
attila_lendvai has joined #commonlisp
rgherdt has quit [Ping timeout: 246 seconds]
<jdz>
lisp123: Not really.
<lisp123>
sliced bread is better?
<jdz>
lisp123: May be only if only a single hook function is allowed in every case.
<lisp123>
hmm good point. guess you could macro over it
<jdz>
I'd say hooks and auxiliary methods are orthogonal.
<jdz>
An auxiliary method might be used to invoke hook functions.
<lisp123>
hmmm I would think they are pretty much the same
livoreno has quit [Ping timeout: 240 seconds]
<lisp123>
the hard part is invoking the hook
<lisp123>
once you do that, its pretty easy just to have an array of functions to call (ancilliary question - what order are multiple hooks invoked?)
<jdz>
So how would you add two hooks for a generic function invoked with the same arguments?
<lisp123>
you would write a macro - the user facing hook function pushes the code the user writes into an array
<lisp123>
the implementation method function iterates over the array of hooks
<jdz>
So how is this "hooks are just glorified auxiliary methods"?
<jdz>
Looks like the other way around from what you're saying.
<lisp123>
the hard part is running the hook when its needed to
<lisp123>
that gets handled by CLOS, otherwise you would have to write all that machinery
<jdz>
Again, the original statement does not hold, and you yourself agree that auxiliary methods are nice to have for the purpose of invoking hooking mechanism, which is orthogonal to auxiliary methods.
cage has joined #commonlisp
<lisp123>
ehh ok
treflip has joined #commonlisp
epolanski has quit [Quit: Connection closed for inactivity]
pillton has quit [Quit: ERC 5.4 (IRC client for GNU Emacs 28.1)]
lisp123 has quit [Remote host closed the connection]
<Demosthenex>
zacque: yeah, its the same site... and i checked archive.org. shame, i wanted to see what he did ;]
<Demosthenex>
i was trying to find a way to do something like perl's named capture groups with cl-ppcre instead of lots of repetition like in register-groups-bind
tyson2 has joined #commonlisp
<Demosthenex>
(cl-ppcre:scan-to-strings "^(?<varA>[0-9]+) (?<varB>[A-Z]+)$" "123 ABC") => (list :varA "123" :varB "ABC") or something similar
<Demosthenex>
in perl you can have the variable name inside the regexp, and it's in the current context hash %+ ?
<zacque>
I'm curious as well ha!
<zacque>
re: (cl-ppcre:scan-to-strings "^(?<varA>[0-9]+) (?<varB>[A-Z]+)$" "123 ABC") => (list :varA "123" :varB "ABC") or something similar ---- Oh, that will be nice
<zacque>
I just started using CL-PPCRE as well
<zacque>
It's register-groups-bind all over the place right now
<Demosthenex>
zacque: just wanted to see someone better's code for a parser ;]
attila_lendvai has quit [Ping timeout: 246 seconds]
<Demosthenex>
maybe he worked around named capture differently
<Demosthenex>
zacque: that paste is my current nasty code for eliminating the duplication
<Demosthenex>
i've also used TXR a bit, it can dump variables as easy as awk for text records and it's lisp based.
<Demosthenex>
my only complaint is debugging the matcher in TXR is hard
<zacque>
I guess you can try to email the author for code? There is a "contact me" at the sidebar
<zacque>
But it's 404 Not found for me
<zacque>
Not sure whether it's my problem
<zacque>
It looks fine to me ha!
<random-nick>
maybe such perl behaviour could be made nicer in CL by making some LET-REGISTER-GROUPS macro which binds those regexp registers lexically to the given names within its body
<zacque>
Can see that you use hashtable to remove duplicate then convert it into list for processing again
<zacque>
There is an equivalent `remove-duplicates` for list data too
<zacque>
First time knowing TXR, interesting...
<Demosthenex>
zacque: i left a comment, we'll see what happens
<Demosthenex>
zacque: i'm using plists
<zacque>
Great, hope he can give you some inspirations ha!
<Demosthenex>
a hash would be too big for these tiny lists.
<zacque>
Oh ya, `getf` is for plist
<Demosthenex>
i'm actually strongly typechecking and doing sql constraints to confirm... but part of me is tempted just to dump the plists as json into raw jsonb tables and make views
<Demosthenex>
but i find json tasteless
<Demosthenex>
i was doing (nconc record (list k v)) before i remembered there are plist functions ;]
occ has joined #commonlisp
lisp123 has quit [Remote host closed the connection]
lisp123 has joined #commonlisp
<zacque>
No strong feeling against json =D
<zacque>
Ah, I see
<Demosthenex>
i've used jsonb and postgres before with external data given to me as json in bulk, and made views to make a regular table out of that json within postgres, it was nearly transparent.
<Demosthenex>
but that's lazy
<zacque>
random-nick: How is that different from the current binding method?
<zacque>
Demosthenex: That's convenient, I guess? Why lazy?
<Demosthenex>
zacque: because json is schemaless. you just HOPE a k/v you need is there and of the right data type
<Demosthenex>
i'm parsing this stuff, i know what it should be. i should check for that and make sure it's consistent
<Demosthenex>
instead of just dumping strings to json and hoping
<zacque>
Oh, I thought input jsons will be checked against db tables schema?
lisp123 has quit [Quit: Leaving...]
<random-nick>
zacque: I'm talking about including variable names in the regexp, cl-ppcre macros have a separate list of names I think
<Demosthenex>
zacque: no. postgres now has a json data type. you can assign a column to accept arbitrary json records. then you can make a view to flatten them into a table
<random-nick>
I think jsonb is a column data type
<Demosthenex>
random-nick: see that dpaste
<Demosthenex>
zacque random-nick: regarding jsonb and views, here's one. i have a table _matches (id, raw jsonb), and transpose that into a view of selected items from the json records https://dpaste.org/FTtNs
<Demosthenex>
i didn't enforce datatype casting there though
<Demosthenex>
but i downloaded 1M json records of matches, and made a virtual table of the fields i wanted that were embedded in the json
<Demosthenex>
after that, i used postmodern to do queries normally
<Demosthenex>
i think postmodern even allowed me to use (:-> ...) in s-sql queries, which was slick. -> is the postgres extra function for digging into json
<zacque>
random-nick: Ah, I see, ya, you have to specify the name in cl-ppcre
<zacque>
Demosthenex: Oh, I think the named register is used only for backreferencing? See: https://edicl.github.io/cl-ppcre/#*allow-named-registers*
<Demosthenex>
zacque: again, cl-ppcre allows named registers, but its only reused inside the regexp (like match word, then same word later with \1), it doesn't export that out
<pjb>
zacque: use &rest instead of &optional: (defun foo (a b &rest rest) (list* a b rest)) (values (foo 1 2) (foo 1 2 3) (foo 1 2 3 4) (foo 1 2 3 4 5)) #| --> (1 2) ; (1 2 3) ; (1 2 3 4) ; (1 2 3 4 5) |#
<pjb>
zacque: if you want you can add a check on the max length of rest.
MajorBiscuit has quit [Ping timeout: 246 seconds]
MajorBiscuit has joined #commonlisp
yauhsien has quit [Remote host closed the connection]
<zacque>
Demosthenex: Interesting! I've thought about porting more Perl text processing capabilities into CL
<Demosthenex>
THAT works. maybe i can just use that to create a plist from varnames embedded as named groups
<zacque>
Perl is like a well-made text processing DSL
<Demosthenex>
perlre's are really flexible, but also black magic.
<Demosthenex>
never ever do multiline regexps in perl :P
Dynom has joined #commonlisp
<zacque>
Me neither ha! Haven't got the chance to try Unicode regex as well
<zacque>
I heard there's a lot of hairy details in it
<zacque>
Demosthenex: re: https://dpaste.org/nhfDU : Huh? How does extracting out name of the registers help? I meant, you can read it from the string itself?
<zacque>
Maybe you can parse the regex string itself using another regex string?
<zacque>
It's a string in the end
<Demosthenex>
zacque: cl-ppcre's parse-string turns a string into a parse tree
<Demosthenex>
but a plist is a bit safer than vars, i kept yours too ;]
<zacque>
pjb: Thanks! Nice to see how `LIST*` work here, but I won't change the function "signature" because it's actually a CL function wrapper over Elisp function. So I will want their signatures to be identical
<random-nick>
why not dynamically bind *allow-named-registers*? I couldn't in my macro because register-groups-bind parses the regexp during load time
<Demosthenex>
random-nick: i could :P in the context of my program its ok to just force it.
<random-nick>
actually, I just remembered that a parse tree can be passed as a regexp, so I updated https://plaster.tymoon.eu/view/3024 and now it works whatever the value of that variable is
<Guest74>
jdz: you could have some sequential method combination and/or make sure everybody adding a hook remembers to call next method. Easy to break. There's something about the simplicity of an ordered list that can be dealt with all the familiar sequence functions.
s-liao has quit [Quit: Client closed]
s-liao has joined #commonlisp
<Guest74>
I still have no idea how to exorcise sly or where it's hiding itself between reboots.
Guest74 has quit [Quit: Connection closed]
s-liao has quit [Quit: Client closed]
s-liao has joined #commonlisp
bonmlp has joined #commonlisp
s-liao has quit [Client Quit]
<_death>
strace
yauhsien has joined #commonlisp
waleee has joined #commonlisp
<_death>
could also use emacs debugging facilities, e.g. debug-on-entry, I suppose
yauhsien has quit [Ping timeout: 246 seconds]
molson has quit [Remote host closed the connection]
morganw has joined #commonlisp
molson has joined #commonlisp
livoreno has joined #commonlisp
bonmlp` has joined #commonlisp
bonmlp has quit [Ping timeout: 248 seconds]
razetime has joined #commonlisp
tyson2 has quit [Remote host closed the connection]
eddof13 has joined #commonlisp
eddof13 has quit [Client Quit]
Inline has quit [Quit: Leaving]
[deleted] has joined #commonlisp
Inline has joined #commonlisp
livoreno has quit [Ping timeout: 248 seconds]
ec has joined #commonlisp
Devon has quit [Read error: Connection reset by peer]
Devon has joined #commonlisp
aeth has quit [Ping timeout: 268 seconds]
aeth has joined #commonlisp
livoreno has joined #commonlisp
[deleted] has quit [Ping timeout: 240 seconds]
ec has quit [Ping timeout: 240 seconds]
ec has joined #commonlisp
MajorBiscuit has quit [Ping timeout: 268 seconds]
bonmlp` has quit [Ping timeout: 260 seconds]
razetime has quit [Remote host closed the connection]
sander has quit [Quit: So long! :)]
karlosz has joined #commonlisp
sander has joined #commonlisp
orestarod has joined #commonlisp
ebrasca has quit [Ping timeout: 272 seconds]
ebrasca has joined #commonlisp
Alfr has quit [Quit: Leaving]
sander has quit [Quit: So long! :)]
sander has joined #commonlisp
morganw has quit [Read error: Connection reset by peer]
morganw has joined #commonlisp
frgo has quit []
tyson2 has joined #commonlisp
karlosz has quit [Ping timeout: 268 seconds]
occ has quit [Ping timeout: 272 seconds]
perro has joined #commonlisp
frgo has joined #commonlisp
dlowe has joined #commonlisp
dlowe has quit [Remote host closed the connection]
treflip has quit [Quit: Quit]
Alfr has joined #commonlisp
attila_lendvai has joined #commonlisp
epolanski has joined #commonlisp
aeth has quit [Ping timeout: 256 seconds]
aeth has joined #commonlisp
Catie has quit [Quit: heading out]
cosimone has quit [Remote host closed the connection]
Guest74 has joined #commonlisp
mon_aaraj has quit [Ping timeout: 246 seconds]
mon_aaraj has joined #commonlisp
CrashTestDummy has joined #commonlisp
Spawns_Carpeting has joined #commonlisp
Lord_of_Life_ has joined #commonlisp
Lord_of_Life has quit [Ping timeout: 260 seconds]
Lord_of_Life_ is now known as Lord_of_Life
CrashTestDummy has quit [Quit: Leaving]
Bike has quit [Quit: Connection closed]
Dynom has quit [Quit: WeeChat 3.5]
mon_aaraj has quit [Ping timeout: 246 seconds]
mon_aaraj has joined #commonlisp
aeth_ has joined #commonlisp
aeth has quit [Killed (NickServ (GHOST command used by aeth_))]
aeth_ is now known as aeth
aeth_ has joined #commonlisp
aeth has quit [Killed (NickServ (GHOST command used by aeth_))]
aeth_ is now known as aeth
dlowe has joined #commonlisp
Bike has joined #commonlisp
mon_aaraj has quit [Ping timeout: 268 seconds]
mon_aaraj has joined #commonlisp
hashfunc14a0 has joined #commonlisp
<hashfunc14a0>
this is like the third time i've forgotten the semantics of bitmasking in CL
<hashfunc14a0>
how do you remember how to use bitmasks in CL?
<hashfunc14a0>
is there an easier method then going about using MASK-FIELD and whatnot?
<hashfunc14a0>
*than
cage has quit [Quit: rcirc on GNU Emacs 27.1]
<Bike>
i don't think the semantics are that complicated. it's just that you have an infinite number of bits and a sign.
<Bike>
i can never remember how two's complement works off the top of my head, tho.
<hashfunc14a0>
Bike: if someone can remember how two's complement works off the top of their head without much thought, i would assume that they have too much time on their hands
<hashfunc14a0>
or they have an incredibly good memory. but there's always a give-and-take IMO. (+remembering-twos-complement, -another-skill)
pranavats has left #commonlisp [Error from remote client]
shka has quit [Ping timeout: 246 seconds]
pranavats has joined #commonlisp
<pjb>
hashfunc14a0: the easier operators are dpb and ldb.
<pjb>
hashfunc14a0: with 1-complement, -1 would be represented as …111110 <--- ! 0 as …0000000 +1 as …0000001
<pjb>
hashfunc14a0: with 2-complement, -1 is represented as …111111 <--- 0 as …0000000 +1 as …0000001
<pjb>
with-1 complement, there's a representation for -0 as …111111 so tests for zerop is more complex…
mon_aaraj has quit [Ping timeout: 268 seconds]
wyrd has joined #commonlisp
mon_aaraj has joined #commonlisp
sander is now known as sndr
<hashfunc14a0>
pjb: awesome, thanks for the help
hashfunc14a0 has quit [Ping timeout: 268 seconds]
<jfb4>
(perhaps naive) question: is there a standard common Lisp web development framework, like Django/python but for CL? It seems like a good problem domain for Lisp
Bike has quit [Quit: Connection closed]
<random-nick>
well, I'm pretty sure there's no one standard web framework
attila_lendvai has quit [Ping timeout: 240 seconds]