This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2018-03-09
Channels
- # alda (5)
- # aleph (10)
- # bangalore-clj (1)
- # beginners (168)
- # cider (68)
- # cljs-dev (263)
- # clojars (4)
- # clojure (66)
- # clojure-brasil (25)
- # clojure-china (1)
- # clojure-dusseldorf (1)
- # clojure-greece (4)
- # clojure-italy (3)
- # clojure-russia (4)
- # clojure-spec (12)
- # clojure-uk (16)
- # clojurescript (36)
- # community-development (12)
- # cursive (9)
- # data-science (1)
- # datascript (8)
- # datomic (20)
- # defnpodcast (6)
- # emacs (2)
- # figwheel (2)
- # fulcro (51)
- # graphql (62)
- # immutant (14)
- # keyboards (1)
- # lein-figwheel (10)
- # leiningen (5)
- # lumo (15)
- # off-topic (4)
- # onyx (3)
- # pedestal (4)
- # portkey (13)
- # protorepl (1)
- # re-frame (8)
- # reagent (2)
- # reitit (4)
- # shadow-cljs (71)
- # spacemacs (7)
- # specter (33)
- # sql (9)
- # unrepl (75)
- # vim (7)
In the Apropos podcast, the 2nd half has live video where we work through small problems at the REPL, with this being geared towards exploring things in a way that might be helpful to beginners. If interested, here's the link https://youtu.be/WyISHu0JFpg
Failed to deploy artifacts: Could not transfer artifact clorandom:clorandom:jar:1.0.0. from/to releases (): Failed to transfer file: . Return code is: 400, ReasonPhrase: Bad Request.
The extra “.” at the end of 1.0.0.
looks suspicious to me.
it's weird, but it also shouldn't matter
SNAPSHOT has a specific meaning
it wouldn't hurt to add itif that's what you mean (that it is meant to be repeatedly re-released), but it isn't needed
@suryapjr if an artifact version ends in -SNAPSHOT leiningen / maven / boot etc. will look for a new version before running and use it if available
(a new version of that snapshot version that is)
(defproject clorandom "1.0.0-SNAPSHOT"
:description "A simple wrapper around the Java Random class"
:url " " :license {:name "Eclipse Public License" :url ""} :dependencies [[org.clojure/clojure "1.8.0"]]
:deploy-repositories [["releases" {:sign-releases false :url ""}] ["snapshots" {:sign-releases false :url ""}]])
yes, that looks like it should be fine
@noisesmith done !!!
so I guess it didn't like the version ending in .
you can change your code and deploy again, with snaphsots that's allowed
for non-snapshot releases, you need to change the version so it is unique
no, the version stays 1.0.0-SNAPSHOT or whatever, but lein will pick the newer one
So now i have added my module as a dependency in my project.. So now i should call my function directly ?
use require to make sure the namespace is in scope, use :as in require to give it a shorter alias
My first library !! https://clojars.org/clorandom
(ns name.core
(:gen-class))
(defn -main[] (
println "Hi whats your name")
(def name (read-line))
(println( str("Hi " name))
(println "Where are you from ")
(def place (read-line))
(println "You are ",name, "from", place)
)
No problem, may I suggest you to take a look at this as well? Readability comes a long way if you don't opt to use tools for matching parentheses https://github.com/bbatsov/clojure-style-guide
@suryapjr Don't put def
inside functions!
@seancorfield noted !!
Maybe take a look at this: https://www.braveclojure.com/zombie-metaphysics/
Atom refers to an "identity", unlike the traditional "variable" concept, Clojure has very different idea regarding values.
I suggest that you learn Clojure gradually from the ground up @suryapjr. IMHO it's more rewarding than by simply "converting" what you already have learned from another language. Sometimes, it's even necessary to unlearn some. This book has been very helpful for me through my earlier phase of learning Clojure: https://www.braveclojure.com/clojure-for-the-brave-and-true/
@hawari.rahman17.. I'm learning it from living clojure
Forgive me for assuming. I have that book as well, but from skimming it just before, It seems that the earlier chapters from the book lack the depth required for a newcomer to Clojure. It jumps straight on how to write a functioning Clojure code instead of slowly introducing on why things are the way they are on Clojure.
I really liked clojure for the brave and true as well, read it on vacation without a laptop, so didn’t do the exercises, but gave a good overview of the syntax and general idea.
I have this code in a cljs file:
(doseq [ra (reverse received-ats)]
(-> @chart .-data .-labels (.push ra)))
(doseq [ts (reverse temps)]
(-> @chart .-data .-datasets (aget 0) .-data (.push ts)))
chart
is created as (def chart (atom nil))
. It then stores a chart.js chart.
Couple of questions about the above code:
1. If I use for
instead of doseq
, their bodies do not execute. Why?
2. received-ats
and temps
have same number of elements. How can I combine these two loops into a single one?@hawari.rahman17 true !! Yes..
@duminda for is not a loop, it's a lazy list comprehension, it does nothing until something consumes the data it is generating
in that code, there's nothing interesting returned by those bodies, so there's no reason to use for
doseq is literally the same as for except not lazy (and allowing multiple forms in its body)
@duminda map
accepts multiple collections — so you could something like:
user=> (doseq [[x y] (map list [1 2 3] [1 2 3])]
(prn (* x y)))
1
4
9
nil
;; where
user=> (map list [1 2 3] [1 2 3])
((1 1) (2 2) (3 3))
(taken from clojuredocs https://clojuredocs.org/clojure.core/doseq#example-542692c6c026201cdc32691b)@orestis @duminda doing that only makes sense if your operation requires both values, and you know both inputs are the same length, and I don't think either applies in the code pasted
I totally missed that - I still think it's clearer as two loops since the ops are unrelated
and I bet the extra lists being created are more expensive than looping twice if it's a perf concern
If I understand the context is chart data — where you have one list with x values, one list with y values, and you somehow need to munge them together.
A macro created a local id from a keyword :db/id. I have the keyword and want to access the local. (name :db/id) returns id, but as a string. How do I access the local named "id" with the string "id". Or is there a more direct way from the namespaced keyword to the local?
That returns
Assert failed: Argument to resolve must be a quoted symbol
(core/and (seq? quoted-sym) (= (quote quote) (first quoted-sym)))
hmm. maybe resolve is not what I am looking for. (symbol (name :db/id)) seems to give me the symbol. How do I get from there to the content of the local the symbol points to?
@magra If you have the symbol then either resolve or ns-resolve will give you the var, which is sort of a value container. var-get will get you the value.
(var-get (resolve (symbol "x"))) will get you the value of x.
But, this only works for symbols that are def'ed. Bindings created via let are kind of in a different world.
Thank you @russ767. That works in the clj repl. But cljs does not get past the resolve statement. And yes, I would need that for locals, not def'd symbols. Am I thinking about this wrong? Is there a more sensible way to go from a keyword to the content of a local by the same name?
So I would hesitate to say "you are doing it wrong" (people do that way too often) but I'm not sure I've ever had the problem you are describing. A macro may be the solution. What are you trying to do at a higher level?
I know the question must have been asked 100 times, but once again. What book/sequence of books would you recommend to learn clojure? Background: I have no problem with functional programming, understand the syntax, and am able to do, say, all of the advent of code. However, there are things I’m extremely uncomfortable with in clojure: concurrency, records vs. plain maps, handling state in a small, but non-toy application, basically, anything “real world”.
The Joy of Clojure sounds like a good fit for you! It’s the one Clojure book I refer back to again and again. It goes into great depth about everything in the core language, including all reference types like atoms. But it doesn’t cover “systems”-level state management like Component, Integrant etc.
You might try Clojure Applied as well.
Anyone ever built a polling trigger kind of thing with a re-frame event? I need to poll an api every 500ms. How do you create an event for such kind of things?
@magra So my knowledge of cljs is pretty limited, but the words "write that code for me" suggest a macro to me.
@timok : perhaps you can have a look at the first example in the re-frame tutorial here: https://github.com/Day8/re-frame/blob/master/docs/CodeWalkthrough.md Basically fire an event from a timer.
@duminda thanks! I found this with the right keywords in google: https://github.com/Day8/re-frame/blob/master/docs/FAQs/PollADatabaseEvery60.md
Depending what the latency is like, how many clients there are, and how client-specific the API call is, I’d consider writing the poll loop on serverside, and streaming down to the client(s)
@magra My advice to beginning macro writers is to start by writing an ordinary function that takes takes the arguments you think you will pass to the macro (keeping in mind that macro args don't get evaluated, so ' is your friend here) and outputs the code that you think the macro should output. Once you have that working, switch from defn to defmacro and see what happens. This way you can start out in the ordinary world of garden variety functions and work from there. You can do the reverse as well - turn your misbehaving macro into a regular function to debug it. And of course there is macroexpand.
The nasty bit is that the expanded stuff needs to contain a syntax-quoted expression. So the nesting of the quotes and unquotes is confusing.
Just keep repeating this to yourself: Syntax quoting is just like HTML templating where instead of {{foo}} or <%= foo %> or whatever you have ~foo.
Hello, I'm reading the third edition of Programming Clojure. In the chapter on Clojure.spec it defines an example spec for clojure.set/intersection. When the spec is tested using s/conform the vector is quoted. But all other examples thus far are using a regular (unquoted vector).
We can spec the arguments to intersection as follows.
(s/def ::intersection-args
(s/cat :s1 set?
:sets (s/* set?)))
(s/conform ::intersection-args '[#{1 2} #{2 3} #{2 5}])
-> {:s1 #{1 2}, :sets [#{3 2} #{2 5}]}
Is there a reason why this specific example uses the quoted vector '[#{1 2} #{2 3} #{2 5}]
?
no reason that i can see - you typically only need to quote stuff when lists/symbols are involved. i wouldn't worry about it 🙂
ah ok thanks. The next example refactors it but still uses a quoted vector so I thought there's some special case with sets.
I'll ask this in beginners as that is how I feel with this issue. Over the past month or so my lein repl
invocations have intermittently started hanging and finally bailing out with a REPL server launch timed out.
. If I start the server with :headless
in one invocation and connect to it with :connect
it works. This breaks even outside of projects running lein in an empty directory. clj
has no issues starting a repl.
lein -v
-> Leiningen 2.8.1 on Java 1.8.0_161 Java HotSpot(TM) 64-Bit Server VM
top of the main
thread jstack output for the hanging lein repl
invocation:
"main" #1 prio=5 os_prio=0 tid=0x00007f0aa800b800 nid=0x3e49 waiting on condition [0x00007f0aaf02b000]
java.lang.Thread.State: TIMED_WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x0000000719974700> (a java.util.concurrent.FutureTask)
at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:215)
at java.util.concurrent.FutureTask.awaitDone(FutureTask.java:426)
at java.util.concurrent.FutureTask.get(FutureTask.java:204)
at clojure.core$future_call$reify__6962.get(core.clj:6699)
at clojure.tools.nrepl.ack$wait_for_ack.invokeStatic(ack.clj:32)
at clojure.tools.nrepl.ack$wait_for_ack.invoke(ack.clj:16)
at leiningen.repl$server.invokeStatic(repl.clj:250)
at leiningen.repl$server.invoke(repl.clj:232)
at leiningen.repl$repl.invokeStatic(repl.clj:320)
ok -finally- figured out the cause of this. Seems I have a vpn solution which is a tad greedy and somehow prevents the repl from starting. Seems strange to me as the repl is starting on 127.0.0.1...but after disconnecting it started working.
you were realizing a lazy seq that was returned, and the print means you don't realize that lazy seq any more?
eg. if a function looked like (defn foo [] ... (for ....)) and it changed to (defn foo [] ... (for ...) (println ...)) - now the for doesn't run
maybe, but no lazy anything in this particular program AFAIK. all that’s being printed is a string fetched from a hashtable.
so the print isn't changing what's returned somewhere?
then there's some other confounding variable
you can look at criterium if you want to get accurate microbenchmarks https://github.com/hugoduncan/criterium
3x is inside the band of noise for naiive benchmarking with (time ...)
I’ve just been trying to do just that, and it baffles me… it seems to want to run the code 50 times, which is prohibitive. Playing with overriding the defaults now
you can't get an accurate benchmark with a single run
you can use quick-bench for less accuracy and less runs
I just want a vague idea why runtime goes from 30 seconds to 120 seconds by making what should be a totally inconsequetial change
I tried quick-bench and it still wants me to wait a long time… I lose patience after 5 minutes or so
that's not answerable with the amount of information you provide, other than saying measurements are unreliable using time
OK then no answer can be given with the amount of info you provide
another option is to do proper profiling, for example using visualvm or yourkit
I'm spec'ing. How should I go about doing this collection of collections of ints and other collections? ([0 (0 2)] [1 (1 4)]
@noisesmith thanks for listening
sorry I couldn't offer something more concrete - I have a strong hunch once you find it it will be something very simple
@jar23 I wonder if you could narrow it down by selectively replacing top-level functions with stubs that return dummy data. Kind of a binary search, find the top-level fn that makes your program run faster when you replace it, then drill down and replace the functions inside that
@elena.caraba I'm just reading the a chapter on clojure.spec so I gave it a shot but I have no idea if this is idiomatic
Ensure it fails for non integers:
(s/explain (s/+ (s/tuple int? (s/coll-of int?))) [[0 '(1.2 2)] [1 '(1 4)]])
In: [0 1 0] val: 1.2 fails at: [1] predicate: int?
@jonjanisch Interesting thought about using tuples. I'm thinking if every or every-kv may be what I want/need.
I believe those are for large collections where you don't want to test all (just some subset)
I think you can simply change s/+
to s/every
also:
(s/explain (s/every (s/tuple int? (s/coll-of int?))) [[0 '(1.3 2)] [1 '(1 4)]])
In: [0 1 0] val: 1.3 fails at: [1] predicate: int?
And you can change s/tuple
to s/cat
if you want to tag them for better error messages:
(s/explain (s/every (s/cat :my-int int? :my-int-coll (s/coll-of int?))) [[0 '(1.3 2)] [1 '(1 4)]])
In: [0 1 0] val: 1.3 fails at: [:my-int-coll] predicate: int?
Is there some succinct clojurescript way to write the equivalent of return a || b;
in other words use a
if it is true (not empty in my case) otherwise use b
?
Minor clarification based on "use a
if it is true (not empty in my case)":
Note that in clojure/script, empty sequences are truthy. You can use seq
or empty?
on them if you want to detect non-emptiness.
user> (if () :truthy :falsey)
:truthy
user> (if (seq ()) :truthy :falsey)
:falsey
ah, thanks I was looking everywhere for that or operator... I just completely missed it -_-;;;
@kara another function you might want to use is https://clojuredocs.org/clojure.core/some_q