freenode/lisp - IRC Chatlog
Search
5:19:01
jasom
my ql2nix script decided that babel depended on a system named ":trivial-features" which we don't know how to build and so all systems that directly or indirectly depend on babel were not built; cffi depends on babel...
5:20:37
jasom
But instead of switching away from regexes, I'm just goign to make the regex more complicated: "Component ([^: ]*::?([^ ]*)|\"([^\"]+)\"|([^ ]+)) not found"
5:23:36
jasom
now I just need to wait for something to depend on |foo| and I can make it even *more* complicated
5:46:59
jasom
and dynamic programming has nothing to do with lisp style typing. Dynamic programming is a style of algorithm that basically boils down to recursion + memoization.
5:47:21
BW^-
jasom: a dynamic graph is a graph that changes edge content over time i.e. edges may be deleted or inserted
5:49:09
jasom
BW^-: this sounds like an incrementalcycle-detector for a reference-counted system. You can probably find algorithms to do this in the garbage collection literature
5:49:53
jasom
BW^-: and you *can't* do it for arbitrary concurrent mutation of the graph unless you have some sort of agrement between the mutator and the cycle-detector.
5:54:23
jasom
BW^-: consider A->B->C and the Mutator changes the graph to C->B->A. You could easily have a false-positive if your cycle-detector was considering B at the time. *however* if you don't allow graph nodes to stay alive while disconnected, then there is no way to perform that transformation without generating a cycle, and you don't have a false-positive, because there was a cycle there at some point in time.
5:57:40
jasom
alternatively if you can exclude the mutator from running when you have found a potential cycle, you can check if the potential cycle is truly a cycle. But if you can prevent the mutator from running, you could just run your entire graph traversal as well, and then the "dynamic" requirement is non-sensical.
6:01:13
BW^-
jasom: what cycle detection algorithms are you aware of being used in reference-counted systems?
6:01:16
jasom
BW^-: so what are the requirements; could the cycle detector exclude the mutator and run a full-pass? Because then it doesn't matter that the graph is dynamic, because it will be static for the full run of your algorithm
6:10:14
jasom
That partitions verticies into components; Any component with multiple verticies is a cycle, and any component with just one vertex is not part of a cycle.
7:07:37
flip214
can I tell QL to compile some systems (with all their dependencies), but not load them?
7:07:58
flip214
guess I can't, because compiling them might require some dependencies to be available...
7:09:07
jasom
flip214: on sbcl, if you don't have any threads running, you can fork a process, load them all and then exit.
7:14:45
jasom
even if it doesn't do what you want, it would be a good place to start to do what you're doing
7:24:26
flip214
hmmm, cliki.net says that my account doesn't exist.... was there a cleanup some time ago?
8:02:29
Shinmera
The primary problem with c-l.net is that like 99% of the pages hosted on it point to links that are long gone.
8:03:36
antoszka
There should be an automatic cleanup procedure. A bot that checks the links and removes them or marks them *dead*.
8:04:48
Shinmera
Either way the problem is that maintainers don't really care to begin with, or there is no real maintainer, so the links stay dead.
8:04:56
flip214
that might be the best solution, because the automatic fixing can be made more intelligent over time
8:07:13
flip214
then I could try to rig something up. (and I had to resist HARD to write "... to make cliki great again" ;)
8:08:39
Shinmera
Sure, but ease of collaboration and integration can go a long way to gaining traction. Cliki feels sluggish and dead.
8:08:48
flip214
any alexandria maintainers here by chance? I asked for permissions to gitlab about a month ago, so I can fix up some of the doc strings... and no answer yet.
8:09:29
flip214
the github interface to edit _any_ file (which just clones the repo and does a PR in the background!) is very slick.
8:11:26
Shinmera
There is definitely value in the idea of a central hub of information and advice for CL.
8:15:40
Shinmera
Anyway, the software and the "cliki idea" are only marginally tied together, so I agree with jackdaniel to a point.
8:19:38
flip214
but if people would hear that the CL wiki would run on PHP, wouldn't that be awful?? ;)
11:49:12
Shinmera
flip214: That's the point. In graph theory, a tree has no "root". Any node in the tree can potentially be considered its root, but that consideration is purely arbitrary.
13:19:46
Younder
edgar-rft, your implementaion conses like crazy. It will be slow for large datasets
13:22:10
Bike
though maybe i don't understand it anyway. is args supposed to be a list of numbers or a list of lists?
13:27:17
Younder
In compiler theory we use bitsets. Because they are a more compact representation of bool. Particularly in data flow analysis.
13:29:02
oleo
When the function receives its arguments via &rest, it is permissible (but not required) for the implementation to bind the rest parameter to an object that shares structure with the last argument to apply. Because a function can neither detect whether it was called via apply nor whether (if so) the last argument to apply was a constant, conforming programs must neither rely on the list structure of a rest list to be freshly consed, nor modify that list
13:48:59
aeth
anyway, this is the final form: (defun everycons (&rest args) (reduce #'cons args :initial-value nil :from-end t))
14:16:54
R0B_ROD
Everytime I try to build something or pull a library it says quicklips isnt installed
14:26:00
pjb
edgar-rft: so there are ones who are more ones than others… (everyone '(1 1.0 2/2 1.0d0)) #| --> nil |#
14:40:26
edgar-rft
pjb: float 1.0 could be an arbitrary accumualtion of floating-point rounding errors, so you can't surely say if float 1.0 is *really* fixnum 1.
14:41:48
edgar-rft
phoe, implement this: <http://68.media.tumblr.com/tumblr_kud6opJD1s1qa31pso1_r2_1280.gif>
14:42:11
Younder
Type systems are notoriously hard to get correct, and embarrassingly easy to get wrong.
15:06:21
zulu_inuoe
I know people complain about LOOP, and show off their loop-fu, but I don't think I've ever even came close to writing a DO that works, even a simple list iteration
15:07:57
marvin2
i think most people who dislike loop don't use do but dolist, filter, map, reduce, etc
15:14:27
marvin2
step keeps getting evaluated (and assigned to var) while test-form evalutes to true. when test-form evaluates ot false, result-form is returned
15:16:40
zulu_inuoe
I think the main thing that threw me off (and something wrong in your example) is that test-form needs to be wrapped in parens, and is followed by multiple return values
15:26:25
phoe
often the only thing that you need in loops are updating the variables and checking the test
16:00:20
aeth
I use do. It's not that hard once you learn it. It's just a let that updates itself each step. do* is just a let* that updates itself each step.
16:02:50
aeth
You can even use it basically like a let except with a (t ...) around the let body: (do ((foo 42) (bar 37)) (t (values foo bar)))
16:05:07
aeth
A properly-written do often needs no body, if it is functional. The form above is one useless example. The body is mostly useful for side effects, when setf makes the iteration more readable.
16:06:38
aeth
Just modifying my example to have it run 3 times: (do ((foo 42 (- foo 2)) (bar 37 (1+ bar))) ((= bar 40) (values foo bar)))
16:07:32
aeth
This will increment bar to 40 (i.e. 3 times) so foo will be 42-6 (i.e. 36). The final return value will be (values 36 40)
16:07:37
pjb
zulu_inuoe: consider (loop :while <test> :do <body>) vs. (while <test> <body>) : it may be good to define a set of simple iteration macros. while, until, repeat, for, etc…
16:09:56
pjb
(also, writing those simple looping macros, expanding to do/do* is a good exercise to understand how things work…)
16:10:59
aeth
Right, in CL almost all iteration (in most implementations) will ultimately become let + tagbody + go, like do expands to in most implementations. Expanding it to do is just a time saver with a more human readable intermediate step.
16:11:28
aeth
I'd much rather deal with do than deal with tagbody, although I'll probably read both forms (expanding to do, and expanding that do to tagbody) just to be sure.
16:12:39
pjb
eg. writing a loop with tagbody by starting (tagbody (go :test) :loop …) to optimize out one jump per iteration and stuff like that :-)
16:13:27
aeth
And all do forms have an implicit tagbody (although your editor probably only supports gotos and labels properly in tagbody, not do-foo and prog) so they really are intended to be useful as an intermediate form.
16:14:00
aeth
You never have to drop down to tagbody if you're using do, because you can put some confusing goto in do itself (but don't do this unless you're writing a macro that targets do, please)
16:15:01
aeth
tagbody is evidence that CL is still, in 2017, the only serious Lisp for general purpose high performance uses.
16:15:23
pjb
(do (…) (…) :retry … (cond ((donep) (go :continue)) ((failedp) (go :retry))) … :continue)
16:42:35
jasom
zulu_inuoe: https://github.com/sbcl/sbcl/commit/585853373a4b43aba7ac740f1fe50bd622f673eb
16:54:31
jasom
Fare: hmm did you get my memo asking about CL conditions and using them for asynchronous aborts?
16:56:38
jasom
I'm not sure how what you're doing in Gerbil is fundamentally different from restarts that escape the critical section and resignal, allowing higher levels of abstractions to do the same.
16:59:14
jasom
I read a rant about asynchronous aborts, not sure if I read sufficiently far into the thread
17:00:37
Fare
I'm sure you could do it with restarts, as long as lower-level failures were handled, e.g. failures in the middle of memory allocation, in the middle of having allocating a resource and binding it to a variable that the user will watch with his own finalizers/restart/whatever
17:01:57
Fare
what if the async abort happens after the open, before the binding to x, and before any unwind-protect inside that let?
17:03:50
Fare
java has try-with-resources pattern... but it would have to be extended to handle atomic return from the function that provides the resource
17:04:23
jasom
so each binding construct would have to ensure that code in the bindings either completely finishes or cleans-up after itself
17:04:40
phoe
how can that restart know when the async abort happened? can it analyze the stack or something?
17:04:58
Fare
I wonder how Rust does it. But then again, I don't think even Rust has async abort. I hear the Swift guys are interested in it... good luck to them, I'm curious what they come up with.
17:05:08
phoe
like, before/during/after the open, before/after binding to x, before/during the unwind-protect...
17:06:12
jasom
Fare: which is why the condition needs to be resignaled once it's safe at the current level of abstraction
17:06:13
phoe
jasom: yes, it would be required for them to provide much more fine-grained information to the condition system
17:06:27
Fare
to kill a thread without killing the larger program, you need to sync it to an atomic transaction *at the highest level* that any other thread cares for.
17:07:16
jasom
phoe: not really; the dumbest way would be to not allow any interruptions until the binding happens, once the form has begun to be evaluated; blocking calls should defer this until no more syscalls are required.
17:07:22
Fare
jasom: exactly. So you must first get everything right at the low-level, then have a mechanism to let the user percolate the information up the abstraction tower
17:07:42
jasom
Fare: conditions are sufficient for the latter, but work would need to be done for the former in CL.
17:08:20
phoe
jasom: so you enable interrupts inside (open), disable them once you get the value, bind the value to x, enable interrupts again?
17:08:35
jasom
And it sounds like Gambit already does a lot at the low level, compared to the typical CL implementation
17:09:38
Fare
phoe: remember, there are now several levels of interruption, one for each level of abstraction.
17:10:01
Fare
phoe: and I don't know how to keep higher-order functions modular in presence of that.
17:10:11
jasom
phoe: at the low level, you want two things to happen with (let ((x (open))) ...) 1: either x is bound to the open file, or the file is not open. 2: We don't disable interrupts for the entire open call, which could take an unbounded amount of time.
17:12:29
jasom
so one way would be the following: 1) disable interrupts 2) have open establish an unwind-protect 3) inside that unwind-protect enable interrupts 4) disable interrupts just before leaving the unwind protect 5) establish the binding 6) reenable interrupts
17:12:56
jasom
however, this still leaves the issue of (let ((x (open))) (unwind-protect FOO (close x))) as having an unsafe region
17:13:48
jasom
wheras (let (x) (uwind-protect (progn (setf x (open)) ...) (when x (close x))) would be safe
17:14:25
jasom
but it's only safe if similar work is done to setf to make sure that it either completes, or the side-effects of the value form are not visible.
17:15:31
jasom
what if "open" is opening a device, and you must send shutdown codes to the device to ensure that it is back in a sane state; then just closing the file when interruptied is not okay...
17:16:29
jasom
phoe: right, but now open must be slightly different; you need to finish the open any time that the underlying syscall succeeds.