This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2017-03-23
Channels
- # beginners (63)
- # cljs-dev (1)
- # cljsjs (1)
- # cljsrn (11)
- # clojure (208)
- # clojure-berlin (2)
- # clojure-dusseldorf (5)
- # clojure-italy (5)
- # clojure-norway (56)
- # clojure-russia (7)
- # clojure-spec (85)
- # clojure-uk (27)
- # clojurescript (191)
- # core-async (73)
- # cursive (4)
- # datomic (62)
- # defnpodcast (1)
- # hoplon (2)
- # jobs-rus (1)
- # juxt (14)
- # keechma (1)
- # leiningen (1)
- # lumo (126)
- # off-topic (2)
- # om (11)
- # onyx (27)
- # pedestal (52)
- # planck (21)
- # powderkeg (1)
- # re-frame (32)
- # reagent (14)
- # ring-swagger (1)
- # rum (3)
- # slack-help (19)
- # specter (23)
- # untangled (32)
- # vim (7)
- # yada (43)
if you have some function that runs some kind of server and responds with what you give it, the response would always be 1
what if while you were working on the server, you wanted to change it to server something other than 1, without restarting it?
you can pass a var in place of a function if the var holds a function, because vars when invoked as functions invoke what they contain
when you define a function like (defn foo [x] x) and then define it again like (defn foo [x] (inc x)) you are changing the value of the var #'foo
just like (atom 1)
and 1 are entirely different things, #'foo
and foo
are different things
@stuartrexking Crossposting to #clojure from #beginners is not encouraged. If you post to #beginners give people a little while to respond (2 minutes is a bit abrupt). As you saw on #beginners people jumped in to help after a short while — bear in mind that you posted after 5pm Pacific time so most Americans have left work… 🙂
@seancorfield My bad. Thanks for the tip.
@hiredman Thanks.
NP. We’re generally a pretty helpful bunch but we have #beginners for a reason — folks can opt out of that.
Is there any easy way in clojure.test to define an 'is' which is run over a list of items ?
Actually, it partially solves what I want, are still requires me to type out each value (e.g. x
& y
seen in the first example of https://clojuredocs.org/clojure.test/are)
Ideally I'd like to iter over a list, binding one var to the current element at each step
You can get around that with something like (is (empty? (remove test-fn test-values)))
if it fits your use case.
I cloned tools.analyzer, cd'd and ran lein repl
but it fails to resolve this dependency - Could not find artifact org.clojure:clojure:jar:1.9.0-master-SNAPSHOT in clojars (
should I change the project.clj file? :thinking_face:
where can I find the .lein/profiles.clj file?
it is not in my ~
tools.analyzer (master) ls -al ~/.lein
total 24
drwxrwxr-x 3 radar radar 4096 Mar 23 17:26 .
drwxr-xr-x 121 radar radar 12288 Mar 23 17:41 ..
-rw-rw-r-- 1 radar radar 54 Mar 23 17:26 repl-history
drwxrwxr-x 2 radar radar 4096 Mar 23 12:25 self-installs
okay, will pull from master when you add it
Hi all! I have a question about transducers in core async channels. is it idiomatic to define a transducer which depends (without side-effects) on a globally defined atom? I posted a longer version of this question with an example here: https://groups.google.com/forum/#!topic/clojure/JCQmEXkIYms
It feels dirty, but the main reason is the syntax. Extract the anon fn into it's own validation/safeguard namespaced fn and you'll realize that (filter allowed?) is not that bad, with the only thing being a lookup against an actual atom. If that's your use case, there is no problem with it.
@elenacanovi is it idiomatic - no; have I done that in the past - yes;
(that is, if you have decided to compose with a transducer). Maybe if you define your composition at a higher level, you can find out the flow of receive->validate->process reads better.
ok thanks.
@elenacanovi I think one purer solution is to always pass ‘banned-users’ as part of the map that goes through the channel
@elenacanovi if this is for an actual production system, FWIW, you'll need some way to prevent a banned user from spamming the channel in the first place. in other words, you should not be processing data that originates with a banned user
in a decent sized project I would rarely have more than 2-3 “mutable hacks" like that in areas that I feel that they are absolutely necessary and actually bring about a simpler code structure; so it’s your call to make; but if you find yourself reaching for things like that many times, it might be a place to re-think the overall approach
yes, as @raspasov said, in some other words -- your "security" is very tightly coupled with your server and very embedded, with this kind of approach. abstract out, if possible
@joshjones well, that was just an example. but for an actual chat you’re absolutely right that banned users should not be able to spam
@elenacanovi I figured as much, but wanted to mention just in case. But yes, filtering out like this should be abstracted out, and not coupled so tightly
@joshjones @raspasov ok 🙂 thanks
I’m trying to create an appender for Logback programatically but can’t get it to work. This is the XML config: https://github.com/papertrail/logback-syslog4j#logging-via-tcp-with-tls-recommended and this is how I try to emulate that in Clojure:
(def appender
(doto (Syslog4jAppender.)
(.setSyslogConfig (doto (SSLTCPNetSyslogConfig. "" 00000)
(.setIdent "my-app")))
(.setLayout (doto (PatternLayout.)
(.setPattern "%-5level %logger{35}: %m%n%xEx")))))
(.setContext ^ContextAware appender ^LoggerContext (LoggerFactory/getILoggerFactory))
(.start ^LifeCycle appender)
(.addAppender (LoggerFactory/getLogger Logger/ROOT_LOGGER_NAME) appender)
Does that look about right?@roberto yes, replaced it with 00000 in the above example
looks fine to me, but I haven’t really tried to do this in clojure. Are you getting any errors? Or just silently does nothing?
It just silently does nothing 😕 There’s a kind of debug mode but I’m not sure how to enable it programatically
true story
shouldn't you use a layoutpatternencoder and bind it to the appender instead of calling setlayout directly?
@mpenet there’s some more context here: https://github.com/pyr/unilog/issues/21 — interestingly there was a slightly different behavior with and without that setLayout call but I’m not sure how to interpret that...
yeah usually with unilog you setup your encoder separately then assoc it to the builder map
also not sure how you test it, but when doing unilog-sentry I often had to look into the server process in cider to get to exceptions
but if I try 'redshift' or 'jdbc:redshift', it errors with clojure.lang.ExceptionInfo: Unknown dbtype: redshift
tjtolton how did you add the dep for the jdbc redshift adapter?
You can’t use dbtype
/ dbname
with types that are not known to java.jdbc
— you have to use subprotocol
/ classname
instead.
@noisesmith I did a mvn install on the jar
tjtolton that doesn’t add it to your project classpath though
https://github.com/clojure/java.jdbc/blob/master/src/main/clojure/clojure/java/jdbc.clj#L225-L229
tjtolton to use it in your project, it should be in your project.clj (or boot config, or whatever) - mvn install just adds it to your local maven cache, which is not visible by default
oh, OK
http://clojure-doc.org/articles/ecosystem/java_jdbc/home.html — community-maintained docs have examples
(I’ve no idea why it’s called subname
🙂 )
I can add built-in RedShift support to java.jdbc
once I have more details about it. I just added the Impossibl PostgreSQL alternative implementation because someone created a JIRA issue with details for me.
well, if a line in documentation is cheaper, these values worked perfectly for me:
{:classname "com.redshift.jdbc.Driver"
:subprotocol "redshift"
:subname "//<host>:<port>/<database name>"
... <other keys>}
I can add a RedShift entry here https://github.com/clojure/java.jdbc/blob/master/src/main/clojure/clojure/java/jdbc.clj#L148-L159 and that will enable built-in support. I definitely need to document this better 😐
@tjtolton What’s the Maven coordinates for the RedShift JDBC driver? Or does it have to be manually downloaded?
I manually downloaded it, used the mvn install command, then added the dependency to the project.clj. it turned out to be much simpler than I thought
the command to install the one I used was
mvn install:install-file -Dfile=/path/to/RedshiftJDBC41-1.1.13.1013.jar -DgroupId=com.amazon -DartifactId=redshift.jdbc41 -Dversion=1.1.13.1013 -Dpackaging=jar -DgeneratePom=true
then, the project.clj uses dependencies with the format
[groupID/artifactID "version"]
im not sure if it even mattered what I set the groupID and artifactID etc to, since I installed it myself
Shame they don’t have it up on Maven Central 😞
I’ve added ”redshift”
as a known subprotocol for the next release of java.jdbc
but I think I’ll enhance how dbtype
is used so you can specify a driver that is not known to the library.
@tjtolton BTW, did you mean com.amazon.redshift.jdbc.Driver
as the classname?
That’s what Amazon’s docs say.
hmm, interesting. that's not what I used. I just pulled some values out of DataGrip's connection settings
Did you use a RedShift JDBC driver downloaded from a non-Amazon site? There seem to be several around.
Hmm, just noticed that Amazon have a Maven repo for their driver so you can use that directly in project.clj
without needing to manually download anything: http://docs.aws.amazon.com/redshift/latest/mgmt/configure-jdbc-connection-with-maven.html
OK, once org.clojure/java.jdbc 0.7.0-alpha3
hits Maven Central (in a few hours), that will be built-in and you can use :dbtype “redshift”
, optionally with :classname “com.redshift.jdbc.Driver”
.
I have a piece of code that should be off in development
is there an easy way to see (programmatically) what :profile
I'm running on, to switch on that?
or some other recommended way, hopefully without an adhoc environment config variable?
your code should not depend on the state of leiningen
you can use env to set an environment variable or java property from leiningen that the app can see though
that's a good point, i'll just stick with something like that
@josh.freckleton in particular it’s good to be able to run from an uberjar without leiningen present at all (it’s nice not to have lein on prod)
true, than you 🙂
@josh.freckleton I might not have made it clear, but by env I mean https://github.com/weavejester/environ which makes it easy to set properties from project.clj when using lein and access them in your code (and in prod you can use your java args or shell environment to set the same values)
totally, that's what I'm using so your advice was well recieved, thank you. I mistakenly didn't want a new environment variable, but that is a better way for solving my current problem
schmee shouldn’t requiring the top level namespace already do that?
since require is recursive and all
(I use a shim where -main is what requires my real code, but even then I only need to require the top level implementation namespace and that causes everything else to load)
hello everyone, im developing a compojure app, and the code inside the handler is getting way too big. i.e:
clj
(ring/POST "/beneficio" []
:summary "Cadastro de Beneficio"
:return {:valorLimiteBeneficio s/Num}
:body-params [cpf :- s/Str
nomeSegurado :- s/Str
emailSegurado :- s/Str
telefoneSegurado :- s/Str
clausula :- s/Str
motivo :- s/Str
atendimentoId :- s/Str
referenciaId :- s/Int
dataInicioBeneficio :- s/Str
dataFimBeneficio :- s/Str]
(match
(benefit-service/create-benefit
telefoneSegurado
(benefit/->Benefit cpf
nomeSegurado
emailSegurado
clausula
motivo
atendimentoId
(:id-cc-carro-extra cfg)
referenciaId
dataInicioBeneficio
dataFimBeneficio
nil
nil))
[:ok limit-value] (res/ok {:valorLimiteBeneficio limit-value})
[:invalid-data] (res/unprocessable-entity {})
[:unkown-error] (res/internal-server-error
{:erro "Ocorreu um erro inesperado no servidor :("})))
is there a way to remove this code from the handler and put it inside something like a controller? i could easily create a function but id have to repeat all the parameters already destructuredschmee does that mean that you call namespaces that are not in your require block? because I don’t see how else you could have that problem
and it should be easy to fix that if that’s why
schmee either the one with -main, or if you are using a shim, the one the shim loads
there shouldn’t be any code path that can hit anything without filtering down from your starting point
so requiring that file should make the rest come in too
(unless you were using some dependency injection trickery with eg. multimethods, but even then best practice is to require all the implementing namespaces explicitly)
why not?
so I was wondering if that is a bad idea and I should require all the namespaces explicitly instead
my answer to that is yes
it makes things much easier to read and understand
schmee I do in fact have a top level namespace for my app without require in the ns form - but this is in order to shim - that is, to have a class a java launcher can call without needing to aot compile any real code
since aot just introduces bugs
but all the top level ns does is require a single ns - the one with the real main that requires everything else
if you are setup to aot compile, then lein will of course aot compile before jaring everything up
@schmee clojure code is usually compiled to bytecodes “just in time” as you load it with e.g. require. aot just does this beforehand and writes JVM class files
i thought they were the same wrt generating bytecode, the diff is that aot puts it on disk?
@tjtolton FYI, java.jdbc 0.7.0-alpha3 is up on Maven Central now, if you want to try :dbtype “redshift”
with that version.
i have a list of fns and want to (lazily) return the first non-nil, i know there's a pattern but I'm spacing it... help?
Do you know the list of functions ahead of time? Or is it dynamic?
it's up to me
i don't want things further down than a success to execute though
(so, lazy)
if you know them while writing the code, use or
:
(or (fn1 some-val) (fn2 some-val) (fn3 some-val))
ahhhh that's right!
thank you thank you
it's been a long day 🙂
I understand
@josh.freckleton you’re looking for some-fn
oh that's awesome, didn't know it existed thanks! In my case, each fn is different so I don't think this would work, but I'm glad to add it to my tool belt 🙂
Oh, sorry, I misread it, then some-some-juxt is your friend:
(some identity ((juxt f1 f2 f3) some-val)))
@U054UD60U that's not lazy though, you'd evaluate every function and then throw away any after the first non-nil
I think it’s lazy but not short circuiting.
juxt
isn't lazy
(or short circuiting)
or
is a simple version that works if you have a small number of functions you're checking and they're static and known at code writing time. If they're dynamic, or or
is just way too verbose for the number of functions you're using, you'd have to either do (first (map #(% some-val) list-of-fns))
and accept that because map
evaluates in chunks, you might call a few extra functions, but not the whole list if it's long enough. Or you'll have to roll your own code to do that (simplest would probably be a loop/recur
version that's not lazy, but at least is short circuiting)
(reduce (fn [_ f] (if-let [r (f some-val)] (reduced r))) nil [f1 f2 f3 f4])
should bail out quick
or even (some-> some-val f reduced)
@U236LQYB0 you’re right, juxt is so eager, I just killed my cider repl
I wonder why, because https://github.com/clojure/clojure/blob/clojure-1.9.0-alpha14/src/clj/clojure/core.clj#L2549 is was chunking with the help of reduce1
(loop [fns fn-list]
(when (seq fns)
(let [result ((first fns) some-val)]
(if (nil? result)
(recur (rest fns))
result))))
is probably how I'd write that if I didn't know the fns while writing the code (or if there were way too many of them)not lazy, but short circuiting at least
how could this ever be lazy if you need to eval up to the first non-nil result and then stop?
lazy makes sense if theres a sequence produced but it’s a single result only.
(delay (loop [fns fn-list]
(when (seq fns)
(let [result ((first fns) some-val)]
(if (nil? result)
(recur (rest fns))
result)))))
for some definition of the word lazy 😄(i.e. you make a valid point, short circuiting is probably what's really important)
lazy makes sense if you do something like (some identity (map #(% some-val) [f1 f2 f3]))
but using loop/recur or reduces skips the generation of the seq of results.
anyone in this thread mention some-fn yet?
clojure.core/some-fn
([p] [p1 p2] [p1 p2 p3] [p1 p2 p3 & ps])
Takes a set of predicates and returns a function f that returns the first logical true value
returned by one of its composing predicates against any of its arguments, else it returns
logical false. Note that f is short-circuiting in that it will stop execution on the first
argument that triggers a logical true result against the original predicates.
nil
@noisesmith yes, but it’s not a match. The task is to have different functions and a constant value.
@noisesmith actually, some-fn
is what to OP was looking for. I had proposed if before but I looks like we got too confused in this thread to realize.