This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2018-12-07
Channels
- # adventofcode (202)
- # aleph (8)
- # announcements (13)
- # architecture (1)
- # aws (2)
- # beginners (201)
- # boot (1)
- # bristol-clojurians (1)
- # calva (2)
- # cider (23)
- # cljs-dev (22)
- # cljsrn (2)
- # clojure (105)
- # clojure-bangladesh (1)
- # clojure-berlin (8)
- # clojure-dev (104)
- # clojure-europe (3)
- # clojure-italy (5)
- # clojure-losangeles (1)
- # clojure-nl (24)
- # clojure-russia (55)
- # clojure-spec (44)
- # clojure-uk (19)
- # clojurescript (58)
- # component (58)
- # cursive (3)
- # data-science (1)
- # datomic (27)
- # duct (6)
- # events (6)
- # figwheel-main (6)
- # fulcro (15)
- # jobs (3)
- # kaocha (5)
- # luminus (1)
- # music (1)
- # nrepl (2)
- # off-topic (24)
- # onyx (1)
- # pedestal (3)
- # protorepl (8)
- # re-frame (18)
- # reagent (39)
- # reitit (1)
- # remote-jobs (1)
- # ring (15)
- # rum (11)
- # shadow-cljs (5)
- # sql (8)
- # tools-deps (12)
- # vim (7)
Got another one: I'm trying to test a group of functions in a common context, which is defined by a global var. To do this, I'd like to do (binding [*x* {...}] (deftest test-1 ...) (deftest test-2 ...))
, but this ends up throwing away my binding. I know about fixtures, but I'd have to use set!
on the var, which feels prone to error and messiness in a way that binding
doesn't, since I'd also need another global variable to restore the root binding from. Any happy medium here?
The other alternative of course is to call binding
inside every test, or combine my assertions into a single test per binding. Both of which are kinda yucky
you don't need to use set! in fixtures
the fixture takes the tests to run as a function to call, you can call it inside the binding block
also, instead of using binding
and dynamic vars, you can have a first class function that takes the functions to test in the arglist, and makes assertions etc., and call that from inside deftest
I'm in cljs, and the docs don't mention that form: https://clojurescript.org/tools/testing
Then you still have a separate deftest for each fn group, but the body is small - just invoking the thing that does the tests with different args. When I worked on a db abstraction that supported multiple backends that is how we exercised all the implementations.
Cool, I'll try that. I do remember looking at the source for cljs fixtures, and I think they support old-style too.
How to generate a sequences of dates/times? Like "2018-09-01", "2018-09-02", "2018-09-03", ...
@stardiviner Clojure or ClojureScript?
If you're on the JVM
user=> (map str (take 10 (iterate #(.plus % 1 java.time.temporal.ChronoUnit/DAYS) (java.time.LocalDate/of 2018 9 1))))
("2018-09-01" "2018-09-02" "2018-09-03" "2018-09-04" "2018-09-05" "2018-09-06" "2018-09-07" "2018-09-08" "2018-09-09" "2018-09-10")
user=>
@seancorfield Where does the .plus
comes from? I use cider-doc
on it. It's from java.math.BigDecimal/plus
. But I guess it might be from some java class instance's method. Can you explain it a little?
The example uses direct Java interop to access the JVM8 built-in Java.time stuff. There is a clojure wrapper here: https://github.com/dm3/clojure.java-time
Why do you need to destructure? If you're using the same key regardless of the map, you can just check the value inside the function, right? What is the reason for doing the destructuring? Will the value be different in some significant way?
You can map names in destructuring with the other syntax, eg. {name-a :name :as a} {name-b :name :as b}
https://clojure.org/reference/special_forms#_map_binding_destructuring
I have a function that takes four parameters, I partially apply the first two parameters, but the last two I'd like to take from a vector like [[1 2] [3 4]]
. Is there a trick for that?
I've started with (map (partial manhattan-distance x y) locations)
, but I obviously get a list of partially applied functions 😂. I want the result of the execution of manhattan-distance
Question: is there a function that converts a normal keyword into a qualified keyword. So :key -> ::key?
I don't think you can actually have "::key", since that gets expanded to :whatever-ns-you-were-in/key
in the reader. So this function takes a key and qualifies it with the current ns.
Thanks, yeah (fn [k] (keyword (str ns) (name k))) is what i ended up with. It’s for a spec helper macro. 🙂
@nikola.kasev you're only calling it with three arguments there. (manhattan x y [1 2]). You could map #(apply manhattan x y) or you could change your distance function to operate on two points rather than four numbers and (map (partial manhattan [x y]) locations)
The regex ops s/*
, s/alt
, s/+
and others help in this
(defn foo [a & more]
(prn {:a a :more more}))
(s/fdef foo
:args (s/cat :a any? :more (s/* any?)))
Like that?
I've plowed through https://clojure.org/guides/spec a couple of times, but there are some stuff I still don't get... 😄
Yeah, I know the feeling, I always have to play around with it to get it right
and it’s going to change in the not-too-distant future
Or at least the (s/keys)
stuff will.
Yeah, excited for s/schema
and s/select
Yeah, that’s going to be a big improvement I expect
I was also wondering about how I'd map a key of a map to another spec. e.g.
(s/def ::b number?)
(s/def ::a (s/keys :req [::b-with-different-name]))
where I'd want {:b-with-different-name 10}
to qualify for ::aa lot of the spec functions run spec-impl
, which I'm not supposed to run myself, so it's hard to know what to do by reading the code 😛
It’s easy to alias a spec, just do (s/def ::b-with-other-name ::b)
oh, okay. but what if the key is really common? in my case I'm parsing xml, and I want the attrs
to map to some specs some times, and other specs at other times
That sounds like you might not want aliasing, more like you want a multi-spec maybe?
I know that multi-spec exists, I’ve kind of skipped over learning about it because it sounded complicated.
Honestly, for something like XML attributes, I’d try to make the spec for the attrs as generic as possible, like map?
or coll?
or something.
If you’re getting the XML elements as maps with keys for :tag and :attrs, and the :attrs can be any number of different things, it’s going to be crazy to spec them all.
but I guess if you were dealing with a relatively small number of different types of attrs, you could do something like define ::foo-attrs
, and ::bar-attrs
and ::baz-attrs
, etc, and then (s/def ::attrs (s/alt :foo ::foo-attrs, :bar ::bar-attrs, :baz ::baz-attrs...)
I think that would work.
well, it's pretty simple xml in this case, and there are a bunch of values that I want to validate since the program shouldn't continue if they aren't there
I'd just want to be able to do something like (s/keys :req [(::b-with-diferent-name ::b)])
something like that is potentially coming in spec2
tbd details
can i only get the line of a macro invocation (via &form
), or is there a way to find the source position of an arbitrarily deep structure passed in?
there’s metadata on the forms you get
well, that might depend actually
(defmacro foo [& body]
(println (meta &form))
(doseq [x &form]
(println (meta x))))
(foo 1 2 3) =>
{:line 1006, :column 27}
nil
nil
nil
nil
Hi all, how can I achieve automatic test re-run on file changes, (as does lein test-refresh
), but with clj
?
Did the job
reused lein-test-refresh
clj -Sdeps "{:deps {healthsamurai/matcho {:mvn/version \"0.3.2\"} com.jakemccrary/lein-test-refresh {:mvn/version \"0.23.0\"}}}" -C:test -e "(require 'com.jakemccrary.test-refresh) (com.jakemccrary.test-refresh/monitor-project [\"test\" \"src\"] {:watch-dirs [\"src\" \"test\"] :refresh-dirs [\"src\" \"test\"]})"
the problem is i am doing all manner of not-particularly-amenable-to-spec validation (this is a dsl that compiles down to GLSL, so it needs some simple type analysis), so i'd like fine grained error reporting
I may be able to do some really horrible cruft with *file*
, the clojure reader and... other stuff. but that is REALLY nasty (a macro that reads it's invocation from the source file externally with a metadata preserving read... yuck).
you might want to look at read+string
- that has been a useful tool in some of the repl changes I’ve done recently
(this is well beyond #beginners territory :)
it’s in core
oh, we added that in 1.10 I guess (time flies)
it both reads and also gives you the string it read
I presume the issue with metadata in macros is.. propagating it from within other macros (scheme has somewhat of an easier time with 'wrapped source' information and its macroexpanders)
i do have metadata, I am a fool. the problem is simple- integers don't implement IMeta
so my test is stupid
yeah, you will mostly see it on colls
that's fine, i can push that down manually. phew, i thought I didn't have anything at all. (I am still a beginner ;)) Thanks again!
Hello, everybody! I’m looking for ways to optimise my a-star algorithm. In particular, I’m trying to find parts of it, that can run in parallel efficiently. I have to say that I’m an absolute beginner in parallel computing. I’m operating 2d vectors of ints (matrices) no more than 10x10 in size and I’m doing are a lot of lookups of cells. I’m wondering if it makes sense to run it in parallel? Maybe somebody can tell of the top of their had if it’s viable or not? I suspect that the question may be naive and hard/impossible to answer without deeper understanding of the problem. I’ll still try, since re-doing the algorithm to benchmark it would be quite hard. I’ve already tried to use fold from clojure.core.reducers in a simple example of reducing a range of few millions ints with a + fn. It actually took longer than a sequential version on a machine with 8 cores.
Anyone know how to get a cider repl to work with deps.edn? I am able to connect, but evaluating anything throws an error as such:
(require '[ion-sample.server :as server])
FileNotFoundException Could not locate ion_sample/server__init.class or ion_sample/server.clj on classpath. Please check that namespaces with dashes use underscores in the Clojure file name. clojure.lang.RT.load (RT.java:463)
is the correct way to raise a clojure.lang.Compiler$CompilerException
by just constructing it as (clojure.lang.Compiler$CompilerException. <args>)
or is there a more idiomatic way buried in the library somewhere?
CompilerException is internal to the compiler so you shouldn’t be raising one of those at all (AFAIK)
what i need is to raise it such that my correct line/column information is reported back, is there a user-exposed alternative?
Is this exception being thrown from inside of a macro you are writing, perhaps?
I don't know of any more idiomatic way to construct one than by using the raw constructor.
it was 'public' but then rhicky makes everything public so that isn't exactly permission to root around in there
I can't think of any reason it is necessarily a bad idea -- just not something that most macros do.
this is translating a dsl into GLSL, so i need to be pretty specific when i report the error to the user
There is a somewhat higher probability that it could break with a future Clojure release, because it isn't part of the Clojure public API, but if you are willing to live with that.
I think I can live with it. It works so well in my case right now I'd argue it should be public 🙂
There are a lot of things that are declared 'public' in Java code that are still probably considered implementation details subject to change, I believe, but not always clear which is which in the Java code.
You are neither the first, nor likely the last, to dig through the Java implementation of Clojure and rely on something in there.
hey guys, advent of code in clojure @potetm https://www.twitch.tv/timpote, broadcasting right now
Thanks Daouda! I really appreciate your promoting the steam and all of your awesome questions!
@mseddon the area of throwing exceptions from macros is one we have focused on a bit during 1.10
my recommendation is NOT to use CompilerException directly
we are specifically looking for exceptions thrown from macros and automatically wrapping them into CompilerExceptions that track the source location
ah, thanks. I've noticed you have a new constructor that takes a phase keyword, though the constructor I was using hasn't changed for 7 years 😉
well, we try to retain backward compatibility :)
we also treat some special types of exceptions as “intentional macro checks” - things like IllegalArgumentException
the set of those is based on a review of all the macros in Clojure and a survey of macros in many public libraries
the 3 in that set are IllegalArg, IllegalState, and ExceptionInfo (which lets you throw extra data as well)
I think my use-case is pretty narrow- only really useful for some hairy embedded language
but there's no way to attach my own source/line information in a supported way currently?
well, you can attach it the same way the compiler does elsewhere
https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Compiler.java#L6808
the compiler is tracking that stuff ambiently in anonymous vars
and that info ultimately comes from metadata set by the LispReader
yeah, so (should) mine, although for fun I can naturally 'hack' emacs and report fake errors anywhere in the code if I felt particularly mean
the Compiler code is written to allow CompilerExceptions to flow through so should work fine
flow up that is
without re-wrapping
it's just extremely useful for me to see something like this when I get a static type error generated by my transpiler:
Does anyone have an example of why you would ever use a hash-map as a function?
I understand that ({:a 1 :b 2} :a)
is equivalent to (:a {:a 1 :b 2})
, but has anyone found a case where the former was more convenient?
@christian.gonzalez for example {nil 1 "a" 2 [1 2] 3}
- it's a valid hash-map, none of its keys can be used to do a lookup
keywords and symbols do that with hash-maps, other types don't
having {nil x}
as an arg to replace
is probably the most common usage of replace
Oh that’s excellent thanks! @noisesmith
user=> (def dna {\a "adenine" \g "guanine" \t "thymine" \c "cytosine"})
#'user/dna
user=> (map dna "aggcgtgc")
("adenine" "guanine" "guanine" "cytosine" "guanine" "thymine" "guanine" "cytosine")
Haha that is awesome. I was having a discussion with a coworker, why would we ever do this? Question answered.
generally I only use this syntax when I have a constant map which I’m using as a function, which isn’t too common in Clojure but it does happen sometimes
it’s important not to do this with maps someone else is giving you, because if it is null, this will throw a NullPointerException
also, I think it’s cool that the invoker of dna
here doesn’t know that it’s a constant map. you could change dna later to be a defn and the invoking it would continue to work the same
I was going to say “that would make a cool ROT-13 encoder/decoder,” but who here remembers ROT-13? :man-shrugging:
yeah, it’s pretty easy with cycle and zip to make a rot-13 encode/decode map
Now if there were still any place you could use one…
Hi everyone.
I’m refactoring some less than pretty loop-recur code. The reason why it used is to check that all elements of a vector share certain properties. The loop-recur ensures an early exit on the first encounter of an element that doesn’t have those properties. We want to maintain this early exit.
I want to replace this loop-recur with an every?
function. Taking a look at the source for every?
, it should exit on the first encounter of a bad element. Moreover, the source has been that way since version 1.0.
However, never in the docs does it mention that the early exit is a feature of every?
that is permanent. The concern is that in a later version of Clojure, the early exit property of every?
might be scrapped since that property is not mentioned in the docs. Is this a valid concern?
Any help is much appreciated. Thanks!
https://github.com/clojure/clojure/blob/clojure-1.9.0/src/clj/clojure/core.clj#L2664
don't understand your concern, what is this early exit thing? if the predicate doesn't hold for some value it produces false, that's all there is to it
The vector could be quite large, so we want to make sure that once the function finds an element that doesn’t have the properties we want, the function returns false and doesn’t compute the rest of the vector.
I don't foresee any reason that every?
would ever be changed to keep going. I personally wouldn't worry about it
@scot0530 the function source says so, it will stop at the first item for which the predicate doesn't hold, so yes, it won't compute the rest of the vector, but that "bad item" might be the last 😉
You could create a unit test that fails if the implementation of every?
ever changes, e.g. using a lazy sequence that generates an element that throws an exception for an element much later than one that should cause an early exit, if you are very very concerned about this for some reason.
Or just examine the source code on each new release of Clojure to see if it changed (although that is more manual, of course)
Sure, yeah, copy the current source code of every?
into your own local version.
Given how concerned the Clojure core team is about performance, it seems pretty far-out-there to imagine them making something like that perform worse than it does now, on purpose.
something something chunking
his concern would violate the semantics of the function, performance is another thing here
Ok, I think I will just include a test case to keep everyone on the team happy about this. That is a good idea. Personally, I am not too concerned that the source for every?
will change but I just wanted to get some other opinions. Thank you!
Leonid, are you saying you have a requirement in this code that the loop end on the very first element that fails the predicate, and is guaranteed to never try to call the predicate on even one more element, ever?
In that case, chunking of lazy sequences could cause that expectation to be violated.
maybe, anyway.
or rather, it is definitely the case that if you pass a lazy sequence into every?, it might cause the "producer" of the lazy sequence to generate a few input elements to the every?
function than it actually needs, but that shouldn't cause the current implementation of every?
to call its predicate function on those extra elements.
right - loop would do the same thing
(and now that I look at the source of every? it is effectively implemented with loop anyway)
Another way of looking at the issue -- I think it is far far more likely that someone will try to hack the security of your system in a way that is independent of the implementation of every?
, than that the implementation of every?
will change in a way that will make you unhappy in a future version of Clojure 🙂
Fortunately, its guaranteed that we won’t pass every?
a lazy sequence in this context, so I wouldn’t be too worried about chunking from lazy sequences.
"The vector could be quite large, so we want to make sure that once the function finds an element that doesn’t have the properties we want, the function returns false and doesn’t compute the rest of the vector."
@noisesmith but the next
call will cause some chunking right? which you can avoid using loop/recur on the vector with something like pop or same thing?
that's not chunking, it's potentially realizing one extra item though
you can avoid that by using rest instead of next
the funny thing is that the function is calling seq anyway, so I don't see why it would use next over rest, I'm likely missing something
@noisesmith I guess it doesn't matter since (first coll)
is realizing the head all the time
(seq has the same behavior of forcing an item, for the same reason - defined to return nil for empty input)
rest "Returns a possibly empty seq of the items after the first. Calls seq on its argument." So no. As I understand, given @noisesmith's statement above.
iiuc, the major difference between rest and next is purely to return nil vs () in the case of the empty list.
with rest you can avoid realizing the head of non-empty seq, but that's probably a small use case
Ah. Then it is not at least documented in the disappointing short docstring. :) not at a repl to test atm
http://ClojureDocs.org is a good place to quickly write short bits of documentation you believe are correct, but of course limited to review only by people who happen to read it and choose to fix things.
Then you would be in good company with anyone adding documentation to http://ClojureDocs.org. You can add it with a note like: "note the following behavior in Clojure 1.9.0" (or whatever version you tested), if you are trying to be more precise.
And/or if the docs ever become wrong, edit them again
Well, there are only 2 implementations that most people use: Clojure/Java and ClojureScript, and they are in effect defined by their implementations. Once a version is released, it is immutable.
And the developers care a lot about backwards compatibility.
Yup, makes sense. The beauty and dangers of lisp is feeling the bits between your toes. As far as backwards compatibility goes, I would hate to accidentally close off future optimisation though :)
But if I can merely claim interesting implementation details for a given version, I don't inherit the guilt. Btw thanks for contributing to such an excellent community and such a usable Lisp! I hope one day to be able to give back too.
You are welcome. It is a fun thing to learn about, and I hope to be able to use it for more than a hobby in my future.
I'm scared of accidents :) common lisp implementation variability taught me to read the hyperspec and only rely on what is stated, and with clojure particularly with realisation semantics I can see scope for realisation that might later be considered undefined.
maybe the docs intention is that it doesn't matter, so omits that part, don't know if it could cause trouble with side effects though