This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2019-06-07
Channels
- # announcements (12)
- # aws (2)
- # beginners (233)
- # calva (68)
- # cider (23)
- # circleci (5)
- # clj-kondo (40)
- # cljsrn (4)
- # clojars (3)
- # clojure (200)
- # clojure-austin (1)
- # clojure-canada (1)
- # clojure-dev (16)
- # clojure-europe (1)
- # clojure-finland (1)
- # clojure-italy (4)
- # clojure-nl (16)
- # clojure-spec (3)
- # clojure-uk (102)
- # clojurescript (16)
- # cursive (14)
- # datomic (16)
- # figwheel-main (7)
- # graalvm (3)
- # hoplon (37)
- # jackdaw (23)
- # jobs-discuss (24)
- # joker (4)
- # kaocha (6)
- # keechma (64)
- # off-topic (66)
- # parinfer (1)
- # pedestal (7)
- # re-frame (7)
- # reagent (10)
- # reitit (45)
- # rewrite-clj (12)
- # shadow-cljs (1)
- # slack-help (8)
- # spacemacs (55)
- # sql (9)
- # tools-deps (9)
- # vim (7)
Finally i get it working. found this: https://figwheel.org/docs/hot_reloading.html
strings in edn can span multiple lines, just like clojure
but I suspect the main place you'd want to use one in a deps.edn would be in something like jvm-opts, which has known escaping issues with whitespace
what's your actual goal?
yep, to pass -Dclojure.server.repl="{:port 5555 :accept clojure.core.server/repl}"
to jvm-opts
the workaround for this is to replace all spaces with commas, which act as whitespace for clojure/edn but don't have escaping issues in the shell
not sure if you can break up the line or not
I'm using tools.deps
-- what's the common way to build an uberjar?
I'm thinking about using this: https://github.com/tonsky/uberdeps
I added the following to my deps.edn
:
:aliases {
:uberjar {:extra-deps {uberdeps {:mvn/version "0.1.4"}}
:main-opts ["-m" "uberdeps.uberjar"]}
}
but when I run clj -R:uberjar
-- it just takes me to a repl
is the programmatic API the only way to get this to execute?
oh, I got it to execute with: clj -m uberdeps.uberjar
but only after moving the dep to :deps
and removing the alias
No idea about tonsky/uberdeps but we use (my fork of) depstar at work for this.
but, now I notice my code isn't being added to the package
@U04V70XH6: got a link to depstar
?
-R
won't be enough, you need -A
Because you need main opts as well as the resource deps adding.
clj -A:uberjar
(for depstar
you would specify the name of the JAR file you want built -- no idea about tonsky's package)
Here's the general list of JAR packaging tools https://github.com/clojure/tools.deps.alpha/wiki/Tools#packaging
(includes depstar and many others)
Did that help @U0FEHF1RS?
hmm ... still running into trouble
example:
# clj -A:native-image
Exception in thread "main" java.io.FileNotFoundException: -A:native-image (No such file or directory)
at java.base/java.io.FileInputStream.open0(Native Method)
at java.base/java.io.FileInputStream.open(FileInputStream.java:196)
at java.base/java.io.FileInputStream.<init>(FileInputStream.java:139)
at java.base/java.io.FileInputStream.<init>(FileInputStream.java:94)
at clojure.lang.Compiler.loadFile(Compiler.java:7570)
at clojure.main$load_script.invokeStatic(main.clj:452)
at clojure.main$script_opt.invokeStatic(main.clj:512)
at clojure.main$script_opt.invoke(main.clj:507)
at clojure.main$main.invokeStatic(main.clj:598)
at clojure.main$main.doInvoke(main.clj:561)
at clojure.lang.RestFn.applyTo(RestFn.java:137)
at clojure.lang.Var.applyTo(Var.java:705)
at clojure.main.main(main.java:37)
deps.edn
:
;; The deps.edn file describes the information needed to build a classpath.
;;
;; When using the `clojure` or `clj` script, there are several deps.edn files
;; that are combined:
;; - install-level
;; - user level (this file)
;; - project level (current directory when invoked)
;;
;; For all attributes other than :paths, these config files are merged left to right.
;; Only the last :paths is kept and others are dropped.
{;; Paths
;; Directories in the current project to include in the classpath
;; :paths ["src"]
;; External dependencies
:deps {org.clojure/clojure {:mvn/version "1.10.0"}
org.clojure/data.json {:mvn/version "0.2.6"}
com.amazonaws/aws-lambda-java-core {:mvn/version "1.0.0"}
nrepl {:mvn/version "0.6.0"}}
;; Aliases
;; resolve-deps aliases (-R) affect dependency resolution, options:
;; :extra-deps - specifies extra deps to add to :deps
;; :override-deps - specifies a coordinate to use instead of that in :deps
;; :default-deps - specifies a coordinate to use for a lib if one isn't found
;; make-classpath aliases (-C) affect the classpath generation, options:
;; :extra-paths - vector of additional paths to add to the classpath
;; :classpath-overrides - map of lib to path that overrides the result of resolving deps
;; :aliases {
;; :deps {:extra-deps {org.clojure/tools.deps.alpha {:mvn/version "0.2.196"}}}
;; :test {:extra-paths ["test"]}
;; }
:aliases {:native-image
{:main-opts ["-m clj.native-image core"
"--initialize-at-build-time"
;; optional native image name override
"-H:Name=core"]
:jvm-opts ["-Dclojure.compiler.direct-linking=true"]
:extra-deps
{clj.native-image
{:git/url ""
:sha "567176ddb0f7507c8b0969e0a10f60f848afaf7d"}}}}
;; Provider attributes
;; :mvn/repos {
;; "central" {:url " "}
;; "clojars" {:url ""}
;; }
}
This seems unrelated to your previous question?
well .. I tried to switch gears from the link you sent me with one of the other packagers
I can switch to stay on topic -- I'll try depstar
This is wrong: "-m clj.native-image core"
-- you should specify a vector of arguments, not a single string containing multiple arguments.
["-m" "clj.native-image" "core" ...]
Bear in mind: depstar
does no AOT and adds no manifest -- so whether it's suitable or not will depend on your expectations.
I do not know what tonsky/uberjar does in that respect. All these different packaging tools do different things.
ok, shifting gears:
{:deps {org.clojure/clojure {:mvn/version "1.10.0"}
org.clojure/data.json {:mvn/version "0.2.6"}
com.amazonaws/aws-lambda-java-core {:mvn/version "1.0.0"}
nrepl {:mvn/version "0.6.0"}}
:aliases {:depstar
{:extra-deps
{seancorfield/depstar {:mvn/version "0.2.1"}}}}}
# clojure -A:depstar -m hf.depstar.uberjar target/clj.jar
Exception in thread "main" java.io.FileNotFoundException: -A:depstar (No such file or directory)
at java.base/java.io.FileInputStream.open0(Native Method)
at java.base/java.io.FileInputStream.open(FileInputStream.java:196)
at java.base/java.io.FileInputStream.<init>(FileInputStream.java:139)
at java.base/java.io.FileInputStream.<init>(FileInputStream.java:94)
at clojure.lang.Compiler.loadFile(Compiler.java:7570)
at clojure.main$load_script.invokeStatic(main.clj:452)
at clojure.main$script_opt.invokeStatic(main.clj:512)
at clojure.main$script_opt.invoke(main.clj:507)
at clojure.main$main.invokeStatic(main.clj:598)
at clojure.main$main.doInvoke(main.clj:561)
at clojure.lang.RestFn.applyTo(RestFn.java:137)
at clojure.lang.Var.applyTo(Var.java:705)
at clojure.main.main(main.java:37)
# tree
.
├── deps.edn
├── src
│ └── core.clj
└── target
└── clj.jar
core.clj
:
(ns core
(:gen-class))
(defn -main [& args]
(println "Hello, World!"))
so, that's the whole repo -- but I still get that error ☝️
What is that clojure
command? What does which clojure
produce?
# clojure -h
Usage: clojure [dep-opt*] [init-opt*] [main-opt] [arg*]
clj [dep-opt*] [init-opt*] [main-opt] [arg*]
The clojure script is a runner for Clojure. clj is a wrapper
for interactive repl use. These scripts ultimately construct and
invoke a command-line of the form:
java [java-opt*] -cp classpath clojure.main [init-opt*] [main-opt] [arg*]
The dep-opts are used to build the java-opts and classpath:
-Jopt Pass opt through in java_opts, ex: -J-Xmx512m
-Ralias... Concatenated resolve-deps aliases, ex: -R:bench:1.9
-Calias... Concatenated make-classpath aliases, ex: -C:dev
-Spath Compute classpath and echo to stdout only
-Srepro Use only the local deps.edn (ignore other config files)
-Sforce Force recomputation of the classpath (don't use the cache)
-Spom Generate (or update an existing) pom.xml with deps and paths
-Sverbose Print important path info to console
init-opt:
-i, --init path Load a file or resource
-e, --eval string Eval exprs in string; print non-nil values
main-opt:
-m, --main ns-name Call the -main function from namespace w/args
-r, --repl Run a repl
path Run a script from a file or resource
- Run a script from standard input
-h, -?, --help Print this help message and exit
For more info, see:
not sure what to do then
seanc@DESKTOP-QU2UJ1N:~/clojure/john$ tree .
.
├── deps.edn
├── src
│ └── core.clj
└── target
2 directories, 2 files
seanc@DESKTOP-QU2UJ1N:~/clojure/john$ cat deps.edn
{:deps {org.clojure/clojure {:mvn/version "1.10.0"}
org.clojure/data.json {:mvn/version "0.2.6"}
com.amazonaws/aws-lambda-java-core {:mvn/version "1.0.0"}
nrepl {:mvn/version "0.6.0"}}
:aliases {:depstar
{:extra-deps
{seancorfield/depstar {:mvn/version "0.2.1"}}}}}
seanc@DESKTOP-QU2UJ1N:~/clojure/john$ cat src/core.clj
(ns core
(:gen-class))
(defn -main [& args]
(println "Hello, World!"))
seanc@DESKTOP-QU2UJ1N:~/clojure/john$ clojure -A:depstar -m hf.depstar.uberjar target/clj.jar
Building uber jar: target/clj.jar
seanc@DESKTOP-QU2UJ1N:~/clojure/john$ java -cp target/clj.jar clojure.main -m core
Hello, World!
FYI Here’s tonsky’s recent blog entry on why he created uberdeps https://tonsky.me/blog/uberdeps/
@U04V70XH6: works now -- looks like I was running clj 1.9.0
instead of 1.10.0
even though 1.10.0
was in deps.edn
@UE21H2HHD that's an interesting read, thanks! My depstar ended up fixing several bugs in the original -- and also no longer copies files to a temp tree, so it's much faster now (that change fixed a Windows compatibility issue as well as removing a security vulnerability that both exist in the original).
Tonsky's issue of using the default classpath -- that's by design since you can control what's on the classpath through aliases. His solution doesn't work at all for the deps.edn
setup we use at work -- several packagers fail that test.
@U04V70XH6 yeah, I remember following that Windows bug here on Slack. Trippy (in the LSD sense).
thanks
@U04V70XH6: can you clarify the differences with the classpath design? I'm trying out uberdeps
now and I'm getting the classpaths I'm expecting with the alias
@U0FEHF1RS According to the docs uberdeps
reads your deps.edn
which means that if you use :override-deps
in your base deps.edn
file, it won't work -- which is how we have things set up at work. Each project deps.edn
has {}
for each dependency's version. You either have to reproduce the entire tools.deps
path to make that work, or you should rely on the classpath (which is what depstar
does).
deps.edn
tooling should work from the classpath, not trying to read and parse the system, user, and project EDN files -- that was the path I went down with boot-tools-deps
and I quickly realized it was a big ol' quagmire and not the right way to do things.
I know why people go down that path (having gone down that path myself!) so I totally get whyTonsky didn't like depstar
and wrote his own -- but it's a mistake 😐
It works in all the simple cases. It seems like the "right thing" to do. But it doesn't work in the real world, once you get into more complicated projects.
The classpath is the System of Record. Trying to replicate the way clj
works in every program is a fool's errand 🙂
I'll be interested to chat to him about cljs builds since I don't do any of that -- I suspect even the cljs stuff can be done with appropriate aliases to create the "right" classpath (with the .js
, without the .cljs
) for depstar
but I haven't tried that. I do like the idea of a verbose mode for displaying everything that ends up in the JAR 🙂 I should add that feature to depstar
!
@U04V70XH6 Bear in mind: depstar
does no AOT and adds no manifest -- so whether it's suitable or not will depend on your expectations. How does both of these things effect project or final result? I mean how do I know if they are suitable or not?
The manifest is a file a JAR that can specify the main (compiled) class, the entry point, so you can do java -jar path/to/the.jar
and it'll know what to run. If you don't have a manifest, you can't use java -jar
, you have to use java -cp path/to/the.jar clojure.main -m my.entry.ns
-- clojure.main
is the name of the main class to start, and it (Clojure) takes the -m
option and it requires that namespace and calls -main
in it.
The default new project created by Leiningen has AOT enabled and compiles the "main" namespace, and when you build an uberjar, Leiningen puts a manifest in, specifying that namespace (which is compiled to a class).
But, as you can see above, you don't need to use AOT, nor a manifest. The only benefit of AOT is faster startup of your application.
@U04V70XH6 Thanks, that is the answer I was looking for. I'm using clj
and your awesome library depstar
for my project.
When i run lein fig:test
i have this:
Figwheel Server: Resource not found
Keep on figwheelin' yep
No really sure but, maybe, because it doesn't start the server, you're running a test so I think there's no reason for launch it
@UK3MP6QKZ ah so. so its for CI purpose right?
I'm no sure about it, certainly, I only have 3 or 4 weeks learning clojure for hobby, C# and CLJ aren't the same at all hahaha
I started with luminus template and then I found "better" ways, ex. figwheel-main so I decided migrated it and I'm here now hahaha
What’s the “proper” way to do string interpolation in Clojure? I found core.incubator
but that seems old; is that still the way to do it? https://github.com/clojure/core.incubator
is format
sufficient?
(or cl-format
if you want an insane set of options)
Yes that works as well. Is that how people tend to do it? I kind’o like having the more descriptive ~{name}
in the string instead of the %...
things.
I usually use format
personally as that's built-in
core.incubator is no longer an active project
which doesn't mean that stuff doesn't work there, but ...
I don't know if the other utility libs out there have other options (medley, useful, tupelo, etc)
I'm using luminus
and buddy
to attempt to create user authentication. Going through the buddy-auth
tutorials, I was trying to combine the signed jwt
with a session like authentication. I store the jwt
as a cookie. Then have wrap-user-cookie
function that takes the cookie and puts it in the request header. That function looks like:
(defn wrap-user-cookie
"Middleware to convert session cookie token value to authentication header."
[handler]
(fn [{:keys [cookies] :as req}]
(if-let [token (get-in cookies ["session" :value])]
(-> req
(assoc-in [:headers "authorization"] (str "Token " token))
handler)
(handler req))))
Is this recommended way of doing things?Mostly because all my coworkers hate me when I use it and not go for freemarker or something like that
Is there a 'between' kinda thing based on compare
or should I make my own?
does (let [order [x y z]] (= order (sort order)))
count?
it's not built in per se, but it's compact because it leverages built in behaviors
I'm a bit performance constrained and sort sets off my speed flags, plus it's string comp, but it's pretty code.
actually! that's just sorted?
- so the answer is yes, and it's called sorted?
⁉️ love it!
it sounded so close
<
and >
do what I want for nums, just not strings.
short-circuiting version
(ins)user=> (defn is-sorted? [& args] (every? (partial apply (comp (complement pos?) compare)) (partition 2 1 args)))
#'user/is-sorted?
(cmd)user=> (is-sorted? 1 2 3)
true
(ins)user=> (is-sorted? 2 1 3)
false
it compares every sequential pair in the arglist, returning false if any pair are in the wrong order (equality side by side is allowed)
That is A) exactly what I need and B) really neat to read
haha, glad I could help
tried to stuff as many useful idioms as I could in there, this being #beginners and all
(->
layer
:asdf
(subs 5 10)
#(is-sorted? "abc" % "aef"))
throws error
java.lang.ClassCastException: clojure.lang.Symbol cannot be cast to clojure.lang.IPersistentVector, compiling:(com/MYSTUFF
Did I do a real dumb?
user=> '#(foo)
(fn* [] (foo))
user=>
see how it expands to an fn form?
user=> (macroexpand '(-> x (fn [y] (bar y))))
(fn* x ([y] (bar y)))
Which is not what I want here, I want the function it would expand to?
So the -> is gonna jamb stuff into the function def all funny like?
the function doesn't get called with x as an argument, the form is updated to insert the symbol
right
-> / ->> are not function composition tools, they are form rewriting tools
My ramda history bites me again.
one option here is to change (-> x #(foo))
to (-> x (#(foo)))
another option is to bind the function (via let or using defn) and use the function name
Which is probably more technically correct. Or I could switch to as->
right, all these options work
just remember that the arrow macros don't do function composition, they do form rewrites, so you need to consider what the form that ends up being compiled would look like sometimes
I should use macroexpand more in the repl, shouldn't I?
I find it helps as a thing to try when results are unexpected sometimes
user=> (->> (+ x y) (let [x 31 y 11]))
42
- my favorite example showing that an arrow macro is rewriting code, not composing functionsOk yeah, that is a bit new thinks to think for me
don't actually use ->> like that - it's just an example to prove that it doesn't do what it intuitively seems like at first
Yeah, a pit not to twist your ankle in, so to speak.
@U051SS2EU So, comp
is used for functional composition. Right?
right
If you were to build a new web-app today, would you use leiningen or deps.edn? I had some success with deps.edn today in a small app.
Created an uberjar and smacked into a docker container.
I’d use deps unless I needed a lein capability or plugin
what did you use for the uberjar @UBN9SNVB4?
I used sean corefields fork of depstar
. https://github.com/seancorfield/depstar
I don’t understand why deps.edn is a thing separate from lein. lein already handles dependency management, building, and distributing. for those that prefer deps.edn/clj, what do you use it for? I’m puzzled why anyone would prefer to manually cobble together random tools to replicate lein. but maybe deps.edn/clj users don’t have the same workflow?
https://clojure.org/reference/deps_and_cli provides some motivation
it just describes what it does, which are all things that lein already does (and then some, like uberjars)
One point: lein is a build tool, deps is an invocation tool
Deps allows code to depend on things other than maven artifacts, e.g. clj files in git repos
it seems like you’d want your dependencies and other project info described in a single place (maybe call it project.clj? 😉) and then use it for both building and invocation, which lein does
But lein is a great tool that’s long proved its worth! I don’t think the authors of deps would advocate switching away from it just because
project.clj
has to be macro-expanded in order to be evaluated, while deps is pure data
it’s just frustrating when cognitect seems to intentionally splinter the community in order to maintain control of the ecosystem. I was away for a few years when deps came to the scene, so maybe it was introduced in such a way that made it clear it wasn’t meant to replace lein. but the fact that we’re having this conversation now seems like that wasn’t effective, if it ever happened
When we started with Clojure at work back in 2011, lein
was the only option. We found it very limiting over time and switched to boot
in 2015. Last year we wanted to streamline our dev/test pipeline and switched to clj
/`deps.edn` and we've been very happy with that.
For simple stuff, where you don't care about startup time for general tasks, lein
is fine. boot
is much more programmable/extensible -- but it also has downsides (complexity, the fileset abstraction can introduce performance issues and have weird effects on some dev/test workflows, edge case async bugs in pod handling).
For where we are, with our 80k lines of Clojure at work, clj
/`deps.edn` is a better fit for a large monorepo with two dozen subprojects, and we have much more control over versions, tooling, etc.
clj
/`deps.edn` don't replace lein
or boot
as a whole, but there's a lot of stuff you can do easily with them.
If you have Java code as well as Clojure, clj
/`deps.edn` won't fit, for example (although you can do stuff to make it work).
Bottom line: if you're happy with lein
, keep using it; if you're happy with boot
, keep using it; if you're just starting out, try clj
/`deps.edn` and see whether you need anything beyond that.
I do not work for Cognitect, nor am I any kind of spokesperson or know all that they know, but they have always made it pretty clear that deps isn't meant to do everything lein can do. One of the reasons it was introduced was to depend on Clojure source code versions in Git repos directly, without having to create a JAR or other artifact from it. It seems to have been at least partially motivated by a use case within Datomic Cloud for deploying apps to AWS clusters.
The fact that the question was asked is because some people have found that they preferred tooling like deps (plus some other tools such as depstar) over lein, given the choice, but not everyone does.
The talk "Spec-ulation" by Rich Hickey provides more motivation/background/"why" than I can do justice to in a short note: https://github.com/matthiasn/talk-transcripts/blob/master/Hickey_Rich/Spec_ulation.md
Also check out some public talks about Datomic Cloud if you are interested in how it arises in that context. This is the one that I saw: https://github.com/matthiasn/talk-transcripts/blob/master/Hickey_Rich/DatomicIons.md
I think deps (and spec) make me uncomfortable because they are “core” projects that displaced community projects that were de facto standards. certainly, lein isn’t perfect, but was there ever an attempt to work with technomancy and others to provide a simpler, deps-like core or package lein with Clojure? I’m also not opposed to competition, we don’t all have to use the same tooling and different approaches result in general improvement. but Cognitect has the unfair advantage that their tools are shipped with Clojure. people may end up preferring deps simply because they don’t need to install it, not because it is actually better
But you do need to install deps. It doesn't come with the base Clojure JAR or anything like that.
I don't have a horse in this race -- if people don't like it that Cognitect gives away free software that competes with other free software, I don't know what to say that will make you comfortable with that.
Making your own thing that you have control over is often an order of magnitude easier than convincing someone else to change what they are doing, especially in ways that are not compatible with what they are doing already
perhaps I’m mistaken, but it looks like clj
and clojure
commands are included during install according to: https://clojure.org/guides/getting_started
Sure, but you can install Leiningen and avoid that entirely, if you don't want it.
It is on the getting started page because if it were not, the fact that the Clojure JAR by itself is no longer enough would make the example "java -classpath ..." command line that used to be there so long, that it would be off-putting.
You can install Leiningen, create a new project, and it will get all of the Clojure JARs needed for your project just fine, even if you never ever touch clj/clojure/deps
So at least one way of thinking is that clj/clojure/deps is packaged with Clojure, just as much as Leiningen is packaged with Clojure.
right, and nowhere is that mentioned in the getting started page. there is only a brief mention that lein and boot exist, but nothing to indicate that they can be used to sidestep the “official” installation scripts which include clj
these finer points aren’t really the issue. it’s the approach to develop something internally to replace something already built by the community without attempting to work with the community
They have always said that clj/clojure does not replace Leiningen, nor is it intended to. They don't want clj/clojure to do everything Leiningen does, repeatedly. Fairly often on the #tools-deps channel, whenever people ask "Can clj/clojure do this thing that Leiningen does?" the answer is often "out of scope"
I am not trying to argue into making you comfortable with any of this. But the fact is that Cognitect wanted something different, paid to build it, and then give it away. They give you prominent instructions on how to install and use it. They mention Leiningen, perhaps not as prominently, on a Clojure getting started page. If that is the stuff of world domination, I'm all for it.
They aren't exactly dominating the world yet 🙂
I just think they’re uninterested in working with the community, and the Clojure community is too small for that to be sustainable
@UCF779XFS that Getting Started page you linked to says
Build tools
Build tools provide a range of capabilities for building, running, and deploying Clojure libraries and applications. The two most popular Clojure build tools are Leiningen and Boot.
(linked to the lein
/`boot` websites).nothing in there implies you don’t need to have already run the installers at the top of the page
I think you're being extremely unfair to the hard-working folks at Cognitect who provide all this stuff for free to us.
My impression is that when they build stuff, they are quite particular about how they want to do so, and doing design work on such things with a community is really, really tough, and they would rather not go to so much trouble. For a related take from the creator of Elm on that, here is yet another talk I like 🙂 https://github.com/matthiasn/talk-transcripts/blob/master/Czaplicki_Evan/TheHardPartsOfOpenSource.md
I can be appreciative of the work Cognitect has done and still criticize their interactions with the community
Most books and tutorials that beginners would use direct them to Leiningen. Some tutorials would direct beginners to Boot. Some direct them to clj
/`deps.edn`.
Such criticisms are not helpful nor particularly constructive -- and really don't help the community either. Saying they're "shitty" is insulting and information-free (and, frankly, isn't appropriate language for a professional international community like this -- with my Admin Team hat on).
anyway, I appreciate the complementary thoughts from you both. I didn’t mean to ramble on so
Sure, you can be both, and many people are. The criticisms aren't necessarily going to generate any more light than heat, I would guess, but sure, everyone is free to do so.
I realize speaking up doesn’t mean anything changes, but I think occasionally voicing opinions is reasonable, no?
how would you or Cognitect know anyone still using Clojure and contributing to the ecoystem is bothered by it otherwise?
You can certainly express opinions and criticism without generalizations like "they're shitty"...
and as far as language goes, I rarely use colorful language and don’t believe I ever have here before.
If you have suggestions for improving the http://clojure.org website, you could create an issue against the GitHub repo for the site, or submit a pull request with updated wording. They might reject it and they may explain why, but that would be constructive (and polite).
yes, but not a generalization. an adjective for the behavior I had already described in messages before it
As a reminder: https://clojure.org/community/etiquette
it’s ironic, because the sort of behavior I was describing here is exactly the sort of thing that tends to make people contribute less
You ask: "how would you or Cognitect know anyone still using Clojure and contributing to the ecosystem is bothered by it otherwise?" Having been keeping half an ear on the community for years now, that seems like a probability 0 situation.
@U04V70XH6 if you don’t like that colorful adjective, I apologize. I didn’t intend to offend anyone. if it’s against the the community etiquette, please show me where. you claimed I was making a generalization, but you either misunderstood or missed the previous messages where I attempt to describe the kind of community interaction that has been bothering me. I do not appreciate what seems like an attempt to shame or threaten me by posting the etiquette link without referencing anything there and mentioning your “admin hat” simply because you disagree with me
It is a pretty darned short etiquette page, and does explicitly give advice on discussions of disagreements of how something has been made, or should be made.
I’m not sure I agree that statement, or indeed the entire page, applies well to conversations about community. deps.edn was only the example, the topic was collaboration between Cognitect and established community projects. :man-shrugging:
A bit tangential: https://www.therepl.net/episodes/23/ has a very thoughtful conversation with Zach Tellman on clojure community interaction that is nuanced, insightful, and respectful, at least to my ears.
@UCF779XFS The Code of Conduct for this Slack https://github.com/clojurians/community-development/blob/master/Code-of-Conduct.md -- specifically "Inappropriate Language". The TL;DR is to think of this forum as a professional, international business group where your co-workers, boss(es), clients, etc could all be present...
NP. It's in a thread so only a handful will see it. It was intended to be more of a reminder of "tone" when offering criticisms and that we're all trying to be professionals here 🙂
I don't agree with all of Cognitect's decisions but they're pretty clear about their vision so I can usually understand their decisions. It's the bane of OSS project maintainers' lives globally that some folks will always be unhappy with how you run a project and/or some decisions you make...
For example, in creating the next generation of clojure.java.jdbc
I thought long and hard about whether it should go in Contrib (as new namespaces in that project) or live externally. Keeping it in Contrib had a number of benefits but I knew that it would also cause several complaints from people who don't like the Contrib development model.
In the end, I decided to keep it outside Contrib but that means I'm now maintaining two JDBC libraries with different contribution/development models, making my life harder.
One of the things I love about the Clojure community and these Slack channels is how friendly, civil and courteous everyone is! You guys are the best!
I've been doing OSS development for about 30 years now, so I've seen a lot of the ugly side of the work...
There is a really good No Manifestos podcast with Mia https://www.nomanifestos.com/episodes/3 She chose Clojure because she found the people involved to be (I paraphrase) smart, happy and pleasant.
Yeah @U04V70XH6, I only dipped me toe into OSS a few years ago and… well let’s just say I’m happy I found the Clojure community.
(let [[t d] (split-with #(< % 12) (range 1e8))] [(count d) (count t)]); #<OutOfMemoryError java.lang.OutOfMemoryError:
Is it correct to say this happens because, by keeping t around, we end up building that lazy rangeb into a realized list. As opposed to reversing d and t which rule mean that as we counted d we could just discarded that number/ sum it into the return value?@drewverlee count
is what is forcing the realization here and that's why you get OoM
user=> (let [[t d] (split-with #(< % 12) (range 1e8))] [(first d) (first t)])
[12 0]
That doesn't realize all of t
or d
so it's "safe".
I'd think the locals clearing would be smart enough to know count doesn't need to hold the head
or maybe I misunderstand what count on a lazy-seq does
user=> (let [[t d] (split-with #(< % 12) (range 1e8))] [(bounded-count 1000 d) (bounded-count 1000 t)])
[1000 12]
only realizes the first 1,000 or so which is also safe here.t
is only a small sequence -- 12 elements -- d
is the long one, and split-with
is lazy (because it's a call to take-while
and a call to drop-while
which are both lazy).
split-with returns a pair of lazyseqs, each of which has a reference to the original sequence
d is holding a reference to the head of the range, while you are walking entire range (throwing parts away) and counting it
sorry, I didn't notice the original code has d and t in the other order when counting, so swap that all around
oh... right
user=> (let [[t d] (split-with #(< % 12) (range 1e8))] [(count t) (count d)])
[12 99999988]
@hiredman is right. Sorry for misleading/missing the point there @drewverleethanks everyone 🙂.