This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2018-05-08
Channels
- # architecture (20)
- # beginners (140)
- # cider (155)
- # cljsjs (1)
- # cljsrn (29)
- # clojure (53)
- # clojure-dev (9)
- # clojure-italy (40)
- # clojure-nl (13)
- # clojure-poland (4)
- # clojure-russia (8)
- # clojure-uk (51)
- # clojurescript (74)
- # cursive (36)
- # data-science (1)
- # datomic (3)
- # emacs (14)
- # fulcro (11)
- # graphql (2)
- # java (21)
- # javascript (2)
- # jobs (3)
- # nrepl (7)
- # off-topic (18)
- # om-next (1)
- # onyx (9)
- # portkey (8)
- # re-frame (72)
- # reagent (64)
- # reitit (4)
- # remote-jobs (1)
- # rum (1)
- # schema (1)
- # shadow-cljs (49)
- # slack-help (1)
- # spacemacs (8)
- # specter (7)
- # tools-deps (27)
- # vim (28)
':use' is kind of old fashioned, ':require' is what is pretty much always used these days, and it has a super set of use's functionality
In terms of ns
forms, this is a good pattern to "just follow", IMHO: https://stuartsierra.com/2016/clojure-how-to-ns.html
Oh hey @mfikes thanks! That's actually a very nice breakdown. Haha, I adore the line "Summary: make it look like this." that's exactly what I was hounding for.
Guys, how do i use a native function from ReactNative with Reagent? like fetch() for example
@sujofoceb You can just use js interop syntax. Here’s an example: https://github.com/JulianBirch/cljs-ajax/issues/155#issuecomment-237257235
Can someone point me to the docs on calling clojure from java? I’m assuming the two steps are: 1. add a gen class function that describes the functions you want to generate a class for… though im not sure of the specifics 2. Use the clojure.java.api.Clojure to call these java classes.
At the bottom is a good explanation https://clojure.org/reference/java_interop
Don't use gen-class would be my recommendation!
The Var/invoke API is fine. You don't need to compile code. AOT is the devil 🙂
Thanks sean. Some docs seemed to imply i didn’t need to, but i wasn’t sure if they were just omitting it because it was commonly understood.
Does anybody ever had a problem when dealing with curly brackets in clojure regex? I'm trying to extract a word inside a curly bracket:
(re-matches #"\{\w+\}" "/user/{type}:{id}")
But it can't find the type
and id
string and resulted nil
.
I've tried double escaping the {
and }
but then it resulted in RuntimeException, clojure complaining that there's an unmatched )
. Why does my seemingly innocent regex can interfere with Clojure reader?re-matches
only matches if the entire string given matches, and your regex fails to match the /user/
or the :{id}
Is there a quick-start template based on tools.deps that includes nRepl support (so it can be used with CIDER?)
Yeah, I saw that announcement but I thought I had to do add some stuff to my deps.edn
file 🙂
Ah you're right @carr0t, should've read it in clojuredocs:
;; The distinction is that re-find tries to find _any part_ of the string
;; that matches the pattern, but re-matches only matches if the _entire_
;; string matches the pattern.
I want to model some tree-like data with internal links using basic map/vector/set structures. For example, I might have articles
and users
and each article
could have an author
link back to the users vector, in such a way that there is no duplication of the user data. (This is just a modelling experiment, not something that will live in production). I guess the various “mutable” stuff like vars and atoms help here but I wonder if there is a proven way of doing this kind of in-memory modelling?
i'm a big fan of the way Om Next and Fulcro do it (a normalized in-memory graph): http://book.fulcrologic.com/#_the_secret_sauce_normalizing_the_database https://github.com/omcljs/om/wiki/Components,-Identity-&-Normalization so for your example it might look something like:
{:articles [[:article/by-id 1]]
:users [[:user/by-id 91]]
:article/by-id {1 {:db/id 1, :article/title "foo", :article/author [:user/by-id 91]}}
:user/by-id {91 {:db/id 91, :user/name "billy"}}}
Oh, that’s neat — now how to get this to the server? I guess DataScript could also be helpful for a first draft?
with Fulcro/Om Next what happens is that you have that kind of in-memory database on the client, and each component has a query that it sends to a 'remote' (which could either be a server or a client-side database like datascript). then the remote responds to the query however it chooses - so for example if a component queries for :user/name
, then the remote gets asked for that, and does the appropriate action for whatever the underlying database is to return that specific piece of data
there's a datascript example for Om Next here: https://github.com/omcljs/om/wiki/DataScript-Integration-Tutorial
Right, yes. What I want to do (to start with) is being able to model my data server-side without worrying too much about storage, structure and so on. Perhaps using plain maps/vectors but not be enough given the relations between entities. I now see though that DataScript can be run on the server side and be like a baby Datomic…
yeah that's what ends up happening with Fulcro - you start by just hard-coding an in-memory database on the server (or just the client) and respond to queries from that, then later on you change it to an actual database
Nice — though to clarify, I’m not even thinking about UI at this point. Just the most canonical and ideal representation of my domain as data that I can come up with.
right. there's a good library for building these kinds of graph query parsers: https://github.com/wilkerlucio/pathom
I’ve expanded my thoughts here: https://clojureverse.org/t/data-modelling-approaches/2118 — any feedback appreciated!
java interop question.. how can i reference / get a handle on the http
constant in this class? https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/cloudfront/util/SignerUtils.Protocol.html#http
you should be able to use (:import [com.amazonaws.services.cloudfront.util.SignerUtils Protocol])
and then use Protocol$http
so that's what i thought, but then...
(:import [com.amazonaws.services.cloudfront.util.SignerUtils Protocol])
CompilerException java.lang.RuntimeException: Unable to resolve symbol: Protocol in this context, compiling:(/private/var/folders/tx/nvfg34312m31g7gsbkjyxxqh0000gn/T/form-init7297532591394822523.clj:1:1)
ahh, try (:import [com.amazonaws.services.cloudfront.util SignerUtils SignerUtils$Protocol])
and then SignerUtils$Protocol/http
there is always a bit of guesswork involved to make stuff like this work (at least for me), it’s easier if you can use auto-complete in the REPL 😛
🙃
(:import [com.amazonaws.services.cloudfront.util SignerUtils SignerUtils$Protocol])
CompilerException java.lang.ClassNotFoundException: com.amazonaws.services.cloudfront.util, compiling:(/private/var/folders/tx/nvfg34312m31g7gsbkjyxxqh0000gn/T/form-init7297532591394822523.clj:1:1)
user=> (import [com.amazonaws.services.cloudfront.util SignerUtils SignerUtils$Protocol])
com.amazonaws.services.cloudfront.util.SignerUtils$Protocol
user=> SignerUtils$Protocol/http
#object[com.amazonaws.services.cloudfront.util.SignerUtils$Protocol 0x238d27ef "http"]
out of curiosity, what stops me from importing all the way down to the Protocol class?
Protocol
is an inner class of SignerUtils
, but inner classes don’t exist at the class file level, they just get renamed to OuterClass$InnerClass
and then there are a bunch of hacks in the Java compiler to make private variable access and stuff like that work
since Clojure operates on class files it must import it with actual name in the class file, which is SignerUtils$Protocol
incidentally, the inner class hacks will not be required once the concept of “nestmates” are introduced: http://openjdk.java.net/jeps/181
-2nd, the first is always the accumulator-
oh, sorry I’m mixing terms - here val
is the initial accumulator, so 1st :)
I always begin a reduce
with (reduce (fn [acc itm]
if you think about a reduce like starting with an initial value, then continually adding new values to it, then the argument order starts to make more sense 🙂
I often use fn over #() for reducing functions too - I think it helps to name those
I rather like to have to function for reduce separately defined above. Sometimes taking an extra argument, using partial. Is that an anti-pattern?
@gklijs not at all!
Infact I often consider complex reduce bodies to be a anti-pattern,
(reduce group-by-products {} coll)
is often much more readable than the alternativei’ve often wondered why clojure and other languages like javascript put the function first. if it were last, it would be easier to deal with complex function bodies because there wouldn’t be so much code before the initial value & collection
Btw, this is why arguments in clojure functions are ordered by "most likely to be partially applied"
For example, in Datomic:
(map (partial d/entity db) list-of-ids)
Hi, while doing some scouting around I found that Leiningen is top consensus choice to get a Clojure + Clojurescript learning environment going, is that still the case?
yeah, even if you eventually use boot it's easier to learn leiningen first
Is there a go-to guide that still reflects how the community feels is best to get "up and going"?
this is an open discussion still, but most would agree that you should use your favorite editor (whether it integrates with clojure or not, but it probably does if it's any good) and leiningen
I'm sure people will contradict me if I'm off base on that
depending what you want, the clj
tool may be sufficient - see https://clojure.org/guides/getting_started
totally fine
Clojure doesn’t hide its host so you will be starting the jvm and may see jvm stack traces, but otherwise, you can largely ignore it at the beginning. over time there are some parts of the JDK that are useful to know about and interop for leveraging Java libs, but you can push that off quite a while
there are some “jvm for clojurists” type posts out there too
or actual courses like https://purelyfunctional.tv/courses/jvm-clojure/
I'd first want to do Clojure as long as possible before I have to deal with underlying Java
^^ that page is probably sufficient
probably more than sufficient actually
there are kind of three parts to java 1. the jvm 2. the libraries that are part of the jre 3. popular 3rd party java libraries
are there alternatives to using nrepl? i got it to work with my editor-setup, but it breaks on the newest version (using the nrepl-middleware)
yeah i haven’t gotten up to java interop yet, just dealing with interpreting stack traces and the current bane of my existence which is the NullPointerException
i only mention that since it has some good ways to filter stacktraces and nav to code
i managed to implement a* with little difficulty so i’m very excited about learning more!
Hi! Is there a better way to do this kind of destructuring?
(let [new-shape-size (:new-shape-size state)
current-shape (:current-shape state)
shape-angle (:shape-angle state)
I wonder if there’s something like
(let [new-shape-size from state]
(let [{:keys [new-shape-size current-shape shape-angle]} state] ... )
it's normally part of the OS install
depends on what you mean though. In production I've never had to manage it, the server VMs came with it
ditto for OSX it comes with a recent enough version
osx comes with that
but very rarely do you need mroe than one jvm on a single box
apt is what you want then
is there a nice chart cheatsheet out there of map vs mapv vs run vs doseq, in particular the lazy vs nonlazy versions? i have some kind of mental block about remembering what’s lazy and what to do when i need a nonlazy version
it's` run!` btw, "do", "!" in the name, and returning a vector all mean "not lazy" if that helps
and the difference between run! and doall is whether the sequence i returned? anything else?
you are thinking dorun
i feel like i’ve read you give the same advice a million times and i feel bad for not absorbing it
the difference between dorun and doall is that doall returns the sequence
now that run! exists I rarely find a use for dorun, fwiw - maybe others have coding styles where it still comes up though
i see so when i moved from mapv
to map-indexed
this is why i got screwed up because vectors are nonlazy (?)
for your actual question, there's no cheatsheet that I know of, but if I made one it would have dorun, doall, doseq, dotimes, run! on one side, and for / map / mapcat on the other
right, vectors are never lazy
in fact we can fudge the specifics and say "only lazy seqs are lazy" (strictly speaking there's a few lazy types but they all act like lazy seqs, that is, linked lists, in being unindexed and having a first and rest)