Claude
Claude

Reputation: 9980

See if part of data is lazy in clojure

Is there a function in clojure that checks whether data contains some lazy part?

Background:

I'm building a small server in clojure. Each connection has a state, an input-stream and an output-stream

The server reads a byte from an input-stream, and based on the value calls one of several functions (with the state and the input and output stream as parameters). The functions can decide to read more from the input-stream, write a reply to the output stream, and return a state. This part loops.

This will all work fine, as long as the state doesn't contain any lazy parts. If there is some lazy part in the state, that may, when it gets evaluated (later, during another function), start reading from the input-stream and writing to the output-stream.

So basically I want to add a post-condition to all of these functions, stating that no part of the returned state may be lazy. Is there any function that checks for lazy sequences. I think it would be easy to check whether the state itself is a lazy sequence, but I want to check for instance whether the state has a vector that contains a hash-map, one of whose values is lazy.

Upvotes: 4

Views: 632

Answers (2)

mikera
mikera

Reputation: 106351

You could certainly force evaluation with doall as Arther wisely suggests.

However I would recommend instead refactoring to solve the real problem, which is that your handler function has side effects (reading from input, writing to output).

You could instead turn this into a pure function if you did the following:

  • Wrap the input stream as a lazy sequence
  • use [input-sequence state] as input to your handler function
  • use [list-of-writes new-state rest-of-input-sequence] as output, where list of writes is whatever needs to be subsequently written to the output stream

If you do this, your handler function is pure, you just need to run it in a simple loop (sending the list-of-writes to the output stream on each iteration) until all input is consumed and/or some other termination condition is reached.

Upvotes: 1

Arthur Ulfeldt
Arthur Ulfeldt

Reputation: 91554

it's easier to ensure that it is not lazy by forcing evaluation with doall

I had this problem in a stream processing crypto app a couple years back and tried several ways until I finally accepted my lazy side and wrapped the input streams in a lazy sequence that closed in input streams when no more data was available. effectively separating concern for closing the streams from the concern over what the streams contained. The state you are tracking sounds a little more sophisticated than open vs closed though you may be able to separate it in a similar manner.

Upvotes: 3

Related Questions