This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2018-05-16
Channels
- # architecture (12)
- # aws (8)
- # bangalore-clj (1)
- # beginners (172)
- # boot (25)
- # chestnut (3)
- # cider (15)
- # cljsrn (5)
- # clojure (170)
- # clojure-india (1)
- # clojure-italy (21)
- # clojure-nl (87)
- # clojure-romania (3)
- # clojure-sg (1)
- # clojure-spec (1)
- # clojure-uk (79)
- # clojurescript (79)
- # cursive (2)
- # datomic (29)
- # dirac (26)
- # emacs (7)
- # fulcro (13)
- # jobs (4)
- # juxt (22)
- # lein-figwheel (1)
- # leiningen (2)
- # lumo (39)
- # nrepl (1)
- # off-topic (54)
- # onyx (124)
- # pedestal (1)
- # planck (4)
- # portkey (1)
- # re-frame (36)
- # reagent (2)
- # ring-swagger (8)
- # shadow-cljs (107)
- # spacemacs (1)
- # specter (25)
- # sql (7)
- # tools-deps (5)
- # vim (10)
- # yada (25)
Hmm, I have to try this with that commit? Let me take a try again
@stardiviner The SHA is in that article...
...I think this will become quite a common way to publish little utilities. The Cognitect test-runner
works like that, as do depstar
and juxt.pack
I think? Also the clj-new
utility I published.
Hmm, still same error with:
clj -Sdeps "{:deps {org.clojure/tools.deps.alpha {:git/url \"" :sha \"d0508cfacfbb1285ac4c3706688176baceb3f83b\"}}}"
tools.deps.alpha.repl
namespace still not available, neither add-lib
.
@seancorfield That's great!! Clojure will be easier to dynamically load lib will be soon.
BTW, why use tools.deps.alpha
instead of tools.deps
, because it's in Alpha development status?
Correct.
@stardiviner Where did you get that SHA from? The article says d492e97259c013ba401c5238842cd3445839d020
Yes, that article.
I found there is a branch called "add-lib" in https://github.com/clojure/tools.deps.alpha/branches
Should I use this instead?
The correct SHA is in the article.
Per the article
(! 944)-> clj -Sdeps "{:deps {org.clojure/tools.deps.alpha {:git/url \"" :sha \"d492e97259c013ba401c5238842cd3445839d020\"}}}"
Checking out: at d492e97259c013ba401c5238842cd3445839d020
Clojure 1.9.0
user=> (use 'clojure.tools.deps.alpha.repl)
nil
user=> (add-lib 'org.clojure/core.memoize {:mvn/version "0.7.1"})
true
user=>
As Alex said, the exact command-line to use is in that article 🙂
Ahu, that's weird, where did I got this commit SHA? I must be copied from somewhere into my Org
The SHA you used looks like the most recent commit on the master branch.
@alexmiller One problem with that article as it stands is the formatting of the code means you can't just copy'n'paste it into a terminal... you seem to get spurious characters:
(! 943)-> clj -Sdeps "{:deps \
> {org.clojure/tools.deps.alpha \
> {:git/url \"" \
> :sha \"d492e97259c013ba401c5238842cd3445839d020\"}}}"
Error while parsing option "--config-data {:deps {org.clojure/tools.deps.alpha \\ \n {:git/url \"" :sha \"d492e97259c013ba401c5238842cd3445839d020\"}}}": java.lang.RuntimeException: Map literal must contain an even number of forms
Yeah, I got this problem before, after tried some times, Then I remove "`\`", turn this command into one-line.
What If I want to specify a branch, instead of :sha
what keyword should I use? I tried :branch "add-lib"
seems does not work.
I think those \
aren't necessary -- contrast with https://github.com/seancorfield/clj-new/blob/master/README.md which only has \
outside the quotes (and does copy'n'paste properly).
You can only use :sha
. But you can always find the latest SHA in any given branch by looking on GitHub.
right, use '...'
can avoid those \
For example https://github.com/clojure/tools.deps.alpha/commits/add-lib then click on that commit to get https://github.com/clojure/tools.deps.alpha/commit/d492e97259c013ba401c5238842cd3445839d020
@stardiviner The nice thing is that you can also write multi-file gists on GitHub and pull code from those in via clj -Sdeps
, for example https://gist.github.com/seancorfield/6e8dd10799e9cc7527da5510c739e52f
Also @stardiviner if it helps https://github.com/seancorfield/dot-clojure/blob/master/deps.edn (I may have shared that before?).
Yes, you remind me that, I did remind that you shared me many useful links. At that moment, I can't understand some of them. Now I can see more. Thank you.
Aha, I found your shared this link, I recorded it into my Org.
That's my ~/.clojure/deps.edn
file full of useful aliases for clj
Cool!
I should probably annotate that file with examples of using the aliases and links to the original repos...
That's better.
@seancorfield Do you use CIDER?
No, I use Atom and ProtoREPL.
I used to use Emacs and CIDER for years, but switched about 18 months ago (I think).
No other means, I just want to inject tools.deps.alpha dependency into CIDER jack-in.
So I asked you by the way.
Looks like CIDER only supports Maven coordinates.
Yes, I take a peek in this option source code, and other used places of functions, only support Maven version numbers. I will go to propose an feature request on CIDER.
(I added a README https://github.com/seancorfield/dot-clojure 🙂 )
Awesome!
After checked out clj-new, It's an smart utility. 🙂
After I do (add-lib 'incanter/incanter-core {:mvn/version "1.9.2"})
I try to require incanter with (require 'incanter.core)
but got error FileNotFoundException Could not locate incanter/core__init.class or incanter/core.clj on classpath. clojure.lang.RT.load (RT.java:463)
. I also tried (require 'incanter/incanter.core)
, (require 'incanter-core/incanter.core)
. Also tried google "add-lib incanter", no useful results. Can someone explain the principle behind this? In an example, use (add-lib 'org.clojure/core.memoize {:mvn/version "0.7.1"})
and (require 'clojure.core.memoize)
is fine. what's the difference?
I also tried (require 'incanter.incanter.core)
, not work too.
what repl are you in?
I start REPL with: clj -Sdeps '{:deps {org.clojure/tools.deps.alpha {:git/url \"https://github.com/clojure/tools.deps.alpha.git\" :sha \"d492e97259c013ba401c5238842cd3445839d020\"} org.clojure/tools.nrepl {:mvn/version \"0.2.13\"} refactor-nrepl {:mvn/version \"2.4.0-SNAPSHOT\"} cider/cider-nrepl {:mvn/version \"0.18.0-SNAPSHOT\"}}}' -e '(require (quote cider-nrepl.main)) (cider-nrepl.main/init [\"cider.nrepl/cider-middleware\"]) (use 'clojure.tools.deps.alpha.repl)'
I have had issues trying to use the add-lib stuff over an nrepl connection
It works from a plain console REPL:
(! 970)-> clj -Sdeps "{:deps {org.clojure/tools.deps.alpha {:git/url \"" :sha \"d492e97259c013ba401c5238842cd3445839d020\"}}}"
Clojure 1.9.0
user=> (use 'clojure.tools.deps.alpha.repl)
nil
user=> (add-lib 'incanter/incanter-core {:mvn/version "1.9.2"})
true
user=> (use 'incanter.core)
nil
user=>
add-lib works by finding the highest DynamicClassLoader and injecting the urls there but it seemed like I was seeing different URLClassLoaders each time when over nrepl
Hmm, I see. @alexmiller I know you're the maintainer of tools.deps.alpha, do you think it is fixable?
don’t know. I think CIDER already has something to do this?
https://github.com/clojure-emacs/clj-refactor.el/wiki/cljr-add-project-dependency
@alexmiller I'm curious, looking at things like clj
and test-runner
and transcriptor
-- and how I've seen Cognitect folks show off code during talks, I get the impression that minimal tooling is favored over "heavy" tooling?
Do any of the Cognitect folks use CIDER? Or do most of them stick to inf-clojure
or whatever it's called?
@alexmiller Yes, clj-refactor can hotload dependency, but cljr does not work if without project.
I sometimes launch CIDER REPL without project for Emacs Org-mode ob-clojure for simple literate programming support.
I personally use Cursive with an nrepl in context of Leiningen or Maven projects pretty often. I also use Emacs with CIDER and nrepl. And I use clj on the command line pretty frequently.
I've been playing with unravel/unrepl and really like that simplicity -- I can start up an app on QA (or even production - shhh!) with a Socket REPL, tunnel to the server from my laptop, then run unravel against that and preload compliment.core for completion and then I have a pretty nice user experience.
interesting, I will take a play of unravel/unrepl.
(caveat: compliment support is somewhat experimental at the moment with unravel I think!)
That sounds super nice. I like the idea of a little sugar around the repl to load files and maybe some jump to definition. But I don't use much of the features
Has anyone used Clojure spec with functions that involve database or some external service? I don't know if it can be used only for pure functions (functions that don't to IO) and would like to do something like fuzzing the function. I don't if it's right to use Clojure spec for this.
@xtreak29 Could you elaborate?
Specs are, essentially, static -- non-parameterized -- so I'm not sure what you're asking about?
In the clojure spec guide there was a section where generative testing was done with random number function (https://clojure.org/guides/spec#_testing). I was wondering if the same can be done with an external service like fuzzing. i.e. Running the function with generated parameters.
There is a section on external services too : https://clojure.org/guides/spec#_combining_code_check_code_and_code_instrument_code
Well... yes... I mean, you can write any predicates you want, including ones that depend on external services... I wouldn't recommend it, tho'... doing generative testing against that is... fraught.
Note that the section you're referring to explicitly shows how to stub the external service so you don't actually call it.
"And then we want to test the behavior of run-query while stubbing out invoke-service with instrument so that the remote service is not invoked:"
"The first call here instruments and stubs invoke-service. The second and third calls demonstrate that calls to invoke-service now return generated results (rather than hitting a service)."
So... don't call external services in a spec...
I'm new to Specter and trying to figure out how to express finding all of the numbers in deeply nested data, except for those that are nested within maps (at any depth) containing a particular value.
Finding all the numbers is totally easy, (traverse (walker number?) data)
, it's the filtering out part that I'm struggling with.
hi i am editing someone elses project
and they are using environ
(https://github.com/weavejester/environ)
but it isn't in project.clj
as dependency
it's just called in ns like environ.core :refer env
and it works?!
how is this possible?
Most likely there’s a dependency that’s pulling it in. Try looking through the output from lein deps :tree
wow implicit dependency first time to come face to face with this thank you very much
Is there a way to refer to a map key within a map. Something like this:
(def map1 {:aaaa 1
:bbbb 2
:c (* (:aaaa map1) (:bbbb map2))}
not within a single form, no
you'll need something other than a default clojure reader, or a preprocessor, in that case
There are some libs to do this
Crap, can’t remember what it’s called
This is a pretty good lib for my requirement but it's like using a whole lib for just one small action. Thought i'll find out from the clojure PROS before I go with this lib
ah, fern is what I was thinking of
I have a large set of data where the elements have the following form
{:from _ :to _ :value _}
For every :from
:to
pairing, there exists the opposite, so if there's
{:from "a" :to "b"}
there will also be
{:from "b" :to "a"}
somewhere in the collection.
The :value
s in such maps will not be duplicates.
I am trying to think of an elegant way to, for every point of data {:from :something}
, look up its pairing, which will contain the key {:to :something}
, and more specifically, get both of the values for those two pairings.
It is some kind of data join, but set/join
is either not the tool for this, or I'm using it wrong (likely).
perhaps something like:
(reduce (fn [values {:keys [to from value]}] (update values (set to from) conj value) {} your-data)
that will give you a map where the keys are sets of the to and from, and the values are vectors of the values
sounds like an adjacency list made of a map of node to set of connections with target and value could help
Direction is ultimately not important here, the result will be a set of maps of the form {#{from to} (+ amount1 amount2)}
, where from
and to
are from the pairing, and amount1
and amount2
are their two values.
oh well then in that case the reduce function could be (fn [values {:keys [to from value]}] (update values (set to from) (fnil + 0) value))
minor typo: (set [to from])
I'm trying it out, thanks so much for the feedback
I didn't consider using update
@noisesmith when say adjacency list, what would be the node
s?
I'm not very familiar with working with graphs but I would like to learn more, and I'm not clear on what the nodes would be
and the map you start with is an edge between them (with a direction)
once you have adjacency list format, there are some nice algorithms that all just work
(if you need to do graph stuff)
in eg. c you would just use a tree with pointers that might loop back, in a language that uses immutable data an adjacency list is much nicer
okay, very cool. I feel like I'd want to find some problems that require graphs to solve to learn more; seems fun and useful
@michael.gaare also, where you using fnil
as a shorthand for partial
in this, or does it actually do something different here?
I've never used fnil
before
@michael.gaare your solution works perfectly by the way 🙂, I'm just working on understanding it fully now
fnil lets you say what to substitute if you get nil. so here you're updating a map at a key that won't be found. so the plus function would bomb, but you say, in that case, use 0 and carry on with the operation (here adding 17)
Ah okay, so @michael.gaare’s solution ensures that if for any datum an opposite pair didn't exist, nothing would explode
@dpsutton that totally makes sense, thank you
so basically, fnil
gives a function default positional values
up to three values it appears. forgot about that. check (source fnil)
@montanonic
yes, up to three, just tested
hey clojurians,
I’m implementing my tcp server and I have one namespace which I called protocol
protocol namespace will be responsible for encoding/decoding the bytes I’ve received from clients.
(ns tcp-protocol.protocol
(:require [gloss.core :as gloss]
[ :as io]))
; frame format
(def frame-format (sorted-map :opcode :byte, :payload (gloss/repeated :ubyte :prefix :ubyte)))
(def frame (gloss/compile-frame frame-format))
(defn encode [opcode message]
(io/encode frame {:opcode opcode :payload (map identity message)}))
(defn decode [buffer]
(io/decode frame buffer))
I’m not 100% happy because my encode/decode is using one global or singleton
definition frame
and I don’t want the callers have to pass the frame everytime
how you guys would solve that ?(defn encode
([opcode message]
(io/encode frame {:opcode opcode :payload (map identity message)}))
([frame-format opcode message]
(io/encode frame-format {:opcode opcode :payload (map identity message)})))
with a better name for frame-format?can also make the 2-arity call the 3-arity with frame passed as an argument although it would be the same with one line less repeated
the problem is (([frame-format opcode message]) is almost dead code, no one will be using ( only on my tests )
or you could make a function that takes a frame format and returns the encoder/decoder using that. then you could create that in tests. there are lots of ways
another option is to have a regular function intended for others to call, and an implementation function - but that's effectively the same as the arity thing (some would consider one cleaner, some the other)
I'm a big fan of that one too. i'm ok with def-ing the one way to use something in reality
interesting ! yeah > or you could make a function that takes a frame format and returns the encoder/decoder using that. then you could create that in tests. there are lots of ways
@noisesmith ( sorry to bother you ) > another option is to have a regular function intended for others to call, and an implementation function didn’t get that
(defn foo*
[impl x]
...)
(defn foo
[x]
(foo* (make-impl) x))
so basically the same thing you would do with arities, mainly useful if you also have a use for arity dispatch
i recommend a book by @alexmiller called https://pragprog.com/book/shcloj3/programming-clojure-third-edition. Its got a good mix of java interop and real world practical things that I think other books don't emphasize enough
Clojure Applied and Joy of Clojure both go beyond basics in their own interesting ways
applied going into the little details of using it in production and non-obvious tricks, JoC going into some more theoretical and design level insights about the language
How do people feel about when to use reduce
over loop recur
? By making the accumulator for reduce
a vector you can hold onto multiple pieces of state just like loop
. Is there any semantic difference between the two at that point? Especially since you can short-circuit via reduced
?
oh, well, wait, duh, reduce handles the sequential navigation through a data structure for you, while loop/recur does not.
Always use reduce instead of loop if you consume the input in order. It can even return early with reduced
.
and yes, using a collection as an accumulator in order to track multiple values is normal
awesome, cool; glad to know what I'm doing is idiomatic
there are other more specialized functions which can be better than reduce as well, but that's more case by case specific
right, totally
see also transduce if you need speed and/or need pre-processing of the input like mapping or filtering or partitioning etc.
but that's likely outside the beginners topic