This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2021-02-24
Channels
- # aleph (19)
- # announcements (59)
- # asami (34)
- # aws (1)
- # babashka (17)
- # beginners (174)
- # bitcoin (11)
- # calva (16)
- # chlorine-clover (5)
- # cider (5)
- # clj-kondo (14)
- # cljsrn (13)
- # clojars (25)
- # clojure (124)
- # clojure-australia (1)
- # clojure-europe (48)
- # clojure-nl (4)
- # clojure-spec (1)
- # clojure-uk (40)
- # conjure (6)
- # core-async (25)
- # cursive (30)
- # data-oriented-programming (3)
- # datomic (14)
- # depstar (14)
- # emacs (3)
- # graalvm (27)
- # helix (1)
- # honeysql (25)
- # hoplon (3)
- # jobs-discuss (6)
- # kaocha (3)
- # lsp (109)
- # lumo (1)
- # malli (5)
- # meander (21)
- # music (1)
- # pathom (1)
- # re-frame (4)
- # reitit (1)
- # remote-jobs (1)
- # reveal (11)
- # rewrite-clj (3)
- # shadow-cljs (42)
- # spacemacs (15)
- # sql (13)
- # startup-in-a-month (4)
- # tools-deps (45)
- # vim (16)
- # xtdb (23)
- # yada (1)
Hi everybody, is there any known problem with satisfies?
not working on protocols that use :extend-with-metadata
?
oooh ok I need a :refer
- I was using namespace/Protocol
inside satisfies?
duh
thanks a lot to the author of this post https://matthewboston.com/blog/clojure-protocol-namespaces/
nope it's not that - that works on extend
ed things though
I get this error, has anybody ever seen it?
Unhandled java.lang.NullPointerException
(No message)
core.clj: 144 clojure.core/instance?
core_deftype.clj: 536 clojure.core/find-protocol-impl
core_deftype.clj: 569 clojure.core/satisfies?
This is when doing:
(import 'MyProtocol)
(satisfies? MyProtocol x)
I get this error, has anybody ever seen it?
Unhandled java.lang.NullPointerException
(No message)
core.clj: 144 clojure.core/instance?
core_deftype.clj: 536 clojure.core/find-protocol-impl
core_deftype.clj: 569 clojure.core/satisfies?
This is when doing:
(import 'MyProtocol)
(satisfies? MyProtocol x)
Ok sounds good, i tried refer as well as namespace/protocol
but not a var. I had to take a break from the madness but will try again tomorrow, do you have any example by any chance I can look at? Thanks for answering!
refer and namespace/protocol should both work (just like normal vars)
but back to your original question - satisfies? does NOT work with metadata extended instances, in case that's the real problem you're seeing
I am just saying, if you use import to get access to a name, that name does not name a protocol
Import let's you refer to a java class or interface by its simple name, a protocol is not a java class or interface
@U064X3EF3 @U0NCTKEV8 I went down the rabbit hole (on mobile) and checked github code. It seems there is at least one other instance of my problem here https://github.com/psagers/links-clj/blob/9e8795dfc1ce407720d5f1f1b683cba3983deeee/src/server/net/ignorare/links/db.clj#L30 Has this been reported? That is exactly what I am seing. In any case tomorrow I will try an isolated repro..
yes, you can vote for it here: https://ask.clojure.org/index.php/4622/satisfies-doesnt-work-instance-based-protocol-polymorphism
Cool thank you Alex
in general, you should not actually be using satisfies? much - it's better to rely on just invoking the protocol methods and fallback to default behavior (Object etc) if needed
Yeah I am doing that ... I was thinking of adding a spec that make sure the passed object satisfies?
my protocol
Super basic macro question: How can I turn {:x 1 :y 2}
into (def x 1)
+ (def y 2)
?
(defmacro def-all [m]
(->> (for [[n v] m]
`(def ~(symbol n) ~v))
(into [])))
This kind of works, curious if there’s better waysI've recently discovered https://clojuredocs.org/clojure.template/do-template could be useful for your scenario
huh, cool! never seen that before and it’s kind of nice
I learned about that like two days ago looking at the implementation of “are”. I had never heard of it either
I'd replace the (into [])
with an outer do
(ins)user=> (defmacro def-all [m] (cons 'do (for [[n v] m] `(def ~(symbol n) ~v))))
#'user/def-all
(ins)user=> (def-all {:x 1 :y 2})
#'user/y
(ins)user=> x
1
(ins)user=> y
2
i wish all this cool ninja code automatically went into a mega list of how to do stuff in clj
At least now it’s not going to disappear in the voids of this Slack https://martinklepsch.org/posts/clojure-macro-magic-vars-from-map.html
I have a question about licensing. I’m working on something that could be construed as a Clojure interpreter - early in the works but planning to be as compatible as possible, probably to the point of being able to crunch clojure.core
. I don’t necessarily plan to distribute clojure.core
with the interpreter as I would rather write my own. But even then, some macros and functions would end up looking 1:1 same as in clojure.core
. Given the above - am I forced to make my project EPL-1.0?
Disclaimer: IANAL and this is not legal advice. It seems to me that if you are copying clojure.core all or in part, you are effectively making a "contribution" under the terms of the license and a derivative work provided in source code form must be made available under the EPL 1.0 agreement per the license. Distributing in object form has different constraints.
If you are doing this as part of a project for a company you work for, and plan to distribute source code for it, then perhaps the company you have actually hires intellectual property lawyers that can give you actual legal advice. If this is a personal project, you can hire an intellectual property lawyer yourself for such advice, but that can be expensive, and is pretty uncommonly done.
Stated more positively, the existence of Clojure implementation distributed under the EPL gives you the option to read it, learn from it, and copy parts of it into your own project, but then you have accepted the EPL and its terms. You can also make the project you want in a clean room implementation where you never look at the Clojure implementation code, and then it is your code and you can use any license you choose.
; offtopic - would be great if we could just write code & solve problems and not have to deal with money or licenses that the latter requires
I understand the feeling, but unless you think that the idea of intellectual and/or all property should be abolished, licenses will exist.
i'd vote for robots doing all the annoying work for us so we'd be left with the fun parts
such robots do not automatically spring into existence by the mere act of voting/wishing 🙂
well once they do we'll be in trouble 😄
not in an armageddon war style trouble, trouble in the way that we still have to stay sane and somehow behave
I wanted to use the MIT license but I’m just wondering if defining my when
as (list 'if test (cons 'do body))
would count as copying parts of clojure and forcing me into EPL
as there would be multiple cases when, even if not intended, code would look the same because sometimes there is only one sane way to implement something
if you separate that part of the code out and publish that under epl with correct references , and use it as a library in your project .... would that enable you to "mit" the rest?
There are examples of companies wanting to be squeaky clean about a reimplementation actually adopting so called "clean room reimplementation" techniques, which you can study more about if you want to be squeaky clean. These same kinds of 'fuzzy boundaries' exist in copyright law for published books and papers, e.g. copying one or a few sentences with attribution is covered under "fair use" in many countries law, copying entire chapters is not. Is the dividing line a particular number of characters or words? I doubt it.
So I’m doing my own compiler and bytecode vm which I have to design and write myself based on: • my knowledge of clojure (top of my head) • available user-facing docs on how clojure and its APIs should behave Thus, I’m not concerned about infringing on anything at this point - the fun will start when the interpreter matures enough to run actual Clojure code
And you have a strong preference to release your code under a license that is something different than EPL 1.0 ?
Still not a lawyer, but if you "write your own replacement for clojure.core", without referring to the contents of clojure.core, from the top of your head understanding of how things should behave, then you are probably fine. If 100 of those definitions are character-for-character identical with sections of the clojure.core source file, it is hard to believe that you actually implemented it independently.
If two one-line functions are character-for-character identical and the rest are slightly different (or more), then it seems plausible that you wrote them yourself.
Those kinds of micro-analysis of differences would only ever be an issue if someone wanted to take this up in a court case, which if you truly implemented your own code, and even briefly described your process in a project README or something, seems unlikely to ever happen.
As a coding practicality side issue, making something 100% compatible with Clojure/JVM implementation in all ways sounds extremely time consuming to do without referring to its implementation code. ClojureScript and Clojure/JVM have differences, partly due to differing underlying JVM and ClojureScript runtimes, but partly due to the fact that it is hard to make two implementations 100% compatible.
You could ask @borkdude for his estimates of % compatibility (if a percent number makes sense at all) between his sci interpreter and Clojure/JVM, but there are a list of known differences there.
I mean, I’m just making an interpreter that could only be considered a toy when compared to Clojure itself - my goal is to have as much compat as possible but, as you pointed out, this will not be 100% due to runtime differences and time constraints
The main diff between sci and JVM Clojure is features that rely on defining new classes at runtime like defprotocol and defrecord are basically "faked" using multi-methods. And deftype and definterface aren't supported at all.
These things aren't supported by joker at all maybe for the same reason. In your interpreter, if you support Go interop, maybe this will be a funny mix of Go structs and defprotocol, that's up to you to find out and I will be interested to look what you come up with :)
I want ns.Def("x", &MyGoStuff{foo: 1})
show up as a record on the other side, with methods if MyGoStuff
has any
anyway, thank you @U0CMVHBL2, @U064X3EF3 and @borkdude. This clears things up a bit for me 👍
as an obvious test, I think if you ever find yourself copying and pasting code from clojure itself into your files, that is clearly ... "copying" ... and "copyright" is in play :)
Hello, I have an issue with a https://gist.github.com/scttnlsn/9744501 that @borkdude helped finding to me, and when I use it seems to only print the value on the first or multiple times `put!, the second, fourth, etc are not called:
(defn debounce [in ms]
(let [out (chan)]
(go-loop [last-val nil]
(let [val (if (nil? last-val) (<! in) last-val)
timer (timeout ms)
[new-val ch] (alts! [in timer])]
(condp = ch
timer (do (>! out val) (recur nil))
in (recur new-val))))
out))
(def in (chan 1))
(go-loop [value (<! (debounce in 1000))]
(println value)
(recur (<! (debounce in 1000))))
(put! in {:bar (rand-int 100)})
So when I call the put!
, the first time it's printed the value, when called a second time, it's not
but If I call quickly multiple times the put!, only the last value is printed as expected
AFAI could understand, the debounce function waits for a second input to them start the debounce
when you recur nil after putting, if you don't get anything with the timer, you >! nil which isn't great for async. I think you need some sentinel value for a lack of value other than nil. and if your timer goes off with this sentinel just recur without the >! to out
oh, it makes sense, actually, there is a if that check if the last value is nil and waits for a next <!, that seems to be the issue too
(go-loop [value (<! (debounce in 1000))]
(println value)
(recur (<! (debounce in 1000))))
This is calling debounce
again for each iteration (constructing its lexically scoped out
channel again each time). Also, did you want the first value to be debounced?(def cin (a/chan 1))
(def cin-d (debounce cin 2000))
(a/go-loop []
(println "Read" (a/<! cin-d))
(recur))
(a/put! cin 5)
^ this is how I would expect to use it, just call debounce
on your input channel once, and keep a reference to the resulting channel
How to find in spec
which specs make an issue with Couldn't satisfy such-that predicate after 100 tries.
?
How to see for each spec how many tries was make during generate?
I have complex data structure and I really don’t want to guess this manually 🙂
Does it mean there is no way to > How to find in spec which specs make an issue with Couldn’t satisfy such-that predicate after 100 tries.? > How to see for each spec how many tries was make during generate? ?
I don't believe so, once generation is happening, things are actually pretty opaque to spec, it is in the hands of test.check
Is it official recommendation from spec authors?
it is reality, using s/and makes the couldn't satisfy error very likely, unless you use a custom generator
I mean exactly what you wrote any spec with s/and
the way generation works for s/and specs is it generates data with the first spec, then filters it through the predicates of the rest of the specs
without this… this is really dark side of spec heh. Even my own generators can be not optimised and there is no good way to test it.
ime it's almost always something with s/and
so I'll echo the advice to start there. struggled with this a bunch and the best I came up with is to use a binary search approach - e.g., for the case you are looking at, eliminate half at a time
also get in the habit of testing generation whenever you update your specs. it's a pain if you go and change a bunch of specs and then have to go through each
☝️:skin-tone-2: Definitely this.
I have a situation where there was no spec before and I wrote spec for data just now.
I tend to have an RCF with s/exercise
calls in while I'm developing new specs and I try to make sure every spec generates as I'm writing them.
fib :: [Integer]
fib = 0 : 1 : zipWith (+) fib (tail fib)
Saw this in another chat medium. It’s a haskell sample to create a Fibonacci sequence. Is there a slick equivalent like that for Clojure or is https://blog.klipse.tech/clojurescript/2016/04/19/fibonacci.html the best out there?except that the list and the tail are flipped in order (doesn't matter for correctness since + doesn't care)
I saw the iterate example but it used an anonymous function, which wasn’t bad but was curious if a cleaner version existed.
the mathematical definition (and the haskell example) starts with 0,1
it also might be kinda both. depending on the branch of mathematics, the natural numbers begin with 0 or 1, depending on what kind of edge cases you are more annoyed by
"In some older books, the value {\displaystyle F_{0}=0} is omitted"
https://clojuredocs.org/clojure.core/lazy-cat Btw what does that mean in the warning about it retaining the head? Does that mean it’s storing every value in memory?
> ;; N.B. this example holds onto the head of a lazy seq which should generally be avoided
I know this doesn’t exactly amount to return value for your help on this but hopefully getting someone excited about something in Clojure is worth something to you.
More efficient fn to create a fibonacci seq
(def m-fib
(memoize (fn [n]
(condp = n
0 1
1 1
(+ (m-fib (dec n)) (m-fib (- n 2)))))))
the lazy version is already memoized (and the memoization has the same memory usage problems that holding onto the head does in terms of heap usage for larger values)
I guess it is true that the memoized version doesn't need to walk the spine of a lazy seq to get the pre-computed answer though
@U012H246NCE Nice! I shared that in the chat and someone had a question I don’t know how to answer: > Why use (- n 2) when you can do (nth (iterate dec 5) 2)?
I'm not sure if (iterate dec 5) 2)
is a valid construction. This construction he suggested out of its context gets hard to see what he really meant. But (- n 2)
makes sense a lot for me
After more discussion it was meant to be a joke that I didn’t pick up on. Sorry about that! 😳
Whoa! The first fib impl shared here is not accurate across all uh dialects?
clojure
(def fib (lazy-cat [0 1] (map + (rest fib) fib)))
In JVM Clojure:
clojure
user=> (time (nth fib 82))
"Elapsed time: 0.052346 msecs"
61305790721611591
In ClojureScript (via shadow-cljs):
clojure
cljs.user=> (time (nth fib 82))
"Elapsed time: 0.055000 msecs"
61305790721611580
In Babashka Clojure:
clojure
user=> (time (nth fib 82))
"Elapsed time: 0.0377 msecs"
61305790721611591
Why is the cljs one off by 11?the wild thing is when you are sending ids as numbers in json from a backend to the fronted and it exceeds the max safe integer
JavaScript represents number as 64-bit IEEE floating point, which can represent integers in the range [-2^54, +2^54] exactly, but only some integers outside of that range.
Wow, I’m surprised Joker (which is purely an interpreter, no JIT or compilation at all, written in Go) is even this fast:
user=> (time (nth fib 82))
"Elapsed time: 0.293 msecs"
61305790721611591
Whoa! The first fib impl shared here is not accurate across all uh dialects?
clojure
(def fib (lazy-cat [0 1] (map + (rest fib) fib)))
In JVM Clojure:
clojure
user=> (time (nth fib 82))
"Elapsed time: 0.052346 msecs"
61305790721611591
In ClojureScript (via shadow-cljs):
clojure
cljs.user=> (time (nth fib 82))
"Elapsed time: 0.055000 msecs"
61305790721611580
In Babashka Clojure:
clojure
user=> (time (nth fib 82))
"Elapsed time: 0.0377 msecs"
61305790721611591
Why is the cljs one off by 11?