freenode/#lisp - IRC Chatlog
Search
19:29:30
Xach
The rest of the advice seems similarly off-kilter. I would not use that site for much.
19:44:17
pjb
phoe: you can call LISTEN before READ-SEQUENCE to avoid a hang. Then it will only read the bytes available (check the result).
19:46:50
phoe
LISTEN will only check if there is any data; if there are only five bytes on the socket stream but you read into a six-byte sequence, there'll be a hang.
19:55:13
didi
*Blegh*. I keep forgetting to set *print-circle* for at least half an hour of endless looping.
20:02:26
Josh_2
So you have to have a listening server on a seperate thread in sly otherwise it'll just sit and wait and you won't be able to send the data
20:03:39
pjb
phoe: yes, but if you use (when (listen (usocket:socket-stream accept)) (read-sequence output (usocket:socket-stream accept))), it works.
20:03:51
pjb
phoe: the problem you have is that you're calling read-sequence before the packet is back.
20:06:11
Josh_2
phoe: https://plaster.tymoon.eu/view/1186#1186 this blocks utnil I send data to the socket
20:06:16
pjb
phoe: it returns #(0 0 0 0 0), because of course, you have to loop reading until you have what you need.
20:08:11
Josh_2
Sure, but whats the point when you map '(vector (unsigned-byte 8) 'char-code "asdf") ?
20:08:42
Josh_2
Arent' you just doing exactly what :element-type 'character would have done anyway or no?
20:10:36
pjb
Most of the time you want (unsigned-byte 8), since most of the protocols are defined on streams of octets.
20:11:34
pjb
Josh_2: notice that the map will fail on characters that are not encoded in one octet by char-code.
20:11:34
dxtr
I *still* don't understand why anyone in their right mind would call listen on an already connected (i.e. accepted) socket
20:12:35
dxtr
"Creates and returns a passive ("server") socket associated with host and port. The object returned is of subtype stream-server-usocket."
20:16:43
makomo
MichaelRaskin: a question regarding agnostic-lizard if you're around. WITH-OVERLOAD example 5: https://plaster.tymoon.eu/view/1187#1187
20:17:02
dxtr
Xach: I wasn't even thinking about listen(2). I was digging through usocket to see if I had missed some feature
20:17:46
makomo
MichaelRaskin: the point of WITH-OVERLOAD is to "syntactically rewrite" (i.e. "name-based" substituion, not "symbol-based") all occurences of a certain operator and replace it with another operator
20:18:03
Josh_2
u have to socket-accept that stream-server-usocket which will block, listen stops it blocking
20:18:35
makomo
MichaelRaskin: MAP-OPERATOR-2 is my little wrapper around AGNOSTIC-LIZARD:WALK-FORM that will go over all of the operators
20:19:05
makomo
MichaelRaskin: now, i would have expected the 5th example to behave just like the 4th one, i.e. for the local macro HELLO to be expanded by agnostic-lizard
20:21:05
makomo
MichaelRaskin: if you notice any other irregularities or wrong assumptions, i'm all ears :-)
20:22:11
MichaelRaskin
Are you using this as a reduced example while wanting to do something much larger, or does with-overload do what you actually want to use?
20:23:46
MichaelRaskin
Because «this in operator position should be replaced with that» sounds like precisely a simple macro (that can be generated, too)
20:24:05
makomo
MichaelRaskin: i have, but the problem is that then i have to know the package of the operator that is to be replaced
20:24:42
makomo
the point is to use WITH-OVERLOAD around users' code, which might use various operators like these
20:25:06
makomo
MichaelRaskin: and their code will reside in their own package, which i won't know about
20:26:02
MichaelRaskin
Makomo: flatten, and generate substitutions based on all the symbols with interesting names present?
20:26:39
phoe
pjb: adding a LISTEN before the READ clearly makes the function not hang anymore, so it means that LISTEN has side effects
20:27:21
makomo
MichaelRaskin: oh, hm, let me think. i did literally the same thing with variables (i.e. collect the variables and then "substitute" them using LET). not sure why i didn't think of the same for operators
20:27:51
MichaelRaskin
I know I am not doing a good job advertising Agnostic-Lizard, but if you can make compiler do the work, it will be much more performant
20:29:30
MichaelRaskin
There is a catch that if you pass an environment, you probably want to pass the :names argument, if possible
20:30:17
MichaelRaskin
The paper contains an example proving that doing the job correctly is impossible, after all
20:30:25
makomo
MichaelRaskin: does that apply to my case? is the behavior i'm seeing with example 5 expected or? is it the result of heuristics failing?
20:32:43
MichaelRaskin
Hm, your code never calls macroexpand-1, so it should be possible to make work with AA
20:42:08
makomo
MichaelRaskin: a question regarding the code walking itself -- https://plaster.tymoon.eu/view/1189#1189. why is :on-function-form-pre called for the arguments to + here?
20:42:49
Xach
phoe: a photo sensor tests state. if you run it at noon and at midnight you might get different results.
20:43:21
_death
phoe: if something sometimes returns true and other times returns false, for the same input (say, the same stream), it's not a pure function
20:44:57
MichaelRaskin
makomo: well, it allows to swap things that do not look like special/hardwired forms
20:46:48
makomo
MichaelRaskin: right, but it is called not only for the operator form (+ 1 2) (which might also be a macro), but also for the atoms 1 and 2
20:50:55
_death
phoe: indeed, read-sequence tries to read elements to fill the sequence, and will return fewer elements only if it encounters eof.. this is why I suggested read-byte and listen earlier
20:51:41
phoe
_death: that's what I was thinking of and IIUC pjb was trying to convince me otherwise
20:51:52
makomo
MichaelRaskin: ah, so i have to somehow construct a metaenv/walker-metaenv from the implementation-specific environment?
20:54:23
MichaelRaskin
In a sense, if just a flatten and generating a macrolet is easier than finding what you need from comments and paper, it is a sign AL is not the tool for the job
20:55:42
makomo
MichaelRaskin: so far i've only dealt with small examples so i haven't hit any slowness problems
20:57:01
makomo
MichaelRaskin: yeah, i understand that 100% portability is impossible, but i guess we can get pretty close
20:58:45
MichaelRaskin
The code is agnostic (so no calling of implementation-specific functions that are technically speaking free to do something else), so to do some approximations close enough it needs to construct environments via on-the-fly compiled code
20:58:57
makomo
MichaelRaskin: did AL come to life because you were doing some interesting code walking yourself, or just because you wanted to (nearly) solve an interesting problem?
21:00:21
pjb
phoe: if you add force-output or otherwise go beyond the internal buffering, you need multiple threads.
21:00:46
MichaelRaskin
Those who write a walker after AL without understanding AL, are doomed to provide an unnecessary failure to AL's testsuite!
21:01:26
MichaelRaskin
(It has a test case for every previous code walker where the previous walker had a chance to work but failed )
21:06:12
MichaelRaskin
makomo: if you are interested in doing something that might have a use and involves AL, I can published my partially working code for implementation-agnostic debugger
21:07:00
MichaelRaskin
It's a bit crazy, but there it seems believable that AL is a hammer of correct size
21:07:54
MichaelRaskin
(actually, in ELS proceedings you can find an interesting practical tool that uses AL — and I learned about that tool at ELS)
21:14:41
MichaelRaskin
My work: a year _before_ AL there was a combo rant/tool about fighting optimiser to get useful debugging information
21:14:41
_death
pjb: in fact, sbcl has a note about "short read" just before socket-receive: https://github.com/sbcl/sbcl/blob/master/contrib/sb-bsd-sockets/sockets.lisp#L134
21:18:37
MichaelRaskin
https://github.com/marcoheisig/Petalisp/blob/63390253cda7b7ad3ba8b6dbc10d60fe07821f5a/code/api/petalisp.api.asd
21:30:33
MichaelRaskin
And I think Petalisp is using AL in a saner way than my attempt to write an agnostic debugger
22:16:06
dxtr
Does it make sense to run call-next-method at the beginning of a method? Or should I rather use :before?
22:24:24
therik
when I (ql:quickload :usocket), why doesn't it pull the server.lisp file too? I have to do separate (ql:quickload :usocket-server) for that
22:50:17
fiddlerwoaroof
The main reasons to use :AROUND are either you want to change the return value of a primary method (and don't want to make people remember to call #'CALL-NEXT-METHOD) or you want to prevent the primary methods (and :BEFORE/:AFTER methods) from running
22:50:53
fiddlerwoaroof
Or, you're doing something interesting, like trying to make the implementations of your function run in a different thread
23:10:04
casouri
Hi, I'm tring to inplement a simple irc backend. I think I would have two streams: one connects to emacs and one connects to irc server. And the program and send/recieve messages from/to them. I've thought of some structure of the program but they all seems complicated.
23:12:06
casouri
For one that I can think of, I would have two special variable bound to streams and have lock on them, and loops through 1) send to emacs, 2) recieve from emacs, 3) send to irc, 4) recieve from irc
23:13:36
fiddlerwoaroof
If you have a recent enough version of slime/swank (I'm not sure if it's in quicklisp), you can use swank-buffer-streams to get a stream that outputs to an emacs buffer
23:15:49
therik
Xach: where's that written? I just randomly typed :usocket-server out of desperation and it downloaded it
23:15:56
casouri
Thanks, swank feels a bit of an overkill to me. A tcp socket should work fine for messeges
23:19:46
casouri
Is there any way to do non-blocking read on normal streams? I searched around and didn't found anything that mentions it.
23:27:30
fiddlerwoaroof
something like (loop when (cl:listen s) thereis (sl:read-char s) do (sleep 0.1))
23:29:24
casouri
verisimilitude: Thanks. Would it be ok if I instead spawn four threads and connects them to some CSP channels?
23:32:11
casouri
Because it seems a non-blocking READ-LINE is more difficult to implement that that. I need to create a buffer and read char to buffer and only return t when I read a newline.
0:23:03
Josh_2
currently using safe-queue I'd like to have sq:make-queue instead of safe-queue:make-queue for example
0:27:33
Josh_2
That is true :) however I got a conflic with clx and usocket so I just went with using the package designators at the start (I think that's what it is)
0:36:37
Josh_2
Is there an advantage to do say (defmacro pop-queue () `(sq:dequeue *commands-queue*)) over (defun pop-queue () (sq:dequeue *commands-queue*))? I've seen it done with accessors before
1:25:26
aeth
Josh_2: If you have a macro and an equivalent function, always go with the function. If you want sort of macro-like behavior then (declaim (inline function-name)) and you get that. Note that that inline includes the macro's *disadvantage* of not updating the callers when you recompile it. It will give you macro-like performance characteristics while permitting higher order functions and removing a bunch of potential bugs, though.
1:27:00
aeth
e.g. (defmacro 2+ (number) `(+ 2 ,number)) vs. (defun 2+ (number) (+ 2 number)) vs. (declaim (inline 2+)) (defun 2+ (number) (+ 2 number)) and for this particular case the 3rd option is probably what you want.
1:29:53
aeth
Forgetting , is such a common bug because the author will probably name their variables the same the whole way so it will take a third party using it to spot the missing , so that's one good reason to never use macros when a function will do.
1:30:25
aeth
e.g. the 2+ macro author might name their number 'number and then write `(+ 2 number) and you'll spot it when you call your number 'n and have to write a pull request
1:32:03
aeth
These seem to be incredibly common in exactly the sort of macro-as-inline-function trivial macros, too. Perhaps because the author isn't paying too much attention to something so trivial.
1:42:29
Josh_2
(bt:make-thread ..) is the way to make a thread that should run in the background, or am I missing something... *thonk*
2:05:38
aeth
Josh_2: (defun hello (n) (format t "Hello, ~D.~%" n)) (defun make-hello (n) (bt:make-thread (lambda () (sleep 10) (hello n)))) (dotimes (i 10) (make-hello i) (sleep 1))
2:06:42
aeth
Josh_2: Interestingly, the #'make-hello is actually *mandatory*, or else it reads the *current* value of i (9 for the first thread and 10 for the remaining 9) at the time of printing instead of printing 0 to 9.
2:07:43
aeth
Also don't forget to put it in its own function or be very aware of the variables it's capturing
2:08:51
aeth
It's a clsoure. It will have access to all of the outer variables, although if it's just (lambda () (receive-data)) I guess it won't matter. I think in that case (zero arguments) you might just be able to say #'receive-data
4:43:24
emaczen
I have a lisp function whose argument gets passed to a particular cffi:foreign-funcall which expects a struct
4:43:49
emaczen
The "struct" I pass to the lisp function gets automatically translated into a lisp list
4:45:30
emaczen
How do I stop this automatic translation, or how can I force the list to be converted back to a struct?
5:43:12
LdBeth
emaczen: then just use the ctype pointer, see https://common-lisp.net/project/cffi/manual/cffi-manual.html#Foreign-Structure-Types