morganw has quit [Remote host closed the connection]
ahc has joined #commonlisp
ahc has quit [Quit: Leaving]
karlosz has quit [Quit: karlosz]
ebrasca has joined #commonlisp
nij- has quit [Remote host closed the connection]
perrierjouet has quit [Quit: WeeChat 3.7.1]
Fare has joined #commonlisp
nij- has joined #commonlisp
perrierjouet has joined #commonlisp
<mfiano>
Random thought: Should library authors that have public-facing interfaces that accept any specific or subset of sequences as input, is it a good idea to always use COPY-TREE or the appropriate function before mutating a list "from the outside" that you didn't create, or should the caller always be informed of the semantics and it's their responsibility not to pass a list literal...or both,
<mfiano>
dependendent on ...?
<mfiano>
dependent*
perrierjouet has quit [Quit: WeeChat 3.7.1]
<mfiano>
Nevermind. That question didn't come out the way I wanted it to, and it doesn't make a lot of sense.
perrierjouet has joined #commonlisp
nij- has quit [Ping timeout: 256 seconds]
nij- has joined #commonlisp
<Bike>
destructive interfaces are ok as long as they are documented as such (and "may destroy" versus "mutates in this particular way" is indicated)
son0p has quit [Ping timeout: 256 seconds]
<Bike>
and often a good idea practically speaking, since consing up a bunch of needless intermediate results slows things down
ebrasca has quit [Remote host closed the connection]
<mfiano>
One thing that upsets me about the standard, and I just had to double-check to make sure I was remembering correctly, is there is no way to get a lazy sequence of the keys stored in a hash table, except within the lexical environment of with-hash-table-iterator, and there are all sorts of UB around trying to make it dynamically scoped with a closure or whatnot.
<mfiano>
I really would like a non-consing alternative to MAPHASH-ing to retrieve all keys, as the starting state in a custom iterator, which is more or less, what I'm trying to accomplish.
euandreh has quit [Quit: euandreh]
perrierjouet has quit [Quit: WeeChat 3.7.1]
euandreh has joined #commonlisp
akoana has quit [Quit: leaving]
euandreh has quit [Quit: euandreh]
son0p has joined #commonlisp
perrierjouet has joined #commonlisp
Oladon has quit [Quit: Leaving.]
euandreh has joined #commonlisp
pjb has quit [Remote host closed the connection]
perrierjouet has quit [Client Quit]
gxt has quit [Remote host closed the connection]
mariari has quit [Ping timeout: 268 seconds]
gxt has joined #commonlisp
Bung has joined #commonlisp
Lord_of_Life has quit [Ping timeout: 265 seconds]
Lord_of_Life_ has joined #commonlisp
Lord_of_Life_ is now known as Lord_of_Life
perrierjouet has joined #commonlisp
perrierjouet has quit [Client Quit]
mariari has joined #commonlisp
perrierjouet has joined #commonlisp
Fare has joined #commonlisp
tyson2 has quit [Remote host closed the connection]
Fare has quit [Ping timeout: 260 seconds]
Bung has quit [Quit: Leaving]
aartaka has joined #commonlisp
azimut has quit [Ping timeout: 255 seconds]
gxt has quit [Ping timeout: 255 seconds]
gxt has joined #commonlisp
ym has joined #commonlisp
dipper has quit [Remote host closed the connection]
aartaka has quit [Ping timeout: 264 seconds]
aartaka has joined #commonlisp
dipper has joined #commonlisp
waleee has quit [Ping timeout: 265 seconds]
ym has quit [Ping timeout: 265 seconds]
gateway2000 has joined #commonlisp
dipper has quit [Remote host closed the connection]
anticomputer has quit [Remote host closed the connection]
anticomputer has joined #commonlisp
lisp123 has quit [Ping timeout: 260 seconds]
lisp123 has joined #commonlisp
<lisp123>
Anybody use around methods with dynamic scoped variables to alter functions?
<beach>
That's a very strange question. I mean, the answer is "Of course, it happens all the time. Just look at something like PRINT-OBJECT."
<lisp123>
I'm more interested in any insights around such patterns, obviously it is used
<beach>
The PRINT-OBJECT method specalized to INTEGER would need to consult *PRINT-BASE*.
<beach>
The use of special variables is no different from the use of special variables in ordinary functions.
<beach>
The use of special variables in methods is no different from the use of special variables in ordinary functions, I mean.
<lisp123>
I was thinking more with the use of &allow-other-keys
<beach>
I don't see the relation between &ALLOW-OTHER-KEYS and special variables. Also, &ALLOW-OTHER-KEYS is not reserved for methods. It is used in ordinary functions as well.
<lisp123>
I guess that's right
<lisp123>
I was thinking of allowing people to override the primary method based on giving them flexibility in &allow-other-keys
<beach>
That's a very different question from the initial one.
<lisp123>
They can use dynamically scoped variables as keys
pve has joined #commonlisp
<lisp123>
Where it is different from normal functions - there is typically no expectation that an ordinary function would be redefined,so arguably special variables should not be an implicit parameter but rather explicit in the parameter list
<lisp123>
Whereas with generic functions and the capabilities offered by method combinations, maybe its more appropriate
<beach>
I think you have a special use case in mind. And I am unable to infer it from the question and the additional descriptions you have given. But then, I am notorious for not understanding what people want, unless the description is very detailed. You can hope that someone else is better with that than I am.
lisp123 has joined #commonlisp
<lisp123>
beach, no worries. I'm experimenting with how to make my programs more extensible
<beach>
Well, in that case, I can tell you about the technique we have adopted in several libraries. Important generic functions have a CLIENT parameter that is not specialized to by the methods in the library. Client code must supply an instance of a standard class as the argument for this parameter. Client code can then override any method by providing a method that does specialize to the standard class in question.
<beach>
You can see this technique in Eclector, for instance. But also in Clostrum, Trucler, etc.
<beach>
Functions that are not allowed to take any additional parameter, such as READ for instance (which must be compatible with the standard one), call a generic function, passing the value of the library-provided special variable *CLIENT* as an argument for this parameter. Client code must bind the special variable around a call to a library function.
<beach>
This way, the library can supply lots of good default methods for all generic functions, while clients with special needs can override any such generic function.
<beach>
Again, Eclector is a very good example.
<lisp123>
Digesting
<lisp123>
I think that's an optimal way
<beach>
This technique also allows for several clients to exist simultaneously in the same Common Lisp image. For instance, if I want to cross-compile code for SICL using an implementation that already uses Eclector, then the host can use Eclector with its own client, and the cross compiler can pass a SICL-specific client in order to use Eclector as a reader.
<lisp123>
Important generic functions have a CLIENT parameter that is not specialized to by the methods in the library. -> When (or what factors drive the decision) of when this should be an explicit parameter vs. a special *CLIENT* variable
<phoe>
lisp123: e.g. CL:READ has no client parameter
<beach>
lisp123: What phoe said.
<phoe>
but eclector's READ-WITH-CLIENT (iirc the name) has CLIENT as its first parameter
<phoe>
so, (let ((eclector:*client* foo)) (cl:read ...)) is equivalent to (eclector:read-with-client foo ...)
<phoe>
if you use eclector as your system reader, that is
<beach>
If the library function is not trying to imitate the lambda list of any known function, then it can freely use a CLIENT parameter.
random-nick has joined #commonlisp
<lisp123>
I get that part for functions that are not allowed to take an additional parameter, but reading the above it seems like its preferable in other cases to make the CLIENT parameter explicit
<phoe>
in the other cases, yeah
<beach>
Absolutely.
<phoe>
when you can't do anything else, though, the oldest trick in the book, one of passing extra arguments via dynamic variables
<phoe>
just used in a rather novel way
<lisp123>
So I guess instead of specialising on keys, the all-encompassing client parameter captures variations
<phoe>
not really all-encompassing
<beach>
I don't know what it means to "specialize on keys".
<lisp123>
&allow-other-keys
<phoe>
not all functions have &key to do this
<beach>
I don't know what it means to "specialize on &ALLOW-OTHER-KEYS".
<beach>
lisp123: Specialization is allowed only with required parameters.
<lisp123>
beach, phoe thanks I got some ideas out of this
cage has joined #commonlisp
<mfiano>
Is there a portable utility function floating around somewhere that linearized a rank>1 array into a rank 1 array (or vector if need be)?
<phoe>
you cannot use row-major-aref for that, can you?
<mfiano>
Since Common Lisp doesn't support ragged matrices, it should literally be what most implementations would store in row-major ordering anyway.
<phoe>
or a displaced array?
<mfiano>
I could write my own loop using that, sure.
shka has quit [Ping timeout: 265 seconds]
<mfiano>
I just thought this would be a common enough pattern to have a utility around for it. It's common in things I do anyway, so just curious before I add a todo to add it to my utility library.
<phoe>
I think that removing the old MIT license notice breaks the old license
thuna` has joined #commonlisp
euandreh has quit [Quit: euandreh]
<mfiano>
Why would you think that?
rangahy has joined #commonlisp
<phoe>
MIT license says, "The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software."
<phoe>
the copyright notice and the permission notice were both removed
euandreh has joined #commonlisp
euandreh has quit [Client Quit]
<mfiano>
the Software pertains to the source code. As it is. Right then and there. The revision with that license still exists.
euandreh has joined #commonlisp
<phoe>
that would imply everyone redistributing this fork of aops without the whole git repository is now in violation, quicklisp included
<phoe>
since "just the tarball" doesn't include the old revision
<mfiano>
Just the tarball is of a new piece of software governed by the license change
euandreh has quit [Remote host closed the connection]
<phoe>
containing a substantial portion of the Software, and therefore still guarded by the old license
euandreh has joined #commonlisp
<mfiano>
It seems you are correct. Quicklisp is violating the terms of some Microsoft agreement. Oops.
<phoe>
not really, the original repository is
<mfiano>
Moreso, aops maintainers are.
<phoe>
seems like lisp-stat is not respecting the MIT license; they're okay with changing to MSPL, they're not okay with removing the MIT license notice
<pjb>
mfiano: so you want a library for (make-array (reduce #'* (array-dimensions arr)) :displaced-to arr) !?!?
<mfiano>
Only thing that could happen is flag the repo, MS notices, kid gets sued, up to court to decide if substantial has been met
<pjb>
mfiano: there you are: (defun linearized-array (arr) (make-array (reduce #'* (array-dimensions arr)) :displaced-to arr))
<phoe>
mfiano: MS has nothing to do with it
<mfiano>
GItHub is MS.
<phoe>
MSPL is not MS
<mfiano>
And?
<phoe>
the former is a copyleft license, the latter is a company
<mfiano>
Ok?
<phoe>
the fact that a license is named MSPL and originates at MS doesn't mean that MS itself gets to do something when someone violates it
<mfiano>
No, but MS gets to decide to respond to flagged repositories/accounts
<phoe>
yeah, if someone files a complaint
euandreh has quit [Quit: euandreh]
dipper has quit [Remote host closed the connection]
<mfiano>
As I said, it is that response that would might (unlikely) cause just enough attention for the 7 moons to align, leading to a court to decide if they made enough substantial changes.
<phoe>
not really my problem, truth be told; more of a problem of #.(ql:who-depends-on "array-operations") who might want to know that their dependency changed its license from MIT to MSPL
dipper has joined #commonlisp
<phoe>
and there's a bunch of them
<mfiano>
I don't care what license it is. It's sketchy that they removed it in violation. And the new license is kinda sketchy too after reading it.
<lisp123>
If you maintain an old version of the code, it should have the old license no?
<phoe>
as long as you dependency pinning
<lisp123>
which is something I think should be recommended to do regardless
<lisp123>
at least when projects start to take shape
<mfiano>
I kinda think sharplispers should take over the archived repo, and rebase any worthwhile new changes by the new maintainer
<lisp123>
'rebase any worthwhile new changes' - that can be a murky ground
<mfiano>
Oh but the license change happened upstream :x
<mfiano>
Welp, not my problem
karlosz has joined #commonlisp
<phoe>
yes, the most recent dist update has the relicensed aops
<mfiano>
Yes, I was just stating that it is recently abandoned/forked, and that change was made _prior_ to that, which is a little unfortunate
<mfiano>
pjb: No, I don't want any shared structure with the original. I want to retain its simple-array property when possible, also, so big no to displacement.
dipper has quit [Remote host closed the connection]
dipper has joined #commonlisp
azimut has joined #commonlisp
random-jellyfish has joined #commonlisp
alfonsox has joined #commonlisp
dipper has quit [Remote host closed the connection]
dipper has joined #commonlisp
dipper has quit [Remote host closed the connection]
dipper has joined #commonlisp
<random-jellyfish>
Does Peter Norvig still use CommonLisp?
epony has quit [Ping timeout: 268 seconds]
<_death>
maybe ask in #peternorvig
random-jellyfish has quit [Quit: Client closed]
alfonsox has quit [Read error: Connection reset by peer]
lisp123 has quit [Ping timeout: 260 seconds]
dipper has quit [Remote host closed the connection]
Inline has joined #commonlisp
Inline has quit [Client Quit]
<pjb>
mfiano: then just add a copy-seq: (defun linearized-array (arr) (copy-seq (make-array (reduce #'* (array-dimensions arr)) :displaced-to arr)))
<pjb>
perhaps this will make you understand why it would be silly to put that in libraries.
<phoe>
can't say it's silly, e.g. simple-style-warning falls under the same case
Bung has joined #commonlisp
<jackdaniel>
silly-style-warning
<phoe>
well, style-warning is not a serious-condition, so obviously
<jackdaniel>
a simple-minded condition system would not check for types at all and leave that for higher level constructs
<jackdaniel>
phoe: btw did you find your jedi student?
<phoe>
not yet
<phoe>
they will arrive when the stars align
<jackdaniel>
I see
Inline has joined #commonlisp
<phoe>
I have put a handler on that so I'll know
Bung has quit [Remote host closed the connection]
Bung has joined #commonlisp
random-jellyfish has joined #commonlisp
<random-jellyfish>
it's an empty channel
<phoe>
random-jellyfish: it was _death's attempt at humor, please forgive him
<phoe>
but yeah you might want to ask him directly; I've seen gigamonkey say a thing or three here in the past few years but he hasn't really been particularly active AFAIR
tyson2 has joined #commonlisp
<random-jellyfish>
not sure I understand, Peter Norvig goes by the nickname gigamonkey in here?
<phoe>
yes, to the best of my knowledge
<random-jellyfish>
okay, that's good to know
<splittist>
phoe: I think you are confused.
<phoe>
aaaa
<phoe>
fuck! you are right
<phoe>
wrong Peter
<phoe>
random-jellyfish: please disregard everything I've said since it refers to Peter Seibel
<phoe>
the author of Practical Common Lisp
<random-jellyfish>
got it, thanks
<phoe>
whereas Peter Seibel wrote PAIP
<phoe>
golly, we need more variety in the names of famous lisp book authors
<random-jellyfish>
how does it do the replacement? each word is replaced by a random non-sense latin word? or does it work at sentence level?
<random-jellyfish>
I don't have a doc nearby to test it, that's why I ask
<random-jellyfish>
wait, I forgot to scroll down
<random-jellyfish>
to where it explains how it works, lol
gateway2000 has quit [Quit: Leaving]
<_death>
hmm, why would one want to do that? upload confidential documents? if the same word translates to the same replacement word, some information is preserved..
<splittist>
It's a thing I use so I can work on realistic documents in my private life without taking home company-confidential stuff. I agree it requires trusting me. But I do! (:
varjag has joined #commonlisp
Inline has quit [Quit: Leaving]
Inline has joined #commonlisp
Inline has quit [Remote host closed the connection]
Inline has joined #commonlisp
<_death>
ok, but may also want to note that it may not be so difficult to recover at least part of the text
Fare has joined #commonlisp
<thuna`>
To get a nonsense document with realistic structure maybe?
<splittist>
thuna`: exactly that
<splittist>
_death: I tried in the bit that says it is not a cipher, and should not be used as a means of encryption. But perhaps I should just delete "confidential" at the top.
<splittist>
Thanks to all for having a look (:
<_death>
splittist: right, it's not a cipher because the function is not 1-to-1.. each lorem ipsum word is a bucket of original words, and you can try and figure out sentences probabilistically
<_death>
if there's only one bucket, then yeah it's pretty good :)
<_death>
I suggest the bucket label "developers" :)
<_death>
or "buffalo", to avoid any possible microsoft trademarks
<splittist>
It's not very sophisticated at all, of course: https://github.com/splittist/loremizer . In particular, it uses Word's idea of a run, which might encompass a whole word, or might split a word into a number of parts, depending on editing history, phase of the moon etc.
Bung has quit [Quit: Leaving]
* splittist
updates the production instance directly
Bung has joined #commonlisp
Inline has quit [Quit: Leaving]
Inline has joined #commonlisp
Inline has quit [Quit: Leaving]
Inline has joined #commonlisp
Inline has quit [Client Quit]
Inline has joined #commonlisp
<Nilby>
as my "Word" is my bond, your confidential documents are 365% safer from lions when you upload them to the herd with everyone else's confidential documents.
pfd has joined #commonlisp
varjag has quit [Ping timeout: 260 seconds]
varjag has joined #commonlisp
Bung has quit [Quit: Leaving]
<splittist>
“No one ever got fired for specifying Azure…“
Fare has quit [Ping timeout: 260 seconds]
<contrapunctus>
("...yet.")
<pve>
Hi, I'm exploring some ideas about "file-local" effects. Here's the first one I made. I'd like to hear thought on this.. is it useless or could there be something here worth exploring further?
<pve>
the idea is to make the code a bit more brief by having a shorthand for the long protocol name
<beach>
What problem does it solve that package-local nicknames don't?
<Nilby>
pve: I like it. Code should look how you want it.
<pve>
beach: I thought about that, I could see situations where the protocol is not in a separate package. Also, sometimes packages are designed to be "USE"d, and I don't know if package-local-nicknames would help there.
<pve>
but I agree that there's overlap
<beach>
I see. I think I always put a protocol in a separate package. And I specifically design packages not to be USEd. That's why I didn't see the use case.
<pve>
Nilby: thanks
<_death>
splittist: btw, since the processor operates a single-pass word by word, extending the buckets, it is a simple substitution cipher up until the first reoccurrence of a bucket label.. then either the bucket is extended or the word was already seen, and so on.. this could make recovery even easier than what I considered from the description
igemnace has joined #commonlisp
gateway2000 has joined #commonlisp
gxt has quit [Remote host closed the connection]
azimut has quit [Remote host closed the connection]
gxt has joined #commonlisp
azimut has joined #commonlisp
rpx has joined #commonlisp
azimut has quit [Ping timeout: 255 seconds]
azimut has joined #commonlisp
gxt has quit [Remote host closed the connection]
gxt has joined #commonlisp
euandreh has joined #commonlisp
causal has joined #commonlisp
Inline has quit [Quit: Leaving]
Bung has joined #commonlisp
epony has joined #commonlisp
jmdaemon has joined #commonlisp
anticomputer has quit [Ping timeout: 255 seconds]
gxt has quit [Remote host closed the connection]
anticomputer has joined #commonlisp
gxt has joined #commonlisp
ec_ has quit [Ping timeout: 255 seconds]
ec_ has joined #commonlisp
rgherdt has joined #commonlisp
rpx has quit [Quit: Client closed]
nij- has joined #commonlisp
random-jellyfish has quit [Quit: Client closed]
Bung has quit [Remote host closed the connection]
Bung has joined #commonlisp
Oladon has joined #commonlisp
Bung has quit [Quit: Leaving]
mason has left #commonlisp [#commonlisp]
tyson2 has quit [Remote host closed the connection]
ebrasca has joined #commonlisp
<seok>
Hi there folks, any book recommendation on metaprogramming in cl perspective?
rgherdt has quit [Remote host closed the connection]
NotThatRPG has joined #commonlisp
azimut_ has joined #commonlisp
azimut has quit [Ping timeout: 255 seconds]
lisp123 has joined #commonlisp
<aeth>
Common Lisp macros are surprisingly easy if you use separate functions (the catch: the functions have to be in a separate file from the DEFMACRO or they need to be inside of an EVAL-WHEN). Remembering when to gensym can be a bit tricky, too, but you avoid issues like not unquoting with , at the right time (nobody knows how to write ` in `) if you use a lot of functions, or at least a giant LET/FLET
<aeth>
inside of the DEFMACRO or something.
<thuna`>
aeth: ` in `? You mean ALEXANDRIA?
<aeth>
no, I mean `(foo ,(bar ... `(baz
* thuna`
was joking
<_death>
to avoid eval-when you can have the functions and defmacro in a single file, but users of the macro in another
<aeth>
some macros might have you write something that looks like ,',
<_death>
*uses
<aeth>
_death: that works until you have a second macro that expands into the macro you just wrote
<aeth>
although you could also use the helper functions inside of both DEFMACROs instead
<_death>
the rule is the same..
<aeth>
there's one thing that's not obvious at all with fancy macros, though: if you need to produce two forms instead of one (macroexpand-1 on DEFUN in some implementations to see this), you need PROGN
<aeth>
But I don't think there's any book substitute to just writing macros because it's just a bunch of edge cases you get from experience.
azimut_ has quit [Ping timeout: 255 seconds]
<lisp123>
i found macro writing pretty straightforwrad
<lisp123>
its just a bit of experience and your mind starting to memorrie the combos of `,, `, etc
azimut has joined #commonlisp
<lisp123>
but yeah I agree the trick is to use helper functions
<lisp123>
splittist, be careful - most companies are very against sharing company materials with private e-mails or accounts
<lisp123>
its just not worth the hassle (and if they are not paying you, why work extra for the company?)
<aeth>
lisp123: yes, but if you can't use separate functions, at least use LET*
<aeth>
that stops the nesting
azimut has quit [Remote host closed the connection]
azimut has joined #commonlisp
Major_Biscuit has joined #commonlisp
<phoe>
if I get annoyed someday I might write a short book on macro writing
<phoe>
even more than TCLCS is right now
<phoe>
people keep on overcomplicating the whole thing
<lisp123>
aeth, will need to have a think about (how to get around it)
<lisp123>
phoe, indeed. I think the trick is to teach what is macro (syntax generating function), how macroexpansion etc works - its always on my list to write such a tutorial but never mustered enough energy to do so
<lisp123>
sometimes trying to use "rules" etc makes things more complicated than required
<phoe>
it has been a three-step process for me - imagine the form before expansion, imagine the form after expansion, write a pure/idempotent function that will translate from the former to the latter
<aeth>
phoe: the problem comes from when it's too big to cleanly fit inside of just one function... which is why sometimes people nest `s and create a mess
<aeth>
this happens more often than you think, e.g. when dealing with bindings
<phoe>
I never nest backquotes as a rule
<phoe>
mostly because I never trust myself to understand them
<aeth>
(I mean, making a macro that's complex, not one that nests `)
<phoe>
and then, a macro is just a pure* function; if you need to split it up then factor it like you would any pure function
<aeth>
although I guess putting bindings probably results in nesting ` if not cleanly organized, since you'd do e.g. `(let ,(mapcar ...
<aeth>
s/putting bindings/generating bindings in your macro/
<phoe>
*idempotence understood in terms of e.g. interning counts as "pure enough"
<phoe>
I kinda use this style of macro writing heavily in PCS