This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2018-04-04
Channels
- # aws (1)
- # beginners (163)
- # boot (1)
- # bristol-clojurians (1)
- # cider (7)
- # clara (1)
- # cljs-dev (22)
- # cljsjs (1)
- # clojure (43)
- # clojure-denver (1)
- # clojure-finland (6)
- # clojure-italy (1)
- # clojure-nl (3)
- # clojure-russia (1)
- # clojure-spec (1)
- # clojure-uk (6)
- # clojurescript (107)
- # cursive (4)
- # data-science (2)
- # datascript (2)
- # datomic (19)
- # duct (31)
- # emacs (1)
- # fulcro (50)
- # graphql (15)
- # hoplon (3)
- # lein-figwheel (2)
- # luminus (21)
- # off-topic (74)
- # onyx (3)
- # parinfer (15)
- # portkey (2)
- # precept (9)
- # proton (1)
- # re-frame (130)
- # reagent (73)
- # reitit (7)
- # ring-swagger (5)
- # shadow-cljs (61)
- # spacemacs (18)
- # specter (12)
- # uncomplicate (1)
- # vim (88)
- # yada (2)
Lets say that I want to use node modules in a cljs library, because that seems pretty cool. How do I include the dependency so that library consumers just have to require my library?
@achythlook are you targeting node or the browser and how do you intend to distribute your library? it isn’t easy to do this generically. lots of different choices with different tradeoffs
and how are you including your node modules currently (double bundle, shadow-cljs, npm-deps, foreign-libs)
Targeting the browser, and clojars. I was hoping to use npm-deps, but it doesn't seem to work at all with ring-cljsbuild so I can't test it with my current testing setup.
Its not a huge necessity, but given that Google has done a lot of the work I would otherwise be doing (in their workbox-sw npm lib) it seems like a good dependency to include.
i’ve heard people talk about “upstream dependencies” around npm-deps. i think this is what they are talking about
Y'know, reading the source for workbox's npm module... I don't need it. It literally just downloads the actual code from google's servers.
So screw it. cljs-oops exists for a reason
I'm kinda disappointed, though. Workbox isn't compatible with Closure, and being a Google product you'd think that they'd include it with the stdlib.
when I was playing with service workers, working with workbox seemed like more work than it was worth
So I have an extensive lein "user" profile in my ~/.lein/profiles.clj
file global to all projects. Am I correct in thinking that a "dev" profile should not be defined in that file, and that its only purpose is project-specific dev configuration that should be applied to all parties working on it, completely separate but merged with my user profile? If that's the case, does a "dev" profile even make sense for a 1-man development team?
@mfiano I look at it this way - a "dev" profile is designed to declare what things a given project needs at dev time, regardless of what the .lein/profiles.clj says. If you ever clone your repo to another computer, it will help you not have so many headaches. If someone else comes along to use your code, even far in the future, they'll have a dev set up that will work without having to hunt you down.
@john Workbox is, indeed, a bit involved if one doesn't need caching. After trying to implement similar myself, however, I'm finding the existence of this library to be a life-saver (as in years of my life that I'd lose due to stress and anger, are no longer wasted).
Ok. That makes a lot of sense. One other thing that doesn't make sense to me is when I create a jar file, does any of my "user" profile stuff make it into it? Or just the project stuff?
Also side note, forgive me if I'm being dumb. I just never worked with maven or the JVM before I started Clojure a couple weeks ago, and I'm trying to make sense of exactly how the tooling works for distribution.
That's okay, we're all dumb at some level. 🙂
That being said, these aren't dumb questions
I suggest reading this md file thoroughly. https://github.com/technomancy/leiningen/blob/master/doc/PROFILES.md
I have an atom storing some state:
(def c (atom [{:user "me" :docs [{:one "two"}]}
{:user "you" :docs [{:three "four"}]}]))
I'd like to conj
another :doc
to you
, like so:
@c
[{:user "me" :docs [{:one "two"}]}
{:user "you" :docs [{:three "four"} {:five "six"}]}]
What combination of swap!
and other stuff to i have to do add an element to the vector in :docs ? it's my understanding that update-in
only works for nested maps, not arbitrary nested data structures.Honestly, I don't use my .lein/profiles.clj. Every project I start gets dependencies that are honed for it, and though it takes me a minute or two to set up it means that the project.clj is all I need to know to understand the project in the future.
I see. I missed the part that says user, dev, and a few others are excluded when building an uberjar.
By the way, what is an uberjar? I've heard of a jar, but... 🙂
@mfm Though I know its not necessarily "right" to suggest a library for every problem, I've gotten quite a bit of mileage out of this one for doing exactly the sort of thing you're doing. https://github.com/nathanmarz/specter
@mfiano A regular jar is to a dll what an uberjar is to an exe, if I'm not mistaken
its a jar with all dependencies, resources, etc bundled in
typically, usually, you can run them
Ok, everything is getting clearer! Now I just have to figure out what AOT is...or rather I know what it means, but not in the context of the JVM
Depends on the specific context. For Clojure, it basically means that the code compiles completely for distribution.
AOT is evil ... 🙂
At the REPL, Clojure compiles on the fly to JVM bytecode. If you wish to distribute a somewhat faster-to-load program (via an executable uberjar), you AOT compile it so that Clojure can skip that step
We don't AOT anything at work. We build uberjars as source, no AOT. We run them by running clojure.main
and telling it (via -m
) which namespace contains our -main
that we want to run.
It doesn't matter all that much once the executable loads, as everything ends up compiled anyway. Practically its a way to frustrate yourself.
We have long-lived server processes so the overhead of compilation at startup isn't really an issue.
Yeah, do what @seancorfield said
I see. Well that skips a step for me then, being already familiar with long-running Lisp processes that compile on the fly
This is bookmarked so I can drop it on anyone who asks about AOT https://gist.github.com/hiredman/c5710ad9247c6da12a99ff6c26dd442e
(and he's written a follow-up about how to run Clojure programs without AOT... I'll see if I can find that)
thanks @achythlook. i've come across that library a couple times, and haven't had enough of a need to learn it. like you say, i'd be interested in a pure clojure solution. funnily enough, the reason i want this in the first place is my data structures are probably so-nested-it's-a-code-smell. so i'm asking for a "non-right" solution...
Ah, here we go https://github.com/hiredman/clojure-site/blob/df56aef005d5d867213a51c2d3bbec5a86b0acad/content/guides/running_a_clojure_program.adoc
Thanks all.
And of course now we have clj
and deps.edn
for running Clojure programs easily from source with no additional tooling.
@mfm Alright, here's an example that looks kinda bad, but it works.
(let [orig [{:user "me" :docs [{:one "two"}]} {:user "you" :docs [{:three "four"}]}] payload {:five "six"} t-me (first orig) t-you (second orig) you-docs (:docs t-you) new-you-docs (conj you-docs payload)] [t-me (assoc t-you :docs new-you-docs)])
With destructing you can make it look a bit cleaner
(let [[t-me {:keys [docs] :as t-you}] [{:user "me" :docs [{:one "two"}]} {:user "you" :docs [{:three "four"}]}] payload {:five "six"} new-you-docs (conj docs payload)] [t-me (assoc t-you :docs new-you-docs)])
oh that makes sense, @achythlook! thanks. i was thinking, wrongly, that i had to find to get the thing i wanted to update and update it in the same step.
@mfm just so you know, this works:
=> (def data [{:user "me" :docs [{:one "two"}]} {:user "you" :docs [{:three "four"}]}])
#'boot.user/data
=> (update-in data [1 :docs] conj 42)
[{:user "me", :docs [{:one "two"}]} {:user "you", :docs [{:three "four"} 42]}]
@sundarj thanks!
question: how would i select "the map containing the kv pair :user "you"
?
edit: inside that update-in
exression, that is
i think update-in ... [1 ..
is selecting the second vector, which i don't necessarily know
I don't think that update-in has that ability. Its purely associative. You could write something to tell you which one it is, like this horrible bodge
(get
(into {}
(map-indexed
(fn [i {:keys [user]}]
[user i])
samp))
"you")
yeah, that's right. if you don't know it, you'd need to do something like
=> (map (fn [m] (if (= (:user m) "you") (update m :docs conj 42) m)) data)
({:user "me", :docs [{:one "two"}]} {:user "you", :docs [{:three "four"} 42]})
That's why I use the library I linked to before. It has faculties for doing this sort of thing a bit more simply
definitely! thanks @achythlook and @sundarj. yeah i'm kinda surprised clojure doesn't have something for exactly this; it's common-enough for me to use vectors to represent "many"-type relationships
@mfm Its a bit of a gap, for sure. Thankfully, we have macros and insane people who write macros 🙂
Hello everyone, what approach worked for you to learn clojure ? (books, blogs, projects...)
I started with books -- Clojure in Action and The Joy of Clojure -- and a paid workshop organized by the author of Clojure in Action. There are better books to learn Clojure from these days (Living Clojure, Clojure for the Brave and True, the first two that spring to mind) and The Joy of Clojure is a great book but not a good first book for learning Clojure (I had prior Lisp and Functional Programming experience which is why I started there).
I already had many years of Lisp experience, so I just had to skim through braveclojure and the clojure docs before I found myself coding on my own.
I also found http://4clojure.com to be helpful.
cool ! thanks I started reading Brave and True but I'm moving slowly
I use C and Python most so other than basic map filter and reduce (in python) I don't have that much experience with FP
Luckily you don't have a lot of OOP teaching you bad habits to unlearn either!
Folks coming from a pure Java background can struggle with the shift from encapsulated data and side effects to immutable-data-as-the-api and pure functions...
what's a good first project idea to build in your opinion >
Hmm, hard question. I would say avoid web projects to start with...
...something that does pure data transformation or analysis is probably a good place to start.
implementing a little machine learning library for example ?
I'm not sure what that would look like -- there are already great ML libraries available in Java you can use from Clojure (but they have complex APIs in general).
well if anybody has ideas 😛 I'm buying
I was fortunate enough to already be programming on the JVM so I was able to just start writing stuff in Clojure and using it from existing projects... Is there a particular project you would have otherwise tackled in C or Python that maybe you could do in Clojure instead? Or perhaps something you created recently, that you could rewrite in Clojure?
(I recommend avoiding web projects as the first thing because Clojure favors composition of libraries over frameworks so there's a lot of "assembly required" -- and front end tooling with ClojureScript is a whole 'nother ecosystem to learn so it distracts from actually learning Clojure)
I'd like to create a 3D fluids simulation
(nothing too complicated, was planning on using python)
Hmm, I have no idea where you'd even start with that, sorry.
can it be done in clojure ? (or maybe clojurscript with three.js ? )
Yeah, definitely, but I'm the wrong person to ask -- I don't do UI at all.
Like I say tho', ClojureScript is a whole new ecosystem to learn that is different to Clojure...
oh I was under the impression it was basically the same thing. Do you have any resources I can look at to understand how they're different ? (I'll google it in the meantime 😛 )
Mostly it's about tooling and the build process and setting up a REPL with your editor that is different. The language is mostly the same.
Hi! Is there any good documentation on how to use native js-react components in cljs? I am struggling with a lib called react-datepicker from cljsjs: https://github.com/cljsjs/packages/tree/master/react-datepicker
I basically never get how to use this
in such a context
<DatePicker
selected={this.state.startDate}
onChange={this.handleChange}
/>
I am using it like this so far:
[(r/adapt-react-class (.-default js/DatePicker))]
but that is not working very well. It does not throw any error but display is not working properly.@U4GEXTNGZ I'm not too familiar with reagent itself, but after creating the component with r/adapt-react-class
you should be able to use it as you do other reagent components without concerning yourself with this
context.
for example (not too sure about the syntax)
[(r/adapt-react-class (.-default js/DatePicker))
{:selected "2017-09-27"
:on-change #(println "I've received" %)}]
@U485ZRA58 Thanks! It works!
[:> (.-default js/DatePicker) {:selected (js/moment())
:on-change #(println "meh!")}]
I now know that I am missing some fundamentals of JS-React-knowledge. I only do CLJ and started some reagent for a project. 🙂Glad to help!
Is there a way how to convert (io/resource "file.pdf")
to a File when called from uberjar? I am unfortunately using PDF manipulation library which accepts only String and File objects as an arguments so I cannot use io/resource
directly 😕
@petr.mensik Which library?
There are only 3 ways how to create it - File, String and PDDocument which by itself created from File
@petr.mensik You can create the PDDocument
manually by calling
with a RandomAccessBufferedFileInputStream
@rauh Thanks, I missed the PDFParser class
However I am not sure how to convert normal InputStream to RandomAccessBufferedFileInputStream
- because this one has to implement RandomAccessRead
which is PDFBox spefific interface
@petr.mensik perhaps this constructor? https://github.com/apache/pdfbox/blob/0597e6de2bb78fdb67ad688717fd4e32d6a90922/pdfbox/src/main/java/org/apache/pdfbox/io/RandomAccessBufferedFileInputStream.java#L111
Do be aware however that RandomAccessBufferedFileInputStream copies the data from the input stream into a temp file and then works from there. In general Java's io classes treat ordinary files and random access files like two separate worlds.
I have to take a look if I have the same version. However I might find other solution with PDDocument/load
, will see
It seems that PDDocument/load
works, thx guys
> java.lang.RuntimeException: Agent is failed, needs restart do agents really ever restart? 🙂
if you restart them
or if you set their error mode to automatically do so
I have a dumb question: I’m using clojure.core.server to create a socket server. however, the server does not keep the process alive when I’m running it as an uberjar
I tried the naive thing and created an atom that will indicate when to quit the application, and then on -main
, I start the server and just loop-recur checking the atom.
there is an option on the socket server for this
use :server-daemon false
https://clojure.org/reference/repl_and_main#_launching_a_socket_server
Is there any clojureschool web site available
Like elxirschool
FWIW, my general pattern for a keep-alive system with clean shutdown behavior is:
(defn -main
[& args]
(let [system (start-system)
runtime (Runtime/getRuntime)
shutdown? (promise)]
(.addShutdownHook runtime (Thread. (fn []
(stop-system system)
(deliver shutdown? true))))
@shutdown?))
I do something similar to the above - for bonus points, make shutdown?
visible to the rest of the code by making it a var or putting it in the system map, then you can have a ‘graceful shutdown’ service endpoint that delivers that promise.
if i have a hi.clj file and a bye.clj file..i want to import functions in hi.clj
to bye.clj
..how do i do that ?
Gracias @U3L6TFEJF
in clojurescript, people use it to define their application state so that the code can be hot-reloaded without changing the application state
yep, I used it in clojure (jvm) sometimes as well to track resources like web servers, loading config files, etc. - though I’ve started using things like mount to track those things instead
No, not that I’m aware if
No, not that I’m aware of
@grierson tools.deps & deps.edn are simple tools to handle dependencies - I don’t think it handles anything to do with running tests or watching files for changes
@lilactown I was following the official docs for Cognitech test-runner. https://github.com/cognitect-labs/test-runner Which says you can run clj -Atest
that’s still just talking about dependency resolution - it’s showing how you can pull in extra dependencies from different aliases
yeah, it looks like cognitect has created a test-runner utility that you can load and run via that command 🙂
@lee.justin.m @avfonarev I've seen people use defonce for exactly that in JVM Clojure as well.
@grierson If it helps, here's my ~/.clojure/deps.edn
file: https://github.com/seancorfield/dot-clojure/blob/master/deps.edn
clj
reads (up to) three deps.edn
files: the default installation one, your account's one, and the current folder.
🙂 clj -A:test:proto:nrepl
is my friend!
Do you have a write up of your workflow/set-up anywhere? It would be interesting to see.
No public write up, I'm afraid. My Atom/ProtoREPL setup is essentially Jason Gilman's "opinionated" setup with the three "refresh" options disabled but I have some custom keymaps etc and several additional packages.
As for workflow, it depends somewhat on which project I'm working with... my Clojure Contrib projects mostly use clj
/ deps.edn
now (a few still use Leiningen for dev work). Those I start an external REPL as above then connect to it from Atom. My work projects are all Boot-based so I just "toggle" a Boot REPL from within the project. In all cases, I pretty much never type into the REPL -- I type into source/test files and eval code (into the REPL) but mostly use the inline result display rather than even look in the REPL pane (which I have at the bottom of my screen shrunk down to just three lines).
That's following Stu Halloway's approach in his REPL-Driven Development talk (from the middle of last year, to the Chicago Clojure group I believe).
Hope that all helps?
I have :test
and :runner
separated out so I can start a REPL with my test dependencies added in or choose to run Cognitect's test runner
clj -A:test
start a REPL with tests available clj -A:test:runner
run tests clj -A:test:runner:1.8
run tests with Clojure 1.8 instead of the default etc.You could combine that with a command-line watcher utility (for whatever O/S you're on).
For my clojurescript :advanced compiles, I seem to be consistently hitting 300k on the low end. That seems... oddly big? How do I get that down?
@achythlook is that all cljs code or are you including a lot of js libraries?
Just cljs. Gzipped its about 80kb