generator in Clojure
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
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
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
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
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
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