This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2016-12-21
Channels
- # beginners (201)
- # boot (125)
- # cider (3)
- # cljs-dev (21)
- # cljsrn (165)
- # clojars (8)
- # clojure (332)
- # clojure-belgium (1)
- # clojure-gamedev (8)
- # clojure-russia (75)
- # clojure-spec (25)
- # clojure-uk (96)
- # clojurebridge (2)
- # clojurescript (130)
- # code-reviews (16)
- # cursive (26)
- # datomic (20)
- # devops (6)
- # emacs (6)
- # hoplon (90)
- # jobs (9)
- # luminus (2)
- # off-topic (4)
- # om (65)
- # onyx (5)
- # pedestal (4)
- # protorepl (6)
- # re-frame (34)
- # reagent (12)
- # ring (4)
- # ring-swagger (7)
- # specter (2)
- # test-check (8)
- # untangled (2)
- # vim (1)
- # yada (6)
also hello I have seen you on stack overflow
what is the best library to display a directed graph where the nodes can have little + button for expanding children?
does "directed graph" mean tree? otherwise children can be shared, right?
yes sorry tree
nodes can be shared but maybe not now 😉
@gfredericks I think maybe a ring is a directed graph without shared children that is not a tree
(it's cyclic though, acyclic is often also mentioned in these contexts)
@richiardiandrea there's a funny little used not quite complete namespace in clojure that shows a GUI widget to examine data structures like that
(I'm trying to remember the name...)
clojure.inspector - that's the one https://clojure.github.io/clojure/clojure.inspector-api.html
I need to deploy it as interactive tool on a website so maybe D3, or some mind map format
aha! totally different
lol yeah
@noisesmith yeah I inferred acyclic, probably from the word "children"
aha, I need to work on my inference engine
Funnily the word children seems most appropriate for a tree, even though the biological analog is not
lol you guys are funny AND clever 😄
phd thesis: incest taboo and it's usefulness in clarifying data relations
Are there any libraries out there containing additional implementations of core.async channels, i.e. implementing the protocols used by ManyToManyChannel like MMC, ReadPort, WritePort? I'm looking for some implementations using alternative backing data structures and I'd rather not have to write any of these myself if possible.
Thinking about it for a second, I guess the closest I know of would be some of the things in Pulsar/Quasar
I think manifold might have a few handy things too
Thanks, I'll try to dig through manifold. I already use it in a couple of projects, but as it relates to core.async, I've only seen stuff bridging between other abstractions and core.async.
hmm, that might be all you find
@hugesandwich: what sort of backing?
The buffering tech has its own protocol. But be very wary of anything working agains ReadPort and WritePort the semantics are super tricky
In short don't touch those instead use channels to implement different buffering starategies
Why does this return nil
instead of "x"
?
(with-redefs [get (constantly "x")]
(get {:a "a"} "a"))
=> nil
What version of clojure are you using?
Consider not using with-redefs
there's almost always a better way
It seems like the only way in this case. 😞 Every time an object is accessed, I need to know about it. And it has to work with the default data structures.
if you (alter-meta! #'get dissoc :inline :inline-arities)
before that, it should work (assuming you also have direct linking turned off), but it's not something I would recommend
Alternatively, why is it a hard requirement to make it work with regular out-of-the-box get
?
well, you can access data structures through way more paths than via clojure.core/get
so even with-redef
fing that wouldn't work
If you could relax one or the other of those requirements, sounds like it would lead to a cleaner solution.
If someone wrote code like this:
(let [thingy {:a "a" :b "b"}
a (:a "a")]
)
I need to know that :a
was access on thingy
and I need to register it in my app.To rephrase, even if what you wanted were possible, it seems like it would be introducing some very unexpected/surprising behavior.
And in order to know what component to update, I need to know what that component accessed
It might not be but it was the first thing that came to my head so I thought I'd give it a shot 🙂
So you're doing data dependency tracing.
If you want to do that, I'd recommend a cleaner, but yet more verbose solution: Write wrappers for PersistentVector, and PersistentHashMap
some access patterns like (:foo the-map)
don't use vars (hence there's nothing you can redef, even ignoring that it won't work when combined with inlining/direct linking)
When you do a get from one of those don't return the data, return your wrapper, and do your tracking in the wrapper.
In short, it's the decorator pattern from OOP...
in cljs what @tbaldridge suggests shouldn't even be too painful to write, using specify!
it's like reify, but works on concrete instances rather than types, so you can redefine e.g. lookup for just some instances of maps rather than for all of PersistentHashMap/PersistentArrayMap
or having to write a wrapper type that implements all the protocols and delegates to the wrapped object
Sounds perfect! I actually asked that question in #clojurescript but no one has replied yet 😛
it's apparently specify
, not specify!
tho, sorryspecify!
is the mutable version, while specify
clones the object
@bronsa Any idea if this was what was actually implemented? http://dev.clojure.org/display/design/specify+i.e.+reify+for+instances I'm looking for example usages 🙂
I think the syntax is the same as reify except it takes the instance rather than the type as first argument, but I've never actually used it
(let [x {:a "a"}
_ (specify! x
ILookup
(-lookup
([o k] "x")
([o k not-found] "y")))]
(:a x "a"))
=> "y"
but this
(let [x {:a "a"}
_ (specify! x
ILookup
(-lookup
([o k] (-lookup o k))
([o k not-found] (-lookup o k not-found))))]
(:a x "a"))
throws a maximum call stack size exceeded.yeah I would expect that. I think you need to grab the original impl via e.g. (.-lookup x)
or something, but not 100% sure you can do that or what the best way would be. You'll probably need to ask somebody in #clojurescript for this
I can imagine the munging cljs does when compiling method names could actually make this not trivial
@kenny I think if you use specify
rather than specify!
you could then do something like
(let [x {:a "a"}
x (specify x
ILookup
(-lookup
([o k] (-lookup x k))
([o k not-found] (-lookup x k not-found))))]
(:a x "a"))
note the -lookup
impl is invoking -lookup
on x
rather than o
(so not on this
, breaking the cycle)
Wonder what the performance implications of that will be. It may be worth code duplication if it is significant
@bronsa @tbaldridge Thanks for your help 🙂
how to get java class function's console out put when working in clojure?My java class has System.out.println
but I have not seen them in clojure repl.what happened?
I am using the clojure.java.jdbc library to write a date into a postgresql database "date" field. It does work, basically, but, on loading the written data it creates an "inst" type which automatically applies an offset. So I use clj-time to create a date with (today), write it into the database, load the data and instead of today I get a timezone adapted date which is yesterday. This is the code with the output: http://pastebin.com/ZrezguSt Any idea what the correct way is to do what I want?
@sveri: Check the timezone your JVM is using. It has to match the timezone expected by your database. My advice is to run everything in UTC. :jvm-opts ["-Duser.timezone=UTC"]
is likely what you want.
@the-kenny That works, at least for the tests 🙂 I guess when running an uberjar I have to add the option to the java call
@the-kenny I have not found it in the generated uberjars Manifest
I've got a question for whomever is using timbre for logging: how in the world do I configure my logging levels per namespace? can I even do that? The README.md on github tells me that I can configure the log level and the namespace filter white/blacklist in 3 different ways; But with logback I could do this:
<logger name "my.awesome.namespace" level="TRACE" />
<root level="ERROR">
<appender-ref="FILE" />
...
</root>
which would mean that I can actually log up to the TRACE
level from my.awesome.namespace
, and up to ERROR
from other places. How do I do this in timbre?@thheller: I have a few pending tickets that should make this a little easier. And I've been tinkering with some things.
I know there was some talk about the ::blah/foo
syntax, google isn't turning it up though. Did it go anywhere in the end?
That's been part of Clojure since the beginning
They are autoresolved keywords if that helps searching
@alexmiller java.lang.RuntimeException: Invalid token: ::db/uri
I think the part that doesn't work is the blah/
prefix
The namespace has to be a valid alias in your current namespace
That's what the "resolve" part refers to
If you literally want db, just use :db/uri
Oh, I've misunderstood the purpose of the auto-resolved keywords, I thought they expanded to :my.ns.blah/foo
@alexmiller is there an official way to determine if something is a spec thingy? other than (or (s/spec? x) (qualified-keyword? x) (regex? x))
Is there something like clojure.core.walk that has a context? e..g I want to walk down a tree and replace values (I’m redacting a deeply-nested data structure), but there is some state I need to keep track of as I walk down the tree (e.g. a key gets redacted, but it’s important that repeat keys point to the same redacted value, so I need to keep track of previously-redacted keys)
if you aren't aiming for purity then a memoized function might be easy
I expect the algorithm you're describing exists somewhere but I don't know where
@lvh i know tellman has a walk in ridley (i think) that maintains state so you can use gensyms across different scopes
@lvh the redacted value needs to be nondeterministic?
@gfredericks I guess it can be deterministic; not sure where you’re going with that
i don't think its directly applicable but its an example of walking and keeping state
@lvh e.g., just based on what you said it's not obvious why putting "*" everywhere doesn't suffice
gfredericks: “secret-1” and “secret-2” both need to be redacted but they need to be reacted to consistent values
ah ha
okay so hash it with a big salt
I assumed the salt wouldn't be exposed; maybe salt is the wrong word for that
yeah; salts are not generally considered secret, and plenty of algorithms explicity expose it or an equivalent
(”key” does the right thing though; and most keyed hashes are PRFs or MACs — the problem is that people think “prefix-SHA-256” counts, and it is not a MAC and certainly not a PRF)
@gfredericks So now I need all sorts of objects (e.g. dates), generated from a deterministic random seed… Sound familiar? Is there a way to tell test.check to generate 1 from a particular seed? (I’m sure there is, because otherwise shrinking could never work, but it doesn’t seem very exposed.)
No it's not very exposed, because doing it by hand circumvents the normal system
But if you're not running tests, just generating, then:
(rose/root (gen/call-gen g (random/make-random seed) size))
I had a good time writing it
Any long
Maybe there are uniform random requirements, you can check the SplittableRandom docs
test.check uses current-time-millis, so let me know if uniformity is important
Has anyone here used https://jitpack.io/
@rickmoynihan yes I have, and I ❤️ it!
pmonks: do you use it with leiningen?
pmonks: and does it run tests before deploying the build? Or does it skip tests? Just wondering if we adopted it what it would mean for our CI processes?
Not sure if it runs tests, sorry.
I’m assuming it doesn't
how long do you typically need to wait for the builds to be deployed? It says upto 15 minutes - and 15 minutes seems like quite a long time
Yeah first time it takes a few minutes (and the local build fails in the meantime with a timeout).
But after that the built artifact is cached by jitpack, and so nice & fast.
sure - but what about changes… i.e. if I push a commit to fix an issue a colleague has - will she have to wait upto 15 minutes to get the update on jitpack?
Yep - that would be a new version (jitpack versions are commit ids)
But once built, anyone else who's also using that version will get the cached one, quickly.
To be clear, I haven't used it in a team setting - I've mostly used it for other people's libraries that haven't deployed anything to Maven central / Clojars. And in that case the versions typically don't change very fast.
ok - yes I understand the version/commit thing… I was referring more to the branch-SNAPSHOT
style
Ah I hadn't seen that before - it might be new.
will need to think about the workflow a little - as I expect it’ll have to skip tests (it’s not a CI server after all) - and in complex builds where you have dependent builds in a chain waiting potentially 15 minutes for each change to propagate will be a problem
also it being async to the deploy
step will probably lead to co-ordination/build failures
still - I really like the idea
Hi, hoping someone can help me out. I'm using the defun
macro to define a function with pattern matching. As you can see the function accepts an options map:
(defun foo
([{:a a :b b}]
(str a b))
([{:a a}]
a))
(foo {:a "foo" :b "bar"}) ;; => "foobar"
Is it possible to use destructuring to bind the whole options map to some-symbol
within the parameters definition?you can
@djjolicoeur let me try again 🙂
may have jumped the gun, you can when destructing args or in a let and what not
a pedantic point - destructuring is not pattern matching and your multiple arities can only dispatch by argument count, not by destructured contents
@mf so your example is flawed because two "arities" are really the same arity with different contents - you need actual pattern matching with that, and defn doesn't offer that
@noisesmith I'm using defun
where is defun defined?
I misread, sorry
@djjolicoeur :as
doesn't seem to work
@mf what library defines defun?
OK - so those binding vectors are not clojure destructures, they are whatever it is defun defines
for what it is worth, this is what core.match has to say about :as https://github.com/clojure/core.match/wiki/Overview#as-patterns
I guess it uses () for that? weird
@noisesmith yup using the parentheses worked:
(defun foo
([({:a _ :b _} :as options)]
"foobar")
([({:a _} :as options)]
"foo"))
(foo {:a "foo"}) ;;=> "foo"
(foo {:a "foo" :b "bar"}) ;;=> "foobar"
@noisesmith thanks for your help
^ needless to say options
is bound as you would expect (although my contrived example not accessing options
)
very cool, glad it worked
----------------
my workflow in clojure is, I think, needlessly complex, but I can't think of how I can stop duplicating work:
not necessarily in order:
* create a schema in Postgres
* write SQL bindings my backend can call (using YeSQL
). Every subset of data I want requires it's own SQL.
* tie those YeSQL
functions to a service (protocol + extension) to be used by Component
* tie those services to endpoints in Compojure
* on the frontend, write glue to the api endpoints. Make sure you did auth right!
* and massage the incoming/outgoing data for how the frontend/backend expects it
* finally, shove the massaged data into a re-frame/db
* UI components need to understand how to interpret data from the re-frame/db
, and how to dispatch
according to the appropriate data shape as well
* oh, I need to change something? make sure you don't over look one of those steps!
* oh, I need to add something? spend a bunch of time on all those steps!
The Ideal Situation, or so I think, looks something like this:
* data is data, so define the shape of it once. Or never (IE dynamic, like datomic/datascript's EAVT model?)
* and use it as data from wherever I am - backend, endpoints, frontend, db, etc. (instead of a treating data like some set of specific cases whose implementation details "should" be the same, but end up varying, and becoming brittle)
* everything is sensibly, i dunno, generated?, such as an API that makes sense as far as GET
ing, and POST
ing, and paths are nouns, etc., with sensible, albeit customizable, auth stuff built in
It seems unecessary that a human should need to do this book keeping by hand, ...
Is there a better workflow, or tool, or philosophy, or something to return my sanity?
@josh.freckleton I started working and using for some time: https://github.com/sveri/closp (still using that) and https://github.com/sveri/closp-crud (not using currently). Both tackle most of the problems. Closp is a web framework providing everything I need out of the box (component, auth, some standard web ui, ...) similar to luminus and Closp-crud is a crud generator for korma, selmer, routes and the create sql scripts I need. I might rewrite it in some time to use clojure.java.jdbc instead, but I liked the workflow. One might extend that to use re-frame UIs instead of selmer. It served me pretty well, especially closp, as I try a lot of different stuff and helps not having to redo all the basic stuff again and again.
Can I ask a stupid n00b question? I have a vector of vectors, and I want to run a transform fn on certain indexes of the vectors. So that 1 -> “Yes”, 2 -> No. Can I map an fn onto only certain indeces?
xsyn (mapv (fn [transform item] (if transform (f item) item)) (cycle [true false]) coll)
is one approach to that
xsyn since vectors are immutable, you need to generate a new vector, so the questions becomes how to best generate the new vector
oh, I think I misread the question
I know that reads poorly, I get what you’re saying. I’m just trying to get it on multiple keys
@sveri I'm checking it out now, seems interesting, thanks... In the experience of clojurians, is my problem generally addressed with frameworks? Because frameworks seem in disrepute, and is the only alternative just doing it all by hand like I listed?
@josh.freckleton I call it framework, although it is not in the classical sense. It is just a leiningen template that you can alter and adapt to your needs afterwards. There is no lockin, everything can be replaced, updated, whatsoever.
@noisesmith thank you anyway 🙂
You could even adapt the template to your needs (which is what I did years ago with the luminus template)
xsyn
(mapv (fn [e] (reduce (fn [v i] (update v i f)) e [0 4 7])) coll)
so for each item in the vector, it updates indexes 0,4,7 with f
but! there's a library for this kind of stuff, one I don't use yet but keep meaning to check out
@josh.freckleton have you evaluated om.next? maybe it could help reducing complexity?
@noisesmith specter ?
that is the one! I forgot the name and was just looking it up
@ag has om.next reduced complexity for you?
I was struggling with the path traversal, and decided to come down a layer of abstraction
@sveri thanks, ya it looks useful, and creating a "pseudo framework", or opinionated list of libs and best practices has kind of been my approach too, but, it seems like it should be possible to offload most of this work/bookkeeping... at least in my dreams 🙂 Like, it really seems to me like you could have an entire app complete simply fall out of, say, 100 lines of a clojure map describing the shape of some data
josh.freckleton the design principle that seems to prevent that so far is that we don't go in for implicit behaviors
@ag I evaluated om
vs re-frame
about 6 months ago, when I first got serious with clojure, and went the re-frame
route. is om.next
pretty good? My impression was that it hasn't really hit it's stride yet.
convention over configuration implies (neccessitates?) methods and behaviors that are never explicit in your actual code
which is something most clojurists are wary of
@noisesmith your point sounds interesting, could you clarify?
@noisesmith @josh.freckleton I just want to make sure that closp / closp-crud is not a convention over configuration framework, in case it sounded like this.
@josh.freckleton I think it derives from simple vs. easy - convention over configuration is easy but not simple, the implications of the conventions leads to complex behaviors that are never present in the code itself
@noisesmith I think what I mean about my search for what you call "implicit behaviors" is that once a problem is really nailed down, you want to stop needing to think about it anymore, and it becomes implicit. For ex: clojure maps, or garbage collection. I don't have to think about their implementation details at all.
and i think my web app problem is (close to) sufficiently "nailed down"
@sveri cool - I think it's possible to have a lot of good defaults without going the way of hidden complexity and spooky action at a distance, but I think people's experience with this taken too far (eg. in rails with many plugins turned on) scared them into the clojure "everything explicit" approach
just speculation
@josh.freckleton we use both re-frame and om. The first project I worked on was done in re-frame. Then later we decided to try out om.next and we really liked it.
@josh.freckleton yeah - if you understand the domain well enough and really have a solid abstraction that can work very well. I think where people get burned is by combining multiple such setups that have unexpected interactions, or using combinations of features that the original devs never expected, where suddenly you go from "it just works" to "it's just broken" with no solid basis to know what was going on in either case
but I was more trying to provide a rationale / community worldview that leads to avoiding magic
kind of say "this is where clojure is coming from, as a community"
I'm all for solid, well thought out abstractions that reduce the amount of work we have to do, but getting it nailed down is often trickier than we think
@noisesmith To me, my problem feels like this. I have a data shaped like {:user {:name ... :email ...}}
, and at every single waypoint, I need to define separate getters, setters, updaters, etc.
Which is crazy, if you just think about updating a map, when you have useful primitives such as assoc
, and update
. But those primitives don't exist at each way point, so I have to implement them each by hand, which is a brittle approach.
I'm not arguing against your idea of explicit > implicit, because in general I think you're right. But I think that point runs a little orthogonally to the problem I'm trying to solve. IE there could be an explicit way of solving my problem too, I just don't know what
Thats why I went with the "generate all the code" approach, so I am free to change everything at any time.
@ag I'll check out om.next
again, thanks for the recommendation!
(to clarify my "primitives at the waypoints" idea, it's like I can assoc
to any map
, but I need to PUT
to an endpoint, and SELECT
from a db, and subscribe
to a reagent/atom
, and all of these implementation details need to exist for each plethora of use cases)
Btw. if you use .cljc you can define the shape of your data and take it all the way through from backend to frontend. Also, thats why I switched to java.jdbc lately, because it works with the maps that I use anywhere else.
@josh.freckleton go straight for Tony Kay’s Untangled tutorials.
spec and even plumatic/schema are great here too (both work in cljc)
or I think spec works in cljc...
@ag, awesome, checking em out now 🙂
@xsyn do you need to apply the transform-fn to the value or just replace it with a static value?
@jr applying a transform-fn worked nicely, because I actually want to transform it into a dataframe (spreadsheet) and if I do a static replace, I lose my headers. So by applying a transform-fn I get to do some checking on that too
@noisesmith’s one-liner worked beautifully
@sveri cljc
is a good idea, is there a way of handling compojure providing endpoints, and the frontend consuming them with cljc
(this is a big clumsy step in my workflow)
I would think not really...
@josh.freckleton if you use something like bidi or polaris that supports data structures defining routes, the same data structure could be used in the front end to generate requests
iirc compojure doesn't make this straightforward though
but it's easy to swap out the router and still use the other ring/compojure features (eg. middlewares)
or you could use the kind of model om.next leads you toward (as I understand it...) where instead of hitting a bunch of endpoints for your data, you describe the graph of data you need and that gets filled in as needed in a front end cache
you are violating abstraction by exposing the schema of your data directly to the frontend, but it can also simplify things quite a bit
> describe the graph of data you need and that gets filled in as needed in a front end cache oooo, that sounds like exactly a piece of my puzzle I was looking for!
@josh.freckleton using datascript with om https://github.com/omcljs/om/wiki/DataScript-Integration-Tutorial
@noisesmith so, I'll look into this further, but real quick: does this mean that you don't really build REST endpoints, but, just like one endpoint and it deals with any shape of data you ask for, and any CRUD?
I'm not 100% certain - I haven't had a chance to build an app this way (currently working on one app for a long time now...) but my recollection is that you would build a query endpoint with GET to retrieve the graph of data and POST to submit alterations?
@josh.freckleton have you looked at https://juxt.pro/yada/manual/index.html#introduction or http://clojure-liberator.github.io/liberator/?
those won’t solve your problem entirely, but you should be able to define your resources as data in cljc
@josh.freckleton regarding the general idea / design you could look at graphql which is a mainstream js way of doing this same pattern
@noisesmith that sounds cool. @tankthinks a while ago I looked at them, but never used em. I'll revisit em as I'm solving this!
I’d like to conditionally enable fixtures on a per-test basis with deftest
. I looked at using metadata on a the test definition but it doesn’t look like this would work. Any way to achieve this?
what is the best way to transform a vector into arguments?
I have a vector of strings that I want to use as arguments to a format function (format "%s \n %s, %s" ["a" "b" "c"])
like this but I need to remove the vector
so: (format "%s \n %s, %s" "a" "b" “c”)
josh_tackett (apply format s v)
where v is your vector
@noisesmith Thank you!
this works for other, non-format functions as well
I believe at one point before I found an earlier JVM based langauge Rich Hickey worked on.
@noisesmith Yes I remember using it for this: (apply str ["a" "b" “c”])
just didn’t think to use it here
I recall Rich talking about his previous projects in the Clojure for Lisp Programmers talk. They sounded more like a glue between Common Lisp and Java, rather than a full-up language.
it might have been something with clr?
I think https://news.ycombinator.com/item?id=9248544 was what I was goign for
@noisesmith I think the clr was involved somewhere in here
well, it says .Net so yeah
and he used to do Clojure on both JVM and CLR earlier on (I believe, not sure how long that went on)
clojure-clr still works!
(like with new clojure releases even)
@mikerod https://github.com/clojure/clojure-clr/releases/tag/clojure-1.9.0-alpha13
it just doesn't have a leinclr or bootclr or whatever I don't think
@mikerod - fun fact, clojure-clr is how I found out how slow nrepl and lein are - when I first tried it I was all like "wow, clojure-clr has great startup time!" until I learned that the startup time I had been experiencing all came from the tooling I was using
It's great to see CLR getting attention
I would like to get a support native implementation of clojure too
If one linked to openjdk or used JNR, you can have a java jar link to native code and a native binary link to java jars
@johnnyillinois - pixie isn't a clojure but it is very much inspired by clojure and its interop is with native code https://github.com/pixie-lang/pixie
So I should fork and just make it a clojure compatible? I like it
I bet an emacs plugin could convert valid clojure into valid pixie and visa versa with 99% accuracy
I'll to look at the licenses, it isn't eclipse or MIT
it's LGPL
yeah, should be good to go
oh cool looks like tbaldridge
is a maintainer
he's the primary author
There are like 4 different half finished native clojure implementation repos on github
Not like that is bad thing
haha, I would be surprised if any of them are more than 5% done
the problem with native is you go from one of the best vms available (jvm) to one of the worst (the one you just started writing)
pixie gets around that by using a vm generator
I was thinking about that
I was hoping to bootstrap it with LLVM
llvm is a toolkit for making a vm though, you still need to write your vm (though llvm makes this much easier...)
Hehe! Totally!
I'm planning to write a chatroom with core.async and websockets... any recommendations for a framework/library?
@bfast sente seems like a good start: https://github.com/ptaoussanis/sente
@bfast: Not sure if this helps, but might be a useful reference for some ideas - https://github.com/tonsky/datascript-chat