Fork me on GitHub
Jamie Rumbelow11:05:26

Can the clojure compiler detect side effects in functions? Can it decide at compile-time whether a function is pure?


I wouldn’t rely on that to be exhaustive though! There’s nothing in the language to make such a guarantee.

Jamie Rumbelow12:05:14

I’m interested in whether the compiler could automatically memoize all pure functions. Could effect massive speed improvements, minimal amounts of memory increase, with very little risk


I don't think it's minimal. Like any function that does something on a data structure using an uuid is unlikely to be called twice with the same.


An interesting aside on the ClojureScript side, once Google Closure knows a function is pure, it does certain optimizations with it. Here is one case where it is incorrect:


I suppose they have a notion of "no side effects" in this case, which is different than "pure" via their terminology


Yeah my initial impression was that you could probably do a whole dissertation on this topic and still only come up with a method that only works on a restricted scope of language features


Clojure as it’s written can not. But a runtime certainly could detect at runtime and do certain optimizations. Or if code was written to be explicit about its effects

Jamie Rumbelow17:05:30

Okay, all interesting stuff - thanks everyone!


It has probably been discussed numerous times but I can't find any answer. I have these macros:

(defmacro format-query [q]
  `(cond-> ~q
     (map? ~q) (sql/format :quoting :ansi)))

(defmacro query [c q params]
  `(jdbc/query ~c ~(format-query q) ~params))
The issue is that (query 1 2 3) expands to (jdbc/query 1 2 3) whereas I want it to expand to (jdbc/query 1 (cond-> 2 ...) 3). Is it possible to do so?


based on your code, i’m not sure why it would expand to (jdbc/query 1 2 3)


but I think in this case you can change format-query to be a function, rather than a macro


and that might be what you want?


should be

(defn format-query [q]
  `(cond-> ~q
     (map? ~q) (sql/format :quoting :ansi)))

(defmacro query [c q params]
  `(jdbc/query ~c ~(format-query q) ~params))


first macro should be a function @p-himik


Sure. But now I can't use format-query anywhere except for other macros. I guess a solution in this case would be to extract the common part to another macro. That's what I'll probably do. Thanks!


Can you help me understand why it's expanded the way it is with two defmacro? The way I read it: ~ in ~(format-query q) unquotes this part, so that the macro is expanded here. It expands in a form (cond-> ...). The thing I cannot understand is why this form is being computed during macro expansion.


It was being computed during macro expansion because you used the macro in a macro


So the format-query macro was being executed, expanded and then the query macro continued evaluating and expanding


I have a need for a sparse vector. Any ideas how I might represent that?


It's a semantic thing rather than a perf thing. I need the inverse of nth: construct a vector with a value at position n.


And then I also need a way of merging the sparse vectors...

Chris O’Donnell18:05:22

What other operations do you need to do?


Pretty much just those


What I'm trying to do is, for example start with a source like [1 2] and project it using second. So it would produce 2. Then, I could change the projection to 3 and use that to update the source to [1 3]


"Project it" and "change the projection" sound a lot like what Specter does.


I'm basically implementing a lens. I am trying to figure out how to implement it myself rather than use a lib like specter 😅

Chris O’Donnell19:05:42

The operations you mention above sound like they could be easily done on a hash map instead of a vector with regular old assoc and merge. It's not entirely clear to me how those things fit in to your lens implementation.

Chris O’Donnell19:05:01

I suppose you could hold onto the novelty in a hash map and do the merge by associng the novelty from the hash map into the vector.


Right, the issue is the source to the data is a vector and that needs to be preserved


hi everyone. is this an overkill?

(some? (some-> project :images :thumbnail))


to check for non-nil value


looks a bit weird 😄


why not just (-> project :images :thumbnail)? thumbnail is probably not a boolean, so just having a value where you do check for nil is ok


or (-> project :images :thumbnail some?) if are you really into booleans 🙂


btw. if you want to get your clojure hat on on the raspberry pi 3 b+ .... installing zulu jdk & lein works surprisingly easy


but trying to use openjdk from adoptopenjdk won't work , something with ssl connections and elliptic ciphers is broken there 😞 ... so zulu instead and life is good


@vlaaad I thought it would throw an exception if I did it without some->


keywords, when called as functions on nils just return nil (:a nil) => nil


gotcha, thank you