Did you try using proxy instead? It can extend a Java class and override its methods as well, and is more convenient when it is possible to use it.
Otherwise you might need to show your macro implementation if you want help
Or do you need help with writing such a macro?
I see this a lot with lazy-seq implementation, some people will lazy-seq the rest, and some will lazy-seq the whole thing. I don't think there's always a reason why people chose one over the other, as more they just did.
In practice it means you shouldn't treat things as fully lazy, but mostly lazy, there's a few functions here and there that end up not being fully lazy, like line-seq, so if you want to be fully lazy, you should design things that way yourself.
most of the times documentation says "returns a lazy-sequence" however if first element was already realized the returned sequence is not that lazy
Ya, that's what I mean, you should most of the time think of something that says lazy or returns a lazy-seq as "mostly lazy" and not "strictly lazy". Because there's a lot of edge cases where you'll have more elements evaluated then you'd expect. So none of the lazy sequence machinery guarantees full 1 element at a time lazy was including the first element.
Yes, this is kind of disappointing when you were actually wanting to be fully 1 element at a time lazy, and hoping you could just use Clojure's lazy sequence functions to do so.
Not so to say disappointing, just unexpected, not documented properly.
That's one of the reasons you'll hear advice that says, don't mix side-effects and sequence functions together. Cause if say you send an email on realizing an element, there's be a lot of occasion you might be surprised like oh.nonit sent way too many emails.
Ya, I agree with you there. More consistent terminology in the documentation would be good.
The whole lazy sequence in Clojure is best thought of as an optimization for performance and memory use. And not really as a mechanism to implement lazy evaluation for your own use cases.
yep, for that we have promises, futures
Ya, promise, delay, or using transducers. You can also do it with lazy-seq, but you need to be careful, cause some of the sequence functions will realize more than you might want. If you keep to your own functions and lazy-seq it can work as well.
Now why is line-seq like this is hard to say and probably speculation. I wonder if the type hint makes it it needs to be this way :thinking_face: It's possible if wrapped around lazy-seq the hint is lost? Or you know could just have been an afterthought, like no one thinking it mattered if the first line was read immediately or not.
or as we concluded to fail-fast if buffered reader\\file misbehaves
Ya possible
I've come to realize that most details in Clojure often have good reasons and were thought through with a trade off chosen, but that still, with all that thoughtful process, there are details that slip through and were "accidental" in a sense, or overlooked. And sometimes it's hard to say if you've got a case of something that's overlooked, or of something that was a conscious choice but wasn't documented.
Whenever you learn about some details like this, please go to http://ClojureDocs.org and add a notes or example for it. That stuff can really help others, even future you.
I think I need a specifically named Class, unfortunately. Unfortunately the actual macro is wrapped up in proprietary code. Let me try to put together a toy example and I'll come back.
I don't think it's so much writing the macro as making the resulting class visible to aot at compile time.
Well there's a :name
property you can pass to gen-class to give it whatever name you want (it's the fully qualified package name + class name)
If you run macroexpand-1 on your macro, do you get the correct gen-class call?
Also, does your macro generate a (ns) or a (gen-class) ? I'd suggest the latter
And make sure your macro calls are top-level, otherwise they won't run at compile time
Well I get something that compiles and looks OK to me. When I put the name of the class in the :aot clause of my project file, the compiler claims not to see it. Maybe I'm not specifying it quite right. I'm away from my desk now, but I'll concentrate on that when I revisit the problem.
The macro generates gen-class statements.
I'm defining the macro in one module and calling it in my 'core' module at top-level.
Thanks for your help!
Oh, so don't put the class name in :aot
Put the namespace name of the clojure file that contains the calls to your macro
Ah. So if the full path is my.ns.MyClass, the aot should be 'my.ns'?
No, it should be like:
(ns foo.bar)
(gen-class
:name my.ns.Class
...)
And in :aot in project.clj you want to put foo.barAh! The ns containing the the macro call?
Which I mean, yes if you class is called foo.bar.MyClass (assuming my example), then you just want to put foo.bar
Yes the macro call
OK. Yeah. Sure, that makes perfect sense now.
Basically you don't compile the gen-class, you compile a Clojure source file which will contain calls to (gen-class ...) inside it at the top level, and when compiling that Clojure source file, the compiler will also emit Class files for each of the gen-class directives it encounters.
Yes, yes, yes. That was the missing piece of my mental model. Thanks @didibus! I have to step away now, but I thank you for clearing that up for me!
No problem, hopefully that'll solve your issue.
Hey everyone š I was wondering is there an easy way to convert a project that was created with a project.clj file (the project was created with leiningen ) to dep.edn project?
- Hi, recently I am trying to use [react-flow](https://github.com/wbkd/react-flow) in my project and I am really new to cljs š¢.
- I am using shadow-cljs in my project and I've install the npm package using npm install react-flow-renderer
and put (:require ["react-flow-renderer" :default ReactFlow])
in my core.cljs file
- But for the next step I tried to implement this demo in [ React Flow - Overview Example](https://reactflow.dev/examples/) page yet didn't know how to start.
- In that example page, I know I should probably represent the array of data objects in initial-elements.js
using [ js-obj ](https://cljs.github.io/api/cljs.core/js-obj) (am I correct ? :rolling_on_the_floor_laughing:)
- But next, in the index.js
, how could I wrap jsx syntax in cljs, for example , this part:
return (
<ReactFlow
elements={elements}
onElementsRemove={onElementsRemove}
onConnect={onConnect}
onLoad={onLoad}
snapToGrid={true}
snapGrid={[15, 15]}
>
<MiniMap
nodeStrokeColor={(n) => {
if (n.style?.background) return n.style.background;
if (n.type === 'input') return '#0041d0';
if (n.type === 'output') return '#ff0072';
if (n.type === 'default') return '#1a192b';
return '#eee';
}}
nodeColor={(n) => {
if (n.style?.background) return n.style.background;
return '#fff';
}}
nodeBorderRadius={2}
/>
<Controls />
<Background color="#aaa" gap={16} />
</ReactFlow>
);
- Is there anyone have relevant experience or know how to solve this problem. Thanks in advance! š»Could probably use reagent to replicate those jsx components using cljs data structures
@sfyire Thanks for your kind reply. This is my attempt to translate but it didn't work.
(ReactFlow {:elements elements
:style graph-styles}))
I believe the problem come from this part but haven't figure out how to solve it.This is my browser's warnings. Thanks again š
Update:
I finally got to solve it by using :>
in reagent
I am trying to translate the following calls to cljs:
var g = new dagre.graphlib.Graph();
g.setGraph({});
g.setDefaultEdgeLabel(function() { return {}; });
g.setNode("kspacey", { label: "Kevin Spacey", width: 144, height: 100 });
My attempt:
(let [g (dagre/graphlib.Graph.)
_ (g.setGraph (js->clj {}))
_ (g.setDefaultEdgeLabel (js->clj #(fn [] {})))
_ g.setNode("kspacey", { label: "Kevin Spacey", width: 144, height: 100 });
It fails withAny tips? Also, is this a question more suited for #clojurescript?
Note that I am not trying to use the g object in the hiccup. I am just trying to create it in a let.
This might be helpful https://lwhorton.github.io/2018/10/20/clojurescript-interop-with-javascript.html#function-invocation
The way to invoke functions is `([func-name] [target] parms)
and js->clj
us used to convert javascript types into clojure types. You probably want the opposite clj->js
I think this should be closer.
not sure about the dare/graphlib.Graph
though
(let [g (dagre/graphlib.Graph.)
_ (.setGraph g (clj->js {}))
_ (.setDefaultEdgeLabel g (fn [] {}))
D'oh, I meant the other way around. cljs->js
.
Thanks for the link.
Hey there - I am trying to use clojure to separate an integer of variable length (ie 15_5_212518674225 => 1-5-5-2-1-2-5-1-8-6-7-4-2-2-5) into two separate vectors splitting every other number. The int would turn into this after the split: [1 5 1 5 8 7 2 5] and [5 2 2 1 6 4 2] .
Iād probably pull the setGraph
setDefaultEdgeLabel
and setNode
into the let body.
And you can use ->
and thread the calls like so
(-> g
(.setGraph (clj->js {}))
(.setDefaultEdgeLabel (fn [] {})))
Probably not pretty but:
(let [n 155212518674225 n-str (str n)] [(take-nth 2 n-str) (take-nth 2 (rest n-str))]) ;; [(\1 \5 \1 \5 \8 \7 \2 \5) (\5 \2 \2 \1 \6 \4 \2)]
I think thatās not too bad. My first idea was way worse š Youād probably have to convert the characters back to integers
(let [n 155212518674225
n-str (str n)
nums (map #(Integer/valueOf (str %)) n-str)]
[(take-nth 2 nums) (take-nth 2 (rest nums))])
The above worked, thanks!
:thumbsup: no worries š
I'm looking for the equivalent of macrolet for cljs. I found clojure/tools.macro but it only seems to be for clojure not clojurescript.
Yours are much shorter and simpler than mine, certainly...
(let [n 155212518674225]
(->> n
str
(partition 2 2 [\x])
(apply map vector)
(map #(filter #{\0 \1 \2 \3 \4 \5 \6 \7 \8 \9} %))
(map #(map str %))
(map #(map (fn [x] (Integer/parseInt x)) %))
(map vec)))
oooo pretty :)
Hello everyone. How do I use the repl to call a function and use itās result (an access token) in other functions?
In bash I call a login function and save the accessToken to a variable I can use in my other rest calls, whatās the clojure-idiomatic way to do this? Iād like to be able to call (login environment)
and then have my following calls use the accessToken from that login result
If I was just messing around in the REPL exploring some api, I'd do (def access-token (login environment))
and use the access-token directly, that would define a var
which is a global variable inside that namespace.
When running production code it might be more likely that I had the token as an environment variable and used System/getenv
to pull in the variable, possibly in a let block instead to limit it's scope.
Doing something like:
export YOUR_TOKEN=topsecret
lein repl
Will make your token avaliable with (System/getenv "YOUR_TOKEN")
Hello everyone. Why does this snippet
(->> ["A" "B" "C"]
(map #(println %))
((fn [x]
(println "Done!"))))
produce this output?
Done!
nil
I.e., why arenāt A
, B
and C
printed out?(Iām only looking for some hints so that I can figure out what to Google to understand this behaviour better.)
map
is lazy. there's nothing realizing that sequence. the only thing that happens to it is that it's passed to a function, ignored, and "Done!" is printed. So nothing cares about the lazy sequence so it doesn't do any work
Ah, of course! Thanks!
And nowā¦
(->> ["A" "B" "C"]
(mapv #(println %))
((constantly (println "Done!"))))
gives me
Done!
A
B
C
nil
Why does the Done!
turn up first? :thinking_face:
Presumably itās something to do with constantly
as with ((fn [x] (println "Done!")))
I get the āexpectedā order in the output.
(constantly (println "Done"!))
will evaluate it's argument, a println which returns nil, and you end up with a function that takes arbitrary input and returns nil
Iāll give it a shot thank you!
Ah, the println
within the constantly
is being evaluated when the function that will be returned is being generated. That makes sense, thanks again. š
@emilaasa in a production environment if you had to hit another server to get a accessToken, how would you save that variable for use in other rest calls? in this scenario it couldnāt be an env variable because it needs to be fetched
You could use an atom to store it:
(def access-token (atom nil))
(reset! access-token (login environment))
(do-something @access-token)
@titanroark depends - does it need to be renewed under the runtime of the program?
yeah during runtime, itāll need to be changed/updated depending on the service I now want to hit
Maybe you can stay immutable and not change/update it and make your life easier?
Hm.. Iād like to stay as functional as possible but I want to be able to target different service endpoints on demand. To do that I need the access token for each service-environment. If I were to stay purely functional, Iād have to call login before each request I make which is way too much overhead.
Hi! I'm playing with my own stupid merge sort implementation. And while mesuring performance I noticed a huge difference depending on how I generate numbers.
this (repeatedlyĀ 1000000Ā (partialĀ rand-intĀ 1000000))
is 70000x slower than
(def N 1000000)
(repeatedly N (partial rand-int N))
a list comprehension (forĀ [_Ā (rangeĀ N)]Ā (rand-intĀ N))
is as slow as the first expression I mentioned
repeatedly
returns a lazy sequence. so most likely you are doing 70000x less work and seeing that take that much less time š
or realizing the sequence in some cases and not in others
but the first and second expressions are IDENTICAL except for using predefined constant or not
and the time difference I mentioned applies to clojure.core/sort too, not my function only
what exact forms are you running in the repl?
user=> (time (do (repeatedly N (partial rand-int N)) nil))
"Elapsed time: 0.022722 msecs"
nil
user=> (time (do (repeatedly 1000000 (partial rand-int 1000000)) nil))
"Elapsed time: 0.022792 msecs"
nil
these behave more or less identically for me, and they are very quick as i'm constructing a lazy sequence and not realizing any of itsorry for bothering you, I can't reproduce the time difference anymore
but it was there
you're most likely seeing the differences in the cached lazy sequence and realizing it.
so sort will realize all of v and then sort it, the other sorts will benefit from having a cached lazy sequence and just do their sorting, rather than computing all of the random numbers and then sorting
but I call time not on combined function but on each sort method separately
and I called it several times changing the let form parameter
and the first function in list - clojure.core/sort produced such different timings
yes. because the first time you access a lazy sequence you have to compute the items in it. subsequent accesses to it use the already computed values
(let [coll (map #(do (Thread/sleep 1000) %) (reverse (range 4)))]
(time (sort coll))
(time (sort coll))
(time (sort coll)))
"Elapsed time: 4014.109926 msecs"
"Elapsed time: 0.008128 msecs"
"Elapsed time: 0.004072 msecs"
(0 1 2 3)
I see now, thanks
I was puzzled because I was changing the source code and evaluating the changed version
does REPL intern such things?
my REPL output changes from yours - I have close times with both subsequent function calls inside the let form
i'm not following
can you post the output?
it's right above yours output
the result of evaluating the let form twice
oh evaluating the left form twice. if you are creating a new lazy seq every time it will be computed every time
Hello! I'm wondering how to disable clojure.test tests in prod mode. The idiomatic way seems to not include the test folder in the classpath using an alias. But I have a technical constraint that some tests are co-located with the source code. Is there a way to set clojure.test/*load-tests*
to false from deps.edn
, and ensuring it during AOT compilation?
Are your tests running or you just donāt want to define them?
The best attack will be on the constraint that forces you to put tests and source in the same place
Putting those in separate folders is common practice in clojure and I can't think of another language where that isn't how projects are layed out, maybe C?
we do it with typescript at my job (thing.ts, thing.test.ts, thing.spec.ts). i hate it, but i don't get to make that decision, lol.
I think Rust has support for same file tests. it's actually quite nice.
eg: <https://github.com/bodil/im-rs/blob/master/src/sort.rs#L184>
sure, you can even do it in clojure, I just mean conventionally most projects don't
yeah. i think it might be a convention in Rust
> However, because unit tests go in the same files as the code
<https://doc.rust-lang.org/book/ch11-03-test-organization.html>
so whatever "technical constraint" there is that is forcing you to co-locate them is likely a misunderstanding or a soft constraint
I agree the constraint is odd, but I don't have control over it. It's a complex design choice with subtle implications. Targeting the constraint seems the best approach at first, but it's just not possible. Tests should not be defined in prod mode. When clojure.test/*load-tests*
is false
, deftest expands to nil. I just want to find a practical way to set it to false from clojure cli, deps.edn
or a similar way. Is there a way to do so?
How are you running your code in production?
Using clj
with a -main
Any reason youāre not building an uberjar and running it just using java -jar
in production?
No reason so far, it could perfectly be done with an uberjar.
And probably should
I'd be happy to discuss the technical constraint, it's an interesting one, but since addressing the constraint itself is not an option I'd prefer to make it another thread :)
you can achieve this with an appropriate -e
call right?
i wonder if there would be interest in that being initialized from a jvm property as well
If -e
has the right precedence it might work, I'll give it a try.
How would the jvm property map to *load-tests*
? Should I read the property from my -main
and set *load-tests*
accordingly?
if the dynamic var was initialized to some jvm property otherwise true. No i'm musing about a change i might suggest on ask.clojure
Ah! I'm allowed to wrap deftest
in a custom macro. So my-deftest
could read this property and expand to clojure.test/deftest
or nil
accordingly. This is another approach I might try.
deftest
is already that macro
But is decides to expand or not on *load-tests*
ok, I'll bite, what is the constraint
If you decide to switch to an uberjar, depstar
has a mechanism for a ācustom compileā function, so you could provide your own function that invokes compile
inside a binding of *load-tests*
.
(but I would strongly advise āfixingā the root cause here and arranging for your tests to be in a separate tests
folder tree instead of mixed in with your src
)
This is interesting and seems clean! I'll check depstar. I'll communicate more about the root cause and use case in the near future. @dpsutton @hiredman @nbtheduke and @seancorfield thank you very much for your help and kind advices. I think it unblocked me and I'll be able to move forward.
Hello Clojure wizards, please forgive my Clojure baby-talk. Does anyone know how to define a reflexive relation in core.logic
? I can define a simple asymmetric relation like this:
(ns logictest.core
(:gen-class))
(require '[clojure.core.logic.pldb :as pldb])
(require '[clojure.core.logic :as l])
(pldb/db-rel thing t)
(pldb/db-rel relation x y)
(def facts (pldb/db [thing 'a] [thing 'b] [relation 'a 'b]))
When I try to run pldb code to ask the question "what thing is related to 'b
"?,
(pldb/with-db facts (l/run* [foo] (relation foo 'b)))
pleasingly, I get back 'a
:
(a)
but when I run this form to try to ask "what thing is related to 'a
,
(pldb/with-db facts (l/run* [foo] (relation foo 'a)))
I get ()
. But I would like to define relation
to be symmetric. Is there a way to do that?
I tried to study the code for pldb/db-rel
to see if there is a hidden option to make a relation reflexive, but it is a bit beyond me, at my novice level of Clojure.no
the way to do that is a conde in your logic program
(pldb/with-db facts
(l/run* [foo]
(l/conde
[(relation foo 'a)]
[(relation 'a foo)])))
thank you!!!
You are the best! This works!
(defn in-symmetric-pair [relation x y] (l/conde [(relation x y)] [(relation y x)]))
(pldb/with-db facts (l/run* [foo] (in-symmetric-pair relation foo 'a)))
Thanks so much.
i have a vector like this [[1 2] [ 6 4]] is there a simple function that can add 1 and 6, and 2 with 4, then generate [7 6]
be aware that it returns a list instead of a vector
> (apply map + [[1 2] [ 6 4]])
(7 6)
seems to workthanks