Trying to do a little premature optimization over here.
The data I get back from a socket is a vector of numbers. They come from
the RoboCup soccer server, which was originally a Lisp project, so those
numbers are character codes of, god bless 'em, a sexpr:
"(init l 2 before_kick_off)"
So I'd like to hand it to read, but (preemy opt) without making it into
a new string.
I see read-from-string, but not read-from-vector. read-from-string won't
eat vectors (damn strong-typing!). I also looked for a way to make a
stream out of a vector, but did not find one.
My workaround is to have a big one-time allocated string and:
(map-into *buffer$* #'code-char (subseq data 0 size))
and then also tell read-from-string about the size.
Did I miss the easy way to do this, or is this what Gray streams are for?
--
kenny tilton
clinisys, inc
http://www.tilton-technology.com/
---------------------------------------------------------------
"Career highlights? I had two. I got an intentional walk from
Sandy Koufax and I got out of a rundown against the Mets."
-- Bob Uecker
From: Christopher C. Stacy
Subject: Re: Streams, sockets, vectors, read...easier way?.
Date:
Message-ID: <ufzk15vmk.fsf@dtpq.com>
>>>>> On Sat, 16 Aug 2003 13:22:43 GMT, Kenny Tilton ("Kenny") writes:
Kenny> Trying to do a little premature optimization over here.
Kenny> The data I get back from a socket is a vector of numbers. They come
Kenny> from the RoboCup soccer server, which was originally a Lisp project,
Kenny> so those numbers are character codes of, god bless 'em, a sexpr:
Kenny> "(init l 2 before_kick_off)"
Kenny> So I'd like to hand it to read, but (preemy opt) without
Kenny> making it into a new string.
Can't you just call READ on the network stream in the first place?
Christopher C. Stacy wrote:
>>>>>>On Sat, 16 Aug 2003 13:22:43 GMT, Kenny Tilton ("Kenny") writes:
>>>>>
>
> Kenny> Trying to do a little premature optimization over here.
> Kenny> The data I get back from a socket is a vector of numbers. They come
> Kenny> from the RoboCup soccer server, which was originally a Lisp project,
> Kenny> so those numbers are character codes of, god bless 'em, a sexpr:
>
> Kenny> "(init l 2 before_kick_off)"
>
> Kenny> So I'd like to hand it to read, but (preemy opt) without
> Kenny> making it into a new string.
>
> Can't you just call READ on the network stream in the first place?
Interesting. With db-sockets we can access the socket stream, but I do
not see anything similar with acl sockets. I /do/ call
mp:wait-for-input-available on the acl socket as if it were a stream,
but that must be provided as a specialization; read complains the
datagram socket is not a stream.
another problem is that the soccer server doc warns that messages can
get truncated, so one may not always get the closing parens. what I do
is stick a few extra on the end before doing the read-from-string.
--
kenny tilton
clinisys, inc
http://www.tilton-technology.com/
---------------------------------------------------------------
"Career highlights? I had two. I got an intentional walk from
Sandy Koufax and I got out of a rundown against the Mets."
-- Bob Uecker
Kenny Tilton <·······@nyc.rr.com> writes:
> another problem is that the soccer server doc warns that messages can
> get truncated, so one may not always get the closing parens. what I do
> is stick a few extra on the end before doing the read-from-string.
That's pretty icky. I'm not certain (no HyperSpec handy) but I don't
think that READ is guaranteed to DTRT with extra random closing
parens. Ie, in some implementation it might signal an error rather
than just ignore them. You'd then need to catch that error to make it
go away. Maybe catch a number of errors, one for each, or bail out
when catching the first one.
And what do you do if you magically receive an extra paren from the
other end?
Just something to think about.
Here's a thought off the top of my head -- put some sort of flag
character at the end of your incoming stream that marks where it
ended. Use something nearly impossible to receive except if the data
is mangled, like #xff or whatever. Maybe use a couple so you have a
complex unique bit pattern. Make a READ macro to handle that which
checks to see if there's still open parens and inserts the appropriate
number.
But that's getting pretty complicated. Still, the idea of throwing a
handful of close parens on the end of the string in hopes of it
fixing any missing parens just doesn't seem very safe.
'james
--
James A. Crippen <james at unlambda.com> Lambda Unlimited
61.2204N, -149.8964W Recursion 'R' Us
Anchorage, Alaska, USA, Earth Y = \f.(\x.f(xx))(\x.f(xx))
James A. Crippen wrote:
> Kenny Tilton <·······@nyc.rr.com> writes:
>
>
>>another problem is that the soccer server doc warns that messages can
>>get truncated, so one may not always get the closing parens. what I do
>>is stick a few extra on the end before doing the read-from-string.
>
>
> That's pretty icky. I'm not certain (no HyperSpec handy) but I don't
> think that READ is guaranteed to DTRT with extra random closing
> parens. Ie, in some implementation it might signal an error rather
> than just ignore them.
Well, if worse comes to worst I can just look at the strings and balance
them intelligently, since the syntax of the soccer server messages is so
simple.
You just gave me an idea. I can name my team "Team'(((Kenny" in the hope
of crashing an opponent who has to parse messages char-by-char on the
chance their parser is buggy. They'll keep reading looking for the
closing parens!
:)
--
kenny tilton
clinisys, inc
http://www.tilton-technology.com/
---------------------------------------------------------------
"Career highlights? I had two. I got an intentional walk from
Sandy Koufax and I got out of a rundown against the Mets."
-- Bob Uecker
Kenny Tilton <·······@nyc.rr.com> writes:
> Trying to do a little premature optimization over here.
>
> The data I get back from a socket is a vector of numbers. They come from
> the RoboCup soccer server, which was originally a Lisp project, so those
> numbers are character codes of, god bless 'em, a sexpr:
>
> "(init l 2 before_kick_off)"
>
> So I'd like to hand it to read, but (preemy opt) without making it into
> a new string.
>
> I see read-from-string, but not read-from-vector. read-from-string won't
> eat vectors (damn strong-typing!). I also looked for a way to make a
> stream out of a vector, but did not find one.
>
> My workaround is to have a big one-time allocated string and:
>
> (map-into *buffer$* #'code-char (subseq data 0 size))
>
> and then also tell read-from-string about the size.
>
> Did I miss the easy way to do this, or is this what Gray streams are for?
Well, I've used Gray streams to do something similar, but I'm pretty
sure it was less efficient than the alternative vector-bashing
approach (waaaaaaay more elegant, though, with the use of mixins).
If I were you, I'd do something like:
(when (< (length *chars*) size)
(setf (*chars* (make-array size :element-type 'character))))
(setf (fill-pointer *chars*) size)
(dotimes (i size) (setf (char *chars* i) (aref *codes* i)))
(read-from-string *chars*)
Of course, you are leading up to a call to READ...
--
/|_ .-----------------------.
,' .\ / | No to Imperialist war |
,--' _,' | Wage class war! |
/ / `-----------------------'
( -. |
| ) |
(`-. '--.)
`. )----'
Thomas F. Burdick wrote:
> Kenny Tilton <·······@nyc.rr.com> writes:
>
>
>>Trying to do a little premature optimization over here.
>>
>>The data I get back from a socket is a vector of numbers. They come from
>>the RoboCup soccer server, which was originally a Lisp project, so those
>>numbers are character codes of, god bless 'em, a sexpr:
>>
>> "(init l 2 before_kick_off)"
>>
>>So I'd like to hand it to read, but (preemy opt) without making it into
>>a new string.
>>
>>I see read-from-string, but not read-from-vector. read-from-string won't
>>eat vectors (damn strong-typing!). I also looked for a way to make a
>>stream out of a vector, but did not find one.
>>
>>My workaround is to have a big one-time allocated string and:
>>
>> (map-into *buffer$* #'code-char (subseq data 0 size))
>>
>>and then also tell read-from-string about the size.
>>
>>Did I miss the easy way to do this, or is this what Gray streams are for?
>
>
> Well, I've used Gray streams to do something similar, but I'm pretty
> sure it was less efficient than the alternative vector-bashing
> approach (waaaaaaay more elegant, though, with the use of mixins).
>
> If I were you, I'd do something like:
>
> (when (< (length *chars*) size)
> (setf (*chars* (make-array size :element-type 'character))))
> (setf (fill-pointer *chars*) size)
> (dotimes (i size) (setf (char *chars* i) (aref *codes* i)))
> (read-from-string *chars*)
OK, that's what I had, to hell with elegance, it stays. Only I did not
have the fill-pointer bit. So that's what that does. And to think I was
returning two values, the buffer and the size. Doh!
--
kenny tilton
clinisys, inc
http://www.tilton-technology.com/
---------------------------------------------------------------
"Career highlights? I had two. I got an intentional walk from
Sandy Koufax and I got out of a rundown against the Mets."
-- Bob Uecker
Kenny Tilton <·······@nyc.rr.com> writes:
> Thomas F. Burdick wrote:
>
> > If I were you, I'd do something like:
> >
> > (when (< (length *chars*) size)
> > (setf (*chars* (make-array size :element-type 'character))))
> > (setf (fill-pointer *chars*) size)
> > (dotimes (i size) (setf (char *chars* i) (aref *codes* i)))
> > (read-from-string *chars*)
[ wow, that code's broken in just about every detail, but it got my point across ]
> OK, that's what I had, to hell with elegance, it stays. Only I did not
> have the fill-pointer bit. So that's what that does. And to think I was
> returning two values, the buffer and the size. Doh!
Oh, fill-pointers are beautiful! When I make functions that read
objects from binary streams, I usually make an accompanying one that
reads from (vector (unsigned-byte 8))'s, making heavy use of one of my
favorite utility functions that Really Should Be In CL (<-- ironic capitals):
(defun vector-shift (vector &optional (amount 1))
(let* ((length (length vector))
(new-length (- length amount)))
(setf (subseq vector 0 new-length) (subseq vector amount length)
(fill-pointer vector) new-length)
vector))
--
/|_ .-----------------------.
,' .\ / | No to Imperialist war |
,--' _,' | Wage class war! |
/ / `-----------------------'
( -. |
| ) |
(`-. '--.)
`. )----'
Thomas F. Burdick wrote:
> Kenny Tilton <·······@nyc.rr.com> writes:
>
>
>>Thomas F. Burdick wrote:
>>
>>
>>>If I were you, I'd do something like:
>>>
>>> (when (< (length *chars*) size)
>>> (setf (*chars* (make-array size :element-type 'character))))
>>> (setf (fill-pointer *chars*) size)
>>> (dotimes (i size) (setf (char *chars* i) (aref *codes* i)))
>>> (read-from-string *chars*)
>>
>
> [ wow, that code's broken in just about every detail, but it got my point across ]
<g> Good thing the warranty had run out by the time I pasted it in.
Anyway, I gotta come clean. Turns out I did throw efficiency to the wind
(Joe woulda been proud) in my very first efforts, so anxious was I to
see guys scurrying around the field; I let the ACL socket read function
allocate space instead of providing it a buffer. And it reasonably
enough returned a vector of numbers, not characters. Now I just pass it
one of your dandy character arrays and read-from-string that.
Life is good. multiple-value-binds and subseqs and end args are dropping
like flies over here.
gee, a significant cleanup, some new CL knowledge, and at least a little
more efficiency. glad I spent time on this. :)
--
kenny tilton
clinisys, inc
http://www.tilton-technology.com/
---------------------------------------------------------------
"Career highlights? I had two. I got an intentional walk from
Sandy Koufax and I got out of a rundown against the Mets."
-- Bob Uecker
Kenny Tilton <·······@nyc.rr.com> writes:
> Trying to do a little premature optimization over here.
> My workaround is to have a big one-time allocated string and:
>
> (map-into *buffer$* #'code-char (subseq data 0 size))
>
> and then also tell read-from-string about the size.
What's wrong with (map 'string #'code-char vector)?
Are you getting huge packets so fast and furious that you need to
worry about them?
Joe Marshall wrote:
> Kenny Tilton <·······@nyc.rr.com> writes:
>
>
>>Trying to do a little premature optimization over here.
>
>
>>My workaround is to have a big one-time allocated string and:
>>
>> (map-into *buffer$* #'code-char (subseq data 0 size))
>>
>>and then also tell read-from-string about the size.
>
>
> What's wrong with (map 'string #'code-char vector)?
> Are you getting huge packets so fast and furious that you need to
> worry about them?
What part of "premature optimization" do you not understand?! <g>
No, seriously, I do not think the injunction against preemy-opt excuses
needless consing which could be avoided if I used the right magic CL
incantation (or if I stick with plan A, which was to copy the data char
by char into a string).
fwiw, the traffic is two or three messages every 100ms, each message
hundreds (but not thousands) of characters long. Multiplied by 22, since
I hope to run entire games from one Lisp image during development.
--
kenny tilton
clinisys, inc
http://www.tilton-technology.com/
---------------------------------------------------------------
"Career highlights? I had two. I got an intentional walk from
Sandy Koufax and I got out of a rundown against the Mets."
-- Bob Uecker
Kenny Tilton <·······@nyc.rr.com> writes:
> Joe Marshall wrote:
>> Kenny Tilton <·······@nyc.rr.com> writes:
>>
>>>Trying to do a little premature optimization over here.
>>
>>>My workaround is to have a big one-time allocated string and:
>>>
>>> (map-into *buffer$* #'code-char (subseq data 0 size))
>>>
>>>and then also tell read-from-string about the size.
>> What's wrong with (map 'string #'code-char vector)?
>> Are you getting huge packets so fast and furious that you need to
>> worry about them?
>
> What part of "premature optimization" do you not understand?! <g>
Yeah, yeah.
> No, seriously, I do not think the injunction against preemy-opt
> excuses needless consing which could be avoided if I used the right
> magic CL incantation (or if I stick with plan A, which was to copy the
> data char by char into a string).
I'm guessing that the amount of CPU time you will save by avoiding
this `needless' consing will *never* add up to the amount of time
you've thought about it.
> fwiw, the traffic is two or three messages every 100ms, each message
> hundreds (but not thousands) of characters long. Multiplied by 22,
> since I hope to run entire games from one Lisp image during
> development.
Not enough to worry about. Just cons it.
> The data I get back from a socket is a vector of numbers. They come from
> the RoboCup soccer server, which was originally a Lisp project, so those
> numbers are character codes of, god bless 'em, a sexpr:
>
> "(init l 2 before_kick_off)"
>
> So I'd like to hand it to read, but (preemy opt) without making it into a
> new string.
>
> I see read-from-string, but not read-from-vector. read-from-string won't
> eat vectors (damn strong-typing!). I also looked for a way to make a
> stream out of a vector, but did not find one.
Hmmm... we interface our agents to RoboCup with code like...
(defparameter *port-for-RS-server* 6000)
(defparameter *RS-client-plist* NIL)
(defparameter *default-RS-socket* NIL)
(defparameter *RS-buffer*
(make-array 3000 :element-type 'character))
(defun make-UDP-socket (host port)
(socket:make-socket :type :datagram :remote-host host :remote-port port))
(defun start-RS-client (server-hostname server-name)
"Open a socket to a passive server."
(let ((client-stream
(make-UDP-socket server-hostname *port-for-RS-server*)))
(cond (client-stream
(setf (getf *RS-client-plist* server-name)
client-stream)
(setf *default-RS-socket* client-stream)
(values client-stream :ok))
(T
(values nil :server-open-failed)))))
(defun stop-RS-client (server-name)
"Stops the named socket."
(close (getf *RS-client-plist* server-name))
(remf *RS-client-plist* server-name))
(defun stop-all-RS-clients ()
"Stops all active RS sockets."
(let ((servers nil))
(do ((s *RS-client-plist* (cddr s)))
((endp s))
(push (first s) servers))
(dolist (s servers)
(stop-RS-client s))))
(defparameter *system-initialized* NIL)
(defun shutdown-RS-system (server-name)
"Closes the socket link..."
(stop-RS-client server-name)
(setf *system-initialized* NIL))
(defparameter *debug-uploaded-cmds?* NIL)
(defun UDP-socket-write (socket message)
(if *debug-uploaded-cmds?*
(print message)
(socket:send-to socket message (length message))))
(defun UDP-socket-read (socket)
(multiple-value-bind (message size host port)
(socket:receive-from socket 3000
:buffer *RS-buffer*
:extract t)
(values message size)))
#|
> (defparameter *rs-1* (make-UDP-socket "localhost" 6000))
*rs-1*
> (UDP-socket-write *rs-1* "(init Scotties)")
15
> (UDP-socket-read *rs-1*)
"(init l 1 before_kick_off)
28
> (progn
(dotimes (i 100) (UDP-socket-read *rs-1*))
(UDP-socket-write *rs-1* "(sense_body)")
(pprint (read-from-string (UDP-socket-read *rs-1*))))
(sense_body 0 (view_mode high normal) (stamina 4000 1)
(speed 0) (kick 0) (dash 0) (turn 2) (say 0))
> (pprint (read-from-string (UDP-socket-read *rs-1*)))
(see 0 ((flag c b) 12.2 -25 0 0) ((line b) 10.8 -86))
> (UDP-socket-write *rs-1* "(bye)")
5
> (pprint (read-from-string (UDP-socket-read *rs-1*)))
(see 0 ((flag c b) 12.2 -25 0 0) ((line b) 10.8 -86))
> (UDP-socket-write *rs-1* "(bye)")
5
> (close *rs-1*)
#<multivalent datagram socket closed, but was at */1993 @ #x20ef3a72>
>
|#
Now our connections to X-Plane require serious UDP bit munging...
Scott
Scott A Douglass wrote:
>> The data I get back from a socket is a vector of numbers. They come from
>> the RoboCup soccer server, which was originally a Lisp project, so those
>> numbers are character codes of, god bless 'em, a sexpr:
>>
>> "(init l 2 before_kick_off)"
>>
>> So I'd like to hand it to read, but (preemy opt) without making it into a
>> new string.
>>
>> I see read-from-string, but not read-from-vector. read-from-string won't
>> eat vectors (damn strong-typing!). I also looked for a way to make a
>> stream out of a vector, but did not find one.
>
>
> Hmmm... we interface our agents to RoboCup with code like...
Yeah, I totally whiffed on this, should have been passing a character
array to receive-from from the get go. My code looks like yours, now,
except I went with nil on extract. I'm desperate at this point, I'll
make it T and see if it fools anybody.
The thing is, I am running the server on my same NT box as ACL, and I am
juggling all the players and the coach from one process. But even just
the coach or one player can somehow block the server. I can run just a
sequence: send init, gather all the responses (nine), and have it work
one time and then not the next. I'll get pack three or four messages and
then nothing. Even if I sleep between messages or do an
mp:wait-for-input-available with a non-zero timeout. If I code it to
fall out of the read loop when the server falls silent, I can then kick
off the read loop on the same socket and get the rest of the messages.
If I lower the WinNT ACL priority (to "low") I do not block the server
(or is it only once in ten? gotta recheck that).
You all coming to ILC 2003 for the RoboCup match? Glad to hear of other
Lispniks doing RoboCup.
--
kenny tilton
clinisys, inc
http://www.tilton-technology.com/
---------------------------------------------------------------
"Career highlights? I had two. I got an intentional walk from
Sandy Koufax and I got out of a rundown against the Mets."
-- Bob Uecker
> The thing is, I am running the server on my same NT box as ACL, and I am
> juggling all the players and the coach from one process. But even just
> the coach or one player can somehow block the server.
I've recently developed a prolog-like agent specification formalism for
research purposes. Last semester, I used it in a cognitive agent modeling
course. The formalism allows you to express agents in UML (Rational Rose).
Model files from Rose are automatically read/translated into ACL/lisp.
Agents are managed/inspected in ACL via a GUI.
The framework is deliberately generic; it has been used to situate
behavior-based and contemplative agents in a number of virtual environments
(RoboCup being one of them). In situations where agents are being situated
in virtual environments not implemented in lisp, the framework gives each
agent a private process. With each agent having its own process and
socket, I've not seen blocking problems while using ACL.
Unless you need to run players and coach on the same rig (in the same
process), I'd recommend that you use an existing project to run the players
and invest your time in the coach. Players just run, dribble, kick, etc.
There are players out there that have solved most of the low-level issues
associated with these actions. The coach assesses situation and sends
instructions to players via the command language. The coach is the really
interesting agent...
> You all coming to ILC 2003 for the RoboCup match? Glad to hear of other
> Lispniks doing RoboCup.
We've just been through "The First RoboCup American Open" here at CMU... I
think that was enough for the time being.
Scott A Douglass wrote:
>> The thing is, I am running the server on my same NT box as ACL, and I am
>> juggling all the players and the coach from one process. But even just
>> the coach or one player can somehow block the server.
>
>
> I've recently developed a prolog-like agent specification formalism for
> research purposes. Last semester, I used it in a cognitive agent
> modeling course. The formalism allows you to express agents in UML
> (Rational Rose). Model files from Rose are automatically read/translated
> into ACL/lisp. Agents are managed/inspected in ACL via a GUI.
OK, i think I saw a reference to your work in my RoboCup surfing.
>
> The framework is deliberately generic; it has been used to situate
> behavior-based and contemplative agents in a number of virtual
> environments (RoboCup being one of them). In situations where agents are
> being situated in virtual environments not implemented in lisp, the
> framework gives each agent a private process. With each agent having
> its own process and socket, I've not seen blocking problems while using
> ACL.
Everyone has their own socket, but everyone and the coach run in the
same proces. I had a Linux guru here last night. he got me set up with
the server under Linux. Better, but still getting blocked after a
period. He fired up tcpdump (i think!) and we could see that the soccer
server was sending everything. but on the receive side the acl socket
could stop finding new messages. but then it falls out to the repl and I
kick off a fresh sequence of reading and it finds them! Programming!! <g>
The really strange thing is that running db-sockets under cmucl I get
/worse/ behavior! I gotta think I am doing something somewhere that
really is a severe non-no in its interaction with sockets.
>
> Unless you need to run players and coach on the same rig (in the same
> process), I'd recommend that you use an existing project to run the
> players and invest your time in the coach. Players just run, dribble,
> kick, etc. There are players out there that have solved most of the
> low-level issues associated with these actions. The coach assesses
> situation and sends instructions to players via the command language.
> The coach is the really interesting agent...
Yes, I see some fine players out there. But our Mission Statement is to
do RoboCup with Lisp, as a way of attracting more people (RoboCuppers)
to Lisp. And I have gotten quite interested in seeing if I can get a
player to learn to dribble by itself, without sitting down with the
soccer server doc and the math and physics handbooks and doing it that
way. I want to give it a way to score its success and then just leave it
running for a night and wake up to find it dribbling like Pele. :)
Too bad I am stuck on sockets. Anyway, thanks so much for your input. It
is helping me reduce the search space.
--
kenny tilton
clinisys, inc
http://www.tilton-technology.com/
---------------------------------------------------------------
"Career highlights? I had two. I got an intentional walk from
Sandy Koufax and I got out of a rundown against the Mets."
-- Bob Uecker
> Everyone has their own socket, but everyone and the coach run in the same
> proces.
Sockets are a hoot :) Using Mac/MCL they don't block and you need to
poll... Using PC/ACL they block and you need to carefully design control
code.
I find giving each agent its own socket/process lets ACL's scheduler do all
the work. When a specific agent's socket blocks, it's process quietly
makes way for the others. Another benefit is that you can inspect/monitor
agents at runtime (GUI-based agent inspectors are like a narcotic).
> The really strange thing is that running db-sockets under cmucl I get
> /worse/ behavior!
Right. CMUCL has "inadequate" thread support and I've had problems with
lockout too. A research programmer I know working on another project (an
environment for our cognitive architecture) has found that an occasional
call to sleep breaks the logjam.
> Yes, I see some fine players out there. But our Mission Statement is to
> do RoboCup with Lisp, as a way of attracting more people (RoboCuppers) to
> Lisp.
Fair enough. Not many of my students see the utility of lisp though--they
prefer "plug&chug" languages where everything is in someone else's library.
Only the sharpest students see that lisp allows them to massively leverage
with meta-linguistic abstraction. I hope you achieve mission success :)
> And I have gotten quite interested in seeing if I can get a player
> to learn to dribble by itself, without sitting down with the soccer
> server doc and the math and physics handbooks and doing it that way. I
> want to give it a way to score its success and then just leave it running
> for a night and wake up to find it dribbling like Pele. :)
If you're willing... I'd enjoy seeing your final effort.
Scott A Douglass wrote:
>> Everyone has their own socket, but everyone and the coach run in the same
>> proces.
>
>
> Sockets are a hoot :) Using Mac/MCL they don't block and you need to
> poll... Using PC/ACL they block and you need to carefully design
> control code.
Oh, i contacted Franz and they said use:
(mp::wait-for-input-available (udp-socket rcs) :timeout 0)
returns nil if no input, so you do not have to do a blocking read.
>
> I find giving each agent its own socket/process lets ACL's scheduler do
> all the work.
been thinking about that. right now, tho, I can see the problem with
just one socket.
>> The really strange thing is that running db-sockets under cmucl I get
>> /worse/ behavior!
>
>
> Right. CMUCL has "inadequate" thread support and I've had problems with
> lockout too. A research programmer I know working on another project
> (an environment for our cognitive architecture) has found that an
> occasional call to sleep breaks the logjam.
I'll try it over there. Didn't help under ACL, but I should see if it
helps under cmu.
>
>> Yes, I see some fine players out there. But our Mission Statement is to
>> do RoboCup with Lisp, as a way of attracting more people (RoboCuppers) to
>> Lisp.
>
>
> Fair enough. Not many of my students see the utility of lisp
> though--they prefer "plug&chug" languages where everything is in someone
> else's library. Only the sharpest students see that lisp allows them to
> massively leverage with meta-linguistic abstraction. I hope you achieve
> mission success :)
thanks. I guess our marketing plan is to go for the early adopters
looking for a Better Way, including letting the ones who appreciate Lisp
know it is an option again. They can build the stuff for others to
plug&chug.
> If you're willing... I'd enjoy seeing your final effort.
Absolutely. I am going to disengage from this socket battle and go lick
my wounds, work on the client under ACL/NT with the priority down. When
I have a world model to work off, I will put the source up on my new
SourceForge project, RoboCells. It will work off another SF project I am
resurrecting, Cells. The code will compile cleanly under ACL, LW, CLisp,
CormanLisp, CMUCL and MCL, but god knows where the sockets can be made
to work (WinNT with lower priority, at least, most of the time).
The bloke who dropped by last night is strong on Linux and keen on
machine learning, but new to Lisp. I am hoping he will lean on the
socket problem and save my butt.
:)
--
kenny tilton
clinisys, inc
http://www.tilton-technology.com/
---------------------------------------------------------------
"Career highlights? I had two. I got an intentional walk from
Sandy Koufax and I got out of a rundown against the Mets."
-- Bob Uecker