This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2018-02-24
Channels
- # beginners (113)
- # boot (9)
- # cider (6)
- # cljs-dev (33)
- # cljsjs (1)
- # clojure (73)
- # clojure-italy (4)
- # clojure-russia (6)
- # clojure-spec (13)
- # clojure-uk (21)
- # clojured (1)
- # clojurescript (79)
- # core-async (6)
- # core-logic (4)
- # datascript (5)
- # datomic (5)
- # duct (12)
- # events (1)
- # figwheel (9)
- # fulcro (143)
- # garden (2)
- # leiningen (1)
- # luminus (24)
- # off-topic (1)
- # parinfer (7)
- # protorepl (12)
- # re-frame (4)
- # reagent (32)
- # rum (1)
- # shadow-cljs (46)
- # spacemacs (4)
- # specter (27)
- # sql (6)
- # unrepl (3)
- # videos (1)
I’m calling a query like this
(let [card-account (j/query t-con [queries/get-card-account-by-card-account-user-id (:entityId receipt)] {:result-set-fn first})]
and the object looks like this
card account {:account #object[org.postgresql.util.PGobject 0x7618a385 ("2015-12-14 08:04:22-07","2019-12-14 08:04:22-07",854.06,854.06,0.00,0.00,29,0,30,0,220)]}
How do I make it come back as a clojure map?Nvm I figured it out, my query looks like this
"SELECT account FROM card_account as account, card_account_user as causer
WHERE account.card_account_id = causer.card_account_id AND causer.card_account_user_id = ?"
Any reason why all the fields from account aren’t in the map?what kind of data type is account?
@josmith2016 Try changing your query to SELECT account.* FROM card_acount as account...
-- I think Postgres is "helpfully" trying to return the whole row as an object because that's what you asked for.
hi I have a question concerning the threading macro, is this the idiomatic way to handle switching argument positions?
(def some-string "this is a string")
(defn foo []
(-> some-string
(str/split #" ")
((fn [x] (map count x))))
check out as->
https://clojuredocs.org/clojure.core/as-%3E
if I have two sets that I know that are disjoint, how can i use the data as a single set? so i don't have to union or map over a list of sets every time
With clojurescript macros, which you write in clojure, how do you handle clojurescript dependencies. Say, for example, that my macro uses clojurescript libraries. How do I ensure that the libraries are included wherever the macro is referred?
@reuben.steenekamp For your macro to use a ClojureScript library, it would have to expand to code that uses that library. One solution is to simply additionally require that library wherever the macro is referred so that the expanded code works properly. Another (perhaps easier to consume) solution could be to introduce a ClojureScript namespace to accompany the macro's namespace, and have the macro expand to calls to that ClojureScript namespace (which can then delegate to the ClojureScript library). In this secenario, if the macro namespace and accompanying ClojureScript namespace have the same name, then you benefit from implicit macro loading and simpler macro inference. This ends up allowing consuming code to simply require the ClojureScript namespace while simply referring the macro (in other words, a single require/refer instead of a require-macros along with a require of the ClojureScript library namepsace). A lot of this is covered in http://blog.fikesfarm.com/posts/2016-03-01-clojurescript-macro-sugar.html but let me know if you could use an example illustrating how this works.
In concrete terms, if your macro wants to call into some.library
, you can introduce a my.foo
split across foo.clj
which has the macro, and foo.cljs
which has a :require-macros
for my.foo
, and a :require
for some.library
, and ClojureScript functions that call into some.library
which the macro in foo.clj
expands to call.
A macro in foo.clj
might look like (defmacro abc [x] (my.foo/bar ~x))
with my.foo/bar
being a ClojureScript function that calls some function in some.library
. It is important that in foo.cljs
you (:require-macros my.foo)
.
The benefit of all of this is that some other ClojureScript namespace can simply (:require my.foo :refer [abc])
and then just use the abc
macro.
@reuben.steenekamp Thinking more on this, a concrete example is probably better than the verbiage above. Here is a gist showing a macro that uses a ClojureScript library (`clojure.zip`) https://gist.github.com/mfikes/d296af1c7621d69c5b1db9323763a6ca
@reuben.steenekamp No problem. I updated that gist (with an abc2
macro) to show how your macro can actually expand to code that directly calls into the ClojureScript library, if you don't want to call a delegating ClojureScript function. Either way works.
@justinlee It just does 🙂
But you asked, "how?". My response is that there is nothing that prevents it. Is that a sufficient answer?
my real question is to try to get some understanding of what requires this funky macro system for cljs in the first place. the existence of self-hosted systems sort of suggests that it isn’t really needed. macros are data-to-data transformations so it has always seemed weird that that’s the one thing that doesn’t work in straight cljs
Ahh, OK. I'd say that macros are "separate" in ClojureScript because ClojureScript wants to optimize by producing artifacts that are small and only contain runtime stuff. (No compiler, essentially.)
The reason macros are separate in self-hosted ClojureScript is for compatibility. There was a desire to not have self-hosted ClojureScript be a completely separate fork that ends up working with code that can't be used with JVM ClojureScript.
See the penultimate FAQ here https://github.com/clojure/clojurescript/wiki/Bootstrapped-ClojureScript-FAQ
that all makes sense at a high level, but still two things nag at me (1) separate is distinct from choosing clojure instead of clojurescript. why not separate clojurescript macros? (2) don’t macros do their thing, expand the code, and then the compiler comes through and compiles it all to js?
Yeah, it is interesting to imagine macros that call ClojureScript functions during expansion, and if the entire compiler were self-hosted, whether you could produce artifacts that are small.
why would the choice of language increase code size if the macroexpansion produces the same result?
@lee.justin.m because right now cljs compiles without running any cljs and doesn't rely on a js runtime - so the naiive way to move macro-expansion to cljs would be to put it in the emitted code and make it happen in the target vm
just a guess
that and the annoyance of making a quirk-compatible macroexpander I bet?
oh! that makes total sense to me. now i get what the compile size comments are about.
If you allow macros to call ClojureScript functions, then in theory the code the macro produces can vary at runtime, and thus you would need the compiler at runtime, which I think implies large artifacts. If the ClojureScript functions called at expansion time were pure or completely independent of runtime state, maybe it could be pulled off. Hrm.
cljs already has quirkier differences from clj in other places, so you might be able to enforce that 😄
Yeah, with a completely self-hosted compiler you could allow mixed macros and functions, so long as the macros were "well behaved" and abided by a constraint that they only use "compile-time state."
how does it work in clojure? can you go make a network call to a server in the middle of macroexpansion?
compiling clojure, should this runtime be able to launch missiles? [Y/n]
- macro by user input
i’d never considered that. super interesting. let’s inject a subtle bug into the code if the weather is nice and it’s a saturday and we are in a production environment
IMHO in good well written code they are 😄
In clojurescript, I have a bunch of networks calls that have to be made in sequence. I have the common pattern of, “do call, if error print message and bail, if okay, go to the next step”. In js, I usually deal with this kind of code by throwing an exception and dealing with it all in a catch block. Is this the suggested way of dealing with this in cljs? If I don’t do it this way, I get indentation problems as each step is in yet another else clause.
each of these is in a nested callback right?
I’m using go blocks right now, but I’m not wedded to it.
(defn complex-remote
[]
(go (let [response (<! (rpc ...))]
(if error-condition
(print "error")
(let [response (<! (rpc ...))]
(if error-condition
(print "error")
... and so on))))))
in javascript, those prints would be throws and then i’d do the print in the catch block
then the problem is nested lets, right?
you never need nested let
or - well sometimes it might be nice, but its not needed
(let [x (f) _ (println "x is" x) y (g x) ...] ...)
let allows referring to previous bindings, and you can use _ for side effecting bindings (it's idiomatic)
so you can throw at any step you like, and put all the bindings in one let block
since throwing doesn't return, you don't need it to be in an if/else, it can be in a when, and the else is just the next binding
okay so throwing is the right move in clojure too. when i read books/blogs it always seems like the section on exception handling is, “oh yea you can do this too”
@lee.justin.m you can, and in this case it's the simplest option IMHO
just make sure your try/catch does the right thing round it - you can use ex-info to construct a throwable with context data so your catch can do whatever you need
so something like this
(defn complex-remote
[]
(go
(try (let [response (<! (rpc ...))
_ (when error (throw (js/Error ..)))
response (<! (rpc ..))
_ (when error (throw (js/Error ..)))
...])
(catch js/Error e
(print ...) ...))))
you need _ on the left hand of each when
but yes, that's exactly it
not only is ex-info more powerful (it lets you accompany it with arbitrary data), (ex-info "foo happened" {:x x})
looks nicer than (js/Error. "foo happened")
in code IMHO
@lee.justin.m @noisesmith Just be careful when throwing inside a go
block — I can’t find it now but I vaguely remember might be some kind of weird behaviour?
@orestis yes I should have mentioned that explicitly, but was reassured to see this was inside an explicit try/catch which does work
Yea I read about the issue of throwing across the go boundary. But thanks because that’s a big gotcha
Hello guys, I've got a problem with Integrant running my web application. The thing is that I can sometimes run it successfully via REPL (meaning that all components are correctly initialized and application is then running). But it cannot be run with lein run
or from built uberjar (and sometimes even not from REPL) with error in the paste. I put the configuration into the pastebin link, for better clarity (it's only 90 lines long including error) https://pastebin.com/AQE9pmVp
I tried to Google it and read upon the topic however I am struggling with this with couple of hours and couldn't solve this problem 😕 I would appreciate any Integrant tips as well, I am not sure if I am using it correctly
I'm dealing with a philosophical problem/brain shift in approaching Clojure and functional programming. I'm starting out in Clojure by writing a Sudoku solver, where the basic idea is to distribute constraints from individual cells, to their rows, columns and "slabs" (3x3 subgrids), and back to other cells. So each cell is a member of three other collections, and when a cell gets renewed, all three need to know about it.
This seems contrary to the principle of immutability. I'm sure i can find workarounds, but I'm trying to learn "the Clojure way" or "the functional way" to achieve this effect, and I could use some wisdom here. Anyone care to set me straight? That would be really helpful, and appreciated, so thanks.
@steve171 the simplest transformation is often to take a function which mutates an item in a collection and make it a function that takes a state of a collection, and returns a new one. Instead of neighbors "knowing about" a change, data is just data, it doesn't do anything - but your algorithm might cue up a series of changes for the neighbors based on a change
and that cue of changes, instead of being a loop that modifies each neighbor, is a list of cells to adjust, which the algorithm is walking through and updating
@noisesmith Thanks for the suggestion. i'm going to have to think about that, but it's an interesting track to pursue. It seems to imply that each row, column and slab are independent; in particular, there are three representations of each cell, independently in each parent. That means that the updating procedure would have to be atomic across all three representations, yes?
…or there’s one representation of the board (a 9x9 grid or maybe a list of 81 cells, each holding a set of constraints)
and the update says: I just put a 3 in the center square, so add the constraint “cannot be a 3” to the remaining cells in that column, in that row, and in that slab.
various ways to “walk” the current board and produce a new one, depending how you chose to represent it. map
probably.
Neil, I've come down to the problem of "functionally" updating the board, i.e., applying a constraint to some cell and returning a revised board. My procedural brain is rebelling at the idea of copying the entire board except for one cell (especially if it's immutable once defined, so I have to special-case the copy of the cell being changed before it gets redefined). This feels like me not getting something, but it's hard to see what. When you suggest using map, do you mean, say, iterating over all the columns on a board using a function which iterates over all cells in a column, and simply returns all cells which are not the one being modified? Is this the "functional way"?
Well, suppose you’re representing the board as a vector of vectors, a 9x9 “array”.
foo.core> (def b (vec (repeat 9 (vec (repeat 9 [])))))
#'foo.core/b
foo.core> b
[[[] [] [] [] [] [] [] [] []]
[[] [] [] [] [] [] [] [] []]
[[] [] [] [] [] [] [] [] []]
[[] [] [] [] [] [] [] [] []]
[[] [] [] [] [] [] [] [] []]
[[] [] [] [] [] [] [] [] []]
[[] [] [] [] [] [] [] [] []]
[[] [] [] [] [] [] [] [] []]
[[] [] [] [] [] [] [] [] []]]
Ok, well actually, that’s a 3 dimensional array where the third dimension are the empty vectors at every cell location.
Suppose I decide to represent the “constraints” at a cell as keywords, :1
, :2
, :3
, etc.
Therefore each of those empty vectors will accumulate up to 8 constraints, at which point the value of the cell is fully determined.
To update the constraint at a given cell you use update-in
foo.core> (update-in b [0 0] conj :3)
[[[:3] [] [] [] [] [] [] [] []]
[[] [] [] [] [] [] [] [] []]
[[] [] [] [] [] [] [] [] []]
[[] [] [] [] [] [] [] [] []]
[[] [] [] [] [] [] [] [] []]
[[] [] [] [] [] [] [] [] []]
[[] [] [] [] [] [] [] [] []]
[[] [] [] [] [] [] [] [] []]
[[] [] [] [] [] [] [] [] []]]
Which returns a new board with the constraint added.
Update an entire row
foo.core> (reduce #(update-in %1 [0 %2] conj :3) b (range 9))
[[[:3] [:3] [:3] [:3] [:3] [:3] [:3] [:3] [:3]]
[[] [] [] [] [] [] [] [] []]
[[] [] [] [] [] [] [] [] []]
[[] [] [] [] [] [] [] [] []]
[[] [] [] [] [] [] [] [] []]
[[] [] [] [] [] [] [] [] []]
[[] [] [] [] [] [] [] [] []]
[[] [] [] [] [] [] [] [] []]
[[] [] [] [] [] [] [] [] []]]
where the #(update-in …)
is syntactic sugar for an anonymous function taking two arguments, the first one is the board b, and the other one is the y coordinate to be updated.or similarly can update a column
foo.core> (reduce #(update-in %1 [%2 0] conj :3) b (range 9))
[[[:3] [] [] [] [] [] [] [] []]
[[:3] [] [] [] [] [] [] [] []]
[[:3] [] [] [] [] [] [] [] []]
[[:3] [] [] [] [] [] [] [] []]
[[:3] [] [] [] [] [] [] [] []]
[[:3] [] [] [] [] [] [] [] []]
[[:3] [] [] [] [] [] [] [] []]
[[:3] [] [] [] [] [] [] [] []]
[[:3] [] [] [] [] [] [] [] []]]
not suggesting you literally use a nested vector, but just to illustrate the idea. constraints are updated by generating the list of locations to be modified, and iterating over those (with reduce
in my example) to produce a new board state.
A nested vector is pretty much what I'm after, so thanks for that. What I hadn't gotten to is update_in, and the fact that it returns a copy of the collection. That's a key pointer (so to speak) for me. Thanks Neil!
cool.
@gonewest818 Yeah, that makes sense. I think you'd still need a queuing mechanism because new constraints will accumulate faster than you apply them...
yes, I believe that’s what noisesmith was getting at.
but… the “queuing mechanism” might not be much more than a plain old list that you map over. At some level this solver is going to have a loop where it is choosing what’s the next number to place. Placing a number ripples a bunch of constraints (the queue). The resulting board state is used to choose the next number to place, which generates a new queue of changes, etc.
right, I was speaking of a queue of changes functionally not implementation wise - and yes a list would work perfectly for that
@steve171 also consider that somer operations are much easier to do with the pure functional version - for example you could create a lazy sequence of every possible placment of a number on the board, and use filter to remove the placements that break some constraint
@steve171 doesn't really help you in writing a functional version, but you might find this logic programming version interesting 🙂 https://gist.github.com/swannodette/3217582
@noisesmith I think that's an interesting alternative strategy, i.e., what do you do when there are no more numbers to place and the queue runs out?
@sundarj Thanks for that. I'll check it out. (I must be learning something; my brain hurts!)
looks like it was inspired by http://norvig.com/sudoku.html
Oh that's funny. I've followed along with Peter's Scrabble machine, but I didn't know he'd presented a Sudoku solver.