Fork me on GitHub
#clojure
<
2017-11-07
>
danielcompton00:11:46

@johanatan you can also use https://github.com/jeaye/orchestra for instrumenting :ret and :fn

MegaMatt01:11:23

what does @ before a variable mean. (let [st @state]... from the om wiki page. Can't seem to find it googling

lsenjov01:11:02

Without the @, it returns the atom object

lsenjov01:11:31

With the @/deref, it returns the value contained in the atom

MegaMatt01:11:09

@ symbols are hard to google for

athomasoriginal01:11:48

haha yes. It seems the only way would be to know that is is short for deref

phronmophobic01:11:06

clojure has a lot of hard to google usage

phronmophobic01:11:33

the backtick, ->, ->>, #(+ 1 %), #{}

MegaMatt01:11:51

what's the last one of those

phronmophobic01:11:11

it’s the set primitive

phronmophobic01:11:36

is a set with the numbers 1, 2, and 3

phronmophobic01:11:41

#{}, is the empty set

phronmophobic01:11:02

oh yea, and #"[a-z]*"

MegaMatt01:11:29

after learning about threading I can't help but get frustrated at c# almost every time i turn the corner at work

phronmophobic01:11:24

looks like I forgot a few

phronmophobic01:11:07

looks like it’s missing the -> prefix

phronmophobic01:11:18

as well as the map-> prefix

phronmophobic01:11:27

a few people were wondering about that earlier today

noisesmith06:11:43

those are just a part of the name of a function though, not syntaxes, which is why they weren't included

phronmophobic06:11:36

seems like it is similar to <symbol>? predicate suffix

tanzoniteblack01:11:01

those would be nice additions to that list. Don't know who maintains it so we can recommend the addition?

Alex Miller (Clojure team)03:11:14

feel free to send a pr or an issue to update on that repo

qqq04:11:23

(defn rx1 [x] x)
(defn rx2 [x] (* x x))
(defn rx3 [x] (* x x x))

(defn hpc [tensor cb]
  ;; cb :: double -> double
  ;; cb is called around 10,000,000 times 

  ;; this is a big, hairy function
  ;; I would prefer to not turn it into a macro
  )

(defn h1 [tensor] (hpc tensor rx1))
(defn h2 [tensor] (hpc tensor rx2))
(defn h3 [tensor] (hpc tensor rx3)) 
Question: is it possible to tell clojure to inline rx1, rx2, rx3 ? "Don't worry about it, JVM hot spotting will take care of it" is a valid answer.

seancorfield04:11:54

@qqq Well, there's :inline metadata but I don't know how well documented that is, and I suspect it's experimental/subject to change...

qqq04:11:31

@seancorfield: yeah, I read http://bytopia.org/2014/07/07/inline-functions-in-clojure/ ... but there is a comment by @alexmiller at the bottom of the blog post suggesting caution

seancorfield04:11:39

That was back in 2014 -- and I don't think anything has actually changed since...?

qqq04:11:09

does tat mean "nothing has changed; therefore stable to use" or "alex's caution hasn't changed, still dangerous to use" ? 🙂

seancorfield04:11:59

It's worth noting that CLJ-1227 is indicated as being caused by https://dev.clojure.org/jira/browse/CLJ-1330 which is fixed.

seancorfield04:11:26

I meant "Alex's caution probably still stands but it hasn't been removed yet" 🙂

qqq04:11:27

~(let [(vary-meta foobar# assoc :tag 'long) ...] 
this is not allowed -- can I not use foobar# , and have to explicitly use a gensym ?

seancorfield04:11:18

You mean with :inline?

phronmophobic04:11:27

the # suffix is just a backtick thing

seancorfield04:11:49

(context is everything @qqq 🙂 )

seancorfield04:11:05

I assume that code is inside a macro...?

phronmophobic04:11:34

you have to use a gensym in your example

qqq05:11:32

sorry, was afk rewriting the function as a macro

qqq05:11:40

yeah, this is part of a macro, and yes, I ended up using gensym

andy.fingerhut08:11:51

@matthewdaniel @smith.adriane @tanzoniteblack There is also the Clojure cheatsheet, with the http://clojure.org version here https://clojure.org/api/cheatsheet which has a link to this page that has some other variants that enable searching, but unfortunately not for the special characters. There is a dedicated section of the cheatsheet to most of the special characters you will find in Clojure, near the 'bottom left' of the page. It has links to other docs for most of them, including a link at the top of that section to Clojure guide page linked earlier: https://clojure.org/guides/weird_characters

chrisblom08:11:22

is anyone familiar with scala interop? I need to construct a case object, but can't figure out how to do this from clojure

Empperi09:11:01

try this:

(def case-disabled RackAwareMode.Disabled$.MODULE$)
Haven’t tested that out but basing this on this stackoverflow discussion https://stackoverflow.com/questions/2561415/how-do-i-get-a-scala-case-object-from-java

chrisblom09:11:16

Found a solution:

chrisblom09:11:21

(import 'kafka.admin.RackAwareMode$Enforced$)
(kafka.admin.RackAwareMode$Enforced$/MODULE$)

asolovyov08:11:51

Hey all! I'm trying to rewrite core.async-based code into aleph/manifold one, and can't figure out what would be equivalent for something like this:

(go-loop [x 0]
  (if (> x 3)
    x
    (do
      (<! (timeout 1000))
      (recur (inc x)))))
the main problem is timeout, I have no idea what's the right way to do it with manifold deferred's: I'm making an http request with aleph and want to retry for a few times with growing backoff. Manifold docs have Thread/sleep somewhere, but I'm a bit scared about that one. 🙂 Any pointers maybe?

chrisblom08:11:08

@asolovyov maybe manifold.deferred/timeout! is useful.

qqq08:11:23

;; o  (if (p/>= g t) (float 255.0) (float 0.0))
            ;; o  (if (p/< g t) (float 0.0) (float 255.0) )
^-- these two lines should do the same thing right ? I'm doing image processing, getting different results, and completely baffled

chrisblom08:11:15

what's the p/ namespace?

qqq08:11:33

oh, it fails when t = NaN

asolovyov08:11:42

@chrisblom maybe, but then I have to find deferred to timeout on then...

asolovyov09:11:30

not really, let's say http://clojure.com responds fast enough, but with an error, and we want to retry it few times in a row with growing backoff

asolovyov09:11:59

in this case we're doing http/get, and then there needs to be a Thread/sleep or something similar

asolovyov09:11:24

like, between http/get and d/recur

chrisblom09:11:14

ah ok, so in my example, you would want to wait before calling d/recur?

asolovyov09:11:54

in current core.async code it looks like this:

(def process-message [...]
  (go
  ...
           (when retry?
             (<! (timeout next-backoff-ms))
             (process-message client url args success? ack-fn async-exception-fn (assoc retry-params :retry-attempt (inc retry-attempt)))))))

chrisblom09:11:24

tbh, in such a situation i'd just run a function in a java executor, so i can use 'Thread/sleep' safely

asolovyov09:11:26

@chrisblom hm, that's an option, thanks!

curlyfry10:11:37

Hi! It seems that the community has pretty much settled on using this convention for test files: http://www.lispcast.com/clojure-test-directory (putting the test files in a separate directory that mimics the same structure as the main project). I find it pretty tedious to mimic the directory structure, and I'd like to have the tests close to the code since I will often look at them in conjunction. Does anyone have any suggestions on how to accomplish this? I would of course like to exclude the test files from production builds.

danm10:11:50

How deep is your directory structure? o.0 We are normally only creating a couple of extra directories for a new project. Most tooling that creates projects/files, like boot (and I assume lein) can also be make to create the test file in the expected place when you tell it to create the source one...

curlyfry10:11:45

Not super deep, but I find it annoying in general to have to change the same thing in several places. I also see tests as a form of documentation, and that would be nice to have as close to the code as possible.

noisesmith13:11:48

if you add the :test metadata to a function, and that contains something callable, that will be run when you execute clojure.test/run-all-tests

noisesmith14:11:01

if it contains test/is etc. it will work just like a deftest

noisesmith14:11:54

I don't think lein test likes this, but making a task that loads your namespaces and runs clojure.test/run-all-tests is not hard at all - you can even just run your tests from the repl

danm10:11:22

Why? It's just opening files. Does it really matter where they are? Especially if the structure is the same apart from the first word being src or test. You can even shell glob it when opening in most editors. Regardless, that is the same as the Java expectation, and as far as I am aware all tooling expects that structure. You could write a boot task that for example copies files named without _test into a src dir under build with the same structure and ones with _test into a test dir under build and then make all other boot jobs run from that dir with the structure it expects, but that seems like a lot of work. I assume you could do something similar with lein

curlyfry10:11:56

I find it definitely matters where the files are located when exploring a project. For example, if the tests where located next to the code, I could immediately see if the module I'm currently working on has any tests associated with it by seeing if there is a test file in the module or not. I agree that writing any sort of complex task is not worth it, however.

ajs10:11:15

I have seen several Clojars deployment tutorials that claim you can enter a public GPG key in your profile there, but I do not see this anywhere in the site. What a I missing?

noisesmith14:11:48

as far as I know this feature is out of date - it wasn't being handled properly(?) and nobody had the expertise or energy to manage it correctly iirc

fantomofdoom11:11:01

Hi, someone work with Immutant 2 and protobuff. When i try to convert stream -> clojure hash map (in safary) i catch

java.io.IOException: UT000034: Stream is closed
but in chrome/firefox/ie all work fine

ajs11:11:21

if you want to use clojure.test on a macro, i gather you'd have to do something like (eval '(my-macro ...)) if the macro could throw an assertion and your is test is in fact testing for thrown?, right?

ajs11:11:11

like (is (thrown? AssertionError (eval '(some-macro {:e :hi}))))

ajs11:11:52

because otherwise the assertion is thrown when the test file is compiled for me

tcrawley12:11:31

@ajs Clojars dropped using your GPG key - it was used to verify that the artifacts you uploaded were signed by you when trying to promote to the "releases" repo, which was removed. See https://github.com/clojars/clojars-web/issues/415 for rationale

ajs12:11:40

but i cannot use lein deploy clojars without it failing with GPG errors

tcrawley12:11:28

Ah, that is a different case - that's lein trying to use gpg to sign your artifacts before sending them to clojars

ajs12:11:03

only too many times

ajs12:11:25

i think i'll give up on it for now

tcrawley12:11:16

You can disable signing by setting :sign-releases to false for clojars: https://github.com/technomancy/leiningen/blob/stable/doc/GPG.md#signing-a-file

tcrawley12:11:20

I believe this should do it (in project.clj): :repositories [["clojars" {:url "" :sign-releases false}]]

ajs12:11:31

is that an actual url with /repo or do i put one in there for my own app? i've tried this both ways and get weird errors about "missing connectors" and stuff

tcrawley12:11:31

That's the actual url - it's not project-specific

ajs12:11:57

ok, i'll try it again in a little while, thanks

stathissideris12:11:16

my data_readers.clj looks like this:

{monitor/date monitor.utils/parse-date}
I start a REPL, refresh (as in, I load all the namespaces) and this happens:
user> #monitor/date "2016 3 1"
IllegalStateException Attempting to call unbound fn: #'monitor.utils/parse-date  clojure.lang.Var$Unbound.throwArity (Var.java:43)
user> @#'monitor.utils/parse-date
#function[monitor.utils/parse-date]
why?

Alex Miller (Clojure team)13:11:02

You still need to require monitor.utils before you use the tagged literal, otherwise Clojure can’t find the constructor function

stathissideris16:11:40

Thanks for this, I was actually including monitor.utils and still had problems. It turns out that it was because I was using CIDER’s refresh functionality (C-c C-x in emacs) instead of clojure.tools.namespace.repl/refresh! Still unsure as to why, but at least I found a way around it

hlolli12:11:09

how does one supress the default logger with jetty, which is set to info,

2017-11-07 13:33:20.868:INFO::main: Logging initialized @3013ms
..etc...

jumar12:11:35

@hlolli it depends on the logging lib you're using - with timbre you can configure it directly in Clojure, clojure.tools.looging uses underlying java libs which usually means using properties or XML files for configuration

hlolli12:11:36

yes it's a mystery to me what logging lib is printing this, since this is always by default with jetty, has never bothered me. Im creating terminal app and it's distracting. Looking at ring/ring-jetty-adapter dependencies, there's no logging lib there, guessing it's coming from org.eclipse.jetty/jetty-server "9.2.21.v20170120". So maybe there's some java option I could set?

hlolli12:11:01

maybe I found it with quick google search -Dorg.eclipse.jetty.LEVEL=ERR

hlolli12:11:09

ok this fixed it :jvm-opts ["-Dorg.eclipse.jetty.LEVEL=OFF"] in case someone googles the slack logs.

ericnormand13:11:20

@curlyfry you can technically add tests in any file, including the file with the implementation

ericnormand13:11:44

the reason they're in a different directory is so that you can exclude them from production deployments

curlyfry14:11:42

Thanks for the reply! I know that's why it's in a different directory. My question was wether it's possible to exclude them anyway without too much hassle.

ghadi16:11:56

Clojure 1.9.0-RC1 is out -- no different than beta4. Start your engines

ghadi17:11:56

it's in the repo

toastbox19:11:07

I was commenting a few days ago that I was having trouble calling some Clojure functions (i.e. implemented in Clojure) from my Java app. I managed to make some progress, and to call a few functions from clojure.core -- but I still haven't been able to call any Clojure functions that I've implemented myself in my own Clojure libraries. It always results in an error saying the function is unbound.

toastbox19:11:23

I'm suspecting that perhaps the clojure.core functions that I call are all static - and thus defined.. and perhaps the reason I'm not able to call my own functions is related to my 'main' being a Java 'main' instead of a Clojure 'main'.. and perhaps this is resulting in the Clojure functions never getting bound in the first place due to some binding step getting skipped? (since this would only occur automatically with a Clojure main?) Anyway - trying to come up with theories/solutions.

bfabry19:11:25

@aletts you need to load the namespaces you want to call functions in

bfabry19:11:42

using for instance require

bfabry19:11:01

clojure.core is the only namespace loaded by default

toastbox19:11:24

"clojure.core is the only namespace loaded by default" - that helps explain what I'm seeing a lot. On Friday, I had difficulty calling 'require' in particular for some reason -- but I'll get back to trying that right now.

bfabry19:11:52

Clojure.var("clojure.core","require").invoke("you-ns-here"); should do the trick

toastbox19:11:29

ok. I had tried this (code follows):

toastbox19:11:41

` String mumbojumbo_ns_name = System.getProperty("mumbo.jumbo.system"); IFn require = Clojure.var("clojure.core", "require"); Object mumbojumbo_ns_sym = Clojure.read(mumbojumbo_ns_name); Object ns = require.invoke(mumbojumbo_ns_sym);`

toastbox19:11:02

but keep getting: Exception in thread "main" java.lang.Exception: prefix cannot be nil, compiling:(NO_SOURCE_PATH:0:0)

toastbox19:11:07

I'll try what you suggested

toastbox19:11:37

When I try the code you suggest, I get this error (I've been seeing this over the past few days as I try it):

toastbox19:11:43

Exception in thread "main" java.lang.IllegalArgumentException: Don't know how to create ISeq from: java.lang.Character

bfabry19:11:49

oh sorry you need to symbolify it

bfabry19:11:16

Clojure.var("clojure.core","require").invoke(Clojure.var("clojure.core","symbol").invoke("your-ns-here"))

toastbox19:11:00

Wow. I think that's done it. Thank you 🙂

toastbox19:11:14

my previous attempt was along the right lines.. but just wrong.

aconanlai19:11:13

does anyone here use VS Code for clojure?

seancorfield20:11:32

@aconanlai There's a #vscode channel -- no idea how active it is tho'...

petr.mensik20:11:25

Hello guys, I am looking for a solution for background jobs which should survive Tomcat server restart or moving application to another VM on AWS. I found https://github.com/metametadata/byplay which looks really promising because we are already using Postgres on separate machine and jobs shouldn't do any heavy lifting (mostly tasks like send email to a user after 2 weeks and stuff like that). Do you think it's feasible to use DB as a persistent storage for jobs or should I look somewhere else?

hiredman21:11:49

there are far worse ways to do that, I am unfamiliar with byplay, but it sounds perfectly reasonable

hiredman21:11:33

the idea of long running transactions doesn't sound great, in the past I've worked on systems that used postgres advisory locks instead, but I am not sure that is any better

petr.mensik21:11:20

Long running transaction are the only part I am worried about because there can be possibly hundreds of jobs waiting to execute and I am not sure how it can affect performance of the DB

hiredman21:11:05

I would be shocked if any database had a problem storing hundreds of things

petr.mensik21:11:23

Storing it's not the issue I thought that lot of opened transactions might be

ghadi21:11:45

generally job systems won't leave a transaction open. workers claim jobs, then relinquish them in two separate tx'es

hiredman21:11:53

having the number of open transactions scale with the number of stored jobs would be the result of a very special system

petr.mensik21:11:11

Ok, I've probably misunderstood the byplay documentation. It seems like worth trying to me, I am building a system with hundreds of users at maximum who generates some background tasks from time to time so it should scale

ajmagnifico22:11:22

Style Question: If I have global-level configuration data, how should I make that accessible to the functions in my program? I can think of 4 ways: 1) Pass ALL configuration data in a single map as an argument to each function that needs some of the config data. 2) Pass ONLY the configuration values that are NEEDED as individual arguments to each function 3) (declare) some vars for configuration, then (defn) all the functions that need access to them, then start runtime, then populate the config vars 4) Start program, read in config values, then use (let) to hold the config values while using (defn) to create closures around the config values as needed.

ajmagnifico22:11:26

I’m sure there are other ways, too.

ajmagnifico22:11:30

Does this make sense?

ajmagnifico22:11:36

Does anyone have any wisdom for me here?

noisesmith22:11:59

I do 1) in combo with using stuartsierra/component which I use to also pass all stateful shared resources in the same map with the config

tanzoniteblack22:11:46

Personally my latest project is using https://github.com/tolitius/cprop to manage the values (via merging environment, system properties, & a config file of defaults) and storing the result loaded at known times via https://github.com/tolitius/mount

noisesmith22:11:00

@smith.adriane I use environ too, but for example if a library needs config, I’d rather pass the config in from my app, rather than putting environ in the library

noisesmith22:11:12

and it turns out I have a few libraries that need config

phronmophobic22:11:07

libraries should avoid imposing too much structure on the consumers of the library

phronmophobic22:11:09

it would be annoying if a library forced you to use environ

ajmagnifico22:11:40

I haven’t used any of those. I’ll go check them out.

ajmagnifico22:11:15

It’s interesting to me that this is such a fundamental task in any programming language, but there are so many libraries to achieve this

ajmagnifico22:11:48

I’m thinking, “shouldn’t there be an obvious, idiomatic clojuric way to do this?”

ajmagnifico22:11:13

but each of the four ways I mentioned definitely have their own specific tradeoffs

phronmophobic22:11:19

there are lots of different tradeoffs

phronmophobic22:11:35

if clojure was just used for one specific domain, then you might seem more convergence

noisesmith22:11:38

4) is definitely not “clojuric” at all

noisesmith22:11:44

we don’t do much data hiding

ajmagnifico22:11:52

right, that seemed hideous as I was typing it

noisesmith22:11:22

for a similar reason, 2 is OK, but most people would prefer 1 to it

noisesmith22:11:54

and 3 is really just accessor methods, which are also not “clojuric” if we are going to use that word

noisesmith22:11:01

so that leaves 1, with a maybe on 2

noisesmith22:11:32

and you don’t need a library to do 1 or 2 - it’s a simple convention using immutable data

phronmophobic22:11:36

i tend to write small apps, but I typically use a form of 3

phronmophobic22:11:06

(def db-conn (env :db-info))

phronmophobic22:11:24

and then have a query function that uses the global db-conn

ajmagnifico22:11:41

do you use ALL-CAPS in those var names or some other convention to mark them as “coming from outside of this function” ?

ajmagnifico22:11:55

or do you just remember “db-conn” is a global thing ?

bronsa22:11:11

no all caps

ajmagnifico22:11:58

Tell me about why all caps is a bad idea

ajmagnifico22:11:14

I’ve been using clojure for about 4 years now off and on, but I feel like I still have a lot to learn

bronsa22:11:09

it's not a bad idea per se, it's just not conventional

ajmagnifico22:11:45

is there some kind of community-approved style guide that I would want to look at?

ajmagnifico22:11:08

cool, thanks!

ajmagnifico22:11:23

tell me all about it, bronsa

phronmophobic22:11:42

most of the application code doesn’t use the db-conn

phronmophobic22:11:45

cause it’s not passed around

phronmophobic22:11:57

the application code will just do (query "select 1")

phronmophobic22:11:06

i realize that might be a controversial way to do it, but most apps never outgrow by needing multiple database connections within the same app

phronmophobic22:11:15

and it’s easy to change once/if that’s the case

seancorfield22:11:50

We used to do 3) when we started out using Clojure (2011) but we've switched to 1) (or 2) for subcomponents) with Component. Much nicer.

seancorfield22:11:12

Our app has five or six DB connections @smith.adriane 🙂

seancorfield22:11:58

So we have a Database Component with a xyz-db element for each DB connection (we create connection pools at startup).

noisesmith22:11:04

also I take it back, 3 isn’t accessor methods (I misread) - but it is singletons which can be a problem

seancorfield22:11:27

Yeah, 3) is very problematic. I speak from (painful) experience 🙂

noisesmith22:11:44

and yeah, 3 is semi-popular in clojure apps, but also a common source of problems which leads to messy refactors from 3 to 2 or 1

noisesmith22:11:45

this is part of why people are skeptical of mount btw - it does some of the same things as eg. component or integrant without providing the biggest benefit which is not locking you into singletons, which is a hard thing to fix later if your app design is built around it

aaelony22:11:42

Is anyone able to run lein-marginalia aka lein marg against their codebase using [org.clojure/clojure "1.9.0-RC1"] ? The last clojure that lein marg seems to work fine with is [org.clojure/clojure "1.8.0"] in my codebase.

seancorfield23:11:24

@aaelony I assume you're getting an error? Probably from the spec checking on some macros. Probably Marginalia has illegal ns syntax that "just happened" to work on 1.8 and earlier...

seancorfield23:11:29

Or more likely, some library it depends on, having looked at the source...

spieden23:11:40

clj-uuid states that its squuids encode retrievably the posix time at which they were generated anyone know of code to retrieve the posix time? i can figure out the bit math but thought i’d ask first

seancorfield23:11:18

@aaelony I created a new empty Leiningen project, updated Clojure to 1.9.0-RC1 and added lein-marginalia "0.9.0" and was able to run it -- but maybe the problem you encountered isn't triggered on an empty project? Can you provide more detail about the problem you are having.

spieden23:11:15

actually nevermind, it’s really simple