This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2020-04-29
Channels
- # announcements (35)
- # aws (40)
- # babashka (10)
- # beginners (119)
- # calva (25)
- # cider (13)
- # clj-kondo (15)
- # cljsrn (23)
- # clojure (205)
- # clojure-dev (3)
- # clojure-europe (15)
- # clojure-germany (3)
- # clojure-italy (3)
- # clojure-nl (2)
- # clojure-uk (58)
- # clojurescript (193)
- # community-development (2)
- # conjure (147)
- # core-async (49)
- # cursive (47)
- # datomic (27)
- # duct (1)
- # fulcro (19)
- # graalvm (3)
- # graphql (1)
- # helix (3)
- # hoplon (11)
- # jackdaw (1)
- # joker (1)
- # juxt (5)
- # kaocha (1)
- # keechma (3)
- # lambdaisland (6)
- # local-first-clojure (27)
- # malli (5)
- # off-topic (41)
- # rdf (27)
- # re-frame (7)
- # reagent (15)
- # reitit (5)
- # rum (11)
- # shadow-cljs (157)
- # spacemacs (18)
- # sql (4)
- # xtdb (8)
Heavy numerical computation in Clojure isn't likely to give you the best performance vs. using other techniques. Is your goal for learning Clojure as an exercise, or for getting a high performance gradient descent implementation?
Is there a version of reduce
that returns a reduced value when early terminated? (Helpful to terminate outer reduction when inner gets terminated early)
You can check this out https://clojuredocs.org/clojure.core/reduced Might be helpful
Yup. Double reduced
is what I've been doing. I don't need it at the moment but was wondering what happens in cases where we have nested reductions to arbitrary depths that aren't known beforehand. Just wondering if there's some mechanism that satisfies that.
If you wanna see it in the wild here it is https://github.com/clojure/tools.analyzer/blob/d2c268a616d63b813be13fbfe1e786e41577b891/src/main/clojure/clojure/tools/analyzer/ast.clj#L53
Did I understand correctly that you'd like to have concentric calls to reduce
and be able to let program logic decide which of the reduce
calls you'd like to escape from? If so, you can do something like what's https://clojurians.slack.com/archives/C053AK3F9/p1588145809461400:
The solution let's try/catch/throw return to any pre-selected place up the calling stack. Unfortunately the implementation as shown (at the time of this posting) is inefficient because it collects information sufficient to generate a stacktrace later. The corresponding Scala implementation prevents this stacktrace generation step, but I don't know yet how to do that in clojure. I'm pretty sure it's possible.
There is a JVM flag that enables fast throw for repeated exceptions. Don't know how to do that programmatically.
Can someone help me translate a piece of code from Scala to Clojure? The Scala code works because within the scope of the function I declare a new class of exception, and then I use a try/catch which catches ONLY that class of exception. This makes the code reentrant. I.e. I can next calls to block
any inner try/catch accidentally catching exceptions thrown to an outer try/catch. Plus, I use a particular extension of Exception
which prevents stacktrace information from being computed, so that it is efficient, plus no actual exception gets generated unless it is actually being thrown.
def block[A](body:(A=>Nothing)=>A):A = {
// CL like block/return, the name of the return() function is provided
// by the caller.
// Usage: block{ ret => ... ret(someValue) ...}
// extending Exception with NoStackTrace prevents throwing the
// exception from computing the stacktrace and storing the information.
// We don't need a stacktrace because the purpose of this exception
// is simply to perform a non-local exit.
import scala.util.control.NoStackTrace
class NonLocalExit(val data:A) extends Exception with NoStackTrace {}
def ret(data:A):Nothing = {
throw new NonLocalExit(data)
}
try{
body(ret)
}
catch{
case nonLocalExit: NonLocalExit => nonLocalExit.data
}
}
In Clojure, i'd like something I can call as follows.
(call-with-return (fn [ret] ... (ret 42) ...))
in which case block
would return 42.Here is my attempt, although I don't know how to suppress the stacktrace.
(defn call-with-return [unary]
(letfn [(ret [v]
(throw (ex-info "" {:data v
:ident ret})))]
(try (unary ret)
(catch clojure.lang.ExceptionInfo e
(if (= ret (:ident (ex-data e)))
(:data (ex-data e))
(throw e))))))
I do not know how to call it from Clojure yet, but there is a constructor for the Throwable
class that lets you create an exception object that has no stack trace: https://docs.oracle.com/javase/8/docs/api/java/lang/Throwable.html#Throwable-java.lang.String-java.lang.Throwable-boolean-boolean-
and the documentation mentions this, which sounds similar to your desired use case: "Circumstances where a given exception object is repeatedly caught and rethrown, such as to implement control flow between two sub-systems, is another situation where immutable throwable objects would be appropriate."
@U0CMVHBL2 thanks, that's exciting to find. can you remind me of the clojure idiom for instantiating such a java object? What do I have to add to my namespace :require, and what does the clojure call to instantiate such an object with writableStackTrace set to false?
One issue is that it is declared protected
in Java, which means that one can only call that method from that class, or a subclass of it. Probably the only way to do that is to write a bit of Java code that defines such a subclass, but in turn makes a public constructor available that creates the no-stacktrace exception.
ahh, it sounds like perhaps I need to request an enhancement to ex-info
to allow setting writableStackTrace
to false?
No need to make a such a request -- you can write such a Java class yourself.
I doubt such a request would result in any change to Clojure's core code.
because it is straightforward for anyone else to write such a class themselves
I was hoping to finish my career as a software developer without ever having to write a single line of java code.
I say "straightforward" not to mean "easy for everyone", but "easy for a person with the right Java knowledge, and enough time"
I wonder whether its possible for me to write it in Scala, and call that function from clojure?
That would likely require enough knowledge of how Scala code compiles to JVM classes, that it would likely be easier to write it in Java unless you were already knowledgeable about that aspect of Scala.
the scala code is pretty short
trait NoStackTrace extends Throwable {
override def fillInStackTrace(): Throwable =
if (NoStackTrace.noSuppression) super.fillInStackTrace()
else this
}
object NoStackTrace {
final def noSuppression = _noSuppression
// two-stage init to make checkinit happy, since sys.SystemProperties.noTraceSuppression.value calls back into NoStackTrace.noSuppression
final private var _noSuppression = false
_noSuppression = sys.SystemProperties.noTraceSuppression.value
}
I mean, I think we are talking basically a Java source file that starts with something close to "class MyExceptionClass extends RuntimeException ..." similar to how this class is declared inside of the Clojure implementation: https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/ExceptionInfo.java#L18
I think the only relavent part is the trait definition which extends Throwable
and overrides the fillInStackTrace
method. Can't I do the same thing in clojure?
If there is a way, I am not familiar with it, but I am not omniscient about Clojure. There is a general practice in Clojure that it does not attempt to give you all of the options of constructing Java classes that Java does, since Java exists and can still be used.
I'm not even sure it is possible to create a class that is a direct subclass of a Java class, in Clojure, which is something that is easy to do in Java, but if I am right about that, Rich Hickey saw no stong enough desire to include such a capability in Clojure -- just write the Java class you want in Java if you need that.
I don't even know how expensive the call to fillInStackTrace
is, whether it is important to attempt to circumvent. However, the existence of the Scala trait and also the constructor options on the java Throwable
class lead me to believe it is desirable to avoid.
It certainly seems to enable the possibility of somewhat better performance, but devising control flow that doesn't use exceptions at all is probably better performance still, if there is a way.
I'm glad I looked into this. It turns out my Scala implementation is wrong. The class declared within the function definitions is not a different class than in a recursive call to the function. That's a bizarre gotcha.
that's the same as would happen in java or clojure - inner classes are defined once when you compile the body that creates them
for example every function (partial f x)
has the same class (implementation wise you get a different class for each arity, since partial has a different code body per arity up to a certain count)
Yes I see that now. However, it is not obvious. For example, functions within functions are different on recursive calls. For example in clojure if you have a (defn f1 [f3] (letfn [(f2 [...] ...)] (f1 f2))
, inside the recursive call, f2
is not equal to f3
.
I am using clojure.test to implement test cases for my clojure project. This works fine. Some of the tests implement some primitive random value selection, which I've implemented myself based on the rand-nth
function. 99% of the time the tests pass correctly. However, occasionally they seem to get caught in an infinite loop. Maybe i'm mistaken, maybe its just very slow in some cases. I run the tests using "lein test" as part of my gitLab CI pipeline. so when the infinite loop occurs, I have no way of debugging it.
Is there a way to tell lein to "time-out", and in doing so generate a stacktrace so I can investigate what it's doing at the time it was interrupted?
It is indeed likely that my code (not my testing infrastructure) has some cases of infinite loops. As I have several functions distributed about the code which are mutually recursive, walking through some large tree-like data structures, applying rules to try to do sort of simplifying-reductions. There may indeed be cases where they reduction does not converge, and I'd love to find such a case.
However, it might be that my randomizer just has a very small percent change of generating HUGE trees which take the hours rather than seconds to manipulate.
If you wanted to take a huge hammer to it you could do something like:
(deftest random-thing
(let [orig-rand sut/my-random-func
called-count (atom 0)
new-rand (fn [& args]
(when (<= 10000 (swap! called-count inc))
(throw (Exception. "You done gone too far"))
(apply orig-rand args))]
(with-redefs [sut/my-random-func new-rand]
(sut/the-thing-being-tested)
or you could run the actual test in an executor and have a check in the main thread to see if the test is spinning
Calling jstack
on the pid of the jvm will dump the stacktraces of all threads @jimka.issy
is java.lang.Object
the root of all class hierarchies which are instantiatable in Java? I ask this because I believe (but am not sure) that any given any interface, if an instance x is an instance of the interface then it is also an instance of java.lang.Object
... Is that true, or is there a counter example?
Object is the base super class of all objects
Hello everyone,
Iâm working through a basic re-frame example following the intro guide. I have a very simple dispatch-sync [:initialize]
call and a simple event handler:
(rf/reg-event-db
:initialize
(fn [_ _]
{:message "I'm initialized!"}))
However, Iâm getting this error in my console:
core.cljs:3912 re-frame: no :event handler registered for: :initialize
eval @ core.cljs:3912
eval @ core.cljs:3907
eval @ core.cljs:3901
eval @ core.cljs:3895
eval @ core.cljs:3889
eval @ core.cljs:3924
eval @ loggers.cljc:40
eval @ registrar.cljc:31
re_frame$events$handle @ events.cljc:57
re_frame$router$dispatch_sync @ router.cljc:265
alpha_journal$core$main @ core.cljs:24
eval @ shadow.module.main.append.js:4
goog.globalEval @ main.js:836
env.evalLoad @ main.js:2224
(anonymous) @ main.js:2429
This is my core.cljs (entry file):
(ns alpha-journal.core
(:require
[reagent.core :as r]
[reagent.dom :as dom]
[re-frame.core :as rf]
[alpha-journal.views :refer [app]]))
(defn render
[]
(dom/render [app]
(js/document.getElementById "app")))
(defn ^:dev/after-load clear-cache-and-render!
[]
;; The `:dev/after-load` metadata causes this function to be called
;; after shadow-cljs hot-reloads code. We force a UI update by clearing
;; the Reframe subscription cache.
(rf/clear-subscription-cache!)
(render))
(defn main
[]
(rf/dispatch-sync [:initialize])
(render))
This is my events.cljs:
(ns alpha-journal.events
(:require
[re-frame.core :as rf]))
(rf/reg-event-db
:initialize
(fn [_ _]
{:message "I'm initialized!"}))
Currently Iâm not subscribing anywhere as I just wanted to inspect the app db in REPL. Does this possibly cause the error? Any thoughts are much appreciated đ thanksHi @pattruong, you probably just need to require your alpha-journal.events
ns in your alpha-journal.core
to be sure it loads/registers your event handlers before main
runs.
Also, thereâs a #re-frame channel available if youâd like to post re-frame questions there. Itâs not wrong to post them here, but you might find more people there who can answer your re-frame questions.
@manutter51 thanks! That solved it! Iâll check out that channel also đ
Iâm having issues with cli-tools
0.10.82
, whereas 0.10.81
has no problems:
probe-design-app git:(master) â datomic help
Error building classpath. Could not find artifact com.datomic:tools.ops:jar:0.10.82 in central ( )
does .read
not do this?
but stdin is kind of special, in that it is usually bound to some kind of terminal emulator, and the default mode those operate in is not sending data until there is a newline
so if you want to read character by character input from stdin you need to use some library that can put the terminal in such a moe to make that happen
iâve recently been using lanterna, but that may be overkill for your use case
it even has mouse support! (which i didnât know existed as possibility)
I was just going to give lanterna as an example, but I haven't really used it all that much
Sorry I missed the discussion. I am reading well defined input where the first line gives the content length. So I ended up using Reader.read(CharBuffer).
I'm doing a small little web app using ring/compojure/hiccup and I wanted to use something "easy" like Bulma for just a minimal css styling of it.
I put this little starter template: https://bulma.io/documentation/overview/start/ as an index.html file in my resources folder. But when I start the app (using lein run 8000
) I don't see the styling applied to the html I've used so far.
So I have the :body
key in the handler functions right. How do I actually use hiccup html with css styling like Bulma in what I put in those functions.
(defn hola [req]
(let [name (get-in req [:route-params :name])]
{:status 200
:body (str "Hola, " name "!")
:headers {}}))
@U9J50BY4C here's how I do it in my pet project (I am also just a beginner):
(defn page [& contents]
[:html
[:head
[:meta {:charset "UTF-8"}]
[:meta {:name "viewport" :content "width=device-width, initial-scale=1.0"}]
[:link {:rel "stylesheet" :href "" :integrity "sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" :crossorigin "anonymous"}]
[:style "
body { padding: 3em; }
"]]
[:body
contents]])
(defn respond-with-page [& contents]
(-> (apply page contents)
hiccup.page/html5
resp/response
(resp/content-type "text/html")))
Then I'd put in your case:
(defn hola [req]
(let [name (get-in req [:route-params :name])]
(respond-with-page (str "Hola, " name "!"))))
(I use Bootstrap CSS, but the idea is the same)
I also require this:
[ring.util.response :as resp]
[hiccup.page]
Not much right now, mostly from the example project I started with. I don't really need these files, so empty is just fine in your case, I guess. To be fair, I didn't get to the part where I have images or other static resources on my website, just plain html/css for now đ Most likely in the future some files will need to be served from the resources folder.
Ok, awesome. Thank you. Yeah right now I want to do the same with just html/css and keep it all text.
Hi, what is the simplest most easy to start IDE for Clojure? I want to collaborate on a project with a non-technical person and I want something they can install easily. I only need rainbow coloring and some editor help (structural editing, parinfer). I don't care about REPL or build tools integreation, we are mostly going to edit hiccup together.
@pavel.klavik, I second @dpsutton there: VS Code with Calva, but I am biased since I am making Calva đ . Calva has all things you mention there, except parinfer. There is a separate extansion for that, but if you use that you will need to disable Calva's formatter. I would skip parinfer and just teach the basics of Paredit: https://calva.io/paredit/
ok, will take a look đ probably just some basic's of paredit would be enough
As a beginner, I strongly recommend parinfer instead of paredit.
If you are on a Mac, also see this: https://calva.io/quirks/#macos-and-the-slurp-and-barf-keyboard-shortcuts
probably just the default setting is good enough for our need
I find that these indent guides help with hiccup a lot: https://clojurians.slack.com/archives/CBE668G4R/p1587812330385900
Can I get the same code formatting as the default Cursive?
Basically I would like to change this: Use a single space indentation for function (macro) arguments when there are no arguments on the same line as the function name.
(filter
even?
(range 1 10))
to have two spaces instead of a single one
Calva uses cljfmt
for the formatting, which can be configured quite a bit. https://calva.io/formatting/
I do think that Cursive and Calva has the same defaults though. https://cursive-ide.com/userguide/formatting.html
I don't think I did any changes in my Cursive config. In Cursive, this is formatted as follows:
(list
:a
:b)
In Calva default, I get this
(list
:a
:b)
Sorry, the latter is the same, I get this
(list
:a
:b)
It sounds a bit strange that it would not by default be following the Community Style Guide, though.
There seems to be this setting, but I don't think I turned that off:
Overall, I think the general idea behind white space formatting is completely silly and does not fit well with Clojure since code are data structure and white spaces are irrelevant. In an ideal world, we would store source code in this way, have Git working in this way (diffing data structures) and everyone could set any formatting they like within their editor.
The small web app I am building is going to be mostly just text information for now. I do not want to try to learn databases quite yet so was hoping to have all this information in something like an edn file or something.
It's a website to help people become online English teachers. So there will be a webpage for each company with title, info, application requirements, etc.
Can I just write that information as a Clojure map in a file and access that through my handler functions? Does that make sense?
Like a poor man's db I think. What do people use for such things when they don't want a real database?
Eventually I will want to add interactive functionality so that they can put in various filters and then it will return those companies that match it. If I go with this Clojure map as a db thing, do you think it is scalable for such functionality later down the line?
I found edn serialization/deserialization really crappy for multiple reasons, but nippy works perfectly for me for similar things to what you mention. Itâs a binary format, so you kind of lose human-readability of the text file, but it preserves all Clojure data types.
As easy as n/freeze-to-file -> n/thaw-from-file
And I will be able to use such functionality in my hiccup style functions you helped me with earlier? So in the [:body contents] part, for example, I could use that n/thaw-from-file to grab the text/info?
Yeah. Probably, youâd want to read the file contents and extract pieces of information from the map separately in a (let [...]) first, and then put those pieces into your hiccup markup.
Yeah, that sounds smart. Awesome, I'll start wrapping my head around this over the next few days.
Anyone knows how to get a repl which isn't hanging using Cursive and a freshly started luminus project ?
Using:
IntelliJ 2019.3 (2020 seems to have issues with Cursive)
Cursive 1.9.1-2019.3
Luminus project lein new luminus lumirest +postgres +service +http-kit
Hm. Seems like only a local repl works.
If I start lein run
(whether from terminal or a separate run configuration) then no matter how I configure a remote clojure repl, it either fails outright (remote, socket repl) or hangs infinitely (nRepl).
@U012RBT15D3 Probably best to ask in #cursive I think.
Hello everyone, Iâm currently setting up re-frame-10x with a very reagent/re-frame basic project that is using shadow-cljs only. I got the go-ahead from Thomas Heller that my config looks good, but we could be overlooking something. Iâm not sure why, but my app-db only shows up correctly in the dashboard when I hot reload my app (change a view file for example). Anyone who got a shadow-cljs app working with re-frame-10x, I would love to hear if you had to do anything special. Hereâs my shadow-cljs.edn:
{:deps true
:builds {:app {:target :browser
:output-dir "public/out"
:asset-path "/out"
:modules {:main {:init-fn alpha-journal.core/main}}
:compiler-options {:closure-warnings {:global-this :off}
:closure-defines {"goog.DEBUG" true
"re_frame.trace.trace_enabled_QMARK_" true
"_frame.tracing.trace_enabled_QMARK_" true}
:optimizations :whitespace}
:devtools {:http-root "public"
:http-port 8020
:after-load alpha-journal.core/render
:preloads [devtools.preload
day8.re-frame-10x.preload]}}}}
My deps.edn:
{:paths ["src"]
:deps {thheller/shadow-cljs {:mvn/version "2.8.94"}
binaryage/devtools {:mvn/version "1.0.0"}
cider/cider-nrepl {:mvn/version "0.25.0-alpha1"}
reagent {:mvn/version "0.10.0"}
re-frame {:mvn/version "0.12.0"}
day8.re-frame/tracing {:mvn/version "0.5.3"}
day8.re-frame/tracing-stubs {:mvn/version "0.5.3"}
day8.re-frame/re-frame-10x {:mvn/version "0.6.2"}}}
and my basic app file, core.cljs:
(ns alpha-journal.core
(:require
[reagent.dom :as dom]
[re-frame.core :as rf]
[alpha-journal.events]
[alpha-journal.views :refer [app]]))
(defn render
[]
(dom/render [app]
(js/document.getElementById "app")))
(defn main
[]
(rf/dispatch-sync [:initialize])
(render))
Looking to hear possible issues with my setup. Thanks for the help!