<White_Flame>
when dealing with sockets, what's the best way to manage CRLF end of lines? I'd like read-line to work with that eol
<White_Flame>
and obviously also sending it by default
karmichammer has joined #commonlisp
jeosol has quit [Quit: Client closed]
karmichammer has quit [Ping timeout: 240 seconds]
s-liao has joined #commonlisp
s-liao has quit [Client Quit]
s-liao has joined #commonlisp
karmichammer has joined #commonlisp
morganw has quit [Remote host closed the connection]
karmichammer has quit [Ping timeout: 256 seconds]
elderK has joined #commonlisp
s-liao has quit [Quit: Client closed]
karmichammer has joined #commonlisp
VincentVega has quit [Remote host closed the connection]
Oladon has joined #commonlisp
karmichammer has quit [Ping timeout: 256 seconds]
<EdLangley[m]>
I'm not sure, I've always used read-sequence and implemented read-line myself
<mfiano>
Is there any way I can transform each value of a multiple-values returning form without an intermediate list, with a macro or such to reduce something like this: (multiple-value-bind (a b c d) (func-that-returns-at-least-four-values) ... (* a 10) (* b 10) (* c 10) (* d 10)). Doubtful but just asking. It is known ahead of time that there will be 1-4 values at all times.
<EdLangley[m]>
multiple-value-call might help?
<EdLangley[m]>
(multiple-value-call 'transform-results (foo)) calls transform-results with all the values of FOO
<mfiano>
Ah that's right. In this case I am trying to clean up some really verbose call sites, both verbose due to DRY, and also the transformation calculation itself. I think it might be worthwhile to macro away the lambda form.
<mfiano>
Ed, always a very helpful community member :)
<yitzi>
Ed Langley: nice!
<mfiano>
EdLangley[m]: Needs documentation. I'm not quite sure what they do at first glance
<mfiano>
Mind showing some example input/outputs if you have time?
<EdLangley[m]>
SKIP-VALUES drops the first N values FORM returns
<EdLangley[m]>
LIMIT-VALUES retains only N values of FORM
<EdLangley[m]>
TRANSFORM-FIRST-VALUE calls TRANSFORM with the first value returned by FORM and then returns it as the first value, without losing the rest of the values
<EdLangley[m]>
SUBSTITUTE-VALUES is probably a bad idea
<EdLangley[m]>
But, most of these were just intended to show how to use MULTIPLE-VALUE-CALL to avoid an intermediate list
<mfiano>
Great!
Common-Lisp has joined #commonlisp
<moon-child>
ideally, a Sufficiently Smart Compiler would be able to avoid actually consing up a list
<moon-child>
I don't think such a thing exists, but...
<Common-Lisp>
Not yet.
<moon-child>
(though bike was apparently experimenting with optimization to mv-call. And I know sroa is wanted for sicl. So combine those and you've got yourself a party)
<moon-child>
I looked at a bit of the online version
<moon-child>
(specifically the interpreter)
<moon-child>
it gets _really_ bogged down in syntax, and I don't think it even showed how to build a parser
<moon-child>
moreover it seems to be written in javascript in name only. No one actually uses head() and tail() in js; they use arrays and hashtables^Wobjects
<ns12>
Ah yes, I think Lispers will have no use for that kind of syntax jungle, given that the Lisp version is much simpler.
<Bike>
multiple-value-call is already pretty optimized in sbcl, or at least if you write (apply ...) that's going to end up as an m-v-call
<mfiano>
Bike: Ah good to know
<Bike>
in clasp (lambda (... &rest r) (values-list r)) will not actually cons a list, and i wouldn't be surprised if that was the case in sbcl as well
perrierjouet has quit [Quit: WeeChat 3.4]
<mfiano>
I'm trying not to assume any specific compiler or heavy type annotations for this code, which is quite unusual for me, and a trend I hope to continue.
karmichammer has quit [Ping timeout: 240 seconds]
perrierjouet has joined #commonlisp
<moon-child>
mfiano: if you are trying to not assume any specific compiler, then you should not make assumptions about your code's performance characteristics
<mfiano>
That is correct
<mfiano>
I won't choose a pattern because "it works good on the implementation I use, or most people use". I also refuse to use structs now, and value the extensibility and modularity supplied by standard-class's and generic functions, which conflicts with any goal for ultimate performance anyway (on current implementations anyway)
<EdLangley[m]>
)
<mfiano>
?
<EdLangley[m]>
(hopefully someone opened a paren for that
<mfiano>
)
<EdLangley[m]>
my daughter got to my keyboard
<moon-child>
but, then, why do you want to avoid an intermediate list?
<mfiano>
Because it's been a long time since I used CL and I must have been remembering m-v-c, and it's standard behavior. Besides, this was mostly a question to reduce DRY violations.
unyu has joined #commonlisp
karmichammer has joined #commonlisp
luna-is-here has quit [Ping timeout: 268 seconds]
<mfiano>
I'm still not quite sure how to use it for my problem though.
<mfiano>
But my problem was ill-specified so that's on me.
<semz>
ns12: To me the book feels like a continuation of this inane obsession that people must be taught in "popular" languages and never learn anything else. It doesn't seem to serve any other purpose. Sad, but what can you do.
karmichammer has quit [Ping timeout: 240 seconds]
<Bike>
i can imagine making (lambda (&rest r) (values-list (mapcar f r))) not cons, but it would take a pretty good amount of compiler work
karmichammer has joined #commonlisp
karmichammer has quit [Ping timeout: 240 seconds]
Oladon has quit [Quit: Leaving.]
iamFIREc1 has joined #commonlisp
iamFIREcracker has quit [Ping timeout: 250 seconds]
karmichammer has joined #commonlisp
triffid has quit [Quit: triffid]
karmichammer has quit [Ping timeout: 240 seconds]
waleee has quit [Ping timeout: 240 seconds]
elderK has quit [Quit: Connection closed for inactivity]
karmichammer has joined #commonlisp
jeosol has joined #commonlisp
Everything has joined #commonlisp
karmichammer has quit [Ping timeout: 240 seconds]
ec has joined #commonlisp
parjanya has quit [Ping timeout: 256 seconds]
Common-Lisp has quit [Quit: Leaving]
ec has quit [Ping timeout: 276 seconds]
Oladon has joined #commonlisp
Alfr has quit [Quit: Leaving]
karmichammer has joined #commonlisp
jpl01 has quit [Remote host closed the connection]
<beach>
Good morning everyone!
<ns12>
Good morning beach.
karmichammer has quit [Ping timeout: 256 seconds]
ec has joined #commonlisp
karmichammer has joined #commonlisp
danieli has quit [Remote host closed the connection]
danieli has joined #commonlisp
danieli has quit [Remote host closed the connection]
karmichammer has quit [Ping timeout: 240 seconds]
jealousmonk has quit [Quit: ERC (IRC client for Emacs 27.1)]
<Bike>
i feel like there's probably a way to do it with integer-length, but it gets funny if you provide a power of two
karmichammer has quit [Ping timeout: 256 seconds]
<mfiano>
What do you mean by funny?
notzmv has quit [Ping timeout: 268 seconds]
Alfr has joined #commonlisp
<mfiano>
Bike: ?
<semz>
It's just (ash 1 (integer-length (- n 1))) if you want (next-power-of-2 (expt 2 n)) to be (expt 2 n).
<mfiano>
Right. (ash 1 (integer-length (1- (ceiling n)))) or (expt 2 (ceiling (log n 2))) should work. You can remove CEILING from the first if you don't expect floating-point inputs.
<EdLangley[m]>
It's funny how everyone's solutions look like (ash 1 ...)
<EdLangley[m]>
My inclination was to do (ash n 1) then clear everything but the first bit
parjanya has joined #commonlisp
karlosz has quit [Ping timeout: 256 seconds]
<EdLangley[m]>
I think "clear everything but the first bit" ends up being equivalent to this problem, though
jeosol has quit [Quit: Client closed]
<Bike>
having to subtract one is the kind of thing i meant by "funny". nothing difficult, but also tricky enough that i'm going to have trouble remembering it
<mfiano>
Well the question _did_ ask for the _next_ power of 2. You could remove the #'1- in that case if you don't want >=
<Bike>
let me rephrase: "funny" was more me saying that i'm bad at bit twiddling than anything substantial about the problem
<mfiano>
Hey, we can start a bad at bit twiddling club!
karlosz has joined #commonlisp
wheelsucker has quit [Remote host closed the connection]
wheelsucker has joined #commonlisp
winningluser has joined #commonlisp
winningluser is now known as [w]
[w] has quit [Client Quit]
masinter has quit [Ping timeout: 256 seconds]
<moon-child>
Bike: I was thinking rather of (lambda (&rest r) (values-list (subseq x 0 3))), which seems more reasonable
<Bike>
also tricky but doable
<Bike>
actually i could probably do that one fairly quickly
<moon-child>
the complication would come from the case where there are fewer than 3 values
winningluser has joined #commonlisp
winningluser is now known as [w]
<Bike>
don't think that would be difficult. it's just an error.
karmichammer has joined #commonlisp
EsoAlgo has quit [Ping timeout: 240 seconds]
karmichammer has quit [Ping timeout: 256 seconds]
Jing has joined #commonlisp
Bike has quit [Quit: Connection closed]
karmichammer has joined #commonlisp
karmichammer has quit [Ping timeout: 240 seconds]
EsoAlgo has joined #commonlisp
karlosz has quit [Quit: karlosz]
karlosz has joined #commonlisp
Everything has quit [Quit: leaving]
lisp123 has joined #commonlisp
karmichammer has joined #commonlisp
karmichammer has quit [Ping timeout: 256 seconds]
asarch has joined #commonlisp
karlosz has quit [Ping timeout: 240 seconds]
lisp123 has quit [Remote host closed the connection]
lisp123 has joined #commonlisp
s-liao has joined #commonlisp
s-liao39 has joined #commonlisp
s-liao has quit [Ping timeout: 256 seconds]
aartaka has quit [Ping timeout: 256 seconds]
notzmv has joined #commonlisp
Jing has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
karmichammer has joined #commonlisp
lisp123 has quit [Ping timeout: 250 seconds]
s-liao39 has quit [Ping timeout: 256 seconds]
Jing has joined #commonlisp
karlosz has joined #commonlisp
asarch has quit [Quit: Leaving]
karmichammer has quit [Ping timeout: 256 seconds]
s-liao has joined #commonlisp
karmichammer has joined #commonlisp
karmichammer has quit [Ping timeout: 240 seconds]
rain3 has joined #commonlisp
foxfromabyss has joined #commonlisp
karmichammer has joined #commonlisp
karmichammer has quit [Ping timeout: 240 seconds]
danieli has joined #commonlisp
karlosz has quit [Quit: karlosz]
karlosz has joined #commonlisp
karmichammer has joined #commonlisp
karmichammer has quit [Ping timeout: 250 seconds]
kevingal has joined #commonlisp
pve has joined #commonlisp
Algernon69 has joined #commonlisp
s-liao has quit [Quit: Client closed]
s-liao has joined #commonlisp
igemnace has quit [Remote host closed the connection]
shka has joined #commonlisp
foxfromabyss has quit [Ping timeout: 256 seconds]
Algernon69 has quit [Ping timeout: 268 seconds]
Algernon69 has joined #commonlisp
karmichammer has joined #commonlisp
vats has joined #commonlisp
vats has quit [Client Quit]
vats has joined #commonlisp
jmpeax has joined #commonlisp
luna-is-here has joined #commonlisp
<contrapunctus>
Is there library to access the default applications for an operating system?
<rotateq>
contrapunctus: On which operating system are you running on?
<moon-child>
sounds like fdo-ish crap
<rotateq>
(sometimes also called platform)
<contrapunctus>
rotateq: Linux, but ideally such a library would be cross-platform...
<rotateq>
Maybe you can have a look at uiop, but surely that's just for unix based platforms. I don't know for Windows, Apple or the like.
<rotateq>
Or better I may ask more: Which kind of applications do you want to access?
<contrapunctus>
rotateq: web browsers, PDF viewers, text editors, info viewers, ...
kevingal has quit [Remote host closed the connection]
<rotateq>
Okay :)
Algernon69 has quit [Ping timeout: 268 seconds]
<rotateq>
So getting information from or write data to foreign system processes.
jmpeax has quit [Quit: leaving]
<rotateq>
Oh now I remember, MacOS of course roots from unix too.
karmichammer has quit [Ping timeout: 256 seconds]
pieguy128 has quit [Ping timeout: 256 seconds]
<beach>
contrapunctus: This is the first time I hear the term "default applications for an operating system".
<pjb>
beach: GUI system such as macOS or Windows, and even on Linux, Gnome or KDE, have such a notion. So you can ask the system to open a url with the default browser, and the user can decide whether he uses Safari or Firefox as default browser. Same for email, and other kind of applications.
<pjb>
contrapunctus: There seem to be a generic tool to do that: xdg-settings set default-web-browser brave-beta-bin.desktop
<moon-child>
on linux, this is primarily specified by fdo. That is redhat-ware, which should tell you all you need to know about it
<[w]>
it doesnt
karlosz has quit [Quit: karlosz]
<beach>
[w]: Are you new here? I don't recognize your nick.
attila_lendvai has joined #commonlisp
<phoe>
oh hey [w]
<[w]>
`xdg-open' will also open assumed default applications. like `xdg-open https://examples.com' will attempt to open a browser, or `xdg-open init.el' will open a text editor and so on.
<phoe>
nice to see you around here too
<[w]>
phoe: hey :)
<[w]>
beach: yes
<beach>
[w]: Great. I take it phoe knows you from elsewhere.
<phoe>
beach: t
<[w]>
yep
jpl01 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
cosimone has joined #commonlisp
Algernon69 has joined #commonlisp
Algernon69 has quit [Ping timeout: 240 seconds]
perrierjouet has quit [Quit: WeeChat 3.4]
attila_lendvai has quit [Ping timeout: 268 seconds]
perrierjouet has joined #commonlisp
jmpeax has joined #commonlisp
karmichammer has joined #commonlisp
vats has quit [Ping timeout: 256 seconds]
pieguy128 has joined #commonlisp
pieguy128 has quit [Ping timeout: 256 seconds]
karmichammer has quit [Ping timeout: 256 seconds]
vats has joined #commonlisp
karmichammer has joined #commonlisp
<|smlckz|>
how do i print the nth argument to format?
<|smlckz|>
how do i zip (transpose?) a list of lists? ((1 2 3 4) (5 6 7 8) (9 10 11 12)) ==> ((1 5 9) (2 6 10) (3 7 11) (4 8 12))
<phoe>
|smlckz|: (mapcar #'list '(1 2 3 4) '(5 6 7 8) '(9 a b c))
* |smlckz|
bangs head into the wall several times
<phoe>
mapcar #'list is just one of these magical things :D
johnjaye has quit [Ping timeout: 250 seconds]
tyson2 has joined #commonlisp
<phoe>
it makes total sense once you understand it, but it isn't the most trivial thing to come up with on your own
<|smlckz|>
T
cage has joined #commonlisp
karmichammer has joined #commonlisp
karmichammer has quit [Ping timeout: 268 seconds]
mgl has joined #commonlisp
karmichammer has joined #commonlisp
<beach>
|smlckz|: And if you already have those lists in another list, it is (apply #'mapcar #'list '((1 2 3 4) (5 6 7 8) (9 10 11 12)))
<beach>
... which is one step harder again to come up with on your own.
random-nick has joined #commonlisp
VincentVega has joined #commonlisp
vats has quit [Ping timeout: 256 seconds]
karmichammer has quit [Ping timeout: 256 seconds]
kevingal has joined #commonlisp
s-liao has quit [Ping timeout: 256 seconds]
karmichammer has joined #commonlisp
pranavats has left #commonlisp [Error from remote client]
pranavats has joined #commonlisp
<|smlckz|>
is there a function which is the same of twice doing not?
<phoe>
usually it isn't necessary, but (lambda (x) (not (null x)))
karmichammer has quit [Ping timeout: 256 seconds]
<phoe>
it isn't necessary because every Lisp value is a valid boolean
<phoe>
a concept known as generalized booleans
<phoe>
e.g. to check if a list contains only true values, (every #'identity list) is enough
<|smlckz|>
i want the output of find as an actual instead of generalised boolean
<phoe>
output of find? what do you mean?
<beach>
You already have a generalized Boolean.
<beach>
Oh, sorry misread.
<beach>
But yeah, generalized Booleans should work in all situations.
<|smlckz|>
the output (find item sequence ...) function
<beach>
Why do you need T rather than the element?
<|smlckz|>
is there anything better than (if a t nil)
<beach>
phoe just told you (not (null x)).
<phoe>
there isn't, but the question is why do you explicitly need the output to be EQ to CL:T
<phoe>
it isn't something I encounter often in code, hence my question
<|smlckz|>
i am making a list of truth values from minterms, say, (1 3 6 7) of 3 variables gives (nil t nil t nil nil t t)
<phoe>
oooh, so you *explicitly* want either the symbol NIL or the symbol T
<beach>
And what do you do with those truth values? If you use them in a test, then any true value will do.
<phoe>
in that case, (if ... t nil) would personally be the most readable to me
<phoe>
if you want them for e.g. later readability, that is
<|smlckz|>
hmm
<phoe>
since it would be more readable than e.g. (nil 2 nil #() nil nil (nil) #<STANDARD-CLASS CL-USER:FOO>)
<phoe>
which is equivalent truth-wise, but not really easy to parse
<beach>
So it depends on what they are going to be used for.
karmichammer has joined #commonlisp
<|smlckz|>
i will share my code here for you to see and to give me suggestions for improvements in it
<phoe>
|smlckz|: please use a pastaebin
<phoe>
pastebin*
<phoe>
and sure, let's take a look at it
karmichammer has quit [Ping timeout: 256 seconds]
Dynom has joined #commonlisp
s-liao has joined #commonlisp
karmichammer has joined #commonlisp
silasfox has joined #commonlisp
<|smlckz|>
here's the current state, it's incomplete, much work is needed to be done to call it what it advertises..: http://sprunge.us/NuxKSQ
<|smlckz|>
suggestions welcome
<phoe>
untabify your sources and only use spaces, that's the first one
<phoe>
otherwise your Lisp indentation depends on the program that opens your file
amb007 has quit [Ping timeout: 240 seconds]
amb007 has joined #commonlisp
<beach>
|smlckz|: There is no particular reason to have a newline after `(loop'. If you use the slime-indentation contribution, it will indent the clauses correctly.
<|smlckz|>
phoe: i'm using emacs along with slime
<phoe>
|smlckz|: tell your emacs to never use tabs for Lisp, then
<beach>
|smlckz|: Your choice of parameter names is not great. It is better to use a complete word than one-letter names.
<|smlckz|>
ok
<beach>
|smlckz|: (loop for i from ... to (1- <something>) can be expressed as (loop for i from ... below <something>.
karmichammer has quit [Ping timeout: 240 seconds]
<beach>
|smlckz|: `if ... collect a else collect b' can be expressed as 'collect (if ... a b)'
<pve>
|smlckz|: you can try something like M-x customize-variable RET indent-tabs-mode RET
kevingal has quit [Remote host closed the connection]
<beach>
|smlckz|: The LOOP keyword DO can take more than one form, so no need for PROGN.
<beach>
|smlckz|: LOOP returns NIL by default, so no need to return NIL explicitly afterwards.
s-liao has quit [Quit: Client closed]
<|smlckz|>
hmm, there was a write-line there, after the loop
<beach>
|smlckz|: I recommend you choose better names also for introduced lexical variables.
<|smlckz|>
what do i use instead of n.. is number-of-variables okay?
<beach>
Sure, or I often use ...-count which is shorter. Like variable-count.
amb007 has quit [Read error: Connection reset by peer]
<phoe>
nvars or nvariables maybe - a bit less verbose but still vonveying the intention
<phoe>
conveying*
amb007 has joined #commonlisp
karmichammer has joined #commonlisp
<|smlckz|>
i'm going with nvars then
<mfiano>
I would much rather be explicit with full words
<mfiano>
It isn't very good style to name things short unreadable variables
<|smlckz|>
hmm
<|smlckz|>
how can i make boolean-values into an iterative function instead of recursive?
karmichammer has quit [Ping timeout: 256 seconds]
<yitzi>
|smickz|: Just increment an n-bit integer from 0 to its max value?
<mfiano>
Note it's the cartesian product, not combination
<mfiano>
And alexandria has a tool for this! :)
amb007 has quit [Read error: Connection reset by peer]
<|smlckz|>
&aux?
<phoe>
yes - don't use that one, it can confuse people
<phoe>
it's an obscure way to create local variables, LET and LET* are more readable
<|smlckz|>
hmm, interesting
amb007 has joined #commonlisp
<mfiano>
Added a comment to my gist with the result. Not sure if it is what you are after
<phoe>
mfiano: looks consistent with what my code outputs, so I assume that's OK
karmichammer has joined #commonlisp
<mfiano>
Yeah only difference I can see is mine is sorted
<mfiano>
I am not sure how map-product is implemented. I am too lazy to go look
<|smlckz|>
i'll use external libraries later, but for now i'm sticking to the standard library
karmichammer has quit [Ping timeout: 240 seconds]
<_death>
smlckz: (dotimes (i (expt 2 4)) (format t "~4,'0B~%" i)) .. you can use logbitp to test the value at a particular bit position
<yitzi>
And then maybe use bit-vectors since you are converting back and forth between 1/0 and t/f. Just a thought.
karmichammer has joined #commonlisp
<_death>
it iterates through each permutation.. bit-vectors don't support such an operation.. they're more useful for, say, representing dense sets
amb007 has quit [Ping timeout: 256 seconds]
amb007 has joined #commonlisp
<_death>
the thing about bit-vectors is that they are mutable, unlike integers (think bignums)
karmichammer has quit [Ping timeout: 256 seconds]
<_death>
to get 0/1 you can use ldb.. so (defun logbit (index integer) (ldb (byte 1 index) integer))
johnjaye has joined #commonlisp
wheelsucker has quit [Remote host closed the connection]
wheelsucker has joined #commonlisp
foxfromabyss has joined #commonlisp
vats has joined #commonlisp
amb007 has quit [Ping timeout: 240 seconds]
amb007 has joined #commonlisp
karmichammer has joined #commonlisp
epolanski has joined #commonlisp
Bike has joined #commonlisp
JoshYoshi has joined #commonlisp
Josh_2 has quit [Ping timeout: 240 seconds]
karmichammer has quit [Ping timeout: 256 seconds]
<phoe>
what's the somewhat-agreed naming convention for global non-dynamic variables? =foo=?
JoshYoshi has quit [Ping timeout: 240 seconds]
[w] has quit [Quit: nyaa~]
<_death>
if you mean something like sbcl's defglobal, why not the same as constants (no muffs)?
<phoe>
a bit too close to setting an unbound lexical variable
<phoe>
which looks like a bug unless someone knows that a symbol names a non-dynamic global
<_death>
when you encounter (setf x 123) and don't rely on warnings you need to look at the context anyway.. granted, context of lexical scope is quite limited in comparison.. I wouldn't have muffs.. but global-vars uses "-" and I think I've seen "=", as you mentioned, somewhere too
<phoe>
yes, these are the two I was wondering about
<_death>
sbcl itself seems to use "*"...
<phoe>
single? or double?
<_death>
single.. I guess because they usually move from special to global
amb007 has quit [Ping timeout: 240 seconds]
karmichammer has joined #commonlisp
amb007 has joined #commonlisp
<White_Flame>
earmuffing constants with #\+ is quite standard, even if manyclhs constants are unmuffed
<White_Flame>
but yeah, I'd say #\* is fine for globals, too
<_death>
White_Flame: that's true.. I used that convention as well for a while.. but in recent decade(?) I think I just left them unmuffed, like CL itself
<White_Flame>
this is also something I wish the dev environments would automatically markup in some way
<White_Flame>
another thing that I would really like to be more directly optimized is to have thread-local variables, instead of special, to remove checking for whether the current binding is tls or global
kuao has joined #commonlisp
kuao has quit [Client Quit]
<_death>
what happens if you (let ((*my-thread-local* *my-special*)) (declare (special *my-thread-local*)) ...)
<White_Flame>
same thing as if it were *my-global* iirc, compilation error
wyrd has quit [Ping timeout: 276 seconds]
<_death>
?
<White_Flame>
let me test...
<White_Flame>
oh, the global error comes from attempting a LET, not from a further declaration
<_death>
not sure how we got to a compilation error
<White_Flame>
what's the standard behavior for having conflicting declarations? the innermost one overrides?
<_death>
I'd guess undefined, but better check
<White_Flame>
ok, so declaring a sb-ext:global as special within a body does error: "Can't declare global variable locally special: *GLOB*"
<White_Flame>
I think that's not unreasonable behavior
karmichammer has quit [Ping timeout: 256 seconds]
<_death>
hmm, why would you declare global as special?
<White_Flame>
why would you declare tls as special? :)
<White_Flame>
as per your "what happens if" line
<_death>
I assumed you want special semantics.. otherwise just use a lexical?
amb007 has quit [Read error: Connection reset by peer]
amb007 has joined #commonlisp
<White_Flame>
special = global or tls
<White_Flame>
and most implemenations have to do a runtime check
<_death>
the reason I mentioned declare special is that then you don't have a global
<White_Flame>
global restricts it to one usage, tls would restrict it to the other usage
<White_Flame>
just like defglobal restricts you from binding it separately, TLS would restrict it from having a global value
<White_Flame>
and you can't take a sb-ext global and declare it locally special
<_death>
again.. my remark had nothing to do with defglobal
<White_Flame>
it's a very related declaration
<White_Flame>
that's already implemented and gives a reasonable model to use
<_death>
I think we are miscommunicating.. time for breakfast ;)
<White_Flame>
I'd consider decisions on edge cases such as locally declaring it special to how defglobal behaves
<White_Flame>
because it already went through all those design decisions
waleee has joined #commonlisp
marcoxa has joined #commonlisp
<marcoxa>
Hi there
<White_Flame>
hi
djuber` has quit [Remote host closed the connection]
karmichammer has joined #commonlisp
karmichammer has quit [Ping timeout: 250 seconds]
Algernon69 has joined #commonlisp
wmblathers has joined #commonlisp
<White_Flame>
a question came up in #lisp that I've pondered as well: What do you do when a macroexpansion needs to generate toplevel code (say like a DEFUN, or add data to a DEFVAR initializer) but the macro is not used at toplevel?
<beach>
If it's top-level code, you can use EVAL.
<White_Flame>
I proposed LOAD-TIME-VALUE, but that seems like an unintentional use of that facility.
<White_Flame>
beach: but then when would the EVAL be called?
<beach>
I think it would expand to (EVAL ....).
<beach>
But I haven't thought too hard about it.
<White_Flame>
(defun foo () (my-macro ...)), you'd want the effect fo that EVAL to exist before the lexical my-macro expansion is executed
<beach>
Oh, I see.
<marcoxa>
I am not sure what you mean White_flame.
<qhong>
If it's top-level code it can just expand to `(DEFUN ...)` directly
<White_Flame>
another idea I used in prior code was that the call-site macro would stuff data into a compile-time variable, then a macro usage at the very end would splat out the top-level accumulation of all that info. But that can be error-prone in terms of discipline
<marcoxa>
Looks like qhong's suggests may work. Then you have EVAL'WHEN or plain PROGN.
<White_Flame>
marcoxa: say you want a hashtable that's initialized with data from every non-toplevel macro usage
<qhong>
marcoxa: top-level is easy. Problem is the macro is not at top-level
parjanya has quit [Ping timeout: 256 seconds]
<marcoxa>
The hash-table example still is unclear to me.
<White_Flame>
in my case, it was a DSL, where every usage would have an entry in a central hashtable that the compiler referenced
<White_Flame>
but the DSL usages were never toplevel; they were inline forms
<White_Flame>
so no toplevel macro to generate the central DEFVAR value
<marcoxa>
Ok. So? You have the HT defined beforehand.
<White_Flame>
you want the HT initialized before anything is run
Algernon91 has joined #commonlisp
<White_Flame>
the initialization data comes from the macros scattered throughout the code, that you want all accumulated before any of them are called
<marcoxa>
Isn't that circular?
<qhong>
marcoxa: Or consider my example: I have a `nclo` macro with syntax like (defun make-inc-1 (x) (nclo inc (y) (setf x (+ x y)))), and it need to generate a toplevel `defun` with name `inc`
<White_Flame>
the accumulation shoudlu happen at compile-time
<White_Flame>
or rather, the accumulation should technically happen at toplevel execution time, before any defun is called
<White_Flame>
*before any runtime entry function is called
<White_Flame>
so yeah, the generalized description is for non-toplevel macro usages to generate toplevel code
aartaka has quit [Ping timeout: 256 seconds]
<marcoxa>
Ok qhong. Quite convoluted but that is what (SETF (SYMBOL-FUNCTION 'INC) ...) seems for. Ov course, you do need to use EVAL at macro-expansion time.
<White_Flame>
EVAL at macroexpansion time is lost when reloading fasls
aartaka has joined #commonlisp
Algernon69 has quit [Ping timeout: 268 seconds]
<marcoxa>
True. Then the LOAD-TIME-VALUE suggestion may work.
<marcoxa>
I still think it's convoluted. KISS principle, etc etc etc.
karmichammer has joined #commonlisp
<White_Flame>
that would seem to be the case. I haven't tried it, my prior "working" things required blowing away the fasl cache on each build, or the 2-step macro hack
<qhong>
macroxa: (SETF SYMBOL-FUNCTION) seems the obvious solution, but it has wrong redefinition time semantics. For example, if someone redefined the above MAKE-INC-1, the new INC definition only take effect after MAKE-INC-1 is first called rather than right after redefinition. EVAL during macroexpansion has correct redefinition time, but has wrong compile time behavior. The new definition doesn't get carried over to runtime environment
<White_Flame>
you want KISS for the user, not for the implementer ;)
Jing has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
<White_Flame>
do the hard things once, so that it's easier to use after solved
<White_Flame>
*after it's solved
<marcoxa>
I think many times implementor and luser like to KISS each other :) Haveing said that, I would look more carefully at L-T-V. Just my 2 cents.
<White_Flame>
yep
<qhong>
yep, LOAD-TIME-VALUE looks like the only hopeful direction so far
<White_Flame>
the guarantees in CLHS for it in COMPILE-FILE scenarios seem to put the side effects at the right time. For other C-c C-c style uses, it's probably also okay
amb007 has quit [Ping timeout: 240 seconds]
amb007 has joined #commonlisp
<White_Flame>
it doesn't seem to be the intent of L-T-V, though, hence the questioning here
<White_Flame>
(and it's a cumbersome problem to describe)
rogersm has joined #commonlisp
<mfiano>
Is there a way to combine two multiple-values-returning forms to be a values form with all values, without using an intermediate list?
<rotateq>
|smlckz|: Many thanks, you reminded me to refresh my knowledge on Karnaugh-Veitch and Quine-McCluskey some day again. ^^
<beach>
I think load-time-value is fine if it works for this situation.
wmblathers has quit [Quit: Ping timeout (120 seconds)]
karmichammer has quit [Ping timeout: 240 seconds]
silasfox has quit [Quit: WeeChat 3.4]
Algernon666 has joined #commonlisp
amb007 has quit [Read error: Connection reset by peer]
jstoddard has joined #commonlisp
amb007 has joined #commonlisp
Algernon91 has quit [Ping timeout: 268 seconds]
karmichammer has joined #commonlisp
wmblathers has joined #commonlisp
<mfiano>
Thanks again, and I now finally have a fairly complicated macro working the way I want, after 2 days of repeated trial and error.
<White_Flame>
cool, congrats
<marcoxa>
Way to go...
karmichammer has quit [Ping timeout: 256 seconds]
karmichammer has joined #commonlisp
<mfiano>
Needed a quasi-code-walker. That was my problem.
<mfiano>
Well the biggest one, anyway
<mfiano>
quasi, because it just needed to find and replace leaf nodes in an arbitrary list...not really code, or constructing a syntax tree in any form. I cheated and used TREE-LEAVES from Let Over Lambda, which worked good enough.
<marcoxa>
mfiano: you may have a look at - shameless plug - clast.sourceforge.net
<_death>
sublis?
amb007 has quit [Ping timeout: 256 seconds]
amb007 has joined #commonlisp
<phoe>
_death: AFAIK tree-leaves walks with arbitrary functions for comparison and substitution
<_death>
well, sublis has :test for comparison
<phoe>
sublis would likely work here, too
xaltsc has quit [Remote host closed the connection]
amb007 has quit [Ping timeout: 240 seconds]
jeosol has joined #commonlisp
masinter has joined #commonlisp
amb007 has joined #commonlisp
johnjaye has quit [Ping timeout: 256 seconds]
<mfiano>
_death: I will look into it, thanks! Admittedly, I don't think I have ever used that one, though I have seen it used in the wild before.
attila_lendvai has joined #commonlisp
<mfiano>
I'm not a huge fan of tree-leaves' api to be honest.
<mfiano>
I typically always use (constantly replacement) for its replacement function, for example.
Algernon666 has quit [Ping timeout: 268 seconds]
cosimone has quit [Remote host closed the connection]
cosimone has joined #commonlisp
perrierjouet has quit [Quit: WeeChat 3.4]
<qhong>
Is there a best pratice for defining readable PRINT-OBJECT methods for objects?
<qhong>
Using `#.` looks wacky
<mfiano>
I'm not sure what the correlation is
<mfiano>
#. is for read-time evaluation
karlosz has joined #commonlisp
<qhong>
I need PRINT-OBJECT to produce something that is able to be read back
<qhong>
Producing something like #.(make-instance ...) is one obvious solution
<Bike>
well, it's that or making up your own reader macro
<White_Flame>
why the #. ? just print (make-instance ...)
<White_Flame>
serialization has a ton of identity issues, and *PRINT-CIRCLE* doesn't really solve them
<Bike>
because that will be read back as the list (MAKE-INSTANCE ...), not the actual instance
wmblathers has quit [Quit: Ping timeout (120 seconds)]
<pjb>
qhong: define a reader macro to read the syntax printed by your print-object method!
<qhong>
pjb: Yes that looks sensible. However I'm worried about interoperation in a sufficiently large image. Read syntax are not scoped like symbols and different libraries might clash. Having each library using its own readtable is also not desired because one might want to print nested object with subobjects from different origins.
karlosz has quit [Quit: karlosz]
perrierjouet has quit [Ping timeout: 256 seconds]
<Gnuxie>
what's the name of the portability layer that has stuff like sb-instrospect:function-lambda-list in it?
wmblathers has quit [Quit: Ping timeout (120 seconds)]
<Gnuxie>
qhong: hmm, yeah I thought about that but I'm a little hesitant to depend on it
<qhong>
Gnuxie: there's also `trivial-arguments'
<Gnuxie>
ok, that works, thanks
<_death>
maybe instead of saying "closures are broken", consider saying "closures are optimized for something that I don't care about, here's what I want"
<White_Flame>
for point 3, the symbol's function is disconnected from any lexical bindings. Calling the function creates the lexical variable scope
<White_Flame>
a function is legitimately one half of a closure, and its redefinition I don't think is applicable to closures
<White_Flame>
I do agree with the complaint about introspectability/display
<qhong>
White_Flame: or if you regard closure as an object, it's quite useful to be able to redefine class
VincentVega has quit [Quit: ERC (IRC client for Emacs 27.2)]
<White_Flame>
redefine class is about the data moreso than the functions
tfeb has joined #commonlisp
<qhong>
the other half of closure is data
<White_Flame>
ah, ok
<White_Flame>
I was linking a function+parameter bindings to a closure
<qhong>
I in general find anything impossible to redefine annoying -- I make mistake, and I have some closure floating around in the memory with buggy code
<White_Flame>
s/linking/comparing/
r3st has quit [Remote host closed the connection]
<qhong>
what named-closure does have some caveat (only closed variable with same name is carried over), but IMO better than nothing
<White_Flame>
yep, that was one of my biggest complaints about let over lambda style
<White_Flame>
hmm, with your chosen API, if you have 2 usages of NCLO with the same name, will they trample each others' behavior depending on which NCLO form was last executed?
<qhong>
White_Flame: it will, so you have to use distinct names
<qhong>
I don't have anything better than this in mind so far
<White_Flame>
(defun foo1 () (nclo ...)) (defun foo2 () (nclo ...)) I wonder if the behavior would change at runtime based as FOO1 and FOO2 get called, or if all the trampling happened at load time
<White_Flame>
(with the same nclo name)
<qhong>
At least you will get bunch of style-warnings at compile time I think
<White_Flame>
if you used DEFUN, probably. If you used (setf (symbol-function ...)...) then no
<qhong>
I do use DEFUN and bunch of DEFMETHOD
<qhong>
seems that I actually get 4 style warnings everytime an NCLO is redefined
<White_Flame>
I personally woudl document this as "Externalizes the body of a closure to a DEFUN so that it can be redefined for all instances of that closure"
<White_Flame>
*all existing instances
<White_Flame>
hmm, I guess that's already covered, n/m
amb007 has quit [Ping timeout: 240 seconds]
tfeb has quit [Quit: died]
wyrd has joined #commonlisp
perrierjouet has joined #commonlisp
morganw has joined #commonlisp
hobo has joined #commonlisp
amb007 has joined #commonlisp
foxfromabyss has quit [Ping timeout: 256 seconds]
varjag has joined #commonlisp
amb007 has quit [Read error: Connection reset by peer]
rain3 has quit [Ping timeout: 268 seconds]
amb007 has joined #commonlisp
aartaka has quit [Ping timeout: 256 seconds]
aartaka has joined #commonlisp
hobo has quit [Ping timeout: 256 seconds]
hobo_ has joined #commonlisp
jpl01 has quit [Remote host closed the connection]
aartaka has quit [Ping timeout: 240 seconds]
hobo has joined #commonlisp
hobo_ has quit [Ping timeout: 268 seconds]
azimut has quit [Ping timeout: 276 seconds]
pieguy128 has joined #commonlisp
<EdLangley[m]>
Has anyone tried embedding ECL in a free pascal program?
minion has quit [Remote host closed the connection]
specbot has quit [Read error: Connection reset by peer]
specbot has joined #commonlisp
minion has joined #commonlisp
lispy has joined #commonlisp
drakonis has left #commonlisp [WeeChat 3.1]
gaqwas has joined #commonlisp
drakonis has joined #commonlisp
tyson2 has joined #commonlisp
Algernon69 has joined #commonlisp
Dynom has quit [Quit: WeeChat 3.4]
Algernon91 has joined #commonlisp
fmozturk has joined #commonlisp
fmozturk has left #commonlisp [#commonlisp]
Algernon69 has quit [Ping timeout: 268 seconds]
<mfiano>
_death: SUBLIS is pretty great, but unfortunately, it is pretty primitive, and I don't think it will work as well as TREE-LEAVES here.
<mfiano>
(if at all)
<mfiano>
I think what bothers me most is does not operate strictly on leaves, and thus, ignores the separate function/variable namespace for data that will be turned into code. For example (sublist '((s1 . foo)) '(+ s1 (* s1 s2) (s1 s3))) is probably not what you want in such a case.
<mfiano>
s/sublist/sublis/
<_death>
(i) sublis doesn't operate on leaves, right (ii) your definition of "leaf" is not what I would expect (iii) seems you want a code walker or a symbol macro
gaqwas has quit [Remote host closed the connection]
<mfiano>
No I simply want TREE-LEAVES from LOL :)
<_death>
(not what I would expect when talking about conses and atoms as trees.. if you're talking about the abstract syntax tree, then sure)
<_death>
well, if you want it..
<mfiano>
Its definition of LEAF is what I would expect. I'm not sure what yours would be.
<_death>
do you know what a box and arrow diagram is?
<mfiano>
Do I know what a cons is? Yes.
<_death>
that's not what I asked.. anyway, if you draw a box and arrow diagram, then you can what the leaves in that tree are
<White_Flame>
mfiano: you want deep list elements, not leaves
<mfiano>
Sure, that does make a lot more sense.
<White_Flame>
(and that has a problem with NIL's duality)
lispy has quit [Quit: Leaving]
<White_Flame>
does (1 2 nil 3) have 4 total/deep elements, or 3?
<White_Flame>
and if NIL is a notable element, then what about (1 2 . 3) vs (1 2 . nil)?
hobo_ has joined #commonlisp
<White_Flame>
(i have a LOT of library functions dealing with crap like that :-P)
hobo has quit [Ping timeout: 256 seconds]
<mfiano>
I was wrong anyway.
cage has quit [Quit: rcirc on GNU Emacs 27.1]
<mfiano>
TREE-LEAVES behaves the same way. Shows how much I use the opinionated crap from LOL.
<EdLangley[m]>
The couple times I wanted code-walking, I used agnostic-lizard
<EdLangley[m]>
(for a macro)
<mfiano>
It was one of my favorite functions from that book, likely because I despise anaphora.
<_death>
if you're defining your own small subset of lisp (say for arithmetic expressions) then a simple (non-CL) code walker is easy
<EdLangley[m]>
I think I wanted a way to grab out a specific function
<EdLangley[m]>
HTMX has this concept of partials where you send the whole page from a web endpoint by default, but if there's a specific header you send out a partial
<EdLangley[m]>
I was experimenting with implementing this by having a macro that looked for a specific symbol in function position
<EdLangley[m]>
To reduce duplication
<EdLangley[m]>
Also, I wanted an excuse to try agnostic-lizard
* mfiano
changes his macro to use SUBLIS
<EdLangley[m]>
I go back and forth on anaphora
<_death>
EdLangley[m]: I still need an excuse to try it :).. I don't remember the last time I needed a code walker for more than playing around.. often I settled for a locally "suboptimal" solution that didn't need one
Algernon91 has quit [Read error: Connection reset by peer]
<EdLangley[m]>
I like Clojure’s #(foo % 1)
<EdLangley[m]>
And all my code has a convention of using IT for variable names where I don’t really care about the name
<White_Flame>
I always pass in a variable name
<_death>
otherwise, I defined an interpreter/compiler for the subset I needed.. there, it may sometime be fruitful to try another approach with a code walker
<EdLangley[m]>
Because I generally end up using lambda as a way of delaying an argument
<EdLangley[m]>
Yeah, I like the idea of being compatible with arbitrary lisp
<EdLangley[m]>
Although it’s probably actually a lot harder than it sounde
Devon has joined #commonlisp
<EdLangley[m]>
It would be nice to be able to use CL-CONT with less concerns about the supported special forms
<_death>
there are monad-based implementations of continuations that don't require code walking
<EdLangley[m]>
Yeah, but they sort of require restructuring all your code
<_death>
procedures can look like (defun rdragon (size level) (if (zerop level) (progc (fd size) (returnc 'nil)) (progc (ldragon size (1- level)) (rt 90) (rdragon size (1- level))))) and that's without additional sugar
<EdLangley[m]>
That’s not bad
<EdLangley[m]>
Especially because CL has macros to hide stuff
<qhong>
_death: It starts to look bad when you have to write (letc ((x stuff)) (+ x 3)) instead of (+ stuff 3)... Basically have to write in ANF
<qhong>
which is IMO not much better than writing CPS directly
hobo_ has quit [Ping timeout: 240 seconds]
<EdLangley[m]>
You might be able to symbol-macro that away?
<EdLangley[m]>
Maybe that’s what letc is doing
<_death>
again, it's not that bad since the procedures are small
<qhong>
and in those cases CPS is also not that bad
<_death>
probably
azimut has joined #commonlisp
random-nick has quit [Ping timeout: 240 seconds]
<mfiano>
Wonder if there is anything like alexandria:ensure-list that optionally conses the atom onto an existing list. Maybe something like: (defun foo (thing &rest rest) (if (listp thing) thing `(,thing . ,rest)))
<phoe>
sounds a bit too specific
<mfiano>
I always feel like I am inventing these weird utility functions for an odd use-case only to find out years later that someone beat me to it.
<EdLangley[m]>
SERAPEUM:UNSPLICE?
* mfiano
checks
<EdLangley[m]>
Hmm, maybe not
<mfiano>
No, definitely not
<moon-child>
no ,@?
varjag has quit [Ping timeout: 250 seconds]
<EdLangley[m]>
Hmm, is this LIST*?
cosimone has quit [Quit: ERC (IRC client for Emacs 27.1)]
<phoe>
it's like (if (listp thing) thing (cons thing some-other-list))