timc wrote:

> I think I know how to do fileLines, but not socketLines. (Each
> received packet should contain one line as it would have been written
> to a file, I think).

Something like this?

(use 'clojure.contrib.duck-streams)

(read-lines (.getInputStream socket))

> My problem is not how to manage a server socket,
> but how to make an ISeq -- i.e. what exactly is the contract that ISeq
> defines (the source code has no comments).

You wouldn't usually implement ISeq directly in Clojure code, you'd use 
the lazy-seq function.  A simple example from clojure.core:

(defn repeat
   "Returns a lazy (infinite!, or length n if supplied) sequence of xs."
   ([x] (lazy-seq (cons x (repeat x))))
   ([n x] (take n (repeat x))))

It's lazy because lazy-seq doesn't evaluate it's body until you ask for 
it (by calling 'seq', 'first' or 'next' on it).  As you access the seq a 
linked list is generated.  So initially there's just a LazySeq object:

  <LazySeq>

Then the body of lazy-seq is evaluated creating a cons cell of the value 
x and (repeat x) which evaluates to another LazySeq:

first next
  +---+---+
  | x | |----> <LazySeq>
  +---+---+

And so on it repeats:

first next    first next
  +---+---+    +---+---+
  | x | |----> | x | |----> <LazySeq>
  +---+---+    +---+---+

So we could make a simple function that returns a sequence of lines by 
calling .readLine over and over on an object:

(defn readline-seq [rdr]
   (lazy-seq (cons (.readLine rdr) (readline-seq rdr))))

However, we also want to stop at the end of the file, so we put in a 
check for the line being null:

(defn readline-seq [rdr]
   (lazy-seq
     (when-let [line (.readLine rdr)]
       (cons line (readline-seq rdr)))))

This is exactly how core/line-seq is defined, and 
duck-streams/read-lines is the same except it also takes care of 
adapting whatever you pass in (like a File or InputStream) to a 
BufferedReader (which provides the readLine method).

As for ISeq, take a look at Range.java for a simplish example.  You just 
need to implement the two methods, first() which returns the first thing 
in the seq and next() which returns a new seq (ie another instance of 
your class) representing the next part of the seq (so seq.next().first() 
is the second item, seq.next().next().first() is the third item and so on).

Hope that explanation was clear enough.

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to