jackdaniel changed the topic of #lisp to: Common Lisp, the #1=(programmable . #1#) programming language<http://cliki.net/> logs:<https://irclog.whitequark.org/lisp,http://ccl.clozure.com/irc-logs/lisp/> | SBCL 1.4.5, CMUCL 21b, ECL 16.1.3, CCL 1.11.5, ABCL 1.5.0
kozy has quit [Remote host closed the connection]
kozy has joined #lisp
Tordek has joined #lisp
robotoad_ has quit [Quit: robotoad_]
Tordek has quit [Ping timeout: 252 seconds]
Tordek has joined #lisp
Kundry_Wag has joined #lisp
slyrus2 has joined #lisp
slyrus has quit [Ping timeout: 268 seconds]
slyrus2 is now known as slyrus
slyrus is now known as 7YSAAYF24
Kundry_Wag has quit [Ping timeout: 244 seconds]
razzy has quit [Ping timeout: 244 seconds]
themsay has joined #lisp
Kundry_Wag has joined #lisp
Kundry_Wag has quit [Ping timeout: 244 seconds]
impulse has joined #lisp
warweasle has joined #lisp
impulse has quit [Ping timeout: 252 seconds]
anamorphic has quit [Ping timeout: 268 seconds]
sword` has quit [Remote host closed the connection]
robotoad has joined #lisp
sword` has joined #lisp
<kooga> skidd0: I think lack.response:response-headers is setf-expander. you can use setf.
<kooga> (ql:quickload :lack-response)
<kooga> (setf (lack.response:response-headers *response*) '(:access-control-allow-origin "*"))
<skidd0> that *response* is part of ningle
<skidd0> i saw that stackoverflow thread
<skidd0> that's about the closest i've gotten in reference
<skidd0> also, i figured out that I needed to add a options verb to the routing library i'm using (snooze)
<skidd0> so now the cors OPTIONS pre flight request returns a 200
<skidd0> but then the POST returns 400 Bad Request
pjb has quit [Ping timeout: 252 seconds]
wanz has joined #lisp
anamorphic has joined #lisp
semz has quit [Ping timeout: 252 seconds]
Oladon has joined #lisp
wanz has quit [Quit: wanz]
robotoad has quit [Max SendQ exceeded]
pjb has joined #lisp
wanz has joined #lisp
Kundry_Wag has joined #lisp
robotoad has joined #lisp
Kundry_Wag has quit [Ping timeout: 244 seconds]
robotoad has quit [Client Quit]
wanz has quit [Quit: wanz]
GoldRin has quit [Read error: Connection reset by peer]
wanz has joined #lisp
robotoad has joined #lisp
pjb has quit [Ping timeout: 264 seconds]
Kundry_Wag has joined #lisp
Kundry_Wag has quit [Ping timeout: 244 seconds]
hvxgr has quit [Quit: leaving]
nullniverse has quit [Remote host closed the connection]
nullniverse has joined #lisp
<beach> Good morning everyone!
<LdBeth> morning, beach
nowolfer has quit [Ping timeout: 260 seconds]
nowolfer has joined #lisp
nullniverse has quit [Quit: Undertaking stack overflow prevention]
anamorphic has quit [Ping timeout: 252 seconds]
warweasle has quit [Quit: rcirc on GNU Emacs 24.4.1]
Kundry_Wag has joined #lisp
arescorpio has joined #lisp
Kundry_Wag has quit [Ping timeout: 244 seconds]
wanz has quit [Quit: wanz]
rumbler31 has joined #lisp
rumbler31 has quit [Ping timeout: 264 seconds]
Kundry_Wag has joined #lisp
Kundry_Wag has quit [Ping timeout: 264 seconds]
Lycurgus has joined #lisp
<russellw> morning!
<Lycurgus> moin russellw
<beach> How does SBCL optimize SLOT-VALUE?
lnostdal has quit [Read error: Connection reset by peer]
<no-defun-allowed> can cl-tesseract use libtesseract.so.4?
<Bike> looks like if the slot name is constant it rewrites it to go through a reader
<beach> Oh, so it creates a reader for the slot?
<Bike> maybe. code is a little confusing.
<beach> I can imagine. :)
<beach> Anyway, there can't be that many ways of doing it.
<beach> What I though of this morning was essentially that.
<beach> In a first-class global environments, I have a table called slot-readers and a table called slot-writers. These tables are indexed by symbol names.
<Bike> in ecl and clasp direct instances of standard object use a hash table from slot names to locations.
<beach> Oh, that's not so great.
<beach> ... then those tables work like the function entries in the first-class global environment.
<beach> i.e., they contain function CELLS.
<beach> Each cell contains a generic function (the reader/writer).
<beach> slot-value with a constant slot name gets rewritten to (funcall (car (load-time-value (find-reader-cell <name>))))
<beach> Or, not rewritten, exactly. The compiler recognizes it.
<beach> Then I can use the ordinary generic dispatch mechanism.
<beach> I think SBCL must do the same, modulo the first-class global environment, and the function cell.
<Bike> it... might be using a funny function name instead of a table, but yeah i think so.
<beach> Sure, because they don't have first-class global environments.
<beach> But Clasp slot readers don't use SLOT-VALUE, I hope.
<Bike> think it goes through slot-value-using-class
<Bike> for the slow path, i mean
<beach> My question was about a :READER slot option.
<beach> How does that reader access the slot value?
<Bike> also wait, what happens if you have like (defclass foo () ((x :reader foo-x))) (defclass bar () ((x :reader bar-x))) (slot-value some-object 'x)
<Bike> let me check what reader methods do
<Bike> slow path reader does go through slot-value.
<Bike> i guess i could fix it to go through slot-value-using-class
<beach> What is "slow path reader" and is there a fast path?
<beach> In my scenario, (slot-value some-object 'x) would be translated to something like (funcall (car (load-time-value (find-reader-cell 'x))) some-object) and the cell would contain a generic function that dispatches on the class of some-object.
skidd0 has quit [Quit: WeeChat 2.2]
<Bike> if the effective method just calls the accessor method, the discriminating function just reads from or writes to the slot directly
<Bike> so there has to be a new generic function? ok.
<beach> Yes.
<beach> But that's fine, because we have fast generic dispatch.
<Bike> just making sure i understand
<beach> Of course.
<beach> Well, let's hope Clasp and ECL don't use SLOT-VALUE a lot.
<beach> Nor SLOT-VALUE-USING-CLASS for that matter.
<Bike> they don't. i mean if the slot name is constant you might as well use an accessor.
<beach> Yeah.
<beach> Unless you program like jmercouris has done up to now.
makomo has quit [Ping timeout: 240 seconds]
<Bike> also the fast path i mentioned only happens if it's an object standard enough to not have custom slot-value-using-class methods possible. forgot that caveat
<beach> Also, until a few years ago, I used slot-value for "internal" access, and slot accessors only for the public interface.
<LdBeth> Seems in most case accessor is fast
<beach> Bike: I see, yes.
<Bike> i'm not sure what the main reader method can do besides calling slot-value-using-class, i guess
<Bike> could be avoided if the object is standard enough...
<beach> Bike: You mean in the general case?
<Bike> yeah
<beach> I think that's true.
<beach> Think about Costanza's implementation of LETF.
<beach> He had classes where slots were implemented as special variables so as to make it thread safe.
<beach> Then there is no "location" for the slot.
<aeth> What I tend to do for internal setting is :accessor %foo :reader foo because that way I can use with-accessors on %foo without surprising behavior (i.e. only being able to set)
<beach> Bike: Have you seen this work by Costanza?
arescorpio has quit [Quit: Leaving.]
<Bike> probably not specifically, but there was similar stuff in contextl, and i get the idea
pillton has quit [Remote host closed the connection]
<beach> Bike: Right. That's what I mean.
<beach> So, in that case, SLOT-VALUE can not be optimized to do a direct slot access, of course, since there is no slot-location.
<Bike> yeah.
<Bike> i have been thinking on and off about adding more interdependencies between methods in fastgf. for example, within a method body replace accessors with direct slot reads when possible, and then recompile the method if there's a change so it works transparently
<Bike> i bet it would make it faster, but it would be pretty involved to maintain everything correctly
<beach> Yes, I see. Good idea, though.
<Bike> really get our money's worth out of the mop dependencies mechanism that nobody uses
<beach> That, or, since you control the implementation, have your own mechanism.
<Bike> practically speaking it would probably be that one, but still :p
<beach> Sure.
<beach> So, I think I'll have to add SLOT-READERS and SLOT-WRITERS to the SICL first-class global environments.
<beach> Not today, though. :)
<Bike> you could do something similar with typep if you want to allow arbitrary redefinition.
<Bike> not so much for compound types though...
<beach> Wow, that's a good idea.
<beach> Right.
<beach> Often, there is no other portable mechanism to use.
<beach> So optimizing it could be a huge win.
<beach> Bike: That smells like an ELS paper to me.
Kundry_Wag has joined #lisp
<beach> This stuff is frequently done "manually": (defgeneric foop (x) (:method (x) nil) (:method ((x foo)) t))
<beach> Bike: Let me take a break and think about that idea. I think better when I am not at my computer.
<beach> Compound types with OR, AND, NOT could be handled.
<beach> Anyway, taking a break.
pjb has joined #lisp
Kundry_Wag has quit [Ping timeout: 264 seconds]
<Bike> not sure i've ever done that "manually"... i can imagine it though.
Bike has quit [Quit: Lost terminal]
_whitelogger has joined #lisp
<beach> minion: memo for Bike: This is totally brilliant. I am convinced that it works. 1. Figure out whether any implementation does it. 2. If not, figure out what happens to the methods and call history as a result of DEFCLASS, and DEFTYPE. 3. Write it down. 4. Submit to ELS.
<minion> Remembered. I'll tell Bike when he/she/it next speaks.
Oladon has quit [Quit: Leaving.]
<beach> minion: memo for Bike: There would be three kinds of methods: always false, always true, and requiring some action (for example if there is a DEFTYPE that expands to a compound type).
<minion> Remembered. I'll tell Bike when he/she/it next speaks.
impulse has joined #lisp
linack has quit [Remote host closed the connection]
impulse has quit [Ping timeout: 240 seconds]
pjb has quit [Ping timeout: 252 seconds]
_whitelogger has joined #lisp
Lord_of_Life has quit [Ping timeout: 246 seconds]
razzy has joined #lisp
Kundry_Wag has joined #lisp
pjb has joined #lisp
Kundry_Wag has quit [Ping timeout: 252 seconds]
jack_rabbit has quit [Ping timeout: 252 seconds]
jack_rabbit has joined #lisp
robotoad has quit [Ping timeout: 252 seconds]
robotoad has joined #lisp
ggole has joined #lisp
ryan_vw has quit [Ping timeout: 252 seconds]
ryan_vw has joined #lisp
shka_ has joined #lisp
rippa has joined #lisp
pjb has quit [Ping timeout: 252 seconds]
dddddd has quit [Remote host closed the connection]
impulse has joined #lisp
gector has quit [Read error: Connection reset by peer]
gector has joined #lisp
orivej has quit [Ping timeout: 246 seconds]
Lycurgus has quit [Quit: Exeunt]
shrdlu68 has quit [Ping timeout: 240 seconds]
Kundry_Wag has joined #lisp
emaczen has quit [Read error: Connection reset by peer]
emaczen has joined #lisp
Kundry_Wag has quit [Ping timeout: 272 seconds]
trittweiler has joined #lisp
FreeBirdLjj has joined #lisp
adam4567 has joined #lisp
makomo has joined #lisp
_whitelogger has joined #lisp
ryan_vw has quit [Ping timeout: 252 seconds]
eschatologist has quit [Remote host closed the connection]
lavaflow has quit [Read error: Connection reset by peer]
lavaflow has joined #lisp
themsay has quit [Ping timeout: 252 seconds]
eschatologist has joined #lisp
eschatologist has quit [Remote host closed the connection]
mejja has joined #lisp
mejja has quit [Quit: mejja]
angavrilov has joined #lisp
lavaflow has quit [Read error: No route to host]
lavaflow has joined #lisp
trittweiler has quit [Ping timeout: 264 seconds]
<makomo> morning
<no-defun-allowed> hi makomo
adam4567 has left #lisp ["ERC (IRC client for Emacs 24.5.1)"]
themsay has joined #lisp
pjb has joined #lisp
themsay has quit [Ping timeout: 240 seconds]
Kundry_Wag has joined #lisp
faraco has joined #lisp
<makomo> hah, today is the day when i finally used a full spec instead of just a symbol for ONCE-ONLY
<makomo> (alexandria:once-only ((indices `(copy-seq ,indices))) ...)
themsay has joined #lisp
Kundry_Wag has quit [Ping timeout: 240 seconds]
vlatkoB has joined #lisp
stereosphere has quit [Read error: Connection reset by peer]
asymptotically has joined #lisp
faraco has quit [Quit: Leaving]
Kundry_Wag has joined #lisp
<oni-on-ion> just thinking.. why wasn't it (. a b) instead of (a . b) ?
<jackdaniel> . is just a notation for a data structure (like #(1 2 3) is for vector), it is not a function
<ggole> Infix . plays nicer with list notation
doubledup has joined #lisp
doubledup has quit [Remote host closed the connection]
svillemot has quit [Quit: ZNC 1.6.5+deb1+deb9u1 - http://znc.in]
<no-defun-allowed> oni-on-ion (IRC): where do you put it if you have (a b . c)?
Kundry_Wag has quit [Ping timeout: 244 seconds]
svillemot has joined #lisp
<|3b|> (x a b) is (x . (a . (b . nil))), which would make (. a b) confusing
<no-defun-allowed> if you do (a (. b c)) you break the expectations of depth - is it (a b . c) or (a (b . c))?
<oni-on-ion> if its (. a b) then its all sexp, wouldnt it be less confusing ?
<no-defun-allowed> nope
<oni-on-ion> no, just renaming cons to .
<oni-on-ion> not that different in order of eval lol
<oni-on-ion> i dont see the mental acrobatics
<no-defun-allowed> if it's (. a b), . looks like an operator and not a cons
<oni-on-ion> but cons is (cons a b) .....
<aeth> If it was anything else it'd probably be #.(a b) but then you wouldn't have it combined with the list representation and (a b . c) wouldn't be an obvious representation for a dotted list
<aeth> (you couldn't do that now because #. is taken)
<no-defun-allowed> again, tell me how it'd work for [ A | @ ]->[ B | C]
<|3b|> what would (cons . a) be then?
<oni-on-ion> it would be (. cons a) ?
<oni-on-ion> cons would just be . , of course
<|3b|> (. . a)?
<oni-on-ion> no-defun-allowed: same way of using cons.
<oni-on-ion> |3b|: hm i dont follow
* |3b| doesn't either, i probably don't actually have any good point :p
* |3b| will go back to trying to figure out android tools :/
<oni-on-ion> perhaps i dont see the purpose of (a b . c) aside from being a bit strange considering lispisms
<oni-on-ion> err sexpyness
<|3b|> probably not much point these days
<no-defun-allowed> so, (. a (. b c))?
<oni-on-ion> we may be used to '.' being specially treated
<oni-on-ion> just like cons
<oni-on-ion> ^
<oni-on-ion> ie. imagine (a b cons c) .. looks a bit wierd. not prefixy
<no-defun-allowed> admittedly, it's fair cause it's a break from proper lists
<phoe> only one element is allowed after the dot
<phoe> since the element after the dot denotes what is in the last CDR of that list
<no-defun-allowed> good point
<no-defun-allowed> when you
<phoe> (a . b) denotes a cons whose CAR is A and CDR is B
<oni-on-ion> phoe: yeah, but its just syntax for cons isnt it? thats the point here, why its in between a and b and not prefix like everything else of lisp system
<phoe> (x y z a . b) denotes the same thing, except three conses are consed on top of that to form an improper list, with CARs X, Y, and Z
<oni-on-ion> oh, reads..
<phoe> oni-on-ion: how would you do that prefix style?
<oni-on-ion> phoe: ok i think i start to see that.
<no-defun-allowed> *when you're parsing, you see a paren. ooh, a list! let's see the first element. A it is. see the rest and stuff it into a cons. you see a B. see the rest again. you see...oh god a period! just return the C. cons B and C, you have (B . C). cons A to it, you finish with (A B . C)
<phoe> . is not an operator
<phoe> . is a part of the lisp syntax
<oni-on-ion> what is (cons a . b) ?
<phoe> an error
<no-defun-allowed> nothing, it doesn't work
<phoe> if you try to call that as a function, that is
<phoe> #'CONS is a function and accepts two arguments
<phoe> function calls must be proper lists in Lisp
<oni-on-ion> different than #'. ?
<phoe> #'. does not exist
<ggole> Seems like confusion between reader syntax, which directs the reader to construct list structure, and the functions used to construct it
<oni-on-ion> how is . different than cons, phoe ?
<phoe> that . is a part of the syntax and cons is a function
<oni-on-ion> i cant tell if im missing an important concept here
<phoe> yes - . is not a function
<phoe> it's not an operator
<oni-on-ion> right. i know that, and that
<phoe> it's a part of the syntax that is processed by the reader.
<oni-on-ion> so i am saying, its syntax sugar for cons.
<oni-on-ion> for consing*
<phoe> not really
<phoe> reading a list conses on its own
<oni-on-ion> k so what am i missing
<phoe> so reading (a b c) already calls CONS three times
eschatologist has joined #lisp
<oni-on-ion> hm, yea..
<phoe> once, to read the cons with CAR A, once, to read the cons with CAR B, once, to read the cons with CAR C
<oni-on-ion> so implicitly (a b c . nil) ?
<phoe> yes
<makomo> oni-on-ion: just like #' and ' operate at the reader level, . does as well
<no-defun-allowed> yes
<phoe> these two are equivalent
<oni-on-ion> hmmm making more sense
<phoe> . tells the reader "okay, you don't need to cons more, just stuff this thing after the period in the CDR and you're done"
<phoe> and (x . nil) is equivalent to (x)
<oni-on-ion> so there is purpose to it being the syntax in the form of "(a . b)" and not "(. a b)" ?
<phoe> yes
<phoe> you can only stuff one thing in the CDR
<phoe> also, what you mention, is actually a function
<oni-on-ion> ah, so then... it is not just not prefix, it is especially before-last-fix
<phoe> (list* a b) ;=> (a . b)
<no-defun-allowed> yep
<phoe> (list* a b c d e f) ;=> (a b c d e . f)
<oni-on-ion> ahh =) i think i get it now =) thanks. i was just trying to sleep and thought of this. quite cool actually ^_^ always really liked linked lists.
<phoe> basically
<phoe> . is a part of the reader syntax
<phoe> whereas #'cons, #'list, #'list* are functions
<oni-on-ion> yes
<phoe> . doesn't do *anything* on its own
<phoe> it just stands there, waiting to be interpreted by the Lisp reader
<phoe> and where does it stand? in the text representation of course
<phoe> the reader operates on strings, and "(a b . c)" is such a string
<phoe> the concept of . is lost by the time you leave the reader and you get the read expression
<phoe> it's all conses and atoms by the time you leave the reader
<phoe> there's no cons mentioning a . and no atom mentioning a .
<oni-on-ion> hmm right.. cool =)
<phoe> you can only infer that there was a . somewhere by parsing the lists made up of the conses, and by noticing that some CDR is a non-null atom
<phoe> and in this case, there's no difference between the result of the function call (CONS 'A 'B) and the result of the reader reading "(A . B)"
<phoe> they're just equivalent by then.
<phoe> so the same result, a cons whose CAR is A and CDR is B, can come both from a #'CONS call and from the reader's operations.
<makomo> what does everyone think of the following "problem": say i want to swap two rows of a matrix and i want a neat set of places for my interface. so i define something like (mrow mat i) which returns a fresh vector representing mat's i-th row, and ((setf mrow) vec mat i) which sets a mat's i-th (receiving a vector as a value and doing it element-wise).
<makomo> but then, let's say i want to swap a mat's rows without creating an intermediary vector. (rotatef (mrow mat i) (mrow mat j)) would create a fresh vector since it evaluates (mrow mat j) before assigning. i could define my own (swap-row mat i j) but then that doesn't play nicely with places.
<makomo> in general, the problem is that setf isn't "fully composable", because the expansion for a place cannot depend on the the form that produces the value to set. for example, i would like for (rotatef (mrow mat i) (mrow mat j)) to expand into a fully in-place swap of the rows (composition of smaller rotatefs). (rotatef (mrow mat i) (get-some-vec)) however would behave just as before.
<makomo> so basically, we would have the ability to analyze the value-producing forms as well and generate expansions of places using that information.
<makomo> i don't know whether this would make SETF better or worse. you get more composability and flexibility but perhaps SETF would become irregular, as you would have no proper separation of (1) eval the value-producing form and (2) set the place's value using its expansion and the produced value
<makomo> the two would be merged into one
frodef has joined #lisp
robotoad has quit [Quit: robotoad]
<phoe> don't use SETF for that - it has a strict order in which its evaluates the forms.
<no-defun-allowed> hi frodef
<makomo> so you could encode any conceptual "assignment operation" into a SETF call, and let the expander generate code that would do that work
<phoe> hm.
<makomo> phoe: yeah, but that's what the thought experiment is about. the ordering between individual assignments would still stay, but there would be no separation between the two phases of getting the value and putting the value somewhere
<makomo> because an expansion might be able to do a better job when there is no separation (in this case, i wouldn't have to cons a new vector just to swap 2 rows)
<phoe> theoretically you have control over SETF in form of define-setf-expander, but I think it would be somewhat confusing.
<makomo> phoe: that's still not enough, because a setf expander doesn't have access to the value-producing form
<phoe> yep, that's a SETF limitation.
<phoe> for example, the expansion of (setf (subseq #(0 1 2 3) 0 2) (subseq #(5 6 7 8) 0 2)) also conses up a new vector.
<makomo> i.e. (setf (mrow mat i) <something>) -- mrow's expansion can't get to <something>
<makomo> yeah :/
<phoe> this could be replaced by a very small and efficient loop, but SETF is too limited to be able to do that.
<makomo> yup
<phoe> it's the compiler's job to notice and optimize this.
<makomo> i wonder whether such a setf would be useful
<makomo> i mean, it certainly would, but i wonder to what extent
<aeth> I actually do something similar to that.
<aeth> (setf (array-row-of-4 foo 42) (values 1f0 2f0 3f0 4f0))
<aeth> Notice that (1) the row size is in the name of the setf and (2) I use multiple values as the input
<makomo> i thought about VALUES as well, but it won't work with "compound objects" that have a large number of "components"
<makomo> "won't work" meaning that VALUES itself would probably start to cons
heisig has joined #lisp
random-nick has joined #lisp
<aeth> Swapping a row is pretty simple if you're willing to put it in a function. Very elegant, actually, since you can just swap the elements via PSETF in a loop.
<makomo> the cool thing is that this "composable setf" could also expand into further such setfs, etc.
<makomo> aeth: true. that's what i ended up doing in the end, but it doesn't play nicely with places. also, i have NxN matrices, so i can't use PSETF
<makomo> unless you were thinking of using PSETF for the swapping of the individual elements, in which case you can just use ROTATEF
<aeth> I never used rotatef before so I wasn't aware of its use there.
<makomo> :-)
<aeth> This is probably the only case I've ever seen where it's useful.
<makomo> hah, yeah
<makomo> now imagine a composable ROTATEF, you could swap literally anything without inducing overhead. swapping two matrix rows would just expand into multiple ROTATEFs between the individual elements
<makomo> or actually, into a loop which would do the ROTATEFs
lumm has joined #lisp
<aeth> (let ((m (make-array '(2 4) :element-type 'single-float :initial-contents '((1f0 2f0 3f0 4f0) (5f0 6f0 7f0 8f0))))) (rotatef (array-row-of-4 m 0) (array-row-of-4 m 1)) m) => #2A((5.0 6.0 7.0 8.0) (1.0 2.0 3.0 4.0))
<russellw> If I do (setq x 1) at the top level with no previous declaration of x, it actually works, to my surprise. What kind of variable does that create? Is it a special variable, the kind that would be created by defvar?
<makomo> russellw: it's undefined behavior :-)
<russellw> Ah! Okay, let me rephrase: in SBCL and CCL, what kind of variables does it create?
<makomo> aeth: and ARRAY-ROW-OF-4 is a function which returns multiple values, right?
<aeth> exactly
<makomo> russellw: it probably does ""the right thing"" and proclaims the variables special, but i don't know for sure
<no-defun-allowed> according to describe, it's an undefined variable with value 1
<no-defun-allowed> describe calls defvar-ed variables special
<russellw> thanks!
<makomo> aeth: that's a nice trick for a small number of components, but for larger Ns, you're back at consing and what not
<heisig> makomo: You could use a compiler macro for (setf mrow) that eliminates the intermediate copy if given a call to mrow as an input.
<phoe> actually they're global but lexical
<phoe> which is weird
<phoe> (setf x 1) (defun foo () x) (let ((x 2)) (foo)) ;=> 1
<aeth> makomo: and, yes, I don't bother going above 4
<russellw> It's a pity that behavior is not defined; global but lexical is sometimes useful
<aeth> makomo: the consing threshold is probably higher than you think, though, and might be entirely optimized away.
<|3b|> phoe: declare the local X special and foo will see it
<makomo> heisig: hmm, interesting idea. but do i have the guarantee that SETF will call my setter with the value-producing as is, instead of say, evaluating it, storing it into a local variable and then passing that variable to my setter
<phoe> |3b|: d'oh
<phoe> thanks, you're right
<|3b|> so it seems to be special on sbcl at least
<makomo> value-producing form as is*
<|3b|> but not declaimed like defvar would
lumm has quit [Quit: lumm]
<phoe> yes, it's my mistake
lumm has joined #lisp
<|3b|> i think at least one implementation does something else though, maybe one of the commercial ones?
<makomo> aeth: yeah, probably, but i'd still like to have a general mechanism that could handle a large number of components as well
<aeth> My composition is designed for small rows, it even manually loop unrolls it.
<makomo> neat :-)
<aeth> (well, I set up the loop in a macro rather than do the loop at runtime... should be better for 4, probably not for 16)
python476 has joined #lisp
themsay has quit [Ping timeout: 252 seconds]
themsay has joined #lisp
Kundry_Wag has joined #lisp
<heisig> makomo: A combination of compiler macros and a custom, composable SETF (CSETF?) might work. I will think about this, because I really like the idea of doing (crotatef (row a i) (row b j)).
<makomo> heisig: i thought of naming it SETF* at first, but that's not a bad idea either
<makomo> heisig: glad you like it :-), keep me posted
<heisig> Sure.
robotoad has joined #lisp
<makomo> heisig: however, if you're already "reinventing" setf, i.e. implementing your own, do you really need compiler macros then?
<pjb> oni-on-ion: you must be careful, people write confusing things. For example, <phoe> (list* a b c d e f) ;=> (a b c d e . f) is wrong. Actually, (list* a b c d e f) -> (the-value-of-a the-value-of-b the-value-of-c the-value-of-d the-value-of-e . the-value-of-f)
<makomo> you just write your own mechanisms of registering an "assignment expander", which takes into account both the destination and the source forms, and generates whatever
Kundry_Wag has quit [Ping timeout: 252 seconds]
<pjb> oni-on-ion: . is not syntax for *the* function cons, it's syntax for *a* cons cell.
<oni-on-ion> ah true, ok =)
<pjb> oni-on-ion: in lisp, things can be computed at different times: read-time, compilation-time, macro-expansion-time, load-time, run-time. And with the use of #. eval compile load-time-value and other operators, you can freely embeb one time in the other.
<pjb> But basically, syntax, and reader macros, are read-time operations. The purpose is to obtain a lisp object that has been "read" from some characters with some syntax.
<pjb> Once the reading has been done, the lisp object has been created, and it becomes a literal object. (it should be considered immutable).
<russellw> Are there any pitfalls with eval that I should watch out for? I have tested it on a complex form including defstruct and defun, and disassembled a resulting compiled function, and everything seems to work just the way it would if the evaluated code had been part of the program in the first place
<pjb> If an implementation provided operators to make immutable objects, reader macros could use them.
<pjb> russellw: CL:EVAL doesn't take an environment argument, so it works in the global environment.
<russellw> right, this is good
<pjb> oni-on-ion: there's however a trap here: a reader macro can read not the final object you'd want, but instead a sexp, which when evaluated, will produce the final object!
<pjb> (values (type-of (quote #P"/tmp/")) (type-of (quote #'foo))) #| --> pathname ; cons |#
<pjb> #P reads a pathname. Also, this means that you cannot read eg. a logical pathname without having first defined the logical hosts. Sometimes, you'll have to use logical namestrings instead of #P.
<pjb> On the other hand, #'foo reads the expression (CL:FUNCTION foo). This expression needs to be evaluated to obtain the function.
<pjb> Notably, if you use #' in a literal list, it won't be evaluated, so you won't get a function in there!
<pjb> (defparameter *my-funs* '( #'sin #'cos #'tan )) ; wrong! Also, it's confusing because the printer usually prints (CL:FUNCTION foo) as #'foo: *my-funs* #| --> (#'sin #'cos #'tan) |#
<pjb> this is actually a list of list, not a list of functions.
<pjb> (defparameter *my-funs* (list #'sin #'cos #'tan )) ; you need a run-time list; then: *my-funs* #| --> (#<Compiled-function sin #x3000000AC95F> #<Compiled-function cos #x3000000AD26F> #<Compiled-function tan #x3000000AE64F>) |# this is a list of functions!
<pjb> Of course, you can evaluate #'foo only if foo has already be defined. If not, you have to keep the function name 'foo instead of the function itself #'foo.
<pjb> Then you can use it in a literal list: (defparameter *my-funs* '(sin cos tan)) *my-funs* #| --> (sin cos tan) |# a list of symbols, naming functions, known or future.
<heisig> makomo: I don't know whether one needs compiler macros here. I like them because you can get the (foo x) case fast, while still allowing the (apply #'foo (list x)) case.
<pjb> So <phoe> whereas #'cons, #'list, #'list* are functions is wrong too. #'foo is NOT a function, it's a list: (type-of (quote #'foo)) #| --> cons |#
<pjb> #'foo EVALUATES to a function, if a function is defined with that name, or signals an error: #'foo #| ERROR: Undefined function: foo |#
<makomo> heisig: mhm, good point
<pjb> russellw: EVAL is only good to implement a REPL or LOAD. If what you're doing could be done at the REPL, or by saving the sexps in a file and loading it, then you're good.
<russellw> pjb, right; I'm working on a machine learning project, so if the generated code ends up working the same as it would if I had written it in a file and loaded it, this is good
<pjb> So the result of your learning is some generated lisp code?
<pjb> your machine learning
<russellw> yes
<pjb> Does this code need to be integrated into the machine learning environment?
<russellw> It needs to call functions defined in the environment, yes
<pjb> But the machine learning program cannot call or use those new functions and types directly.
igemnace has joined #lisp
<russellw> well, except for calling the 'do-stuff' function, where do-stuff is by convention the name of the entry point to the generated code
<pjb> Anyways, if you generate defstructs and other types, you need to use EVAL to integrate them to be used by your generated functions.
<russellw> right, that's how I was hoping it would work
<pjb> For the functions you may consider just defining them as anonymous functions that you would keep in your data structure and call them from there with funcall or apply (setf (gethash (generate-function-identifier) *funcs*) (compile nil `(lambda () ,expression)))
<pjb> If you use eval defun, you may want to intern the name of the functions in a specific package, to avoid redefining a function of the program.
<russellw> yeah, the more transient functions might be best handled that way
<pjb> gensym works too.
FreeBirdLjj has quit [Remote host closed the connection]
<russellw> gensym is very handy
<pjb> So you seem good.
<russellw> thanks!
<pjb> Now for the problem of closures , you can always have something like: (let ((x 42)) (eval `(let ((x ,x)) (defun foo () x)))) ; ie. you re-create an independent closure with EVAL. Since the outer let was compiled in your program, it couldn't know that you would need it as a closure for a run-time generated function. So you can only recreate a similar closure at run-time.
<pjb> So while eval accesses only the global environment, you can still use it to define NEW lexical environments.
<russellw> right
Kundry_Wag has joined #lisp
nowolfer has quit [Remote host closed the connection]
Kundry_Wag has quit [Ping timeout: 240 seconds]
FreeBirdLjj has joined #lisp
Lord_of_Life has joined #lisp
nowolfer has joined #lisp
rozenglass has quit [Remote host closed the connection]
<russellw> is there a concise idiom for 'if this is not already a list, put it in one'?
<no-defun-allowed> pushnew or adjoin
<phoe> russellw: alexandria:ensure-list
<russellw> thanks!
<phoe> which is (if (listp x) x (list x))
<phoe> which is probably what you just described
<russellw> it is indeed
<no-defun-allowed> oh, i mentally put a "in" somewhere
<no-defun-allowed> "already in a list" i suppose
<russellw> no-defun-allowed, adjoin is interesting in other contexts, though
<makomo> pjb: i have a perfect macro for that, EVAL-WITH: http://plaster.tymoon.eu/view/978#978
<makomo> the backquote is beautiful as well :-)
<phoe> makomo: why the quote?
<phoe> (eval-with (a b) (+ a b)) makes more sense for me
<phoe> the quotation is unnecessary because you already are in a macro
<makomo> phoe: because i wanted to keep the usual syntax of EVAL (it being a function and evaluating its 2nd argument), but i'm not sure why i put a &body there
<phoe> neither am I
<makomo> let me rework it
robotoad has quit [Quit: robotoad]
Kundry_Wag has joined #lisp
<makomo> phoe: oh, i think i wanted the nice indentation that &body gives you, lol
Kundry_Wag has quit [Ping timeout: 240 seconds]
<beach> scymtym: Do you happen to know whether SBCL optimizes TYPEP with a constant atomic type specifier in a way similar to what Bike described?
lumm has quit [Ping timeout: 260 seconds]
<makomo> phoe: which is silly, because i want it to look like a function call, not a macro
<makomo> but maybe it would make more sense if it worked without the quote, idk
<makomo> probably not, because usually you're constructing the rest of the body yourself
varjag has joined #lisp
sword` has quit [Remote host closed the connection]
sword` has joined #lisp
FreeBirdLjj has quit [Remote host closed the connection]
<phoe> I'd rather avoid the EVAL completely
<phoe> .....oh, I can't avoid it
<makomo> improved version
Kundry_Wag has joined #lisp
<makomo> but it's a weird macro nonetheless. it kinda looks like a LET, except that the 2nd argument is evaluated to produce a body... for EVAL to eval
<phoe> why are you using EVAL in there at all?
<pjb> (funcall (let ((a 1) (b 2)) (eval-with (a b) (lambda () (list (incf a) (incf b)))))) #| --> (2 3) |# would be a more typical usage.
<phoe> EVAL should not be used unless absolutely required - if you absolutely need to create and evaluate Lisp forms at runtime
<pjb> (loop :with fun := (let ((a 1) (b 2)) (eval-with (a b) (lambda () (list (incf a) (incf b))))) :repeat 3 :collect (funcall fun)) #| --> ((2 3) (3 4) (4 5)) |#
<makomo> oh, this isn't for anything specific, it's just an old macro i wrote. pjb mentioned a use case above so i thought of it
<phoe> which is usually when you write evaluators or REPLs
frodef has quit [Ping timeout: 252 seconds]
<makomo> pjb: so, not evaluating the 2nd argument would be better?
<pjb> phoe: actually, it would be more like: (loop :with fun := (let ((a 1) (b 2)) (eval-with (a b) `(lambda () ,(progn (write-line "enter a sexp using a and b:") (read))))) :repeat 3 :collect (funcall fun))
Kundry_Wag has quit [Ping timeout: 252 seconds]
<pjb> The point of eval here is to take an expression that is generated at run-time.
<makomo> right, so it doesn't really make sense for EVAL-WITH to not evaluate the 2nd argument
<pjb> My example above with lambda, since it's not quoted, actually refers to the variables in the compilation-time closure!
Lycurgus has joined #lisp
<makomo> pjb: that is a neat example. EVAL-ing a closure just returns that closure, right?
<pjb> Yes.
<pjb> A closure is an non-symbol atom, so it's self-evaluating.
<makomo> mhm
<makomo> pretty nice, crossing boundaries between different EVALs so easily
<makomo> spooky
zotan has quit [Ping timeout: 260 seconds]
semz has joined #lisp
shifty has joined #lisp
orivej has joined #lisp
FreeBirdLjj has joined #lisp
frodef has joined #lisp
Kundry_Wag has joined #lisp
Kundry_Wag has quit [Ping timeout: 252 seconds]
dueyfinster has joined #lisp
rumbler31 has joined #lisp
rumbler31 has quit [Remote host closed the connection]
Essadon has joined #lisp
Kundry_Wag has joined #lisp
Kundry_Wag has quit [Ping timeout: 246 seconds]
Bike has joined #lisp
heisig has quit [Ping timeout: 252 seconds]
rumbler31 has joined #lisp
rumbler31 has quit [Remote host closed the connection]
_whitelogger has joined #lisp
Kundry_Wag has joined #lisp
Kundry_Wag has quit [Ping timeout: 268 seconds]
igemnace has quit [Remote host closed the connection]
Lycurgus has quit [Quit: Exeunt]
scymtym has quit [Ping timeout: 245 seconds]
Kundry_Wag has joined #lisp
Kundry_Wag has quit [Ping timeout: 252 seconds]
hvxgr has joined #lisp
scymtym has joined #lisp
dddddd has joined #lisp
asarch has joined #lisp
_whitelogger has joined #lisp
uint has quit [Remote host closed the connection]
aydio has joined #lisp
lukego has quit [Ping timeout: 256 seconds]
themsay has quit [Remote host closed the connection]
didi has joined #lisp
semz has quit [Ping timeout: 264 seconds]
<didi> Hehe. So TIL `list-length' exists.
<didi> I might have read "The Conses Dictionary" thousands of times and I never noticed.
<beach> didi: In combination with WITHOUT-ERRORS it can be used to write a very simple function for determining whether a list is a proper list.
heisig has joined #lisp
<pjb> didi: you might prefer to use com.informatimago.common-lisp.cesarum.list:list-lengths
<didi> I'm yet to use an improper list. I can imagine there's an use case for circular lists, but for what would one use a dotted list?
<didi> beach: Thank you.
<didi> pjb: Thanks.
<pjb> didi: actually, once I had a case, were I didn't want NIL as the end of the list. IIRC, I had to distinguish two cases for the end of the list.
<pjb> But otherwise, it's more often an error, indeed. Hence the use of ENDP and list-length.
* didi nods
<pjb> notably, length may do an infinite loop on circular lists, so if you have them, better use list-length (or my list-lengths which gives more info).
Josh_2 has joined #lisp
aindilis has quit [Read error: Connection reset by peer]
aindilis has joined #lisp
warweasle has joined #lisp
<jcowan> didi: my implementation of lazy sequences uses improper lists to represent an incompletely materialized sequence, with the generator function in the cdr of the last pair.
<didi> jcowan: Ah, interesting.
<jcowan> you can cdr down the already realized values, and when you get to a pair whose cdr is nil then you are done, but if you get a function then you call it and add a new pair.
<didi> Good one.
<jcowan> See https://github.com/scheme-requests-for-implementation/srfi-127/blob/master/lseqs/lseqs-impl.scm (in Scheme, but should be readable to any Lisper), specifically the lseq-cdr procedure
<didi> jcowan: Thank you.
Kundry_Wag has joined #lisp
edgar-rft has joined #lisp
<jcowan> Scheme returns a dedicated "end-of-file object" when any input function reaches end of file (rather than raising a condition) and I use the same convention for generator functions.
Kundry_Wag has quit [Ping timeout: 252 seconds]
random-nick has quit [Read error: Connection reset by peer]
didi` has joined #lisp
didi has quit [Disconnected by services]
didi` is now known as didi
beach has quit [Disconnected by services]
beach has joined #lisp
FreeBirdLjj has quit [Remote host closed the connection]
ryan_vw has joined #lisp
FreeBirdLjj has joined #lisp
kuwze has joined #lisp
FreeBirdLjj has quit [Ping timeout: 252 seconds]
zfree has quit [Quit: zfree]
Kundry_Wag has joined #lisp
Kundry_Wag has quit [Ping timeout: 264 seconds]
wanz has joined #lisp
nowolfer has quit [Ping timeout: 240 seconds]
nowolfer has joined #lisp
FreeBirdLjj has joined #lisp
anamorphic has joined #lisp
wanz has quit [Quit: wanz]
Kundry_Wag has joined #lisp
aindilis has quit [Remote host closed the connection]
aindilis has joined #lisp
Kundry_Wag has quit [Ping timeout: 240 seconds]
fikka has joined #lisp
aydio has quit [Quit: WeeChat 2.2]
heisig has quit [Quit: Leaving]
fikka has quit [Ping timeout: 246 seconds]
maarhart has joined #lisp
Roy_Fokker has joined #lisp
FreeBirdLjj has quit [Remote host closed the connection]
trocado has joined #lisp
frodef has quit [Ping timeout: 252 seconds]
igemnace has joined #lisp
maarhart has quit [Client Quit]
Kundry_Wag has joined #lisp
aindilis has quit [Read error: Connection reset by peer]
pjb has quit [Ping timeout: 252 seconds]
Kundry_Wag has quit [Ping timeout: 252 seconds]
shifty has quit [Ping timeout: 245 seconds]
fikka has joined #lisp
nowolfer has quit [Ping timeout: 264 seconds]
xkapastel has joined #lisp
fikka has quit [Ping timeout: 252 seconds]
aindilis has joined #lisp
FreeBirdLjj has joined #lisp
nowolfer has joined #lisp
ryan_vw has quit [Ping timeout: 264 seconds]
Josh_2 has quit [Ping timeout: 244 seconds]
zfree has joined #lisp
Kundry_Wag has joined #lisp
Kundry_Wag has quit [Ping timeout: 252 seconds]
Oladon has joined #lisp
fikka has joined #lisp
lumm has joined #lisp
stereosphere has joined #lisp
pjb has joined #lisp
orivej has quit [Ping timeout: 240 seconds]
v0|d has joined #lisp
fikka has quit [Ping timeout: 268 seconds]
fikka has joined #lisp
frodef has joined #lisp
warweasle has quit [Quit: rcirc on GNU Emacs 24.4.1]
trocado has quit [Ping timeout: 252 seconds]
fikka has quit [Ping timeout: 245 seconds]
trafaret1 has joined #lisp
<trafaret1> hi there
<anamorphic> Hi
asymptotically has quit [Quit: Leaving]
Lord_of_Life_ has joined #lisp
Lord_of_Life has quit [Ping timeout: 252 seconds]
Josh_2 has joined #lisp
Oladon has quit [Quit: Leaving.]
trafaret1 has left #lisp ["ERC (IRC client for Emacs 25.2.2)"]
Kundry_Wag has joined #lisp
Kundry_Wag has quit [Ping timeout: 245 seconds]
slyrus has quit [Quit: slyrus]
maarhart has joined #lisp
<anamorphic> Hmm how would I ensure a text file I write to always produces Unix-style line endings, even on Windows?
robotoad has joined #lisp
<jcowan> anamorphic: https://bugs.launchpad.net/sbcl/+bug/310185 suggests that sbcl always writes LF only, even on Windows, though this may have been fixed and not recorded there
ggole has quit [Quit: ggole]
ecraven has quit [Read error: Connection reset by peer]
orivej has joined #lisp
<scymtym> jcowan: it is not yet fixed, but there is work-in-progress
maarhart has quit [Quit: Mutter: www.mutterirc.com]
aydio has joined #lisp
scymtym has quit [Ping timeout: 260 seconds]
ecraven has joined #lisp
fikka has joined #lisp
fikka has quit [Ping timeout: 272 seconds]
Kundry_Wag has joined #lisp
vlatkoB has quit [Remote host closed the connection]
vmmenon has joined #lisp
Kundry_Wag has quit [Ping timeout: 272 seconds]
Lycurgus has joined #lisp
robotoad has quit [Read error: Connection reset by peer]
FreeBirdLjj has quit [Remote host closed the connection]
robotoad has joined #lisp
fiveop has joined #lisp
aydio has quit [Quit: WeeChat 2.2]
aydio has joined #lisp
aydio has quit [Client Quit]
aydio has joined #lisp
HighMemoryDaemon has joined #lisp
pjb has quit [Ping timeout: 260 seconds]
Kundry_Wag has joined #lisp
dueyfinster has quit [Quit: My iMac has gone to sleep. ZZZzzz…]
lnostdal has joined #lisp
Kundry_Wag has quit [Ping timeout: 240 seconds]
kajo has joined #lisp
mrblack has joined #lisp
frodef has quit [Ping timeout: 264 seconds]
dale has joined #lisp
solene has joined #lisp
<solene> hello, is it possible to use a pipe command like echo foo | wc using uiop:run-program?
<solene> I can't find out to do it, using a list as a parameter
<didi> solene: Use a string as the command, so it will shell out.
slyrus has joined #lisp
<solene> ok
pjb has joined #lisp
pierpa has joined #lisp
glassofethanol has joined #lisp
glassofethanol has left #lisp [#lisp]
jack_rabbit has quit [Ping timeout: 252 seconds]
drot_ has quit [K-Lined]
knicklux has joined #lisp
random-nick has joined #lisp
nly has quit [Read error: Connection reset by peer]
nly has joined #lisp
nowhere_man has joined #lisp
Lycurgus has quit [Quit: Exeunt]
fikka has joined #lisp
<mrblack> what would be a good lisp project (that is not too hard) for the Linux environment that would solve things lispers need?
<solene> IMO starting something that you don't need/use if a dead end :(
<solene> s/if/is
<mrblack> that makes sense
<mrblack> but I don't need anything right now
<mrblack> in that regard
<solene> you could look lisp projects and getting involved in one you like
nly has quit [Quit: Quit]
random-nick has quit [Read error: Connection reset by peer]
fiveop has quit []
mrblack has quit [Remote host closed the connection]
mrblack has joined #lisp
<aeth> solene: you might want launch-program instead because it has a :stream option for :input and :output (but it's harder to work with because it's async).
random-nick has joined #lisp
<solene> aeth: I'm quite happy with run-program, I just wanted to use a list because it prevents errors in passing parameters
<mrblack> solene, I had this idea of implementing some of the gnu coreutils because hackability... but I don't know if that makes sense.
<aeth> solene: With :stream you can basically get a pipe, though.
<aeth> (defun uiop-pipe () (let* ((echo (uiop:launch-program "echo foo" :input :stream :output :stream)) (echo-output (uiop:process-info-output echo)) (wc (uiop:launch-program "wc" :input echo-output :output :stream)) (wc-output (uiop:process-info-output wc))) (loop :for line := (read-line wc-output nil :eof) :until (eql line :eof) :do (write-line line))))
<mrblack> it would also help understand gnu coreutils on a deeper level, which would be nice
aindilis has quit [Remote host closed the connection]
Kundry_Wag has joined #lisp
<aeth> (I'm not sure why it prints " 1 1 4" though)
Oladon has joined #lisp
<aeth> (oh because it's wc, not wc -foo)
aindilis has joined #lisp
zxcvz has quit [Quit: Leaving]
scymtym has joined #lisp
Kundry_Wag has quit [Ping timeout: 252 seconds]
anamorphic has quit [Ping timeout: 272 seconds]
<solene> thank you
mkolenda has quit [Remote host closed the connection]
<aeth> Even though launch-program is technically async, this sort of resyncs it and makes it basically the same as run-program. run-program doesn't have :stream for some reason, possibly because :stream could hang.
mkolenda has joined #lisp
<aeth> It looks like it's not totally portable.
hhdave has joined #lisp
Guest13389 has quit [Ping timeout: 244 seconds]
frodef has joined #lisp
random-nick has quit [Remote host closed the connection]
shka_ has quit [Ping timeout: 252 seconds]
hhdave_ has joined #lisp
hhdave has quit [Ping timeout: 240 seconds]
hhdave_ is now known as hhdave
solene has left #lisp ["WeeChat 2.2"]
random-nick has joined #lisp
lumm has quit [Read error: Connection reset by peer]
lumm has joined #lisp
knicklux has quit [Quit: Leaving]
rippa has quit [Quit: {#`%${%&`+'${`%&NO CARRIER]
pyx has joined #lisp
TMA has quit [Ping timeout: 252 seconds]
pyx has quit [Client Quit]
Guest13389 has joined #lisp
TMA has joined #lisp
asarch has quit [Quit: Leaving]
dale has quit [Quit: dale]
dale has joined #lisp
slyrus has quit [Quit: slyrus]
mrblack has quit [Remote host closed the connection]
slyrus has joined #lisp
mrblack has joined #lisp
Kundry_Wag has joined #lisp
Kundry_Wag has quit [Ping timeout: 240 seconds]
Roy_Fawlty has joined #lisp
<gendl> Hi, what is the deal with using nil in a multiple-value-bind binding list?
<gendl> for example (multiple-value-bind (a b c nil) (list 1 2 3 4) ...)
<Bike> they might want it to mean "ignore this variable"
<Bike> i don't think it actually does, though
<gendl> as a way of ignoring that one.
<gendl> Right, but it doesn't work reliably
<gendl> and sometimes throws errors
<gendl> it seems to throw errors pretty reliably on recent implementations
<Bike> yeah.
random-nick has quit [Read error: Connection reset by peer]
<gendl> but i'm seeing old code where it looks like they expected this kind of thing to work.
<Bike> that's why i said "want it to mean" instead of "it means"
<gendl> Is anyone familiar with the "metabang.bind" system? I'm looking at code in cl-markdown, which uses metabang.bind:bind, and it's doing this kind of thing and failing
TMA has quit [Ping timeout: 246 seconds]
<gendl> it works on e.g. sbcl 1.3.1 but crashes on 1.4.8.
Roy_Fokker has quit [Read error: Connection reset by peer]
igemnace has quit [Quit: WeeChat 2.2]
<gendl> it's doing (metabang.bind:bind (((a b c nil) (list 1 2 3 4)) ...) ... ) which I assume bubbles down into some kind of multipe-value-bind thing -- and it fails similarly as with mutiple-value-bind but with a slightly different error message.
<Bike> it's some kind of LET replacement. that one might be a destructuring-bind
<phoe> binding anything to nil is a good way to fail
<phoe> since NIL is a constant, it cannot be rebound
<phoe> ..oooh
<phoe> it's not treated as a symbol there
<phoe> read this as (bind (((a b c ()) (list 1 2 3 4)) ...) ...)
TMA has joined #lisp
<gendl> phoe: are you looking at render-handle-eval?
<phoe> gendl: I'm looking at the code you just posted
<gendl> Ok.
<phoe> this code fails, because BIND expects to match (a b c ()) against (1 2 3 4)
<phoe> and 4 is not an empty list, so the match fails
<phoe> that's what I understand
<gendl> right. I'm wondering why it wasn't failing in sbcl 1.3.1
<phoe> that's a good question
<Bike> actually iirc sbcl did used to specifically treat it as an ignore
<Bike> but that wasn't conformant, so, bye
<Bike> http://sbcl.org/all-news.html#1.4.0 here you go
<phoe> "This seems to be what the standard mandates, so conforming code should not be affected."
<phoe> welp
<gendl> Well SBCL is doing its job - non-conforming code should be shaken out of the ecosystem. And that's exactly what's happening right now.
TMA has quit [Remote host closed the connection]
<gendl> i'm just not sure whether metabang.bind aims to smooth over this kind of thing or not
hhdave has quit [Quit: hhdave]
<gendl> i.e. should I lodge a merge request against cl-markdown, or metabang.bind?
<phoe> metabang-bind defines the BIND macro
<gendl> (the thing is, I know how to fix it in cl-markdown, but not in metabang.bind, so my only real option is the former)
<phoe> it's up to them to define what an empty list means.
<phoe> I suggest you open an issue on metabang-bind asking them to clarify and define that behavior.
<gendl> but in the meantime I need cl-markdown to work.
<phoe> then apply a hotfix anywhere.
ryan_vw has joined #lisp
meepdeew has quit [Remote host closed the connection]
<gendl> phoe: what does that mean.
<gendl> I'd like it to work for everyone, not just for my application (in this case the application is the clnet site generator)
<phoe> gendl: I think the proper way to make it work for everyone is to ask BIND authors for clarification, and to do what they say.
<phoe> But that's also the slow way.
<gendl> I'm gonna do the following: 1. lodge a merge request against cl-markdown, which they can feel free to reject if they can fix it in metabang.bind instead (it happens to be the same author).
<phoe> Oh. That sounds like a good option, in that case.
<gendl> 2. Make a local patch in my application with a flag to remove it if/when the issue is fixed in Quicklisp.
<phoe> Yep, that's what I was thinking.
lavaflow_ has joined #lisp
lavaflow has quit [Read error: Connection reset by peer]
<gendl> phoe: thanks for the guidance.
<gendl> Bike: thanks for tracking down the change in sbcl which explains why it was working before.
<Bike> mhm.
<phoe> gendl: no problem.
TMA has joined #lisp
montxero has joined #lisp
HighMemoryDaemon has quit [Remote host closed the connection]
<montxero> how can one query quicklisp to list all "installed" "software"?
<montxero> I cant find it on the quicklisp page.
Kundry_Wag has joined #lisp
<phoe> montxero: I'd query the ~/quicklisp/dists/quicklisp/installed/systems directory
<montxero> phoe: lol if you mean actually looking in there, I already do that. I just figured there ought to be a way to do it without leaving a the repl
Kundry_Wag has quit [Ping timeout: 240 seconds]
rumbler31 has joined #lisp
angavrilov has quit [Remote host closed the connection]
funnel has quit [Ping timeout: 245 seconds]
funnel has joined #lisp
Oladon has quit [Quit: Leaving.]
adam4567 has joined #lisp
aydio has quit [Quit: WeeChat 2.2]
rumbler31 has quit [Remote host closed the connection]
adam4567 has quit [Remote host closed the connection]
pjb has quit [Ping timeout: 264 seconds]
warweasle has joined #lisp
pillton has joined #lisp
fikka has quit [Ping timeout: 240 seconds]
aindilis has quit [Read error: Connection reset by peer]
pierpa has quit [Ping timeout: 256 seconds]
aindilis has joined #lisp
Essadon has quit [Quit: Qutting]
sjl has joined #lisp
meepdeew has joined #lisp
pjb has joined #lisp
varjag has quit [Ping timeout: 264 seconds]
pierpa has joined #lisp
mejja has joined #lisp
moei has quit [Quit: Leaving...]
graphene has joined #lisp
slyrus1 has joined #lisp
slyrus has quit [Ping timeout: 252 seconds]
slyrus1 is now known as slyrus
pjb has quit [Ping timeout: 264 seconds]
frodef has quit [Ping timeout: 252 seconds]
Kundry_Wag has joined #lisp
Kundry_Wag has quit [Ping timeout: 244 seconds]
<gendl> montxero: from repl: `(directory "~/quicklisp/dists/quicklisp/installed/systems/")`
<gendl> or better: `(directory (merge-pathnames "dists/quicklisp/installed/systems/" ql:*quicklisp-home*))`
shifty has joined #lisp
MetaYan has quit [Ping timeout: 246 seconds]
slyrus has quit [Ping timeout: 252 seconds]
slyrus has joined #lisp
fikka has joined #lisp
<Xach> or maybe (ql-dist:installed-systems (ql-dist:dist "quicklisp"))
fikka has quit [Ping timeout: 246 seconds]