generator in Clojure

2010-10-14 Thread clwham...@gmail.com
I need a function that produces the 'next' value from a lazy-seq --
something like a Python generator. I imagine it would have to be some
sort of closure like:

(def next-sine
(let [sines (atom (cycle (map sin (range 0 6.28 0.01]
#(swap! sines rest)))

Is there a more idomatic way of doing this? I don't see a lot of use
of closures in clojure...

-- 
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


Re: generator in Clojure

2010-10-14 Thread clwham...@gmail.com
I originally thought of calling nth on the seq but isn't that pretty
wildly inefficient?

On Oct 14, 1:38 pm, Moritz Ulrich 
wrote:
> Are you sure you need to capture the state in next-sine? It's not very
> clojure-ly to have functions with state. I would capture the state in
> the caller as an integer and just use get or nth on the lazy seq.
> If you want to stick to your impure function, please mark it with a !
> at the end: next-sine!
>
> On Thu, Oct 14, 2010 at 9:52 PM, clwham...@gmail.com
>
>
>
>
>
>
>
>
>
>  wrote:
> > I need a function that produces the 'next' value from a lazy-seq --
> > something like a Python generator. I imagine it would have to be some
> > sort of closure like:
>
> > (def next-sine
> >    (let [sines (atom (cycle (map sin (range 0 6.28 0.01]
> >        #(swap! sines rest)))
>
> > Is there a more idomatic way of doing this? I don't see a lot of use
> > of closures in clojure...
>
> > --
> > 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
>
> --
> Moritz Ulrich
> Programmer, Student, Almost normal Guy
>
> http://www.google.com/profiles/ulrich.moritz
> BB5F086F-C798-41D5-B742-494C1E9677E8

-- 
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


Re: generator in Clojure

2010-10-17 Thread clwham...@gmail.com
I don't actually 'know' that I need a function that relies on mutable
state, I'm really just trying to understand how to do what I want
using the functional paradigm.

I'm writing a data generator which creates CSV files to be uploaded to
a test database. I'm simulating the behavior of some network objects
(servers, server pools, virtual IP addresses, etc.) and I want to be
able to generate traffic records randomized around an arbitrary
function, like a sine wave. Currently I do something like this:

(def network-object {:name "foo" :value 0})

(defn generate-data [n-timestamps network-objects f]
  (loop [t 0]
(when (< t n-timestamps)
  (doseq [object network-objects]
(prn t (object :name) (f (object :value
  (recur (inc t)))

So I apply f to each object's value for each time t and I'd like that
function f to modify each network-object's value in a (potentially)
periodic manner. How should I structure my code to do this
functionally? I could (of course) pass the timestamp to f so f is not
stateful and I get effectively the nth value but that seems highly
inefficient. Ideas welcome.

On Oct 14, 11:56 pm, Konrad Hinsen  wrote:
> On 14 Oct 2010, at 21:52, clwham...@gmail.com wrote:
>
> > I need a function that produces the 'next' value from a lazy-seq --
> > something like a Python generator. I imagine it would have to be some
> > sort of closure like:
>
> > (def next-sine
> >    (let [sines (atom (cycle (map sin (range 0 6.28 0.01]
> >        #(swap! sines rest)))
>
> > Is there a more idomatic way of doing this? I don't see a lot of use
> > of closures in clojure...
>
> Closures are common in Clojure, but mostly they capture values rather  
> than storage locations.
>
> Could you tell us why you "need" a function that relies on mutable  
> state? Clojure has lots of functions to make, transform, and use  
> sequences in a functional style, and those are usually preferred.
>
> If your need comes from the wish to do stream processing without  
> passing the stream around explicitly among lots of functions, consider  
> using monads to abstract away the stream argument:
>
>        
> http://github.com/clojure/clojure-contrib/blob/master/modules/stream-...
>
> Konrad.

-- 
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


java interop question

2011-02-02 Thread clwham...@gmail.com
I am doing some prototyping with the event processing framework Esper
(http://esper.codehaus.org/) and I'm running up against my ignorance
of clojure/java interop. I would like to create a java bean in clojure
that is visible to the Esper runtime; I found some sample Java code
that I clojurized as follows:

(ns cepdemo.core
  (:import [com.espertech.esper.client
Configuration UpdateListener
EPServiceProviderManager EPRuntime]))

(defrecord Tick [symbol price timestamp])

(defn generate-random-tick [runtime]
  (let [price (rand-int 10)
timestamp (java.util.Date.)
symbol "AAPL"
tick (Tick. symbol price timestamp)]
(print "Sending tick: " tick)
(.sendEvent runtime tick)))

(defn cep-listener []
  (proxy [UpdateListener] []
(update [new-data old-data]
(print "event received: " new-data

(defn config []
  (let [cep-config (Configuration.)]
(.addEventType cep-config "StockTick" (.getName Tick))
(let [cep-sp (EPServiceProviderManager/getProvider "myCEPEngine"
cep-config)
  cep-rt (.getEPRuntime cep-sp)
  cep-admin (.getEPAdministrator cep-sp)
  cep-statement
  (.createEPL cep-admin
  "select * from
StockTick(symbol='AAPL').win:length(2) having avg(price) > 6.0")]
  (.addListener cep-statement cep-listener)
  (doseq [i (range 10)]
(generate-random-tick cep-rt)

The error I get is:
Property named 'symbol' is not valid in any stream [select * from
StockTick(symbol='AAPL').win:length(2) having avg(price) > 6.0]

from which I conclude that defrecord may not be the way to create a
java bean. Do I need to use gen-class?

-- 
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


Re: java interop question

2011-02-03 Thread clwham...@gmail.com
Thanks for the tip on how to express a java bean -- that appears to
only be part of the problem; I still have the error I posted above.
But I'm going to keep flailing at it.

On Feb 2, 10:11 am, Ken Wesson  wrote:
> On Wed, Feb 2, 2011 at 11:15 AM, clwham...@gmail.com
>
>  wrote:
> > I am doing some prototyping with the event processing framework Esper
> > (http://esper.codehaus.org/) and I'm running up against my ignorance
> > of clojure/java interop. I would like to create a java bean in clojure
> > that is visible to the Esper runtime; I found some sample Java code
> > that I clojurized as follows:
>
> > (ns cepdemo.core
> >  (:import [com.espertech.esper.client
> >            Configuration UpdateListener
> >            EPServiceProviderManager EPRuntime]))
>
> > (defrecord Tick [symbol price timestamp])
>
> ...
>
> > The error I get is:
> > Property named 'symbol' is not valid in any stream [select * from
> > StockTick(symbol='AAPL').win:length(2) having avg(price) > 6.0]
>
> > from which I conclude that defrecord may not be the way to create a
> > java bean. Do I need to use gen-class?
>
> I'd try first to make Tick bean-ish with
>
> (definterface ITick
>   (getSymbol [this])
>   (setSymbol [this y])
>   (getPrice [this])
>   (setPrice [this y])
>   (getTimeStamp [this])
>   (setTimeStamp [this y]))
>
> (defrecord Tick [symbol price timestamp]
>   ITick
>     (getSymbol [this] symbol)
>     (setSymbol [this] (throw (UnsupportedOperationException.)))
>     (getPrice [this] price)
>     (setPrice [this] (throw (UnsupportedOperationException.)))
>     (getTimeStamp [this] timestamp)
>     (setTimeStamp [this] (throw (UnsupportedOperationException.)))
>
> Tell the external tool that the bean properties are Symbol, Price, and
> TimeStamp (rather than symbol, price, and timestamp) and unless it
> tries to mutate your Ticks it ought to work.
>
> Of course, you might also consider making a defbean macro that wraps
> defrecord and automates the above. :)

-- 
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


Re: java interop question

2011-02-04 Thread clwham...@gmail.com
Yes, Ken's original suggestion was correct -- the clojure code had to
look like a real java bean. It works perfectly now, so thanks!

On Feb 3, 3:55 pm, Stuart Sierra  wrote:
> I don't know what "select * from StockTick(symbol=..." is doing, but it
> looks like the error is coming from the library handling that query, not
> Clojure.
>
> -Stuart Sierra
> clojure.com

-- 
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