Fork me on GitHub
#clojure
<
2018-01-01
>
kaosko20:01:44

any immutant users here? does immutant have a proxyname configuration similar to tomcat, for when it's run behind a proxy?

kaosko20:01:56

oops, wrong channel

dl20:01:35

hey guys

dl20:01:47

anyone going to the conference in New Orleans in February?

mjo324_5621:01:53

how do i return json with COMPOJURE ?

mjo324_5621:01:07

a fool proof way, like with one line of code

mjo324_5621:01:25

the examples in the net are to difficult for an idiot like me

mjo324_5621:01:15

like (GET "/mystuff" (jsonFUNC [ 1 2 3]))

mjo324_5621:01:24

that's all i need

noisesmith21:01:56

are you aware that compojure is a router?

mjo324_5621:01:07

@noisesmith i want to get a json document if the user goes to http://www.mysite.com/mystuff

noisesmith21:01:41

right, my point is that compojure is a library for routing requests to request handling functions

noisesmith21:01:13

there's ring middleware for returning json, compojure is used with ring

mjo324_5621:01:49

is there anything i can copy paste?

noisesmith21:01:37

that library I just linked to has a function called wrap-json-response, if you call that and pass your handler as an argument, it returns a new handler that returns json (edit, fixed function name)

mjo324_5621:01:35

i dont understand,

mjo324_5621:01:36

(wrap-json-response [my-json])

noisesmith21:01:04

your handler is the function that processes a request

noisesmith21:01:27

(wrap-json-respone my-handler) returns a new function, it will have json as its body

mjo324_5621:01:26

it is not possible to return a json without diving into the abstract mechanisms of handlers?

noisesmith21:01:47

you can create a json string, if you return a string that's what ring returns

mjo324_5621:01:50

i am sorry that i am too dumb to understand this concept of handlers in these circumstancesw

noisesmith21:01:18

you have a handler, you can't serve requests without a handler

noisesmith21:01:35

if you call wrap-json-response with your current handler as an argument, it returns a new handler

noisesmith21:01:37

use that one

noisesmith21:01:41

that's the whole thing

noisesmith21:01:54

or, you can use cheshire/generate-string, if you handler function returns a string, ring will give that string to the client as the request body, tha's another option but it's more complicated

mjo324_5621:01:58

(GET "/mystuff" [ 1 2 3]) should work if there's before wrap-json-response?

mjo324_5621:01:26

(GET "/mystuff" {jsonstuff})

noisesmith21:01:34

somewhere in your code you start a server, you pass an argument to the server, that argument is a handler

mjo324_5621:01:25

yes, i use reagent, it uses lot of stuff

mjo324_5621:01:29

i have a handler

noisesmith21:01:32

this has nothing to do with reagent

mjo324_5621:01:35

i can return fancy html

mjo324_5621:01:48

i want siomply to return a json ebject instread of html

noisesmith21:01:09

I've told you two different ways to do this already

noisesmith21:01:34

you either call cheshire/generate-string on your data, or you wrap the function returning the data in wrap-json-request

mjo324_5621:01:39

ok, this means that i did not understand neither of them at all

noisesmith21:01:45

right, good luck

mjo324_5621:01:49

(defn json-response [data & [status]] {:status (or status 200) :headers {"Content-Type" "application/json"} :body (json/generate-string data)})

mjo324_5621:01:59

this is what i was looking for

mjo324_5621:01:09

that used anothwer library, i'll try the cheshire one, that seems like something that i could understand

noisesmith21:01:25

you don't need that

noisesmith21:01:32

all you need is the json/generate-string

mjo324_5621:01:03

(GET "/get-wixas" [] (generate-string {:foo "bar" :baz 5}))

mjo324_5621:01:09

thiks one works

seancorfield21:01:31

@mjo324_56 It sounds like you're fairly new to Clojure so you might find #beginners to be a better venue for asking these sorts of questions? There are over 11,000 people in this channel but in #beginners folks have opted in to helping folks who are new to Clojure and/or struggling with basic concepts.

zignd22:01:41

Hi there, I have a custom Cheshire encoder being added like so:

(add-encoder ValidationError
    (fn [v jsonGenerator] ...))
ValidationError is a Schema class defined with deftype and I have it imported like so:
(ns foo.setup
  (:import [schema.utils ValidationError]))
The code works well when it's being executed with leiningen in my :dev profile, but it fails to compile to a jar file. Here's my uberjar configuration:
:uberjar {:aot  :all
        :main foo.main}}

zignd22:01:56

Here's the error I get when I try to compile it:

zignd22:01:06

The deftype doc has a few considerations about AOT compiling and how it dynamically generates bytecode for the class, could it be related somehow? I seriously have no idea. By the way, the foo.main namespace is tagged with the :gen-class directive.

hiredman22:01:58

you are importing the generated class, but not loading the clojure code that generates the class

hiredman22:01:25

the best thing to do is to not treat deftypes like java classes that you use via import

hiredman22:01:16

deftype (if I recall, I generally use defrecord) generates a factory function something like ->TypeName that takes the same arguments as the constructor

hiredman22:01:43

use that instead, and you won't end up using the class without first loading the clojure code to generate the class

hiredman22:01:54

in general though, you most likely shouldn't be using deftype at all, and you shouldn't be aot compiling

zignd22:01:14

that's a great tip! thanks @hiredman I required the namespace and it worked. but I will try this another approach you mentioned, seems less error prone

zignd22:01:26

most of the time i use defrecord just like you mentioned, i think there's something advertising against deftype in the book i read

zignd22:01:42

but why did you say i shouldn't be aot compiling?

hiredman22:01:53

most projects don't need to be aot compiled. aot compilation is a process with edge cases and unintended consequences, you can end up with weird issues related to types and type visibility and types with the same name that are not the same type. better to leave it out

zignd23:01:22

@hiredman thanks, i understand it now! and by removing :aot :all from by :uberjar configuration leiningen used aot compilation only on my main namespace.

hiredman23:01:48

that is unlikely

zignd23:01:14

seriously? i got it wrong then

hiredman23:01:46

any namespaces loaded while aot compiling your main namespace will also be aot compiled (and so on)

zignd23:01:03

i thought it had compiled only the main one because the logs showed that only the main one was being compiled, when i use :aot :all i get compiling logs for every namespace in the project

hiredman23:01:43

this confusion is one of the reasons it is best to avoid aot compiling

hiredman23:01:19

if I recall the message being printed out is coming from lein when it calls the clojure compiler to compile a given namespace

hiredman23:01:59

but the compiling of transitive dependencies is something the clojure compiler does and lein doesn't have visibility into it

hiredman23:01:09

best to not do it at all

zignd23:01:12

oh i get it now, but is it possible to build an uberjar through leiningen without aot compilation at all? this might be a silly question, but i also couldn't find any docs on how to build the uberjar and turning off this setting. and when I remove the :aot directive it still takes the main namespace for aot compilation according to its logs, in your post you described the steps by loading the project directly from the clojure.jar.

hiredman23:01:59

if you leave out the :aot directive, lein shouldn't aot compile anything

hiredman23:01:44

if you are setting :main the default is to aot compile it

hiredman23:01:56

there is no reason to set :main

zignd23:01:39

oh got it, thanks a lot!

sophiago23:01:11

I'm hoping to clarify my understanding of the JVM wrt to why we chunk seqs at 32 elements. Native x86-64 has 64 byte data buses, so with 64 bit types that means 8 are read from cache at once (assuming no misses). Clojure's built-in data structures box elements, and I have no idea how much additional memory that takes, so we're chunking at >4x a native cache line. However, I assume the JVM works differently than native. Can anyone explain?

vemv23:01:56

I'd say the chunk seq size is orthogonal to CPU architectural concerns... A seq can contain e.g. 32 very-large arbitary objects. Maybe just a handful of those elements would surpass already what a CPU cache can retain. So the 32 is more like a sensible general-purpose default - a "not too big not too small" number.

schmee00:01:41

32 is also the branching factor of Clojures persistent data structures, dunno if that is related though

sophiago00:01:07

From what I can recall, using 32 as the branching factor on the JVM was determined by experimentation. Chunking may be based on that and have nothing to do with the size of JVM cache lines.