+ and -, and some other functions in some circumstances behave like macros, and sort of rewrite themselves
yes, I see with str
in place of -
above the behaviour is different
(+ 1 2)
will rewrite itself before compilation to something like (clojure.lang.Numbers/add 1 2)
> it is resolved once when the class that the code is attached to when the class does what?
whoops, is loaded
the compiler then rewrites some static method calls (under circumstances I don't recall) to a simpler series of bytecodes
Thanks for explanation -- very helpful!
It's not that I'd want to sprinkle my code with with-redefs
s and defn
s, just trying to explore how mutable clojure functions are and in what contexts guarantees or assumptions can be broken 🙂
functions aren't mutable at all, what you are mutating are var
s which are kind of like a special kind of pointer or handle that is used for linking code together
when you use def
you are creating a var with a name, and setting the initial thing the var points to the given value, subsequent defs of the same name change what that var points to
alter-var-root!
and intern
are both other ways to create/mutate vars
If I'm not mistaken, its because of a feature called inlining. You can define functions to be inlined, which will well, inline them.
And -
and +
are inlined
As you can see here: https://github.com/clojure/clojure/blob/master/src/clj/clojure/core.clj#L989
Its kind of a hidden feature not really meant for general consumption, and it seems that they kind of reserve the right to break how it works in the future. So best to assume its a behind the scene optimization for core functions.
But basically, when the function is directly called, the compiler inlines the call, as if it was a macro, using similar semantics to macros. But if the function is passed as an argument (higher order) and later used, the function is evaluated normally, as a function.
@didibus thanks for the details, that makes it quite clear
@hiredman by «mutable» I wanted to express the fact that what one might naïvely consider to be value of, say, (fn [x] (str x))
, can change after evaluation, depending on context (as e.g. inside with-redefs
). Is there a better term for that?
As far as I can see atm (values of) functions are probably best thought of as immutable values which reference other values, with those references being possibly subject to change, and that makes them different from simple immutable values in my understanding.
Currently I can't think of other types of values which would use that kind of implicit referential sharing, but I might very well know too little about clojure atm.
It reminds me of some discussions about Clojure collections allowing one to include mutable objects inside of them, e.g. the vector [1 2 3 a]
after (def a (atom 4))
is a Clojure collection, but I doubt many people would call it an immutable value, or an immutable collection, because it contains an atom.
There is a very real sense in which Clojure functions containing Var references are mutable -- if you mutate what the Var refers to, the behavior of the function can change to something it never could have done before.
In Datomic’s pull syntax, is there a way to (pull ?e [*]) but exclude a specific key, say :db/id or a number of keys?
(yes, I can transform the data recursively after I receive it, but wondering if there’s a nicer way)
Why do I get here that the home-handler is unused where there is one
(defn home-handler
[request]
(let [page (extract-page-number request)]
(future (memo-display-data (inc page))
(-> (memo-display-data page)
(display/generate-html page)))))
(defroutes app
(GET "/" home-handler)
(route/resources "/")
(GET "/favicon.ico" [] ""))
and what can be the reason for this error message : HTTP ERROR 500 java.lang.NullPointerException: Response map is nil URI:/ STATUS:500 MESSAGE:java.lang.NullPointerException: Response map is nil SERVLET:- CAUSED BY:java.lang.NullPointerException: Response map is nil Caused by:
java.lang.NullPointerException: Response map is nil
at ring.util.servlet$update_servlet_response.invokeStatic(servlet.clj:100)
at ring.util.servlet$update_servlet_response.invoke(servlet.clj:91)
at ring.util.servlet$update_servlet_response.invokeStatic(servlet.clj:95)
at ring.util.servlet$update_servlet_response.invoke(servlet.clj:91)
at ring.adapter.jetty$proxy_handler$fn__7287.invoke(jetty.clj:28)
at ring.adapter.jetty.proxy$org.eclipse.jetty.server.handler.AbstractHandler$ff19274a.handle(Unknown Source)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127)
at org.eclipse.jetty.server.Server.handle(Server.java:501)
at org.eclipse.jetty.server.HttpChannel.lambda$handle$1(HttpChannel.java:383)
at org.eclipse.jetty.server.HttpChannel.dispatch(HttpChannel.java:556)
at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:375)
at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:273)
at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:311)
at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:105)
at org.eclipse.jetty.io.ChannelEndPoint$1.run(ChannelEndPoint.java:104)
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:806)
at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:938)
at java.base/java.lang.Thread.run(Thread.java:834)
Code so far : https://github.com/RoelofWobben/paintingsSeems like :keys
destructuring only works for let
and not for fn
arguments, is that correct? Seems like I cannot have a (map (fn [{:keys...} args])
(map (fn [{:keys [k]}] (inc k)) [{:k 1} {:k 2}])
(2 3)
Looks like I did something wrong. What if I also wanted the original map? (map (fn [{:keys [k]} m] ..)
I think that's where I got it wrong
(map (fn [{:keys [k] :as m}] (assoc m :a (inc k))) [{:k 1} {:k 2}])
({:k 1, :a 2} {:k 2, :a 3})
recommend checking the docs 🙂 https://clojure.org/guides/destructuringThanks @rakyi , I actually checked the docs but I missed the :as
part (which isn't needed for let
can you clarify what you mean by "isn't needed for let
"? e.g. (let [{:keys [a b] :as m} (invoke-some-fn)] ..body)
oke, I got a project work with hiccup What is now a good way to learn to do the front-end with reagant or re-frame ?
thanks
One cool thing I've found with hiccup / reagent is that hiccup form can generate other times of XML like SVG. https://github.com/Aeyk/clojure-scratchpad/blob/master/opus_flammagramma.svg Was generated with hiccup code, for instance
??? I want to learn how I can convert some hiccup to re-frame
re-frame has a bunch of other moving parts, since it has a philosophy on memory management and such. I recommend starting a simple project from scratch before trying to port this one. (don’t worry your knowledge of hiccup will help you quite a bit because reagent and re-frame also use a version of it) I’d probably recommend reagent first then maybe try re-frame. and this site is highly recommended for getting a quick overview with a bunch of examples: https://reagent-project.github.io/
thanks
Once you get a good grasp of how the template is set up and runs maybe you can try adapting your previous one to work with reagent as well. This might be very fast if you’ve used react before and understand the underlying concepts, otherwise it might take a bit of getting used to.
then I have a big problem. I have no xp in react or friends
not a big problem, it’ll just take a bit longer to understand why they do certain things.
You’ll be fine!
Eric Normand has some good videos on the basics of reframe and reagent. Jacek Schae has free and paid courses for both reagent and reframe, building an application starting from the ground up. Both assume no knowledge of react.
yep, I have seen the free course on reframe
As mentioned earlier in the thread, you probably want to do reagent before reframe, since the latter is used on top of the former.
i know
@allaboutthatmace1789 so first this course : https://www.jacekschae.com/learn-reagent-free
wil do the next few days
and maybe reagent is all I need and maybe not
can I better use npm or yarn ?
I use npm with no issues. I’m not familiar with yarn so couldn’t say if it’s better.