This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2017-11-28
Channels
- # adventofcode (2)
- # bangalore-clj (3)
- # beginners (171)
- # boot (28)
- # chestnut (3)
- # cljs-dev (20)
- # cljsjs (5)
- # clojure (280)
- # clojure-austin (1)
- # clojure-czech (1)
- # clojure-dev (9)
- # clojure-dusseldorf (2)
- # clojure-greece (20)
- # clojure-italy (6)
- # clojure-poland (16)
- # clojure-russia (7)
- # clojure-serbia (4)
- # clojure-sg (1)
- # clojure-spec (18)
- # clojure-uk (153)
- # clojurescript (57)
- # core-async (9)
- # cursive (21)
- # data-science (29)
- # datomic (18)
- # dirac (8)
- # docker (6)
- # duct (1)
- # emacs (50)
- # fulcro (15)
- # hoplon (56)
- # klipse (3)
- # leiningen (14)
- # lumo (1)
- # off-topic (5)
- # onyx (13)
- # other-languages (14)
- # pedestal (1)
- # perun (5)
- # planck (17)
- # re-frame (10)
- # reagent (2)
- # ring (1)
- # spacemacs (51)
- # sql (14)
- # test-check (16)
- # testing (1)
- # unrepl (93)
@bravilogy you don’t have to use it, but it prevents problems caused by global mutable singletons for application resources
@bravilogy at one moment in time, it’s running and you can use it to listen for connections, at another moment in time it isn’t
at one moment, it uses your handler to serve requests - at another moment it has a different handler, or different middleware
it’s a resource that has state
how do we avoid the situation where your server is still running and you want a different one?
it owns a resource that comes from the OS, what if you replace the global reference before stopping it?
component helps streamline these things, not just for your server, but for other things that own limited or unique resources, or manage a mutable internal state
including database connections, or user state, or even graphic windows
what if one mutable or resource owning thing needs to access another one? component helps
I meant OS windows, but yes, I also use it in cljs
@bravilogy another important usage is with tests - if your code is made to use components you don’t have to go redefining things in other namespaces to run tests - all you need to do is pass in data that is usable in the right way
@bravilogy I use it to control the websocket connection, and ensure that when things try to send to the server via websocket and the socket is closed, the messages get saved to send later, and that all the messages go through once the handshake is done
@bravilogy it ensures that the r/atoms that we create to manage state don’t have to be globals, instead they can be passed in from the component that initializes them on startup and owns them
if you have any public repos that show some simple usages, it would be very helpful to see please
similarly the router that acts on address bar changes - it gets passed routing rules via components, so that it doesn’t need to use globals and be tied to implementation details of the rest of hte app
@bravilogy sadly this is a closed source app - it’s the product we sell
but there are definitely examples of components out there, and they work on the same principles: if something is mutable or owns a limited resource, make sure it has a specific owner, isn’t global, and gets passed as an argument to things that need it
ok no problem 🙂 thanks for explanation. I think I’ll just need to see in action to actually understand what it does. I’m trying to understand it in other languages I know. perhaps it’s very Clojure related
how do the other languages work with limited or mutable resources?
maybe I should build this app from scratch and perhaps I’ll stumble upon the issue where I’ll have that ‘aah I see’ moment and use it
@bravilogy in my experience making something around a shared mutable global value, then trying to convert to use an explicit argument later, is a huge pain - it requires a lot of work
if you start with explicit arguments, it’s very easy to make it implicit (or even act like it’s global) in specific scopes if you later decide you need that
it’s not a two way thing - one way is easy, the other is hard
you mentioned the Websocket connection, so in simple terms do you mean that a mutable resource would be a global variable in js
for example, that holds the connection instance?
yes - and attached logic that ensures that if some other part of the app starts to send, and we are not connected, the message is queued for later
and some data unpacking / packing, stuff like that
but when you use component, it’s not global any more
which means if you need to test it, or use things differently later, you can just replace an argument
instead of rewriting code or faking other namespaces or such
the way I’ve seen it written in some examples, it was assigned to something.. like (def system (create-system))
where create-system
returned a component/system-map
or component/Lifecycle
that’s convenient during development but isn’t recommended in an actual application
your code should not rely on that global
but it’s very useful to have that global in your repl
ah so in a production - ready application, I would have something like
(defn -main [& _]
(let [config (config)]
(-> config
app-system
component/start)))
in fact, it’s recommended to only create that def in dev mode, and simply anonymously create the system in prod, without leaving any handle to it anywhere
exactly
component/start automates the start up order of the parts of the app, and makes sure they can see the other parts they need
that’s another advantage, instead of having to mentally juggle the order that things start up because of functional deps, it can just do a topo sort of the tree of deps
glad I could help!
maybe I will some day, heh
if you think about it, it’s providing the same advantages that fp does over imperative code, on an app architecture level
immutable arguments instead of mutable resources (or at least pretend, as much as you can 😄)
@bravilogy See if this simple example helps: https://github.com/seancorfield/clojure-webapp-live-demo/blob/master/src/webapp/core.clj -- it uses Component to start/stop a Jetty web server.
thank you @seancorfield
I know about Integer. and Float. Is there a clojure function of type "string -> number or nil" which does if full string parses to a number, return number else, return nil
I always use #(try (Long/parseLong %) (catch Exception _))
or Double/parseDouble as needed
I was under the impressions that exceptions are slow and should be avoided for simple tasks, but I hnever benchmaked it tobe sure
Exceptions are not slow
catching that exception and returning nil is much simpler than a reliable maybe-read-a-number
and honestly since I only do that parsing at system boundaries, it is guaranteed to never be in a hot loop
so I haven’t had to think about its performance
I’ve got this 6 page SPA that I decided to re-build using clj + cljs. At the moment I’m using Node.js + Elm
on that one and I’m so motivated to do it 😄 I’ve been playing around with clojure for a while now but haven’t built anything significant yet
if you think that your communication with the outside world is in a hot loop you need to optimize - statistically speaking it’s unlikely you shoudl be using clojure
is there a builtin for 'apply this function to last element of this vector' or is it a matter of peek, pop, and conj
is count on a vector guarnttted to be constant time ? https://clojuredocs.org/clojure.core/count says nothing
@qqq Here is the implementation of the method count() for objects of type PersistentVector in the Java source code for Clojure, which is the type that Clojure vectors are: https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/PersistentVector.java#L205-L207
That is the method that clojure.core/count calls when you call count on a Clojure vector, because PersistentVector implements the Counted Java interface (through several intermediate subclass/implements relationships that I won't bore you with unless you want to know).
you can see this in Clojure by using counted?
which indicates a coll can be counted in constant time
the fastest way to do this is going to be peep/pop, then transform, then push
So for probably all versions of Clojure up to 1.9, you are guaranteed it is constant time. Future versions? Only Rich Hickey knows 🙂
but really if you are asking this question, you are probably using the wrong data structure in the first place
if you’re doing something stack-like, use a list (and pop/peek/conj)
most of the time, it's just conj to end of vector, but occasionally I have to modify the last conjed token
well, I’d recommend: (defn transform-last [v f] (conj (pop v) (f (peek v))))
peek is definitely the fastest way to get the last element of a vector
I'm trying to download a dependency, jai_core, from here https://repository.jboss.org/nexus/content/repositories/thirdparty-releases/javax/media/jai-core/1.1.3/. I added the repository to my project.clj like this :repositories [[["jboss-third-party" "
. I still get an error message like this though Could not find artifact javax.media:jai_core:jar:1.1.3 in jboss-third-party (
You need to request jai-core
not jai_core
https://mvnrepository.com/artifact/javax.media/jai_core/1.1.3 ah, there's jai-core and jai_core 🙂
#?(:cljs [cljs.tools.reader.edn :as edn]
:clj [clojure.edn :as edn])
is there a better way to write this, or do I need the conditional ? (this is for a cljc file)yay for tools.reader!
I couldn't figure out how to start clojure 1.9. from the command line (sans boot tools) using java -cp
because of the additional dependency (now that java -jar clojure.jar
is not sufficient anymore). Specifically
- which version of spec is needed for clojure-1.9.0-rc2?
- is java -cp clojure.jar:spec.jar clojure.main
the recommended way to start this?
- is this documented somewhere? This would be a good candidate for the release notes as it might catch users switching to 1.9 unaware
This will be documented on the Getting Started page on release but there are several answers.
1) use a build tool like lein, boot, maven, etc. If you include Clojure 1.9 as a dependency, it will also pull in its dependencies automatically (spec.alpha and core.specs.alpha).
2) use the new Clojure cli scripts doc’ed at https://clojure.org/guides/deps_and_cli. If you’re on a Mac this is as simple as brew install clojure
then clj
.
3) build a stand-alone jar from the Clojure git repo - git clone the repo and then follow the directions in the readme.
4) Download the jars for Clojure, spec.alpha, and core.specs.alpha and manually create the classpath. This is probably the most cumbersome
thanks for the reply! building the classpath manually is fine by me - looks like you can see the correct spec.alpha and core.spec.alpha versions here: https://mvnrepository.com/artifact/org.clojure/clojure/1.9.0-RC1
Yep, but note that the reason for breaking these out is to allow them to change more quickly than Clojure so there won’t be one single version that is applicable necessarily
right, so the version in clojure's pom is essentially the minimal version of those extra deps
> If you’ve spent years learning tricks to make your [multi-threaded] code work at all, let alone rapidly, with locks and semaphores and critical sections, you will be disgusted when you realize it was all for nothing. If there’s one lesson we’ve learned from 30+ years of concurrent programming, it is: just don’t share state. It’s like two drunkards trying to share a beer. It doesn’t matter if they’re good buddies. Sooner or later, they’re going to get into a fight. And the more drunkards you add to the table, the more they fight each other over the beer. The tragic majority of MT applications look like drunken bar fights. ~ http://zguide.zeromq.org/page:all
hello everyone, is there a function equivalent of haskells partition :: (a -> Bool) -> [a] -> ([a], [a])
in clojure?
My suggestion is incorrect for what you have in mind, I misunderstood the purpose of partition in Haskell.
Give the group-by
suggestion by @U051SA920 a whirl, it’s more likely what you’re looking for.
and I’m not 100% certain if that is actually what that haskell function does but I think it gets close enough
@pesterhazy two options: 1- use the new clj
script 2- the just released 1.9.0-RC2 has a standalone jar, it's documented in the readme
let me put my suggestion here, it’s now hidden inside a thread:
(defn haskell-partition [f coll]
(map (group-by f coll) [true false]))
(haskell-partition even? (range 10))
=> ([0 2 4 6 8] [1 3 5 7 9])
Hm the rc2 link on https://clojure.org/community/downloads is broken
@bronsa, do you know if the standalone jar is published somewhere?
Ah yeah, I need to update that page. This just changed as of yesterday.
We have a weird issue where some go routines stop working after about 5hrs - any ideas what we can look at ?
when I try to build the classpath manually I get Could not locate clojure/spec/alpha__init.class or clojure/spec/alpha.clj on classpath
if you block all the threads available in that threadpool, nothing will gets executed anymore
@pesterhazy how are you bulding that cp?
@bronsa, I had a typo
it works now - here's a simple script to download clojure manually: https://gist.github.com/pesterhazy/afdfa47ac04d94ee16b5f2e8ddbb0bb1
I understand, but this is simple and I know exactly what it does - it's the moral equivalent of the standalone jar in clojure 1.8
clojure is just a jar, remember?
(or three jars)
all clj
does is download your artifacts and build a cacheable classpath for you, nothing more than that or magical
clj
is wonderful, but that doesn't mean that it's not useful to build a shell script to understand how it works
I'm not saying it's not useful to build a simplified version of X to understand how it works, I'm saying if you need to use it, it's probably better to use X instead. in this case, your script will break when clojure adds a new dependency. clj
would handle that automatically
it won't break so long as I don't update the clojure version 🙂
@decoursin ex-info can contain any java objects, so it depends on the contents
This doesn't seem to work:
(try (throw (ex-info "testss" {:a 3}))
(catch Exception e
(clojure.data.json/write-str (Throwable->map e))))
=> Exception Don't know how to write JSON of class java.lang.Class clojure.data.json/write-generic (json.clj:385)
get it using ex-data?
you’re trying to serialize an object of the class java.lang.Class, and your json writer doesn’t know how to do that
Ah thank you, it's a macro so I must evaluate it?
(try (throw (ex-info "testss" {:a 3}))
(catch Exception e
`(json/write-str (Throwable->map ~e))))
no, being a macro doesn’t have anything to do with it. (Throwable->map e)
produces something that has a java.lang.Class object inside it.
Serialization libraries generally have a way to teach them how to serialize opaque objects. cheshire allows you to extend a protocol to achieve that, not sure what c.data.json gives you as an extension point
Thank you, I see now that even a generic exception fails with the same issue:
(try (throw (Exception. "hi"))
(catch Exception e
(json/write-str (Throwable->map e))))
=> Exception Don't know how to write JSON of class java.lang.Class clojure.data.json/write-generic (json.clj:385)
(extend-protocol JSONWriter
java.lang.Class
(-write [c out]
(let [representation (do something to the class c)]
(.print ^PrintWriter out representation))))
you'll need to import JSONWriter from c.d.json and PrintWriter from http://java.io
> clojure.core/Throwable->map formerly returned StackTraceElements which were later handled by the printer. Now the StackTraceElements are converted to data such that the return value is pure Clojure data, as intended.
Is there something like promise
where delivery can happen multiple times and deref just returns the last delivered value?
I think the implications behind "delivery can happen multiple times" rule out volatile. sounds like an atom though
hello everyone, id like to to spawn 4 threads in paralallel to do some IO, i dont need to get data back from those threads, whats the best way to achieve this besides
(thread ....)
(thread ..)
...
(thread ...)
I meant that "delivery can happen multiple times" says to me that it's multithreaded, meaning volatile is a bad choice 🙂
if you are already using core.async (which I guess you are from the use of thread) I would look at pipeline-blocking
@hiredman, my mistake, i was talking about clojure.core/future
which spawns a thread ..
do you think its worth to turn my vector
to a core.async
queue
and use pipe-line
blocking
it depends, I might start looking at using Executors directly too instead of using clojure.core/future
like, do you want to have 4 threads that a re-used for doing io, or do you want to spin up 4 threads each time, does the io return a result, and do you need those results in order or not
i trully dont care about the result, and i wont reuse anything, those threads perform their work and die silently
might be worth looking at Claypoole even if your current requirements are minimal right now…. https://github.com/TheClimateCorporation/claypoole
This works I think.
(let [p (promise)]
(defn last-val [] @@p)
(defn reset-val! [v]
(or (deliver p (atom v))
(reset! @@p v))))
(future (println (last-val)))
(reset-val! 10)
(reset-val! 11)
I feel like I'm missing something simple here, but has anyone ever implemented a file-tailing algorithm in Clojure? That is, as new lines are written to a file, you process them in your Clojure code? It seems that just opening a reader gets me a snapshot of the file at opening time.
@U06FS3DLH https://commons.apache.org/proper/commons-io/javadocs/api-2.4/org/apache/commons/io/input/Tailer.html or google Java file tailing
ah, so basically I need interop. I guess I should go ask the planck folks then since I'm in a planck / cljs context. 🙂 Thanks for the pointer!
@ghadi See my above code. It’s the other way around. Promise in atom doesn’t work, because you can only delivery to a promise once.
@borkdude what about checking if the atom is nil, and if so putting a watch on the atom that triggers your thing if the new value is non-nil, and then removing the watch inside the watch callback?
or maybe you even want to always want to ignore the current value, and only run your action when the value changes, and add-watch
is what you want directly
> what about checking if the atom is nil this is hard to make thread safe without compare-and-set! I don’t need a watch.
the xy about this: I need to prepare some data in the background and I want the first web request to wait for this thing to be ready. It might be refreshed later.
with a watch, you can ensure your code doesn’t return until the value is ready
or, use an agent instead of an atom and use await
(well, watch plus delay or promise you can block on that is)
and really, if all you need is to prepare data in the background, why not just use future
?
why does it need to be updated? why can’t you just make a new value?
and if you have async updates multiple threads wait on, that would happen repeatedly, await
on an agent sounds like it maps directly to that
right, there are no pending actions on it
Maybe we should switch to a thread as to not flood this channel with this topic, it’s getting kind of long
what I don’t understand is how you would know when a is “ready” and when it isn’t
@U051SS2EU Everything after the first init is fine
This works: https://clojurians.slack.com/archives/C03S1KBA2/p1511901724000313 Just wondered if there is some other primitive I could use.
But I’m not even sure anymore if I want to do it like this, so it’s ok, I’ll think about it some more
I think you're on the right track
maybe something with a count-down-latch? (I may be thinking of the wrong primitive)
I think you have an extra @
on that reset! - but otherwise that is sensible
Or if you want to drop to Java you could due this with Thread.wait, notify and clojure's locking
1) get the value (non locking) 2) if the value is not a sentinel return it 3) Lock and check if the value is still a sentinel 4) If so, add yourself to a pending threads queue and sleep
the producer then simply sets the value to != a sentinel and wakes all the pending threads. Future writers can ignore the pending threads list
(.setLevel (Logger/getLogger "org.flywaydb") Level/WARNING)
this works (silent DEBUG/INFO logs) unless add to project.clj [org.slf4j/slf4j-simple "1.7.25"]
.
How can i make silent this logs?
probably not, there's a few places in Clojure that could still use some transient love
Probably because creating a new map from an existing map using assoc is very efficient already
I tested this because I wanted to know the performance difference between using map literals and zipmap:
(def f (fn [[a b num]]
#_=> {:a a
#_=> :b b
#_=> :num num}))
(def g (partial zipmap [:a :b :num]))
(quick-bench (f ["a" "b" 1])) ;;=> 22 ns
(quick-bench (g ["a" "b" 1])) ;;=> 250 ns
There was a ticket for making merge
faster CLJ-1458 but it could use some love, starting with a decent set of benchmarks
I would like someone to give that a whack. Keeping in mind that merge 1) preserves metadata 2) and because it is based on conj, happens to take either a mapentry, vector, or maps as arguments
Oh why am I talking with prose: @alexmiller do you have a spec
lying around for c.c/merge?
wow, I'm pulling my hair out over this issue, when I create a reader at the repl this form parses correctly, but when I call a function on the form it throws an error. I'm about to hit the road so hopefully the comments on the ticket are clear https://github.com/gdeer81/marginalia/issues/165
;; A symbol string begins with a non-numeric character and can contain
;; alphanumeric characters and *, +, !, -, _, and ?. (see
;; for details).
I would expect :
inside a symbol to work by accident, and any bugs caused by having :
in a symbol to be the fault of the one naming the symbol
Symbols beginning or ending with ':' are reserved by Clojure. A symbol can contain one or more non-repeating ':'s.
ugh - never mind then - that seems like a terrible choice to me, but it’s allowedwell, time and again, in these kind of discussions a distinction has been made between legal symbols and readable symbols
right, but those docs seem to say that a single : in a symbol is readable
(and also legal)