Fork me on GitHub

Is it possible to use transducers to explode a collection? Suppose I have a transducer called (map some-fn) where some-fn returns a collection and I want each element in that collection to be returned as a top level element in the transduction process. Is that possible?


@stephenmhopper - that's what mapcat does


user=> (into [] (mapcat rest) [[1 2 3] [4 5 6] [7 8 9]]) => [2 3 5 6 8 9]


oh hey, that’s what I was looking for. thank you, @noisesmith


I have most likely a deadlock issue with a jni dll library on windows (linux and mac don't produce deadlocks for same c++ code), this happens at the point of instanciateing a class with new. Could I wrap the new call into some timeout error handler? (for debugging purposes, want to see some error instead of eternal freeze).


@hlolli this is a bit OT but if you use gdb to attach to the process you can see exactly what it was doing when it deadlocked


jdb might even be informative from a more jvm centric point of view


yes, I'm bit clueless, I'll try gdb, I guess I can find it on cygwin? jconsole doesn't detect deadlock on the java process, but this is as frozen as it gets. Thanks for the tip, didn't know about jdb


both can tell you where a certain thread is in its stack, and what the locals are - that should be enough to know how it got stuck


of course the gdb view of things will make more sense from the c lib's point of view, and hte jdb view will make more sense from the java side


I'm kinda curious why clojure.algo.generic.functor isnt advertised more


It just straight up solved every problem I've had with interfacing with libraries written in vavr


^ its a really dumb example but it turned interop from agonizing to manageable


Hi! Can I change the definition of a clojars library's private function that were used by a public function which is being used in my project, in my file that required this public function?


@cmal Depending on your use case, there might be a better answer


in general its best to keep encapsulation with the public interface your libraries provide


so if you could say more details maybe I can help you find a better answer


that will let you use a private var


This is a general pattern for managing things you might want to mock out in tests (as well as other reasons)


I think with-redefs gives you a scoped version of what you want, but there are some gotchas so be careful with concurrent code


Theres also the things that other people will tell you


those are probably much more informed opinions


@emccue that's a pretty nifty trick, I ran into issues with private functions a while back, and this would have been awesome to know


@cmal the only acceptable way to tackle this problem is to make it public in a PR/patch, send it to the author of the library, and explain your use case. All other solutions are dirty hacks


Guys! I think I found the answer to making collections in fif!


I am actually impressed


you seem to not have been eaten alive by maggots


you ARE the maggot


also, whats fif


actually, why fif


I can google the other stuff


haha, I don't know. I read some article where a guy implemented a small subset of Forth


I don't think i'm sticking with the XML stuff, i'm having a hard time deciding on variable names for this stuff


The only reason i'm continuing with making this language, is so I can maybe replace a restful API with something akin to generating data structures. Similar to something called Falcor


So just imagine a clojure server sitting somewhere, with http://localhost/api/fif sitting there, waiting for requests


Oh, the glory


It would also be cool to develop a frontend web client which can just point at random server instances with a fif repl, and poke around at the functions available, throw down a few queries


It would be like that movie... what's it called again? Hacker?


Just read the backlog, super interesting discussion with the differing views of @tbaldridge and @alexmiller


could you link to the earlier discussion? I scrolled and scrolled and seem to have missed it.


@U05092LD5 it's way up, can't find it anymore now 😕


Having ran teams whose main language was Clojure for 7+ years now, I tend to agree that pace of development is not an issue


But I do wish some libraries would be handed over to 3rd-party maintainers if they are willing to step up, core.async is a good example. I do regret that Clojure has decided it would be an ecosystem without blessed libraries and that some very simple tasks need decisions


If you look at contributor heavy projects like riemann, even dead simple things like http requests end-up being done through a number of libraries


Anyone have any advice on formatting destructuring?


I believe that is correctly formatted as I would any other nested map


There are a couple of things I could do. I could put it all on one line (Probably my preferred method). I could format over multiple lines like shown. And lastly I could avoid destructuring such a deeply nested map


Not sure what would be better if I was to avoid destructuring this nested map alltogether


Definitely leaning toward all on one line though. It is densely packed logic and perhaps that is ok?


^ That is what it look like all on one line


do you need all those names destructured?


Yea I’m using every symbol defined here


Hey Caleb! 👋 I usually avoid destructuring everything in one place with nested data


For me it's much easier to read with separate destructruing steps


Looking at your example I have absolutely no idea what's the shape of your data, and I would probably need a few good minutes to understand the input


I'd prefer a lot of (get-in input [:kw1 :kw2]), more verbose but it's easy to parse in your head


or just sequential let bindings where you destructure step by step


It would seem that if you need that many destructurings, perhaps you should split the work of that function to many smaller ones


@tatut This is being used in view code. There are sections/components in my view code where the whole map could be passed into each one. I could destructure only what I need in each component. I think that would be an improvement. My only issue is that some sections need values at all levels of depth in the map. For example one component uses the titles to construct a path. This component would still need to destructure deeply nested data.


with re-frame that would be trivial, just put all of that in the db and define subscriptions as needed


I like the “regular functions” approach, functions take as parameters what they need and return a value… without any subscription magic


still let-binding 20 names seems like it could be split to smaller pieces


@joelsanchez Wow, why didn’t I think of that?! I am using re-frame. I’m currently returning the whole object. I should definitely make subs for all of these.

👍 4

Looks like using subs in re-frame is going to be my solution here. This kind of heavy destructing is interesting to me though. I wonder if a macro like this would be a good idea.


You could represent the entire tree as the data structure it could define the variables as the provided symbols


An issue a see with this though, is that you cannot define the values of the map and the map itself at the same time


But it is very clear right away what the data structure looks like


Can I use a string as a property accessor in clojure? e.g., is there some way, given the string "yellow" to access (. Color yellow)?


@idiomancy This works, but perhaps could be improved

(defmacro str->color [s] `(. Color ~(symbol s)))


oh neat, okay, gotcha, so one uses a macro there


Hey all, I’m looking for a reliable Clojure Kafka client, any recommendations?


I settled on using the standard Java interface through java interop, was relatively straight forward (there didn’t seem to be any great clojure wrappers)


Got it, thanks!


Good advice for almost anything with a Java lib

Volodymyr Sereda15:04:09

Yes, we’re also just using the Kafka Java library. It works very well, and you can always wrap it in some Clojure code.


Im writing a command line program


This seems like an abuse of the let form


is there anyone willing to bikeshed this?


for the sake of testability i would have at this top level only printing help or passing those parsed args into a function that does all of the work and this top level just parses and either prints the help or invokes that function


also passing a vector of expected parsed args would make this a bit more readable of what you expect to be in that args return value but this looks simple enough that it might not matter. but other than that it's not that abusive. (not a big fan of a system exit in a let binding for sure though)


marginally better


Do namespaced keywords have to follow the parent namespace, or are they namespaced by their closest context/object. I know ::somekw will take the top level, but should I use :some-ns/kw only when referencing or also definining?


i'm partial to this:

(defn write-csv [{:keys [output-file board-name]}]
  (let [client (make-li-client output-file board-name)]
    (with-open [writer (io/writer output-file)]
      (->> (all-messages client board-name)
           (map to-csv-format)
           (csv/write-csv writer)))))

(defn -main [& args]
  (let [options (parse-args args)]
    (if (:help options)
      (do (println summary)
          (System/exit 0))
      (write-csv options))))


I also prefer that


now the writer is testable and invocable from the rpel rather than just from the cli


The Options is a map with 7 keys


which is partially why I didnt jump to the destructuring


but even without that I like your approach better


where can i find a list of valid var characters? want to make sure that $ is a valid function name and not just happens to be right now


I think that's the closest thing to an official list

Alex Miller (Clojure team)16:04:30

that’s certainly used extensively in Datomic and unlikely to be made an invalid symbol


I think it's somewhat fair to assume the set of valid characters won't change. I know <>=&%$ also works, although you better be careful with & and % because some macros consider some symbols with those two chars as special.


@alexmiller its used in datomic but always in a quoted vector though right? or are you speaking internally? (ie, '[find: ... :in $ ....)

Alex Miller (Clojure team)17:04:30

why does it matter if it’s in a quoted vector?


i guess that solves it then. I thought it might change the considerations. thanks for your clarification 🙂

Alex Miller (Clojure team)17:04:22

quoting just prevents evaluation, doesn’t affect reading


i didn't realize var names === valid symbosl but i guess it makes sense


thank you very much

Alex Miller (Clojure team)17:04:41

there is nothing special about var names - they are just symbols

👍 4
Alex Miller (Clojure team)17:04:24

the main considerations are really in the reader to make sure that we can differentiate them from some other token

Alex Miller (Clojure team)17:04:06

so like a symbol can’t start with a : because it would then conflict with keywords


or .foo and interop, right

Alex Miller (Clojure team)17:04:30

there are no such conflicts with $ and seems unlikely there will be in the future


@devn sentry works really well


I want to add some vars to an existing namespace (e.g. clojure.spec.alpha). I create a file and use (in-ns 'clojure.spec.alpha), then define some vars. But when I require clojure.spec.alpha in other files, the new vars I defined are not loaded. Is there a way to force the new vars to be loaded in the clojure.spec.alpha ns?

Alex Miller (Clojure team)20:04:54

I think you need to be more explicit about what you’re trying - can you show what you’re doing at the repl?


I decided to change tact, but it’s not about the REPL. It’s about creating a new file that I wanted to be in another ns. I figured out that explicitly :requireing the original namespace of the new file solves the problem, but it’s tedious.


Is it common practice to have a :type key in clojure maps, with a keyword indicating the “type” of the entity that the map is representing?


Maybe I should ask that in #beginners


@hmaurer we don't have any key like that in any of our maps here 🙂


But if you do, make sure to namespace it.


@the2bears do you have some way of describing what a map represents then? beyond just the keys it contains


spec does that in a way, but we don't use anything else to describe our maps, other than documentation


@the2bears thats not completely true, you can use specs for generative testing with clojure.test.check


@sveri I meant we don't have anything else for describing maps, not what spec is capable of.


ah, ok, sorry, I misunderstood you then.

👍 4

Yeah, I edited my original comment as it was pretty ambiguous.


🙂 That happens to me all the time.


I’m trying to import vars from one namespace into another like:

(defmacro import-def
  "import a single fn or var
   (import-def a b) => (def b a/b)
  [from-ns def-name]
  (let [from-sym# (symbol (str from-ns) (str def-name))]
       (def ~def-name (var ~from-sym#))
       (reset-meta! (var ~def-name) (meta (var ~from-sym#))))))

(defmacro import-vars
  "import multiple defs from multiple namespaces
   works for vars and fns. not macros.
   (same syntax as potemkin.namespaces/import-vars)
     [m.n.ns1 a b]
     [x.y.ns2 d e f]) =>
   (def a m.n.ns1/a)
   (def b m.n.ns1/b)
   (def d m.n.ns2/d)
    ... etc
  [& imports]
  (let [expanded-imports (for [[from-ns & defs] imports
                               d defs]
                           `(import-def ~from-ns ~d))]
    `(do [email protected])))

(defmacro import-from-ns
  (let [publics (keys (ns-publics ns))]
    `(import-vars [~ns [email protected]])))
But (import-from-ns clojure.spec.alpha) is returning Unable to resolve symbol: spec in this context. If I evaluate its macroexpansion, no such error occurs.

Alex Miller (Clojure team)21:04:15

if you want to do this (for the record, I personally think it’s a bad idea), there are things in potemkin for this


Yes, it’s a bad idea, it’s not my idea, and I need it to be cljs compatible


Here’s all the above in a single macro:

(defmacro import-from-ns
  (let [publics# (keys (ns-publics ns))]
       [email protected](for [v publics#]
           (let [from-sym# (symbol (str ns) (str v))]
                (def ~v (var ~from-sym#))
                (reset-meta! (var ~v) (meta (var ~from-sym#)))))))))