This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2017-07-06
Channels
- # beginners (90)
- # boot (83)
- # cider (39)
- # clara (4)
- # cljs-dev (124)
- # cljsrn (10)
- # clojure (208)
- # clojure-boston (1)
- # clojure-italy (13)
- # clojure-nlp (3)
- # clojure-russia (34)
- # clojure-spec (63)
- # clojure-uk (101)
- # clojurescript (65)
- # community-development (13)
- # copenhagen-clojurians (1)
- # core-async (1)
- # cursive (24)
- # datascript (1)
- # datomic (65)
- # emacs (20)
- # graphql (20)
- # hoplon (21)
- # instaparse (18)
- # jobs (5)
- # jobs-discuss (2)
- # leiningen (8)
- # luminus (32)
- # midje (1)
- # mount (3)
- # off-topic (18)
- # om (10)
- # parinfer (6)
- # pedestal (2)
- # planck (2)
- # precept (22)
- # protorepl (7)
- # re-frame (45)
- # reagent (9)
- # ring (1)
- # ring-swagger (4)
- # rum (2)
- # spacemacs (5)
- # sql (2)
- # unrepl (13)
- # untangled (8)
- # yada (5)
ok, just got a big burst, it looks like I'm not blocking when I publish, the pre/postpublish log messages are all within the same millisecond
it sounds like you are interfacing regular thread using code and core.async, and my bet is you are either using put! to publish or (async/go (>! ...)), when you should be using >!!
Also, go blocks can die without visible feedback or error messages, you could just get backed up as consumers silently fail.
if you create a go block from a normal thread, you should wait for its result using <!!
I still think it is some kind of issue with your topic-fn, but you have assured me it isn't
if the publishers aren't actually blocking, all the symptoms point to a disconnect between pub and sub, the likely reason is the result of topic-fn isn't what you think
so I might do something like replace the topic fn with (constantly 1)
make a channel subbed to 1, and verify it is getting all the traffic
@hiredman ok, but I think based on what @noisesmith was saying is that my usage of go (>! ...) could be the prob
definitely, like I said, "if publishers aren't actually blocking" if they are blocking and you just can't tell, or they are just dying, then that would be your problem
I have a log message before the publish and another after, and they are always within a millisecond
are you sure those aren't spurious log messages coming from threads left running from a previous attempt?
given that I'm not buffering what are the scenarious that would cause events to be dropped?
well, you could think events are being published when they are not, because your producers are just blocking. the topic-fn could be returning something you are not subscribed to so messages get dropped, or your subscribers do get the messages and just don't do anything
givent that I only have 1 publication on one channel there should be no pub log messages that are publishing into nothing
right, that blocking is back pressure being communicated back from the downstream async bits, which are stuck where or going really slow
no thats part of this whole business I've never been too clear on. I have no logic for re-publishing
whenever you have a feedback loop (a process that feeds output back in to its input) it is really easy to deadlock
since the sub channels don't have a buffer, publishing to them blocks until someone else consumes from them
depending on what you are doing, adding a buffer might fix it, or might not, because a buffer is fixed in size, and if you feedback more than the size of the buffer, you are deadlocked again
all of my sub loopse run forever taking from the sub channels and then calling a handler
I think you're saying if my sub loops get stuck then that could be causing the deadlock, like handler never returning I guess
that would all make sense if the whole thing locked up and never recovered, but that doesn't happen
if my handlers got stuck the whole system should eventually lock up, and that never happens
the handlers can be slow compared to the publishers, when there is lots of activity, they all run in their own go blocks
it sounds like everything is behaving as designed, feedback is slowing your publishers to a rate that matches the consuming
in this case, the processes reading from the sub channels aren't able to get time on the threadpool to run
are you sure they are lost? or are they just waiting to run in a completely backed up system
you see the thing is, my publishers are bursty, there are short periods of busy activity and long periods of relative calm,
given that the system never locks up, all events should eventually be handled in the calm period, but that isn't what is happening.
aggh, I'm gonna have head home soon, thanks for being a sounding board on this pub/sub stuff
you might want to look at one of the pipeline variants, it may simplify things a lot
cool, thanks, have a good evening (or what ever timezone appropriate part of day is appropriate)
@qqq if you didn't already look at the source a few hours ago, yes, identical?
is just:
static public boolean identical(Object k1, Object k2){
return k1 == k2;
}
Trying to flatten a nested map to a 'referenced nested map':
{:a1 {:b1 "val1" :c1 2}
:a2 {:b1 "val2" :c2 {:d1 3}}}
to
[{<0> {:a1 <1> :a2 <2>}
<1> {:b1 "val1" :c1 2}
<2> {:b1 "val2" :c2 <3>}
<3> {:d1 3}]
<n>
being some value, doesn't really matter a lot - just a number would certainly do.@tjscollins did you get an answer ? is this useful https://github.com/r0man/oauth-clj/blob/master/src/oauth/google.clj
I am somewhat bewildered by core-async terminology. pipeline
is for computation (non-blocking all the way), pipeline-async
is for "async" operations which seems to be operations which may park the statemachine and pipeline-blocking
is used for straight up blocking ops.
I am mostly confused about ´pipeline-async`.
Am I right in assuming:
* (#A1) some operations, say (a/<! (a/timeout 3000))
- would park for approximately 3 seconds - so operations like it (take from a channel) are OK inside of pipeline-async
.
* (#A2) the reason the af
fn in pipeline-async
receives a channel onto which the result should be delivered is because I can then easily wrap a typical callback-style async operation by letting the callback put a message onto this result channel ?
@tjscollins this might be better .. I think you need OAuth2 for google and this repo has a google example https://github.com/craygo/clj-oauth2/blob/master/src/clj_oauth2/google.clj
@pseud the purpose of the chan passed to af is to allow N results (0 or more) onto to from each call too af
Otherwise it would have to build and return a collection.
@joshjones: (re identical? being pointer equality check) -- nope, haven't read source yet; thanks for checking for me 🙂
Is there a exports.default
equivalent (from Node.js) for Clojure? Use case, I have a file called config
that loads an EDN file, parse it and store it to a variable called config
. Whenever importing it I have to config/config
which looks... Weird.
@hmaurer Thanks, that could work. However, I am also exposing two other variables on this file that I later want to reference too. As far as I understand, with your solution, I would only be able to refer to the config
variable and nothing else.
@rinaldi actually I got the syntax a bit wrong. It’s
(require '[my-app.config :refer [config]])
@rinaldi another thing to consider is that since good clojure style is to use the namespace prefix, you can use a name that isn’t redundant with the prefix
for example if the ns were environment so it was environment/config
and the other things in the ns were environment related but not the config data itself, or if the var were settings, so it’s config/settings
and the rest of the ns is about things that are about config but not the specific settings
@noisesmith is using :refer bad clojure style? I am new to clojure so I don’t really know
@hmaurer it’s OK in moderation - but there’s a reason nobody writes ns forms with :use
any more
Thanks both @hmaurer and @noisesmith.
that’s the most I’d want in a client ns period
not just from one ns - from all combined
@noisesmith :use is an order of magnitude worse though, right? it just refers everything
right, but it’s a matter of degree not kind
@noisesmith What if I have a library that exposes a bunch of stuff but I just need a few of them. Still the best practice is to go with namespaces instead of using :refer
and :only
?
use :as
unless you are using the function extremely frequently
that has nothing to do with it
all :as does is create an alias in your ns
not using :refer is not about memory usage, it’s about poluting a namespace with bindings that are irrelevant
it’s about code readaiblity
So I don't really see a use case for anything other than :as
(perhaps only :use
because can be handy on the REPL)
yup - that’s almost always the right way to do it
but there are exceptions eg. if every function in your ns is using >! from core.async
that makes sense to refer
@dpsutton yeah, to me that’s the same exception - every form in my test ns uses deftest once and is multiple times
so it’s ubiquitous enough to drop the prefix
for sure. i'm a big fan of the namespaced functions. common lisp gets difficult to read because of that. also emacs-lisp...
it’s another flavor of the same problem overuse of inheritance causes - “where the hell is this name defined?”
but inheritance tends to get into a worse state because it’s so common to rebind the same names
i actually alias clojure.test, mostly to get completion and automatic require in cursive
oh can it not suggest things that aren't in the current namespace if they don't have an alias?
I'm writting a macro that transform a keyword into a symbol
This symbol will be used on a (def ~symbol ...)
There is a "default" way to normalize :foo.bar/quoo
to a valid symbol?
def can’t take namespaced symbols though
yeah, probably just munge the ns & name into a string, separated by some other string, if the namespace is important
if it needs to be “local” why is it going in a def?
perhaps I misunderstand what you mean by local here, but by the standard clojure definition, def doesn’t and can’t be used to create locals
(my-cool-macro :about.this/keyword [some cool dsl])
macro-magic> (def about_this_keyword :result-of-my-macro)
That addresses the question, that doesn’t do anything with locals as clojure defines them. But given that in order for the macro to work :about.this/keyword needs to be a literal, why not just provide the symbol directly?
noisesmith: because I'm talking about a a keyword. I will generate a rule for clara. Dynamic symbols will cause difficulties on debug
what I am saying is that the macro won’t work unless the keyword is a literal in the form
a symbol as a literal in a macro that becomes a binding does not cause any debug difficulties
do you mean the keyword literal is the same as a keyword that gets used elsewhere?
@dpsutton no it suggests them fine, it just feels more useful when it narrows it down to a specific alias
hello, i’m trying to take a sqlvec like
["SELECT * FROM ? WHERE (? = ? AND ? = ?)"
"Aliens"
"WritesPoetry"
"True"
"TheirPoetryIsGood"
"False"]
and convert it into a sql string
usually, i would be content with this as clojure.java.jdbc accepts this. but in my current situation i am communicating with AWS Athena which accepts a string representing a sql query.if athena doesn't have prepared statements then you'll need a function that escapes sql in a manner that's safe for athena
jdbc, or all the jdbc drivers I have used, don't let you parameterize the table name
apparently the .toString method on a prepared statement for some jdbc drivers will give you the sql string
what clojure libraries exist for desktop ui's? is there anything like re-frame for clojurefx? not really interested in electron
i found a lot of things that are out of date.... looking for something that's been maintained
@cjhowe I maintain fn-fx, but to push it much further we need users. Not a whole lot of people trying to do JavaFX with Clojure
That being said it's React for JavaFX and works fairly well for "normal" apps, the rough edges are around things like animation.
hi, just a quick question, how do you do comment blocks? do you just put a string inside (comment)?
@tbaldridge i see... well, i'm a student trying to build a portfolio, so this seems like an interesting area that clojure could improve on... do you know if javafx is popular in the java world?
@joelsanchez #_(this block is commented)
ok, i see, thanks!
@cjhowe there aren't a lot of Java desktop apps, but JavaFX is a really nice platform. It's fast, GPU accelerated, and the API is very uniform. Infact the vast majority of fn-fx is auto-generated code created by the library introspecting on the JavaFX API.
@tbaldridge sounds interesting, i'll check it out! thanks
@joelsanchez "comment block" is a little ambiguous. do you just want a block of comment text (like a multiline comment) or do you want to comment one or more sexp's?
@mbjarland without going too far into it, your filter
example is lazy and your transducer example isn't, and you're only taking the first result. so the comparisons are going to be a bit meaningless
@mbjarland are you sure of your measurements? The above benchmark code looks very questionable
also without showing what year-dirs-only-xf
is defined as we can only really guess as to what's happening
@dpsutton yes, most of my project is commented like that but it's a little bit of a pain
not sure which editor you're in, but most should have some way to format a long single comment
Cursive
it does not bother me to use it, it bothers me to write ;; all the time when i am writing it
i'll try to activate something in cursive for that, because right now it does not
@mbjarland: ok then yes it looks like it's pretty much because your latter example is lazy and your format example is not
@bfabry was trying to not spam the channel with too much code. Any easy way to keep the composability of transducers but stay lazy and fast?
if the situation/algorithm benefits from laziness my first instinct is to say "don't use transducers there"
doesn't look like it @dpsutton , there's an option to auto-wrap at the 80-columns limit but i don't want that for code, i will ask in the cursive channel
I believe so, one of the reasons that they're faster (in situations where laziness isn't a benefit) is because they don't have the overhead of keeping track of unrealised computations
it’s a lot simpler to enumerate the things that are lazy (there’s very few), and sequence is the only built in lazy thing using transducers and I forget the details but saw it explained that sequence was sub-optimal in important was compared to other lazy functions
a transducing function just transforms a single result, so would hardly benefit from laziness, a transducing context can be lazy or not (and sequence is the only lazy built in transducing context)
@bfabry @noisesmith thanks, I will go back and meditate some more on transducers and laziness…
(* 3 (/ 1 3))
=> 1N
I am confused why I would get a BigInt hereis there a design choice which made the return value a BigInt and not an Int?
user=> (type (/ 1 3))
clojure.lang.Ratio
and Ratio
is defined in terms of BigInt
https://github.com/clojure/clojure/blob/f572a60262852af68cdb561784a517143a5847cf/src/jvm/clojure/lang/Ratio.java#L23
ah ok, thank you
@alex-glv yes, someone told me about that macro, thanks anyway
Any book (or blog) recommendation, specifically for clojure concurrency?
I've spent some time today wrangling atoms, agents, add-watch
and promises, for managing a work queue. It has been a nice drill. I'm undecided what's the best queue management technique and might suspect clojure.async or even some Java implementation might be more performant/safe.
@gmercer Thanks. That second did the trick.
one of these two expressions looks wrong to me:
user> (* 2.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001M 1.0)
2.0
user> (* 2.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001M 1.0M)
2.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010M
user=> (.doubleValue (BigDecimal. "2.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001"))
2.0
user=>
basically, fixed precision floating point numbers are dirty and their dirtiness will contaminate any math they are used in
1.0 in that expression is a fixed precision float (a jvm double), and that is what causes weirdness
clojure, encoded as a big honking class file, has rules about how you convert types to do math operations, and doubles as a type dominate pretty much everything, meaning if you have doubles in your expression, internally numbers that are not doubles are going to be turned in to doubles when doing math