libera/#commonlisp - IRC Chatlog
Search
0:09:12
doomduck
being new to this, what do people use for the regular functional list/sequence manipulation? I know there's mapcar, but I'm imagining things like stuff in LINQ with all the where/first/flat-map/etc. ... I mean I know how to write these myself, it's more like "is there a nice/popular library?" ... not exactly sure how to search for quicklisp stuff
0:10:19
aeth
Not always functional but e.g. (loop :for i :from 0 :below 20 :collect i) or (loop :for i :from 0 :below 20 :sum i)
0:14:23
fe[nl]ix
aeth: I compiled that on my laptop, so not Ubuntu 18.04 but I want to test the build
0:15:06
fe[nl]ix
aeth: src/runtime/sbcl.extras is statically linked to libfixposix and openssl-1.1.1l with openSUSE patches
0:17:21
doomduck
aeth: is it recommended to learn loop instead of composable tools? it feels very very adhoc, but maybe that's just me being a noob, but not sure if i'm a fan of a big magic macro
0:18:26
verisimilitude
It's always preferable to use a standard function than some library, at least for me.
0:18:56
verisimilitude
It's not fun to audit some code and see a single usage of some library where LOOP would've sufficed.
0:19:45
fe[nl]ix
doomduck: learn loop because it's in the standard. its deficiencies won't matter until you want to write and maintain large amounts of code
0:20:54
aeth
doomduck: The big messy monoliths of LOOP and FORMAT don't have to be composable, but they can be used that way.
0:21:19
aeth
FORMAT can take in an arbitrary stream, while LOOP can be used as I just used it to return values
0:21:38
aeth
So you can mix-and-match them with other things even though some people probably (ab)use them as an all-in-one solution
0:22:39
aeth
for a toy example that probably isn't useful: (defun mapeven (function list) (loop :for item :in list :for evenp := t :then (not evenp) :when evenp :collect (funcall function item)))
0:23:27
aeth
if you're writing composable functions, you're probably defining them from fairly simple LOOPs
0:31:56
doomduck
speaking of this, how do I do something like (and ,@(list t t nil)) but not inside a macro? like I have something that gives me a list of truthy things, and I just want to `and` them, and I can't (apply and things) because it's not a function
0:32:53
aeth
(defun mapfizzbuzz (function list) (loop :for item :in list :for i :from 1 :for fizz := (zerop (mod i 3)) :for buzz := (zerop (mod i 5)) :for result := (funcall function item) :when fizz :collect result :into fizzes :when buzz :collect result :into buzzes :unless (or fizz buzz) :collect result :into rest :finally (return (values fizzes buzzes rest))))
0:36:24
doomduck
can I somehow do that in a loop so I don't have to do (every p (loop for x in xs collect (thing x)))?
0:36:37
doomduck
I guess that's kinda a silly question considering I literally just asked how to get a "more composable loop" lol
0:38:10
aeth
(mapfizzbuzz (lambda (x) (when (zerop (mod x 3)) (format t "Fizz")) (when (zerop (mod x 5)) (format t "Buzz")) (unless (or (zerop (mod x 3)) (zerop (mod x 5))) (format t "~D" x)) (write-char #\Space) x) (loop :for i :from 1 :to 15 :collect i))
0:41:06
doomduck
verisimilitude: hmm I'm not sure if that does the same thing, this (loop for x in '(1 2 3 4 5) thereis (progn (print x) (evenp x))) just prints 1 2 and returns T, evne tho clearly not evenp for every element
0:43:43
doomduck
except in my case the list is generated by a loop, hence my question how to include that in the loop to avoid nesting
0:48:20
doomduck
I guess the very nice things a bout using `always` in place of `every` is avoiding the ugly LAMBDA
0:54:18
_death
(collect (mapping ((x (scan-range :from 1 :upto 15)) (fb (mask (scan-range :from 14 :by 15))) (f (mask (scan-range :from 2 :by 3))) (b (mask (scan-range :from 4 :by 5)))) (cond (fb "Fizzbuzz") (f "Fizz") (b "Buzz") (t x))))
1:06:00
_death
maybe more series-y would be (collect (mapping ((x (scan-range :from 1 :upto 15)) (b (expand (mask (scan-range :from 4 :by 5)) (series "Buzz"))) (f (expand (mask (scan-range :from 2 :by 3)) (series "Fizz")))) (if (and f b) (concatenate 'string f b) (or f b x))))
5:46:39
hayley
I missed that conversation, but it seems reasonable. The HyperSpec suggests no type checking is done in that situation.
10:38:19
phantomics
What's the difference under the hood between doing C-c C-k to compile a file and doing C-x C-e on an expression in Emacs with Slime? When doing the former, the compiler will print all the available style warnings. When doing the latter, it will print much less, usually only the serious warnings.
10:39:13
phantomics
I also find that C-x C-e is much faster to compile in certain cases than C-c C-k, even if I'm comparing compiling a file with just the one expression in it to doing a C-x C-e on that expression
10:41:01
_death
C-x C-e simple sends the string representation of the form to swank, which reads and evaluates it
10:41:55
phoe
but I think the difference is that C-c C-c creates a new file under the hood, copypastes the single form into it, compile-and-loads it, C-c C-k does that with the whole file, and C-x C-e, what _death said
10:43:43
_death
I tend to use C-M-x, which is like C-x C-e but has a special case for defvar.. I almost never use C-c C-k, and sometimes use C-c C-l which just loads the file
10:45:45
phantomics
Any idea why there would be a massive difference in the time taken to compile via sending a string to swank with C-x C-e and doing C-c C-c? A difference of 19 sec vs. 3 sec
10:48:44
phantomics
Although when I've made changes to stuff in the material to be compiled, I've never not had those changes manifest when doing C-x C-e
10:51:05
phantomics
So interprets rather than compiling? I'm wondering doing a full compilation compiles many dependencies of the compiled code, thus the long time taken
10:51:53
lisp123
usually there are phantomics: fasl files already created I thought, so the dependencies shouldn't recompile?
10:52:38
splittist
Any suggestions for interesting codebases using postmodern I could read to learn from?
10:53:01
_death
phantomics: you can profile compilation the same way you profile ordinary code (say with sb-sprof)
10:53:40
splittist
phantomics: the sbcl manual has a chapter on it: http://www.sbcl.org/manual/index.html#Profiling
11:06:04
phantomics
Thanks _death and splittist, when I do (sb-sprof:with-profiling (:loop nil :show-progress t :max-samples 100 :report :flat) ...) it returns no samples and prints the message "No sampling progress; run too short, sampling frequency too low, inappropriate set of sampled threads, or possibly a profiler bug." This is even when the actual elapsed time is around 19sec
11:07:13
phantomics
Maybe because the code generated by the compilation includes an (eval ...) form?
11:10:30
phantomics
It contains (april-load (with (:space numeric-lib-space)) (asdf:system-relative-pathname :april-lib.dfns.numeric "numeric.apl"))
11:11:32
_death
it should contain the code to compile the form that takes time to compile... like a call to compile-file or compile
11:19:22
phantomics
Interestingly, the actual April compilation, as much as I can measure, is relatively fast even after deleting the relevant .fasl file. Compiling that numeric.apl file without running the compiled code takes only 606 cycles according to (time), there must be something wrong with that but the time I perceive is still under a second
11:20:34
phantomics
When I just return the compiled code, no (eval) happens either, so I don't know why it measures so little activity, I know compiling all that APL code takes more than 606 cycles
11:42:30
phantomics
max-samples of 100000 still returns 0 samples, whether I just compile or compile and load
11:44:31
phantomics
Even up to 10 mil samples returns nothing, it doesn't take that long to compile, I perceive a time of about 19s to compile and load it but it's not reflected, really strange