freenode/#lisp - IRC Chatlog
Search
15:12:12
emaczen
just map but it is a defmethod so I can't have different datastructures be mappable and for this instance spawn a bunch of threads
15:37:24
Xof
I couldn't find one. I wonder whether it was a figment of my imagination. I *did* find a half-baked Canvas backend
15:40:07
Xof
sorry! (Also, the firmware for the network card on that machine appears not to be y2k18 compliant
15:43:57
joe42
Hello. Is there a 'preferred' way to use fastcgi & common lisp? Or basically 'which ever tool suits you'?
16:09:42
Xach
joe42: i'm not sure there are a lot of options regarding fastcgi. i do not think it is often used for lisp web apps. it is more typical to use a reverse proxy to a lisp web server.
16:12:50
p_l
cheapest option if you really don't have anything else - /etc/inittab (better use runit there, though)
16:15:03
p_l
joe42: runit should work on OpenBSD, it's quite damn portable (except for writing to process name, but that's not critical feature)
16:24:25
AeroNotix
joe42: I'd recommend systemd, it solves 99% of issues but since you're on BSD and I'm not familiar at all with BSD. I don't know what to suggest.
16:25:07
AeroNotix
Seems it uses the typical https://www.freebsd.org/doc/en_US.ISO8859-1/articles/rc-scripting/index.html style though
16:27:11
AeroNotix
not entirely sure what to suggest since, like I said, not familiar at all with bsd but if runit is available then that route is probably best.
16:28:10
AeroNotix
joe42: but if you're running a web server in CL then perhaps nginx + proxy_pass and use the typical start up scripts you've probably already got for nginx
16:29:00
AeroNotix
and just configure nginx to proxy to the CL application, and write a runit script to start the CL application before nginx.
16:30:12
joe42
yeah, that part seemed pretty strait forward, and I will be testing a web server written using ningle. Thanks
16:35:11
AeroNotix
phoe: regarding the REPL. You can embed a slime listener into your application rather than needing to have access to the terminal it ran in. That's how I've always deployed CL applications. A slime repl on a non-exposed port.
16:38:02
trittweiler
AeroNotix, it should be possible (perhaps it is even done by default), that the swank socket listens on localhost only
16:39:43
trittweiler
yeah, but it means you need a firewall rule and so it's one more component that could fail, murphy's law etc.
16:40:21
AeroNotix
take out the words "non-exposed port" and replace with "non-exposed listener" then
16:40:53
AeroNotix
The way I used to have to deploy it was listening on all interfaces and use AWS firewall rules to give me access via a bounce box
16:41:36
AeroNotix
previous work didn't allow access directly to all machines, only certain ones. We'd have to get to the SLIME port via another machine
18:13:10
phoe
Read the comment at https://github.com/quicklisp/quicklisp-projects/issues/1273 though
19:42:53
AeroNotix
and Xach mentions here that his library is "not good" and "only works on SBCL": https://github.com/quicklisp/quicklisp-projects/issues/1273#issuecomment-286510639
19:44:15
Shinmera
You can have two systems with the same name in separate dists, in which case it will pick the one from the dist with a higher priority number.
19:46:00
AeroNotix
Shinmera: since you're so prolific, don't you have a library which implements: https://www.xach.com/lisp/timer/doc.html (and may already be in quicklisp?)
19:47:57
Shinmera
I have a tiny task processor that could be used for something like this I suppose, but nothing that directly fits what you want.
19:50:06
AeroNotix
no worries, reason I ask is that yeah, the one that cl-muprocs depends on is SBCL only.
19:50:25
AeroNotix
which is weird af because the cl-muprocs library seems to have gone to some lengths to predicate certain forms on different implementations
19:50:28
Shinmera
Spawning a thread that calls sleep in a loop and compares time differences isn't a huge effort.
19:50:53
Shinmera
I probably would have written it in the time we've spent discussing libraries here :)
20:55:23
earl-ducaine
CL macrologists! I'm trying to write a macro that transforms a lambda list into an alternate lambda list and function body wrapper, within the context of a macro. E.g. https://gist.github.com/earl-ducaine/f510eb0091d04e2d0131cffe080f5d28
20:56:28
earl-ducaine
I'm having that familiar feeling of having the macro 90% written, then 50%, then wondering whether what I'm attempting is possible at all. :)
21:01:37
aeth
earl-ducaine: Unless I'm reading your requirements wrong, destructuring-bind does everything you want for free (only downside is that it *might* be slower)
21:03:45
aeth
The only difference is that that would require the list to be of length 3 and using nth does not (your approach doesn't care about the tail). You can implement not caring about the tail in destructuring-bind with (medium pathname options &rest rest) (declare (ignore rest))
21:04:10
earl-ducaine
Is there any way of doing that in the context of a macro? The reason for my need is that I'm trying to convert some old flavors code, and I'd like to rewrite the flavor defmethods into CLOS defmethods
21:05:41
aeth
I think it would look something like this: `(defun ,my-function (&rest rest) (destructuring-bind ,lambda-list rest (list ,@lambda-list))
21:06:14
aeth
The only problem is that destructuring-bind's lambda list is very similar to a macro's lambda list, so it would permit nested things like (foo (bar baz))
21:07:28
aeth
and, yes, you'd want to use gensym instead of rest, even though it doesn't really matter because there's no ,@body and even if you had an internal rest in your lambda list, it would use the inner rest from the destructuring-bind, not the outer rest
21:08:44
aeth
(let ((rest (gensym))) `(defun ,my-function (&rest ,rest) (destructuring-bind ,lambda-list ,rest (list ,@lambda-list)))
21:10:31
aeth
The only thing you might want to do differently from phoe's version is (let ((rest (gensym "REST"))) ...) instead of (let ((gensym (gensym))) ...)
21:11:57
earl-ducaine
Truly awesome. Thanks again! Looking at it I can't even remember why I thought it was so difficult. :)
21:13:31
aeth
The one catch about destructuring-bind is that sometimes it's inconvenient, especially when combined with e.g. mapcar or defun, because you often want the function to have one, temporary argument.
21:13:48
aeth
For lambdas (e.g. use in mapcar) I wrote this: (defmacro destructuring-lambda (lambda-list &body body) (let ((expression (gensym))) `(lambda (,expression) (destructuring-bind ,lambda-list ,expression ,@body))))
21:14:34
aeth
Then I can (mapcar (destructuring-lambda (foo bar baz) `((,baz ,bar) ,foo))) some-part-of-a-macro)
21:15:04
aeth
It saves two lines and a temporary variable and is very similar to phoe's solution for defun
21:15:50
aeth
If you don't write macros to save yourself two lines (multiplied by dozens of times in a large program), you might as well be coding in Java. :-)
21:18:32
aeth
I personally find that most macros have some structure to their s-expressions, and you either want to transform that to another structure (e.g. maybe a series of function calls) or you want to create a data structure of standard-objects/structure-objects/arrays/etc. at compile time. So destructuring-bind is incredibly useful imo.
21:21:08
aeth
stylewarning: Imo any pattern that repeats itself constantly (like a temporary variable for destructuring-bind in a one-argument lambda) is a place where bugs can easily happen.
21:23:14
earl-ducaine
The paragraph I was remembering was in cltl, related to parse-macro, a suggested function that didn't make it into the standard. https://www.cs.cmu.edu/Groups/AI/html/cltl/clm/node102.html
21:23:40
earl-ducaine
In particular: However, parse-macro is worth having anyway, since any program-analyzing program is going to need to define it, and the implementation isn't completely trivial even with destructuring-bind to build upon.
21:25:31
aeth
earl-ducaine: It looks like the function phoe wrote *is* parse-macro, but without the environment stuff?
21:27:11
aeth
I'm surprised there isn't one for lambda, like the one I wrote. Happens all the time in mapcar.
21:36:42
Bike
parse-macro is more complicated because it handles &whole differently from destructuring-bind
21:58:48
Duns_Scrotus
why does funcall look in the function namespace but apply looks in the value namespace
23:40:24
Xach
Shinmera: http://report.quicklisp.org/2018-08-29/failure-report/staple.html#staple-server has my log
2:41:21
lyf[kde]
Using CSP, I can wrap the continuations, to implement event loops and to optimize tail calls, but CSP is handly only when it comes to tail calls.