Fork me on GitHub
#beginners
<
2020-04-29
>
Steiner02:04:59

anyone know how to write gradient descent in clojure?

andy.fingerhut03:04:10

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?

jaihindhreddy04:04:30

Is there a version of reduce that returns a reduced value when early terminated? (Helpful to terminate outer reduction when inner gets terminated early)

g7s05:04:17

Double reduced I guess?

👍 4
jaihindhreddy05:04:35

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.

g7s05:04:28

Nice. Yeah I think I have used it only once..

Jim Newton08:04:24

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:

Jim Newton08:04:44

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.

4
hindol08:04:17

There is a JVM flag that enables fast throw for repeated exceptions. Don't know how to do that programmatically.

Jim Newton07:04:49

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.

Jim Newton07:04:12

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
    }
  }

Jim Newton07:04:44

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.

Jim Newton07:04:50

Here is my attempt, although I don't know how to suppress the stacktrace.

Jim Newton07:04:06

(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))))))

andy.fingerhut08:04:00

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-

andy.fingerhut08:04:42

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."

Jim Newton08:04:18

@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?

andy.fingerhut08:04:47

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.

Jim Newton08:04:57

ahh, it sounds like perhaps I need to request an enhancement to ex-info to allow setting writableStackTrace to false?

andy.fingerhut08:04:51

No need to make a such a request -- you can write such a Java class yourself.

andy.fingerhut08:04:08

I doubt such a request would result in any change to Clojure's core code.

andy.fingerhut08:04:31

because it is straightforward for anyone else to write such a class themselves

Jim Newton08:04:14

I was hoping to finish my career as a software developer without ever having to write a single line of java code.

andy.fingerhut08:04:34

I say "straightforward" not to mean "easy for everyone", but "easy for a person with the right Java knowledge, and enough time"

Jim Newton08:04:11

I wonder whether its possible for me to write it in Scala, and call that function from clojure?

andy.fingerhut08:04:42

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.

Jim Newton09:04:02

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
}

andy.fingerhut09:04:25

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

Jim Newton09:04:33

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?

andy.fingerhut09:04:20

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.

andy.fingerhut09:04:42

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.

Jim Newton09:04:23

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.

andy.fingerhut10:04:18

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.

Jim Newton15:04:39

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.

noisesmith15:04:57

that's the same as would happen in java or clojure - inner classes are defined once when you compile the body that creates them

noisesmith15:04:44

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)

Jim Newton16:04:39

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.

Jim Newton11:04:58

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?

Jim Newton11:04:42

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.

Jim Newton11:04:15

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.

Darin Douglass13:04:15

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)

Darin Douglass13:04:35

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

ghadi13:04:14

Calling jstack on the pid of the jvm will dump the stacktraces of all threads @jimka.issy

Jim Newton15:04:52

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?

Alex Miller (Clojure team)15:04:03

Object is the base super class of all objects

Patrick Truong17:04:38

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 🙂 thanks

manutter5117:04:38

Hi @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.

😀 4
manutter5117:04:13

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.

Patrick Truong17:04:06

@manutter51 thanks! That solved it! I’ll check out that channel also 🙂

👍 4
lostineverland17:04:24

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 ()

hindol20:04:38

Hi, what is the way to read from stdin without waiting for newline?

phronmophobic20:04:03

does .read not do this?

hiredman20:04:13

I mean, it does

hiredman20:04:24

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

hiredman20:04:33

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

hiredman20:04:42

those tend to be something ncurses like or based on

phronmophobic20:04:05

i’ve recently been using lanterna, but that may be overkill for your use case

phronmophobic20:04:22

it even has mouse support! (which i didn’t know existed as possibility)

hiredman20:04:43

I was just going to give lanterna as an example, but I haven't really used it all that much

hindol20:04:05

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).

Chase20:04:38

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.

Chase20:04:48

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.

Chase20:04:51

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.

Chase20:04:17

(defn hola [req]                                                           
  (let [name (get-in req [:route-params :name])]                           
    {:status 200                                                           
     :body (str "Hola, " name "!")                                         
     :headers {}}))

Chase20:04:37

So if I want this page to actually have css stying how do I do that?

Chase20:04:40

I hope that makes sense.

Timur Latypoff20:04:21

@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 "!"))))

Timur Latypoff20:04:45

(I use Bootstrap CSS, but the idea is the same)

Timur Latypoff20:04:36

I also require this:

[ring.util.response :as resp]
[hiccup.page]

Chase20:04:00

Ahh! I think this is exactly what I am looking for. Thank you!

👍 4
Chase20:04:14

And what do you have in your resources folder? Anything or can that just be empty?

Timur Latypoff20:04:39

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.

Chase20:04:33

Ok, awesome. Thank you. Yeah right now I want to do the same with just html/css and keep it all text.

👍 4
Pavel KlavĂ­k20:04:57

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.

dpsutton20:04:37

most likely vs code?

pez20:04:27

@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/

calva 8
dpsutton20:04:59

ease of use, size, install manner, and UI all point towards vs code for sure

Pavel KlavĂ­k20:04:33

ok, will take a look 🙂 probably just some basic's of paredit would be enough

calva 4
Timur Latypoff20:04:42

As a beginner, I strongly recommend parinfer instead of paredit.

Pavel KlavĂ­k20:04:30

ok, got it running, it was quite easy, thx

metal 4
pez20:04:30

Also please feel welcome to ask for help in #calva .

Pavel KlavĂ­k20:04:45

probably just the default setting is good enough for our need

pez20:04:10

We have tried to make it with sane defaults and want it to be easy to get going.

pez20:04:55

I find that these indent guides help with hiccup a lot: https://clojurians.slack.com/archives/CBE668G4R/p1587812330385900

Pavel KlavĂ­k21:04:41

Can I get the same code formatting as the default Cursive?

Pavel KlavĂ­k21:04:55

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))

Pavel KlavĂ­k21:04:01

to have two spaces instead of a single one

pez21:04:01

Calva uses cljfmt for the formatting, which can be configured quite a bit. https://calva.io/formatting/

pez23:04:01

I do think that Cursive and Calva has the same defaults though. https://cursive-ide.com/userguide/formatting.html

Pavel KlavĂ­k16:04:34

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)

Pavel KlavĂ­k16:04:14

Sorry, the latter is the same, I get this

(list
 :a
 :b)

pez16:04:56

Then the Cursive docs lie. 😃

pez16:04:45

It sounds a bit strange that it would not by default be following the Community Style Guide, though.

Pavel KlavĂ­k16:04:12

There seems to be this setting, but I don't think I turned that off:

Pavel KlavĂ­k16:04:51

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.

Chase20:04:40

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.

Chase20:04:15

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.

Chase20:04:43

Can I just write that information as a Clojure map in a file and access that through my handler functions? Does that make sense?

Chase21:04:04

Like a poor man's db I think. What do people use for such things when they don't want a real database?

Chase21:04:06

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?

Chase21:04:17

Sorry I can't form clearer thoughts on this

Timur Latypoff21:04:18

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.

Chase21:04:25

Ok, cool. I will bookmark and check this out.

👍 4
Timur Latypoff21:04:38

As easy as n/freeze-to-file -> n/thaw-from-file

Chase21:04:26

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?

Timur Latypoff21:04:52

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.

Chase21:04:33

Yeah, that sounds smart. Awesome, I'll start wrapping my head around this over the next few days.

👍 4
pseud21:04:35

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

pseud21:04:31

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).

seancorfield21:04:03

@U012RBT15D3 Probably best to ask in #cursive I think.

Patrick Truong22:04:31

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!