This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2019-01-10
Channels
- # announcements (15)
- # bangalore-clj (1)
- # beginners (207)
- # calva (22)
- # cider (4)
- # clara (73)
- # cljs-dev (7)
- # cljsrn (4)
- # clojure (125)
- # clojure-dev (38)
- # clojure-europe (2)
- # clojure-india (11)
- # clojure-italy (11)
- # clojure-nl (14)
- # clojure-russia (22)
- # clojure-uk (32)
- # clojurescript (30)
- # cursive (11)
- # datavis (2)
- # datomic (14)
- # editors (3)
- # emacs (3)
- # hyperfiddle (4)
- # juxt (13)
- # klipse (1)
- # luminus (5)
- # nrepl (7)
- # off-topic (9)
- # overtone (13)
- # portkey (1)
- # re-frame (15)
- # reagent (13)
- # ring (30)
- # schema (4)
- # shadow-cljs (108)
- # spacemacs (8)
- # specter (3)
- # sql (2)
- # testing (11)
- # tools-deps (21)
- # unrepl (4)
I'm seeing if I can turn my project.clj
into a deps.edn
. Can't figure out using a github repo. E.g., :deps {com.github.cognitect/transcriptor {:git/url "
gives "Manifest type detected"
also the guide suggests a form like {:git/url "
which..... seems like what I used
aren't the two forms [email protected]:foo/bar.git
and the https form?
so I'd try [email protected]:cognitect-labs/transcriptor.git
no, if yo go to repo and click the clone button the url it gives you is the https url with .git
I tried successfully with the following deps.edn:
{:deps {clt {:git/url "" :sha "05e9eb093b21d9a3458e0d946ad9dab76ae1e1c8" :deps/root "examples"}}}
The examples subproject relies on the non-git version of transcriptor, however...
You can rely on a version of the examples project, but that doesn't get you transcriptor itself via git 🙂
tools.deps
does not understand project.clj
-- only pom.xml
and deps.edn
(I think that's all)
Hi guys! Question: I have a spec defined like this:
(s/def ::person (s/keys :req [::foo ::bar ::baz]))
In another namespace, I need a similar spec like ::person
, but with all keys as optional. Is there a way to copy the ::person
spec and change the req
keys into opt
keys?The examples subproject relies on the non-git version of transcriptor, however...
@vincentdm Not any easy way, no. This is a problem that Rich talked about at Conj and a future version of clojure.spec will address this.
Hi all, new here. Not sure what the correct etiquette for asking new questions is but...Is there a built in function similar to clojure.core/time
but allows for prepending a string to the output of elapsed time output. I find when using lots of time
calls it can get confusing where they are from. I know it's simple enough to write this myself using do
but just curious if there is already something built in?
@chriskellendonk probably easiest is to use with-out-str
and then modify the string you capture
Oh nice, thanks I didn't know that existed. I'll check it out looks pretty close to what I need
user=> (str "foo: " (subs (with-out-str (time (+ 1 1))) 1))
"foo: Elapsed time: 0.010721 msecs\"\n"
it's sloppy still, but it's a start
Yeah I will probably just write my own helper to wrap this
And how do you get the original value in that case?
ah good point, this does not pass the output through
Where did 2
go? 🙂
user=> (time (+ 1 1))
"Elapsed time: 0.038226 msecs"
2
user=> (with-out-str (time (+ 1 1)))
"\"Elapsed time: 0.009613 msecs\"\n"
yeah, you could use a promise or whatever to capture the return value
but that seems ugly
I was using
(time (do (print "Timed =>") (+ 1 1)))
which works, but was hoping this may be built in. Sounds like it's not though. Thanks for the help 👍
Here's what we use:
(defmacro with-time
"Evaluates expr and returns a map of the :value and the :time (in ms)."
[key & expr]
(let [value (if expr key :value)
expr (if expr (first expr) key)]
`(let [start# (System/nanoTime)
ret# ~expr]
{:time (/ (double (- (System/nanoTime) start#)) 1000000.0)
~value ret#})))
(ins)user=> (defn timed [f] (let [res (promise) timing (with-out-str (deliver res (time (f))))] {:result @res :time timing}))
#'user/timed
(cmd)user=> (timed #(+ 1 1))
{:result 2, :time "\"Elapsed time: 0.029535 msecs\"\n"}
Return a hash map with the time and the value.
yeah, that macros probably the smarter bet
The docstring was not written with the public in mind 🙂
I still want the value to be passed through as normal with time
. I just want to add my own custom string so it reads "My string => Elapsed time: 0.029535 msec"
that's straightforward to do without a macro, in that case
(with-time expr)
produces {:time .. :value ..}
whereas (with-time :x expr)
produces {:time .. :x ..}
I don't know the macro syntax but something like
(defmacro time-with-str
"Evaluates expr and prints the time it took. Returns the value of
expr."
{:added "1.0"}
[my-str expr]
`(let [start# (. System (nanoTime))
ret# ~expr]
(prn (str my-str " Elapsed time: " (/ (double (- (. System (nanoTime)) start#)) 1000000.0) " msecs"))
ret#))
This still returns the normal output but lets me use a custom string to mark this specific call
(defmacro time-str [prefix & body] `(let [start# (System/nanoTime) ret# (do ~@body) time# (- (System/nanoTime) start#)] (println (str ~prefix time#)) ret#))
about the same thing
using prn in this context seems odd, as it just forces awkward quoting of the string part of the output
(. System (nanoTime))
might make sense in the context where clojure.core/time is defined, or might have been the right code when it was implemented, but it's not how we'd normally do interop
That’s good to know. And thanks for the implementation
oh now i see that clojure.core/time was using prn - I guess that' s to make it clearer in the repl that what you are seeing is separate from the return value?
Which predicate would return true
on a vector
, a list
, a set
or a sorted-set
, and false
on a map
?
(sequential? ...)
maybe
eh bah, not on set
I guess your best bet would be to assert that it is seq?
, but not map?
, I don’t think that all non-mapping collections have a common ancestor. Edit: or is coll?
and not associative?
is maybe better.
Okay, thank you.
Theres also a stack btw, as a collection, it doesn’t have a simple syntax for creating, but it can be useful at times
(prove me wrong tho!)
Are the semantics of #inst
defined at the level of EDN or Clojure syntax?
^ Please ignore. #inst
and #uuid
are part of EDN.
Are there plans to add more tags in EDN? (Stuff like IP addresses and URLs)
I did check out this discussion on google groups about #inst
and tagged literals in general:
you can of course add any tagged literals you like
How I do a validation on a map with prismatic schema that returns the data if the data is correct or empty string if the data is incorrect?
I ask on schema's channel?
#schema is probably more appropriate.
or here?
can anybody help me with something? I'm trying to read a clojure file and analyze the forms, but it looks like autoresolved keywords can't be read 😞 I'm not sure what to do...
how are you reading it?
the reader has a pluggable system for resolution so it is possible to plug in your own handler there to give it the “namespace context” if needed
SLF4J: Failed to load class "org.slf4j.impl.staticloggerbinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See for further details.
This isn't anything I'm depending on directly... presumably something else I'm depending on is
not sure if I should just ignore it or address it in my project.clj somehow, or what
SLF4J is a logging API with pluggable impls
many Java libraries use it
what it means is that one of those libs wrote a log statement, and no log impl was found, so it’s using the default (which does nothing)
yeah, jgit uses it
you can add an additional dependency on one of the explicit slf4j impls and then use that to configure the logging
if you want the warning to go away
I get similar errors when I boot up CIDER on an empty lein project
I see that https://github.com/clojure/tools.logging exists.... if I include it, what else would I need to do?
well, that will only deepen your problems :) tools.logging is also a pluggable logging api.
you can plug slf4j in underneath it though :)
You can include the dep org.slf4j/slf4j-nop to explicitly tell it to not do anything
this is one of those great tragedies of software right, there where once too many logging frameworks. Now there are too many logging framework frameworks
yeah but then one meta level higher
everything about Java logging should be set on fire
this is a problem that seems to plague the java ecosystem most
how did other platforms deal with it
Python has a built-in logging library that seem to be well-known enough and good enough that most people simply use it. I wouldn't be surprised if there are a few various implementations from years ago that are effectively "dead" now because of that.
Is it this one? https://github.com/Delgan/loguru
This is the library in the http://python.org docs: https://docs.python.org/3.8/library/logging.html
Oops I totally missed the “built-in” part 😔
also logging is something that is cross-cutting - needed at many levels, and its users expect to apply a single solution across libraries
so if something usable isn't in the default setup built in, you end up with lots of hacky attempts at modularity and compatibility and "dependency injection" that make the whole thing harder to understand or use properly
right, I must admit that I always use timbre in clojure. And most libs of my comp also use timbre. So basically, if something doesn’t its part of the problem
The other nice thing about Timbre -- and some of its satellite libraries -- is that you can "hijack" pretty much every Java logging library and force them all through Timbre, giving you centralized control.
yeah, was looking into that. Can you do it the other way around tho, or is it unwise to depend on Timbre if you publish a lib
Well... Timbre pulls in a bunch of other dependencies from the same author... and that has often bothered me enough to want to switch to something else...
...but whenever I've tried, the pain of logging usually makes me go back to Timbre 🙂
So I added that bridge thing, slf4j-timbre
, and now some java dep decided to DEBUG spam, do perhaps know how to tell timbre to drop everything below INFO from external deps?
timbre/set-level!
-- needs to be called before those other libraries get up and running. I tend to have that in my main namespace as a top-level call.
yeah, but that also silences my own debugs, no?
You can also blacklist packages/namespaces -- see https://github.com/ptaoussanis/timbre#configuration
For example (from our code at work):
(taoensso.timbre/merge-config! {:ns-blacklist ["com.eclipse.*"
"org.eclipse.*"
"org.apache.http.*"
"org.redisson.*"
"com.mchange.*"]
:level :debug})
Yeah, but thats a blanket ban, not level based. Well, I think I’ll learn to live with not having debug
OH, you can pass a level
Thanks!
No, that sets the level to debug but blacklists those packages.
By default, we set the level to info.
We have
(timbre/set-level! :info)
as a top-level form, immediately after the ns
form in our main namespace -- to suppress any/all debug/trace stuff at startup, then we blacklist stuff we're not interested and go back to debug level if needed in dev/test.I don't believe you can set different levels for different packages/namespaces...?
Right, its the kafka library thats very spammy, but luckily for me in a particular package only.
So I’ll just blacklist that
Thanks!
So, it turns out that you can write a custom middleware function to achieve such a feat
I think it's reasonable for a library to depend on tools.logging
and then users can do what they want with it -- including using Timbre to control everything.
Right, that makes sense
… added slf4j-timbre to my project, now I get spammed with debug info of one of its libs
I’m back on the clojure wagon for a bit. Just got my vs-code set up with calva, and worked through the 4th chapter of Brave and True. It uses Lein - and I still don’t fully understand what the bounds of that are. When I start lein repl
, it’s giving me a `Warning: implicit middleware found: cider-nrepl.plugin/middleware
Please declare all middleware in :middleware as implicit loading is deprecated.` - is that something I should resolve, or ignore for now?
sounds like something the CIDER devs need to fix - or may have fixed in a newer version
@wmichaelshirk do you have an old project.clj or something with cider-nrepl in it? If you are just starting lein repl
there should not be any CIDER deps in it at all.
I had an ancient profiles.clj
in my home directory when I started yesterday. I didn’t know what it did, but it was causing problems. I just deleted everything in it. That got my lein repl working - though with a warning that my profiles.clj was invalid.
I was still having trouble getting running with calva (clojure extention for vs code), and it was suggested to me to copy this in: `
{:user {:plugins [[cider/cider-nrepl "0.20.0-SNAPSHOT"]
#_[lein-figwheel "0.5.19-SNAPSHOT"]]
:dependencies [#_[cider/piggieback "0.3.10"]
[nrepl "0.5.3"]
#_[figwheel-sidecar "0.5.19-SNAPSHOT"]]
:repl-options {:nrepl-middleware [#_cider.piggieback/wrap-cljs-repl]}}}
in terms of everything appearing to work - yes. 😉 Just wondering if this lein warning is something to be concerned about
one last thing is that there's been a migration from tools.nrepl to nrepl/nrepl. and they clash. perhaps some of your deps have a dep on the older tools.nrepl
or lein deps :plugins-tree
if you need to check plugin deps
grepping nrepl, I get
[cider/cider-nrepl "0.20.0-20190108.170816-9"]
[nrepl "0.5.3"]
[nrepl/bencode "1.0.0"]
as these aren't project deps
the version of CIDER that Calva would recommend is likely older than the one that makes the latest lein happy
Which lib is better for clojure selenium? https://github.com/komcrad/webdriver or https://github.com/igrishaev/etaoin or other
@joshlemer In case you are learning about them, I may suggest you to take a look at this transducer blog post serie and its exercises. https://vincent.404.taipei/clojure/build-your-own-transducer-part1/ https://github.com/green-coder/transducer-exercises
I hope it helps.
@josh_tackett We've used clj-webdriver
for years but it is no longer maintained. I've been looking at switching to Etaoin but haven't had the time to investigate it fully yet. I had not heard of that other one.
@joshlemer Define "commonly". I think they are being used more and more these days but I'm not sure I'd say they were "common" yet.
It can take a while before new features are really internalized by developers at large and become "the norm". We're only recently seeing "common" usage of the Socket REPL that was introduced in Clojure 1.8, for example, and people are still asking lots of questions about clojure.spec
introduced in 1.9.
I think transducers are great -- but they can take a bit of getting your head around -- and a lot of material out there about Clojure was written before they were added so folks aren't as widely exposed to them yet as I think they will/should be.
@seancorfield
I'm in the exact same position 🙂 Here are some notes I made about switching. Hope they are helpful:
clj-webdriver
to Etaoin
- to -> go
- current-url -> get-url
- wait -> wait-visible
- input -> fill-human
- element & click -> query & click-el
We've started using HtmlUnit for some newer applications -- and nearly everything we have clj-webdriver tests for is legacy and will be retired (this year) -- so we must stick with HtmlUnit going forward rather than convert the legacy tests and/or take on a new Selenium library.
hello, I think I'm confused on how to bring in libraries. I want to use exponential math so am trying to bring in the math.numeric-tower library like so:
(ns armstrong-numbers
(:require [clojure.math.numeric-tower :as math]))
but I keep getting an error.Error:
Caused by java.io.FileNotFoundException
Could not locate clojure/math/numeric_tower__init.class,
clojure/math/numeric_tower.clj or clojure/math/numeric_tower.cljc
on classpath. Please check that namespaces with dashes use
underscores in the Clojure file name.
what are you doing to add that library to your project?
it doesn't come with clojure
hmmm. I was just trying to follow along with this: http://clojure-doc.org/articles/cookbooks/math.html
that would be the standard way to do it if you are using lein, yes
user=> (Math/pow 3 3)
27.0
that's what comes with the vm at least
I think numeric tower tries harder to use precise types
yeah, it's part of the java.lang.Math api https://docs.oracle.com/javase/8/docs/api/java/lang/Math.html
So, as I understand so far, clojure.spec and functions pre- and post-conditions server similar purposes (typechecking at runtime). Is clojure.spec supposed to replace the latter? Or is there something I'm not understanding about their usage?
if you review, that has the standard things like pow, abs, floor, ceil, cos, sin, sqrt etc. etc.
so what do I put in dependencies for the numeric tower? [clojure/math/numeric_tower "0.0.5"]?
@pberganza10 just definign a spec isn't enough to make it get checked, you can use spec checks in a :pre or :post, and you can explicitly turn on checking for a specced function
Ahhh. Think I got it. But what do you mean by you can explicitly turn on checking for a specced function
?
https://clojure.org/guides/spec#_instrumentation_and_testing if you don't turn on instrumentation, the specs you declare aren't checked
(unless you manually check things inline)
(at work, I've dealt with code that was specced incorrectly, and there was no indication that it was because no code path actually ever checked args)
@pberganza10 instrumentation and checking are good for development, but spec can also be used explicitly in your code for production use via s/conform
and s/valid?
We use spec very heavily at work, both in our development/test work and also in our production code for validation of data structures (such as API inputs).
Ok so spec has a much general use-case than I thought. I guess I could compare it to schema validation on other languages (e.g. Marshmallow in Python)?. So pre- and post-conditions are exclusively used for feedback during development,?
@chase-lambert I think the article you linked had a link to the numeric tower project, that will tell you the right way
it's probably more like [org.clojure/math.numeric-tower "..."]
yeah, and the github shows the dep vector to use