Xach changed the topic of #commonlisp to: Common Lisp, the #1=(programmable . #1#) programming language | Wiki: <https://www.cliki.net> | IRC Logs: <https://irclog.tymoon.eu/libera/%23commonlisp> | Cookbook: <https://lispcookbook.github.io/cl-cookbook>
karlosz has quit [Ping timeout: 240 seconds]
akoana has left #commonlisp [Leaving]
<phantomics> hey White_Flame figured out the problem I was having turned out it was something completely unrelated
<lotuseater> ok good
Fare has quit [Ping timeout: 268 seconds]
lottaquestions has quit [Quit: Konversation terminated!]
waleee has quit [Ping timeout: 240 seconds]
nij- has joined #commonlisp
<nij-> I wonder why `defunt` in this article isn't defined as a function, but a macro. Doesn't a function do the job well too? https://medium.com/@MartinCracauer/static-type-checking-in-the-programmable-programming-language-lisp-79bb79eb068a
<hayley> I suppose it could be done as a function, but typically you would use a macro there.
<hayley> Rather than DECLAIM, use PROCLAIM, and (SETF FDEFINITION) rather than DEFUN. But I suppose a macro gives better source tracking information at least.
<nij-> Why does a macro give better source tracking info?
<hayley> Actually, no, I retract my statement: you could not write DEFUNT as a function. The body, name, and lambda list have to remain unevaluated.
<hayley> But in such a situation, the compiler would detect a DEFUN form (somehow) and attach source information to the function.
<aeth> oh, one of those DEFUN variations
<aeth> they all have horrible flaws
<aeth> It seems incredibly easy, but it's not
<aeth> My own version of that has several hundred lines (in addition to a docstring that's about 50 lines) and it's still misisng suppliedp and &aux support
<aeth> and probably has a few more undiscovered bugs waiting to surface
<hayley> I don't mind the external DECLAIM/DECLAREs really. Those kinds of "annotations" compose better than the macros.
<aeth> eh
<aeth> iirc, it messes with the M-. because now there are multiple things that it looks up
<aeth> If you put it in a macro (1) you have one authoritative origin for M-. and (2) you can't have typos where you change the name of the DEFUN but not of the DECLAIM (which absolutely can happen)
<lotuseater> so when to use PROCLAIM rather than DECLAIM?
<aeth> I have never used PROCLAIM
<aeth> It's the function-not-a-macro right? So I think it can be used to change global OPTIMIZE levels?
<aeth> otherwise, I don't think I've seen it
<lotuseater> i saw it just for inline, eg (proclaim '(inline foo1 foo2))
<aeth> probably a bug unless at something in the REPL
<aeth> because it won't eval at the right time?
<lotuseater> don't know
<aeth> because it will already have the DEFUN FOO defined before the PROCLAIM INLINE FOO is read
<aeth> s/read/executed/
<lotuseater> erm no, I meant having it in before
nij- has quit [Ping timeout: 258 seconds]
<aeth> yes
<aeth> I think it has to be a DECLAIM not a PROCLAIM
<lotuseater> yeah ok. I saw it in PAIP, so a bit older style.
nij- has joined #commonlisp
<nij-> hayley: That's right that you must use a macro for that. But, if we accept for quotes in function calls, then we can define defunt as a function, right?
<lotuseater> then you get the list form of your new function
<nij-> I've been looking for a persuasive example that demonstrates why lisp macros are superior than macros of the others. However, all examples I found so far are not persuasive to those who don't use lisp at all.
<aeth> HTML
<aeth> in most languages, HTML templates are embed-source-or-DSL-in-HTML-files
<aeth> e.g. for a cross-language example (and there's a CL version of this too). https://mustache.github.io/mustache.5.html
<aeth> but in Lisps, the natural thing to do is to express HTML as s-expressions inside of the code
<moon-child> people have expressed html directly using c macros!
<nij-> aeth: Is that to answer my question/complaint?
<lotuseater> moon-child: no way! crazy o_O
<aeth> moon-child: Yes, but C macros lack hygiene... and it matters way more in C-style text macros than in CL-style syntactic macros, especially since CL's package namespacing and Lisp-2 nature gets around most of the hygiene issues
<aeth> so I can't even begin to imagine composing that sort of thing in a serious project (plus, C isn't a good language for string manipulation...)
<moon-child> lotuseater: you do it with for loops
<nij-> I remember reading somewhere in PCL that promises in the beginning chapters that
<lotuseater> the more complex CPP macros get the more parentheses they need, but can get broken easily
<aeth> And a lot of the other ways to do things would involve literal strings and runtime execution, rather than doing it at compile time
<moon-child> #define div for (int divcounter = (printf("<div>"),1); divcounter--; printf("</div>"))
<nij-> "soon we will see macros defined on top of macros which are almost impossible to write without macros".. (paraphrased)
<moon-child> and yeah it's not super practical
<nij-> But I didn't see/pay attention to the resolution of that @@
<lotuseater> there's no real difference writing functions with macros or macros with macros
<lotuseater> nij-: try writing the *= operator as a function. i choose that as a simple example because the += and -= are given by INCF and DECF respectively ^^
<nij-> What is *=?
<nij-> As in C?
<lotuseater> yes or in Python etc
<nij-> lotuseater: Urgh is it an example that even a non lisper would understand?
<nij-> I understand that it's not possible to write `if` as a function, but that's due to the nature of lisp.
<nij-> It does not consist of an example that is persuasive for nonlispers.
<lotuseater> it's just about YOU now :) and yes, I used it as such some times
<nij-> I guess I know why macros are important and useful. I'm just trying to find some example that's persuasive even to nonlispers.
<lotuseater> any WHY are if/and/or not useful as function?
<nij-> (so then I can smug and talk them into lisp xD)
<aeth> HTML is my go-to example
<aeth> since it's just so radically different rather than just sugar
<nij-> aeth: yes, I'm thinking about that
<aeth> that you string-generate from s-expressions rather than embed the source code into raw files as a template language
<aeth> generally
<nij-> aeth: Or more generally, s-expressions help us lift a language from its syntax to its meaning easily?
<nij-> So as long as it's dealing with some sort of translation, lisp macros shine?
<lotuseater> nij-: so say if you have an answer :)
<aeth> nij-: well, more generally, s-expressions help do at compile time what you'd probably otherwise do at runtime
<aeth> and string-generation is just one of the simplest cases of that (you can easily just generate down to one constant string or down to a FORMAT call)
<nij-> Why do we sometimes want it to be done at compile time?
<aeth> well it's two things
<aeth> 1. same syntax everywhere (so you want to do it more than in other languages) and 2. it's done at compile time (so it's more efficient than many approaches)
<aeth> so if you have to work with some external language (HTML, CSS, JS, GLSL, etc.) you probably want to generate it
<aeth> and you want to represent it the same way as the CL source
<hayley> nij-: Yes, but why would you?
<lotuseater> it's something like using a meta plateau for this foreign stuff
<nij-> hmm i see
<jcowan> It's perfectly possible to write IF as a function: (defun if* (p t e) (if p (t) (e)))
<lotuseater> when it's no problem that t and e get evaluated
<aeth> usually anything that you can write as a function can be written as a macro if you're okay with quoting, lambdas, etc.
<lotuseater> in before or unneccessary
<aeth> sorry, the other way around
<aeth> usually anything you can write as a macro can be written as a function
<aeth> it'll just look uglier
<nij-> jcowan: (if* t 1 (loop))
<nij-> It never returns 1 for me.
<aeth> in jcowan's case, if* is designed to take in lambdas iirc
<jcowan> Just sio
<jcowan> so
<aeth> you still get the delayed evaluation, but it looks uglier
<jcowan> like Smalltalk
<nij-> i c
<nij-> If sexprs are so great, why isn't there a yaml that's sexp..?
<aeth> and the other thing (other than taking in LAMBDAs) you can do instead of a macro is EVAL something that's quoted, but that won't always work, and it's not a good style
<jcowan> That's partly because (lambda () ...) is much more verbose than Smalltalk's [...] notation
<aeth> Although if you don't need to EVAL it you could just walk through it, which is safer.
<hayley> nij-: Why isn't there an orange that's an apple?
<aeth> e.g. the HTML macro we were talking about earlier could also be an HTML function that just takes in quoted s-expressions
<jcowan> There are: the golden apples oof the Hesperides
<nij-> hayley: \ @@ /??
<lotuseater> so nij- how do you write the function for *= ?
<hayley> I wonder how many people I could trip up in a pure message-passing Lisp wherein IF is a macro defined such that (if p t e) == (if: p (lambda () t) (lambda () e))
<aeth> Macros are basically just the last level of polish
<hayley> nij-: S-expressions and YAML are both representations of some tree structure. You don't have to do anything to get something "YAML-like".
<nij-> lotuseater: tried (defun *= (sym val) (setf sym (* sym val))) but it didn't work.
<nij-> The form inside cannot get the address outside.
<lotuseater> sad
<hayley> (define-modify-macro *= *)
<nij-> hayley: Oh by that I mean.. why don't people use some sexp-based lang instead of yaml.
<lotuseater> hayley: cheater :P he shall figure out himself why
<nij-> I know why you can't use a function for *=..
<jcowan> People can and do.
<lotuseater> You do?
<jcowan> Where is "is an error" defined in the CLHS?
<nij-> jcowan: ?! Any de facto lang based on sexp?!
<lotuseater> pff de facto
<hayley> Why the ceremony for another "language"? It's just another damn tree representation.
<aeth> technically, CL isn't a tree
<aeth> it's in the /topic
<aeth> #1=(programmable . #1#)
<hayley> beach tends to modify the printer so that [ blah :initarg-name value ... ] will read an object by (make-instance 'blah :initarg-name value ...) and an object will be written like that.
<hayley> That requires no additional processing on either end, other than READ and WRITE. Nothing more really needs to be specified.
<jcowan> https://people.csail.mit.edu/rivest/Sexp.txt never made it to an RFC
<nij-> Why didn't it made to an rfc?!
<nij-> It's so sad that it didn't.. why jcowan
<jcowan> Politics, no doubt
<lotuseater> nij-: so how to write *= without having DEFINE-MODIFY-MACRO ?
<nij-> As a macro? lotuseater
<lotuseater> I now, I'm annoying as always.
<nij-> jcowan: Is it too late? Someone can push it again to an rfc?
<lotuseater> Yes, so *how*?
<lotuseater> PUSH is also not a function :) but VECTOR-PUSH is indeed
<jcowan> Presumably yes. The draft has long since expired, as it's dated 1997
<nij-> lotuseater (defmacro *= (sym val) `(setf ,sym (* ,sym ,val)))
<lotuseater> okay, progress
<nij-> :)
<lotuseater> and of course this is not just bound to be used on symbols, but also to places
<lotuseater> so now you can think on how to write DEFINE-MODIFY-MACRO ;)
<lotuseater> and abstracting things like that, even locally when they're used over and over is even safer
<jcowan> https://github.com/s-expressions/pose is a suggestion for an S-expressioh syntax that works in all Lisps with just READ and WRITE/PRINT/DISPLAY as the case may be. THere are also implementations for other languages there
pillton has joined #commonlisp
prxq_ has joined #commonlisp
<nij-> jcowan: Hmm.. I see pose does provide a spec. But what is it, really?
<nij-> It seems to give some codes in various langs. What is it doing?
kulernil has joined #commonlisp
prxq has quit [Ping timeout: 258 seconds]
<beach> Good morning everyone!
<nij-> Good morning beach.
<lotuseater> Ohai beach :)
silasfox has joined #commonlisp
Skyfire has quit [Quit: WeeChat 3.2]
Skyfire has joined #commonlisp
vats has quit [Ping timeout: 240 seconds]
<kakuhen> For some reason, READ-BYTE is messing with the endianness of byte I am reading out of a file
<moon-child> what do you mean?
<kakuhen> I have a file with magic number 0x664C6143, and the following is what I did
<kakuhen> (with-open-file (s "~/Music/sample.flac" :direction :input :element-type '(unsigned-byte 32)) (format t "~S~%" (read-byte s))) ; => #x43614C66
<moon-child> 'unsigned-byte 32' is your problem
<kakuhen> oh
<beach> moon-child: Why? That should work, no?
<moon-child> beach: it is reading a 32-bit byte, and interpreting it in the native endian
<moon-child> where the original file is an endianness-agnostic sequence of octets
derelict has quit [Ping timeout: 240 seconds]
<beach> Ah, so that's not a problem then. It is doing it right.
<hayley> When in doubt, use a (unsigned-byte 8) stream and have the Nibbles library read with the right endianness.
<hayley> i.e. (nibbles:read-ub32/be s)
<kakuhen> ooh this seems like a convenient library for what I want to do; thanks hayley
<beach> kakuhen: Which one is the first byte of the file, and what is the native endian-ness of your system?
<kakuhen> the first byte of the file is 0x66 and my system is little-endian
<beach> Then READ-BYTE is not messing with the endian-ness.
<moon-child> it's clearer as characters: fLaC
<moon-child> you want to read individual octets
<beach> kakuhen: That is the right answer.
<moon-child> (at least for that part; by the time you get to samples, go bigger and do as hayley suggests)
<kakuhen> yeah i naively thought I could just specify and (unsigned-byte 32) and read-byte once to ensure the magic number is right
<kakuhen> thanks for the help, you three
<kakuhen> specify an*
<beach> I still think it is important to establish that READ-BYTE is doing the right thing.
lisp123 has joined #commonlisp
<White_Flame> phantomics: what was it, out of curiosity?
nij- has quit [Quit: Using Circe, the loveliest of all IRC clients]
taiju has quit [Ping timeout: 240 seconds]
taiju has joined #commonlisp
blihp has quit [Quit: Leaving]
azimut_ has quit [Remote host closed the connection]
azimut has joined #commonlisp
Bike has quit [Quit: sleep]
gaqwas has joined #commonlisp
rain3 has joined #commonlisp
derelict has joined #commonlisp
derelict has quit [Ping timeout: 245 seconds]
gaqwas has quit [Ping timeout: 268 seconds]
lisp123 has quit [Remote host closed the connection]
lisp123 has joined #commonlisp
Inline has quit [Quit: Leaving]
lisp123 has quit [Ping timeout: 268 seconds]
rgherdt has joined #commonlisp
lisp123 has joined #commonlisp
lisp123 has quit [Ping timeout: 240 seconds]
paulman has joined #commonlisp
kulernil has quit [Ping timeout: 244 seconds]
lisp123 has joined #commonlisp
amb007 has quit [Ping timeout: 248 seconds]
amb007 has joined #commonlisp
silasfox has quit [Ping timeout: 245 seconds]
<kakuhen> hayley: I don't understand the documentation for nibbles:read-ub32/le-into-sequence, or maybe I am using it wrong
silasfox has joined #commonlisp
<kakuhen> I made an octet-vector with 8 elts in it, then decided to invoke this function with the vector. It copies one element fine then signals an error the remaining stuff
<hayley> "Each element is a 32-bit unsigned integer read in little-endian order." Do you not need a (unsigned-byte 32) array?
<kakuhen> oh i am dumb
<kakuhen> I misinterpreted "STREAM must have an element type of (UNSIGNED-BYTE 8)" to mean that the vector should also match the element type of the stream, but that is false
silasfox has quit [Ping timeout: 245 seconds]
silasfox has joined #commonlisp
retropikzel has joined #commonlisp
gaqwas has joined #commonlisp
amb007 has quit [Read error: Connection reset by peer]
amb007 has joined #commonlisp
rgherdt has quit [Remote host closed the connection]
derelict has joined #commonlisp
lisp123 has quit [Ping timeout: 245 seconds]
Lord_of_Life_ has joined #commonlisp
Lord_of_Life has quit [Ping timeout: 240 seconds]
Lord_of_Life_ is now known as Lord_of_Life
lisp-newbie has joined #commonlisp
pve has joined #commonlisp
Cymew has joined #commonlisp
Krystof has joined #commonlisp
lisp-newbie has quit [Quit: This computer has gone to sleep]
selwyn_ has joined #commonlisp
selwyn_ has quit [Remote host closed the connection]
selwyn_ has joined #commonlisp
lisp-newbie has joined #commonlisp
heisig has joined #commonlisp
hendursa1 has joined #commonlisp
lisp123 has joined #commonlisp
amb007 has quit [Read error: Connection reset by peer]
amb007 has joined #commonlisp
hendursaga has quit [Ping timeout: 244 seconds]
makomo has joined #commonlisp
waleee has joined #commonlisp
micro has quit [Quit: Lost terminal]
micro has joined #commonlisp
lisp123 has quit [Remote host closed the connection]
lisp123 has joined #commonlisp
lisp123 has quit [Ping timeout: 248 seconds]
lisp-newbie has quit [Quit: This computer has gone to sleep]
lisp123 has joined #commonlisp
lisp123 has quit [Remote host closed the connection]
lisp123 has joined #commonlisp
lisp-newbie has joined #commonlisp
retropikzel has quit [Remote host closed the connection]
retropikzel has joined #commonlisp
retropikzel has quit [Quit: Leaving]
waleee has quit [Ping timeout: 240 seconds]
waleee has joined #commonlisp
nij- has joined #commonlisp
gpiero_ is now known as gpiero
lisp-newbie has quit [Quit: This computer has gone to sleep]
Oddity has quit [Ping timeout: 245 seconds]
PinealGlandOptic has joined #commonlisp
NeoCron has quit [Quit: Leaving]
<flip214> https://github.com/mbattyani/cl-pdf/blob/master/zlib.lisp contains a few #+ cases; I've got :USE-SALZA2-ZLIB in *features*, :USE-NO-ZLIB is not included, but COMPRESS-STRING is the #+use-no-zlib one? (according to the disassembly)
NeoCron has joined #commonlisp
jasom has quit [Ping timeout: 258 seconds]
Oddity has joined #commonlisp
<flip214> removing fasl cache and recompiling doesn't help
<flip214> hrmpf
<lisp123> flip214: Are you using ASDF? By the way it has a way to force recompliation (add :force t to your asdf command)
waleee has quit [Ping timeout: 248 seconds]
kakuhen_ has joined #commonlisp
<flip214> lisp123: QL, which uses ASDF... but I already touched the ASD files as well, and removed fasls, so it got recompiled
<lisp123> (Sorry because I'm a bit new to ASDF), does that mean you manually removed the fasls?
kakuhen has quit [Ping timeout: 240 seconds]
<flip214> yes
selwyn_ has quit [Read error: Connection reset by peer]
<flip214> now I touched the ASD again, recompiled, and it works? what's different to the last 15 tries?
<lisp123> No, just that if you call ASDF directly (and perhaps there's an option in QL) you can simply tell it to recompile everything instead of removing the files first
<lisp123> Won't solve your problem, but hopefully a quality of life improvement over the long run
<mfiano> asdf will recompile everything in a module that has a newer timestamp
<mfiano> The asd itself is the root module, so touching it works for the whole system to be recompiled
<mfiano> but if you modify single files, only that file and files thereafter in the same module will be recompiled
<mfiano> (if you use multiple modules)
PinealGlandOptic has quit [Quit: leaving]
gxt has quit [Remote host closed the connection]
gxt has joined #commonlisp
kakuhen_ has quit [Quit: Leaving...]
frgo has quit [Remote host closed the connection]
frgo has joined #commonlisp
pillton has quit [Ping timeout: 256 seconds]
<mfiano> I'm struggling to remember the correct FORMAT incantation to conditionally include part of the string (and conditionally the "-" delimiter in this case): (format nil "test..." nil) => "test", (format nil "test..." "foo") => "test-foo"
cosimone has joined #commonlisp
<nij-> Can I safely use quicklisp and ultralisp at the same time?
<nij-> I'm afraid that they will pollute each other.
<mfiano> flip214: Yes, I'm trying to figure out the above semantics with that page open
* mfiano needs coffee it seems
<Xach> nij-: yes. when there is something available by the same name in each, you can choose which has priority.
silasfox has quit [Ping timeout: 258 seconds]
<flip214> (format nil "test~@[~a~]" "foo")?
<mfiano> flip214: no condition "-" there
<mfiano> conditional*
<flip214> (format nil "test~@[-~a~]" "foo")?
<flip214> sorry
<nij-> Xach: is there something like (ql:quickload :pkg1 :from 'quicklisp)?
<Xach> nij-: no.
paulman has quit [Remote host closed the connection]
<mfiano> thanks
silasfox has joined #commonlisp
paulman has joined #commonlisp
<flip214> for systems in multiple distributions, does QL use version numbers? If yes, can I prepend an epoch to make my version "better"? (like in Debian)
<Xach> flip214: there is a preference value, an integer. it can be set at the dist level, the project level, or the system level.
<Xach> it defaults to dist-wide and is initialized with the universal-time at which the dist was installed.
random-nick has joined #commonlisp
<mfiano> Xach: Can you remove my feed? (not sure if you got the last request)
<flip214> mfiano: try (macroexpand-1 '(formatter "test~@[-~a~]"))
<Xach> mfiano: from planet lisp?
<mfiano> Yes
<Xach> i can
<mfiano> I am moving it to gemini, and i don't want to use a script to create a feed that would look decent for the web
<Xach> it is done
<mfiano> thanks
gxt_ has joined #commonlisp
Spawns_Carpetin- has joined #commonlisp
gxt has quit [Remote host closed the connection]
Spawns_Carpeting has quit [Ping timeout: 248 seconds]
<pjb> flip214: mfiano: https://termbin.com/ono7
lisp-newbie has joined #commonlisp
lisp-newbie has quit [Client Quit]
Spawns_Carpetin- has quit [Ping timeout: 240 seconds]
Spawns_Carpeting has joined #commonlisp
lisp-newbie has joined #commonlisp
<MetaYan> mfiano: Not what you asked for, but the format function sure is pretty amazing: (format nil "test~{~@[-~a~]~}" '("foo" "bar" "ding"))
<jackdaniel> format - the operator where the readability of perl meets the homoiconity of c
<gin> Why does this evalute to 2? (let ((nums (read-from-string "'(10 20 30 40 50)"))) (length nums)) => 2
<mfiano> because of the QUOTE
<gin> But this one evaluates to 5. (let ((nums (read-from-string "(10 20 30 40 50)"))) (length nums)) => 5
knobo has joined #commonlisp
<gin> mfiano: where does the 2 come from? 2 of what?
<jackdaniel> '(10 20 30 40 50) is in fact (quote '(10 20 30 40 50))
<Xach> jackdaniel: BOO
<jackdaniel> yeah, without '
<gin> jackdaniel: thanks
<jackdaniel> (quote (10 20 30 40 50))
<_death> gin: try (write (read-from-string "'(10 20 30 40 50)") :pretty nil)
nij- has quit [Read error: Connection reset by peer]
cosimone has quit [Remote host closed the connection]
lisp123 has quit [Remote host closed the connection]
lisp123 has joined #commonlisp
silasfox has quit [Ping timeout: 245 seconds]
lisp123 has quit [Ping timeout: 258 seconds]
silasfox has joined #commonlisp
Qwnavery has joined #commonlisp
<Qwnavery> #lispcafe
* edgar-rft hands Qwnavery a mug of coffee with lots of lisp in it
* Qwnavery sips
<Qwnavery> ^_^
<gin> what do you think of the indentation of the last parentheses here: https://plaster.tymoon.eu/view/2596#2596 is it bad? how else do you make it easy to add new entries in between without the closing paren on its own line?
<beach> gin: It is bad. What you do is C-M-f and then RET
<gin> beach: thanks
<beach> Sure.
heisig has quit [Quit: Leaving]
<gin> my workflow is to copy one plist, then paste it, then edit it for the new entry. so looks like my workflow is going to be C-M-k to cut a plist, C-/ to undo the cut, C-M-f to put the cursor after the last plist, RET to create a new line, then C-y to paste it.
<_death> gin: I sometimes do that (with the last parenthesis)
<beach> _death: Yes, but that was not the question.
<gin> _death: You mean you sometimes leave the last paren on its own line?
<_death> well, my answer is that it may be practical and therefore not bad
<_death> gin: yes, for cases like you've shown
<gin> _death: thanks. good to know that.
lisp-newbie has quit [Quit: This computer has gone to sleep]
<beach> It is even better to be comfortable with your editor commands. One thing I sometimes do is I insert the entry before the last one, and when I am done, I do C-M-t.
<beach> I mean, you don't want to leave that dangling parenthesis there anyway, and it is hard to decide when you are done. So inevitably, you are going to have to insert when the parenthesis is on the same line at some point.
lisp-newbie has joined #commonlisp
<_death> I agree that the dangling parentheses (it's usually more than one) are less aesthetically pleasing, so if you don't mind putting the effort or don't even feel there is an effort, it makes sense.. every now and then, though, I have cases where adding/removing entries happens frequently enough that I just leave them dangling.. usually it's when the entries are single lines though, I think
<hayley> I have a habit of addling danglies after a line comment describing what code I need to write eventually. But no one ever sees them, because I eventually write that code before committing.
<hayley> Say, something like (when blah <newline> ;; Handle blah by frobbing the quux <newline> )
lisp123 has joined #commonlisp
<_death> if I looked at my snippets directory, which has 566 lisp files.. there are 14 files with dangling-parens
Qwnavery has quit [Quit: WeeChat 3.2]
karlosz has joined #commonlisp
tyson2 has joined #commonlisp
Fare has joined #commonlisp
silasfox has quit [Ping timeout: 258 seconds]
silasfox has joined #commonlisp
lisp-newbie has quit [Quit: This computer has gone to sleep]
Bike has joined #commonlisp
<gin> beach: C-M-t is very useful. thanks! I think I will use this one from now on.
<beach> Sure.
<lisp123> https://github.com/unjordy/LispM-Font Fonts from the Lisp Machine
<lisp123> I tried using it on my Emacs, but looks terrible. Not sure if its an Apple issue
Lycurgus has joined #commonlisp
<hayley> Yes, it is a bitmap font really, but someone traced it and you really have to suffer trying to a. disable antialiasing and b. get the pixels to match up.
<lisp123> hayley: I see, thanks. Oh well
<hayley> I ran with it for a while, but then gave up and eventually used Computer Modern Typewriter Text. Which is funny, because that font does have embedded bitmaps or something.
<lisp123> I am using Courier New and it is _nice_
<beach> lisp123: Why would you want the fonts from the Lisp Machine?
<lisp123> I will have a look at Computer Modern Typewriter Text - likely will work well with LaTeX
<hayley> I guess the font looks fine. Though my favourite old bitmap font would have to be Cream from Smalltalk.
<lisp123> beach: I am writing some documentation and wasting time on design :) I got the background color from the cover of CLTL2E - #9DC2B0
<hayley> There was a vector version of it for printers, but I only found one picture of it. I failed miserably at trying to remake it in Metafont and ended up doing my own thing.
<lisp123> hayley: Oh nice, I have been thinking of getting into MetaFont. I assume it takes a lot of time
<lisp123> I would also like a font that matches some of the academic papers from the 60s - 80s, (sorry for going off topic), if you know something that would work well there?
<hayley> In my opinion, it is easier than any other technique for font making, because it is a structured programming language, and it rather simulates a pen tracing some path, instead of having you specify an outline of the imaginary pen.
<lisp123> I see, that's interesting
<akater[m]> gin: I often leave dangling parentheses in these cases. Navigating to the end of lists so written is faster if you use avy.
<hayley> lisp123: Well, I don't use any custom fonts in my documentation. Some of the articles I've written are styled with one title font (Computer Modern Typewriter Text Variable-Width) to match the site logo, but that is it.
<hayley> See https://cal-coop.gitlab.io/netfarm/documentation/ - I took inspiration from books I had for the layout of small things like function definition lines, but it is mostly unique.
<lisp123> hayley: It is very nice. Which program did you use?
<lisp123> (by the way I learnt org mode can be really helpful here because it can output syntax highlighted & indented lisp code - without javascript or anything fancy)
karlosz has quit [Quit: karlosz]
<hayley> I used to use LaTeX and htlatex, but found the output contained too many errors to fix, so I rewrote everything in Racket's Scribble language.
<hayley> Both the HTML and TeX outputs of Scribble have a few errors, but I can "fix" them with a few passes of sed unfortunately.
knobo has quit [Quit: Client closed]
<lisp123> hayley: Thanks, I will have a look at Scribble. I tweaked org mode mostly, I think I was able to get basically what I wanted from it, I may try replicating (or somewhat similar) to what you have in Org and see if I can do it
<hayley> Sure, org mode should work well too.
<lisp123> Love the <- prev up next ->, those arrows are perfect. I was spending so much time to get that part looking nice
tyson2 has quit [Quit: ERC (IRC client for Emacs 27.2)]
<gin> is there a function that can sum numbers in a list? example: (multi-sum '(10 20 30)) => 60
<Bike> (reduce #'+ '(10 20 30))
<gin> oh! nice. thanks Bike
<Bike> glad to help
<gin> any review comments on this? I want to pick :c value from each plist and sum them up. (defparameter *plist* '((:c 10) (:c 20) (:c 30))) (reduce #'+ (loop for entry in *plist* collect (getf entry :c)))
<akater[m]> gin: That's not a plist.
<gin> bad variable name. should have been *list-of-plists*.
<beach> I think gin meant *plists* in plural.
<gin> yes, *plists*
<gin> any other review comments apart from the bad name. just curious to know if my code is unnecessarily complicated or if that is how you would do it too.
jasom has joined #commonlisp
<beach> Looks fine to me.
<gin> thanks beach
<beach> Oh, and I would not call the loop variable ENTRY, but PLIST.
<beach> So you have (loop for plist in *plists*...)
<beach> That a very nice pattern, i.e., (loop for <singular-noun> in <plural-noun>...)
<Bike> gin: if a plist doesn't have :c there will be an issue. i don't know if you need to worry about that.
<Xach> That could be solved by switching to something like :key (rcurry 'getf :c 0)
<akater[m]> gin: `(loop for (&key c) in '((:c 1) (:c 2)) sum c)`
<Xach> so many options
<Bike> loop destructuring doesn't accept lambda list keywords, does it?
<beach> akater[m]: I think each plist in the example was simplified.
<akater[m]> But I'm not sure it's standard,
<Bike> that "works" because it treats &key as a variable
<beach> Bike is right.
<Bike> so (loop for (&key c) in '((:c 1) (:d 7)) sum c) => 8
<beach> Hence my remark that the example was simplified.
<akater[m]> And `loop for (&key (c 0)) …` doesn't work for me, sadly.
<beach> akater[m]: It doesn't work because of what Bike said.
<gin> beach: akater[m]: yes, they were simplified plists
<akater[m]> Yes, it doesn't destructure, sad.
<beach> gin: Did you see my remark about singular/plural in the LOOP clause.
<gin> beach: yes, I used it in my code. in my real code it isn't named *plists* of course. it is named *orders*, so (loop for order in orders ...) looks nice. thanks for the the pattern.
<beach> Ah, yes, I see.
nij- has joined #commonlisp
ec has joined #commonlisp
tyson2 has joined #commonlisp
Alfr has quit [Quit: Leaving]
karlosz has joined #commonlisp
<hexology> What about this? (reduce '+ (loop for entry in *data* collect (getf entry :c 0)))
rudi has joined #commonlisp
<hexology> oops, #'+
<pjb> (loop for entry in *data* sum (getf entry :c 0)) is simplier.
<beach> Unnecessary consing, no?
<pjb> '+ or #'+ is the same when it's cl:+
<hexology> it seems like it should be valid for any function, being a valid "function designator" http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_f.htm#function_designator
<hexology> i didn't actually realize this. it looks like REDUCE, MAPCAR, etc support "designators" as well as actual function objects. and i guess the only valid "designator" for a function is a symbol of the function name. but it also looks like the designator/symbol thing only works if the function is defined in the global environment.
<hexology> i can't tell what the difference is between a "function designator" and an "extended function designator" http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_e.htm#extended_function_designator
<hexology> the wording is different so i must be missing a subtle difference
cage has joined #commonlisp
<Bike> an extended function designator can be a "function name", which can include lists (SETF whatever)
<Bike> a "function designator" can only be a function or a symbol
<Bike> and yes, it's only global lookups
<Bike> also what beach meant by unnecessary consing was the loop.
<hexology> right
<hexology> re: "function name", what do they mean by "a list (SETF symbol)"?
<Bike> um, just that. i don't know how to explain it otherwise. the name of a setf function.
<Bike> a list whose first element is the symbol SETF and whose second element is a symbol.
<rudi> Stackoverflow to the rescue! https://stackoverflow.com/a/11458640 shows how to define such a function
<hexology> your answer is better rudi thank you
<hexology> so as per <http://www.lispworks.com/documentation/HyperSpec/Body/05_abi.htm>, if i do (DEFUN (SETF foo) ...), then (SETF (foo 2 3) 1) is equivalent to (FUNCALL (FUNCTION (SETF foo)) 1 2 3)
<hexology> so this lets you "hook" into SETF'ing certain things
<beach> It's that (setf (bla ...) ...) by default expands to (funcall #'(setf bla) ...)
<hexology> oh
d4ryus1 has joined #commonlisp
<Xach> there is a funny bug in allegro - something like (setf (bla bloo) 42) will call compiler macros on BLA but not on (SETF BLA).
<beach> hexology: Try (macroexpand-1 '(setf (bla x) y)) for instance.
<Bike> huh. that's pretty weird.
<Bike> with how setf is usually defind it's hard to understand how that would happen
<Xach> Allegro - Far From Usual
<hexology> is that where the "f" comes from?
<beach> "that"?
d4ryus has quit [Ping timeout: 248 seconds]
ec has quit [Ping timeout: 244 seconds]
<pjb> hexology: local (lexical) functions are like local lexical variables: their name may be optimized out by the compiler.
<pjb> (defun foo () 'outside) (mapcar 'funcall (flet ((foo () 'inside)) (list 'foo #'foo))) #| --> (outside inside) |#
<pjb> While of course: (defun foo () 'outside) (mapcar 'funcall (list 'foo #'foo)) #| --> (outside outside) |#
<pjb> so whether 'foo designates the same function as #'foo depends on the lexical context.
<lotuseater> hexology: the "f" stands for "form" afaik
shka has joined #commonlisp
<pjb> But since it's forbidden to write something like (flet ((identity (x) x)) #'identity) then 'identity designates always the same function as #'identity (cl:identity).
<nij-> While using ultralisp, if I want to use an older version of some system, is it easily doable?
<hexology> i see.. so the function designator has to refer to global definitions only, in order to permit this kind of compiler optimization
doyougnu has joined #commonlisp
<hexology> i will have to try to wrap my head around SETF another time
<lotuseater> yeah depends how far you are now, first it would totally be enough using the pre- or automatically defined ^^ a powerful facility
ec has joined #commonlisp
<lotuseater> Xach: and the bug still remains?
<hexology> it seems like the setf-function thing is good for writing CLOS "setters" https://lispcookbook.github.io/cl-cookbook/clos.html#controlling-setters-setf-ing-methods
<beach> hexology: A method on a generic function named (SETF FOO) is automatically generated when you write :ACCESSOR FOO in a slot description of DEFCLASS.
<lotuseater> when you use :accessor it's generated for you by the DEFCLASS macro
<beach> Heh.
<lotuseater> beach: ack
<rudi> But it
<rudi> ... but it's nice to be able to write :around functions on such functions etc.
<beach> Indeed.
<lotuseater> beach: So the difference is, that it will be a method, right? Rather than eg (SETF AREF) which is a function.
nij- has quit [Quit: Using Circe, the loveliest of all IRC clients]
<beach> Well, (SETF FOO) is a function too, but a generic one.
<rudi> every method is a function, but yes - you can write (defmethod (setf foo) :around (...) ...)
pve_ has joined #commonlisp
<lotuseater> so the bug can now go to jail for being naughty
<lotuseater> oh by a dude named Wozniak :)
yitzi has joined #commonlisp
<beach> Probably a common Polish name I would think.
pve has quit [Ping timeout: 240 seconds]
peterhil_ has joined #commonlisp
peterhil has quit [Ping timeout: 268 seconds]
selwyn has joined #commonlisp
selwyn has quit [Remote host closed the connection]
selwyn has joined #commonlisp
Inline has joined #commonlisp
pve_ is now known as pve
nij- has joined #commonlisp
random-nick has quit [Read error: Connection reset by peer]
nij- has quit [Client Quit]
silasfox has quit [Ping timeout: 240 seconds]
silasfox has joined #commonlisp
Alfr has joined #commonlisp
ec has quit [Ping timeout: 244 seconds]
lisp-newbie has joined #commonlisp
lisp-newbie has quit [Client Quit]
selwyn has quit [Read error: Connection reset by peer]
ec has joined #commonlisp
<Josh_2> Hi Hi
hendursa1 has quit [Quit: hendursa1]
hendursaga has joined #commonlisp
<Josh_2> mfiano: I saw that you made your game engine public, is that the one you had been working on for a long time?
<mfiano> Yeah I made it public to link jeosol a file in it...it's a rewrite of the one that I've been working on for a long time that only took me a couple days...and there is lots I learned since then that I want to redo still :)
ec has quit [Remote host closed the connection]
ec has joined #commonlisp
<Josh_2> Very cool! Weren't you running into some performance problems with the last one?
waleee has joined #commonlisp
<mfiano> Yeah, due to method dispatch
silasfox has quit [Ping timeout: 240 seconds]
lisp123_ has joined #commonlisp
tyson2 has quit [Ping timeout: 252 seconds]
<mfiano> In other news, I highly recommend people interested in a sane solution to versioned dependencies to check out CLPM as a nice alternative to Quicklisp. I switched to it recently and the amount of time it saves me and other collaborators I work with is very nice.
karlosz has quit [Quit: karlosz]
lisp123 has quit [Ping timeout: 248 seconds]
ec has quit [Ping timeout: 244 seconds]
yitzi has quit [Quit: Leaving]
selwyn has joined #commonlisp
lisp123 has joined #commonlisp
psycomic has joined #commonlisp
random-nick has joined #commonlisp
tyson2 has joined #commonlisp
tyson2 has quit [Remote host closed the connection]
lisp123_ has quit [Ping timeout: 252 seconds]
<shka> mfiano: it replaces quicklisp or just builds on top of it?
<mfiano> Replaces
<shka> i will have to check it out
<shka> package versioning is a problem honestly
<etimmons> But can also use QL metadata so you still have every system in QL available to you.
<mfiano> It still benefits from the Quicklisp dists (it can use the metadata as a source, just like git, etc), and it knows from which dist it got it from, so your lockfile that you distribute has reproducible versions for anyone building your code.
<shka> oh, this is SMART
<mfiano> There is a matrix room if you have any questions about it (don't think there is an IRC channel...yet): https://matrix.to/#/#clpm:matrix.org
selwyn has quit [Read error: Connection reset by peer]
<shka> thanks
Fare has quit [Remote host closed the connection]
ec has joined #commonlisp
cosimone has joined #commonlisp
selwyn has joined #commonlisp
amb007 has quit [Ping timeout: 240 seconds]
amb007 has joined #commonlisp
tyson2 has joined #commonlisp
aeth has quit [Ping timeout: 245 seconds]
aeth has joined #commonlisp
cosimone has quit [Remote host closed the connection]
lad has quit [Ping timeout: 240 seconds]
Lycurgus has quit [Quit: Exeunt]
Lord_of_Life has quit [Read error: Connection reset by peer]
Lord_of_Life has joined #commonlisp
Lord_of_Life has quit [Read error: Connection reset by peer]
Lord_of_Life has joined #commonlisp
Lord_of_Life has quit [Read error: Connection reset by peer]
Lord_of_Life has joined #commonlisp
Lord_of_Life has quit [Read error: Connection reset by peer]
Lord_of_Life has joined #commonlisp
Lord_of_Life has quit [Read error: Connection reset by peer]
Lord_of_Life has joined #commonlisp
amb007 has quit [Read error: Connection reset by peer]
amb007 has joined #commonlisp
lad has joined #commonlisp
lisp123 has quit [Remote host closed the connection]
lisp123 has joined #commonlisp
lisp123 has quit [Ping timeout: 252 seconds]
lambdatheultimat has joined #commonlisp
psycomic has quit [Ping timeout: 240 seconds]
cosimone has joined #commonlisp
lambdatheultimat has quit [Remote host closed the connection]
psycomic has joined #commonlisp
amb007 has quit [Read error: Connection reset by peer]
karlosz has joined #commonlisp
amb007 has joined #commonlisp
lisp123 has joined #commonlisp
amb007 has quit [Ping timeout: 252 seconds]
tyson2 has quit [Quit: ERC (IRC client for Emacs 27.2)]
amb007 has joined #commonlisp
lisp123 has quit [Ping timeout: 268 seconds]
cosimone has quit [Ping timeout: 258 seconds]
lisp123 has joined #commonlisp
semz has joined #commonlisp
nij- has joined #commonlisp
lad has quit [Quit: Leaving]
<nij-> In CL, can I take exact square root, without losing any precision?
Oladon has joined #commonlisp
<nij-> (= 2 (expt (sqrt 2) 2)) ;; => NIL
<moon-child> nij-: what form do you want this 'exact square root' to take?
<semz> there's isqrt for integers if you know a priori that the square root should be integral
<moon-child> the square root of 2 cannot be precisely represented using a floating-point number. I know of no primitive data type in cl that precisely represents the square root of two except for the list (sqrt 2) (which you may quote if you would like to manipulate it symbolically)
<akater[m]> nij-: Not with the standard. This requires a symbolic algebra system. Check out various CASes in CL. I know of Maxima and Weyl. But I never tried to get any deep into these.
aeth_ has joined #commonlisp
aeth has quit [Killed (NickServ (GHOST command used by aeth_))]
aeth_ is now known as aeth
<Bike> there's an old computable-reals library that could be used https://github.com/stylewarning/computable-reals
<Bike> but i don't know what nij has in mind here
<Bike> the square root of two can't be represented as a float and also can't be represented as a rational, because it is irrational. you could use a repeating continued fraction since it's a surd, i guess.
<lotuseater> nij-: of course. you take (sqrt 2) => '(sqrt 2)
<nij-> Bike: the form (MAKE-REAL fun) makes me laugh
<moon-child> nij-: depending on your goals, you might also want to do approximate comparison (>= *epsilon* (abs (- 2 (expt (sqrt 2) 2)))). However, this is prone to rounding and floating-point error and _will_ lead to unexpected resrults if you are not careful
<nij-> I may just start writing a wrapper for sagemath...
<Bike> also, per richardson's theorem, real arithmetic (with exp, identity, sin, and rationals) is not decidable
<Bike> which the readme sort of obliquely mentions
<Bike> in that it implies that = does not necessarily terminate
<Bike> so, think carefully about what you want to do
<nij-> yeah the true set of real numbers are not possible
<lotuseater> Bike: good that you are aware of continued fractions :) even pi and e have regular patterns with that ^^
<nij-> It's an uncountable set, but all we can express are countably many.
<semz> equality on computable numbers isn't decidable either
<Bike> that's true, bu- yes, that.
<Bike> and yeah i tried to work out how to do square roots on paper when i was a kid and stumbled on hakmem. continued fractions are neat
<nij-> OK nvm
<semz> the argument is pretty simple even: assume it was and take two equal numbers. if equality for them is determined after inspecting n digits, the algorithm would erroneously signal equality if they first differed on the n+1-st digit
<nij-> What should I pay attention to if I want to write a wrapper for sagemath?
<semz> maxima :-)
<nij-> Like I should be familiar with CLOS.. but to what extent?
<moon-child> maxima!
<nij-> semz: moon-child ?? I'm talking about sagemath..
<moon-child> why do you want to wrap sagemath?
<lotuseater> nij-: sagemath uses also maxima
<nij-> b/c sagemath includes maxima and is therefore larger (?)
<nij-> sagemath also supports very advanced mathematics.
<nij-> sad to say.. but maxima doesn't (yet)
<nij-> But at the end it shouldn't matter. All I want is a calculator in lisp.
<nij-> If I can design a wrapper correctly, the new cl-sage should be able to absorb goodies from different langs.
<nij-> Let's call it cage.
<lotuseater> don't mix up advanced with abstract
<nij-> mmmhmmmm ok abstract
<lotuseater> Macsyma was from what I know a very capable system from its very beginning.
<lotuseater> one can always say "oh but this system doesn't include my newest special topic in my special topic"
<nij-> I dunno.. sagemath's ability to deal with abstract math seems to be the most promising.
<nij-> schemes, hecke algebra, and homology are not small and specialized topics
<lotuseater> so then.
<semz> https://clbin.com/hkJT4 <- Am I missing something obvious or is this a bug in CCL 1.12?
<semz> SBCL eats it without complaint as I'd expect it to from my (flaky) understanding of array type upgrades
<lotuseater> hm it makes sense giving '(unsigned-byte 40) gets stretched to fixnum
<Bike> seems buggy to me.
<lotuseater> I realized in (my) CCL version with 64bit a fixnum is 60 bits wide, in SBCL 62.
<nij-> What's the de facto way to read a python object into cl?
<lotuseater> look at CLPython
<Bike> simple-unsigned-doubleword-vector appears to be a simple (ub 64) vector. seems like the compiler and make-array are using different upgrades, kinda.
<lisp123> nij-: why don't you write your own calculator?
<lisp123> unless you want to do symbolic expressions (which may be a bit consuming), the rest is easy
<lisp123> Also SCIP has a good introduction of symbolic algebra within Scheme (concepts which you could apply over to CL)
<nij-> lisp123: Because it will take years to get scheme, hecke, (co)homology working by myself.
<lisp123> nij-: Fair enough
<lotuseater> so then you would know you really understand parts of it
<nij-> lotuseater: what do you mean?
<nij-> I'm still estimating.. if it's a good bet on translating sage
<nij-> or maybe i should just use sage
<lotuseater> hm
pve has quit [Ping timeout: 240 seconds]
psycomic has quit [Remote host closed the connection]
psycomic has joined #commonlisp
Cymew has quit [Ping timeout: 240 seconds]
<akater[m]> nij-: Kenzo is an example of a very specific calculator built in CL. I think it does not depend on other CASes. So maybe you don't want wrappers and better concentrate on your specific problem. It's easy to write some wrappers and then abandon the whole thing because the problem is very demanding.
CrashTestDummy has joined #commonlisp
CrashTestDummy3 has quit [Ping timeout: 268 seconds]
lambdatheultimat has joined #commonlisp
psycomic has quit [Ping timeout: 240 seconds]
Lord_of_Life has quit [Ping timeout: 252 seconds]
Lord_of_Life has joined #commonlisp
Fare has joined #commonlisp
tyson2 has joined #commonlisp
gethuen has joined #commonlisp
<nij-> akater[m]: Yeah, Kenzo is always encouraging in my mind.. I take your advice. For now, I'm just curious how a wrapper can be done right. I know I'm quite far from writing one..
<nij-> Looking back, Kenzo is also a program that made me determined to stick with CL :) How amazing.
<akater[m]> nij-: Note that according to press releases (or whatever the appropriate term is), Kenzo achieved more than others and it utilized CLOS substantially. Not surprising. Complex problems need advanced tools, and CL offers a lot. You can benefit from wrappers when you stumble upon a specific algorithm that is tedious to implement. But I highly doubt they make a good initial target… unless you have (or aim for) a NLNet grant, I guess.
<akater[m]> Computer algebra is one of my passions (but I don't work on anything related now, sadly). I was largely brought to Lisp thanks to it.
<nij-> yay <3 me too brought to lisp thanks to it
<nij-> For those who are interested in what kenzo is, here's a note to a great summary video: https://bpa.st/OHXQ
lisp123 has quit [Remote host closed the connection]
rain3 has quit [Ping timeout: 240 seconds]
lambdatheultimat has quit [Remote host closed the connection]
lambdatheultimat has joined #commonlisp
tyson2 has quit [Quit: ERC (IRC client for Emacs 27.2)]
yitzi has joined #commonlisp
h3ck3r9696 has joined #commonlisp
h3ck3r9696 has quit [Remote host closed the connection]
hendursaga has quit [Remote host closed the connection]
h3ck3r9696 has joined #commonlisp
lambdatheultimat has quit [Ping timeout: 258 seconds]
hendursaga has joined #commonlisp
cage has quit [Remote host closed the connection]
shka has quit [Ping timeout: 240 seconds]
h3ck3r9696 has quit [Remote host closed the connection]
h3ck3r9696 has joined #commonlisp
lisp123 has joined #commonlisp
Oladon has quit [Quit: Leaving.]
h3ck3r9696 has quit [Ping timeout: 240 seconds]
psycomic has joined #commonlisp
psycomic has quit [Remote host closed the connection]
psycomic has joined #commonlisp
lisp123 has quit [Ping timeout: 252 seconds]
lambdatheultimat has joined #commonlisp
Oladon has joined #commonlisp
lisp123 has joined #commonlisp
psycomic has quit [Ping timeout: 240 seconds]
akoana has joined #commonlisp
lambdatheultimat has quit [Remote host closed the connection]
lambdatheultimat has joined #commonlisp
aeth has quit [Ping timeout: 252 seconds]
aeth has joined #commonlisp
lambdatheultimat has quit [Ping timeout: 240 seconds]
ec has quit [Ping timeout: 244 seconds]
gaqwas has quit [Ping timeout: 240 seconds]
<jfb4> nij-: cool, interesting link
wheelsucker has joined #commonlisp
srhm has quit [Quit: Konversation terminated!]
kevingal has joined #commonlisp
Oladon has quit [Read error: Connection reset by peer]
<nij-> yw. I hope one day I can grasp their algorithms.
<nij-> They didn't use the "algorithms" mathematicians use btw.
<nij-> In fact, what mathematicians have are not algorithms.. and that's part of the reason why homotopy theory is hard.
<nij-> KENZO uses true algorithms, which are unrealistic for humans to perform either.
Oladon has joined #commonlisp
lisp123 has quit [Remote host closed the connection]
lisp123 has joined #commonlisp
cosimone has joined #commonlisp
doyougnu has quit [Remote host closed the connection]
lisp123 has quit [Ping timeout: 268 seconds]
tyson2 has joined #commonlisp
<hexology> re: "unnecessary consing", are lisp compilers generally not able to "flatten" operations like (reduce #'+ (mapcar (#'foo data)) into something more akin to (loop for x in data sum x)?
<hexology> are there any good references on lisp compiler optimizations that would be understandable by non-compiler people?
doyougnu has joined #commonlisp
<White_Flame> that would mean pipelining two looping constructs together
<White_Flame> mapcar is necessarily consing
<White_Flame> the semantics mean that all the calls to FOO occur before any calls to #'+
<phoe> (#'foo data)?
<Bike> yeah, deforestation is harder if side effects exist.
<White_Flame> and yeah, I presume you meant (mapcar #'foo data)
<White_Flame> if CL was a pure functional language, that optimization would be possible
<Bike> it coudl also be possible if a compiler kept track of enough info about side effects. i don't know if any do.
<phoe> I think SBCL might do?...
<moon-child> White_Flame: the compiler knows that + is effect-free, though
<Bike> not necessarily. the compiler is allowed to be stupid.
<moon-child> like, I would be very surprised if (progn (+ 2 2) other stuff) didn't DCE the (+ 2 2)
<moon-child> sbcl generates identical code for (lambda (x) x) and (lambda (x) (funcall #'+ 2 2) x)
<White_Flame> probably because it reduces it to (+ 2 2) first, and then can eliminate that
<moon-child> good point. It does the same for (reduce #'+ '(2 2)), though, and reduce is just a regular primitive
<moon-child> but it's weird; (reduce #'+ (list 2 2)) does generate code
<Bike> reduce is not usually used on constant data, so they probably didn't put in an optimization for it like that
<moon-child> ohh, wait, maybe with the const data it was inlined and folded?
<Bike> for (funcall #'+ 2 2) it would be yes.
<Bike> (funcall #'+ 2 2) -> (+ 2 2) -constantfold-> 4
<moon-child> (reduce #'+ '(2 2)) generates no code. (reduce #'+ (list 2 2)) generates a call to REDUCE
<moon-child> that's what I'm confused about
srhm has joined #commonlisp
<White_Flame> LIST is side-effectful by default?
<White_Flame> at least when it comes to changing the heap
<White_Flame> and identity of the term when the function is called again, vs literal data
<moon-child> i don't think changing the heap is generally considered an effect
<moon-child> and since it's guaranteed unique, there's nothing to compare it to
<moon-child> but yeah that's actually probably what it is
<White_Flame> (push *somewhere* (list 2 2)) certainly would leave a trail of testably EQ vs not EQ lsits
<White_Flame> so this gets into escape analysis
<moon-child> yea
<White_Flame> and before any of that is tackled, I'd use my magic wish for a peephole optimizer :-P
<moon-child> and I think you're right it's not tracking purity; it would have to know reduce is pure to know it doesn't escape any references to its parameter
lisp123 has joined #commonlisp
pillton has joined #commonlisp
pillton has quit [Client Quit]
selwyn has quit [Read error: Connection reset by peer]
pillton has joined #commonlisp
frgo has quit [Read error: Connection reset by peer]
CrashTestDummy2 has joined #commonlisp
lisp123 has quit [Ping timeout: 252 seconds]
frgo has joined #commonlisp
taiju has quit [Ping timeout: 240 seconds]
CrashTestDummy has quit [Ping timeout: 245 seconds]
taiju has joined #commonlisp
NeoCron has quit [Remote host closed the connection]
kevingal has quit [Remote host closed the connection]
yitzi has quit [Quit: Leaving]
<akater[m]> hexology: `mapcar` must return an actual list, according to the standard. `reduce`, according to the standard, is a function. It must evaluate the mapcar form. I thus don't see how deforestation could happen even if compiler could recognise the pattern. CLtL2 has Appendix about SERIES package that does deforestation, check it out. I'd love to have a better version of it. It's not trivial.
<moon-child> akater[m]: because aside from performance, there would be no observable difference between a 'naive' compilation of that code and a 'deforested' version
cosimone has quit [Ping timeout: 252 seconds]
aeth has quit [Ping timeout: 252 seconds]
aeth has joined #commonlisp
<hexology> that was a helpful discussion ^^
<hexology> thanks all
<akater[m]> moon-child: There would be if you, say, `(trace mapcar)`. If data is constant, it's fine to optimize. In general, however, rewriting the program behind the user's back adds to confusion. CLtL2 actually discusses a case with SERIES optimization which would be possible to perform automatically but SERIES doesn't do it. I think it was a good decision.
makomo has quit [Ping timeout: 240 seconds]
nij- has quit [Ping timeout: 258 seconds]
<hexology> this looks very interesting https://www.cliki.net/Series
<hexology> i've been meaning to at least browse cltl2 anyway, so this is good motivation to do so
<hexology> so purely functional programming languages are able to "deforest" or pipeline/flatten loops specifically because they know there are no side effects happening inside those loops
<hexology> that makes sense
<hexology> also i made a typo in my original but i think you all realized what i meant :P
<hexology> (reduce #'+ (mapcar #'foo data))
<hayley> You can manually deforest by (reduce #'+ data :key #'foo) at the least.
<hexology> and there's no "lazy" iteration construct in the standard library / spec right? you would have to use a 3rd party library like that series library above?
<hexology> or could you do better with plain MAP
<akater[m]> hexology: Yes, you'd need a non-standard library. series however is almost cltl2 and cltl2 is almost standard. :-] You may also fund this https://arxiv.org/abs/1612.06668 interesting.
<hexology> :) i don't have any qualms about a dependency like that, although i am definitely used to having lazy iteration built-in from python
<hexology> and thank you for the tip on the paper, the abstract seems interesting
<hexology> one of the great things in python for example is being able to treat an i/o stream like any a lazy iterator, and you can build arbitrary lazy iterators (really generators/coroutines), makes for surprisingly elegant data processing compared to what i think most people imagine when they think "python"
<akater[m]> hexology: Some people believe the approach of Series is flawed because it requires too much handcraft. They suggest using transducers instead. I happen to favor handcrafting but I'm an amateur; I just want code that is human-readable at every point of transformation (until it's reasonably possible) while transducers seem to follow the “trust the compiler to do the right thing to be as efficient” way which is more opaque.
akoana has quit [Quit: leaving]
Oladon has quit [Quit: Leaving.]
amb007 has quit [Read error: Connection reset by peer]
<akater[m]> hexology: “Elegant” is easy, ”elegant and efficient” is much harder. “Elegant, efficient and comprehensible at every level” is something that apparently nobody's interested in. At least, I couldn't find anyone else who explicitly cares about this.
amb007 has joined #commonlisp
<hexology> akater[m]: transducer?
<hexology> also - did you all just get a lot of join/leave spam from me?
<hexology> i see, that's part of Series https://www.cs.cmu.edu/Groups/AI/html/cltl/clm/node352.html
PinealGlandOptic has joined #commonlisp
<akater[m]> Transducers are popular in Language-That-Must-Not-Be-Named. Certain partially applied functions.