it also does the nice thing and will ignore thing
if it is prepended with _
, like _thing
to signal unused
Hi everybody
does somebody know how to convert this java line code into clojure code?
this.API = (WindowsNamedPipeLibrary) Native.loadLibrary("kernel32", WindowsNamedPipeLibrary.class, W32APIOptions.UNICODE_OPTIONS)
I've been trying this...
(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))
You should print out the value of interface-class
what error are you getting?
Im getting that error Interface (Class) of library=kernel32 does not extend Library
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.
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)
...
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
now it seems it is working
(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?
yes you are right
I'm just kind of puzzled by a Java interface that seems to have data members...
with that change it seems its working
My Java is rustier than I thought? 🙂
thanks all
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.
@pez hmm that sounds quite strange (esp the 200x)… what kind of code are you running and how many cores is the machine? What’s the (pipeline n …) number?
Is it pure functions or is there IO in the code?
I’ll make a repro.
I think this is similar enough to what I do in my program, where I have a boolean-array where some positions are set, and some are not. Most are not. Then I want the indexes of the set bits of every odd position from the array, as a sequence.
(let [n 1000000
ba (boolean-array n)
every-other (range 1 n 2)
prob 0.15
sample-size (long (* n prob))
to-ch (a/chan 1)
from-ch (a/to-chan every-other)]
(doseq [i (take sample-size
(random-sample prob (range n)))]
(aset ba i true))
(println "filter")
(time
(count
(filter #(aget ba %) every-other)))
(println "transduce")
(time
(count
(transduce
(filter #(aget ba %))
conj
every-other)))
(println "core.reducers/filter")
(time
(count
(into [] (r/filter #(aget ba %) every-other))))
(println "core.async/pipeline")
(time
(do
(a/pipeline 4 to-ch (filter #(aget ba %)) from-ch)
(count
(a/<!! (a/into [] to-ch))))))
Output:
filter
"Elapsed time: 24.779003 msecs"
transduce
"Elapsed time: 23.854725 msecs"
core.reducers/filter
"Elapsed time: 23.759016 msecs"
core.async/pipeline
"Elapsed time: 3535.955765 msecs"
=> 74885
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
You can try this:
(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...
hmmm ☝️ that's one way to do it
Works for moi in my application 🙂
of course, I'd have to add the sentry hook to all of the caught exceptions - but that's mostly search and replace
yeah, I like this one. Thank you!
you're welcome. 🙂
btw, which sentry library are you using?
I think I'll go with the official one. Got any reccomendations?
Which one would that be?
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.
Which version of the sentry-clj are you using?
@dharrigan sentry-clj
good question, I believe I tried the latest one a few weeks ago
I also saw one from exoscale - is it worth it? which one are you using?
I'm maintaining the semi-official one
(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 🙂
PRs are welcome 'tho 🙂
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
I guess it focuses on Clojure data, and arrays are host-specific things:
(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\"]"
I see… I don’t have other guesses 🙂
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?@timofey.sitnikov in the leiningen world you have pomegranate for this, in the deps.edn world there is something called add-lib
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.
(I'm assuming you're using deps.edn
)
I there a way to override a specific method implementation in a defrecord?
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:But not really I think
Do you mean a defrecord instance of the defrecord type btw?
The idea was to override the equality methods for a record, but I can roll my own with a minimal deftype
oh right
Things got less pleasant where I had to implement my own hasheq 😞
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
or is there some more advanced magic involved?
the compiler first reads (string -> clojure data)
then compiles, then evaluates
@vandr0iy you can make your own try catch
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)
thats always on the table
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
not recommending it but you can always make
(custom/try
...
(catch RuntimeException e
...)
(finally
...))
and expand it to have whatever calls to sentry you want
the unit of compilation/evaluation is a single top-level form (not a file)
that would be the AOP-iest way
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
ah right, that’s what I was wondering about
thanks @alexmiller 👍
obviously it is not called set-macro!
in Clojure, used that name for brevity
That's what I ended up doing
Could someone please point me to the repo that tracks the Clojure CLI bash script?
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.
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
preseeding this timestamp might be worth a try
Oh, that might help, I'll try that!
please let me know if it does!
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)
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.
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
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
.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
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?
please file a question on ask.clojure..
don't have time to look at it atm
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?
https://ask.clojure.org/index.php/10277/preventing-clojure-namespace-refresh-loading-namespaces
Yes thank you
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.
@vemv 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 didn't suggest so
I’m not tracking this thread so please make sure relevant info ends up on the ask question, thanks!
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).
OK, so how do you start? Do you just execute a single command and everything gets re-loaded?
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. 😀
Thanks for the heads up @tcrawley — and glad it was sorted quickly.
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.
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?
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
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 @p-himik. 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
.
@d4hines 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.