This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2019-11-21
Channels
- # aleph (2)
- # announcements (2)
- # babashka (10)
- # beginners (117)
- # calva (11)
- # cider (19)
- # clj-kondo (27)
- # cljs-dev (24)
- # cljsjs (1)
- # clojure (73)
- # clojure-europe (3)
- # clojure-italy (2)
- # clojure-nl (47)
- # clojure-spec (23)
- # clojure-uk (28)
- # clojurescript (71)
- # cursive (7)
- # data-science (17)
- # datascript (1)
- # datomic (7)
- # duct (23)
- # emacs (23)
- # fulcro (6)
- # graalvm (41)
- # jobs (2)
- # luminus (1)
- # malli (1)
- # off-topic (151)
- # pathom (1)
- # portkey (10)
- # re-frame (12)
- # reitit (17)
- # shadow-cljs (158)
- # spacemacs (14)
- # sql (8)
- # tools-deps (17)
- # xtdb (9)
if you had (alias 'ex 'example.ns)
you could then use ::ex/foo/bar
but using multiple /
in a namespaced keyword is weird
to point to a value inside a nested map, consider [::ex/foo :bar]
that can be passed to get-in
to do the lookup even
In this example foo
does not refer to anything special, I just would like foo/bar
to spec a value in a nested map
I have just added a new library(taoensso/tempura ) to my Clojurescript project. In advanced compilation I get a warning with 'unreachable-code'. Do I need to write an 'extern' for this?
is there a trivial way to walk a nested object removing all namespaces?
{:my-ns/a 2 :my-ns/thing {:my-ns/blah 3} :a [{:my-ns/val "a"}]}
=> {:a 2, :thing {:blah 3}, :a [{:val "a"}]}
being an example
I've attempted using something like (clojure.walk/walk (fn [[k v]] [(-> k name keyword) v]) identity my-obj)
but that chokes on any nesting
In practice walk
should always have a conditional because your fn should do different things for leaves / branches. Also, if your pre or post fn is identity, just use prewalk or postwalk
not everything you walk will be a pair like [k v]
. usually you can do something like (fn [form] (if (keyword? form) (keyword (name form)) form))
walk is recursive, it combines pre and post walks into one function
in fact both prewalk and postwalk are defined using walk
Unless you call it again yourself in the inner function you pass in. Which is what prewalk and postwalk do.
Look at the code: https://github.com/clojure/clojure/blob/master/src/clj/clojure/walk.clj#L35-L51
I was swetting there for a minute 😛 Like was I just not able to understand how the source for walk was recursing hehe, fiew
oh wow I missed that in the docs
that was all I needed
thanks
Hi, I created a library (Project A) using lein new libary greetings
command. I was wondering if it was possible to require this library as an jar. So I ran lein jar
and generated a jar.
I placed this jar in a different project (Project B), including it in the :resource-paths
. This all works fine. The problem however is when I try adding a dependency to Project A, Project B cannot find it (which is logical). So instead of lein jar
I tried the lein uberjar
, assuming it would compile all dependencies into a single jar file. Adding this uberjar to Project B makes it crash, sadly.
Is it possible to build Project A and its dependencies into a single jar file to be used in Project B?
leiningen (and any other maven tool) will look up dependencies recursively
if adding a dep to A doesn't make it available in B, you made some other error - making a new jar and restarting with that should make A's new deps available
adding an uberjar to B shouldn't make it crash either
right
my usual flow is to run lein install
in A, then declare B as a dep of A in project.clj
perhaps the real issue is that you are trying to manually use the jar, instead of properly doing inter-project dependencies, sorry, I forgot that one would even consider doing that, but of course a beginner would :D
Haha, yes I’m aware that I’m not using inter-project depedencies. This is a business related issue that I’m trying to solve
@kevin.van.rooijen so my previous answer was subtly wrong because I misunderstood what you were doing, the real solution is to add A to B's project.clj, and run lein install
which creates a jar for a and puts it in local cache
then you need to add all of A's deps to B
by hand
or remove all A's deps from B so the uberjar works
Ok, so there’s no way to bundle the dependencies somehow? I thought uberjar was supposed to do that
the problem is that uberjar now duplicates libs, but doesn't ensure versions match
in theory it could work, but that would basically be an accident
you could also just add A as an extra classpath element when running B
(that wouldn't work)
right, yeah
@kevin.van.rooijen also deps.edn does allow this sort of thing, but then you need to replace all non classpath building features of lein
it's likely simplest to merge A+B into a single project, or set up a private maven repo (eg. there's a plugin to treat an s3 bucket as a private maven repo)
The problem is that Project A is kind of a dynamic thing. And I don’t have control over that
third project that depends on both A and B?
That’s probably not going to work for my case. I’ll think about this a bit more. Thanks a lot for your help though
I may be misunderstanding your question, but the literal answer is symbols - deps reads the config but doesn't eval, so the symbols are used as data rather than being resolved
it internally turns the symbols into strings and parses them to get maven coordinates
user=> ((juxt namespace name) 'com.foo/bar-lib)
["com.foo" "bar-lib"]
basically this I assumeit is used - the edn reader does not resolve symbols
it's a reader not a compiler or evaluator
(cmd)user=> (clojure.edn/read-string "{foo bar}")
{foo bar}
(ins)user=> (type (first (keys *1)))
clojure.lang.Symbol
they are valid symbols, just not bound, clojure.edn doesn't care if anything is bound
it doesn't resolve bindings
@lockdown- here's the code that parses out the parts of the coordinate https://github.com/clojure/tools.deps.alpha/blob/b77bab1b86/src/main/clojure/clojure/tools/deps/alpha/util/maven.clj#L203
is weird to see the return value as {foo bar} though, but I guess is on purpose to be able to pass things that eval at runtime
it uses name
on lib, then either namespace
or name again
@lockdown- the point of clojure.edn is to be able to read things without evaluation, without eval a symbol is just a symbol
yeah, I mean after you have read the edn, the key might a function that you later evaluate if you choose too
it might point to a function, sure, in this case it's just turned into a string, but using a symbol in the input makes the config syntax less noisey I guess
Hi there, as a begginner Clojure developer I'm trying to understand the concepts behind the framework from James Reeves, Integrant. The video tutorial was available few months ago although seems to be down. Does anyone has a copy of it? Thanx in advance (this URL is down https://skillsmatter.com/skillscasts/9820-enter-integrant-a-micro-framework-for-data-driven-architecture-with-james-reeves)
here's something similar behind a paywall https://lambdaisland.com/episodes/integrant
@rogerio.adachi I think if you find integrant strange or hard to grasp, it might be helpful to find some of what Stuart Sierra has written about his component
library, because integrant is a refinement and attempt to improve his approach while preserving its benefits and functionality
@noisesmith do you approve those refinements? 😉
haha - I haven't used integrant in anger, I have used component and been annoyed by some of the things integrant claims to fix, but can't personally vouch for it
@dpsutton if you mean mount, integrant was an attempt to streamline component while avoiding what it considers the mistakes of mount
in what context? clojure will pass any extra args to your -main if you start your app by specifying an ns with -main
clojure.core/*command-line-args*
A sequence of the supplied command line arguments, or nil if
none were supplied
it sounds like this is a record of what was passed to the main, not what will be passed there
the data in *command-line-args*
will be the same as the args to -main if your app was started in the "normal" way
yeah, not sure of the ordering there
and since it's guaranteed to be unevaluated strings, the order doesn't really matter
Hi Clojurians. I've just started learning Clojure and I'm working thru the "Programming Clojure" (3rd edition) book. Got a basic question about the repl. When I start it there are a bunch of functions that are available that are coming from different namespaces (like the functions in clojure.core)... why don't I have to use the namespace to invoke them? That is, I can just do (take-while even? [2 4 6 7 8 10])
You can exclude specific functions if you want to define your own with the same name, eg.
(ns foo.core
(:refer-clojure :exclude [read]))
Not generally needed, but possible.Sure. Thank you! Since I'm just getting started its all interesting to me at this point. I realize some of the things (like this) just won't come up in "real" code but I like digging into features a bit until my curiosity is satisfied.
ok, that makes sense. is there some config file that I can use to control what gets loaded/mapped ?
the clojure repl ones (doc, source, dir ...) are in user for you and you can use them elsewhere as you would consume any other ns
@fmcgeough there are many ns manipulation functions
huh. yeah I see that. Its very interesting. back to the book ! thank you.
Are there any options if I want a cross platform catch all in my exceptions? Don't mind using a library for error handling but I don't want some kind of maybe error thing leaking everywhere
slingshot looked good but cljs support isn't there yet
suppose I could use reader conditionals for now
@sfyire it's been ages since I did cljs, but when I did I just used a conditional that either made a js object (for cljs) or an ex-info (for clj) - oh that's on the throw side, on the catch side I always try to use the most concrete type I can but Object vs. Throwable for those "catch everything" cases via cljc