This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2020-04-21
Channels
- # babashka (16)
- # beginners (182)
- # calva (13)
- # chlorine-clover (43)
- # clj-kondo (17)
- # cljs-dev (14)
- # cljsrn (19)
- # clojure (97)
- # clojure-argentina (7)
- # clojure-dev (45)
- # clojure-europe (7)
- # clojure-germany (5)
- # clojure-nl (4)
- # clojure-portugal (4)
- # clojure-romania (5)
- # clojure-spec (46)
- # clojure-uk (21)
- # clojuredesign-podcast (2)
- # clojurescript (159)
- # conjure (28)
- # core-async (7)
- # cursive (13)
- # datomic (17)
- # defnpodcast (9)
- # duct (1)
- # fulcro (45)
- # graphql (6)
- # jobs (7)
- # jobs-discuss (1)
- # juxt (3)
- # kaocha (4)
- # leiningen (12)
- # malli (5)
- # observability (1)
- # off-topic (50)
- # pathom (15)
- # re-frame (16)
- # reitit (5)
- # remote-jobs (21)
- # ring (7)
- # shadow-cljs (166)
- # test-check (6)
- # tools-deps (27)
- # xtdb (2)
Hello, what would it be the correct to resolve a symbol that is referred in a namespace this way?
(defn resolve-referred
[ns sym]
{:pre [(symbol? ns) (symbol? sym)]}
(some-> (find-ns ns) (ns-refers) (get sym)))
Is there any other way?I tried but my input is the ns that :refer
s and an unqualified symbol and ns-resolve
was returning nil
will try again though, maybe I am doing something odd, thanks!
so actually you are right
user> (ns orchard.test-ns (:require [orchard.test-macros :as test-macros :refer [my-add]]))
nil
orchard.test-ns> (in-ns 'user)
#namespace[user]
user> (ns-resolve 'orchard.test-ns 'my-add)
#'orchard.test-macros/my-add
user> (ns-resolve 'orchard.test-ns 'orchard.test-ns/my-add)
nil
the latter case is fully qualified and that is what's not working
also ns-resolve
is weird, and if you know the full ns you want something from already, you can use (resolve 'orchard.test-ns/my-add)
that is, ns-resolve
asks for a symbol to be resolved as if you were in some other ns, and resolve
is just "get me the binding of this symbol", which seems more direct to me
Hi, how could I run clojure code in an isolated environment (e.g. in a new ClassLoader) so I can reload the classes every time I run some code? Isolated like made in https://github.com/tlaplus/tlaplus/blob/master/tlatools/org.lamport.tlatools/test/util/IsolatedTestCaseRunner.java
I think ztellman's virgil lib is made for this sort of thing https://github.com/ztellman/virgil
Thank you! But I was thinking more about runtime isolation, I will try https://github.com/RutledgePaulV/clj-embed o/ thanks
i always forget I made that. I should probably clean it up and make it work for git deps, etc
Is there a built-in function to ease implementation of string translations? What I’d like is something like:
(translate {"cat" "dog"
"dog" "cat"
"rain" "snow"}
"It is raining cats and dogs")
;; => "It is snowing dogs and cats"
(defn applesauce [s substitutions](->> (clojure.string/split s #" ") (replace substitutions) (clojure.string/join " ")))
isn’t that what raining -> snowing is doing?
clojure.string/escape
is the closest function to what you are asking about that is built into Clojure.
> isn’t that what raining -> snowing is doing?
yea sorry, I read the output too hastily. It actually returns "It is raining cats and dogs"
which is incorrect.
For a general set of strings to be replaced, if they can overlap with each other in the input, one also would need to specify (or not care about) deciding what you want as output, e.g. if you ask to replace {"bare" "1", "aren't" "2"}
, what should the output be for an input string of "baren't" ?
That question is not applicable for clojure.string/escape
, because it only allows individual characters in the "to be replaced" set, not arbitrary strings.
@andy.fingerhut hm good point. What if I restrict the substitutions to only occur within special syntax, like a template language:
"It is <precipitation> <feline> and <canine>"
? This is likely a bit easier to solve. I could pull in a template language dep, but it’d be cool to solve it inline.
That kind of restriction certainly eliminates most, if not all, cases that could otherwise be ambiguous. As long as the template separators do not occur in any other non-substitution places in the input string, of course.
I wouldn't be surprised if cl-format
can do it, but haven't dug into all of its capabilities. reduce
and clojure.string/replace
should work probably-more-closely to what you want as long as the replacement strings also never contain the boundary characters <
>
The main potential down side to combining reduce
and replace
is efficiency, if the number of strings to be replaced is large, since it will scan over the to-be-replaced string N times for N strings to be replaced. There are other solutions that guarantee passing over the to-be-replaced strings exactly once, of course.
Yea, in this scenario the perf cost might be prohibitive. Is there a name for the single pass algorithm?
Found this https://www.oreilly.com/library/view/python-cookbook/0596001673/ch03s15.html
With delimiters like <
and >
that are not used for any other purpose, it would be a simple kind of 'lexing' or parsing to find all of those in one pass, and for each one, look up the string in the map for its replacement.
At least the first solution there doesn't seem to mention what its behavior would be in the overlapping-to-be-replaced-strings case. It has some behavior in that case, of course -- I just do not know what it is off the top of my head.
Hm yea…does clojure have the regex.sub
equivalent? That’s pretty cool how you can pass it a lambda in python.
user=>(clojure.string/replace "<foo> dog <bar>" #"<[^>]+>" {"<foo>" "cat" "<bar>" "bear"})
"cat dog bear"
this works because {} is a lambda in clojure, any other string->string function works there
the hard part was making the regex that only matched one <...> at a time :D
Try (doc clojure.string/replace)
🙂
it says so right in the doc string
user=> (clojure.string/replace "<foo> dog <bar>" #"<[^>]+>" clojure.string/reverse)
">oof< dog >rab<"
anyway, it's nice that there's such a direct answer to your question
This is great. Thank you @U051SS2EU 🙏
clojure.string/replace
?
Yea that’s what I’m looking at. It should be straightforward to reduce over the translation table kvs and do a str/replace
for each one.
(defn- translate
[table s]
(reduce-kv (fn [s* pattern replacement]
(cstr/replace s* (re-pattern pattern) replacement))
s
table))
it’s because you are replacing cat first, so you get “It is snowing dogs and dogs”
then it goes to “It is snowing cats and cats”
@andy.fingerhut hm good point. What if I restrict the substitutions to only occur within special syntax, like a template language:
"It is <precipitation> <feline> and <canine>"
? This is likely a bit easier to solve. I could pull in a template language dep, but it’d be cool to solve it inline.
you can probably do that with cl-format
, it does everything else
I could maybe preprocess the translation table keys to wrap them in the syntax. {"cat" "dog"}
would become {"<cat>" "dog"}
for example.
(I should add that I’m solving a very specific problem but asking very general questions 😅 )
Sort of a longshot, but is there a way to change equality checks for ##NaN
? When doing comparisons this is a real bummer:
(= {##NaN 0} {##NaN 0}) ; => false
That's pretty much "by definition": https://clojure.org/guides/equality -- "'Not a Number' values ##NaN, Float/NaN, and Double/NaN are not = or == to anything, not even themselves. Recommendation: Avoid including ##NaN inside of Clojure data structures where you want to compare them to each other using =, and sometimes get true as the result."
And this is a long shot answer, but the only way I can think of to change that behavior in Clojure is to change the Java code that implements equality, which would be your own custom version of Clojure that no one else is likely to use.
there's prior art for specialized hash-maps that let you use special functions for equality
##NaN
is not really a true value in Clojure, in the sense of the "value of values" talk by Rich Hickey. It is a thing masquerading as a number 🙂
I have seen specialized hash-maps in many other languages, but I do not recall coming across one in Clojure before. Even if you created one, it would not change the behavior of =
for ##NaN
in all of the other contexts where they appear.
right - I'm just saying I could imagine making a hash map that handled NaN differently as a key, without changing clojure's equality globally
Apparently it is now 9 months since I spent too many hours creating this: https://github.com/jafingerhut/batman
Yeah mostly wishful thinking in asking, I’ve run across is a couple times during generative testing, for example (s/gen map?)
can produce ##NaN
as a key or value. I have enough control over the predicates I’m using though to make a version that doesn’t include NaN, so I’m gonna do that :man-shrugging:
I have a half a recollection that test.check might have an issue/ticket to add a non-Nan generator, but I haven't checked.
Interesting, there are variants in test.check.generators
like any-equatable
, I rolled my own since I’m using spec and those aren’t in spec.gen.alpha
That looks like a good filter for most things you would want to generate via test.check
Right, I would rather require extra effort to the opposite than avoid that as the default
You can ask folks like Gary Fredericks in #test-check channel for back story if you want to dig further. I suspect backwards compatibility of the test.check library may play a role here.
It's both not wanting to change the meaning of things, but also there's a tension with PBT libraries and edge cases like this
On the one hand it's annoying to have to opt out of the edge cases you're confident you don't care about, but on the other hand a big reason to use a PBT library is to discover edge cases you weren't thinking about
So making them all opt-in can actually decrease the utility
Makes sense. Perhaps this is more of the genericness of the generators spec predicates like map?
produce
I think you could make a good argument that map? shouldn't generate nans as keys in particular
Since you can't even look them up
But honestly the whole situation is terrible and there's no good answer and I think languages should never conflate floating point equality semantics with generic object equality
even java.util.IdentityHashMap, which is the only one I know of that uses identity instead of equality, still fails to match a nan key because it requires both identity and equality for some reason(???)
Regexes are a similar case
Yeah, I was shocked/annoyed the first time I discovered that regexes don't compare equal to themselves 🙂
But you can always pull the underlying string out of the regex and use that instead.
They do to themselves
Just not an identical regex
Ah, right. Yes, that was the issue I ran into.
user=> (= #"one" #"one")
false
user=> (= (.pattern #"one") (.pattern #"one"))
true
I have yet another cors issue:
Access to XMLHttpRequest at '' from origin '' has been blocked by CORS policy: The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.
So it's a cors error, and I follow the instruction and set the credentials to false:
{"Content-Type" "application/edn"
"Access-Control-Allow-Headers" "Content-Type"
"Access-Control-Allow-Origin" "*"
"Access-Control-Request-Method" "GET, OPTIONS"
"Access-Control-Allow-Credentials" false}
But still getting the same error. Fixes?@pshar10 with CORS, it's not as simple as returning the extra headers -- you need to send those headers in a CORS preflight response, i.e. OPTIONS request. A common way to solve this in a cross-cutting way is to add middleware which sets this configuration up, for example: - https://github.com/r0man/ring-cors - https://github.com/unbounce/encors