beginners

Getting started with Clojure/ClojureScript? Welcome! Also try: https://ask.clojure.org. Check out resources at https://gist.github.com/yogthos/be323be0361c589570a6da4ccc85f58f.
2021-01-23T00:00:24.172600Z

+ and -, and some other functions in some circumstances behave like macros, and sort of rewrite themselves

2021-01-23T00:01:36.172800Z

yes, I see with str in place of - above the behaviour is different

2021-01-23T00:02:04.173Z

(+ 1 2) will rewrite itself before compilation to something like (clojure.lang.Numbers/add 1 2)

2021-01-23T00:02:34.173200Z

> it is resolved once when the class that the code is attached to when the class does what?

2021-01-23T00:02:55.173400Z

whoops, is loaded

2021-01-23T00:04:59.173600Z

the compiler then rewrites some static method calls (under circumstances I don't recall) to a simpler series of bytecodes

2021-01-23T00:06:17.173800Z

Thanks for explanation -- very helpful!

2021-01-23T00:10:08.174Z

It's not that I'd want to sprinkle my code with with-redefs s and defns, just trying to explore how mutable clojure functions are and in what contexts guarantees or assumptions can be broken 🙂

2021-01-23T00:12:55.174200Z

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

2021-01-23T00:14:21.174400Z

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

2021-01-23T00:15:26.174600Z

alter-var-root! and intern are both other ways to create/mutate vars

1
2021-01-23T00:15:37.174800Z

If I'm not mistaken, its because of a feature called inlining. You can define functions to be inlined, which will well, inline them.

đź’ˇ 1
1
2021-01-23T00:15:51.175Z

And - and + are inlined

2021-01-23T00:21:57.175700Z

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.

2021-01-23T00:23:02.175900Z

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.

2021-01-23T00:24:07.176100Z

@didibus thanks for the details, that makes it quite clear

2021-01-23T00:55:58.176400Z

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

2021-01-23T01:33:10.177100Z

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.

2021-01-23T01:33:58.177300Z

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.

1
raspasov 2021-01-23T10:38:40.179100Z

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?

raspasov 2021-01-23T10:39:58.179800Z

(yes, I can transform the data recursively after I receive it, but wondering if there’s a nicer way)

roelof 2021-01-23T10:48:28.180500Z

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" [] ""))

roelof 2021-01-23T11:00:35.181100Z

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

2021-01-23T16:24:14.183100Z

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

rakyi 2021-01-23T16:32:03.183200Z

(map (fn [{:keys [k]}] (inc k)) [{:k 1} {:k 2}])
(2 3)

2021-01-23T16:36:30.183400Z

Looks like I did something wrong. What if I also wanted the original map? (map (fn [{:keys [k]} m] ..)

2021-01-23T16:36:57.183600Z

I think that's where I got it wrong

rakyi 2021-01-23T16:40:42.183800Z

(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/destructuring

2021-01-23T16:54:10.184Z

Thanks @rakyi , I actually checked the docs but I missed the :as part (which isn't needed for let

lassemaatta 2021-01-23T17:44:02.184200Z

can you clarify what you mean by "isn't needed for let"? e.g. (let [{:keys [a b] :as m} (invoke-some-fn)] ..body)

roelof 2021-01-23T18:55:40.185300Z

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 ?

roelof 2021-01-24T13:33:48.215Z

thanks

Malik Kennedy 2021-01-23T19:02:26.185400Z

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

roelof 2021-01-23T19:08:58.185800Z

??? I want to learn how I can convert some hiccup to re-frame

Mno 2021-01-23T19:17:10.186Z

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/

roelof 2021-01-23T19:18:25.186300Z

thanks

Mno 2021-01-23T19:20:38.186700Z

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.

roelof 2021-01-23T19:47:39.187Z

then I have a big problem. I have no xp in react or friends

Mno 2021-01-23T20:00:49.189Z

not a big problem, it’ll just take a bit longer to understand why they do certain things.

Mno 2021-01-23T20:01:15.189700Z

You’ll be fine!

Joe 2021-01-23T20:01:36.190200Z

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.

âž• 2
roelof 2021-01-23T20:25:48.190700Z

yep, I have seen the free course on reframe

Joe 2021-01-23T20:27:26.192300Z

As mentioned earlier in the thread, you probably want to do reagent before reframe, since the latter is used on top of the former.

roelof 2021-01-23T20:28:08.192500Z

i know

roelof 2021-01-23T20:30:02.192700Z

@allaboutthatmace1789 so first this course : https://www.jacekschae.com/learn-reagent-free

roelof 2021-01-23T20:32:33.193Z

wil do the next few days

đź‘Ť 1
roelof 2021-01-23T20:33:01.193300Z

and maybe reagent is all I need and maybe not

roelof 2021-01-23T20:59:24.193500Z

can I better use npm or yarn ?

Joe 2021-01-23T23:01:52.194900Z

I use npm with no issues. I’m not familiar with yarn so couldn’t say if it’s better.