Fork me on GitHub
#clojure
<
2016-03-14
>
cky00:03:23

The Raleigh-Durham-Chapel Hill area is known as the Triangle (short for Research Triangle), so the local Clojure meetup is called TriClojure: http://www.meetup.com/TriClojure/

cky00:03:30

It’s nice in that, at least for the first couple of years, Clojure/conj was also hosted locally, so I was able to attend the 2011 one. 😄

cky00:03:47

BTW, that picture in the Meetup link? That’s of the Cognitect office. 😛

cky00:03:10

which hosted a number of TriClojure (and West End Ruby) meetups in the past.

schrepfler00:03:05

I suppose there’s isomorophic clojurescript running between the browser and node, but is there isomorphic clojure server rendering/passing data to closurescript SPA’s?

maxov03:03:16

you could certainly share code between clojure and cljs with reader conditionals, and there’s implementations of hiccup for cljs that would allow you to render it on the client side

tianshu03:03:58

I ran into a problem:

(ns tunnel.datomic
  (:require [com.stuartsierra.component :as component]
            [datomic.api :as d]
            [ :as io])
  (:import datomic.Util
           com.stuartsierra.component.Lifecycle))

(defrecord DatomicDatabase [uri schema initial-data connection]
  Lifecycle
  (start [component]
    (d/create-database uri)
    (let [c (d/connect uri)]
      @(d/transact c schema)
      @(d/transact c initial-data)
      (assoc component :connection c)))
  (stop [component]
    (d/delete-database uri)
    (assoc component :connection nil)))

(defn new-database [db-uri]
  (DatomicDatabase.
    db-uri
    (first (Util/readAll (io/reader (io/resource "data/schema.edn"))))
    (first (Util/readAll (io/reader (io/resource "data/initial.edn"))))
    nil))
When lein run without :aot :all, It works fine. However, here will be a ClasssNotFoundException when I run with :aot :all. Is thereany works must be done for AOT-compile?

tianshu03:03:36

ClassNotFoundException => com.stuartsierra.component.Lifecycle

tianshu03:03:38

After some search on stackoverflow, I'm going to reinstall my leiningen, and rm .m2 and .lein

nasko03:03:03

I am trying to implement a real-time chat service into an existing compojure/ring web application. I looked into using Lamina but was quickly dissuaded after seeing it's about to be deprecated. What are there some viable alternatives you'd recommend?

tianshu03:03:19

rm .m2 and .lein solve my problem, don't know why 😂

tianshu04:03:13

I'm wrong, I forgot I've removed :aot :all, the problem still exists.

sveri06:03:40

@nasko did you look at sente?

hiredman06:03:57

doglooksgood: you should implement the protocol for the record

component/Lifecycle
no the interface generated behind the scenes for the protocol

tianshu06:03:06

@hiredman: remove import, and use component/Lifecycle doesn't solve the problem.

Exception in thread "main" java.lang.ExceptionInInitializerError
        at clojure.lang.Namespace.<init>(Namespace.java:34)
        at clojure.lang.Namespace.findOrCreate(Namespace.java:176)
        at clojure.lang.Var.internPrivate(Var.java:151)
        at user.<clinit>(Unknown Source)
Caused by: java.lang.NoClassDefFoundError: com/stuartsierra/component/Lifecycle, compiling:(user.clj:1:1)
        at clojure.lang.Compiler.load(Compiler.java:7239)
        at clojure.lang.RT.loadResourceScript(RT.java:371)
        at clojure.lang.RT.loadResourceScript(RT.java:358)
        at clojure.lang.RT.maybeLoadResourceScript(RT.java:354)
        at clojure.lang.RT.doInit(RT.java:468)
        at clojure.lang.RT.<clinit>(RT.java:330)
        ... 4 more
Caused by: java.lang.NoClassDefFoundError: com/stuartsierra/component/Lifecycle
        at java.lang.ClassLoader.defineClass1(Native Method)
        at java.lang.ClassLoader.defineClass(ClassLoader.java:760)
        at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
        at java.net.URLClassLoader.defineClass(URLClassLoader.java:467)
        at java.net.URLClassLoader.access$100(URLClassLoader.java:73)
        at java.net.URLClassLoader$1.run(URLClassLoader.java:368)
        at java.net.URLClassLoader$1.run(URLClassLoader.java:362)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(URLClassLoader.java:361)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
        at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
        at java.lang.Class.forName0(Native Method)
        at java.lang.Class.forName(Class.java:348)
        at clojure.lang.RT.classForName(RT.java:2154)
        at clojure.lang.RT.classForName(RT.java:2163)
        at tunnel.datomic$fn__17714.<clinit>(datomic.clj:11)
        at tunnel.datomic__init.load(Unknown Source)
        at tunnel.datomic__init.<clinit>(Unknown Source)

tianshu06:03:28

Is that the defprotocol will generate the class dynamically, so actually the .class for component/Lifecycle does not exist?

hiredman06:03:25

have you run lein clean?

hiredman06:03:03

that is in error in a file called user.clj

hiredman06:03:33

but I guess line one of user.clj loads tunnel.datomic

hiredman06:03:10

I would guess, since you mentioned aot compiling at one point that for some reason you have some stale compiled class files in target, given that you changed the code and the error didn't change

tianshu06:03:25

I've run lein clean.

hiredman06:03:22

maybe rm -rf target/ for good measure

tianshu06:03:36

Does aot care about the source-paths?

hiredman06:03:17

what else is in user.clj?

tianshu06:03:23

(ns user
  (:require [reloaded.repl :refer [system init start stop go reset]]
            [tunnel.system :refer [prod-system]])
  (:gen-class))


(defn -main [& args]
  (reloaded.repl/set-init! prod-system)
  (go))

tianshu06:03:11

The file where prod-system is defined, require the tunnel.datomic. But tunnel.system and tunnel.datomic are not in the same directory.

hiredman06:03:36

that user.clj is rather odd

tianshu06:03:14

I have two user.clj, one for dev and one for prod.

hiredman06:03:10

files named user.clj at the root of the classpath have some special behavior in the clojure runtime, and the user namespace is created by the clojure runtime, so you don't need the ns macro, and you shouldn't creating your app entry point in user.clj

tianshu06:03:53

okay, I'm going to rename it.

hiredman06:03:11

don't use a single segment namespace

hiredman06:03:51

(they sort of work, but clojure ends up compiling them as classes without a package which is a bad practice on the jvm)

hiredman06:03:20

if the reason you aot compiling is just to get a main entry point, you can use something like

java -jar your-uber-jar.jar clojure.main -m your.namespace
instead

hiredman06:03:33

aot compilation is best avoided

tianshu06:03:14

why I should avoid aot compilation?

hiredman06:03:05

because you end up chasing issues like this

hiredman06:03:16

why should you use aot compilation?

tianshu06:03:51

I think aot will speed up the program?

tianshu06:03:05

It works, after I rename the user.clj!

hiredman06:03:18

aot will make the initial loading slightly (barely) faster

hiredman06:03:38

but either way, you get jvm bytecode that the jvm will run and jit as needed

hiredman06:03:54

aot does not effect runtime performance

tianshu06:03:31

Okay, whatever I shouldn't use user.clj.

hiredman07:03:46

clojure is always compiled to the same jvm bytecode, aot compiled or not

hiredman07:03:12

aot compilation just saves off the same bytecode the compiled generates for loading in the future

tianshu07:03:42

So aot will make the size of jar larger?

hiredman07:03:30

it might, I doubt by much though, unless you are using a lot of really intense macros

tianshu07:03:26

I unzip the uber-jar, I found there're lot of .clj and .java, is these files necessary?

hiredman07:03:36

it is complicated, the ,java generally isn't, but the uberjar is your code combined with the code of all your dependencies, so if your dependencies include the .java source in their jar for whatever reason, you will end up with it in your uberjar

hiredman07:03:51

the .clj code is more complex of an answer because clojure's runtime includes the compiler, so the .clj could be turned in to jvm bytecode to be executed at anytime

hiredman07:03:45

in theory if you aot compile clojure, you'll be left with classfiles, and you don't need to load the .clj, but there are some provisos to that

hiredman07:03:15

some things that aren't really code, but data, end up using the .clj extension too

hiredman07:03:41

(like having a file containing json in your jar)

tianshu07:03:40

Thanks for answer in detail!

jimmy10:03:38

@urbanslug: in short mult is some kind of "broadcast" operation with go async. If you wonder what is the difference between pub and mult then Timothy has a comprehensive answer for it : http://stackoverflow.com/questions/22530610/whats-the-difference-between-pub-and-mult-in-core-async-a-sample-usecase

urbanslug10:03:04

nxqd: I don’t even see why we need mult in the first place.

dialelo11:03:30

whenever you need to broadcast values put in one source channel to multiple "sinks"

dialelo11:03:50

you can build it yourself with core.async primitives but is nice that it offers several higher-level abstractions: mult, pub-sub & mix

mrjaba11:03:42

I don't suppose anyone knows the status of clj-http 3.0 do they? I just ran the tests and they all passed on master, the readme says that was what's holding up the 3.0 release. Curious to know if it'll be soon or not

dialelo11:03:46

don't know about the state of the project but note that you can release you own versions of libraries in Clojars changing their group id @mrjaba

dialelo11:03:06

so you could publish under mrjaba/clj-http and depdend on it until the clj-http authors release the 3.0 version

mrjaba11:03:10

Ah didn't know that, thanks, might be worth a go. Fingers crossed it's done soon simple_smile

dialelo11:03:43

yeah, probably a matter of the authors having some spare time to cut a new release

mrjaba11:03:05

yeah was running the tests to see if there was much I could help with, seems not!

tcrawley12:03:42

@mrjaba: note that the preferred group for a fork would be org.clojars.mrjaba - clojars will show those as non-canonical forks in the search results: https://clojars.org/search?q=org.clojars.tcrawley

mrjaba13:03:07

@tcrawley: cool, thanks for the tip

tcrawley13:03:15

my pleasure

danielstockton13:03:48

What could be the reason for the following error when running lein test aaas.core-test? Exception in thread "main" java.lang.ClassNotFoundException: aaas.core-test, compiling:(aaas/core_test.clj:1:1)

danielstockton13:03:36

I have (ns aaas.core-test in test/aaas/core_test.clj

danielstockton13:03:33

Oh dear, I've been struggling with this for hours and justs realised i'd mistyped the namespace

danielstockton13:03:39

I had (:ns aaas.core-test

darnok14:03:59

How to work with records/protocols and plumatic schema? There are no macros for checking types. What approach should I use? I have a protocol Sender in my app that has send method which sends message that is a map with :body and :to keys. I wanted to document/check that with plumatic/schema.

bteuber14:03:05

Hi, I’ve got a lazy seq question: (fn [huge-lazy-seq] (->> huge-lazy-seq rest (reduce f))) Would that hold onto the head and thus create a memory problem?

rickmoynihan14:03:46

not normally - at least

em14:03:12

Hi, I've been looking for an XPath-like tools for working with Clojure data structures. (Please note: I am not looking for a tool that works with XML) Is there such a thing? If not, is there an easy way to do operations like this: for example, "Given a data structure, find me all maps that contains key :xyz."

rickmoynihan14:03:39

@em: you can use assoc-in update-in etc... or look at something like specter if you need more: https://github.com/nathanmarz/specter

rickmoynihan14:03:03

but depending on the datastructure and exactly what you want to do there are lots of options... e.g. core.zip tree-seq etc...

rickmoynihan14:03:13

sorry - just realised I misread - your question if you're finding things - obviously don't use assoc-in/update-in simple_smile - you can do things like this too of course (-> {:foo {:bar "baz"}} :foo :bar)

rickmoynihan14:03:01

and combine with whatever else you might need e.g. some/filter/remove etc...

em14:03:57

Thanks @rickmoynihan, specter is interesting. I'll look into it. I'm currently looking for something: 1. That works with all (most) clojure data structures. (the way clojure.walk does) 2. I want it to return a sequence of all sub-data structure that match a criteria.

dm314:03:47

@em: something like https://github.com/davidsantiago/hickory/blob/master/src/hickory/select.cljx only not specific to HTML? Hickory uses zippers with some predicates on top to select through a map representation of an XML document

em14:03:17

@dm3. Thank you. I think you are saying I can look at hickory as a code sample, which I will do.

ghadi19:03:07

What's the recommended JVM LDAP library?

nasko19:03:15

Thanks @sveri, I'll look into sente

cky20:03:30

@ghadi: The standard JVM LDAP interface is called JNDI. But I don’t know how easy it is to use JNDI with Clojure; I’ve never tried.

bherrmann20:03:18

At first blush, the Scala Center, <HTTP://scala.EPFL.ch> looks pretty cool. Is there anything like this in clojure land?

fasiha20:03:42

From experimentation, Clojure reader conditionals (combined code for Clojure & ClojureScript, etc., e.g., #?(:clj (java.util.Date.) :cljs (js/Date.))) are only allowed in .cljc files. Is this indeed the case?

cky20:03:34

Surely it’s the only place where such things make sense?

fasiha20:03:48

@cky: hah, in retrospect that's obvious and you're right.

jonahbenton21:03:37

@ghadi use spring-ldap http://projects.spring.io/spring-ldap/. JNDI is not an LDAP implementation

cky21:03:52

@jonahbenton: To be fair, ghadi was asking for an LDAP library, not an implementation.

cky21:03:39

But Spring LDAP does sound like a good project for this purpose.

bherrmann21:03:12

I've used clj-ldap but only briefly... It seemed to work

jonahbenton21:03:45

hey @cky, sure- my comment was just to the point that JNDI is more of an wrapper around directory services in the abstract; to talk to LDAP in particular from JNDI you still need something to bridge from JNDI to LDAP, plus JNDI configuration. Might as well just talk directly to LDAP...but can work either way

talios22:03:41

@cky @ghadi I’d avoid the JNDI LDAP stuff. I’ve used https://github.com/pauldorman/clj-ldap with nice success in the past tho

cky22:03:05

@talios: Good to know. Thanks!

talios22:03:21

(ldap/add conn entry-dn {:objectClass #{"top" "domain"}})
- nice and clean. Just works with clojure maps and hides all the mess

talios22:03:38

it wraps the UnboundID LDAP libraries ( nicest java LDAP libs I’ve seen - they also have a nice in-memory pure java LDAP server which we use for integration tests )