This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2020-08-25
Channels
- # announcements (2)
- # babashka (35)
- # beginners (74)
- # calva (26)
- # cider (14)
- # clojure (74)
- # clojure-dev (27)
- # clojure-europe (9)
- # clojure-italy (2)
- # clojure-nl (2)
- # clojure-spec (10)
- # clojure-uk (9)
- # clojuredesign-podcast (6)
- # clojurescript (40)
- # data-science (1)
- # datalog (7)
- # events (1)
- # figwheel-main (13)
- # fulcro (11)
- # graalvm (58)
- # helix (4)
- # jobs (4)
- # jobs-discuss (9)
- # kaocha (23)
- # malli (5)
- # meander (112)
- # membrane (7)
- # off-topic (13)
- # pedestal (2)
- # re-frame (4)
- # reitit (1)
- # rewrite-clj (1)
- # rum (2)
- # sci (3)
- # shadow-cljs (79)
- # sql (12)
- # tools-deps (17)
- # vim (15)
- # vrac (11)
- # xtdb (6)
I vaguely recall a Clojure socket/prepl client written in Clojure. But now I can't find it! Does anyone know the project I'm referring to?
Propel maybe? https://github.com/Olical/propel
I wrote this a while ago after banging my head against the wall trying to figure out the whole prepl thing: https://gist.github.com/eerohele/e06551b115c6a31d1280a115c4c2abb2 But you might be looking for something more complete.
(Note that I don’t fully know what I’m doing there — some examples I found use PipedInputStream
and PipedOutputStream
instead of PipedWriter
and PipedReader
. I’m not sure how much of a difference that makes. I just wanted to come up with the simplest possible thing that works.)
Right, now I remember — if you use streams, you have to turn them into readers/writers anyway. So I figured I could just straight up use PipedReader
instead of (io/reader (PipedInputstream.))
etc.
@U09LZR36F maybe this is useful https://github.com/jeroenvandijk/clojure-scripting/blob/master/client/src/clojure/scripting/client.clj It’s a simple prepl client
I've got a thing with a mini query language which looks like ".resistors.0.value>470" and I want to generate a callable predicate (an Ifn
, I suppose) from it at run time - for example (fn [rec] (> (get-in rec [:resistors 0 :value]) 470)
. I'm OK with the parsing (and sanitizing) part but how do I make a function - is eval
the best option? Is it safe?
Otherwise you’re building an interpreter
Thanks both. I tried reify and got as far as
(*defn* maker [op path val]
`(case op`
`:lt (reify clojure.lang.IFn (invoke [this rec] (< (get-in path rec 0) val)))`
`:gt (reify clojure.lang.IFn (invoke [this rec] (> (get-in path rec 0) val)))`
`:eq (reify clojure.lang.IFn (invoke [this rec] (= (get-in path rec 0) val)))))`
but seemed to be 'swimming against the tide' somewhat
defmacro
would easily DRY that code up. Alex's feedback is interesting though, OTOH I'm not sure what to make of it (compiler vs. interpreter might be perceived as merely semantics; whereas eval
has practical nuances and risks)
It’s not just semantics - it has big performance impacts here. Peter said earlier that he was ok with sanitizing, so I assumed those risks are being managed
If not, something like clojail is designed for this
The whole idea of lisp is that we can build programs as data and eval them
Interesting. I think I had "don't use eval" in my head from Javascript - but in JS I'd be building a string to eval, which is not as neat as Clojure/LISP's symbolic way of working.
using eval is fine. using eval on arbitrary data provided by a user is dangerous, so that's the place to act carefully
if you are doing any read
type operation, I would either prefer clojure.edn/read-string or bind *read-eval*
to false around the read to disable read-eval and arbitrary java object construction
What's wrong with this simple approach?
(def ops
{:lt <
:gt >
:eq =})
(defn maker [op path val]
(fn [rec] ((get ops op) (get-in rec path) val)))
(comment
((maker :gt [:resistors 0 :value] 470)
{:resistors [{:value 480}]}))
@U7KD4HQ1W btw. in your maker
implementation you have incorrect order of args passed to get-inI can't see why it wouldn't work. I believe that approach would be 'building an interpreter' as described by Alex above.
Re. get-in - I ought to have it tattoo'd on my knuckles, I just can't get the correct order to stick in my mind! 🙃
Hi! I' working with clojure.data.xml to parse a xml file. The xml elements all have an xml:id attached. How to get the value of the attribute? #:xmlns.http%3A%2F%http://2Fwww.w3.org%2FXML%2F1998%2Fnamespace{:id "3"} Thanks.
https://github.com/clojure/data.xml/blob/master/src/main/clojure/clojure/data/xml.clj#L111-L130
check option available for parse-str function.
:namespace-aware false
could help
Thanks, but accordingly to the javadocs, the property "javax.xml.stream.isNamespaceAware" has True as a default value. Which means, it should work without setting it.
true as a default option force parser to include namespaces into tag itself.
(parse-str "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
<foo:html xmlns:foo=\"\"/>")
;; => #xml/element{:tag :xmlns.http%3A%2F%2Fwww.w3.org%2F1999%2Fxhtml/html}
(parse-str "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
<foo:html xmlns:foo=\"\"/>" :namespace-aware false)
;; => #xml/element{:tag :foo:html, :attrs #:xmlns.http%3A%2F%2Fwww.w3.org%2F2000%2Fxmlns%2F{:foo ""}}
try to parse xml with :namespace-aware false
Great. Now it works. Thanks alot!
Given a :foo/bar
spec in my-lib
, a :foo/bar
spec in my-service
, and my-service
has my-lib
as a dependency, will the my-service
:foo/bar
spec always shadow the my-lib
:foo/bar
spec?
which is why you should use sufficiently unique namespaces to avoid collisions
multi-methods can not be spec'd ala fdef, correct?
just making sure, as I was reading about multi-spec (implemented with multi-methods in the example) and got a little confused
Hi people, I’m in a process to convince an old dinosaur about the benefits of Clojure and Datomic. This person has a lot of scars about how to scale monolithic systems using C# and SQL Server, and when I showed Clojure and Datomic he expressed the feeling that he was suffering without knowing the cause. I want to present to him at least the three best talks from Rich Hickey, that conveys the philosophic view of why Clojure is the best way to build situated programs or more generally, situated systems.
Personal OPINION: • https://www.youtube.com/watch?v=CX13jZtV-xs • https://www.youtube.com/watch?v=-6BsiVyC1kM • https://www.youtube.com/watch?v=D6nYfttnVco
if he would prefer a written form, the HOPL paper is really good, https://download.clojure.org/papers/clojure-hopl-iv-final.pdf
Transcripts of Rich's talks: https://github.com/matthiasn/talk-transcripts/tree/master/Hickey_Rich
Ah, looks like the last time I scrubbed the list of Rich Hickey videos against the already-published transcripts, I noticed "Database as a Value" is not transcribed yet: https://github.com/matthiasn/talk-transcripts/issues/96. Good, I'm not losing my mind completely 🙂
Is there some library which provide enums for clojure?
Hi all! Is it possible to exclude a namespace from :aot
? Basically, one of our namespaces as a def
which creates an object that spawns some threads. During aot (we believe), this def
is called and as a result, lein uberjar
hangs (since it’s waiting on the threads). So, the idea is that if we can skip this namespace during :aot
then we can avoid the issue. What are some other approaches to a problem such as this?
leiningen allows you to specify :aot
using a vector or a regex. you can either manually specify the namespaces in a vector or it might be easier to generate a regex that matches anything except the offending namespace
better would be to wrap that def in a delay and then deref when you use it
as a general rule, you should never have top-level def's that eagerly side effect on load
Right, that makes sense. So, we went with the delay
and it works great! Thank you!
Out of curiosity, how can we achieve this without a top level def and no delay
?
what are you trying to achieve?
based on your description, it seems like the spawning of threads should be kicked off from your app's main function
or if it's a library, it should probably be an function the user can call in their main to initialize the threads
The issue with the introduction of the delay is that after the delay is deref-ed, we get an NPE because the threads have yet to be spawned. If we add the object creation to main
then the issue is that we need to access the object in another namespace and this creates a circular dependency problem.
what if you make an init!
function that spawns the threads and call that from main
?
you may also benefit from something like https://github.com/stuartsierra/component
if you require things to be initialized at startup, then initialize them at startup :)
even better, hand them to the things that need them, rather than storing them in defs
component is one of many tools that can help you do this, but that's the important thing
So, we decided to initialize at startup and this solves the issue. I’ll check out component
. Looks really cool!