This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2015-12-11
Channels
- # admin-announcements (26)
- # aws (1)
- # beginners (356)
- # boot (28)
- # cider (20)
- # clara (12)
- # cljs-dev (78)
- # cljsrn (22)
- # clojure (333)
- # clojure-brasil (1)
- # clojure-dev (15)
- # clojure-miami (1)
- # clojure-nl (3)
- # clojure-russia (61)
- # clojurecup (3)
- # clojurescript (137)
- # clojurex (4)
- # core-async (4)
- # data-science (3)
- # datavis (2)
- # datomic (31)
- # editors (1)
- # emacs (9)
- # hoplon (3)
- # juxt (8)
- # ldnclj (47)
- # leiningen (4)
- # luminus (4)
- # off-topic (20)
- # om (332)
- # onyx (1)
- # parinfer (23)
- # portland-or (4)
- # proton (161)
- # reagent (46)
- # ring-swagger (11)
- # specter (7)
- # yada (2)
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.
Does this help (with Leiningen)? https://github.com/technomancy/leiningen/blob/master/doc/TUTORIAL.md
(Brave and True is an awesome learning resource)
It also covers editing in Emacs on the next page.
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}] )
Did you print
the output or just let the repl display the value?
I did repl dis play the output , @seancorfield
@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 ))
(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)
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
No idea about that. I was just trying to show a string/join
solution 😸
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"
Only print
(or println
) will convert the escapes into actual new lines.
@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.
@roelof: @billypiston: FIrstly, (with-out-str ...)
temporarily rebinds *out*
to capture what is printed and return a string instead.
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
@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?
Without going through the full solution (you need to think about these things to learn) the bit of your code that does this:
(POST "/saveform" req
(with-out-str (clojure.pprint/pprint (:params req)))))
is extracting the params from the req
map here: (:params req)
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.
so you can test the params value extracted using if
I leave you to try that. Just try returning different strings depending on whether the value is < 18 or >= 18.
@agile_geek: so param holds the value of the form ?
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.
So what you see in the browser is the string representation of the contents of params posted in the http request
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
@roelof: try lein ring server
from terminal session.
I'm going to have to go back to work but I'll check in later.
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)
@roelof: Slack has translated (:params req)
to :simple_smile: params req)
when I changed that to (with-out-str (clojure.pprint/pprint ( :params req)))))
I still see the same error
I see there is some problem with this part : [ring.middleware.params: refer [wrap-params]]
I see this error Exception in thread "main" java.lang.RuntimeException: Invalid token: ring.middleware.params:, compiling:(test/handler.clj:9:37)
[ring.middleware.params :refer [wrap-params]]
it must be
roelof: the :
indicates a clojure „keyword“, in the paste above, the same error is on lines 9 to 12
it’s some.namespace :refer [var1 var2]
, not some.namespace: refer [var1 var2]
this should fix it:
next one : Map literal must contain an even number of forms, compiling:(test/handler.clj:31:62
you should now be able to fix it
still a misplaced :
I give up, I think this is wrong :type = "button"
but when I change it to :type button
absolutely
any maybe read some intro to clojure tutorial
Hi, everybody! Help to solve my task please. I ask for help as I only started studying Clojure. Про меня выше писал #roelof
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 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 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?
I can't understand where to insert a code with the conditional operator.
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.
@billypiston: Please use refheap/pastebin for big chunks of code, or at least surround it with ` so Slack formats it nicely
Well. I apologize. I will conform to the rules. Simply I the first time use Slack.
@billypiston: Can you paste your code here? https://www.refheap.com/
When copying it over, it seems like slack converted some things to smilies
Making it very hard to parse
@billypiston: did you read the help @agile_geek give you
@surreal.analysis: I have tried to help him and came with this code : https://www.refheap.com/112585
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
You need to add [compojure.core :refer :all]
to the (:require []) section
GET and POST are both in there
Oh, or just add GET and POST in the same vector as defroutes and routes, in line 2
thanks, next error in the code : Illegal character in query at index 34: https://fonts.googleapis.com/icon? family=Material+Icons
here the "working" code where you can enter a age but nothing seems to happen: https://www.refheap.com/112587
@roelof: you need to go to "/" the root url as that is mapped to the GET http method.
"/saveform" is the url the form served from "/" posts to using the POST http method.
You need to understand a little about how HTTP works
you could if you called /saveform using a POST http method...
but a browser does a get by default
you get a post on a submit button for example
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
@roelof: as a test replace the (with-out-str (clojure.pprint/pprint (:params req)))
with a simple string like "hello"
when you submit you should see "hello"
not if you are running lein ring server
you could do it just in case though
so your code for the POST route should look like this:
(POST "/saveform" req
"Hello")
try restart then
you will only see hello once you click the submit button
how are you running the server?
do you see the page with "How old are you?" when you point the browser to the root of the server?
type a number and click the button
what happens?
OK try this:
(POST "/" req
"Hello")
I think the problem is the submit is posting to "/" and not "/saveform"
not sure how this could ever work
Yes. The submit is not in a form so it doesn't post anywhere
yep except the action needs to be something like "/saveform"
it schould be something like this (form-to [:put "/post"]
if I understand the hiccup docs well
If you are using hiccup to generate the form- yes.
That basically renders the html <FORM...>
tag you typed in above
except you don't do a put but a post like this: (form-to [:post "/saveform"]...
as the defroute
is expecting a :post
not a :put
You need to require the hiccup.form
ns
i.e. [hiccup.form :refer [form-to]]
in your (:require...
hmm, I have now this : https://www.refheap.com/112588
what do you mean on /saveform?
Remember you can't do a get on /saveform
you are right
I had forgotten to ask @roelof to change that back!
when you click the button?
yep, I did restart the server and put a number in the box and then open /localhost:3002/saveform
open it in the browser by manually typing the url?
Remember /saveform is only mapped to a post
typing something into the browser issues a get request
go to http:// /localhost:3002/
and click the button
Your hiccup code looks wrong to me. Not sure the end brackets are in the right places.
Your input field seems to include the button within it
Can you paste what it looks like now in refheap?
@agile_geek: we are the whole day busy for someone and still not closer to the problem
Whole thing
Then leave it with me and i'll look at it on my 3 hour train journey home later tonight.
oke, I have this so far : https://www.refheap.com/112591
I hope when I m so far that I wil make a website with clojure I can find a good book or tutorial
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 ]
Just in case here is my project.clj too. https://www.refheap.com/112593
@agile_geek: are you working on a Linux or a mac maybe ?
Wouldn't matter
check your project.clj
what port does the server say it's listening on when you start it?
and are you using 3000 in your url?
Previously you were using port 3002?
I think you may be getting multiple servers running and if you are not stopping them you may be looking at the wrong one
close Intellij
open a cmd terminal
cd to your project dir
Hmm. Not sure why. I'd need to be there
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.
thanks. Bye
Can someone explain to me what problem 107 of 4clojure exactly wants in simple English.
problem 107 can be found here : http://www.4clojure.com/problem/107
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
lets take the first one (( 2 ) 16) so the first function must return something like (fn [x] (partial (reduce * (repeat 2)
Is this a good example :
(defn outer []
(let [foo (get-time-of-day)]
(defn inner []
#(str "then:" foo " now:" (get-time-of-day)))))
@roelof: what are you aiming to achieve there ?
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
@roelof: if you make your inner
an (fn [] ...)
rather than a defn
then outer
will return the fn
inner
which closes over foo
and your inner
fn
doesn't need to return a function, just to call str
, so you can get rid of the #
like this
(defn outer []
(let [foo (get-time-of-day)]
(fn inner []
(str "then:" foo " now:" (get-time-of-day)))))
then ((outer))
will do what you want
or what i think you want
also, you don't need to name your inner
fn, since it's not called by name from anywhere
(defn outer []
(let [foo (get-time-of-day)]
(fn []
(str "then:" foo " now:" (get-time-of-day)))))
(defn outer []
(let [foo (get-time-of-day)]
#(str "then:" foo " now:" (get-time-of-day))))
the last two being equivalent
Thanks, as I understand the outer needs to be the function with 1 argument and the inner schould call it with the other argument
@mccraigmccraig: sorry but both looks equal to me. I do not see the difference between your code and the mine
(defn foo [] :foo)
is different to (fn foo [] :foo)
... defn
is like (def foo (fn [] :foo))
(fn [] ...)
returns a function object. defn
returns a var
object which has a function bound to it
oke, I see it, I wil play and experiment with it to see if I can solve problem 107 myself
secondly #(str ...)
is a function which calls str
on invocation, whereas (str...)
is a direct call to str
#(str %)
is sugar for (fn [x] (str x))
@roelof for prob 107, maybe def
the var you want to capture, then write the inner function, then write the enclosing function
e.g. if you want to capture n
and return a function which adds n
to x
(def n 10)
(def f (fn [x] (+ n x)))
(f 5) ;;=> 15
then once you've got the inner fn correct
(def g (fn [n] (fn [x] (+ n x))))
((g 5) 20) ;;=> 25
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
@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
lets take the first one ((_ 2) 16) I thought the function to calculate 2 ^16 must be the outer
no, you've got it backwards... if ur stuck i can give you a solution to pick apart
@mccraigmccraig: thanks for offering but I like to solve it myself
@roelof: how about i give you a ruby solution, and you can see if you can translate that
they are sufficiently different yet similar that i would think there is learning value there
I got already a idea how the anymous function must look like. For clojure you need some sort of recursion to calcaulate 2 ^16
f = ->(n){ ->(x){ x**n }}
f.call(2).call(5) #=> 25
easier in ruby 'cos it has **
you have several options in clojure ... recursion, reduce or java
correct I liked ruby but I do not like rails. too much magic and too much you have to do it like this
yeah, i did too... the reduce can be quite pretty
@roelof: How did you manage with the end of the exercises we were talkin about yesterday from Brave and True?
@rantingbob: I quit. the exercises of the next chapter where even difficult. so I decided to do only the 4clojure exercises
Shame. I've found it really useful...but whatever fits I say
@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.
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.
Functionally they are the same
Most of what was wrong was html and nothing to do with Clojure.
Sorry I'm not a cursive user but I'm guessing it's the Intellij Project it can't find.
I think that import from existing sources creates the Intellij Idea project..nothing to do with the project.clj file.
I've used Idea for Java but not with Cursive and Clojure.
I promise you the project.clj
file is there!
Maybe ask someone who uses Cursive?
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?@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?
If you want the draft date to be after the start use the first form with t/before?
instead of after?
I am correct if you look at the source for clj-time you see this:
(after? [this ^ReadableInstant that] (.isAfter this that))
if this
is nil what would happen?
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)
So you could filter for nil as well.
@agile_geek: Good idea, I'll give that a try first. Lots of nils in the data set
@mostr: I am not sure I could explain it any better than that comment!
@shaun-mahood: do you understand why the first example you gave worked and the second did not?
@mostr: the reader macro '#
stops Clojure evaluating the symbol app
to the function. Instead it just passed the symbol unevaluated.
So it's passing the var (a handle to the function) not the actual function.
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)?
@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.
@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.
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.
but I suspect this forces unwanted side effects in production.
yes it definitely is defonce
the bit I don't know is why use defonce
@mostr: Oh, I've got it! If we used def
and reloaded we would define another jetty server on the same port!
at least until the gc collected the dereferenced first instance.
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)
because when Clojure evals the defonce
it will memoize the function if you didn't use the reader macro
whereas defn
will reevaluate on reload - defonce
would not
(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
Try (defonce myapp [r] (handler r))
won’t compile, you mean (defonce myapp handler)
or (defonce myapp (fn [r] (handler r)))
maybe?
Second probably works because you are defonce`ing the anonymous function which evals every time you invokes myapp
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.
I learned something too! Thanks @mostr