------------------------------------------------------------------------ (define println-to-port-and-flush ; /!\ needs nicer name!
(lambda (port string)
(println port: port string)
(force-output port))) ------------------------------------------------------------------------
ChickenScheme's wiki is much more blingblingy than Gambit's manual.
<https://wiki.call-cc.org/man/5/Module%20(chicken%20tcp)>
That 1st shot at sockets in Chicken took definitely longer than the same snippet in Gambit:
Scheme may have some standard(s), but the interesting stuff like sockets isn't covered in there. Gambit sockets yield readwrite ports, Chicken
two ports.
--
If you know one Lisp/Scheme, you know one Lisp/Scheme.
yeti <yeti@tilde.institute> writes:
That 1st shot at sockets in Chicken took definitely longer than the same
snippet in Gambit:
Compare it to C. :)
Very true. Now, what's even more interesting is why I don't exchange
Lisp for Scheme.
Patricia Ferreira <pferreira@example.com> writes:
yeti <yeti@tilde.institute> writes:
That 1st shot at sockets in Chicken took definitely longer than the same >>> snippet in Gambit:
Compare it to C. :)
I've a snippet that just spits out the NNTP server's welcome line, not a complete message (yet?). I'd like to have `defer` in C and easier/safer strings, but if I had to add reading a message via Message-ID, I'd not
fall into panic.
Unlike the dialect specific Scheme examples so far, the same C code
passes different C compilers. That's what should be underlined with a
flashy text marker.
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#define BUF_SIZE (4096)
int main()
{
int sock;
ssize_t nread;
char buf[BUF_SIZE];
struct addrinfo hints, *addrs;
memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
if (0 == getaddrinfo("news.tilde.club", "119", &hints, &addrs))
{
sock = socket(addrs->ai_family, addrs->ai_socktype, addrs->ai_protocol);
if ( sock >= 0 )
{
if ( connect(sock, addrs->ai_addr, addrs->ai_addrlen) >= 0 )
{
/* Nothing to send, just read */
nread = read(sock, buf, BUF_SIZE);
if ( nread != -1)
printf("Received %zd bytes: %s\n", nread, buf);
else {
perror("read");
exit(EXIT_FAILURE);
}
}
close(sock);
}
freeaddrinfo(addrs);
}
}
( Works with GCC, PCC and TinyCC )
Very true. Now, what's even more interesting is why I don't exchange
Lisp for Scheme.
But from one Lisp to the next one, you'll probably not find things like sockets handled in a standard way too.
Despite my frequent cursing about GCCisms breaking portable C code, for
stuff you write yourself, portability in C still seems doable. OTOH,
many huge projects like Emacs can't be compiled any more via compilers without GCCisms and I'm very angry[0] about this and call this GNU/GCC
locked in syndrome ™Stallman's Revenge™.
yeti <yeti@tilde.institute> writes:
Patricia Ferreira <pferreira@example.com> writes:
yeti <yeti@tilde.institute> writes:
struct addrinfo hints, *addrs;
memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_family = AF_UNSPEC;
I would say you should say AF_INET here. POSIX.1 only specifies
AF_INET, AF_INET6, AF_UNIX. So your program is not POSIX.1 with
AF_UNSPEC.
Check all that bureaucracy! :-)
But from one Lisp to the next one, you'll probably not find things
like sockets handled in a standard way too.
I had in mind things like error messages. SBCL's error messages are
so nice, for example. And Scheme virtual machines tend to be
horrible.
In practice, I view portability as an easy way to adapt your software
to another system. Having it compile and run perfectly in ``all
systems'' can only be achived with some specific types of programs if
at all.
Patricia Ferreira <pferreira@example.com> writes:
yeti <yeti@tilde.institute> writes:
Patricia Ferreira <pferreira@example.com> writes:
yeti <yeti@tilde.institute> writes:
struct addrinfo hints, *addrs;
memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_family = AF_UNSPEC;
I would say you should say AF_INET here. POSIX.1 only specifies
AF_INET, AF_INET6, AF_UNIX. So your program is not POSIX.1 with
AF_UNSPEC.
---<man 3 getaddrinfo>--------------------------------------------------
ai_family
This field specifies the desired address family for the
returned addresses. Valid values for this field include
AF_INET and AF_INET6. The value AF_UNSPEC indicates that
getaddrinfo() should return socket addresses for any
address family (either IPv4 or IPv6, for example) that can
be used with node and service. ------------------------------------------------------------------------
Sorry, I needed that IPv4/v6 tolerance.
Check all that bureaucracy! :-)
That allows plugging in more error checks in a way that fits the rest of
the application than just using one fat monolithic call.
For a quick throw away one liner I sure like it easier, e.g.:
---<manually \-wrapped for half a bit of readability>-------------------
$ gawk 'BEGIN { \
N="/inet/tcp/0/news.uni-stuttgart.de/119" ; N |& getline ; print \
; print "date" |& N ; N |& getline ; print \
; close(N) ; }'
200 news.uni-stuttgart.de InterNetNews NNRP server INN 2.5.2 ready (no posting)
111 20240323164058
$ # terminates, gives next prompt ------------------------------------------------------------------------
Near to unbeatable for some quick and dirty throw away code.
OTOH monopolies kill evolution.
Sysop: | deepend |
---|---|
Location: | Calgary, Alberta |
Users: | 263 |
Nodes: | 10 (0 / 10) |
Uptime: | 15:30:16 |
Calls: | 1,926 |
Calls today: | 1 |
Files: | 4,341 |
D/L today: |
28 files (10,306K bytes) |
Messages: | 404,008 |