This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2021-03-02
Channels
- # announcements (9)
- # babashka (67)
- # beginners (62)
- # bitcoin (2)
- # clara (1)
- # clj-kondo (62)
- # cljfx (6)
- # cljs-dev (25)
- # clojars (17)
- # clojure (142)
- # clojure-australia (2)
- # clojure-europe (42)
- # clojure-gamedev (2)
- # clojure-nl (31)
- # clojure-poland (10)
- # clojure-spec (14)
- # clojure-uk (30)
- # clojurescript (3)
- # conjure (1)
- # cursive (10)
- # data-science (1)
- # datascript (4)
- # datomic (9)
- # depstar (7)
- # fulcro (17)
- # girouette (15)
- # graalvm (44)
- # honeysql (20)
- # jackdaw (3)
- # jobs (8)
- # jobs-discuss (10)
- # juxt (5)
- # lein-figwheel (1)
- # lsp (175)
- # malli (19)
- # pedestal (2)
- # reagent (31)
- # reitit (2)
- # remote-jobs (3)
- # reveal (12)
- # sci (77)
- # shadow-cljs (22)
- # specter (6)
- # startup-in-a-month (2)
- # tools-deps (1)
- # xtdb (21)
this.API = (WindowsNamedPipeLibrary) Native.loadLibrary("kernel32", WindowsNamedPipeLibrary.class, W32APIOptions.UNICODE_OPTIONS)
(defn get-API []
;this.API = (WindowsNamedPipeLibrary) Native.loadLibrary("kernel32", WindowsNamedPipeLibrary.class, W32APIOptions.UNICODE_OPTIONS)
(let [interface-class (.getClass osquery-clj.interfaces.IWindowsNamedPipeLibrary)
unicode-options (W32APIOptions/UNICODE_OPTIONS)
API ^osquery-clj.interfaces.IWindowsNamedPipeLibrary (Native/loadLibrary "kernel32" interface-class unicode-options)]
API))
what error are you getting?
For JNA, I've been using something like:
(def objlib (try
(com.sun.jna.NativeLibrary/getInstance "CoreFoundation")
(catch java.lang.UnsatisfiedLinkError e
nil)))
It looks like you can pass in an options map to this call too. Does this work for you?
(def api (try
(com.sun.jna.NativeLibrary/getInstance "kernel32" (W32APIOptions/UNICODE_OPTIONS))
(catch java.lang.UnsatisfiedLinkError e
nil)))
UNICODE_OPTIONS
is not a function so the parens look wrong around that.
that part works though
> (W32APIOptions/UNICODE_OPTIONS)
{"type-mapper" #object[com.sun.jna.win32.W32APITypeMapper 0x4a9f4493 "com.sun.jna.win32.W32APITypeMapper@4a9f4493"], "function-mapper" #object[com.sun.jna.win32.W32APIFunctionMapper 0x703d3680 "com.sun.jna.win32.W32APIFunctionMapper@703d3680"]}
¯\(ツ)/¯it also works without the parens :thinking_face:
Source https://github.com/java-native-access/jna/blob/master/src/com/sun/jna/win32/W32APIOptions.java so...
that block is from my repl, so I can confirm it works with and without parens
unless my repl is doing something goofy
I'm just kind of puzzled by a Java interface that seems to have data members...
My Java is rustier than I thought? 🙂
there's some odd things in JNA to make interop with c better
honestly, I'm not sure how all of it works
Apparently you can declare variables (data members) in an interface and they are treated as static final
. TIL.

I remember reading the code in Clojure compiler that would explicitly turn (MyClass/STATIC_FIELD)
into a regular static field lookup. Can't quickly find it right now though.
Perhaps it even worked that way for (.regularNotCallableField myObject)
...
(defn get-API []
;this.API = (WindowsNamedPipeLibrary) Native.loadLibrary("kernel32", WindowsNamedPipeLibrary.class, W32APIOptions.UNICODE_OPTIONS)
(let [interface-class osquery-clj.interfaces.IWindowsNamedPipeLibrary
unicode-options W32APIOptions/UNICODE_OPTIONS
API ^osquery-clj.interfaces.IWindowsNamedPipeLibrary (Native/loadLibrary "kernel32" interface-class unicode-options)]
API))
And as for WindowsNamedPipeLibrary.class
, in Clojure the class name evaluates to the class itself, so WindowsNamedPipeLibrary
should be all you need?
Hi everybody! I gotta hook up a call (sentry 🙂 ) to all of the exceptions (`Throwable`s) in my application. Is there a nice AOP way to do it by adding a hook somewhere once?
What kind of application are you developing? For example with a HTTP stack you can create a http middleware, which catches and re-throws the exceptions thrown by the handler(s) and reports them to sentry
(defn ^:private set-default-exception-handler
[sentry-logger]
(Thread/setDefaultUncaughtExceptionHandler
(reify Thread$UncaughtExceptionHandler
(uncaughtException [_ thread ex]
(log/warn ex "Uncaught Exception!")
(sentry-logger {:throwable ex})))))
You simply need to then provide a sentry-logger, which is a function that creates a sentry instance, configured as you see fit...
of course, I'd have to add the sentry hook to all of the caught exceptions - but that's mostly search and replace
I recently had some problems with the official one (`sentry-clj`?), it failed to report some clojure exceptions properly. raven-clj
did not have this issue.
@U11EL3P9U sentry-clj
good question, I believe I tried the latest one a few weeks ago
(sorry, I didn't mean to hijack this thread with my own issues 😄 )
sentry-clj
isn't official, in the sense that it's not sanctioned by Sentry. It's deemed a community-driven effort
If you have issues with sentry-clj, raise an issue on github and I'll see what I can do 🙂
@U1C72J3J4 you can make your own try catch
not recommending it but you can always make
(custom/try
...
(catch RuntimeException e
...)
(finally
...))
I'm a bit surprised that transit doesn't offer support for serializing arrays out of the box:
user=> (write-transit [1 2 3])
"[1,2,3]"
user=> (write-transit (into-array [1 2 3]))
Execution error (NullPointerException) at com.cognitect.transit.impl.AbstractEmitter/marshalTop (AbstractEmitter.java:203).
null
(into-array [1 2 3])
=> #object[“[Ljava.lang.Long;” 0x55cad8a0 “[Ljava.lang.Long;@55cad8a0"]
So are byte arrays, yet it supports them:
user=> (write-transit (.getBytes "foo"))
"[\"~#'\",\"~bZm9v\"]"
Good Morning Clojurians, if I make a mistake and require something that I should not have, and get this:
user=> (require 'development)
Syntax error (FileNotFoundException) compiling at (app/model/session.clj:1:1).
Could not locate datascript/core__init.class, datascript/core.clj or datascript/core.cljc on classpath.
It seems like after fixing the issue, I have to completely restart the REPL for it to work properly. Would there be a process to fix and not have to restart the REPL?Yes. You can use a different classloader that allows adding things to the classpath in runtime.
While it may sound complicated, there are already implementations out there.
Probably the easiest way to start using such functionality is to look at Sean Corfield's dot-clojure repo: https://github.com/seancorfield/dot-clojure
Namely, search for :add-libs
in the README.
OK, so how do you start? Do you just execute a single command and everything gets re-loaded?
Nothing gets reloaded. You require t.d.a (tools.deps.alpha) and call the right function to add a dependency in runtime.
The linked repo mentions this near the description of :add-libs
: "see the example load-master function in the comments in my deps.edn". That example explains pretty much everything.
@timofey.sitnikov in the leiningen world you have pomegranate for this, in the deps.edn world there is something called add-lib
Hmm, maybe :extend-via-metadata
helps somehow?
user=> (defprotocol Foo :extend-via-metadata true (foo [_]) (bar [_]))
Foo
user=> (defrecord FooRec [] Foo (foo [_] :foo) (bar [_] :bar))
user.FooRec
user=> (foo (->FooRec))
:foo
user=> (foo (with-meta (->FooRec) {`foo (fn [_] :overriden)}))
:foo
user=> (foo (with-meta (into {} (->FooRec)) {`foo (fn [_] :overriden)}))
:overriden
:thinking_face:The idea was to override the equality methods for a record, but I can roll my own with a minimal deftype
you should not do this
if you want custom equality/hashing semantics, you should deftype
dumb question about internals: is the compiler supposed to evaluate each top level form one-by-one when compiling? it has to learn about macros somehow as it goes
the compiler first reads (string -> clojure data)
then compiles, then evaluates
compiling an expr will look at the thing in function position. if that's a macro, it expands the macro (this happens until it's not a macro)
a macro is just a function that takes a form (clojure data representing a function call) as input and returns an alternate form (clojure data) to replace it with
the unit of compilation/evaluation is a single top-level form (not a file)
yes, but defmacro
is basically (do (defn x ...) (set-macro! (var x)))
and that set-macro!
call has to be evaluated for the compiler to know that x
is a macro
thanks @alexmiller 👍
https://github.com/clojure/brew-install/blob/1.10.2/src/main/resources/clojure/install/clojure
Thanks! Would've never thought to look in something that has "brew" in its name. :) And for some reason Google doesn't index the repo.
https://clojure.org/releases/tools is also a useful reference, listing all the releases and the changes in each.
Yes, the repo name is bad and we have a ticket for that (but it requires updating a bunch of infrastructure so has not seemed worth it so far)
Note that the script linked above does have some variable replacement done on it before it gets published so you can’t just use it as is
Often when people ask this, their real need is something else which might have a better answer if you care to share
Thanks! Yeah, I was just curious about the history of commits that first introduced clojure.libfile
and later removed it.
Cursive seems to still set the clojure.libfile
property.
Ah, yeah, that’s dead, replaced by the basis property. I was setting both so add-lib would keep working but that’s updated now
I'm trying to use clojure.tools.namespace.repl/refresh
and I've stumbled upon an interesting issue.
When called for the first time, it seems to reload absolutely all Clojure files that it could find in the classpath. Regardless of whether they have been loaded before or not.
The problem is that I have a few files that aren't loaded and require extra dependencies to be loaded. Clearly, I don't want refresh
to load them at all.
Is it possible to fix it on my end?
Would it make sense to alter something in clojure.tools.namespace
to support reloading only the files that have been loaded before?
we’re also seeing this, iirc it’s a problem with tools namespace not seeding the timestamp it uses to track what needs to be compiled directly
Not sure. The docstring explicitly says that it will load all files upon the first call: > Scans source code directories for files which have changed (since the last time this function was run)
yeah, might well be a design decision but it’s annoying in our project where you need to wait forever the first time you call it
OK, adding
(alter-var-root #'clojure.tools.namespace.repl/refresh-tracker
assoc :clojure.tools.namespace.dir/time (System/currentTimeMillis))
seems to work.
However, it truly fixes only the initial loading issue.
It will not fix a situation where you change some file that has not yet been loaded (and that cannot be loaded due to a missing dep for example) and then call refresh
.Got it working properly (or at least, as I want it to work) with this:
(alter-var-root #'clojure.tools.namespace.repl/remove-disabled
(fn [orig-remove-disabled]
(fn [tracker]
(let [filter-loaded #(filter find-ns %)]
(-> tracker
orig-remove-disabled
(update :clojure.tools.namespace.track/unload filter-loaded)
(update :clojure.tools.namespace.track/load filter-loaded))))))
@alexmiller You're the latest contributor to tools.namespace
- do you have any thoughts on the above? Would it make sense to add such a behavior to the lib, perhaps under a flag or via a function that changers some var, like disable-reload!
already does?
don't have time to look at it atm
https://ask.clojure.org/index.php/10277/preventing-clojure-namespace-refresh-loading-namespaces
Looks like you aren't invoking set-refresh-dirs
beforehand? It's very recommendable to do so
It still doesn't solve item 1 in the post above. It's easy to forget to add a newly created dir there. It's impossible to have a file that you don't want to load in the same dir with a file that should be reloaded.
> It's easy to forget to add a newly created dir there. Can be solved in a number of ways; this is not a place to question t.n's API/design. > It will attempt to (re)load even the files that haven't been loaded before. This doesn't make sense, t.n's very job is loading code. Its first load will typically load all your project's code; if you aren't doing this you are following a custom/hybrid approach
And I don't think that it's an invalid approach. At the very least, mkvlr above seems to share it with me.
@U45T93RA6 IMO there’s nothing to reload when you call refresh after you project boots without code changes
there's everything to reload because nothing can be assumed to have been require
d. If something else was require
ing your code, making refresh
perceivedly redundant, you should have a careful look at what/why is doing that.
https://github.com/stuartsierra/reloaded is the canonical example of how to setup a project using t.n.
Still, it doesn't invalidate the desire to be able to adhere to, as you called it, a custom/hybrid approach.
I’m not tracking this thread so please make sure relevant info ends up on the ask question, thanks!
PSA: Clojars is having DNS issues - our provider (DNSimple) is having an outage, which is making it impossible to resolve http://clojars.org in some parts of the world. Hopefully they will get it fixed soon.
If folks are having dependency resolution failures, check your clojars repo url. If it is https://clojars.org/repo/, change it to https://repo.clojars.org. The former just redirects to the latter, and the latter isn't impacted by the DNS issues.
Thanks for the heads up @U06SGCEHJ — and glad it was sorted quickly.
If folks are having dependency resolution failures, check your clojars repo url. If it is https://clojars.org/repo/, change it to https://repo.clojars.org. The former just redirects to the latter, and the latter isn't impacted by the DNS issues.
I remember I found a tool similar to Ansible but written in Clojure, it’s not pallet, it was recently developed, I can’t find. any idea?
Hey guys, I posted this on news-and-articles but there aren't many people there so reposting here, hope it's ok. I published a new video about my visual/mechanical programming language MockMechanics on youtube. It's created and scripted entirely in clojure. In the video I show how I built a 7 segment display that I'm using to build a 3d printer machine. It uses just a little snippet of clojure to do something that looks pretty cool. What do you guys think? https://www.youtube.com/watch?v=9rieZb2hzLE
We discourage cross-posting. People who want to see news and articles will subscribe to that channel. It's the same reason that articles/videos/etc are generally disallowed in #announcements -- it is for project/library releases only (and maintainers are discouraged from posting too often -- that's why we have #releases for more minor updates).
FYI, every new member is automatically subscribed to #news-and-articles -- so if that channel has fewer people it is because they've chosen to leave it.
Got it. Sorry 😬
I deleted it from #clojure as it seems you are getting feedback in #news-and-articles
Sometimes you just need to be patient before people get around to responding 🙂
Maybe I got greedy, it's not like nobody cared, I'll stick to announcements from now on. 😀
Hello Clojure friends. It's your prodigal son who's spent some time wandering in statically typed functional land, especially OCaml as of late. Compared to Clojure, OCaml's experience for live editing is really subpar, and I want to improve it. There are 2 routes I'm considering: 1. Add better REPL support in my editor (similar to Calva/CIDER) 2. Don't do a REPL per se, but instead do something like https://quokkajs.com/. Whereas a REPL is stateful, Quokka just runs a file and prints results inline in the editor, discarding the context each time. What do you guys think? I'm guessing that experienced Clojurians probably think 1 is strictly better than 2. Could you explain why?
One thing that immediately comes to mind - CPU intensive work. It wouldn't be fun to wait for something to finish each time you run the file or to keep track of all the temporary files with intermediate results. Another thing is side-effects. You usually don't want to repeat them unless necessary.
Come to think of it, Quokka has some pretty crazy heuristics for finding exactly what code needs to be rerun to mitigate those issues @U2FRKM4TW. Re implementing those for OCaml would not be fun, whereas with a REPL, the user decides what needs to be rerun.
I suspect a Quokka-style setup up is easier to get up and running since you don't have to maintain a connection so I don't know about strictly superior. Although if you're coming up with heuristics, it's probably not simpler anymore.
Also, the reloading entire files avoids situations where, e.g., you're running (g (f val)))
but the actual code running is (old-g (current-f val)))
because you forgot to re-evalute your new definition of g
.
@U8QTB156K Perhaps - apart from having a glance at the website, I'm not that familiar with Quokka so I was talking about just running a file each time.
I think the REPL approach is ultimately better because like you said, the user can decide and you can include shortcuts to reload the entire file. But running everything from scratch has a certain simplicity. I don't think it's well-suited to Clojure due to the startup time, but it might work for ClojureScript or something like Lumo or Babashka.
Retrofitting a "real" repl into an existing language might be harder than it sounds. See https://news.ycombinator.com/item?id=25620256
the workflow that worked for me with OCaml was structuring my projects so that I could iteratively re-compile and run targetting the specific feature I was working on (kind of a TDD flow), since the OCaml compiler is extremely fast and its repl is significantly different from the compiler
with my OCaml projects I could compile to native code and run in less time than clojure typically takes to get a repl prompt