This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2021-11-24
Channels
- # announcements (4)
- # asami (5)
- # babashka (20)
- # beginners (94)
- # bristol-clojurians (1)
- # calva (23)
- # cider (2)
- # clj-commons (3)
- # clj-kondo (43)
- # cljfx (2)
- # cljs-dev (13)
- # clojure (112)
- # clojure-dev (44)
- # clojure-europe (17)
- # clojure-nl (5)
- # clojure-poland (12)
- # clojure-spec (2)
- # clojure-uk (3)
- # clojurebridge (1)
- # clojurescript (92)
- # cursive (17)
- # data-science (8)
- # datahike (1)
- # datalevin (1)
- # datomic (3)
- # deps-new (7)
- # events (2)
- # fulcro (40)
- # graalvm (110)
- # holy-lambda (16)
- # introduce-yourself (1)
- # lsp (13)
- # malli (8)
- # missionary (12)
- # off-topic (10)
- # pathom (13)
- # polylith (10)
- # portal (28)
- # re-frame (37)
- # reitit (1)
- # releases (1)
- # shadow-cljs (30)
- # spacemacs (1)
- # tools-deps (9)
- # xtdb (10)
This has probably been discussed to death already, but I haven’t had the bandwith to follow it, so I’m asking here
WRT to the https://clojure.atlassian.net/browse/CLJ-2664 and the https://github.com/clojure/clojure/blob/master/src/clj/clojure/java/math.clj, I’m wondering at the approach saying:
• Portability to CLJS is a non-goal (so namespace is clojure.java.math)
If portability is not a concern, then I’m wondering what the namespace is for, given that it is such a thin wrapper around https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/Math.html. Is it just the typehinting? Having a namespace that was outside of clojure.java
would have made portability possible, given that most of the functions are already available in https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math, and the rest can be implemented. After all, IEEE754 math is not platform dependent.
I can understand not making portability a priority, but blocking it out seems like the wrong approach. (Yes, I know that ClojureScript could implement clojure.java.math
, but that would be a poor idea).
If you're interested more discussion in #clojure-dev which is a better place for this
If i expost f
and s
in this could, would f be considered thread safe? e.g if 2 threads try to call `foo "at the same time" is it safe? Or do i have to express that another way?
(ns core)
(defn foo [] "hi")
(def s (atom {'foo 0}))
(defn f [x]
(when (= 0 (@s x))
(do
(swap! s update x inc)
((eval x)))
))
@s;; => {foo 0}
(f 'foo);; => "hi"
@s;; => {foo 1}
(f 'foo);; => nil
it's not thread safe - between the deref and the swap the value of s can change - this is a classic data race
So this is a job for compare-and-set!
then?
(ns core)
(defn foo [] "hi")
(def s (atom {'foo 0}))
(defn f [x]
(when (= 1 ((swap! s update x inc) x))
((eval x))))
@s;; => {foo 0}
(f 'foo)
@s;; => {foo 1}
(f 'foo);; => nil
then?Is there a way to figure out if/when a subprocess is requesting something from stdin when using ProcessBuilder? The usecase is I'm running some long shell commands, and I want to print a little ascii loading icon thing. That works fine, but if any of the subprocess request input from stdin - specifically a sudo prompt, that immediately screws things up because suddenly I have a sudo prompt that's immediately getting written over by a loading icon. What I'd like is if the ProcessBuilder can recognize when it's subprocess is requesting input, signal to my loading (which is on a different thread) to stop and wait for the input to be done, then once the input is entered, continue the loading icon. I can't just run the program using sudo cause that breaks all sorts of stuff since I'm relying on the user's environment - using their home directory and user installs and stuff
weird, does ProcessBuilder not let you read stdout of the subprocess as it executes?
I know that it lets you take control of it, but I don't actually want to take control of the sudo prompt if I don't have to.
@phdumaresq this is reminding me of a Tcl tool called Expect. there are ports to many languages, including java https://github.com/ronniedong/Expect-for-Java
I’ve been trying to write an Expect script, and maybe I’m spoiled by not having to do that much terminal scripting in my day job, but I found it a little hairy. But I really want what it can give me.
you're depending on output from the subprocess asking for input like a password, and you need to handle their password, but it handles the thing you're talking about.
@phdumaresq also I was reminded of this, which could be helpful https://mdk.fr/blog/how-apt-does-its-fancy-progress-bar.html -- apt keeps its progress bar at the bottom of the screen using terminal tricks that could be helpful
ELI5: are functions values? if yes, how and why? (I have a hunch they are, I just don't know why)
in a loose sense - all things have observable properties. The full set of those observable properties is the “value” of a thing.
the way we talk about values here generally is in distinction to an “identity”, which is a label attached to a succession of values
you can define a function “object” by all the different results it would produce when called with different arguments
but stepping back in to the “real” - if a function in your program depends on context that will change outside of itself then that function itself is not a “value”. The full state of that function and the properties of its environment that it relies on are its “value”
so the “value” of the function bound to the identity of f
includes the current value associated with the identity of state
which becomes more complicated when you introduce concurrency, since the definition for what exactly the value for f
is depends on what processes are doing what with regards to state and at which time/clock cycle the value of state is accessed
“impure” functions are also values that include the value of every property of their environment
its the same kind of thought train that “pure newtonian mechanics” drives you down - If you knew all the properties of the universe at some time P(t)
, then the laws of physics are just the function from P(t) -> P(t')
So if your very real function in your program called RDRAND
and sampled the randomness of the surrounding universe it would be impossible to define the value of that function at any given point in time, even with infinite knowledge of P(t)
@U3JH98J4R Damn, I appreciate your 2am answer. haha. what I understood from this is that since pure functions in the mathematical sense map one value to another they can be considered values themselves. Whereas impure functions aka procedures are not values.
clojure.lang.Namespace
has an implementation for Navigable
. But why don't I see that type show up here?
(keys (:impls clojure.core.protocols/Navigable))
(java.lang.Object)
I see there is even a public function for this:
(extenders clojure.core.protocols/Navigable)
;;=> (java.lang.Object)
wild guess: clojure.lang.Namespace implements the Navigable interface, which is generated by the Navigable protocol, but not equal to it
also where did you find the Navigable implementation? it's not in https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Namespace.java
that's Datafiable, not Navigable, and it seems to work for me:
user=> (require 'clojure.datafy)
nil
user=> (extenders clojure.core.protocols/Datafiable)
(nil java.lang.Object java.lang.Throwable clojure.lang.IRef clojure.lang.Namespace java.lang.Class)
$ clj
Clojure 1.11.0-alpha3
user=> (extenders clojure.core.protocols/Navigable)
(java.lang.Object)
user=> (extenders clojure.core.protocols/Datafiable)
(nil java.lang.Object)
That worked.
user=> (extenders clojure.core.protocols/Navigable)
(java.lang.Object)
user=> (extenders clojure.core.protocols/Datafiable)
(nil java.lang.Object java.lang.Throwable clojure.lang.IRef clojure.lang.Namespace java.lang.Class)
e.g. code that happens to work due to namespace loading order breaks when somebody makes a new namespace
right, so clj-kondo is fine with (:require ... [foo.bar.quux] ...)
? that's a good convention
also it "forces" you to require explicitly even if you know the namespace is already loaded. e.g. (clojure.string/join ...)
isn't accepted if you don't require clojure.string
not a clojure question, but ... does git status
consider .gitignore
before showing you modified files?
There's also #off-topic
IIRC Git only considers .gitignore
for files that have not been tracked already. If you track a file, adding it to .gitignore
will change nothing. But there are ways around that.
i initially forgot adding an /compiled folder to my .gitignore, so now everything in there shows up as modified with git status
just want to figure out if git add and git commit will ignore it, or if I need to reset those modified files first
Try searching online for "git untrack directory" or something like that. Plenty of answers on StackOverflow and similar websites or blogs.
some time ago I ran across a snippet that somehow called stest/instrument
automatically whenever any var was (re)defined. But I can't find it now; does anybody know how they might've done it? Some kind of watch?
(I didn't post in #clojure-spec because I think it's only tangentially related— I believe the key here is watching vars.)
presumably used http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/add-watch
we have full search in the slack at the moment, I bet you can find it...
it was on the web, and I've tried every search variation I can think of without success. The part I can't figure out is that it worked on all vars, and didn't require manually creating a watch for each one
no - vars are held in each namespace
no, don't know of any single thing that does that, although the pieces to build it exist
https://clojure.github.io/spec.alpha/clojure.spec.test.alpha-api.html#clojure.spec.test.alpha/instrumentable-syms and add-watch seem like they get you most of the way there ?
A good way to accomplish this is:
(clojure.tools.namespace.repl/refresh :after `stest/instrument)
if i run that from inside emacs with cider i'm told it can't find clojure.tools.namespace.repl class. I can't require it either. hm
Is there a library anywhere of transducer functions over and above those provided by clojure.core
? I have a couple of custom partition functions I’ve used in situations where partition-by
doesn’t quite do what I need, but now find myself needing transducer versions of them. Before I create transducer versions of them myself, it would be good to see if there’s a well-supported option that I can use?
Or alternatively if there’s some way to get equivalent functionality with clojure.core
that I’m missing?
Specifically the functionality I need is:
(defn partition-with
"Partitions a sequence whenever pred returns true"
[pred? coll]
...)
(defn partition-when
"Pass sequential pairs of values to comp? and partition the collection whenever it returns true (splitting the pair)"
[comp? coll]
Thanks - I'll check it out 👍
I'm missing something, clearly, as I'm I sure how I can get the same functionality from partition-by?
user=> (into []
(comp (map biginteger)
(partition-by #(.isProbablePrime % Integer/MAX_VALUE))
(partition-all 2)
(map (partial apply concat)))
(range 20))
[(0 1 2 3) (4 5) (6 7) (8 9 10 11) (12 13) (14 15 16 17) (18 19)]
user=>
Ah! Of course. Thank you.
I’ll have to see if I can come up with a similar replacement for partition-with
.
Thanks again!
The thing with partition-when
is that it deals with delimiters and you then have a lot of choices: should delimiters be returned? (and if yes how? As single items? Sequence? Appended to the previous partition? Prepended to the next partition?) How delimiters runs are treated?
So either a single function with an options map or many functions. Or you find a way to compose it out of other fns.
our production jar is AOT compiled for startup speed. When i start the jar with a socket repl, I can successfully evaluate things but it seems that I cannot replace vars. I suspect this is because the classfiles are on the classpath. Is it possible to get an AOT jar back into a more dynamic environment, able to redefine vars and functions in the repl?
@dpsutton you should be able to "replace" vars, but perhaps you compiled with direct linking, which goes against that
(b/compile-clj {:basis basis
:src-dirs paths
:class-dir class-dir
:ns-compile ns-decls})
i don't see that set in this call. Would that property exist in the jar? Or would that only be relevant in the jvm that created the jar?functions called by api handlers. So I would expect that these can be replaced at runtime with the jar but it does not seem to be happening
like once the var has been derefed and that value is being passed around, redefing the var won't do anything
the class files on the classpath could only possible effect looking for classes, but if you are evaling things in the repl, you can get brand new classes
the possible explanations are really: 1, direct linking 2. taking the value of the var once and using that value without ever checking the var again 3. you aren't defing what you think you are defining
MB_JETTY_PORT=3006 java -Dclojure.server.repl="{:port 50506 :accept clojure.core.server/repl}" -jar ~/projects/work/jars/0.41.2.jar
vs clj -M:dev:...:reveal
etc
thanks @hiredman and @borkdude. That's what I was worried about. I'll keep looking then
i'm glad to know that my expectation is correct and the AOT nature isn't the culprit
things could get weird if what you are evaluating don't just set the value of vars, but generate named classes, like deftype, defrecord, or defprotocol
ah, i've realized what it is. I'm used to changing source and (require ns :reload)
and forgot that this doesn't work like this here. I've been reloading the namespaces. The thing that mislead me so much was that i would log to the repl and interact but forgot to individually evaluate forms rather than work on the namespace