This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2019-04-08
Channels
- # bangalore-clj (4)
- # beginners (160)
- # calva (132)
- # cider (18)
- # clara (1)
- # cljsrn (2)
- # clojure (129)
- # clojure-boston (1)
- # clojure-europe (5)
- # clojure-italy (5)
- # clojure-losangeles (1)
- # clojure-nl (33)
- # clojure-uk (49)
- # clojurescript (88)
- # cursive (20)
- # datomic (5)
- # duct (3)
- # fulcro (33)
- # graphql (7)
- # jobs (3)
- # kaocha (3)
- # nrepl (41)
- # off-topic (58)
- # pathom (18)
- # re-frame (1)
- # reagent (5)
- # shadow-cljs (148)
- # spacemacs (7)
- # tools-deps (7)
Hey guys what is the most efficient way of importing large javascript libraries (in this case THREE.js) inside clojurescript?
Same as any other library. Either use shadow-cljs as your build tool, or see the ClojureScript webpack guide https://clojurescript.org/guides/webpack
so you end up repeating:
(+ 1 nil) ;; => 1, which will be passed in to the next one as the accumulator
(+ 1 1) ;; => 2
(+ 1 2) ;; => 3
Hmm, I don't think I understand. This is still not working: (reduce #(+ 1 %2) [1 2 3])
(returning 4 instead of 9)
Your second example is really the same issue, you need to use both the accumulated value and the element
It will likely be clearer to you if you use fn
and explicitly list out the arguments and give then names
What I don't get now is why (reduce #(+ 1 %1 %2) [1 2 3])
is returing 8 instead of 9. Same with (reduce (fn [x y] (+ 1 x y)) [1 2 3])
you are expecting something like (+ 1 (+ 1 (+ 1 _ 1) 2) 3)
, so the question is what _ needs to be and where and how you communicate it to reduce
I thought reduce would work like this: Step 1: 1 (from my vector) + 1 (hardcoded) = 2 Step 2: 2 (acculmated) + 2 (from my vec) + 1 (hardcoded) = 5 Step 3: 5 (accumlated) + 3 (from my vector) + 1 (hardcoded) = 9
but you have a function of two arguments, and one is missing in your step 1, so that cannot be what is happening
right? you step one doesn't have an accumulator to use, and reduce obviously doesn't make up an initial accumulator value from nothing
so in order to call your function it needs an item from the vector and an accumulator value
Yeah, this works. Thanks for the explanation. I need to get more used to the functional way of thinking ๐
The docstring for reduce
is quite complex but it is also very specific about what happens.
If val is not supplied,
returns the result of applying f to the first 2 items in coll
-- so the first call in your case was (+ 1 1 2)
(just so you understand where @hiredmanโs expression above came from).Thanks for the very helpful addition. I see now. In the case of (reduce #(+ 1 %1 %2) [1 2 3])
, I am getting 8 because:
Step 1: 1 (first elm in coll) + 2 (first elm in coll) + 1 (hardcoded) = 4
Step 2: 3 (third elm in coll) + 1 (hardcoded) = 4
= 8
It's much safer to always provide the initial val
to avoid the somewhat strange cases (empty collection, one element, two-or-more elements).
for a function, I don't know if I should use a named args or just accept a map, the fn has to create a map from the values given, some args are required, some are optional - what's recommended to do here?
@lockdown- Accept a map, in general.
Named arguments are good for functions that will only ever be called by humans but they don't compose well if they're called by other functions.
I haven't eval tool on hand, but I think into
function will be solution.
https://clojuredocs.org/clojure.core/into
@haiyuan.vinurs {1,2}
is the same as {1 2}
in Clojure, because commas are treated as white space.
If you were asking how to create a vector from a map, then this is one simple approach
(vec {1 2})
;; => [[1 2]]
(flatten
(vec {1 2}))
;; => (1 2)
@haiyuan.vinurs as in the string or the dictionary?
@haiyuan.vinurs - have you seen https://re-find.it/?args=%7B1%202%7D&ret=%5B1%202%5D ?
@henri.schmidt itโs a string
@haiyuan.vinurs then a regex would do the trick.
or if you know your input is safe you could be really cheeky convert "{1,2}" => "[1,2]" and call read-string on it.
Is there a way to get partition-all
or similar Clojure core function to partition (or group) starting at the end of a sequence?
So if I had an argument of "abcdefg
I would get a result (("a") ("bcd") ("efg"))
Of course I could reverse
before partitioning, just wondering if I missed something
({:xAxis 48}{:yAxis 35}) This is my map .I want value of only xAxis.
If you have a single map of {:x-axis 48 :y-axis 35}
then you can do (:x-axis {:x-axis 48 :y-axis 35}
this is not single map. How can i convert it to single map?
You could merge
maps.
Or you could map over the collection using:
(some :x-axis '({:x-axis 48} {:y-axis 35}))
or you can use map, but you also get a nil value because :x-axis only exists in one map
(map :x-axis '({:x-axis 48} {:y-axis 35}))
if i want {:x-axis 48 :y-axis 35} then how to do it ??? above solutions giving me nil value
the above some
and map
functions work on the sequence of maps.
If you want to combine the maps, then use
(reduce merge '({:x-axis 48} {:y-axis 35}))
Remember, when using a list ()
as an argument (data) then you need to quote the list, '()
or Clojure will try to call the first element of a list as a function.
Thanks for the very helpful addition. I see now. In the case of (reduce #(+ 1 %1 %2) [1 2 3])
, I am getting 8 because:
Step 1: 1 (first elm in coll) + 2 (first elm in coll) + 1 (hardcoded) = 4
Step 2: 3 (third elm in coll) + 1 (hardcoded) = 4
= 8
Hey all ๐ Iโm using Visual Studio Code + Calva. In Clojure, is it possible to put a breakpoint on a line in the source file, stop execution there and start stepping in/over the code?
It is generally possible (other tools like Cursive can do so via the JVM debugging API), but I don't know if Calva does it
@UHBCE1X7D ask on the #calva-dev channel, they are very responsive. As Calva is modelling itself after CIDER in Emacs, then Calva should have debugging at some point (if not already)
Will do, @U05254DQM, thank you ๐
well, the debugging in Cursive is a bit strange sometimes. For example, you sometimes โcontinueโ to the same line three times, because the form was a macro that happened to expand to multiple โlinesโ
well, that's true of all Clojure debuggers, both from macroexpansion and having multiple expressions per line in the bytecode
(mean no disrespect, I love cursive! just warning newcomers for that caveat!)
same is true in CLJS ๐ the places you can actually set a breakpoint in Chrome is a bit mysterious sometimes
yeah, I guess both debuggers are made for non-functional languages
(not sure how a functional language debugger would look tho)
I think it just has to do with the fact that thereโs not a 1:1 correspondence with a Clojure expression and an expression on the host platform
anyone seen illegal access when starting lein repl. just updated to 1.11.0.
java 11 you mean?
or clojure 1.10 ๐
clojure 1.10 opendjdk 1.11
yeah, Java >=9 has a new module system that hides certain implementation details from you. They are slowly removing access to those implementation details. I am sure others call explain it better than me
and already apparently have! Thanks Alex!
--illegal-access=deny, do I add this to my profiles.clj: :jvm-opts ^:replace ["---illegal-access=deny"] (that didn't seem to help)
you have one too many --- there
but this is the right place
Thank you
I think this needs to be passed to the jvm. It isn't clear from the site where to pass it, especially for someone new to Clojure and using mainly the lein tool.
or perhaps an environment variable
if you guys had to name a temporary folder and a zip file, that later will be requested by the user front-end application. What would you use to name it? i was thinking on using a UUID
The JDK has an api for this that can create unique things in an os-friendly location
@cybersapiens97 make a sha1 of the content, set the sha1 as the filename. Instant collision-free ๐
also gives the benefit of people being able to verify the contents of that specific file (but yeah, 99.99999999% of users won't care about that)
Hi, would anyone be able to explain a couple of things about Clojure spec? I am trying to wrap my head around how it compares to a static type system. I understand that it is extremely tunable and flexible (obviously different than static types), but what are some ways that it's not as powerful as a type system?
spec is used at runtime, so you do not get the ability to "check your program" by just adding specs and running a tool against your code
Okay, thanks. Since Clojure is so extensible, could one devise a program that runs everytime before you compile code to basically do static type checking via spec?
Like a middleware that checks against spec before clojure code gets read by the reader.
Oh shite, I just realize what @U064X3EF3 messaged after you
(Although Spectrum does this better than I would expect using specs)
In effect, is this library any different than having static type checking, or is it basically the exact same thing?
It canโt handle everything
And it canโt protect you from things that happen at runtime
Ultimately, types are about proving things. Specs will not help you prove things.
๐:skin-tone-2: I have a map that has some metadata, I'm trying to read a key from it, who's value is a string, but I get a ClassCastException
error, as strings are not able to have metadata
sounds like you are flipping something, because metadata is a map, and it's allowed to have strings as both keys and values
oh nm this works which kills my assumption on what was wrong
clojure
(def a (with-meta {:a "ok"} {:type "a map!"}))
(meta a) ;; => {:type "a map!"}
(:a a)
Is there any reason I can't put docstrings on my deftype methods?
How would you see them?
deftypes can only implement interface methods and protocol methods, and those are the visible abstractions
the method on a deftype isn't data that it owns, so it doesn't contain storage for a doc string - on the jvm methods aren't Objects
nominally the doc should go on the protocol or interface owning that method
(or on the type owning the method)
Poll: Leiningen or Boot?
wondering which is more used
clj and deps maybe
leiningen is used more by far
I like clj and deps so far. But my project is only 6K lines of clj/cljs.
is there a good tutorial on using clj and deps as far as workflow?
I got cider, repls, and cljs working with it. I doubt I'll ever use lein now.
clj / deps is a tool for starting a repl, and a dependency manager, you will usually still need a build / packaging / deployment tool(s) for library dev or deploying apps
there are ways to use deps and/or clj with lein or boot, and various relatively young build tools that use deps
They do are planning some cool things with boot, like being part native and supporting other languages. But for me it's still Leiningen, mostly because I now know how it works, and haven't really felt limited by it so far.
@sotrhraven At World Singles Networks, we started with Leiningen back in 2011 (because that was the only choice), switched to Boot in 2015 (I blogged about that at http://corfield.org ), and then switched to clj
/ deps.edn
completely last year (I have not blogged about that yet!).
what do you use for build / package / deploy with deps.edn?
Our code base is currently 81,461 lines (production source + tests)
With a total of 986 lines of EDN (config files + deps.edn
) across our monorepo.
(822 lines are the various deps.edn
files)
We use (my fork of) depstar
for build JAR files for deployment to production and we have a handful for small dev/build "tasks" written as Clojure namespaces containing -main
functions that we invoke with clj
and :main-opts
in various aliases.
Various clj
/`deps.edn` tools available (including depstar
): https://github.com/clojure/tools.deps.alpha/wiki/Tools
just to anyone who would like to try out: https://github.com/tengstrand/lein-polylith i'm a relative beginner on clojure web development, and i'm finding much more easier to work with my projects using Polylith, not only more easier but more fun and simple after you get how it works!
does anyone have advice or reading on composing promises? i'm defining several simple but computationally-intensive processes, which I want to combine in a few ways. Some can be done in parallel, others must wait for completion of earlier ones.
the big thing is that a Clojure promise (as opposed to other implementations like JavaScript) isn't an execution mechanism, it's a container that starts empty and gets filled exactly once
you can wait on it in a blocking manner but there's no "chaining" and it doesn't allocate a thread
there are abstractions meant for managing parallel / async execution - and promises can even be part of it, but they will be a small part if they are (they are a straightforward way to make one thread wait for a specific action in another thread)
AFAIK attend
, then
, recover
, and fail
from the page you linked were never implemented
hmmmmmm. well i don't think what i've got is complicated enough for core.async, maybe I'm wrong --- my big problem is, I'm the guy who has to start all the different components of our app several times a day, to test different revisions and scenarios, and i'm getting v. tired of forgetting to start components, or having to restart some but not others, and none of it's in code
i was inspired by a talk that suggested, maybe async is an elite carbon-fiber mountain bike, and i need a fixie ๐
there are other mechanisms before core.async - eg. agents (which use a threadpool and abstract a value that you send functions to)
it sounds more like you want something to start things and make sure there dependencies are started first, and do the reverse when you stop things
yes. i figure i'm heading in the integrant
direction but i've never written async in clojure
kinda figured i should figure out how to async, at least a little, before datafying it all
but I don't think any of that has anything to do with async/promise/futures/threads/etc
yeah i guess you could say, i can see i have a problem with multiple pieces but i don't see the seams yet
you could always just create a dependency graph then toposort the graph and do whatever with that (which is what component does)
there's also plumatic/plumbing/graph which has a data / value oriented approach to this https://github.com/plumatic/plumbing#graph-the-functional-swiss-army-knife
graph lets you define data dependencies, then hand them to an execution strategy (single threaded or async)
the promise thing came in, btw, when i was looking into ways to shell and i started playing with clj-commons-exec. it returns a promise instead of a value so I was thinking, huh, is it time to learn this aspect of clojure
you can get a plumatic graph kind of thing from a dependency graph and a topo sort as well https://gist.github.com/hiredman/71b71e4e07e7666fe1b9def9a476c765
When one does (defn foo [{:keys [a b c]]....)
, is the arg converted to a seq, then map, or to map directly?
the arg isn't converted - the clojure.core/destructure
function is used inside the defn macro to pull the values out of the map and bind them
perhaps you were thinking of (defn foo [& {...}] ...)
syntax? that starts with a seq of args and builds a hash-map
user=> (macroexpand '(fn [{:keys [a b]}] [a b]))
(fn* ([p__143] (clojure.core/let [{:keys [a b]} p__143] [a b])))
user=>
user=> (macroexpand '(let [{:keys [a b]} y] [a b]))
(let* [map__146 y map__146 (if (clojure.core/seq? map__146) (clojure.lang.PersistentHashMap/create (clojure.core/seq map__146)) map__146) a (clojure.core/get map__146 :a) b (clojure.core/get map__146 :b)] [a b])
user=>
@noisesmith heh yeah, missed the &
there