Fork me on GitHub
#beginners
<
2015-12-11
>
rishat01:12:15

Hey, channel, is there a tutorial for complete beginners that would cover environment and editing part of Clojrue? Like, what is lein, where do I get it, how to install it, how do I make a Hello, World app, how do I put it on whatever server I have? I mean, I'm good with FP, Clojure syntax and its standard lib but, since I've lived in REPL all this time, I'm completely lost when it comes to deploying an app to a server.

seancorfield01:12:24

(Brave and True is an awesome learning resource)

seancorfield01:12:47

It also covers editing in Emacs on the next page.

roelof06:12:15

Why does this code :

(defn convert-back
  "convert the map back to strings"
  [records]
  (reduce (fn [it] (str (:name it) "," (:glitter-index it) "\n" )) "" records )
  )

(convert-back [{:name "roelof" :glitter-index 2}]  ) 

roelof06:12:22

gives this output ; "roelof,2\n" so why is the \n not executed but printed

seancorfield06:12:19

Did you print the output or just let the repl display the value?

roelof06:12:05

I did repl dis play the output , @seancorfield

roelof06:12:22

@seancorfield: thanks. this convert a map back to the orginal file : (println (reduce (fn [ acc it] (str (:name it) "," (:glitter-index it) "\r\n" acc )) "" records ))

roelof06:12:44

I wonder why the exercise says to use string/join

seancorfield06:12:52

(string/join "\n" (map (partial string/join ",") (map (juxt :name :glitter-index) records))) off the top of my head, untested (since I'm on my phone)

roelof06:12:12

nice one , only the book has not explained juxt but I know that on the last exercises you have to look further into things then explained

seancorfield06:12:47

No idea about that. I was just trying to show a string/join solution 😸

roelof06:12:57

it worked. only windows needs a /r/n

roelof06:12:56

Chips, I do not . I see this output in repl : "Edward Cullen,10\r\nBella Swan,0\r\nCharlie Swan,0\r\nJacob Black,3\r\nCarlisle Cullen,6"

roelof06:12:07

or must i use println again ?

seancorfield07:12:23

Only print (or println) will convert the escapes into actual new lines.

roelof07:12:56

oke, thanks for the explanations

agile_geek07:12:24

@cjmurphy: the f namespace qualifier in f/formatter resolves to [clj-time.format :as f]. Sorry i should have expanded the example to the fully qualified namespace.

agile_geek10:12:23

@roelof: @billypiston: FIrstly, (with-out-str ...) temporarily rebinds *out* to capture what is printed and return a string instead.

agile_geek10:12:03

so instead of printing to System.out the println will return the value printed as a String which then gets returned as the body of the http response

agile_geek10:12:25

@billypiston: If I understand you correctly you want to extract the value posted from the http request, test if it's less than 18 and return different responses?

agile_geek10:12:34

Without going through the full solution (you need to think about these things to learn) the bit of your code that does this:

agile_geek10:12:06

(POST "/saveform" req
                (with-out-str (clojure.pprint/pprint (:params req)))))

agile_geek10:12:45

is extracting the params from the req map here: (:params req)

agile_geek10:12:45

and then printing it within the scope of the with-out-str which, as discussed returns the String value of the params passed in the http request.

agile_geek10:12:11

so you can test the params value extracted using if

agile_geek10:12:04

I leave you to try that. Just try returning different strings depending on whether the value is < 18 or >= 18.

roelof10:12:01

@agile_geek: so param holds the value of the form ?

roelof10:12:42

how can i print that out or does pprint do that ?

agile_geek10:12:05

Yes. You should be able to see what is in params when you run this and submit the form from the browser as the pprint outputs the contents of params (translating the Clojure data structure to a String in the process) and with-out-str catches the output of pprint before it writes to the console and turns it into a String returning it in the http response.

agile_geek10:12:51

So what you see in the browser is the string representation of the contents of params posted in the http request

roelof10:12:42

oke, so the param are visible on the page saveform

roelof10:12:48

I could not make it run with lein run on Cursive because there is no :main in the project.cli as billypiston stated in the clojure channel

agile_geek10:12:16

@roelof: try lein ring server from terminal session.

roelof10:12:58

moment, I have to make the project again

roelof10:12:26

I think I will do lein new compojure test also with the prompt

agile_geek10:12:38

I'm going to have to go back to work but I'll check in later.

roelof10:12:50

have a good working day

roelof10:12:40

first problem : when I change the code from the template compojure-app to this : https://www.refheap.com/112580 on handler.js . I see this error message when running lein ring server : Exception in thread "main" java.lang.RuntimeException: Invalid token: ring.middleware.params:, compiling:(test/handler.clj:9:37)

agile_geek11:12:56

@roelof: Slack has translated (:params req) to :simple_smile: params req)

roelof11:12:13

when I changed that to (with-out-str (clojure.pprint/pprint ( :params req))))) I still see the same error

roelof11:12:17

I see there is some problem with this part : [ring.middleware.params: refer [wrap-params]]

roelof11:12:42

or this line (POST "/saveform" req

roelof11:12:22

I see this error Exception in thread "main" java.lang.RuntimeException: Invalid token: ring.middleware.params:, compiling:(test/handler.clj:9:37)

ordnungswidrig11:12:59

[ring.middleware.params :refer [wrap-params]] it must be

roelof11:12:09

Thanks, another error Invalid token: clojure.pprint

roelof11:12:36

in this line (with-out-str (clojure.pprint/pprint (:params req)))))

ordnungswidrig11:12:01

roelof: the : indicates a clojure „keyword“, in the paste above, the same error is on lines 9 to 12

ordnungswidrig11:12:35

it’s some.namespace :refer [var1 var2], not some.namespace: refer [var1 var2]

roelof11:12:11

oke, slack has messed up things well

ordnungswidrig11:12:33

this should fix it:

roelof11:12:29

next one : Map literal must contain an even number of forms, compiling:(test/handler.clj:31:62

roelof11:12:47

I try to help someone but the code is full of errors

ordnungswidrig11:12:50

you should now be able to fix it simple_smile

ordnungswidrig11:12:59

still a misplaced :

roelof11:12:44

I give up, I think this is wrong :type = "button" but when I change it to :type button

roelof11:12:12

I see a message that unable to resolve symbol get

roelof11:12:26

I think the person first must make this work before I can help him/her

ordnungswidrig11:12:41

any maybe read some intro to clojure tutorial

billypiston12:12:58

Hi, everybody! Help to solve my task please. I ask for help as I only started studying Clojure. Про меня выше писал #roelof

billypiston12:12:32

Prompt please in the solution of a task. I have a clojure-project. I use a hiccup and Bootstrap styles. Everything works, but here only I don't understand as conditional operators work. Here my code: Project.clj file: (defproject yupppie "0.1.0-SNAPSHOT" :description "FIXME: write description" :url "http://example.com/FIXME" :license {: name "Eclipse Public License" :url "http://www .http://eclipse.org/legal/epl-v10.html" } :dependencies [[org.clojure/clojure "1.7.0"] [ring "1.4.0"] [compojure "1.4.0"] [hiccup "1.0.5"]] :plugins [[lein-ring "0.9.7"]] :ring {: handler yupppie.core/app }) Yupppie.core file: (ns yupppie.core simple_smile require [compojure.core: refer: all] [compojure.route: as route] [ring.middleware.params: refer [wrap-params]] [clojure.pprint: refer: all] [hiccup.core: refer: all] [hiccup.page: refer [include-css include-js]])) (defn home [] (html [: head (include-css "/bootstrap-3.3.6-dist/css/bootstrap.min.css") (include-css "/styles.css") (include-css "https://fonts.googleapis.com/icon? family=Material+Icons") (include-js "/bootstrap-3.3.6-dist/js/bootstrap.min.js")] [: body [: div {: class "col-lg-6" } [: div {: class "input-group" } [: input {: type "text": class "form-control": placeholder "How old are you?" } [: span {: class "input-group-btn" } [: button {: class "btn btn-default": type = "button" } "Go, baby!"]]]]]])) ; (defroutes app (route/resources "/") (GET "/" [] (home)) (POST "/saveform" req (with-out-str (clojure.pprint/pprint simple_smile params req))))) (def apps (wrap-params app)) I began to study it recently so so far not really I understand. I have a simple form. And at input in the field of figure less than 18 and pressing the button, it is necessary to make so that the picture was shown, and at input of figure 18 or more other picture. Here is how to me to use the conditional operator if that it earned?

billypiston12:12:12

I can't understand where to insert a code with the conditional operator.

billypiston12:12:55

It is necessary for me that at input in the field of figure less than 18 one picture and if in the field entered figure 18 or more, other picture was shown.

snowell12:12:57

@billypiston: Please use refheap/pastebin for big chunks of code, or at least surround it with ` so Slack formats it nicely simple_smile

billypiston12:12:52

Well. I apologize. I will conform to the rules. Simply I the first time use Slack.

surreal.analysis13:12:43

When copying it over, it seems like slack converted some things to smilies

surreal.analysis13:12:47

Making it very hard to parse

roelof14:12:37

yep, and very hard to help you

roelof14:12:19

@billypiston: did you read the help @agile_geek give you

roelof14:12:39

@surreal.analysis: I have tried to help him and came with this code : https://www.refheap.com/112585

roelof14:12:05

but then I see this error message : Exception in thread "main" java.lang.RuntimeException: Unable to resolve symbol: GET in this context, compiling:(test/handler.clj:36:12

surreal.analysis14:12:42

You need to add [compojure.core :refer :all] to the (:require []) section

surreal.analysis14:12:57

GET and POST are both in there

surreal.analysis14:12:16

Oh, or just add GET and POST in the same vector as defroutes and routes, in line 2

roelof14:12:37

thanks, next error in the code : Illegal character in query at index 34: https://fonts.googleapis.com/icon? family=Material+Icons

roelof14:12:05

(include-css "? family=Material+Icons")

roelof14:12:32

I tried to help him but the code posted is full of errors

roelof14:12:31

oke, the form works but when you goto /saveform nothing is displayed

roelof14:12:52

and there is no redirection to the saveform page

roelof14:12:36

so it looks to me the req is never used

roelof14:12:18

I hope someone with more experience in web design can help this person

roberto14:12:33

it is hard to read, he should post it in refheap or as markdown.

roelof14:12:41

I can post the coe on refheap

roelof14:12:02

here the "working" code where you can enter a age but nothing seems to happen: https://www.refheap.com/112587

agile_geek14:12:17

@roelof: you need to go to "/" the root url as that is mapped to the GET http method.

agile_geek14:12:51

"/saveform" is the url the form served from "/" posts to using the POST http method.

roelof14:12:01

Yep, there you see the form

agile_geek14:12:23

You need to understand a little about how HTTP works

roelof14:12:37

I thought on /saveform you could find the result of the submission

agile_geek14:12:03

you could if you called /saveform using a POST http method...

agile_geek14:12:13

but a browser does a get by default

agile_geek14:12:27

you get a post on a submit button for example

roelof14:12:48

oke, when I added a number I do not see any output of the pprint part

agile_geek14:12:15

you could post the data using a curl statement from command line but you would need to know what the data from the submit looks like

agile_geek14:12:35

@roelof: as a test replace the (with-out-str (clojure.pprint/pprint (:params req))) with a simple string like "hello"

agile_geek14:12:57

when you submit you should see "hello"

roelof14:12:09

oke, and do I have to restart the server ?

agile_geek14:12:26

not if you are running lein ring server

agile_geek14:12:45

you could do it just in case though

agile_geek14:12:48

so your code for the POST route should look like this:

(POST "/saveform" req
                 "Hello")

roelof14:12:13

when I do not restart it I do not see "hello" on the root screen

agile_geek14:12:24

try restart then

agile_geek14:12:00

you will only see hello once you click the submit button

roelof14:12:05

oke, I will hit the book how to to that ?

roelof14:12:16

This is total new stuff for me

agile_geek14:12:21

how are you running the server?

roelof14:12:32

lein ring server

agile_geek14:12:22

do you see the page with "How old are you?" when you point the browser to the root of the server?

agile_geek14:12:48

type a number and click the button

agile_geek14:12:34

what happens?

agile_geek14:12:03

OK try this:

roelof14:12:04

I still see the form

agile_geek14:12:46

(POST "/" req
                 "Hello")

roelof14:12:48

and nothing else

agile_geek14:12:22

I think the problem is the submit is posting to "/" and not "/saveform"

agile_geek14:12:33

not sure how this could ever work

roelof14:12:07

if im right there schould be a form action part

roelof14:12:48

something like this : <FORM action="http://somesite.com/prog/adduser" method="post">

agile_geek14:12:54

Yes. The submit is not in a form so it doesn't post anywhere

roelof14:12:28

So he has a bad example or did not type anything the tutorial says

agile_geek14:12:32

yep except the action needs to be something like "/saveform"

roelof14:12:50

He/she says that the code is found somewhere

roelof14:12:50

it schould be something like this (form-to [:put "/post"] if I understand the hiccup docs well

agile_geek15:12:22

If you are using hiccup to generate the form- yes.

agile_geek15:12:53

That basically renders the html <FORM...> tag you typed in above

agile_geek15:12:19

except you don't do a put but a post like this: (form-to [:post "/saveform"]...

agile_geek15:12:51

as the defroute is expecting a :post not a :put

roelof15:12:53

pff. (form-to cannot be resolved 😞

agile_geek15:12:16

You need to require the hiccup.form ns

agile_geek15:12:46

i.e. [hiccup.form :refer [form-to]]

agile_geek15:12:26

in your (:require...

roelof15:12:11

but on /saveform I see a 404 error

agile_geek15:12:29

what do you mean on /saveform?

sveri15:12:45

the route handler does not define a /saveform route

agile_geek15:12:46

Remember you can't do a get on /saveform

roelof15:12:54

oke, moment

roelof15:12:09

I schould see the hello on the root page ??

sveri15:12:13

(POST "/" req "Hello") should be (POST "/saveform" req "Hello")

agile_geek15:12:16

you are right

sveri15:12:37

no problem

agile_geek15:12:47

I had forgotten to ask @roelof to change that back!

roelof15:12:23

no problem

roelof15:12:55

still a 404 error on /saveform

agile_geek15:12:07

when you click the button?

sveri15:12:18

and did you restart your server after changing the route?

roelof15:12:57

yep, I did restart the server and put a number in the box and then open /localhost:3002/saveform

agile_geek15:12:25

open it in the browser by manually typing the url?

agile_geek15:12:52

Remember /saveform is only mapped to a post

agile_geek15:12:12

typing something into the browser issues a get request

roelof15:12:35

there is also a problem in my code . I see this {:span {:class "input-group-btn"}}

agile_geek15:12:40

go to http:// /localhost:3002/

agile_geek15:12:56

and click the button

roelof15:12:38

then nothing happens

agile_geek15:12:54

Your hiccup code looks wrong to me. Not sure the end brackets are in the right places.

agile_geek15:12:54

Your input field seems to include the button within it

roelof15:12:04

could be that i messed it up when adding the form to

roelof15:12:45

I see it the [ before :span was change to a {

roelof15:12:38

hmm, after chancing that still nothing happens

agile_geek15:12:03

Can you paste what it looks like now in refheap?

roelof15:12:37

only the form or the whole code

roelof15:12:34

@agile_geek: we are the whole day busy for someone and still not closer to the problem

agile_geek15:12:57

Then leave it with me and i'll look at it on my 3 hour train journey home later tonight.

roelof15:12:37

I leave it to you , this is still more then i could chew

roelof15:12:12

I hope when I m so far that I wil make a website with clojure I can find a good book or tutorial

roelof15:12:08

now finnaly time for my own 4 clojure problem

agile_geek15:12:17

This works https://www.refheap.com/112591 - note that the [] are balanced in my example. I.e. [:input {:type "text" :class "form-control" :placeholder "How old are you?" }] has a closing ]

agile_geek15:12:17

Just in case here is my project.clj too. https://www.refheap.com/112593

roelof15:12:47

Wierd, here on my windows computer still nothing happens . I tried Edge and Firefox

roelof15:12:11

even if changed to your project.clj

roelof15:12:19

@agile_geek: are you working on a Linux or a mac maybe ?

agile_geek15:12:41

Wouldn't matter

agile_geek15:12:03

check your project.clj

roelof15:12:54

I copied the project.clj from you and did a lein dep after that

roelof15:12:20

after that I start my server with lein ring server in Cursive

agile_geek15:12:38

what port does the server say it's listening on when you start it?

agile_geek15:12:12

and are you using 3000 in your url?

roelof15:12:16

and I also see the form with localhost:3000

roelof15:12:27

yep, as I said before I see the form

roelof15:12:45

I put a number in it and press on the submit form

roelof15:12:57

and then nothing happens

agile_geek15:12:16

Previously you were using port 3002?

roelof15:12:47

maybe cursive is playing with the ports no idea

agile_geek15:12:05

I think you may be getting multiple servers running and if you are not stopping them you may be looking at the wrong one

agile_geek15:12:16

close Intellij

agile_geek15:12:27

open a cmd terminal

agile_geek15:12:42

cd to your project dir

roelof15:12:06

done and entered lein ring server

roelof15:12:13

I now see the form

roelof15:12:56

and I enter a number , press on the submit button and I still see the form

roelof15:12:06

same problem as before

agile_geek15:12:19

Hmm. Not sure why. I'd need to be there

roelof15:12:55

need a teamviewer session to see what happens here ?

agile_geek15:12:35

I've got to go and I'm traveling for next 5 hours but I can post my project in github over weekend and send link to you.

roelof15:12:18

that is a lot of traveling Have a nice trip and a save one

roelof15:12:27

I try to understand what problem 107 is wanted

roelof16:12:53

Can someone explain to me what problem 107 of 4clojure exactly wants in simple English.

cab16:12:45

it wants a function (A) that takes a parameter X that returns a function (B), and when you call (B) with parameter Y it should give me Y ^ X

polymeris16:12:11

the other way around, I think

cab16:12:45

you’re right

cab16:12:06

do you know how to do exponentiation in clojure @roelof?

cab16:12:19

or in lisp / functionally

roelof16:12:33

@cab : I think it will be a x or else recursion

cab16:12:11

personally i would do (reduce * (repeat base exponent))

roelof16:12:51

lets take the first one (( 2 ) 16) so the first function must return something like (fn [x] (partial (reduce * (repeat 2)

roelof16:12:04

and somehow I have to call that with 16 to see 256

roelof16:12:25

@cab : do I understand you right

cab16:12:51

i think so — but i wouldn’t even worry about doing it with partial right now

cab16:12:56

just use two (fn)s

roelof16:12:30

oke, I will think about it

roelof16:12:34

and google how one anymous function can call another anymous function

roelof16:12:48

This is something complete new to me

cab16:12:02

what language are you coming from?

cab16:12:07

programming-wise

roelof16:12:51

I did a lot of ruby and I tried erlang before I changed to clojure

roelof16:12:34

Is this a good example :

(defn outer []
    (let [foo (get-time-of-day)]
      (defn inner []
          #(str "then:" foo " now:" (get-time-of-day)))))

mccraigmccraig16:12:32

@roelof: what are you aiming to achieve there ?

roelof16:12:12

Try to understand how problem 107 of 4 clojure can be solved

roelof16:12:50

I have to use there lexical closures

mccraigmccraig16:12:29

in your code inner returns a fn when called, and outer returns a var containing inner without calling inner ... i'm guessing that's probably not what you want

mccraigmccraig16:12:48

@roelof: if you make your inner an (fn [] ...) rather than a defn then outer will return the fn inner which closes over foo

mccraigmccraig16:12:47

and your inner fn doesn't need to return a function, just to call str, so you can get rid of the #

mccraigmccraig16:12:58

(defn outer []
    (let [foo (get-time-of-day)]
      (fn inner []
          (str "then:" foo " now:" (get-time-of-day)))))

mccraigmccraig16:12:18

then ((outer)) will do what you want

mccraigmccraig16:12:25

or what i think you want simple_smile

mccraigmccraig16:12:15

also, you don't need to name your inner fn, since it's not called by name from anywhere

mccraigmccraig16:12:33

(defn outer []
    (let [foo (get-time-of-day)]
      (fn []
          (str "then:" foo " now:" (get-time-of-day)))))

mccraigmccraig16:12:10

(defn outer []
  (let [foo (get-time-of-day)]
    #(str "then:" foo " now:" (get-time-of-day))))

mccraigmccraig16:12:02

the last two being equivalent

roelof17:12:08

Thanks, as I understand the outer needs to be the function with 1 argument and the inner schould call it with the other argument

roelof17:12:39

@mccraigmccraig: sorry but both looks equal to me. I do not see the difference between your code and the mine

mccraigmccraig17:12:58

(defn foo [] :foo) is different to (fn foo [] :foo) ... defn is like (def foo (fn [] :foo))

mccraigmccraig17:12:37

(fn [] ...) returns a function object. defn returns a var object which has a function bound to it

roelof17:12:22

oke, I see it, I wil play and experiment with it to see if I can solve problem 107 myself

roelof17:12:39

thanks for helping and not given me the answer

mccraigmccraig17:12:44

secondly #(str ...) is a function which calls str on invocation, whereas (str...) is a direct call to str

mccraigmccraig17:12:52

#(str %) is sugar for (fn [x] (str x))

mccraigmccraig17:12:28

@roelof for prob 107, maybe def the var you want to capture, then write the inner function, then write the enclosing function

mccraigmccraig17:12:55

e.g. if you want to capture n and return a function which adds n to x

mccraigmccraig17:12:37

(def f (fn [x] (+ n x)))

mccraigmccraig17:12:18

then once you've got the inner fn correct

mccraigmccraig17:12:20

(def g (fn [n] (fn [x] (+ n x))))

mccraigmccraig17:12:36

((g 5) 20) ;;=> 25

roelof17:12:38

Thanks, that look almost the solution. except the last one it looks the functions is in the inner where as i read it well, it schould be in the outer

mccraigmccraig17:12:23

@roelof: you want an outer function which sets up the closure with n, and returns the inner function which is called with the value x

roelof17:12:02

now im confused

roelof17:12:19

lets take the first one ((_ 2) 16) I thought the function to calculate 2 ^16 must be the outer

mccraigmccraig17:12:26

no, you've got it backwards... if ur stuck i can give you a solution to pick apart

roelof17:12:56

oke, so the part whith def g is the right way to do

roelof17:12:35

@mccraigmccraig: thanks for offering but I like to solve it myself

roelof17:12:49

by just copy/paste I learn nothing

mccraigmccraig17:12:54

@roelof: how about i give you a ruby solution, and you can see if you can translate that

mccraigmccraig17:12:35

they are sufficiently different yet similar that i would think there is learning value there

roelof17:12:20

I got already a idea how the anymous function must look like. For clojure you need some sort of recursion to calcaulate 2 ^16

mccraigmccraig17:12:11

f = ->(n){ ->(x){ x**n }}

mccraigmccraig17:12:39

f.call(2).call(5) #=> 25

mccraigmccraig17:12:15

easier in ruby 'cos it has **

mccraigmccraig17:12:54

you have several options in clojure ... recursion, reduce or java simple_smile

roelof17:12:57

correct I liked ruby but I do not like rails. too much magic and too much you have to do it like this

roelof17:12:14

I go for reduce I think

mccraigmccraig17:12:30

yeah, i did too... the reduce can be quite pretty

roelof17:12:32

Time to hit the repl after dinner

roelof17:12:57

and otherwise I will be tomorrow

rantingbob18:12:36

@roelof: How did you manage with the end of the exercises we were talkin about yesterday from Brave and True?

roelof18:12:23

You mean the convert back to a csv ?

roelof18:12:39

I found one without using join and sean give me one where join is used

roelof18:12:25

@rantingbob: I quit. the exercises of the next chapter where even difficult. so I decided to do only the 4clojure exercises

rantingbob18:12:53

Shame. I've found it really useful...but whatever fits I say simple_smile

roelof18:12:02

yoiu mean shame that I quit brave

roelof18:12:19

Need any pointers ?

agile_geek19:12:52

@roelof: Here's a link to a repo with a working version of that ring/compojure/hiccup app. https://github.com/chrishowejones/trialapp There was a lot of little things to fix. The highlights were: 1. Vector describing input were closed in wrong place. 2. Form didn't submit an action and method of post. 3. project.clj ring: {:handler ... pointed to the defroutes and not the def that defined the wrap-params around the routes.

roelof19:12:44

Thanks, I will make a fork and place it into my working archibe

roelof19:12:59

and study it well

agile_geek19:12:05

If you look at it the master branch has an implementation using hiccup.form and the alternative branch has an implementation that hand codes the hiccup tags.

agile_geek19:12:12

Functionally they are the same

agile_geek19:12:55

Most of what was wrong was html and nothing to do with Clojure.

roelof19:12:49

hmm, importing into cursive does not work

roelof19:12:02

it cannot find any project

agile_geek19:12:37

Sorry I'm not a cursive user but I'm guessing it's the Intellij Project it can't find.

roelof19:12:13

I did first import from leiningen and now I do impotrt from existing sources

roelof19:12:17

and it seems to work

roelof19:12:58

nope, it downloaded the repo for working on 4clojure problems

agile_geek19:12:59

I think that import from existing sources creates the Intellij Idea project..nothing to do with the project.clj file.

agile_geek19:12:42

I've used Idea for Java but not with Cursive and Clojure.

agile_geek19:12:13

I promise you the project.clj file is there!

agile_geek19:12:18

Maybe ask someone who uses Cursive?

roelof19:12:37

my fault. I try to import the wrong one

roelof19:12:10

Yes, I see now age = 5

shaun-mahood19:12:20

Running into a problem with clj-time, not sure what I'm doing wrong.

(defn filter-by-draft-date [start end data]
  (filter
    #(t/after? (f/parse date-formatter start)
               (:draftdate %))
    data))
works fine,
(defn filter-by-draft-date [start end data]
  (filter
    #(t/after? (:draftdate %)
               (f/parse date-formatter start))
    data))
gives me the error
IllegalArgumentException No implementation of method: :after? of protocol: #'clj-time.core/DateTimeProtocol found for class: nil  clojure.core/-cache-protocol-fn (core_deftype.clj:554)
Any ideas?

agile_geek19:12:15

@shaun-mahood: I am guessing that the underlying implementation of after (possibly in the Java joda time library) can't cope with a nil in the first argument and you have nils in your data sequence?

agile_geek19:12:52

If you want the draft date to be after the start use the first form with t/before? instead of after?

agile_geek20:12:16

I am correct if you look at the source for clj-time you see this:

(after? [this ^ReadableInstant that] (.isAfter this that))

agile_geek20:12:33

if this is nil what would happen?

mostr20:12:32

trying to understand var vs symbol difference when passing to functions. To be specific: why in the following example passing #’app works that way in contrast to simply passing app (which doesn’t see changes when app gets redefined) https://www.evernote.com/l/AORSQcOaX6RNd54ZwITKK4nTt3YR1APRYS8 (source here http://www.learningclojure.com/2013/01/getting-started-with-ring.html)

agile_geek20:12:32

So you could filter for nil as well.

shaun-mahood20:12:05

@agile_geek: Good idea, I'll give that a try first. Lots of nils in the data set

agile_geek20:12:07

@mostr: I am not sure I could explain it any better than that comment!

agile_geek20:12:40

@shaun-mahood: do you understand why the first example you gave worked and the second did not?

agile_geek20:12:46

@mostr: the reader macro '# stops Clojure evaluating the symbol app to the function. Instead it just passed the symbol unevaluated.

agile_geek20:12:23

So it's passing the var (a handle to the function) not the actual function.

mostr20:12:07

so why, when I pass function a (not #’user/a) to function b it works fine (I mean I can redefine a, call b again and see changes)?

shaun-mahood20:12:49

@agile_geek: Yep, thanks for the help. Works fine when I filter out the nils - I just kind of assumed it would handle nils and didn't read the error message closely enough.

agile_geek20:12:01

@mostr: you are at the limits of my knowledge here but my understanding is when you eval a in the repl you are overwriting the def of the original a but that won't work with the jetty adapter. But I'm guessing.

agile_geek20:12:23

The defonce does mean that reloading the ns will not overwrite the def so I suspect if you changed the def of server to def not defonce it would overwrite on reload.

agile_geek20:12:53

but I suspect this forces unwanted side effects in production.

mostr20:12:05

yeah I guess it’s this defonce thing that makes it working like this

mostr20:12:17

thanks for help!

agile_geek20:12:51

yes it definitely is defonce

agile_geek20:12:04

the bit I don't know is why use defonce

agile_geek20:12:14

@mostr: Oh, I've got it! If we used def and reloaded we would define another jetty server on the same port!

agile_geek20:12:13

at least until the gc collected the dereferenced first instance.

mostr20:12:04

yep, that’s true, and that’s why defonce is there, but still - why for regular defn passing just symbol (not var) works fine (let me prepare some REPL stuff)

agile_geek20:12:51

because when Clojure evals the defonce it will memoize the function if you didn't use the reader macro

agile_geek20:12:16

whereas defn will reevaluate on reload - defonce would not

mostr20:12:23

(defn handler [r] (println (str "doing stuff with " r)))
=> #'sandbox/handler
(defn myapp [r] (handler r))
=> #'sandbox/myapp
(myapp "123")
doing stuff with 123
=> nil
(defn handler [r] (println (str "doing stuff with CHANGED " r)))
=> #'sandbox/handler
(myapp "123")
doing stuff with CHANGED 123
=> nil

mostr20:12:02

this one works fine (I mean it sees that handler was changed)

mostr20:12:17

without passing #’sandbox/handler

agile_geek20:12:32

Try (defonce myapp [r] (handler r))

mostr20:12:32

won’t compile, you mean (defonce myapp handler) or (defonce myapp (fn [r] (handler r))) maybe?

mostr20:12:42

(defonce myapp (fn [r] (handler r))) this one works fine without passing var

mostr20:12:50

and the former one does not

agile_geek20:12:15

Second probably works because you are defonce`ing the anonymous function which evals every time you invokes myapp

agile_geek20:12:03

Given that you have to use defonce to prevent reload creating multiple jetty servers, to get app to re-eval you need the reader macro.

mostr20:12:09

ah, right! facepalm

agile_geek20:12:34

I learned something too! Thanks @mostr

mostr20:12:16

win/win simple_smile thanks a lot for the “session”