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
rumbler31 has joined #lisp
pjb has joined #lisp
<aeth> jcowan: That example actually survived in the HyperSpec. http://www.lispworks.com/documentation/HyperSpec/Body/m_prog_.htm
<jcowan> Yes, that's where I was quoting it from, but I remember it now from CLtL1
kristof has quit [Ping timeout: 272 seconds]
<LdBeth> I would say this guy absolutly has not many knowledges about Lisp
spm_ has quit [Ping timeout: 250 seconds]
<LdBeth> I suspect he didn't even know Lisp has array
astronavt has joined #lisp
Arcaelyx has joined #lisp
sjl has quit [Ping timeout: 252 seconds]
astronavt has quit [Ping timeout: 252 seconds]
ryan_vw has quit [Ping timeout: 245 seconds]
pjb has quit [Ping timeout: 250 seconds]
<no-defun-allowed> Fun fact: Python doesn't have O(1) arrays.
<no-defun-allowed> Additionally, no structs either.
<no-defun-allowed> I wouldn't trust shit on codeproject tbh. People who call themselves coders are probably losers.
<aeth> LdBeth: There's an argument there, it's just that the author doesn't know Lisp. e.g. ":type float" is probably not what you'd ever want to use since it's basically (or short-float single-float double-float long-float) and probably won't get you anything over ":type number" (or maybe even ":type T"!). If you're going to use a float in a struct, you probably want a specific type of float. The author probably meant "single-float" and was think
Kundry_Wag has joined #lisp
<aeth> The author probably meant "single-float" and was thinking in C.
<aeth> You can also get rid of the prefix with (:conc-name nil)
<aeth> No surprise that the author primarily knows Clojure. Clojurists seem to have the wrong idea of how Common Lisp works but seem to think that they know how Common Lisp works.
Kundry_Wag has quit [Ping timeout: 252 seconds]
<aeth> And, yes, the author has no mention of specialized arrays as an option (or multiple return values!), which is strange.
<aeth> (I didn't mean to insult Clojure programmers, although in hindsight I see how it could seem this way... let me just put it differently: I know I don't know Clojure, so I don't blog about Clojure's weaknesses. Plenty of Clojurists who don't know CL seem to blog about CL's weaknesses.)
<LdBeth> aeth: I didn't noticed the type thing. But I mean, tuple is more close to vector and any saner (Common) Lisper would use vector ranther than list for it
<aeth> It's pretty strange that the author argues that Python, Ruby, and JavaScript are more popular than Lisp because Common Lispers don't use statically typed structs very often.
<LdBeth> Well it infers the author's background
<aeth> LdBeth: There is a point that could be made in a similar essay. There is a long tradition in Lisp of people using lists when they are completely and totally inappropriate. e.g. 2.2.4 in the famous Worse is Better essay. http://dreamsongs.com/WIB.html
<aeth> LdBeth: Except someone could just post section 2.2.4 of that essay. It's shorter, too!
rumbler31 has quit [Read error: Connection reset by peer]
<LdBeth> aeth: It is sometimes understandable because the writer wants it to be comaptble with other dialects, especially for someone had used MacLisp or InterLisp for a while
rumbler31 has joined #lisp
<LdBeth> But it doesn't apply for a "morden" programmer
elfmacs has joined #lisp
<aeth> Oh this part is great. (define point (make-vec3d :x 3 :y 4 :z -3))
<aeth> Didn't even notice it.
<aeth> He defines a struct that holds floats. He then sets the values to fixnums.
<aeth> This means that he tested it in something other than SBCL, one which doesn't do type-checking in the struct constructor. I'm betting CLISP.
<LdBeth> ha, being an inspector
fikka has quit [Ping timeout: 268 seconds]
<jcowan> I'd say he thinks that because he declared the slots to be floats, he assumes the constructor will cast its arguments to floats
<aeth> jcowan: But then he prints it out, which should then make that assumption very clearly disproven
* jcowan chuckles
<jcowan> You assume he looked at the output.
<aeth> You assume he ran the code.
python476 has joined #lisp
<oni-on-ion> why keywords for :x :y :z sigh
<oni-on-ion> are they ever out of order? i wouldnt assume any of them optional given the name 'vec3d'
<aeth> oni-on-ion: There are two common approaches for this sort of thing (vec3s). One is to use a specialized array, and the other is to use defstruct to define a specialized array rather than to define a struct. The result is basically the same, except the latter automatically creates accessors (but not a type, which is strange because defstruct normally defines a type and the type can still be useful if it's a specialized array)
nullniverse has quit [Ping timeout: 252 seconds]
<aeth> oni-on-ion: I use a macro to make my own specialized array instead of using defstruct. I call it define-array-and-type: https://gitlab.com/zombie-raptor/zombie-raptor/blob/b90f23cf6168f892fce8fd980649eaf882662acb/util/array.lisp#L55-67
<aeth> e.g. (define-array-and-type vec3 (single-float '(3)) (x y z)) and then (vec3 1f0 2f0 3f0)
<jcowan> Tuples make sense in the context of destructuring-bind, but without such things, not so much
Kundry_Wag has joined #lisp
<jcowan> The point of a tuple is that it is both heterogeneously typed (in the sense that every object in it has a known type) and indexable.
<jcowan> However, it is not clear that indexability is actually a win in this circumstance.
Guest13389 has quit [Ping timeout: 272 seconds]
nullniverse has joined #lisp
nullniverse has quit [Remote host closed the connection]
<aeth> oni-on-ion, jcowan: I think the example of a vec3 is a bad example for a tuple.
<aeth> Sort of like how class cat inherits from mammal is a bad example of OOP imo.
<jcowan> Yes it is.
<jcowan> (to both)
<jcowan> One could say that tuples are first-class multiple values.
<aeth> You could, if you assume tuples to be immutable, use a macro on top of defstruct to build tuples for CL since defstruct also has :read-only for each slot (just set every slot to read-only). Of course, the compiler won't optimize it because it's not a common idiom.
<jcowan> I have been seeing in my current job how people who have never used dynamically typed languages are actually afraid of code written in them, and I think this is an example.
Kundry_Wag has quit [Ping timeout: 244 seconds]
<cgay> I'm not that familiar with defstruct. Can you really use it to implement tuples, which have unbounded length?
<jcowan> Terminology is loose, but most people talk about tuples as being of a particular length: there are pairs, triples, quadruples, ....
<oni-on-ion> i also think tuples are great for vecs
<aeth> cgay: Hmm... If you need unbounded length tuples, you could create the tuple on demand with deftuple if it doesn't currently exist.
<jcowan> (there may or may not be singletons distinct from their contents)
<oni-on-ion> tuples = twoples ?
<aeth> cgay: (assuming that deftuple is some small wrapper over defstruct)
<jcowan> You hardly even need a wrapper, you just need to specify a BOA constructor
<aeth> jcowan: would that get read-only slots, though?
<jcowan> The result is nominally rather than structurally typed, but that really is a fine detail.
robotoad has quit [Ping timeout: 272 seconds]
<jcowan> "tuple" doesn't necessarily mean "immutable tuple"; in Python it does, but not everywhere.
<oni-on-ion> dimensions or contents? =)
<jcowan> in C# tuples are mutable in content but not in length
Guest13389 has joined #lisp
<jcowan> like Lisp pairs/conses
<jcowan> in Maclisp hunks were mutable in content, immutable in size, and had to be a power of 2.
<jcowan> (in size)
<cgay> Interesting because just yesterday I was noticing that in Dylan <stretchy-collection> is not a subclass of <immutable-collection>.
<cgay> Interesting because just yesterday I was noticing that in Dylan <stretchy-collection> is not a subclass of <mutable-collection>.
<cgay> (fixed)
rozenglass has quit [Remote host closed the connection]
nokdoott has quit [Quit: Leaving]
joast has quit [Quit: Leaving.]
<oni-on-ion> ah =)
robotoad has joined #lisp
Kundry_Wag has joined #lisp
johnjay has joined #lisp
joast has joined #lisp
Kundry_Wag has quit [Ping timeout: 252 seconds]
shifty has joined #lisp
<gendl> Is gitlab.common-lisp.net down for everyone?
<gendl> or is it just me.
<cgay> wfm
<gendl> yep, nvmnd. Back for me. Sorry to jump the gun.
<oni-on-ion> works for me
<oni-on-ion> ah
kristof has joined #lisp
kushal has quit [Read error: Connection reset by peer]
kushal has joined #lisp
fikka has joined #lisp
arescorpio has joined #lisp
ryan_vw has joined #lisp
HighMemoryDaemon has joined #lisp
johnjay has quit [Ping timeout: 256 seconds]
fikka has quit [Ping timeout: 252 seconds]
<HighMemoryDaemon> Does most people's Lisp programming session (At least Emacs users) start by doing the follow? : Open Emacs, Open your project's ASD file, M-x slime, C-c C-c l (load file to Slime), (cl:quickload 'my-project)
<HighMemoryDaemon> *ql
Kundry_Wag has joined #lisp
<oni-on-ion> pretty much. M-x eshell , cd to place, M-x slime, ql:quickload :project
Kundry_Wag has quit [Ping timeout: 268 seconds]
orivej has quit [Ping timeout: 244 seconds]
pjb has joined #lisp
<HighMemoryDaemon> oni-on-ion: You don't need to 'C-c C-c l' the ASD file if you are in the folder that contains all your projects?
<oni-on-ion> HighMemoryDaemon: nah, i symlink my project in ~/quicklisp/local-projects/
<oni-on-ion> forgot to mention that
robotoad has quit [Quit: robotoad]
<HighMemoryDaemon> Very nice, so changing directories with eshell wouldn't even matter since QuickLisp looks in the local-projects folder by default.
snits has quit [Ping timeout: 244 seconds]
<oni-on-ion> yeah, true=) its a convention for me for find-file etc
snits has joined #lisp
python476 has quit [Ping timeout: 252 seconds]
robotoad has joined #lisp
gector has joined #lisp
kristof has quit [Remote host closed the connection]
cylb has quit [Ping timeout: 252 seconds]
elderK has quit [Quit: Connection closed for inactivity]
pierpa has quit [Quit: Page closed]
pjb has quit [Ping timeout: 252 seconds]
Kundry_Wag has joined #lisp
HighMemoryDaemon has quit [Remote host closed the connection]
Kundry_Wag has quit [Ping timeout: 244 seconds]
<drmeister> Hello everyone
ryan_vw has quit [Ping timeout: 244 seconds]
<drmeister> I gave two talks in the last two days in the Bay Area with “Common Lisp” in the title.
<drmeister> One at the llvm developers meeting and another at Nvidia.
<drmeister> The llvm talk was very well received and should be online in a few weeks
sjl has joined #lisp
<drmeister> The nvidia one was not very well attended.
<drmeister> I think I’ll use the term “flexible compiler for a compiled dynamic language” in the future.
<drmeister> Anyway - does anyone write nvidia gpu kernels?
buffergn0me has joined #lisp
<no-defun-allowed> hi drmeister (IRC)
<no-defun-allowed> i don't think FOSS writers do much CUDA, it's a proprietary language and only useful on nvidia machines unfortunately
pjb has joined #lisp
<drmeister> Yeah - I ask hoping to be surprised.
<no-defun-allowed> sorry about that.
<drmeister> No worries
<no-defun-allowed> I am looking to make cl-vep use GPGPU, but it'll probably be in OpenCL/oclcl. The interfaces for oclcl and cl-cuda are fairly similar so it could be possible to port it anyway.
<drmeister> Cl-vep?
<drmeister> Got it
<drmeister> Found it I mean
<no-defun-allowed> it's a video effect processor i made
<drmeister> I saw one talk on opencl at the llvm dev meeting.
<drmeister> Who’s got good gpu drivers for opencl?
<no-defun-allowed> haha, on linux i never found a good opencl/amd driver
Kundry_Wag has joined #lisp
<no-defun-allowed> that or my card is slow and/or old which it is
<drmeister> I get it - and the situation sucks.
<no-defun-allowed> apparently i'm using amdgpu right now which is the best free amd driver
Kundry_Wag has quit [Ping timeout: 245 seconds]
<no-defun-allowed> funny you bring it up, beach and i have been poking at (presumably) amdgpu crashing and halting our computers
linack has joined #lisp
<drmeister> Really? Beach is working with amdgpu?
<drmeister> I’m in California waiting for a red eye back to the east coast
<no-defun-allowed> he's not working on it, but we've both had problems with it freezing recently
<drmeister> Ah
<no-defun-allowed> nothing happens before it freezes, but then it becomes unusable and doesn't respond to the usual TTY changes, SysRq keys, etc
<no-defun-allowed> my motherboard has lights which indicate when something went terribly wrong, and the GPU one lights up when that happens though
<drmeister> Yuck
<no-defun-allowed> indeed, very nasty
pjb has quit [Ping timeout: 252 seconds]
rumbler31 has quit [Remote host closed the connection]
Roy_Fokker has quit [Read error: Connection reset by peer]
Oladon has joined #lisp
<no-defun-allowed> hi LdBeth and Oladon (IRC)
<LdBeth> Good evening
<LdBeth> just figuring out how to use FriCAS's plotting tool in Axiom
Arcaelyx has quit [Quit: Textual IRC Client: www.textualapp.com]
terpri_ has quit [Remote host closed the connection]
terpri_ has joined #lisp
relaxed has quit [Remote host closed the connection]
relaxed has joined #lisp
linack has quit [Quit: Leaving]
dddddd has quit [Remote host closed the connection]
_whitelogger has joined #lisp
azimut_ has joined #lisp
azimut has quit [Ping timeout: 244 seconds]
rumbler31 has joined #lisp
Kundry_Wag has joined #lisp
rumbler31 has quit [Ping timeout: 252 seconds]
<beach> Good morning everyone!
nly has joined #lisp
arescorpio has quit [Quit: Leaving.]
Lord_of_Life has quit [Ping timeout: 245 seconds]
Kundry_Wag has quit [Ping timeout: 252 seconds]
Kundry_Wag has joined #lisp
Kundry_Wag has quit [Ping timeout: 252 seconds]
rumbler31 has joined #lisp
rumbler31 has quit [Ping timeout: 272 seconds]
anewuser has quit [Quit: anewuser]
froggey has quit [Ping timeout: 244 seconds]
Lycurgus has joined #lisp
froggey has joined #lisp
terpri_ has quit [Remote host closed the connection]
terpri_ has joined #lisp
charh has quit [Ping timeout: 252 seconds]
fikka has joined #lisp
ryan_vw has quit [Ping timeout: 246 seconds]
fikka has quit [Ping timeout: 252 seconds]
rippa has joined #lisp
pjb has joined #lisp
Bike has quit [Quit: Lost terminal]
Oladon has quit [Quit: Leaving.]
doubledup has joined #lisp
<LdBeth> Ah, morning
stereosphere has quit [Read error: Connection reset by peer]
<Lycurgus> moin LdBeth
mingus has quit [Ping timeout: 272 seconds]
heisig has joined #lisp
pjb has quit [Ping timeout: 252 seconds]
asarch has quit [Quit: Leaving]
wigust has joined #lisp
zxcvz has joined #lisp
rotty has quit [Ping timeout: 260 seconds]
trittweiler has joined #lisp
vlatkoB has joined #lisp
quazimodo has quit [Ping timeout: 252 seconds]
nowolfer has quit [Ping timeout: 252 seconds]
nowolfer has joined #lisp
wigust has quit [Read error: Connection reset by peer]
wigust has joined #lisp
Kundry_Wag has joined #lisp
razzy has joined #lisp
shka_ has joined #lisp
Kundry_Wag has quit [Ping timeout: 252 seconds]
pjb has joined #lisp
Lycurgus has quit [Quit: Exeunt]
papachan has joined #lisp
Kundry_Wag has joined #lisp
Kundry_Wag has quit [Ping timeout: 272 seconds]
papachan has quit [Quit: WeeChat 2.2]
vaporatorius has quit [Quit: Leaving]
aeth has quit [Read error: Connection reset by peer]
aeth has joined #lisp
trittweiler has quit [Ping timeout: 268 seconds]
JohnMS has joined #lisp
pjb has quit [Ping timeout: 260 seconds]
reverse_light has quit [Remote host closed the connection]
wigust has quit [Ping timeout: 252 seconds]
orivej has joined #lisp
Kundry_Wag has joined #lisp
nowolfer has quit [Ping timeout: 252 seconds]
doubledup has quit [Quit: Leaving]
nowolfer has joined #lisp
Kundry_Wag has quit [Ping timeout: 252 seconds]
bigfondue has quit [Ping timeout: 250 seconds]
pjb has joined #lisp
buffergn0me has quit [Remote host closed the connection]
doubledup has joined #lisp
doubledup has quit [Remote host closed the connection]
python476 has joined #lisp
<python476> oh no I missed a Maya discussion T_T
elderK has joined #lisp
random-nick has joined #lisp
buffergn0me has joined #lisp
bigfondue has joined #lisp
Kundry_Wag has joined #lisp
lumm has joined #lisp
Kundry_Wag has quit [Ping timeout: 252 seconds]
trittweiler has joined #lisp
frodef has joined #lisp
pjb has quit [Ping timeout: 260 seconds]
mkolenda has quit [Remote host closed the connection]
mkolenda has joined #lisp
sjl has quit [Ping timeout: 252 seconds]
<makomo> morning
<no-defun-allowed> morning makomo
<beach> Hello makomo.
<makomo> hello :-)
<makomo> does anyone know of anything like MAP-INTO, but that would additionally let me specify the maximum number of elements i want to map over
<makomo> i.e. my destination sequence is shorter than the source sequence
<makomo> i know the destination is an array, but the source can be *any* sequence, which is why i turned to MAP-INTO, instead of TYPECASE/LOOP
<makomo> and i want to COERCE every element from the source to a specific type before assigning it to its corresponding destination element
cylb has joined #lisp
pjb has joined #lisp
Kundry_Wag has joined #lisp
cylb has quit [Ping timeout: 252 seconds]
<beach> makomo: You can keep a counter in your function.
Kundry_Wag has quit [Ping timeout: 245 seconds]
lumm has quit [Read error: Connection reset by peer]
<beach> (block foo (let ((counter 0)) (map-into .. (lambda (destination source) (when (> (incf counter) max) (return-from foo ...) ...)) ...)))
<makomo> oh wait, MAP-INTO has the same behavior regarding multiple sequences as MAPCAR, etc. (stops at the shortest sequence) and it **includes** the destination sequence
<beach> It does.
<makomo> for some reason i thought it wouldn't take the destination sequence's length into account
<beach> I thought you wanted a max that is not necessarily the length of the source.
<beach> So you can just use MAP-INTO as is?
<makomo> beach: pretty much, but i'm trying to understand what you wrote, or rather, the way you interpreted my question
<beach> I thought you max number of elements processed was unrelated to the length of either sequence.
<makomo> ahh, i see
<ggole> You could always use subseq, although that is quite wasteful
<makomo> ggole: exactly :-), that's what i'm trying to avoid
<makomo> beach: in that case, my max would still have to lower than either of the lengths, right? otherwise MAP-INTO would stop early
<makomo> s/still//
nowolfer has quit [Ping timeout: 252 seconds]
<makomo> i went to see what ITERATE has, but it uses ELT, which wouldn't be too good for lists
<makomo> s/lower/less than/
python476 has quit [Remote host closed the connection]
<beach> You can just write two loops and choose one according to the type of the sequence.
fikka has joined #lisp
<beach> makomo: So what *is* your max?
<makomo> beach: in this case my max is the length of the shorter sequence, and that is already handled by MAP-INTO nicely
<makomo> of the destination sequence*
trittweiler has quit [Ping timeout: 252 seconds]
<beach> So, problem solved?
<makomo> yeah, pretty much :-)
buffergn0me has quit [Remote host closed the connection]
buffergn0me has joined #lisp
fikka has quit [Ping timeout: 252 seconds]
<makomo> beach: one thing i'm wondering though. i wanted to delegate the typecase i would have to write to MAP-INTO. now, it would be the best to do the typecheck only once, and then blast through the sequence knowing what the type is (instead of calling ELT for example which has to do the typecheck every time). is this a correct assumption i'm making, that MAP-INTO usually does such a thing and that ELT has the
<makomo> described downside?
<makomo> (how they're implement is an implementation detail in general, but would this be the logical thing to do? could a compiler try to optimize an ELT call if it knew the type of the sequence?)
<makomo> s/how/i know/
<makomo> what is it with the typos today...
<makomo> and i just typo'd the correction as well, oh dear. s/implement/implemented/ instead of the above
<ggole> If you are calling elt on a list you have already lost
<ggole> (Unless the list is unconditionally short.)
<ggole> Whatever map-into does, it should be implemented fairly sanely
<makomo> ggole: right and what about calling ELT on an array (instead of AREF for example)? ELT in general has to figure out the type of the sequence first, and it would in general have to do that for every access. could a compiler optimize that into an AREF directly for example?
python476 has joined #lisp
<ggole> It might do, if the type were apparent.
<ggole> This is the sort of thing that varies widely among compilers.
<makomo> mhm, i imagined it would be something like that
<pjb> makomo: beach: in those cases, I would use a displaced array: (map-into r (lambda (s1 s2) …) (make-array (- end1 start1) :displaced-to v1 :displacement-offset start1) (make-array (- end2 start2) :displaced-to v2 :displacement-offset start2))
rozenglass has joined #lisp
Kundry_Wag has joined #lisp
<makomo> pjb: neat idea
<beach> makomo: The compiler would have to replicate the loop for that optimization to take place.
<beach> I doubt that SBCL does that.
<beach> Oh, wait, it might.
<pjb> It might be a good idea to optimize dynamic-extent displaced arrays in loops…
<beach> If MAP-INTO dispatches on the type of the sequence(s), then the loop is already replicated. But given that MAP-INTO takes several sequences, that might become complicated to pull off.
<pjb> and even, non-dynamic-extent ones, if it can be proven the displacement is not mutated
<jcowan> Inline caching is designed to deal with exactly this problem, based on the fact that at a particular call site, typically only one or a few of the types that a procedure can accept are actually ever passed to it.
razzy has quit [Ping timeout: 252 seconds]
Kundry_Wag has quit [Ping timeout: 272 seconds]
<jcowan> Combined with dynamic recompiling, this allows a monomorphic call site to be maximally efficient, making the simplest possible test: is this the type we had before? Mildly polymorphic call sites can handle a few types with type dispatching; only intensely polymorphic sites need a full dispatch.
<no-defun-allowed> does anyone know of any alternatives to neural networks for machine learning?
<jcowan> In this way a procedure like elt can be compiled in two forms, one for lists and one for vectors, with the correct one being called based on call-site dispatching.
robotoad has quit [Quit: robotoad]
<makomo> beach: yes, that's exactly what i was thinking about -- just like i would have to do if i was going to do it manually
<makomo> interesting
nly has quit [Read error: Connection reset by peer]
nly has joined #lisp
<ggole> Displaced arrays won't work for other sequences.
<ggole> (Nifty idea though.)
<makomo> beach: hm yeah, since MAP-INTO takes a variable number of lists, can it even be done in general? would you have to resort to run-time compilation or something?
<|3b|> you could make an optimized iterator per sequence without duplicating the loop
<jcowan> Memory is cheap, conditional tests are not.
<jcowan> And the difference between most-efficient list iteration and vector iteration is drastic.
<|3b|> (for lists, just POP, for vectors, aref with shared counter)
<pjb> For lists, you can easily use nth-cdr to start from where you want, and count on the length of other sequences to stop it.
<pjb> nthcdr of course.
<makomo> jcowan: that's very interesting. do any implementations do that (for any function, not necessarily ELT and the like)?
<jcowan> No idea. Historically the idea arose in the Smalltalk community and has been used for other OO languages as well.
<makomo> i also read about SynthesisOS, an OS that would recompile parts of itself on the fly to make itself more efficient
robotoad has joined #lisp
<makomo> and it was actually written in assembler
<ggole> Inline caching and recompilation could be used for a bunch of stuff in CL
<ggole> Shame that the implementation complexity is so high.
<jcowan> https://gist.github.com/twokul/9501770 explains its use in JavaScript, a language without overt classes.
<jcowan> ggole: If you are JIT compiling anyway, inline caching isn't that much more expensive.
nowolfer has joined #lisp
<ggole> I mean the difficulty of programming it, not the computational cost
<ggole> Pulling invalidated code off a stack in a threaded environment is pretty hard
<pjb> There was an OO system that would also recompile the methods specially for each instance (thus duplicating the code), letting use relative addressing and other tricks, since they were directly attached to the object data.
<ggole> For each *instance*?
<heisig> jcowan: Thank you for sharing that. It could be interesting to use inline caching to bypass the discriminating function in CLOS. Though ggole is right, there are certainly some hairy corner cases.
<beach> makomo: If I were to write map-into, I would probably define a few special cases, like at most three sequences, and replicate the loop for those.
<pjb> Yes, for each instance!
<pjb> That's what made it special.
<ggole> Interesting decision... I wonder how expensive that was.
<ggole> I've read papers where people implement lexical scope that way
<ggole> By literally substituting values into the program text
<ggole> I don't think that was ever seriously used, though.
<pjb> ggole: since relative addressing use shorter opcodes, the methods were smaller and faster, so it was worth the duplication.
<pjb> Also, it would work great for eql specialized methods.
<heisig> jcowan: But how does inline caching preserve what Alan Kay calls "extreme late binding of all things"? I would think there must be at least two conditional branches: One to check whether the types are the same, and one to check that no metaobjects have changed.
<heisig> In that case, it might not be much faster than a good discriminating function.
<pjb> Compilation is performed late! (at run-time).
<jcowan> Yes, that's true. But such a check is still cheaper than a full dispatch. You can put the check at the head of the method, and provide two returns, a successful return in which the method ran, and a failure return which triggers recompiling
<pjb> This is the advantage of having the compiler available at run-time: you can recompile and optimize for the current data.
<ggole> Usually a check would not be on the type, but a token that represents all the assumptions that you wished to optimise based upon
<ggole> If something invalidates those assumptions, you update the token and you no longer pass the check.
<ggole> In this way you can assume just the type, or type + other stuff
<ggole> For example, you might want to assume that a global variable has not been written to, because you make use of its current value in some way.
<jcowan> https://arxiv.org/pdf/1711.03050.pdf <-- paper on dynamic deoptimization
<jcowan> AFAIK the first JIT compiler was HP APL back in 1977, which compiled APL line by line. The code for each line involved a check that the rank and shape of every variable referenced in the line was the same as before, and the line was compiled to a set of nested loops with fixed endpoints (so-called "hard compilation"). If a line failed the check, it was compiled again, this time assuming only rank constancy ("soft compilation").
<jcowan> So since variables polymorphic in rank are not common in any language, most lines were compiled once or at most twice and then ran almost at full AOT speed while keeping the dynamic nature of APL.
asymptotically has joined #lisp
robotoad has quit [Quit: robotoad]
shrdlu68 has joined #lisp
Kundry_Wag has joined #lisp
Kundry_Wag has quit [Ping timeout: 252 seconds]
razzy has joined #lisp
joga has quit [Ping timeout: 244 seconds]
<heisig> jcowan: Thank you for posting that HP Journal! This dynamic APL compiler is definitely something I should mention in my thesis.
<makomo> great stuff :-)
<jcowan> tx
lumm has joined #lisp
lumm has quit [Ping timeout: 272 seconds]
themsay has joined #lisp
fikka has joined #lisp
fikka has quit [Ping timeout: 252 seconds]
Essadon has joined #lisp
nowhere_man has quit [Ping timeout: 252 seconds]
Essadon has joined #lisp
Essadon has quit [Read error: No route to host]
heisig has quit [Quit: Leaving]
elderK has quit [Ping timeout: 260 seconds]
elderK has joined #lisp
JohnMS is now known as JohnMS_AWAY
JohnMS_AWAY is now known as JohnMS
frodef has quit [Ping timeout: 272 seconds]
scymtym has quit [Ping timeout: 276 seconds]
Lycurgus has joined #lisp
edgar-rft has quit [Remote host closed the connection]
Essadon has quit [Ping timeout: 268 seconds]
Inline has quit [Quit: Leaving]
Inline has joined #lisp
aindilis has joined #lisp
scymtym has joined #lisp
meepdeew has quit [Remote host closed the connection]
nowhere_man has joined #lisp
eminhi has joined #lisp
younder has quit [Quit: Leaving]
dddddd has joined #lisp
Lord_of_Life has joined #lisp
jmercouris has joined #lisp
<jmercouris> so, the printer prints objects that can be read, but some of them cannot be read, for example, hash tables, why is that?
<jmercouris> who decided the print representation of a hashtable, for example?
<jmercouris> why wouldn't the default behavior be a printable form of the key/value? I mean it is built-in object after all
nowhere_man has quit [Ping timeout: 252 seconds]
<beach> It might be tricky. The keys can be arbitrary objects.
<ggole> eq-ness of objects is hard to print
<pjb> jmercouris: the read syntax was defined (long) before hash-tables were introduced into the language.
<jmercouris> ok, so it's just a timeline thing?
<pjb> jmercouris: they ran out of time and money to further standardize hash-table read syntax. (and a lot of other things).
<pjb> definitely.
<jmercouris> I see, that's too bad
<pjb> You can use com.informatimago.common-lisp.cesarum.utility:print-hashtable
<pjb> There's no need to include it in the standard actually.
Bike has joined #lisp
FreeBirdLjj has joined #lisp
<jmercouris> beach: definitely possible, but you can imagine that for all built-in objects used as keys/values the modele would be relatively straightforward
frodef has joined #lisp
<pjb> (let ((h (make-hash-table :test 'equal :rehash-threshold 0.5))) (setf (gethash :hi h) 1 (gethash "Hi" h) 2) (com.informatimago.common-lisp.cesarum.utility:print-hashtable h)) #| #.(HASHTABLE :TEST (FUNCTION equal) :SIZE 2
<pjb> :ELEMENTS '(
<pjb> :REHASH-SIZE 1.5 :REHASH-THRESHOLD 0.5
<pjb> (:hi 1)
<pjb> ("Hi" 2))) --> #<hash-table :test equal size 2/63 #x302002435F3D> |#
<pjb> Of course, Using the function com.informatimago.common-lisp.cesarum.utility:hashtable
nly has quit [Ping timeout: 252 seconds]
<jmercouris> that is interesting I've seen some other libraries as well that do the same for arbitrary CLOS objects using their slots and the like to create printable and readable representations, though the name is currently eluding me
<pjb> If you don't want to rely on a library to read the hash-table, you can generate something like: #.(let ((h (make-hash-table :test 'equal :rehash-threshold 0.5))) (setf (gethash :hi h) 1 (gethash "Hi" h) 2) h) #| --> #<hash-table :test equal size 2/63 #x30200227747D> |#
<pjb> The only use of a specific reader macro, is when you want to (setf *read-eval* nil)
shrdlu68 has quit [Ping timeout: 252 seconds]
Lycurgus has quit [Quit: Exeunt]
<jmercouris> okay so basically you'd only have to implement the print part
<jmercouris> because you could emit a set of sexp when eval'd that would reproduce the hash table, not necessarily with the same eq as alluded above, but with the same general contents keys/values
<jmercouris> interesting
<Bike> (that's what make-load-form is for btw)
<pjb> For example, you could define a reader macro: Ɦ((:test equal :rehash-threshold 0.5) :hi 1 "Hi" 2)
<pjb> or perhaps: ⫍ (:test equal :rehash-threshold 0.5) :hi 1 "Hi" 2 ⫎
<pjb> This would look nice.
<pjb> for eql hash-tables with default parameters: ⫍ :one 1 :two 2 :three 3 ⫎
<jmercouris> in a defclass slot what is the :reader argument?
<Bike> :reader defines a reader method with the given name.
<pjb> defines a reader method.
<pjb> Same as an accessor, but only to read the slot.
<pjb> So when you want to provide a read-only API.
themsay has quit [Ping timeout: 268 seconds]
<beach> jmercouris: The Common Lisp HyperSpec says: The :reader slot option specifies that an unqualified method is to be defined on the generic function named reader-function-name to read the value of the given slot.
<pjb> :writer is for write-only API.
<pjb> Or you can use both :reader and :writer when the names are different, vs. a :accessor that use the same name for both.
<jmercouris> I don't understand, why would you need a reader method?
<Bike> ....so you can get the value in the slot?
<jmercouris> or rather, that is a bad question, let me instead ask, what is a reader method?
<jmercouris> okay, so I am right in my thinking what it is
<jmercouris> then, why specify a reader-method, when you can use slot-value, for example?
<beach> jmercouris: The existence of a slot is an implementation detail.
<beach> jmercouris: You don't want to mention slots in your protocol.
<pjb> (defclass account () ((solde :type integer :reader balance :writer in-the-bank))) (let ((a (make-instance 'account))) (in-the-bank 42 a) (balance a) ) #| --> 42 |#
<jmercouris> so, when you define :accessor, does it automatically make a reader-method?
<beach> Yes, and a writer too.
<pjb> jmercouris: readers and accessors are more easily overloaded than slot-value.
<jmercouris> ah, so basically it is a question of specificity
<pjb> slot-value is a low-level method.
<jmercouris> so you can provide a slot that can only be read from
<jmercouris> or only be written to
<jmercouris> yes?
<beach> Yes, you can.
<beach> Allowing only a reader is common.
<pjb> Also, indeed, you can define methods behaving like readers, writers or accessors, without a slot.
<jmercouris> I'm basically asking why does :reader exist, if :accessor exists, and I guess the answer is to make a slot-value read only?
<shka_> jmercouris: exactly
<pjb> (defmethod interest ((a account)) 0.0) (interest (make-instance 'account)) #| --> 0.0 |#
<pjb> no slot.
<beach> jmercouris: Not necessarily read-only, but read-only for client code.
<Bike> or to give the reader and writer different names, like for example if only one is exported
<Bike> one name*
<shka_> jmercouris: also, sometimes you want to have reader and writer, and export just a reader
<jmercouris> shka_: Aha, I see
<shka_> or, for instance if you are working on container in package containers
<jmercouris> so here's another thing though right, can't any client just redefine your class and add an accessor to get access to whatever you are hiding?
<shka_> and you have implementation in package sets
<Bike> if your client redefines your class they deserve everything coming to them
<shka_> you may add reader containers:size to size slot
<shka_> jmercouris: it is possible, but not advised
<jmercouris> okay, so this is all for the sake of encapsulation
<shka_> jmercouris: more or less
<jmercouris> so far, I have been programming common lisp entirely without any sort of "enforced" encapsulation, but this might be a good idea for exposing interfaces to 3rd parties
<shka_> jmercouris: as beach said, you should not use slot-value
<beach> jmercouris: Also to make your maintenance sane.
<shka_> at least usually
<jmercouris> so, let's say you have a slot that only has a reader, you can then only use slot-value to set its value, right?
<beach> Not quite true.
<jmercouris> so then, if you are saying, don't use slot-value, and you only have a reader, what should you do?
Kundry_Wag has joined #lisp
<beach> But yeah, sort of.
<jmercouris> make a writer but not export its symbol outside of your package? is that basically your only course of action?
<shka_> jmercouris: if it is your own class, add writer but don't expose it
<makomo> jmercouris: you define a writer (or both a reader and a writer by using :accessor) separately with a different name
<beach> jmercouris: Wow, you have to distinguish between client code and code for your own module.
<beach> jmercouris: Client code may only see the reader, whereas you can have a writer for your module implementation.
<shka_> jmercouris: i for instance always name reader to be read-foo, writer write-foo and accessor access-foo
<jmercouris> ok, I know these questions seem absolutely idiotic, and they feel so too
<jmercouris> but let me explain why I am asking them
<beach> shka_: That sounds like a bad idea.
<jmercouris> clhs make-load-form
<Bike> they're not stupid questions.
<shka_> beach: it is not-issue in practice
<shka_> but it looks funny
<jmercouris> look at the example for defclass obj
<jmercouris> I am just wondering how this class is expected to be used without a writer
<Bike> it uses make-load-form-saving-slots, which uses slot names directly
<shka_> jmercouris: immutable
<Bike> rather than writers
<jmercouris> is it just a class that we only initialize and then that's it? we can never set it?
<shka_> or you can have higher level operation exported
<Bike> yes, in the definition of the class that's basically how it is.
<Bike> it's like a complex number. it has components but you can't mutate a complex number.
<beach> jmercouris: You initialize it with :x when you create the instance.
wanz has joined #lisp
<shka_> jmercouris: essentially, it is like saying that java class without public members can't be used
<jmercouris> beach: right, that's what I'm saying, just seemed strange to m
<jmercouris> s/m/me
<jmercouris> ok, it is making more sense to me now, and I now see why there is no writer here
<beach> jmercouris: For example, if you create an instance of PERSON, you can put the date of birth in there. It won't ever change.
<phoe> jmercouris: sure, immutable instances are frequent in many places
<phoe> (make-instance 'foo :x 42)
<phoe> (x instance) ;=> 42
<jmercouris> here is a case of enforced immutability in common-lisp, that's something quite new to me!
<phoe> it doesn't mean that you may ever #'(SETF X) - there needs not be a writer
<phoe> jmercouris: not really enforced
<jmercouris> pseudo-enforced
Kundry_Wag has quit [Ping timeout: 260 seconds]
<shka_> jmercouris: it is just a suggestion
<phoe> the only thing that isn't there is, the writer function isn't created
<phoe> so the programmer states that this value shouldn't be modified
<jmercouris> without a writer function, I imagine the author is strongly implying, don't write to this slot
<shka_> lisp style is to say "You really shouldn't" instead of "You shall not"
<phoe> exactly
<beach> jmercouris: Yes, like date-of-birth.
<makomo> jmercouris: it is not enforced, you can always use slot-value. the thing you were getting at with "enforced encapsulation" is an important point
<beach> That usually doesn't change.
<phoe> shka_: You'd Better Not, like in the pastafari
<shka_> heh, right
<makomo> jmercouris: it's just like python. you have access to everything, but you really don't want to access the implementation details of the class
<beach> makomo: You can also use REINITIALIZE-INSTANCE. :)
<jmercouris> I guess nothing in lisp is really ever enforced, we can always :: to get at a symbol anyway
<makomo> or that :-)
<shka_> jmercouris: yup
<jmercouris> lisp seems to be a programming language for adults
<makomo> jmercouris: that too. it's important to break yourself free from the "what if"
<beach> jmercouris: Luckily. Otherwise debuggers and inspectors would not be possible to write.
<shka_> jmercouris: it is interactive, and it is hard to work (program, debug) in interactive envs if there are walls everywhere
<jmercouris> I see, thank you all for your patience in explaining :D
<makomo> jmercouris: "what if" in the sense, "what if my client changes this variable, oh no!"
<makomo> you just stop caring. if one does that, he gets what he deserves :-)
<jmercouris> right, if they break they contract, that's on them, simple as
<jmercouris> s/they/the
<makomo> exactly, that's the fundamental point
<jmercouris> beach: I remember you saying you don't like the usage of the word self within a defmethod, does it bother you that it appears in the hyperspec so?
<jmercouris> I think you had said it bothered you because it was a remanant of single dispatch object oriented systems
<beach> jmercouris: Yes, that bothers me.
<beach> Exactly.
<jmercouris> I guess the problem is, if you are specializing on multiple classes, you can't just say "self" for all of them, so there will be this inconsistency
<jmercouris> what if instead of self you write something like classa-instance classb-instance, would that appeal to you more?
<Bike> sounds wordy
<shka_> instance-a would be enough
<Bike> usually you should just name them same as you do in any other function
<jmercouris> I guess Bike makes sense here
<jmercouris> I can't think of anything better, and I'm sure many people have spent already many hours thinking about it :D
<Bike> two hard problems in CS etc.
<phoe> jmercouris: "self"?
<phoe> in case of multiple inheritance, this term is ambiguous
<phoe> if you have classes foo and bar, you write a function like (frob foo bar)
<phoe> and you write a method the same way
<shka_> lisp is such a selfless language ;-)
<phoe> there's no self in there, just arguments
<jmercouris> phoe: yeah, I get that, that's what I was trying to say above, albeit, far more ambiguously
<phoe> embrace the zen
<jmercouris> I wrote a project recently for a client, in Lisp, and the developer taking over the project was asking me, "why did you do it in lisp"? Felt kind of like an accusation, like I had burdened them in some way by picking this arcane language that they would now have to work on
igemnace has joined #lisp
<jmercouris> I told them why I picked the language, why it was faster for me, but it felt like trying to win a holy war, in which I had comitted an atrocity, and had to atone or something, not sure how to explain it, but without them knowing the language, I couldn't articulate to them why I had chosen it
<jmercouris> so, perhaps more appropriate for #lispcafe, but the question is, how do you explain your decision to those who question you in a way that they can understand, when they don't know the language
shifty has quit [Ping timeout: 252 seconds]
<russellw> Be careful of assuming everything has to be about explanations and understanding. Most human interactions are more about social status. So the real point of an answer to something like that is replying in such a way to make it look like, you, your language and your community are at least as high status as his
<jmercouris> interesting, so you are saying it is more of a "tribal war" type query than one of genuine interest in understanding?
<russellw> exactly.
<phoe> russellw: "it works the best for me as a programmer and I can deliver the most value in this language"
<phoe> uh, sorry
<phoe> jmercouris: ^
<shka_> heh
<jmercouris> that is more or less what I said, I couldn't think of what else I could tell them that would make sense without a lot of context and background
<russellw> phoe, good start, but allows too much possibility that another language might be better for the majority of people
<shka_> jmercouris: "chill dude"
<russellw> I would say something more like "best tool for the job" or "most powerful language anyone has yet come up with"
<phoe> russellw: sure, that's actually true - Lisp isn't a good choice for a lot of programmers and they'll produce more value in other languages
<phoe> and that sentence is true for s/Lisp/any other language/
<jmercouris> I wanted to find some sort of appeal to authority where I could say "X is in Lisp" to demonstrate that it has been shown to be capable for application in the domain of the application that I wrote
<phoe> jmercouris: don't, the only winning move in that game is not to play
<russellw> But it's not just about the words, it's also about the tone. Your tone needs to suggest that your answer is really obvious formality, and not subject to debate
<pjb> jmercouris: there's an important point here. In C or C++, since you can write random pointers, you can write randomly into any object very easily. But in lisp you cannot make random references, so it's impossible to write to an object unintentially.
<jmercouris> shka_: lol
<phoe> russellw: I think that "works the best for me" is an obvious formality enough - you can't really debate with that
<russellw> I agree with phoe about that, the less arguing you have to do, the better
<pjb> jmercouris: so despite this absence of walls, code doesn't trepass.
<russellw> If you really have to bring first-person pronouns into it, at least say something like "I find it the best tool for this kind of project"
<jmercouris> pjb: yep
<phoe> it's simply stupid to say "but you're more proficient in Java++, I know it for some reason" if you're a customer
<phoe> because that's a hidden requirement of "but I'd rather want you to do this in Java++"
<russellw> phoe, I was talking about the presented scenario where the challenge did not come from the customer but from another programmer
<pjb> And you still have the god-mode access to slots with slot-value, unless it's overriden for your class or your object ;-)
nowolfer has quit [Ping timeout: 272 seconds]
<phoe> russellw: oh, hm
<russellw> If it comes from the customer, then that is a different scenario. He who pays the piper calls the tune
<jmercouris> I wonder how hard it would be to make a lisp --> java compiler that produces sensible looking code
<russellw> So if the customer asks about your choice of language, say something like "I believe this is the best tool for this job, but it's your call"
<phoe> as for the programmers, I'd say it's the bendiness of the language - allowing to tailor the language towards the problem instead of only having the option of hammering the problem into the language
<jmercouris> like, human readable code
<pjb> jmercouris: have a look at CLforJava, IIRC, they had that purpose.
<pjb> ah, wrong. It compiles LISP to Java byte code.
<russellw> jmercouris, as far as I know, no one has ever written an x->y compiler that produces readable code for any x,y
nowolfer has joined #lisp
<Bike> snort
<jmercouris> pjb: yes, too bad we can't even look at the source
<pjb> Well, the closest would be clicc; perhaps you could adapt it to generate java/
<phoe> jmercouris: it'll be tough, since you'll need to reinvent a big amount of mechanisms. multiple inheritance, conditions, dynamic variables all don't exist in Java or even the JVM.
<jmercouris> multiple inheritance could be circumvented through the use of protocols that multiple classes implement
<russellw> Yeah, restartable conditions alone would make it practically impossible
<phoe> implement all of this, and you already have ABCL.
<phoe> and ABCL compiles to JVM bytecode, not to Java source code.
<phoe> So that's another layer you need to bridge.
<jmercouris> ABCL can run common lisp on the jvm?
<phoe> Yes
<jmercouris> that's fascinating I didn't know that
<pjb> See also https://cliki.net/LinJ sexpified java.
<phoe> It's a CL implementation on the JVM.
<jmercouris> the only example I can think of is parenscript
<jmercouris> which compiles to almost readable JS
<jmercouris> at least for most of the time/simple casees
<phoe> yes, but it's a huge subset of CL.
<phoe> you can compile subsets of CL easily to other dynamic languages.
<jmercouris> don't you mean a small subset?
<russellw> subsets yes
<phoe> uh, yes
<phoe> relatively small
<phoe> the trouble begins when you start trying to compile actual features of CL as a language.
Kundry_Wag has joined #lisp
<phoe> CLOS, conditions, dynavars, et al.
<phoe> you suddenly get to embed chunks of the Lisp runtime in that language to be able to support them.
Essadon has joined #lisp
<phoe> and be able to bend and modify the control flow in the language in case of conditions and CLOS dispatch.
<phoe> so, at some point, you stop compiling CL to that other language
<phoe> you start writing a CL implementation in that language
<phoe> which, at some point, stops being readable at all, unless you start abstracting things away.
<phoe> like, for example, with Lisp macros.
<phoe> which require you to write Lisp.
<phoe> and bam, you're back again in the Lisp world.
<jmercouris> damn
<phoe> just with an implementation hosted on whatever other virtual machine.
<jmercouris> I was thinking to make it simpler for CL -> other people interop
<jmercouris> in which case, maybe it is only necessary to support a subset
<phoe> jmercouris: what do you mean by other people?
<phoe> and what do you mean by interop?
<jmercouris> I guess at that point you'd only be getting CL syntax and not much else
<jmercouris> I mean for example, in the example I mentioned above, imagine if my CL could have been compiled to python
<russellw> jmercouris, not going to happen.
<jmercouris> it would have been easier for him to take and modify
<phoe> not going to happen.
<russellw> You need to solve your problem in a different way
<phoe> if anything, embed a Python runtime in your Lisp image and use that python as a scripting language for your Lisp image.
<russellw> If the customer wants python, bite the bullet and write python
<phoe> or what russellw said.
<beach> Or find a different customer.
<phoe> (:
<jmercouris> it wasn't the customer, just the developer who is taking over the project for the customer, after my initial implementation
Josh_2 has joined #lisp
Kundry_Wag has quit [Ping timeout: 252 seconds]
<beach> Oh, he or she is very likely going to rewrite it.
<russellw> But you described a scenario where the customer was happy and it was a rival programmer who would've preferred Python. In that scenario, you need to get more confident and better at winning status fights
<beach> Just like Yahoo did with viaweb.
<jmercouris> so they had been working on this project for like 6 months, and in Lisp I did it in literally one week
<russellw> Why was the customer replacing you with that guy anyway?
<jmercouris> and they were still not convinced
<phoe> jmercouris: are you working in some kind of company? are you a freelancer? a consultant?
<jmercouris> the customer was replacing me because I do not have the time to give them, there are other projects that demand my attention
<russellw> Well of course the rival programmer was not convinced! You made him look like an idiot!
<jmercouris> I am a freelancer/consultant
<Josh_2> jmercouris: you maintain Next browser?
<russellw> But if you are short of time, you need to raise your rates.
<jmercouris> Josh_2: yes
<phoe> yep - tell them that this project is in Lisp and they'll need to learn it to be able to develop/maintain it, just like with any other project
<Josh_2> It won't launch on my machine :(
<phoe> you can't maintain Oberon code unless you know Oberon
<jmercouris> I told them yes, I linked them to PCL, Portacle, and wrote some pretty thorough documentation
<shka_> jmercouris: normal
<jmercouris> Josh_2: don't worry, you're not alone, it won't launch on most people's machine, unless they are on a Mac :D
<Josh_2> also the make next/gtk doesn't create a binary in source
<Josh_2> O okay
<z0d> well, Python is a subset of CL with a different syntax anyway :->
<phoe> jmercouris: then they're good to begin learning
<shka_> especially since they are doing this in python
<jmercouris> Josh_2: Yes, I am sorry about that, we are working hard on the new GTK version using the Lisp Core -> Dumb GTK front-end architecture we previously discussed in this channel, so it should work for you, hopefully within a couple months
<Josh_2> awesome :)
<shka_> jmercouris: can you link next campaign?
<shka_> i forgot to pledge
<jmercouris> shka_: yes, of course, one moment please!
flazh has quit [Quit: flazh]
<jmercouris> thank you in advance!!
<shka_> don't thank me, just make it work on the LINUUUUUUUUUUUXXXXXXX
<jmercouris> Will do!
<Josh_2> jmercouris: what do you need c++ devs for?
flazh has joined #lisp
<jmercouris> Josh_2: basically we have a program written in pure lisp that uses xml-rpc to control a client written in c/c++ gtk/qt
<jmercouris> that client needs to respond to some basic commands like make-window, delete-window, make-buffer, set-visible-buffer-for-window, etc
<jmercouris> so that we can continue to evolve the LISP core without any foreign code
<jmercouris> this adds greater stability, significantly more consistent cross-platform performance and support, and a more reliable/reproducible build process
<jmercouris> whatever technology GUI framework/web engine comes out in the future, it will be easy to port to because of this API that the LISP core and the GUI will use to communicate to each other with
<Josh_2> Sounds like an awesome plan :D
FreeBird_ has joined #lisp
<jmercouris> thank you, it was not my idea, all credit to beach , it is however a huge pain to implement and very challenging :D
FreeBirdLjj has quit [Ping timeout: 245 seconds]
<jmercouris> even just thinking about what is the minimal API needed to control the GUI application was an incredibly time consuming task
nowolfer has quit [Ping timeout: 260 seconds]
nowolfer has joined #lisp
<shka_> ok, done
nly has joined #lisp
FreeBird_ has quit [Remote host closed the connection]
lukego has joined #lisp
<shka_> jmercouris: let me know when next will work on linux
makomo has quit [Read error: Connection reset by peer]
<shka_> also, why gtk?
<jmercouris> shka_: I will make an update for sure
<jmercouris> why GTK? some people run GTK
<jmercouris> If there was a de-facto GUI framework / web engine port for Linux, it'd be an easier target
<jmercouris> but ultimately to please all I'll have to do QT/Webengine and GTK/Webkit both
<shka_> some run qt
<shka_> anyway, i don't care that much
<shka_> i just want browser
<jmercouris> That much you shall have!
<shka_> ok, cool
nly has quit [Read error: Connection reset by peer]
<jmercouris> Thanks again!
<lukego> Suppose you have a static programming language with relatively weak abstraction capabilities. So you make an S-expression representation of its source code and then write programs using CL macros. Final step is to generate readable code in the target language with no dependency on Lisp. What's the best example of this approach?
rozenglass has quit [Remote host closed the connection]
<pjb> LinJ
<pjb> Liskell
rumbler31 has joined #lisp
<lukego> Thanks, pjb!
FreeBirdLjj has joined #lisp
Kundry_Wag has joined #lisp
<ggole> You'd have to author your macros rather carefully to produce 'readable code'
<lukego> Relatedly: Have many people taking this approach to hardware description languages like Verilog and VHDL? I googled for this and found Verilisp that seems like exactly what I was thinking of but with a mysterious status (homepage not even on internet archive.) I'm not sure if this is what Marc Battyani does.
<ggole> It's convenient to make free use of let, and the compiler will have no trouble with redundant variables, but a human reader of the output might not be pleased.
lumm has joined #lisp
<Bike> HDLs have their own problems because they're not programming languages, and because you can't usually access the "assembly" level because of proprietary-ness
FreeBirdLjj has quit [Ping timeout: 260 seconds]
Kundry_Wag has quit [Ping timeout: 252 seconds]
<lukego> Verilisp looks awesome in the ECLM sense. Like somebody who wanted to build hardware just decided to use Lisp and bloody well did it. Code looks funky to a Lisper though :-) giving closing parens their own lines like C braces, defining functions like REMOVE-IF-NOT and EXPT with comments thinking they are not already built in..
<lukego> Total respect to whoever wrote it, but tempting to rewrite rather than reuse
makomo has joined #lisp
<lukego> also liberal use of EVAL in cases where the idiomatic Lisp is not obvious and author doesn't care but just wants to get shit working. Man, this is a pleasure to read :)
warweasle has joined #lisp
Lycurgus has joined #lisp
JohnMS has quit [Quit: Konversation terminated!]
<jmercouris> lukego: that's hilarious
<lukego> I bet they had a lot of fun writing that :)
<lukego> Reminds me of the time a guy turned up at ECLM talking about how he'd written a successful commercial product for designing aeroplane engines in Common Lisp, afaik with no prior experience, just a bright guy with a problem to solve who somehow recognized Lisp as a good fit
semz has joined #lisp
<makomo> is there a way to compare types for equality?
<Bike> subtypep in both directions.
<Bike> alexandria has it as type= or something.
<makomo> neat, thanks
pjb has quit [Ping timeout: 252 seconds]
oleo2 has joined #lisp
Kundry_Wag has joined #lisp
Roy_Fokker has joined #lisp
FreeBirdLjj has joined #lisp
<makomo> is there a way to determine whether a type A is coercable to type B?
<Bike> look at the definition of COERCE?
<makomo> right, but i mean without catching the condition. i was thinking of something like COERCEP
<Bike> cond... what? i mean just look at it
<Bike> clhs coerce
<Bike> that's what you can coerce
Kundry_Wag has quit [Ping timeout: 245 seconds]
FreeBirdLjj has quit [Ping timeout: 244 seconds]
pjb has joined #lisp
<makomo> yeah, but i don't want to replicate COERCE and write out all the possible cases
<Bike> what are you doing exactly
oleo2 has quit [Ping timeout: 260 seconds]
oleo2 has joined #lisp
<makomo> i'm reading some data from the user. these objects should be something that is coercable to a certain numeric type stored in *type* (which can be changed at runtime by the user)
<makomo> s/these objects/the objects read/
<makomo> if it's not possible to coerce the values, i would like to report a proper error, instead of letting the following code just explode or w/e
<Bike> only numbers are coerceable to other numbers
<Bike> and you can't coerce to like, integer
<lukego> Thanks again pjb. I'll make a deep dive on the LTD code. Just brilliant to have Norvig code for inspiration.
<phoe> makomo: (handler-case (coerce a b) (error (e) (error (make-condition 'coerce-error :data a :type b))))
<pjb> makomo: notice that implementations are free (and even must have to) implement additionnal coertions.
<pjb> makomo: in the spec of coerce, notice the use of the expression: *recognizable* subtype.
<pjb> recognizable subtype n. (of a type) a subtype of the type which can be *reliably* *detected* to be such by the *implementation*. See the function subtypep.
<pjb> So COERCE is highly implementation dependent, at least when you use it on strange types.
<pjb> For example, consider: (values (eval '(lambda (x) (list x x))) (compile nil '(lambda (x) (list x x))) (coerce '(lambda (x) (list x x)) 'function))
<beach> lukego: Long time no see.
<pjb> makomo: You may get the same result for the 3 values, but you could also expect to get an interpreted function from eval, a compiled function from compile, and whatever is best for the implementation, according to the implementation from coerce.
<lukego> Hey beach :)
<Bike> don't need the make condition...
<makomo> pjb: i see, thanks
<lukego> beach: I find myself in the pleasantly surprising situation that I want to prototype a little project and CL seems like the only suitable language :)
<lukego> Let's see how this pans out. Meanwhile: childcare...
<pjb> makomo: another example, I hear that sbcl has other sequence subtypes than vector and list…
<beach> lukego: Good luck (with both).
lumm has quit [Read error: Connection reset by peer]
lumm has joined #lisp
elfmacs has quit [Quit: WeeChat 2.2]
ryan_vw has joined #lisp
asymptotically has quit [Remote host closed the connection]
asymptotically has joined #lisp
Kundry_Wag has joined #lisp
Lycurgus has quit [Quit: Exeunt]
rumbler31 has quit [Remote host closed the connection]
lumm has quit [Ping timeout: 260 seconds]
Kundry_Wag has quit [Ping timeout: 268 seconds]
rumbler31 has joined #lisp
rumbler31 has quit [Remote host closed the connection]
rumbler31 has joined #lisp
rumbler31 has quit [Ping timeout: 244 seconds]
meepdeew has joined #lisp
meepdeew has quit [Remote host closed the connection]
nly has joined #lisp
wanz has quit [Quit: wanz]
bendersteed has joined #lisp
razzy has left #lisp ["ERC (IRC client for Emacs 25.1.1)"]
FreeBirdLjj has joined #lisp
bendersteed has quit [Read error: Connection reset by peer]
ryan_vw has quit [Ping timeout: 260 seconds]
FreeBirdLjj has quit [Remote host closed the connection]
FreeBirdLjj has joined #lisp
Kundry_Wag has joined #lisp
Kundry_Wag has quit [Ping timeout: 268 seconds]
razzy has joined #lisp
jeosol has joined #lisp
pjb has quit [Ping timeout: 276 seconds]
lnostdal has quit [Read error: Connection reset by peer]
lnostdal has joined #lisp
Kundry_Wag has joined #lisp
Kundry_Wag has quit [Ping timeout: 272 seconds]
Pixel_Outlaw has joined #lisp
Kundry_Wag has joined #lisp
zxcvz has quit [Quit: Leaving]
Kundry_Wag has quit [Ping timeout: 246 seconds]
anamorphic has joined #lisp
pjb has joined #lisp
Oladon has joined #lisp
jcowan has quit [Quit: Connection closed for inactivity]
Kundry_Wag has joined #lisp
Kundry_Wag has quit [Ping timeout: 244 seconds]
dtornabene has joined #lisp
igemnace has quit [Quit: WeeChat 2.2]
warweasle has quit [Quit: rcirc on GNU Emacs 24.4.1]
lumm has joined #lisp
Grauwolf has quit [Quit: WeeChat 2.2]
FreeBirdLjj has quit [Read error: Connection reset by peer]
Grauwolf has joined #lisp
FreeBirdLjj has joined #lisp
makomo has quit [Ping timeout: 252 seconds]
ryan_vw has joined #lisp
Lord_of_Life has quit [Ping timeout: 272 seconds]
FreeBirdLjj has quit [Ping timeout: 244 seconds]
jcowan has joined #lisp
dtornabene has quit [Quit: Leaving]
scymtym has quit [Ping timeout: 260 seconds]
Lord_of_Life has joined #lisp
Kundry_Wag has joined #lisp
eschatologist has quit [Ping timeout: 240 seconds]
Kundry_Wag has quit [Ping timeout: 252 seconds]
stereosphere has joined #lisp
eschatologist has joined #lisp
robotoad has joined #lisp
scymtym has joined #lisp
dale has joined #lisp
jmercouris has quit [Ping timeout: 252 seconds]
aindilis has quit [Ping timeout: 252 seconds]
vtomole has joined #lisp
aindilis has joined #lisp
<jcowan> Lisp-flavored C is not uncommon, though it usually doesn't escape particular Lisp implementations.
<jcowan> and there is Lisp-flavored Erlang
shymega has joined #lisp
zfree has quit [Ping timeout: 268 seconds]
kristof has joined #lisp
<kristof> I know this will sound like the most peculiar question, but
<kristof> (let ((x (the single-float 0.1)) (y (the single-float 0.2))) (the single-float (+ x y))) => 0.3
<kristof> why is that giving me the "right" answer? :P
<shka_> peculiar indeed
<shka_> what did you expect?
<kristof> A floating point answer that smacks of imperfection
robotoad has quit [Quit: robotoad]
<shka_> i don't understand
<kristof> Oh, maybe it's the print settings...
<anamorphic> %PRIMITIVE HALT called; the party is over.
<jcowan> no, not the print setting
eminhi_ has joined #lisp
vtomole has quit [Ping timeout: 256 seconds]
<rme> for imperfection, see (= 0.9f0 0.9d0)
<jcowan> it so happens that when you add the nearest approximation to 1/10 to the nearest approximation to 2/10', you get the nearest approximation to 3/10.
<jcowan> (this is in double-floats, I don't have single-float support handy with a printer I trust)
eminhi has quit [Ping timeout: 244 seconds]
<kristof> (format t "~50$" (the single-float 0.3)) just pads with 0s. Ridiculous!
<aeth> kristof: Is this SBCL?
<kristof> this is SBCL.
<kristof> D also does this. I presume it has something to do with the way floating points are printed from their binary representation and I know there's some tradeoffs to be made there
<aeth> SBCL does something special with floats. Even double-floats. I wrote something that ran in SBCL, CCL, ECL, and CLISP... and for one of the five values, the error was really huge in all of them except for SBCL.
<kristof> peculiar :P
<aeth> So I wouldn't be surprised if it wasn't just a printing hack.
<kristof> I wonder if this is the first time someone came in to this channel to complain of correctness and utility
<kristof> What is this, stockholm syndrome?
<aeth> well, you can disassemble
<kristof> What, the format form?
<kristof> or just the constants
<anamorphic> Is there a way to destructure a plist in a loop?
shka_ has quit [Ping timeout: 245 seconds]
robotoad has joined #lisp
<aeth> Well, (defun foo () (let ((x (the single-float 0.1)) (y (the single-float 0.2))) (the single-float (+ x y)))) is compiled to constantly return 0.3 so I'd test with (defun foo (x y) (declare (single-float x y)) (+ x y)) (foo 0.1 0.2)
<aeth> I'm still getting 0.3, though.
<ggole> Isn't 0.3 the right answer for single floats?
<aeth> 0.1 + 0.2 returns 0.30000000000000004 in python3
<ggole> Those are doubles.
<ggole> Try (+ 0.1d0 0.2d0)
<aeth> good point
<ggole> Er, swap the zeros and other digits :/
* ggole might have to go to bed soon
<aeth> 0.30000000000000004d0
<Bike> anamorphic: not really, other than do (destructuring-bind ...)
<aeth> So what's going on is that single-float seems more accurate than double-float here!
<ggole> Well, you get the point anyway.
<ggole> Yes, accuracy and precision are not the same thing.
<aeth> I think this is just what happens with singles vs. what happens with doubles.
Kundry_Wag has joined #lisp
eminhi_ has quit [Ping timeout: 252 seconds]
eminhi has joined #lisp
zxcvz has joined #lisp
<jcowan> aeth: 0.30000000000000004 and 0.3 are two tokens for the same double-float, but the former is in some sense the canonical one.
<jcowan> Python doesn't require implementations to print the canonical representation.
Kundry_Wag has quit [Ping timeout: 252 seconds]
random-nick has quit [Read error: Connection reset by peer]
vlatkoB has quit [Remote host closed the connection]
<kristof> anamorphic: (loop for (sym val . rest) on '(a 1 b 2 c 3 d 4) by #'cddr do (print sym))
<jcowan> Scheme requires it, and AFAIK the last holdout against doing so has now given in. There is no C requirement to do so, but at least glibc always prints the shortest correct representation. CL doesn't have a requirement either, but I'd be surprised if any CL implementation does otherwise.
robotoad has quit [Quit: robotoad]
<kristof> however that will give you the final nil so you should throw a when clause in there
<kristof> (loop for (sym val . rest) on your-list by #'cddr when sym do (whatever))
<jcowan> kristof: That surprised me until I remembered that (cdr nil) => nil
<kristof> I have a suspicion there's a way to avoid that when clause but it escapes me
<kristof> Wait, lol
<kristof> I was confusing the return value of the loop function for the print action. The first thing I wrote works just fine.
<kristof> And they're colored differently, too! Some genius I am
<jcowan> oh, yes, so did I'
lumm has quit [Read error: Connection reset by peer]
lumm has joined #lisp
<kristof> does slime support a way to do newlines at the prompt? Sometimes I don't want to load forms from a scratch buffer, I just want to write in the single buffer.
<kristof> but of course for longer snippets that becomes problematic
<jcowan> You don't have to be a genius to write Lisp, it just helps. :-)
jasmith has quit [Ping timeout: 244 seconds]
<pjb> kristof: I don't understand what you want.
<kristof> nothing, my question has been answered
<pjb> aeth: the same thing happens with doubles.
<phoe> kristof: newlines at the prompt? you mean REPL?
<kristof> Yes.
<phoe> it does support them as long as you do not have a complete form; for example, "(+ 2 2)" and RET triggers evaluation but "(+ 2 2" and RET creates a newline.
<phoe> I frequently delete the last closing parenthesis after typing the opening one creates a pair, if I expect to be writing a multiline form.
<pjb> Or you can type C-q (
<kristof> SBCL's repl does but slime does not... on Atom, at least. Does it have that before on emacs?
<phoe> welp, slime-atom is a weird beast
meepdeew has joined #lisp
Oladon has quit [Quit: Leaving.]
oleo2 has quit [Ping timeout: 252 seconds]
<phoe> the last time I tried to use it, slime-atom did not accept any multiline input
<phoe> even if the form was incomplete
<kristof> nice!
<kristof> :P
angavrilov has quit [Remote host closed the connection]
Kundry_Wag has joined #lisp
lumm has quit [Remote host closed the connection]
random-nick has joined #lisp
Kundry_Wag has quit [Ping timeout: 252 seconds]
kristof has quit [Ping timeout: 268 seconds]
asymptotically has quit [Remote host closed the connection]
asymptotically has joined #lisp
ryan_vw has quit [Ping timeout: 252 seconds]
<LdBeth> Morning
warweasle has joined #lisp
<LdBeth> For slime the editor processes the form rather than the Lisp itself, it doesn’t know very well on when to send it, sometimes it even applies to GNU/Emacs
oleo2 has joined #lisp
shifty has joined #lisp
shifty has quit [Read error: No route to host]
shifty has joined #lisp
robotoad has joined #lisp
shrdlu68 has joined #lisp
<oni-on-ion> slime, and editor, you say? how is that *ever* without emacs?!
oleo2 has quit [Ping timeout: 260 seconds]
ggole has quit [Quit: ggole]
zfree has joined #lisp
Kundry_Wag has joined #lisp
asymptotically has quit [Remote host closed the connection]
asymptotically has joined #lisp
Kundry_Wag has quit [Ping timeout: 268 seconds]
nowhere_man has joined #lisp
eminhi has quit [Quit: leaving]
mejja has joined #lisp
<LdBeth> Emacs is for Unix people
<oni-on-ion> most operating systems are 'unix'
Pixel_Outlaw has quit [Quit: Leaving]
cpt_nemo has joined #lisp
<aeth> In SBCL, SLIME's #'sin is (FUNCTION (T) (VALUES NUMBER &OPTIONAL)) and (introspect-environment:function-type 'sin) is (FUNCTION (NUMBER) (VALUES (OR (SINGLE-FLOAT -1.0 1.0) (DOUBLE-FLOAT -1.0d0 1.0d0) (COMPLEX SINGLE-FLOAT) (COMPLEX DOUBLE-FLOAT)) &OPTIONAL))
<aeth> Why does SLIME get worse information than introspect-environment?
<aeth> (And it's not for portability, I don't think either even has function types in the other implementations)
<Bike> what do you mean "slime's"
Josh_2 has quit [Quit: ERC (IRC client for Emacs 26.1)]
<Bike> "slime's" is the derived type, whereas the one you attributed to introspect environment is the declared type
<phoe> aeth: (describe 'sin)
<phoe> aeth: (describe #'sin)
warweasle has quit [Quit: rcirc on GNU Emacs 24.4.1]
<aeth> I see.
<aeth> Wouldn't there be a use in providing both?
<Bike> where are you getting "slime's"
Kundry_Wag has joined #lisp
<aeth> Bike: Inspect the return value of #'sin which is #<FUNCTION SIN>
<aeth> In SBCL (and I think just in SBCL) it has the line TYPE: (FUNCTION (T) (VALUES NUMBER &OPTIONAL))
<aeth> But personally if I was for some reason debugging something involving #<FUNCTION SIN> (obviously this is just an example) then I'd find the declared type to be more useful.
<oni-on-ion> caps help to know that its Actual Lisp
<aeth> Well, I (setf *print-case* :downcase) most of the time, but I keep having to restart SLIME to switch implementations/etc.
<aeth> (Not because I'm afraid of #<FUNCTION SIN> but because I do macroexpand-1 a lot)
<Bike> as you can see from looking at the source, slime-inspect on sbcl for functions uses the simple-fun-type that's actually in the function object, rather than the declared type
Kundry_Wag has quit [Ping timeout: 240 seconds]
<aeth> Bike: So a declaration is tied to a name rather than to the function object itself?
<Bike> evidently
<aeth> Well, this is weird. (sb-disassem:disassemble-code-component #'sin) shows the very small entry point of a T input value. I declare stuff all the time and there's usually a check in the part that's in sb-disassem:disassemble-code-component but not in cl:disassemble
<aeth> I think this must just be a weird special case for built-in SBCL functions.
varjag has joined #lisp
<aeth> Actually, what I think is going on is that SBCL's declaim ftype and SBCL's type declarations are separate things, but when you declaim ftype for something you write you also type declare or something. (declaim (ftype (function (number) number) bar)) (defun bar (number) (sin number)) will produce a #'bar as if I did a (declare (number number)) even though I didn't.
pjb has quit [Ping timeout: 252 seconds]
<aeth> Perhaps the ftype declaration happens after sin is already defined internally?
mathrick has joined #lisp
nowhere_man has quit [Ping timeout: 264 seconds]
grumble is now known as Spooktober
pjb has joined #lisp
rippa has quit [Quit: {#`%${%&`+'${`%&NO CARRIER]
Kundry_Wag has joined #lisp
kristof has joined #lisp
Kundry_Wag has quit [Ping timeout: 252 seconds]
postit has joined #lisp
lnostdal has quit [Ping timeout: 252 seconds]
Lycurgus has joined #lisp
jdw4000 has joined #lisp
lnostdal has joined #lisp
Roy_Fokker has quit [Read error: Connection reset by peer]
robotoad has quit [Quit: robotoad]
Lycurgus has quit [Quit: Exeunt]
lnostdal has quit [Ping timeout: 252 seconds]
kristof has quit [Remote host closed the connection]
skidd0 has joined #lisp
lnostdal has joined #lisp
<skidd0> With clack or lack, does anyone know how to set response headers?
<skidd0> or do I have to skip clack and set the hunchentoot headers-out?
shifty has quit [Ping timeout: 252 seconds]
kristof has joined #lisp
<skidd0> or, how can i directly manipulate the lack.response reesponse structure before sending?
easye has quit [Remote host closed the connection]
GoldRin has joined #lisp
dmiles has quit [Ping timeout: 252 seconds]
kristof has quit [Remote host closed the connection]
logicmoo has joined #lisp
<frgo> Hi all. I am struggling with CFFI: How to define a C type like typedef char ac[10]; ?
<pjb> (cffi:defctype foo (:array :char 10)) I'd say.
<pjb> Well, not in cffi :-( clisp FFI can define such types howeverl
<frgo> Oh hi pjb - yep. Works.
asymptotically has quit [Quit: Leaving]
<pjb> The declaration works, but to use it you have to define type translators.
<pjb> CFFI is lower level than most implementation FFI.
<pjb> Basically, it's the greatest common denominator.
<pjb> With a few macros above it.
<jcowan> Is it considered bad practice to use qualified internal symbols in production code?
<frgo> Which is still fine. Thanks for reminding me.
<pjb> jcowan: why would it?
<pjb> frgo: it may be simplier to just use mem-ref, in lisp functions doing the checking.
<jcowan> Well then, why bother to have external symbols at all and require a (slightly) more verbose syntax to access them from other packages? (This is not a rhetorical question.)
python476 has quit [Ping timeout: 252 seconds]
themsay has joined #lisp
themsay has quit [Ping timeout: 244 seconds]
robotoad has joined #lisp
robotoad has quit [Quit: robotoad]
<skidd0> to get access to the lack.response, would I want to do something :around the CALL method?
<skidd0> that seems to be what ningle does
<skidd0> or :before?
<skidd0> I guess :around replaces the method, right?
Kundry_Wag has joined #lisp
random-nick has quit [Ping timeout: 244 seconds]
Kundry_Wag has quit [Ping timeout: 240 seconds]
robotoad has joined #lisp
rozenglass has joined #lisp
<Bike> skidd0: it doesn't replace, but if your :around method doesn't call-next-method the original method will not be called
<skidd0> oh that's right
<skidd0> thanks
nullniverse has joined #lisp
Essadon has quit [Quit: Qutting]
jack_rabbit has joined #lisp
Kundry_Wag has joined #lisp
ryan_vw has joined #lisp
elderK has quit [Quit: Connection closed for inactivity]
varjag has quit [Ping timeout: 244 seconds]
ryan_vw has quit [Client Quit]
Kundry_Wag has quit [Ping timeout: 264 seconds]
dale has quit [Quit: dale]
Kundry_Wag has joined #lisp
robotoad has quit [Max SendQ exceeded]
Kundry_Wag has quit [Ping timeout: 268 seconds]
frodef has quit [Ping timeout: 260 seconds]
makomo has joined #lisp
ryan_vw has joined #lisp
robotoad has joined #lisp
varjag has joined #lisp
robotoad has quit [Ping timeout: 252 seconds]
varjag has quit [Ping timeout: 264 seconds]
SenasOzys has joined #lisp
SenasOzys has quit [Remote host closed the connection]
rumbler31 has joined #lisp
Tordek has quit [Ping timeout: 246 seconds]
robotoad has joined #lisp
rumbler31 has quit [Ping timeout: 244 seconds]
mejja has quit [Quit: mejja]
robotoad has quit [Read error: Connection reset by peer]
robotoad_ has joined #lisp
<skidd0> I'm getting an error where hunchentoot doesn't know how to handle options http requests
<skidd0> for CORS
<skidd0> has anyone run into this before?
<skidd0> How would i go about adding my own response to an options request?