(list-head lst k) with k longer than (length lst)
Hello, I'm getting: scheme@(guile-user)> (list-head '(1 2 3) 5) ERROR: In procedure list-head: ERROR: In procedure list-head: Wrong type argument in position 1 (expecting pair): () This looks pretty much like a bug to me. Shouldn't list-head return the entire list when the 'k' is bigger than its length? If that is not the case, at least the error is really confusing. I'm using Guile 2.0.11. Cheers, -- Jan Synáček
Re: (list-head lst k) with k longer than (length lst)
On Tue, 17 Nov 2015 11:53:05 +0100 Jan Synáčekwrote: > Hello, > > I'm getting: > > scheme@(guile-user)> (list-head '(1 2 3) 5) > ERROR: In procedure list-head: > ERROR: In procedure list-head: Wrong type argument in position 1 > (expecting pair): () > > This looks pretty much like a bug to me. Shouldn't list-head return > the entire list when the 'k' is bigger than its length? If that is not > the case, at least the error is really confusing. I'm using Guile > 2.0.11. The error message is confusing, but I guess the behaviour of list-head mirrors R5RS list-tail: instead of mandating the return of an empty list, R5RS states that "It is an error if list has fewer than k elements". Chris
Re: Reading data from a file descriptor
On Tue, 17 Nov 2015 13:52:21 +0100wrote: > -BEGIN PGP SIGNED MESSAGE- > Hash: SHA1 > > On Tue, Nov 17, 2015 at 12:59:56PM +, Chris Vine wrote: > > On Tue, 17 Nov 2015 10:53:19 +0100 > > [...] > > > guile's R6RS implementation has get-bytevector-some, which will do > > that for you, with unix-read-like behaviour. > > Thank you a thousand. You made me happy :-) I suppose it is worth adding that it might not be optimally efficient for all uses, as there is no get-bytevector-some! procedure which modifies an existing bytevector and takes a maximum length value. I guess it is a matter of 'suck it and see', efficiency-wise. If you are sending/receiving binary packets, it might be better to make them of fixed size and use get-bytevector-n!. (Unfortunately, get-bytevector-n! does block until n is fulfilled according to R6RS: "The get-bytevector-n! procedure reads from binary-input-port, blocking as necessary, until count bytes are available from binary-input-port or until an end of file is reached".) Chris
Re: Reading data from a file descriptor
-BEGIN PGP SIGNED MESSAGE- Hash: SHA1 On Tue, Nov 17, 2015 at 01:55:17PM +, Chris Vine wrote: > On Tue, 17 Nov 2015 13:52:21 +0100 >wrote: > > -BEGIN PGP SIGNED MESSAGE- > > Hash: SHA1 > > > > On Tue, Nov 17, 2015 at 12:59:56PM +, Chris Vine wrote: > > > On Tue, 17 Nov 2015 10:53:19 +0100 > > > > [...] > > > > > guile's R6RS implementation has get-bytevector-some, which will do > > > that for you, with unix-read-like behaviour. > > > > Thank you a thousand. You made me happy :-) > > I suppose it is worth adding that it might not be optimally efficient > for all uses, as there is no get-bytevector-some! procedure which > modifies an existing bytevector and takes a maximum length value. I > guess it is a matter of 'suck it and see', efficiency-wise. > > If you are sending/receiving binary packets, it might be better to make > them of fixed size and use get-bytevector-n!. (Unfortunately, > get-bytevector-n! does block until n is fulfilled according to R6RS: > "The get-bytevector-n! procedure reads from binary-input-port, blocking > as necessary, until count bytes are available from binary-input-port or > until an end of file is reached".) :-( As I noted before, it's a while since I attempted that. I was looking for an equivalent of read(2) and write(2): simple, efficient, easy to understand semantics (if you discount the EOF problem for now). Perhaps the limitations you mention above steered me towards read-string!/partial and friends, then. Thanks & regards - -- tomás -BEGIN PGP SIGNATURE- Version: GnuPG v1.4.12 (GNU/Linux) iEYEARECAAYFAlZLLJcACgkQBcgs9XrR2kbS9gCeNM696u8KT9Fzq0fSifH8YKa3 VjEAn0KKx5Im4UNxUumiy0RroiKT3iDU =nAXY -END PGP SIGNATURE-
Re: Reading data from a file descriptor
On Tue, 17 Nov 2015 10:53:19 +0100wrote: > -BEGIN PGP SIGNED MESSAGE- > Hash: SHA1 > > On Mon, Nov 16, 2015 at 11:54:33AM +0100, Amirouche Boubekki wrote: > > On 2015-11-13 21:41, Jan Synáček wrote: > > [...] > > > >I have an open fd to a unix socket and I want to read data from > > >it. I know that the data is going to be only strings, but I don't > > >know the length in advance. > > > > Do you know a delimiter? maybe it's the null char? > > > > TCP is stream oriented, it's not structured at this layer into > > messages or segments. You need some knowledge about the byte stream > > to be able to split it into different meaningful piece for the > > upper layer. > > I think I "got" Jan's request, because I've been in a similar > situation before: delimiter is not (yet) part of it. What he's > looking for is an interface à la read(2), meaning "gimme as much > as there is in the queue, up to N bytes, and tell me how much > you gave me". Of course, putting stuff in a byte vector would > be preferable; the only functions I've seen[1] which "do" that > interface are read-string!/partial and write-string/partial > operate on strings, not byte arrays, alas. guile's R6RS implementation has get-bytevector-some, which will do that for you, with unix-read-like behaviour. You cannot use this for UTF-8 text by trying to convert the bytevector with utf8->string, because you could have received a partially formed utf-8 character. So for text, you should use line orientated reading, such as with ice-9 read-line or R6RS get-line. Chris
Re: Asynchronous event loop brainstorm at FSF 30
Chris Vine writes: > It is certainly the case that mixing threads with coroutines is usually > best avoided, otherwise it becomes very difficult to know what code > ends up running in which particular thread and thread safety becomes a > nightmare. However, it would be good to allow a worker thread to post > an event to the event loop safely, whereby the handler for the posted > event would run in the event loop thread. asyncio allows this. > > Although not particularly pertinent to this proposal, which looks > great, I use coroutines implemented with guile's delimited > continuations for a minimalist "await" wrapper over glib's event loop > as provided by guile-gnome (the whole thing is about 20 lines of code), > which appears (to the user) to serialize the GUI or other events posted > to the event loop. When I don't want to use guile-gnome, which is most > of the time, I have my own (also minimalist) thread-safe event loop > using guile's POSIX wrapper for select. > > My uses of guile are pretty undemanding so as I say these are > minimalist. Something like asyncio for guile would be very nice indeed. > > Chris This sounds very interesting... is the source available? Could you point to it? Thanks! - Chris
Re: Reading data from a file descriptor
-BEGIN PGP SIGNED MESSAGE- Hash: SHA1 On Mon, Nov 16, 2015 at 11:54:33AM +0100, Amirouche Boubekki wrote: > On 2015-11-13 21:41, Jan Synáček wrote: [...] > >I have an open fd to a unix socket and I want to read data from it. I > >know that the data is going to be only strings, but I don't know the > >length in advance. > > Do you know a delimiter? maybe it's the null char? > > TCP is stream oriented, it's not structured at this layer into messages > or segments. You need some knowledge about the byte stream to be able to > split it into different meaningful piece for the upper layer. I think I "got" Jan's request, because I've been in a similar situation before: delimiter is not (yet) part of it. What he's looking for is an interface à la read(2), meaning "gimme as much as there is in the queue, up to N bytes, and tell me how much you gave me". Of course, putting stuff in a byte vector would be preferable; the only functions I've seen[1] which "do" that interface are read-string!/partial and write-string/partial operate on strings, not byte arrays, alas. > In Python the socket.recv method returns bytestring but still you > have to parse > to bytestring to make sure the delimiter is not in the middle of the > string. What > I mean is that in theory you might socket.recv the end of an > application level message > and the beginning of another using the same call. Not (yet) about delimiters. > Otherwise said, the only thing that could make sens for a (recv) > procedure is > to return the full content of the inbound network buffer for the > given socket > as a bytevector but it will still require work to to make things work... Exactly, see above. A delimiter, or just feed the thing to an incremental scanner/parser (e.g. a finite state machine, which can get its input spoonwise). > Have a look at the implementation. IMO the solution is to build a > loop with > (read-char) [1] looking for the *end char* to stop the loop. If your application is set up to accept partial buffers of arbitraty length, it seems a bit wasteful to have a buffered read (which is definitely beneath `read-char') going through a character-wise read into a new buffered read... regards - -- tomás -BEGIN PGP SIGNATURE- Version: GnuPG v1.4.12 (GNU/Linux) iEYEARECAAYFAlZK+Q8ACgkQBcgs9XrR2kaV6QCdFkPPiAZqhyC4knvJroGyq2+m I0QAnicg8Cz5VL2I9VfWm7GcMLNhvNsM =dk4d -END PGP SIGNATURE-
Re: (list-head lst k) with k longer than (length lst)
Chris Vinewrites: > On Tue, 17 Nov 2015 11:53:05 +0100 > Jan Synáček wrote: >> Hello, >> >> I'm getting: >> >> scheme@(guile-user)> (list-head '(1 2 3) 5) >> ERROR: In procedure list-head: >> ERROR: In procedure list-head: Wrong type argument in position 1 >> (expecting pair): () >> >> This looks pretty much like a bug to me. Shouldn't list-head return >> the entire list when the 'k' is bigger than its length? If that is not >> the case, at least the error is really confusing. I'm using Guile >> 2.0.11. > > The error message is confusing, but I guess the behaviour of list-head > mirrors R5RS list-tail: instead of mandating the return of an empty > list, R5RS states that "It is an error if list has fewer than k > elements". Exactly right, but I agree that the error message is confusing. Unless otherwise specified, Scheme and Guile tend to be strict in cases like this. For example, if a procedure is documented to "Copy the first K elements from LST", and says nothing about what happens for lists with fewer than K elements, you should assume that it's an error. Mark