Search
Saturday, 7th of October 2017, 16:01:08 UTC
16:26:01
Shinmera
I'll leave that to someone who cares more about it than I do
16:36:50
sjl
is there something built-in or in a utils library somewhere that will mapcar, but only stop at the end of the longest list, filling in values for shorter lists with a default value?
16:37:21
sjl
e.g. I want (mapcar #'+ '(1 2 3) '(10 20))
16:37:41
sjl
(mapcar-longest #'+ 0 '(1 2 3) '(10 20))
16:42:05
sjl
alexandria and serapeum don't seem to have it
16:42:57
phoe_
sjl: time to write it and submit to some sorta library then
16:43:03
phoe_
I don't recall seeing such an util anywhere.
16:46:50
sjl
probably a better way to do it, but http://paste.stevelosh.com/59d904eca46df70008775a50
16:55:12
phoe_
hey, but we already have #'car and #'first!
16:55:38
sjl
I needed a name for a nil-patched car
17:02:08
Shinmera
Oh wait, that would be if it returns NIL, not "error on nil"
17:02:23
Shinmera
Then something like ensure-car
17:02:26
sjl
ah, alexandria's ensure-car
17:03:11
Shinmera
Generally I name things ensure- if it should error on unfound, and maybe- if it should NIL on unfound or error.
17:03:33
sjl
"If `thing` is a `cons`, its `car` is returned. Otherwise `thing` is returned."
17:04:00
sjl
I want "if thing is a cons, its car is returned, otherwise some default value is returned"
17:04:25
Shinmera
Not what I would expect ensure-car to do, tbqh
17:05:14
sjl
right, so I don't want that for this case
17:05:17
phoe_
sjl: uh, "some default value"
17:05:26
phoe_
(ensure-car thing default)
17:05:41
phoe_
if thing is a cons, its car is returned, otherwise, default is returned
17:05:46
phoe_
so you can do (nth n list)
17:05:51
phoe_
and either you get a valid cons and return its car
17:05:59
phoe_
or you get a NIL when you run out of conses and you return default
17:06:18
phoe_
(ensure-car (nth n list) default)
17:06:26
sjl
phoe_: https://gitlab.common-lisp.net/alexandria/alexandria/blob/master/lists.lisp#L246-250
17:06:31
sjl
that's not how ensure-car works
17:06:57
phoe_
(or (ensure-car (nth n list)) default)
17:07:14
phoe_
it'll return NIL in case of proper lists, at which point you can default.
17:07:15
sjl
phoe_: what if the car of the list is nil?
17:07:41
phoe_
it stops being trivial now.
17:07:54
sjl
it just doesn't already exist
17:08:40
phoe_
(if (nthcdr n list) (nth n list) default)
17:09:20
phoe_
(let ((cons (nthcdr n list))) (if cons (car cons) default))
17:09:45
phoe_
still, it's linear, so if you iterate, it'll be quadratic
17:11:18
sjl
the version I pasted should be O(number of lists * length of longest list), right?
17:11:44
phoe_
http://paste.stevelosh.com/59d904eca46df70008775a50 this, right?
17:11:49
Posterdati
beach: what is CST-to-AST?
17:12:17
sjl
it iterates until all the lists are finish, which takes length-of-longest-list times
17:12:41
phoe_
yes, for N lists with max length of M you iterate M*N times
17:12:48
sjl
and at each step, it iterates over the collection of lists 3 times (every, advance, mapcar)
17:12:49
phoe_
so basically once for each list element
17:13:16
sjl
I could potentially combine the advance/finish check to get it down to 2N
17:13:20
sjl
but I don't care enough right now
17:13:28
phoe_
so it's O(n) where n is number of conses
17:14:25
sjl
M*N does not equal the number of conses...
17:14:37
phoe_
M lists, each with N conses
17:14:46
sjl
sure, if they all have the same number
17:14:58
phoe_
yes - less, if there's less
17:15:02
sjl
but if I do (mapcar-long ... (1 2 3 ... 1000))
17:15:07
sjl
and then add another list into it
17:15:12
sjl
(mapcar-long ... (1 2 3 ... 1000) ())
17:15:25
sjl
it doubles the number of operations, right?
17:15:34
sjl
but only adds a single cons to the total
17:15:37
phoe_
you are right - I was giving an upper bound there, not trying to be precise and correct :)
17:15:46
phoe_
2000 operations, correct.
17:16:20
sjl
yeah, so I could potentially improve it, but this is clear and works well enough for what I need right now
17:27:55
flip214
the list of lists could be trimmed, and then the end-check becomes (null list-of-lists)
17:28:12
sjl
flip214: but then how do you know where the placeholders go in the arglist to apply?
17:28:26
flip214
oh, so much flexibility is wanted?
17:28:45
flip214
I thought that some function should just get "a list of arguments", never mind which original list they're from
17:28:52
sjl
I mean, (mapcar-long ... '(1 2 3) () '(10 20)) should work properly
17:29:01
sjl
yes, I want the order of args preserved...
17:30:08
flip214
but if the arguments don't have any special role within the called function (so NILs can be removed), you could reduce the number of lists during traversal.
17:30:47
sjl
for a case like + that would work, but other cases it might not
17:55:26
sjl
also if anyone knows of a way to iterate over a list L plus one extra value that's cleaner than https://github.com/sjl/euler/blob/master/src/problems.lisp#L1896-L1898 please let me know
17:57:31
pjb
sjl: (loop for e in (cons 'one-more list) do (something e))
17:58:28
pjb
sjl: (loop for previous in (cons nil list) for current in list do (something-with previous current))
18:33:58
sjl
pjb: that adds 'one-more to the beginning of the iteration, I want it at the end
18:34:40
sjl
e.g. (loop :for x :in '(1 2 3) ...plus 4 somehow... (collect x)) => (1 2 3 4)
18:34:53
sjl
without reversing the list or appending or something equally wasteful
18:41:33
pjb
sjl: (loop for e in list do (something e) finally (something 'one-more))
18:50:43
sjl
that works for side effects, but doesn't work for collecting/etc. I'll probably just write an iterate driver for it
18:51:36
sjl
that steps them in parallel?
18:54:42
|3b|
(loop for (x . m) on '(1 2 3) collect x unless m collect 4) is a slightly ugly way
19:02:20
jackdaniel
sjl: (alexandria:mappend 'fun (list 1 2 3) (list 4))
19:03:05
sjl
jackdaniel: which of my questions is that for?
19:03:39
jackdaniel
about iterating over a list plus one extra value
19:04:04
sjl
I'm ... not sure how that does that?
19:05:09
sjl
that requires the function to return a list, which gets appended
19:06:07
sjl
http://paste.stevelosh.com/59d925984221e30008a616c9
19:06:15
sjl
there's an iterate driver that does what I was looking for
19:06:23
sjl
(iterate (for x :in-list '(1 2 3) :initially 0 :finally 4) (collect (cons x (square x))))
19:06:28
sjl
((0 . 0) (1 . 1) (2 . 4) (3 . 9) (4 . 16))
19:06:47
jackdaniel
yes, I have confused things, mb
19:06:48
sjl
just need to make it not *require* both args now...
19:10:06
sjl
gross http://paste.stevelosh.com/59d926824221e30008a616ca
19:11:35
sjl
http://paste.stevelosh.com/59d926c94221e30008a616cb?lisp macroexpansions
19:23:47
phoe_
oh wait, this isn't your average macroexpand
19:26:27
sjl
yeah this is an iterate driver's macroexpansion
19:26:38
sjl
so it gets spliced into an (iterate ...) form
19:29:28
sjl
if final-value should be if final-value?
19:29:37
sjl
otherwise a final-value of nil breaks things
19:47:32
sjl
fixed version https://github.com/sjl/euler/blob/3eec0faddae1871bcda358828b463a14178a4dbd/src/utils.lisp#L70-L120
23:26:31
emaczen
Isn't (and #+ccl #+darwin) an example of a correct compound read time conditional?
23:27:25
emaczen
is it #+(and ccl darwin) then?
23:37:34
pierpa
curiously, in the hyperspec there's not even a single example of a compound conditional (that I could find :)
23:40:23
pierpa
ah, no, here they are http://www.lispworks.com/documentation/lw70/CLHS/Body/24_abaa.htm
Sunday, 8th of October 2017, 4:01:08 UTC