Re: [ANN] Clojure 1.7.0-alpha2
Oops, I skipped the volatile keyword while reading the code snippet. Sorry :) Luc P. No, it means exactly the same thing as volatile in Java (and is implemented in the Volatile Java class which holds a single volatile field). Basically a volatile box since a field must exist inside a class. The semantics are the same as Java - writes are guaranteed to be seen by subsequent reads on any thread (that property is not guaranteed by a non-volatile field). vswap! on a volatile is syntactically similar to swap! on an atom but without the atomicity guarantees. That is, vswap! consists of a read followed by a write but this is non-transactional so another thread could change the value in between. In other words: don't use this unless you can enforce thread isolation or safety through other means. Thus, volatiles are dangerous *by default*, unlike every other stateful thing in Clojure. Some stateful transducers use volatiles for performance and provide thread isolation via how they are constructed and used. On Tuesday, September 9, 2014 12:06:36 PM UTC-5, Luc wrote: The keyword has different meaning depending on the language and context. Most of the time to prevent optimizations by the compiler to insure write ordering and some consistent view (Java use). Not here. It's meant to warn that nothing is guaranteed, no synchronization, no consistent view. It should be kept local (no leak outside of a narrow scope) and certainly not shared by multiple threads. Luc P. Excuse my ignorance but does volatile! have anything to do with Java's volatile keyword? Is there any relation at all? I'm not suggesting a name change, but it can be confusing coming from that angle. Maybe a blurb in the doc string? -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clo...@googlegroups.com javascript: Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+u...@googlegroups.com javascript: For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+u...@googlegroups.com javascript:. For more options, visit https://groups.google.com/d/optout. -- Luc Prefontainelprefo...@softaddicts.ca javascript: sent by ibisMail! -- 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 --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout. -- Softaddictslprefonta...@softaddicts.ca sent by ibisMail from my ipad! -- 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 --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: [ANN] Clojure 1.7.0-alpha2
I thereby promise to not use my mobile phone ever again to access github :) Luc P. Oops, I skipped the volatile keyword while reading the code snippet. Sorry :) Luc P. No, it means exactly the same thing as volatile in Java (and is implemented in the Volatile Java class which holds a single volatile field). Basically a volatile box since a field must exist inside a class. The semantics are the same as Java - writes are guaranteed to be seen by subsequent reads on any thread (that property is not guaranteed by a non-volatile field). vswap! on a volatile is syntactically similar to swap! on an atom but without the atomicity guarantees. That is, vswap! consists of a read followed by a write but this is non-transactional so another thread could change the value in between. In other words: don't use this unless you can enforce thread isolation or safety through other means. Thus, volatiles are dangerous *by default*, unlike every other stateful thing in Clojure. Some stateful transducers use volatiles for performance and provide thread isolation via how they are constructed and used. On Tuesday, September 9, 2014 12:06:36 PM UTC-5, Luc wrote: The keyword has different meaning depending on the language and context. Most of the time to prevent optimizations by the compiler to insure write ordering and some consistent view (Java use). Not here. It's meant to warn that nothing is guaranteed, no synchronization, no consistent view. It should be kept local (no leak outside of a narrow scope) and certainly not shared by multiple threads. Luc P. Excuse my ignorance but does volatile! have anything to do with Java's volatile keyword? Is there any relation at all? I'm not suggesting a name change, but it can be confusing coming from that angle. Maybe a blurb in the doc string? -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clo...@googlegroups.com javascript: Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+u...@googlegroups.com javascript: For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+u...@googlegroups.com javascript:. For more options, visit https://groups.google.com/d/optout. -- Luc Prefontainelprefo...@softaddicts.ca javascript: sent by ibisMail! -- 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 --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout. -- Softaddictslprefonta...@softaddicts.ca sent by ibisMail from my ipad! -- 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 --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout. -- Softaddictslprefonta...@softaddicts.ca sent by ibisMail from my ipad! -- 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 --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from
[ANN] Jet - Jetty9 wrapper (ring, websocket, http client)
Jet [1] is a lightweight library for using Jetty9 from clojure. Jetty9 is interesting (compared to 7 or 8) mostly due to the fact that its core has been rewritten to take advantage of Async IO and it brings first class support for WebSocket among other nice things. There's an old'ish post that describes some of the new things here: https://webtide.com/jetty-9-updated-websocket-api/ This library tries to make all this accesible from clojure, using core.async interfaces whenever async comes into play. It currently includes: * a drop in replacement adapter for ring apps * a ring extension to do async responses via a core.async channel * another ring extension to do chunked transfers when the response :body is a core.async channel (compatible with the previously described extension) * WebSocket server support * a full featured WebSocket client (jvm based), with an api that's nearly identical to the server side of WS * a HTTP client, very similar to clj-http, with streaming support, connection pooling, cookies support, etc, etc... The README has more info and examples: https://github.com/mpenet/jet/blob/master/README.md Codox Documentation: http://mpenet.github.io/jet/ 1. https://github.com/mpenet/jet -- 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 --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: [ANN] Async Ring 0.1.0
Hi David, It's excellent to see this tools and others like it (eg: Max Penet's Jet - https://github.com/mpenet/jet)! The more ideas we get in this area, the better all the tooling will become. There are a few things I'd like to clear about the notion of asynchronous processing in general and the comparison to Pedestal specifically. I think in discussing the details, everyone will come out ahead. 1. The interceptor queue is merely the current path. In your comparison, you state that Pedestal forces Interceptors to be placed in a queue for execution. This isn't entirely accurate. You can arbitrarily specify the order of interceptors (imagine a graph of connected interceptors). The interceptor queue is merely the current path of interceptors executing (or scheduled to execute). Any interceptor can dynamically add more interceptors to that path during execution. The interceptor is the core abstraction from which all things are built in Pedestal - it's the only abstraction. I have written a predicate dispatch Interceptor that allows open/extensible rules to route requests - with the interceptor you can create a Liberator-style system, QoS-style routing, or anything of similar nature. I also have written a cond-interceptor, that does a one-off conditional dispatch. Both will probably land in Pedestal's base interceptors at some point. 2. One notion of concurrency in Pedestal is managed with core.async In your comparison, you state the concurrency mechanism is pure functions. This is also not accurate. The concurrency mechanism to signal to the container you're going async, is to have an interceptor return a core.async channel (we'll call this the context channel). In the application code, you continue forward using core.async. Once you want the web-server to resume processing your request, you place a context (a map) on the context channel (sometimes others refer to the context channel as the resume channel). I think what you're getting at is there's a notion of interceptors for entering, leaving, and handling errors - which I'll address in the next item. 3. There are two notions of async behavior - Pedestal delivers both. One notion of async behavior was discussed above - your application gives up the current/main execution thread, continues execution on another thread, and later gets resumed on one of the main execution threads. To truly do this in an asynchronous manner, one must separate the notion of request and response. This is why Pedestal uses a context, and why function composition and coupling request and response will limit (or prevent) async capabilities. To be async in this sense, you must never block the main execution thread at any point. Another notion of async behavior occurs when placing the actual response on the wire - most applications do so in a blocking manner using standard Java IO. Recently, Pedestal added the capability to do this in a non-blocking, asynchronous manner using NIO. That is, in Pedestal, if your response body is a ByteBuffer or a ReadableByteChannel, and you're running on a container that supports NIO (Jetty), it will use NIO through the entire container when handling the request. If a developer can't get manage to return a ByteBuffer or a ReadableByteChannel (or if the developer is on a container that doesn't support NIO), they can still return a core.async Channel and Pedestal will perform the standard IO response within a `go`. Using a core.async Channel has limits, and NIO should be preferred if available. 4. Routing and Extension Two pieces missing from the comparison were routing and general extension mechanisms. I won't dive too deep into the routing piece (it's data driven, can be programmatically consumed or generated, can be read off of the wire or out of a DB, etc), but I do want to touch upon the extension piece a bit. In Pedestal, all the major integration points are backed by protocols - including the async handling discussed above. This allows developers to shape and extend Pedestal to fit any operational need. Routing is also backed by protocols, which enables a developer to shape how routing endpoints should be interrupted. Pedestal's use of protocols throughout has proven extremely beneficial as I've tackled complex web systems. I hope this helps clarify some topics and I look forward to further discussion! Cheers, Paul -- 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 --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving
Extending clj-time
I have a type that's an extended date-time. It can be constructed with the usual year, month, day parameters but (for legacy reasons) the month can be overloaded to mean extra things. E.g. a month of 21 means 'spring', 33 means 'third quarter'. I want to construct this type in a way that it preserves that information (so, for example, it can print itself appropriately), but that has comparison and equality with other dates. I want to extend clj-time somehow. My first thought is write a type that construct with the given arguments and implements the clj-time/DateTimeProtocol, converting whenever required (I don't need high performance). (defprotocol IWeirdDate (as-date [this]) (pp [this])) (defrecord WeirdDate [year month day] IWeirdDate (pp [this] (condp = month 21 (str Spring year) 33 (str Third Quarter of year) (str (as-date this (as-date [this] (let [[y m d] (condp = month 21 [year 3 day] 33 [year 7 1] ; third quarter ; ... others ; default [year month day])] (clj-time/date-time y m d))) clj-time/DateTimeProtocol (clj-time/year [this] (clj-time/year (as-date this))) (clj-time/month [this] (clj-time/month (as-date this))) (clj-time/day [this] (clj-time/day (as-date this))) ; ... and the rest of DateTimeProtocol ) Is this the right way to do this? Could I somehow make this implicit and avoid re-writing the DateTimeProtocol implementations? Cheers Joe -- 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 --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
defrecord - CompilerException to referring record defined at other namespace
I have records defined at datatypes.clj: ```clojure (ns defrecord-example1.datatypes) (defrecord Record1 [f1]) (defrecord Record2 [f1 f2 f3]) ;; this is working at repl (def m-inside1 {Record1 (fn [] ({:a A})) Record2 (fn [] ({:n B}))}) And using at core.clj : ```clojure (ns defrecord-example1.core (:require [defrecord-example1.datatypes :as dt])) ``` ;; error at repl ;; CompilerException java.lang.RuntimeException: No such var: dt/Record1, compiling:(defrecord_example1\core.clj:7:1) (def m-in-core1 {dt/Record1 (fn [] ({:a A})) dt/Record2 (fn [] ({:n B}))}) ``` Any one can help on this ? My project.clj: ``` clojure (defproject defrecord-example1 0.1.0-SNAPSHOT :description FIXME: write description :url http://example.com/FIXME; :license {:name Eclipse Public License :url http://www.eclipse.org/legal/epl-v10.html} :dependencies [[org.clojure/clojure 1.6.0]]) ``` -- 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 --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: Extending clj-time
On 10 September 2014 at 15:42:01, j...@afandian.com (j...@afandian.com) wrote: Is this the right way to do this? Yes. Could I somehow make this implicit and avoid re-writing the DateTimeProtocol implementations? There's no way around implementing the DateTimeProtocol functions you need for your data structure but you can make some of your function delegate to the original clj-time ones (e.g. by instantiating a DateTime or another class and passing them on to clj-time). -- @michaelklishin, github.com/michaelklishin -- 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 --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: [ANN] Clojure 1.7.0-alpha2
So to summarize, Clojure's volatile provides synchronization across threads but does not provide atomaticity with vswap!. So, as a follow up question, then why would the creation of a volatile be dangerous but creating an atom isn't? (Hence the exclamation point in the name volatile!) -- 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 --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: [ANN] Clojure 1.7.0-alpha2
When I say synchronization, I specifically mean writes are guaranteed to be seen by subsequent reads on any thread* *as Alex said. On Wednesday, September 10, 2014 9:37:09 AM UTC-4, Brent Millare wrote: So to summarize, Clojure's volatile provides synchronization across threads but does not provide atomaticity with vswap!. So, as a follow up question, then why would the creation of a volatile be dangerous but creating an atom isn't? (Hence the exclamation point in the name volatile!) -- 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 --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: [ANN] Clojure 1.7.0-alpha2
Usually that's called visibility. Atoms are *not* subject to race conditions if swap! is called from multiple threads (the state of the atom will not change while the update function is being applied). The atom is thus safe to be used from multiple threads. Volatiles *are* subject to race conditions with vswap! is called from multiple threads (the state of the volatile may change while the update function is being applied). The volatile is thus dangerous and safety is derived from how it's used. On Wednesday, September 10, 2014 8:44:27 AM UTC-5, Brent Millare wrote: When I say synchronization, I specifically mean writes are guaranteed to be seen by subsequent reads on any thread* *as Alex said. On Wednesday, September 10, 2014 9:37:09 AM UTC-4, Brent Millare wrote: So to summarize, Clojure's volatile provides synchronization across threads but does not provide atomaticity with vswap!. So, as a follow up question, then why would the creation of a volatile be dangerous but creating an atom isn't? (Hence the exclamation point in the name volatile!) -- 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 --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: defrecord - CompilerException to referring record defined at other namespace
Is datatypes.clj at src/defrecord_example1/datatypes.clj ? (note _, not - in directory name) On Wednesday, September 10, 2014 6:01:25 AM UTC-5, Bin Li wrote: I have records defined at datatypes.clj: ```clojure (ns defrecord-example1.datatypes) (defrecord Record1 [f1]) (defrecord Record2 [f1 f2 f3]) ;; this is working at repl (def m-inside1 {Record1 (fn [] ({:a A})) Record2 (fn [] ({:n B}))}) And using at core.clj : ```clojure (ns defrecord-example1.core (:require [defrecord-example1.datatypes :as dt])) ``` ;; error at repl ;; CompilerException java.lang.RuntimeException: No such var: dt/Record1, compiling:(defrecord_example1\core.clj:7:1) (def m-in-core1 {dt/Record1 (fn [] ({:a A})) dt/Record2 (fn [] ({:n B}))}) ``` Any one can help on this ? My project.clj: ``` clojure (defproject defrecord-example1 0.1.0-SNAPSHOT :description FIXME: write description :url http://example.com/FIXME; :license {:name Eclipse Public License :url http://www.eclipse.org/legal/epl-v10.html} :dependencies [[org.clojure/clojure 1.6.0]]) ``` -- 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 --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: [ANN] Clojure 1.7.0-alpha2
As an example, if I have: (def a (atom 5)) and execute these from different threads: T1: (swap! a * 2) T2: (swap! a + 2) it depends on timing which update runs first so you can get either 12 (T1 then T2) or 14 (T2 then T1). But it must be one of those results. With a volatile, the reads and writes can interleave in a variety of ways (I think this is all of them as the JMM will guarantee that the read happens-before the write for each T): T1 read, T1 write, T2 read, T2 write: v = 12 T1 read, T2 read, T1 write, T2 write: v = 7 (T1 write is effectively lost) T1 read, T2 read, T2 write, T1 write: v = 10 (T2 write is effectively lost) T2 read, T2 write, T1 read, T1 write: v = 14 T2 read, T1 read, T2 write, T1 write: v = 10 (T2 write is effectively lost) T2 read, T1 read, T1 write, T2 write: v = 7 (T1 write is effectively lost) Non-atomic updates are fine if you have thread isolation though, as there is no chance for interleaving as above. The atomicity you get from atoms must be provided as a consequence of program construction in that case. There are a very small set of cases where non-atomic multi-threaded updates as above are actually valid. [The racy single-check idiom used for hash caching is one - that's a special case where the update function and initial value are identical so threads race to produce the *same* value, and all interleavings produce the same result. This technique used in several places in Clojure for hash caching.] Also note that the default in Java (non-volatile, non-synchronized fields) is even worse than this - they provide neither visibility nor atomicity, so different threads may not even seen writes by other threads at all (not to mention things like long-tearing). On Wednesday, September 10, 2014 9:19:33 AM UTC-5, Alex Miller wrote: Usually that's called visibility. Atoms are *not* subject to race conditions if swap! is called from multiple threads (the state of the atom will not change while the update function is being applied). The atom is thus safe to be used from multiple threads. Volatiles *are* subject to race conditions with vswap! is called from multiple threads (the state of the volatile may change while the update function is being applied). The volatile is thus dangerous and safety is derived from how it's used. On Wednesday, September 10, 2014 8:44:27 AM UTC-5, Brent Millare wrote: When I say synchronization, I specifically mean writes are guaranteed to be seen by subsequent reads on any thread* *as Alex said. On Wednesday, September 10, 2014 9:37:09 AM UTC-4, Brent Millare wrote: So to summarize, Clojure's volatile provides synchronization across threads but does not provide atomaticity with vswap!. So, as a follow up question, then why would the creation of a volatile be dangerous but creating an atom isn't? (Hence the exclamation point in the name volatile!) -- 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 --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: Extending clj-time
Thanks. Sorry this is turning into a bit of a brain dump. I've created my record that decorates the original type: (defprotocol IWeirdDate (as-date [this]) (pp [this])) (defrecord WeirdDate [year month day] IWeirdDate (pp [this] (condp = month 21 (str Spring year) 33 (str Third Quarter of year) (str (as-date this)) )) (as-date [this] (let [[y m d] (condp = month 21 [year 3 day] ; spring 33 [year 7 1] ; third quarter ; ... others ; default [year month day])] (clj-time/date-time y m d))) clj-time/DateTimeProtocol (clj-time/year [this] (clj-time/year (as-date this))) (month [this] (clj-time/month (as-date this))) (day [this] (clj-time/day (as-date this))) (day-of-week [this] (clj-time/day-of-week (as-date this))) (hour [this] (clj-time/hour (as-date this))) (minute [this] (clj-time/minute (as-date this))) (sec [this] (clj-time/sec (as-date this))) (second [this] (clj-time/second (as-date this))) (milli [this] (clj-time/milli (as-date this))) (clj-time/after? [this that] (clj-time/after? (as-date this) that)) (before? [this that] (clj-time/before? (as-date this) that))) And I want to be able to use some functions in both directions: (def x (WeirdDate. 1986 5 2)) (def y (clj-time/date-time 2014 5 2)) (prn (clj-time/before? x y)) (prn (clj-time/after? y x)) The first one works, the second one fails with `ClassCastException: WeirdDate cannot be cast to org.joda.time.ReadableInstant`. I think this is because of a type hint which is present on the on the org.joda.time.DateTime implementation[0] of the DateTimeProtocol but not on the protocol: (after? [this ^ReadableInstant that] (.isAfter this that)) So I add the ReadableInstant methods to the WeirdDate record: ReadableInstant (.equals [this readableInstant] (.equals (as-date this) readableInstant)) (.get [this type] (get (as-date this) type)) (.getChronology [this] (.getChronology (as-date this))) (.getMillis [this] (.getMillis (as-date this))) (.getZone [this] (.getZone (as-date this))) (.hashCode [this] (.hashCode (as-date this))) (.isAfter [this instant] (.isAfter (as-date this) instant)) (.isBefore [this instant] (.isBefore (as-date this) instant)) (.isEqual [this instant] (.isEqual (as-date this) instant)) (.isSupported [this field] (.isSupported (as-date this) field)) (.toInstant [this] (.toInstant (as-date this))) (.toString [this] (.toString (as-date this))) Now I get `IllegalArgumentException: Must hint overloaded method: get`. So I annotate according to the Java interface[1]: ReadableInstant (.equals ^boolean [this ^Object readableInstant] (.equals (as-date this) readableInstant)) (.get ^int [this ^DateTimeFieldType type] (get (as-date this) type)) (.getChronology ^Chronology [this] (.getChronology (as-date this))) (.getMillis ^long [this] (.getMillis (as-date this))) (.getZone ^DateTimeZone [this] (.getZone (as-date this))) (.hashCode ^int [this] (.hashCode (as-date this))) (.isAfter ^boolean [this ^ReadableInstant instant] (.isAfter (as-date this) instant)) (.isBefore ^boolean [this ^ReadableInstant instant] (.isBefore (as-date this) instant)) (.isEqual ^boolean [this ^ReadableInstant instant] (.isEqual (as-date this) instant)) (.isSupported ^boolean [this ^DateTimeFieldType field] (.isSupported (as-date this) field)) (.toInstant ^Instant [this] (.toInstant (as-date this))) (.toString ^String [this] (.toString (as-date this))) Again, `IllegalArgumentException: Must hint overloaded method: get`. As far as I know this is all correctly annotated, although I'm not sure about the return types, as records aren't mentioned in the documentation[2] but it does say For function return values, the type hint can be placed before the arguments vector. Any ideas? [0] https://github.com/clj-time/clj-time/blob/v0.7.0/src/clj_time/core.clj#L126 [1] http://joda-time.sourceforge.net/apidocs/org/joda/time/ReadableInstant.html [2] http://clojure.org/java_interop#Java Interop-Type Hints -- 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 --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options,
[ANN] Strap 0.1.0
Strap is a faster Clojure project builder https://github.com/runexec/strap $ time strap.js my-project om compojure prismatic/om-tools secretary https://clojars.org/repo/prismatic/om-tools/maven-metadata.xml https://clojars.org/repo/om/om/maven-metadata.xml https://clojars.org/repo/compojure/compojure/maven-metadata.xml https://clojars.org/repo/secretary/secretary/maven-metadata.xml real0m1.204s user0m0.497s sys 0m0.053s $ cat my-project/project.clj (defproject my-project 0.1.0-SNAPSHOT :description FIXME: write this! :url http://example.com/FIXME; :dependencies [[org.clojure/clojure 1.6.0] [org.clojure/core.async 0.1.338.0-5c5012-alpha] [prismatic/om-tools 0.3.3] [om 0.7.1] [compojure 1.1.9] [secretary 1.2.1]] :plugins [[lein-cljsbuild 1.0.4-SNAPSHOT]] :source-paths [src] :cljsbuild { :builds [{:id strap :source-paths [src] :compiler {:output-to strap.js :output-dir out :target :nodejs :optimizations :simple}}]}) $ ls -R my-project/ my-project/: src/ project.clj my-project/src: my_project/ my-project/src/my_project: core.clj -- 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 --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: [ANN] Clojure 1.7.0-alpha2
When I explain to new Clojurists what the ! means, I explain that it calls attention to a mutation function that is unsafe to call inside a transaction. Many programmers coming from Scheme are used to thinking of ! as meaning *anything* involving mutation, but that's not the case in the Clojure. This more subtle distinction (that it needs to be unsafe in a transaction) clarifies why swap! has an exclamation point, but ref-set does not, even though both involve mutation. Assuming my description of Clojure's use of ! is correct (and if I'm wrong and am not thinking of some important counterexample, please let me know), then it doesn't really make sense for volatile to be called volatile!. Yes, volatiles are less safe than atoms, but the creation of the volatile itself is perfectly fine to occur in a transation. Only vswap! and vreset! require the exclamation point. I'd go one step further and question why we need new names vswap! and vreset!, when swap! and reset! are perfectly clear and sufficient. As Clojure has become increasingly interface and protocol-driven, it makes less and less sense to have a proliferation of function names for the same behavior on different underlying objects. vswap!, for example, is exactly the semantics you'd expect if you overloaded swap!, describing it as a function that can be applied to both atoms and volatiles, where volatiles are the more thread-unsafe, less atomic, alternative, because that's the nature of the underlying box. --Mark -- 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 --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: [ANN] Clojure 1.7.0-alpha2
That's also my explanation about the use of exclamation mark. IMHO, +1 for volatile, without !. Plínio On Wed, Sep 10, 2014 at 1:05 PM, Mark Engelberg mark.engelb...@gmail.com wrote: When I explain to new Clojurists what the ! means, I explain that it calls attention to a mutation function that is unsafe to call inside a transaction. Many programmers coming from Scheme are used to thinking of ! as meaning *anything* involving mutation, but that's not the case in the Clojure. This more subtle distinction (that it needs to be unsafe in a transaction) clarifies why swap! has an exclamation point, but ref-set does not, even though both involve mutation. Assuming my description of Clojure's use of ! is correct (and if I'm wrong and am not thinking of some important counterexample, please let me know), then it doesn't really make sense for volatile to be called volatile!. Yes, volatiles are less safe than atoms, but the creation of the volatile itself is perfectly fine to occur in a transation. Only vswap! and vreset! require the exclamation point. I'd go one step further and question why we need new names vswap! and vreset!, when swap! and reset! are perfectly clear and sufficient. As Clojure has become increasingly interface and protocol-driven, it makes less and less sense to have a proliferation of function names for the same behavior on different underlying objects. vswap!, for example, is exactly the semantics you'd expect if you overloaded swap!, describing it as a function that can be applied to both atoms and volatiles, where volatiles are the more thread-unsafe, less atomic, alternative, because that's the nature of the underlying box. --Mark -- 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 --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout. -- 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 --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: Extending clj-time
I just noticed that the ReadableInstant[0] interface is generic, extending ComparableT [1]. Is it possible to implement a generic interface with a defrecord? [0] http://joda-time.sourceforge.net/apidocs/org/joda/time/ReadableInstant.html [1] http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/Comparable.html On Wednesday, September 10, 2014 4:15:51 PM UTC+1, j...@afandian.com wrote: Thanks. Sorry this is turning into a bit of a brain dump. I've created my record that decorates the original type: (defprotocol IWeirdDate (as-date [this]) (pp [this])) (defrecord WeirdDate [year month day] IWeirdDate (pp [this] (condp = month 21 (str Spring year) 33 (str Third Quarter of year) (str (as-date this)) )) (as-date [this] (let [[y m d] (condp = month 21 [year 3 day] ; spring 33 [year 7 1] ; third quarter ; ... others ; default [year month day])] (clj-time/date-time y m d))) clj-time/DateTimeProtocol (clj-time/year [this] (clj-time/year (as-date this))) (month [this] (clj-time/month (as-date this))) (day [this] (clj-time/day (as-date this))) (day-of-week [this] (clj-time/day-of-week (as-date this))) (hour [this] (clj-time/hour (as-date this))) (minute [this] (clj-time/minute (as-date this))) (sec [this] (clj-time/sec (as-date this))) (second [this] (clj-time/second (as-date this))) (milli [this] (clj-time/milli (as-date this))) (clj-time/after? [this that] (clj-time/after? (as-date this) that)) (before? [this that] (clj-time/before? (as-date this) that))) And I want to be able to use some functions in both directions: (def x (WeirdDate. 1986 5 2)) (def y (clj-time/date-time 2014 5 2)) (prn (clj-time/before? x y)) (prn (clj-time/after? y x)) The first one works, the second one fails with `ClassCastException: WeirdDate cannot be cast to org.joda.time.ReadableInstant`. I think this is because of a type hint which is present on the on the org.joda.time.DateTime implementation[0] of the DateTimeProtocol but not on the protocol: (after? [this ^ReadableInstant that] (.isAfter this that)) So I add the ReadableInstant methods to the WeirdDate record: ReadableInstant (.equals [this readableInstant] (.equals (as-date this) readableInstant)) (.get [this type] (get (as-date this) type)) (.getChronology [this] (.getChronology (as-date this))) (.getMillis [this] (.getMillis (as-date this))) (.getZone [this] (.getZone (as-date this))) (.hashCode [this] (.hashCode (as-date this))) (.isAfter [this instant] (.isAfter (as-date this) instant)) (.isBefore [this instant] (.isBefore (as-date this) instant)) (.isEqual [this instant] (.isEqual (as-date this) instant)) (.isSupported [this field] (.isSupported (as-date this) field)) (.toInstant [this] (.toInstant (as-date this))) (.toString [this] (.toString (as-date this))) Now I get `IllegalArgumentException: Must hint overloaded method: get`. So I annotate according to the Java interface[1]: ReadableInstant (.equals ^boolean [this ^Object readableInstant] (.equals (as-date this) readableInstant)) (.get ^int [this ^DateTimeFieldType type] (get (as-date this) type)) (.getChronology ^Chronology [this] (.getChronology (as-date this))) (.getMillis ^long [this] (.getMillis (as-date this))) (.getZone ^DateTimeZone [this] (.getZone (as-date this))) (.hashCode ^int [this] (.hashCode (as-date this))) (.isAfter ^boolean [this ^ReadableInstant instant] (.isAfter (as-date this) instant)) (.isBefore ^boolean [this ^ReadableInstant instant] (.isBefore (as-date this) instant)) (.isEqual ^boolean [this ^ReadableInstant instant] (.isEqual (as-date this) instant)) (.isSupported ^boolean [this ^DateTimeFieldType field] (.isSupported (as-date this) field)) (.toInstant ^Instant [this] (.toInstant (as-date this))) (.toString ^String [this] (.toString (as-date this))) Again, `IllegalArgumentException: Must hint overloaded method: get`. As far as I know this is all correctly annotated, although I'm not sure about the return types, as records aren't mentioned in the documentation[2] but it does say For function return values, the type hint can be placed before the arguments vector. Any ideas? [0] https://github.com/clj-time/clj-time/blob/v0.7.0/src/clj_time/core.clj#L126 [1] http://joda-time.sourceforge.net/apidocs/org/joda/time/ReadableInstant.html [2] http://clojure.org/java_interop#Java Interop-Type Hints -- 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
Re: [ANN] Clojure 1.7.0-alpha2
I've also been explaining them the same way as Mark. On 10 September 2014 17:28, Plínio Balduino pbaldu...@gmail.com wrote: That's also my explanation about the use of exclamation mark. IMHO, +1 for volatile, without !. Plínio On Wed, Sep 10, 2014 at 1:05 PM, Mark Engelberg mark.engelb...@gmail.com wrote: When I explain to new Clojurists what the ! means, I explain that it calls attention to a mutation function that is unsafe to call inside a transaction. Many programmers coming from Scheme are used to thinking of ! as meaning *anything* involving mutation, but that's not the case in the Clojure. This more subtle distinction (that it needs to be unsafe in a transaction) clarifies why swap! has an exclamation point, but ref-set does not, even though both involve mutation. Assuming my description of Clojure's use of ! is correct (and if I'm wrong and am not thinking of some important counterexample, please let me know), then it doesn't really make sense for volatile to be called volatile!. Yes, volatiles are less safe than atoms, but the creation of the volatile itself is perfectly fine to occur in a transation. Only vswap! and vreset! require the exclamation point. I'd go one step further and question why we need new names vswap! and vreset!, when swap! and reset! are perfectly clear and sufficient. As Clojure has become increasingly interface and protocol-driven, it makes less and less sense to have a proliferation of function names for the same behavior on different underlying objects. vswap!, for example, is exactly the semantics you'd expect if you overloaded swap!, describing it as a function that can be applied to both atoms and volatiles, where volatiles are the more thread-unsafe, less atomic, alternative, because that's the nature of the underlying box. --Mark -- 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 --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout. -- 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 --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout. -- 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 --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: Extending clj-time
On 10 September 2014 at 21:11:06, j...@afandian.com (j...@afandian.com) wrote: I just noticed that the ReadableInstant[0] interface is generic, extending Comparable [1]. Is it possible to implement a generic interface with a defrecord? Type parameters in generics do not exist at runtime, they are purely a javac feature. So yes, you can reify a generic interface, just ignore the type variable(s). -- @michaelklishin, github.com/michaelklishin -- 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 --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: Clojure/conj Speakers and Opportunity Grants
Will the videos be uploaded somewhere? On Tue, Sep 9, 2014 at 5:02 PM, Alex Miller a...@puredanger.com wrote: *Clojure/conj - Nov 20-22, 2014* Warner Theater - Washington, DC http://clojure-conj.org/ Tickets https://www.eventbrite.com/e/clojureconj-2014-tickets-12388174363: $350 Training http://www.eventbrite.com/e/dc-clojure-training-intro-to-clojure-datomic-tickets-1268741: Intro to Clojure (2 days, $795), Intro to Datomic (1 day, $395) The Clojure/conj *speakers and talks* have been announced http://clojure-conj.org/speakers: - Brian Goetz - *Keynote* by the Java Language Architect - Rich Hickey - *Transducers* - Anna Pawlicka - *Om nom nom nom* - Ashton Kemerling - *Generative Integration Tests* - Bozhidar Batsov - *The evolution of the Emacs tooling for Clojure* - Colin Fleming - *Cursive: a different type of IDE* - David Pick - *Building a Data Pipeline with Clojure and Kafka* - Ghadi Shayban - *JVM Creature Comforts* - Glenn Vanderburg - *Cló: The Algorithms of TeX in Clojure* - Jeanine Adkisson - *Variants are Not Unions* - Julian Gamble - *Applying the paradigms of core.async in ClojureScript* - Lucas Cavalcanti, Edward Wible - *Exploring Four Hidden Superpowers of Datomic* - Michał Marczyk - *Persistent Data Structures for Special Occasions* - Nathan Herzing, Chris Shea - *Helping voters with Pedestal, Datomic, Om and core.async* - Steve Miner - *Generating Generators* - Steven Yi - *Developing Music Systems on the JVM with Pink and Score* - Paul deGrandis - *Unlocking Data-Driven Systems* - Zach Oakes - *Making Games at Runtime with Clojure* - Zach Tellman - *Always Be Composing* Clojure/conj is also pleased to announce our first ever *Opportunity Grant* program to support community members who would not otherwise be able to attend the conference for financial reasons. For more information on applying, see http://clojure-conj.org/grants. We hope you can join us at Clojure/conj 2014! It's going to be a great show. - Alex Miller, Lynn Grogan, and Cognitect -- 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 --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout. -- 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 --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: Clojure/conj Speakers and Opportunity Grants
Presumably yes, but I don't think that is finalized. On Wednesday, September 10, 2014 2:09:37 PM UTC-5, melipone wrote: Will the videos be uploaded somewhere? On Tue, Sep 9, 2014 at 5:02 PM, Alex Miller al...@puredanger.com javascript: wrote: *Clojure/conj - Nov 20-22, 2014* Warner Theater - Washington, DC http://clojure-conj.org/ Tickets https://www.eventbrite.com/e/clojureconj-2014-tickets-12388174363: $350 Training http://www.eventbrite.com/e/dc-clojure-training-intro-to-clojure-datomic-tickets-1268741: Intro to Clojure (2 days, $795), Intro to Datomic (1 day, $395) The Clojure/conj *speakers and talks* have been announced http://clojure-conj.org/speakers: - Brian Goetz - *Keynote* by the Java Language Architect - Rich Hickey - *Transducers* - Anna Pawlicka - *Om nom nom nom* - Ashton Kemerling - *Generative Integration Tests* - Bozhidar Batsov - *The evolution of the Emacs tooling for Clojure* - Colin Fleming - *Cursive: a different type of IDE* - David Pick - *Building a Data Pipeline with Clojure and Kafka* - Ghadi Shayban - *JVM Creature Comforts* - Glenn Vanderburg - *Cló: The Algorithms of TeX in Clojure* - Jeanine Adkisson - *Variants are Not Unions* - Julian Gamble - *Applying the paradigms of core.async in ClojureScript* - Lucas Cavalcanti, Edward Wible - *Exploring Four Hidden Superpowers of Datomic* - Michał Marczyk - *Persistent Data Structures for Special Occasions* - Nathan Herzing, Chris Shea - *Helping voters with Pedestal, Datomic, Om and core.async* - Steve Miner - *Generating Generators* - Steven Yi - *Developing Music Systems on the JVM with Pink and Score* - Paul deGrandis - *Unlocking Data-Driven Systems* - Zach Oakes - *Making Games at Runtime with Clojure* - Zach Tellman - *Always Be Composing* Clojure/conj is also pleased to announce our first ever *Opportunity Grant* program to support community members who would not otherwise be able to attend the conference for financial reasons. For more information on applying, see http://clojure-conj.org/grants. We hope you can join us at Clojure/conj 2014! It's going to be a great show. - Alex Miller, Lynn Grogan, and Cognitect -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clo...@googlegroups.com javascript: Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+u...@googlegroups.com javascript: For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+u...@googlegroups.com javascript:. For more options, visit https://groups.google.com/d/optout. -- 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 --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: [ANN] Clojure 1.7.0-alpha2
On Wednesday, September 10, 2014 11:05:36 AM UTC-5, puzzler wrote: When I explain to new Clojurists what the ! means, I explain that it calls attention to a mutation function that is unsafe to call inside a transaction. Many programmers coming from Scheme are used to thinking of ! as meaning *anything* involving mutation, but that's not the case in the Clojure. This more subtle distinction (that it needs to be unsafe in a transaction) clarifies why swap! has an exclamation point, but ref-set does not, even though both involve mutation. I do not think there is a hard definition of what ! means as a suffix. Assuming my description of Clojure's use of ! is correct (and if I'm wrong and am not thinking of some important counterexample, please let me know), then it doesn't really make sense for volatile to be called volatile!. Yes, volatiles are less safe than atoms, but the creation of the volatile itself is perfectly fine to occur in a transaction. Only vswap! and vreset! require the exclamation point. The name is not going to change, sorry. I'd go one step further and question why we need new names vswap! and vreset!, when swap! and reset! are perfectly clear and sufficient. As Clojure has become increasingly interface and protocol-driven, it makes less and less sense to have a proliferation of function names for the same behavior on different underlying objects. vswap!, for example, is exactly the semantics you'd expect if you overloaded swap!, describing it as a function that can be applied to both atoms and volatiles, where volatiles are the more thread-unsafe, less atomic, alternative, because that's the nature of the underlying box. vswap! and vreset! do something similar in shape but different in meaning than swap! and reset! (they are non-atomic). As with all the stateful containers, the functions are specific to the container type (alter-var-root, alter, send, etc). --Mark -- 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 --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: [ANN] Async Ring 0.1.0
Hi Paul, Thanks for your feedback! I updated the comparison with pedestal when discussing the async queues to address this point. I am also really excited about Jet--I think that it would be a great combination with Spiral! One key difference in Spiral from Jet and Pedestal is that not only can you use core.async to make an async handler, but you can also make async middleware using core.async as well. On Wednesday, September 10, 2014 6:29:11 AM UTC-4, Paul deGrandis wrote: Hi David, It's excellent to see this tools and others like it (eg: Max Penet's Jet - https://github.com/mpenet/jet)! The more ideas we get in this area, the better all the tooling will become. There are a few things I'd like to clear about the notion of asynchronous processing in general and the comparison to Pedestal specifically. I think in discussing the details, everyone will come out ahead. 1. The interceptor queue is merely the current path. In your comparison, you state that Pedestal forces Interceptors to be placed in a queue for execution. This isn't entirely accurate. You can arbitrarily specify the order of interceptors (imagine a graph of connected interceptors). The interceptor queue is merely the current path of interceptors executing (or scheduled to execute). Any interceptor can dynamically add more interceptors to that path during execution. The interceptor is the core abstraction from which all things are built in Pedestal - it's the only abstraction. I have written a predicate dispatch Interceptor that allows open/extensible rules to route requests - with the interceptor you can create a Liberator-style system, QoS-style routing, or anything of similar nature. I also have written a cond-interceptor, that does a one-off conditional dispatch. Both will probably land in Pedestal's base interceptors at some point. 2. One notion of concurrency in Pedestal is managed with core.async In your comparison, you state the concurrency mechanism is pure functions. This is also not accurate. The concurrency mechanism to signal to the container you're going async, is to have an interceptor return a core.async channel (we'll call this the context channel). In the application code, you continue forward using core.async. Once you want the web-server to resume processing your request, you place a context (a map) on the context channel (sometimes others refer to the context channel as the resume channel). I think what you're getting at is there's a notion of interceptors for entering, leaving, and handling errors - which I'll address in the next item. 3. There are two notions of async behavior - Pedestal delivers both. One notion of async behavior was discussed above - your application gives up the current/main execution thread, continues execution on another thread, and later gets resumed on one of the main execution threads. To truly do this in an asynchronous manner, one must separate the notion of request and response. This is why Pedestal uses a context, and why function composition and coupling request and response will limit (or prevent) async capabilities. To be async in this sense, you must never block the main execution thread at any point. Another notion of async behavior occurs when placing the actual response on the wire - most applications do so in a blocking manner using standard Java IO. Recently, Pedestal added the capability to do this in a non-blocking, asynchronous manner using NIO. That is, in Pedestal, if your response body is a ByteBuffer or a ReadableByteChannel, and you're running on a container that supports NIO (Jetty), it will use NIO through the entire container when handling the request. If a developer can't get manage to return a ByteBuffer or a ReadableByteChannel (or if the developer is on a container that doesn't support NIO), they can still return a core.async Channel and Pedestal will perform the standard IO response within a `go`. Using a core.async Channel has limits, and NIO should be preferred if available. 4. Routing and Extension Two pieces missing from the comparison were routing and general extension mechanisms. I won't dive too deep into the routing piece (it's data driven, can be programmatically consumed or generated, can be read off of the wire or out of a DB, etc), but I do want to touch upon the extension piece a bit. In Pedestal, all the major integration points are backed by protocols - including the async handling discussed above. This allows developers to shape and extend Pedestal to fit any operational need. Routing is also backed by protocols, which enables a developer to shape how routing endpoints should be interrupted. Pedestal's use of protocols throughout has proven extremely beneficial as I've tackled complex web systems. I hope this helps clarify some topics and I look forward to further discussion! Cheers, Paul
Re: defrecord - CompilerException to referring record defined at other namespace
Yes , it is. Is it because that / is accessing the 'static' function/field ? so at core.clj: we can only have there constructors as follow ? dt/-Record1 dt/-Record2 dt/map-Record1 dt/map-Record2 On Wednesday, September 10, 2014 10:21:45 PM UTC+8, Alex Miller wrote: Is datatypes.clj at src/defrecord_example1/datatypes.clj ? (note _, not - in directory name) On Wednesday, September 10, 2014 6:01:25 AM UTC-5, Bin Li wrote: I have records defined at datatypes.clj: ```clojure (ns defrecord-example1.datatypes) (defrecord Record1 [f1]) (defrecord Record2 [f1 f2 f3]) ;; this is working at repl (def m-inside1 {Record1 (fn [] ({:a A})) Record2 (fn [] ({:n B}))}) And using at core.clj : ```clojure (ns defrecord-example1.core (:require [defrecord-example1.datatypes :as dt])) ``` ;; error at repl ;; CompilerException java.lang.RuntimeException: No such var: dt/Record1, compiling:(defrecord_example1\core.clj:7:1) (def m-in-core1 {dt/Record1 (fn [] ({:a A})) dt/Record2 (fn [] ({:n B}))}) ``` Any one can help on this ? My project.clj: ``` clojure (defproject defrecord-example1 0.1.0-SNAPSHOT :description FIXME: write description :url http://example.com/FIXME; :license {:name Eclipse Public License :url http://www.eclipse.org/legal/epl-v10.html} :dependencies [[org.clojure/clojure 1.6.0]]) ``` -- 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 --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: [ANN] Clojure 1.7.0-alpha2
I understand usage of volatiles are dangerous via vswap! but what about creation? Again relating to what you said, 'I asked Rich and he said making a volatile is as dangerous as any ! op.' On Wednesday, September 10, 2014 10:19:33 AM UTC-4, Alex Miller wrote: Usually that's called visibility. Atoms are *not* subject to race conditions if swap! is called from multiple threads (the state of the atom will not change while the update function is being applied). The atom is thus safe to be used from multiple threads. Volatiles *are* subject to race conditions with vswap! is called from multiple threads (the state of the volatile may change while the update function is being applied). The volatile is thus dangerous and safety is derived from how it's used. On Wednesday, September 10, 2014 8:44:27 AM UTC-5, Brent Millare wrote: When I say synchronization, I specifically mean writes are guaranteed to be seen by subsequent reads on any thread* *as Alex said. On Wednesday, September 10, 2014 9:37:09 AM UTC-4, Brent Millare wrote: So to summarize, Clojure's volatile provides synchronization across threads but does not provide atomaticity with vswap!. So, as a follow up question, then why would the creation of a volatile be dangerous but creating an atom isn't? (Hence the exclamation point in the name volatile!) -- 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 --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: [ANN] Clojure 1.7.0-alpha2
Perhaps me means dangerous as in it shouldn't be done causually, and that it could become a problematic habit if formed. On Wed, Sep 10, 2014 at 8:55 PM, Brent Millare brent.mill...@gmail.com wrote: I understand usage of volatiles are dangerous via vswap! but what about creation? Again relating to what you said, 'I asked Rich and he said making a volatile is as dangerous as any ! op.' On Wednesday, September 10, 2014 10:19:33 AM UTC-4, Alex Miller wrote: Usually that's called visibility. Atoms are *not* subject to race conditions if swap! is called from multiple threads (the state of the atom will not change while the update function is being applied). The atom is thus safe to be used from multiple threads. Volatiles *are* subject to race conditions with vswap! is called from multiple threads (the state of the volatile may change while the update function is being applied). The volatile is thus dangerous and safety is derived from how it's used. On Wednesday, September 10, 2014 8:44:27 AM UTC-5, Brent Millare wrote: When I say synchronization, I specifically mean writes are guaranteed to be seen by subsequent reads on any thread* *as Alex said. On Wednesday, September 10, 2014 9:37:09 AM UTC-4, Brent Millare wrote: So to summarize, Clojure's volatile provides synchronization across threads but does not provide atomaticity with vswap!. So, as a follow up question, then why would the creation of a volatile be dangerous but creating an atom isn't? (Hence the exclamation point in the name volatile!) -- 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 --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout. -- 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 --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: [ANN] Clojure 1.7.0-alpha2
I'm curious: how much faster are volatiles than atoms? -- 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 --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.