This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2018-10-31
Channels
- # aleph (1)
- # announcements (2)
- # beginners (105)
- # braveandtrue (1)
- # cider (61)
- # clara (47)
- # cljdoc (29)
- # cljs-dev (5)
- # clojure (61)
- # clojure-austin (14)
- # clojure-brasil (1)
- # clojure-india (3)
- # clojure-italy (4)
- # clojure-mexico (1)
- # clojure-nl (2)
- # clojure-spec (37)
- # clojure-uk (95)
- # clojurescript (73)
- # cursive (12)
- # data-science (1)
- # datomic (26)
- # duct (10)
- # emacs (5)
- # fulcro (47)
- # hoplon (6)
- # hyperfiddle (3)
- # jobs-discuss (3)
- # kaocha (2)
- # leiningen (3)
- # nrepl (8)
- # off-topic (3)
- # onyx (2)
- # re-frame (31)
- # reitit (16)
- # shadow-cljs (36)
- # spacemacs (46)
- # specter (16)
- # tools-deps (13)
- # yada (22)
anyone have a real basic web app idea for a beginner to do some training with compojure+ring?
@cybersapiens97 I guess the classic ones would be a To-Do list or an Address Book.
the address book seems nice, i'll give a try, what database you recommend for this ?
You could use any of the simple, embedded/semi-embedded DBs. SQLite, H2, HSQLDB, Derby...
Then all you need is org.clojure/java.jdbc
and the driver for whichever DB you pick -- no external process to run.
cool, thanks 😀
If you have any questions about that aspect, hit me up in #sql (it's easy for me to keep an eye open for questions there).
Have you thought about how you might generate the HTML web pages? (assuming you're going to build a traditional server-side web app)
no i haven't yet, i assume i can either feed them to the user directly with ring, or use a specialized lib for this? also, days ago i think i saw some lib which could automatically generate html pages. (if didn't knew about it, probably i would write by hand the entire html)
Hiccup is one option: generates HTML from Clojure data structures. Selmer is another: Django-like templates that can include basic loops, conditionals, and variable substitutions.
I like Selmer, since it keeps the "views" separate from code, as near-HTML templates that can easily be edited and worked with using any web-capable tooling.
(and you can easily view the template directly in a browser)
seems better suited for me, because on future projects i'll have a friend working on the front end
still don't know how we are going to glue things together haha
but i'm excited doing web development in clojure
Feel free to read over this small example https://github.com/framework-one/fw1-clj/blob/master/examples/usermanager/main.clj -- it shows how to put together Component, Compojure, Ring, Selmer...
It uses Derby for the DB.
There's a story behind that example 🙂 About a decade ago, I created a fairly minimal MVC framework which become of the two most popular frameworks in the CFML (ColdFusion) world. After learning Clojure, I ported it from CFML to Clojure -- and we used it at work as we migrated from CFML to Clojure -- but after using it for a while, I decided the framework didn't add enough value in the Clojure world, so I stripped it out of that example, to show what a simple DB-backed MVC web app might look like, with just libraries used together.
seems nice as example and you haven't lost your work along the way
i'm kindly rejecting Luminus and it's book, seems too much to digest, and i'm feeling very easy and pleasant using just libraries for things i need
My feeling about Luminus is that, although it's "only" a template, it has too many moving parts. I've seen a lot of beginners go down that path and then get horribly confused when they try to move outside the guidance of the book and discover all the pieces of the template that they don't understand (or even know about) yet.
yes, that was my initial reaction, and i felt lost
and when i started reading just the wiki section of ring and then compojure, it's so easy and simple to use
and you can even do lot's of little things to understand how you can communicate with the http protocol, everything seems less confusing
I agree that starting from scratch with a basic "Hello World!" with Ring and Compojure and building up from there is probably the best way to learn how the pieces work.
i'm trying to render a html file with selmer, and it's documentation says By default the templates are located relative to the ClassLoader URL.
but what is the classloader URL ?
and btw my file is at resources/public and i'm seeing an error saying that it doesn't found the file with this code
(render-file "register.html" {:title "title"})
and this one doesn't work too, same error:
(render-file "resources/public/register.html" {:title "title"})
also tried to put the file inside src folder
Is there anybody use clj-http
for store session? Just like Python requests.Session().get
? I checked clj-http README.md document, found cookies support, but have not found the session support.
never used sessions before, but i've seen it on Ring documentation
Fellow Clojurians I have a problem which I am trying to solve, would appreciate some advice. I have this datastructure: A vector of maps
[{:identifier "1337" :colors [:yellow :blue :brown] :size [:s :m :l :xl]}
{:identifier "1338" :colors [:yellow :brown] :size [:s :m]}
{:identifier "1339 ":colors [:blue] :size [:xl]}]
I want to group this collection by matching colors and sizes, in this case I want to return 1337 and 1339 since both have the :colors :blue
and the :size :s
.
I am a bit unsure what to use to solve this problem to be honest/what to look at.is it possible to change the :colors
and :size
to sets instead of list? that would simplify things
also, 1337 and 1339 don’t have :size :s
in common, do you mean 1337 and 1338? :thinking_face:
I mean xl
xl and blue are matching so I want 1337 and 1339
the return I want would be something like this:
{:identifiers ["1337" "1339"] :size :xl :color :blue}
and yes, they could be sets
ok, this will get you almost all the way:
(def items
[{:identifier "1337" :colors #{:yellow :blue :brown} :sizes #{:s :m :l :xl}}
{:identifier "1338" :colors #{:yellow :brown} :sizes #{:s :m}}
{:identifier "1339 ":colors #{:blue} :sizes #{:xl}}])
(defn find-by-color-and-size [color size items]
(filter
#(and (contains? (:colors %) color)
(contains? (:sizes %) size))
items))
user=> (find-by-color-and-size :blue :xl items)
({:identifier "1337", :colors #{:yellow :blue :brown}, :sizes #{:m :s :l :xl}}
{:identifier "1339 ", :colors #{:blue}, :sizes #{:xl}})
I see thank you very much:wizard:✌️, I will do some more reading
If this is a large dataset and you want to do this kind of lookup often, I’d look into a database though.
(Because lookup time this way is linear, so if the dataset gets too large it might be slow).
@U3L6TFEJF i read ur solution now more in detail (was in a hurry to work) and I don't want to have to send in color and size. I want to find 1339 and 1337 by seeing that it has the same color in its :colors set and the same size in the size set.
Might actually go with the database for this. It's gonna suck to do that lookup when I have 100k lines in the vector. Or I will have to re-think my strategy.
if you use datomic it’s trivial, or if you can fit your entire data set in memory you can use https://github.com/tonsky/datascript/
in that case I have to do a lookup as soon as a new Entry is added in Datomic (which might actually be really smoth.. they have some QUEUE-stuff). I am currently using core-async with channels, before I only had items that I put on a channel which were batched by 10. Now I have to do some filtering too so it's like "Batch the items that have values that are equal by 10". 🙂
Transaction report queue
here’s a start of how to do it with Datomic/Datascript:
(def db2
(d/create-conn
{:item/colors {:db/cardinality :db.cardinality/many}
:item/sizes {:db/cardinality :db.cardinality/many}}))
(def items
[#:item{:identifier "1337" :colors #{:yellow :blue :brown} :sizes #{:s :m :l :xl}}
#:item{:identifier "1338" :colors #{:yellow :brown} :sizes #{:s :m}}
#:item{:identifier "1339 ":colors #{:blue} :sizes #{:xl}}])
(d/transact! db2 items)
(defn into-set [a b]
(set [a b]))
(defn find-all-that-share-colors-and-sizes []
(d/q '[:find [?t ...]
:where [?e :item/colors ?c]
[?e2 :item/colors ?c]
[(not= ?e ?e2)]
[?e :item/sizes ?s]
[?e2 :item/sizes ?s]
[(user/into-set ?e ?e2) ?t]]
@db2))
user=> (find-all-that-share-colors-and-sizes)
[#{1 2} #{1 3}]
Thank you I will use datomic, it looks really smooth. Very appreciated that you took your time to explain this and showed some nice examples @U3L6TFEJF 🙂
@cybersapiens97 I just watched it, but still don't know how to use the Ring sessions
with clj-http
.
sorry @stardiviner i don't have experience with back end development. starting just now, wait until someone more experienced appears on the chat
Thanks still
@stardiviner cookies are sessions, no?
Yes, Python's requests.Session()
objects did this.
I want similar in Clojure
Right, first of all Ring is a server thing AFAIK, it won’t help you here. Let me look at clj-http docs.
The idea being that cookies received by the server are stored in the store, then sent back on further requests. This is what browsers do.
I see, let me have a look.
@orestis This is exactly what I want. Thanks very much.
What do you guys think about clj-http
and http.async.client
. Which one do you guys use, and why?
@jaihindh.reddy We mostly use clj-http
as it's been around longer and it is very robust and full-featured. We've started using http://www.http-kit.org/client.html recently for async HTTP handling (since we were already using http-kit as a server -- although we've since switched back to Jetty, to get better New Relic support).
can I get some thoughts on what is "the right way" to write this? In this context, restore-commands
is a collection of arrays containing tokens I would send to the shell---
The data making those commands was slurped out of a bash script that is known to work, so I can apply sh
to them and get a good result, if the pwd
is correct
but when I went to try a similar trick using with-sh-dir
, I discover apply
cannot take a macro
you are now stuck in macro-land:
(defmacro foo [dbh tokens] `(with-sh-dir dbh ~@tokens))
Where "`" means, 'act like you're literally typing this,' and "~@" means 'but evaluate this part to its value'
with-sh-dir just sets up a binding for a dynamic var, and you aren't changing its binding anywhere, so you don;t need it
would you recommend a different way of accomplishing the task, "execute a command but as through from a particular directory"?
running lein repl
I get Exception in thread "Thread-1" java.lang.IllegalAccessError: loose! does not exist
. lein version
gives Leiningen 2.8.1 on Java 1.8.0_171 Java HotSpot(TM) 64-Bit Server VM
. Anyone know what may be the cause of this?
Exception in thread "Thread-1" java.lang.IllegalAccessError: loose! does not exist
at clojure.core$refer.invokeStatic(core.clj:4119)
at clojure.core$refer.doInvoke(core.clj:4087)
at clojure.lang.RestFn.applyTo(RestFn.java:139)
at clojure.core$apply.invokeStatic(core.clj:648)
at clojure.core$load_lib.invokeStatic(core.clj:5755)
at clojure.core$load_lib.doInvoke(core.clj:5717)
at clojure.lang.RestFn.applyTo(RestFn.java:142)
at clojure.core$apply.invokeStatic(core.clj:648)
at clojure.core$load_libs.invokeStatic(core.clj:5774)
at clojure.core$load_libs.doInvoke(core.clj:5758)
at clojure.lang.RestFn.applyTo(RestFn.java:137)
at clojure.core$apply.invokeStatic(core.clj:648)
at clojure.core$require.invokeStatic(core.clj:5796)
at clojure.core$require.doInvoke(core.clj:5796)
at clojure.lang.RestFn.invoke(RestFn.java:408)
at user$eval736.invokeStatic(NO_SOURCE_FILE:0)
at user$eval736.invoke(NO_SOURCE_FILE)
at clojure.lang.Compiler.eval(Compiler.java:6927)
at clojure.lang.Compiler.eval(Compiler.java:6916)
at clojure.lang.Compiler.eval(Compiler.java:6890)
at clojure.core$eval.invokeStatic(core.clj:3105)
at clojure.core$eval.invoke(core.clj:3101)
at leiningen.core.eval$fn__4181.invokeStatic(eval.clj:342)
at leiningen.core.eval$fn__4181.invoke(eval.clj:332)
at clojure.lang.MultiFn.invoke(MultiFn.java:233)
at leiningen.core.eval$eval_in_project.invokeStatic(eval.clj:366)
at leiningen.core.eval$eval_in_project.invoke(eval.clj:356)
at leiningen.repl$server$fn__5864.invoke(repl.clj:244)
at clojure.lang.AFn.applyToHelper(AFn.java:152)
at clojure.lang.AFn.applyTo(AFn.java:144)
at clojure.core$apply.invokeStatic(core.clj:646)
at clojure.core$with_bindings_STAR_.invokeStatic(core.clj:1881)
at clojure.core$with_bindings_STAR_.doInvoke(core.clj:1881)
at clojure.lang.RestFn.invoke(RestFn.java:425)
at clojure.lang.AFn.applyToHelper(AFn.java:156)
at clojure.lang.RestFn.applyTo(RestFn.java:132)
at clojure.core$apply.invokeStatic(core.clj:650)
at clojure.core$bound_fn_STAR_$fn__4671.doInvoke(core.clj:1911)
at clojure.lang.RestFn.invoke(RestFn.java:397)
at clojure.lang.AFn.run(AFn.java:22)
at java.lang.Thread.run(Thread.java:748)
REPL server launch timed out.
profiles.clj:
{:user {:java-cmd "/Library/Java/JavaVirtualMachines/jdk1.8.0_172.jdk/Contents/Home/bin/java"
:dependencies [[vvvvalvalval/scope-capture "0.3.1"]]
:injections [(require '[sc.api :as sc :refer [spy defsc brk loose!]])
(sc.api.logging/register-cs-logger
:sc.api.logging/log-spy-cs
(fn [cs]
nil))]}}
oh man, it must be that injection
the first thing I would do is remove any plugins/injects/middleware/etc, those will come from a project.clj, a profiles.clj, or a your .lein/profiles.clj
ok, thanks. removing that fixed the problem
it appears it should be loose
without an !
https://github.com/vvvvalvalval/scope-capture/blob/master/src/sc/api.cljc#L297
but i agree that the things in the profiles are just problems and its not obvious where to look
@hiredman I once spent 2 hours debugging a cryptic error protobuf message, only to find out that the cljfmt in my profiles.clj had an older version of protobuf as a dependency. It was a nightmare.
I also recommend not using profiles.clj