Fork me on GitHub
#clojure
<
2017-06-23
>
michaelblume00:06:59

Would it be possible to arrange things so that (when (instance? Foo x) (.fooMethod x)) wouldn’t reflect?

michaelblume00:06:39

ie special-case compilation of (if (instance? …) …) so that the then branch was automatically hinted?

michaelblume00:06:53

…I guess this belongs in #clojure-dev

devn01:06:18

@hcarvalhoaves I was talking to the sentry folks and it sounds like the source code context will be something that's pulled from github in the near future. All of the data required to do it is there, just hasn't been plumbed into the product. I think it's better than a log aggregator, but I'm using an on-premises install which affords some extra flexibility you don't really get in the SaaS product.

bja02:06:56

@devn interesting to see that the sentry folks picked up maintaining a clojure client. I'll have to give theirs a spin to see how it compares to the fork of raven-clj (which currently works very well for me).

sgerguri08:06:43

G’day everyone, I have a macro puzzle question - how can I access an atom from within a macro? I have the following:

(def tatom (atom nil))

(defmacro tmacro
  []
  `(let [t# (deref tatom)]
     (if t#
       (prn "tatom is nil")
       (prn "tatom has value"))))

(tmacro)
"tatom is nil"
=> nil

(reset! tatom 1)
=> 1
(tmacro)
"tatom is nil"
=> nil
Anyone got any ideas as to why the atom is not being correctly deref’d here?

sgerguri08:06:39

The gist of the question is - I want to access mutable storage from within a macro, how do I do that?

bronsa08:06:44

@sgerguri the branches on your if are the wrong way around

bronsa08:06:50

also there's no need for that to be a macro

sgerguri08:06:30

This is just a contrived example, not real production code which is what this question is really about - and I want that one to be a macro for various reasons.

sgerguri08:06:58

Thanks for pointing out the ordering, I knew it had to be my morning idiocy. facepalm

valyagolev10:06:03

in which ns is the tatom ? the same as defmacro, or the same as its usage?

mfikes11:06:48

@sgerguri I can’t repro. The first call to (tmacro) causes it to print "tatom has value" and after the reset! it causes it to print "tatom is nil"

sgerguri11:06:48

Thanks guys, but as I mention above, this was just a morning brainfart on my part, with the branches reversed. This was just a contrived example that I quickly put together to verify that I can deref atoms (from the same ns, but it doesn’t really matter if they’re fully ns-qualified) and screwed up in the process.

mfikes11:06:41

@sgerguri Right, understood that the branches are reversed. I still can’t repro what you pasted above.

sgerguri11:06:38

The other half of the morning brainfart was the behaviour of things. The behaviour above cannot really be reproduced, it’s just my bad copy paste. This has stirred quite a conversation here. I wonder if I should just remove the question but the sharper minds will at least get a good laugh out of it if I leave it hanging here.

sgerguri11:06:28

Sometimes, rubber-ducking makes one look like an idiot if he uses the whole community for it.

mfikes11:06:59

OK cool. I thought you might have a bad REPL environment or something exhibiting a low-level bug.

sgerguri11:06:16

I had a few things mixed up together as I was re-defing things.

sgerguri11:06:36

Then add to that me being half asleep and this is the result. Still thanks for all the help!

nicoschneider12:06:23

for a hobby project, i’d like to implement some kind of extension system. the “modules” (or whatever they’ll be called) should be able to extend the system in various predefined ways depending on their type (think “themes”, “content elements”, …). my question relates to being able to add them “dynamically” somehow, if that’s the right word, without me having to recompile the app (but maybe the individual module?)

nicoschneider12:06:33

i’d be thankful for any pointers

dominicm12:06:15

@nicoschneider load-file should do the trick 🙂

nicoschneider12:06:16

i’m aware of the added complexities; is this maybe a bad idea in general for reasons i’m unaware of?

nicoschneider12:06:42

uh neat! thanks. with clojure it’s always those functions you find after months … 😉

dominicm12:06:46

I think Lisp is well suited to this, it was designed to receive code over sockets & such. In fact Clojure has made decisions to ensure that this is the case.

nicoschneider12:06:27

my thoughts exactly, but coming from OOP it seems so… daring

dominicm12:06:22

Well, this isn't OO vs functional. Smalltalk could do this too.

dominicm12:06:31

More about live programming I guess 🙂

nicoschneider12:06:00

i wasn’t referring to the technical aspects, more the mindset. in my experience this idea would be considered “hacky stuff”

ulath713:06:18

Hey all, compujure-api throws an exception "No such var: compojure.response/send" when I try to import it in my namespace. I'm using [org.clojure/clojure "1.9.0-alpha17"]. Anyone exprienced this issue?

a1313:06:20

what compojure version are you using?

ulath713:06:03

It is a transitive dependency over compojure-api currently. By the way the error message is like this: 2. Unhandled clojure.lang.Compiler$CompilerException Error compiling compojure/api/async.clj at (24:1) 1. Caused by java.lang.RuntimeException No such var: compojure.response/Sendable

ulath713:06:20

That means the version of the compojure 1.6

gaverhae13:06:40

what compojure version does lein deps :tree report?

ulath713:06:49

Ok another dependency overrides it I will try with an explicit dep

ulath713:06:05

Ok it did work thanks!

gaverhae14:06:41

Be slightly careful when adding an overriding dep like that as the final result depends on the order of the dependencies vector; it's safer to add explicit :excludes in addition to pinning the version.

tmountain14:06:10

if I have an initial value 100, and I want to apply successive arbitrary functions to it which will result in a final value, what's a good way to do so? I'm looking for something that would allow me to do this: (some-fn 100 [:inc :dec :set-50 …])

tmountain14:06:34

or something in the spirit of that at least 😉

dpsutton14:06:41

could be a really elegant reduce in there

dpsutton14:06:17

(reduce (fn [val fn] (fn val) 100 [functions go here])

rinaldi14:06:17

Why in Clojure we are encouraged to use recur instead of making self-calls? I imagine is for performance reasons but couldn't find much information about it.

tmountain14:06:53

(reduce (fn [val fn] (fn val) 100 [dec dec dec]) gives an error: Wrong number of args (1) passed to: core/reduce

dpsutton14:06:10

your parents are off

dpsutton14:06:15

ah because mine were

dpsutton14:06:33

(reduce (fn [val fn] (fn val)) 100 [functions ...])

bostonaholic14:06:58

> your parents are off

tmountain14:06:26

that works beautifully, thank you

bostonaholic14:06:27

that’s some deep stuff

hcarvalhoaves14:06:40

> Since Clojure uses the Java calling conventions, it cannot, and does not, make the same tail call optimization guarantees. Instead, it provides the recur special operator, which does constant-space recursive looping

rinaldi14:06:02

hcarvalhoaves: Awesome, that makes sense. Thank you Henrique.

dpsutton14:06:41

didn't mean to get so personal 🙂

tmountain14:06:00

oh, they are, trust me 😉

dpsutton14:06:29

((apply comp [dec dec dec]) 100)

noisesmith16:06:54

dpsutton: a goofy version of this ((apply comp (repeat 3 dec)) 100)

dpsutton16:06:24

he wanted for arbitrary functions. the three decs are just placeholders

noisesmith16:06:44

right, I called it goofy for a reason

dpsutton14:06:38

you could also just apply compose

dpsutton14:06:54

which is very much the mathematical definition of what you want to do. really conveys the intention

dpsutton14:06:03

"compose these functions and apply them"

tmountain14:06:27

ah, I like that solution

chrisdavies16:06:49

I'm curious how you all configure your web services? There seem to be a large number of libraries out there to do this. Is there one that is generally considered "the Clojure way"?

mpenet17:06:07

juxt/aero is nice. Or just env vars (with or without environ)

hmaurer17:06:54

Hi! Is anyone familiar with Datomic here?

ghadi17:06:25

there is dedicated #datomic room @hmaurer

hmaurer17:06:45

@ghadi oh sorry, I hadn’t noticed. Thanks

ghadi17:06:57

np. lots of helpful cognitect people seem to hang there

bja18:06:14

@chrisdavies I usually see people pull config out of the environment ("12 factor"), a properties file, or (more rarely) an edn config. There is a commonly used library called environ that does this, but you could just use System/getProperties or System/getenv without needing a dependency. I feed certain values like an HTTP_PORT to my web server. I use immutant.web, which uses Undertow under the hood, but a lot of people use http-kit or Jetty. My web server knows how to serve a Ring handler (which is a spec for http handlers in the vein of Python's WSGI or Ruby's Rack), and I use a library for mapping http routes to handlers called compojure-api.

bja18:06:56

@chrisdavies I usually suggest people take a look at Luminus (http://www.luminusweb.net/) which is a curated collection of libraries and docs until they form their own opinions on library choices.

dorab18:06:44

@chrisdavies I don't know if there is a "Clojure way" but try cprop https://github.com/tolitius/cprop or juxt/aero https://github.com/juxt/aero

chrisdavies19:06:27

Thanks dorab and bja!

hmaurer20:06:16

Hi! I am having a little issue setting up Datomic Starter. I posted this message in #datomic but I suspect it might be a more general clojure/jvm question. Here is the error I am getting: https://gist.github.com/hmaurer/b9d303055c7a9b7c4e4827b5b79e2acc

chrisdavies20:06:32

@hmaurer I can't help you, but would you mind updating us with the solution when you find it?

chrisdavies20:06:53

Also, I like to open these kinds of questions on StackOverflow and then answer them when I find a solution. Helps everyone!

hmaurer20:06:21

@chrisdavies sure thing, although I suspect it’s an issue due to my own ignorance and not a problem with Datomic’s tutorial

chrisdavies20:06:37

Well, I'm also ignorant, so your answer will help me. 🙂

hmaurer20:06:06

@chrisdavies it’s odd, the jar doesn’t seem to contain any “peer server”

chrisdavies20:06:23

That is odd. It sounds like maybe you have an invalid installation or something.

chrisdavies20:06:41

What version of Datomic did you download?

hmaurer20:06:15

The latest one, but I also tried 0.9.5561 (the one mentioned in the “Getting Started” guide, and I downloaded an earlier version just to check they didn’t rename the peer server

chrisdavies20:06:56

Hm. I haven't messed with Datomic at all, but I'm planning on doing it soon. So... yeah... definitely let us know what you find, if you ever resolve it.

chrisdavies20:06:42

What do Clojurists use to send emails? A bit of searching turned up this: https://clojars.org/org.clojars.sethtrain/postal Which looks nice and Clojurey, but it only has 250ish downloads...

chrisdavies20:06:45

That seems pretty popular... I wonder, is there a way to sort clojar search results by popularity?

hmaurer20:06:58

@chrisdavies I didn’t realise there was difference between “datomic free” and “datomic starter”

hmaurer20:06:06

datomic free does not include the peer server

chrisdavies20:06:52

Ah! I see. What's the point of "datomic free", I wonder?

chrisdavies20:06:59

Thanks for posting the solution!

hmaurer20:06:57

@chrisdavies I have expanded on the topic in #datomic

hmaurer20:06:05

quoting this google group:

hmaurer20:06:06

> The primary use case for Free is not new users, but rather people who need a license that includes redistribution rights.

j-po21:06:04

I think (-> 100 inc dec set-50 ...) is the most idiomatic way to do this.

eriktjacobsen21:06:15

(fn [value fn-list] ((apply comp (reverse fn-list)) value))

dpsutton21:06:54

^ that's the one we settled on. i always forget the order of comp so i left off the reverse earlier

xiongtx22:06:36

dpsutton: Order is same as in math:

((comp h g f)x)    ; => h(g(f(x)))

noisesmith23:06:47

@j-po the problem with -> is it isn’t a function composition, it’s a syntax. You can’t pass it a list of functions.

j-po23:06:57

Valid. I hadn't inferred that the list part was important. My bad!