Fork me on GitHub
#clojure
<
2017-06-17
>
lvh01:06:35

Is there a transducer, outside of christophe grand’s x/into, that adds elements? I have a blacklist xf that removes stuff, and want a whitelist xf.

lvh03:06:09

wait, conj is a transducer now?

noisesmith03:06:26

mapcat is a transducer, and can return 0 or more items for each call so it effectively can insert new items into a result

mpenet08:06:46

Or just cat 😻 (+into)

rauh08:06:57

@lvh A transducer is just a function that, if called with a reducing function, will return a reducing function. So actually, identity is a transducer.

rauh08:06:41

Fun fact: this also works:

(reduce
  ((map (fn [x] x)) conj)
  [] (range 3))

(transduce
  (constantly conj)
  nil [] (range 3))

matan10:06:38

So, after few projects with clojure, I still find the following task ridiculously inefficient compared to some other languages: figuring out the structure of some data when coming back to code no longer in my mental buffers. Any expert advice?

matan10:06:20

As an aside on it, I have found clojure.inspect/inspect-tree quite awkward in its display paradigm, after several hours of usage still haven't gotten used to the way it redundantly details the data as you drill in. Although I perfectly understand it sits well with some smarter people, I find it horrific for drawing the structure of a piece of data without getting lost 🙂

matan10:06:26

What would be your advice for very effectively examining the structure of data?

rauh11:06:13

@matan Rigth after 90% of my functions I add example invocation with example data. Example:

(defn preload-items [xs]
  ....)
#_(preload-items (db/items-by-filter :item/due true))

rauh11:06:03

Often even multiple #_ comments. Makes it super easy to REPL. Partially eval the argument to see what is a good example of being passed. New developer cans quickly get familiar

rauh11:06:21

I have thousands of these #_ comments, and I use them a TON.

stuarthalloway12:06:26

also I would love to see a (or many) better inspect-tree choices 🙂

matan13:06:14

@rauh @stuarthalloway thanks. I am still waiting for 1.9 to get started with clojure.spec

matan13:06:05

I usually add tests next to non-obvious functions, but vai with-test not as comments @rauh That doesn't solve my itch though when data has non trivial structure.

stuarthalloway13:06:25

@matan I haven’t tried https://github.com/tonsky/clojure-future-spec but you might consider that for 1.8

matan13:06:24

Yes I know about it, but have been burned by chasing changes in backported libraries before

matan13:06:07

Am I like the only person not using clojure.spec out here already?

rauh13:06:47

@matan The comments aren't really test, they're examples. Without side-effects obviously.

rauh13:06:54

Even a spec can be tough to read, and the way that everything is kind of a lookup in the registry doesn't make it easy to understand at first sight. So I don't think it'd help in your use case

matan13:06:10

I hear you

rauh13:06:39

You can eval every arg separately in your REPL on the example invokation. That gives you the data that the function expects right away.

matan13:06:16

Sometimes I wish to traverse the data, not only know the structure, in e.g. javascript, the browser console lets you do that. Maybe I should tweak inspect-tree towards more standard behavior 🙂 not really sure where in the code does it determine what/how to display for child nodes when expanded. https://github.com/clojure/clojure/blob/f572a60262852af68cdb561784a517143a5847cf/src/clj/clojure/inspector.clj#L91 I guess @alexmiller would know 🙂

matan13:06:48

@rauh admittedly I prefer tests, they live with your code. somehow people in clojure think that once they've written a function and tested it in the repl, it will work forever 🙂 maybe they don't work much in teams. But thanks for the suggestions!

stuarthalloway14:06:07

@matan I don’t think it is an “individual vs. team” problem — it is more about whether you change working code, or leave it alone

stuarthalloway14:06:52

@matan a better inspect-tree would be awesome! 🙂

matan14:06:00

@stuarthalloway The code of clojure inspect is quite simple, but I get lost as to where it determines what to show for a node

stuarthalloway14:06:27

@matan replace it with a multimethod driven by your data

stuarthalloway14:06:38

then you can have a default impl that does something plain

stuarthalloway14:06:56

and open dispatch to plugging in renderers

stuarthalloway14:06:40

of course once you do that, it is likely that the best way to choose a renderer is … by spec! 🙂

pwrflx15:06:36

hi! maybe a very basic question, but what's the shortcut to exit the stacktrace view of cider? (apart from C-x K to kill buffer)

hlolli15:06:32

(defn destructured [& {:keys [a b]
               :or {a 1 b 2} :as env}]
  env)

(destructured)
=> nil
Is there a way to collect the env along with the or values so that env returns
=> {:a 1 :b 2}

pwrflx15:06:21

@hlolli damn, thx 🙂

pwrflx15:06:32

@hlolli how to find out such btw? I've looked through the menus and did not find "h" next to any of the menu items..

pwrflx15:06:05

is there maybe a "show all shortcuts that make sense in the current context" function?

hlolli15:06:20

Maybe there exists one, as for the stacktrace buffer, it's common in emacs when you compile, that you get a buffer that is exitable with q like when you install a package via package-install. Many years of using emacs and googling stackoverflow helps.

noisesmith15:06:47

there's an emacs command that shows local keybindings

pwrflx15:06:48

@hlolli yes, that's whats missing for me. thanks!

noisesmith15:06:33

@hlolli you would need to construct the map by hand, I would use merge instead of or in that case

noisesmith15:06:40

(defn destructured
  [& {:keys [a b] :as env}]
  (merge {:a 1 :b 2} env))

hlolli15:06:43

@noisesmith thanks, I think I'll go for merge. Was bit unintuitive behaviour I thought.

noisesmith15:06:57

:as is meant to return your original input

hlolli15:06:14

and :or to be default for missing original input 😕

hlolli15:06:42

tja ok, I can see when seeing the real inputs matters as well

noisesmith16:06:25

yeah, usually if I use :as it's because I want to use parts of it that aren't captured in the destructure itself, later on

kaosko16:06:49

argh, how do I wrap a plain Undertow handler around a Ring handler?

dpsutton17:06:14

why can i map #(Integer/parseInt %) but not just Integer/parseInt

dpsutton17:06:26

the javadocs seem to say that it's a static method

noisesmith17:06:13

methods are not first class data on the vm

noisesmith17:06:32

you need an object to put on the stack, a clojure function is an object so it works

noisesmith17:06:17

clojure could hide this by automatically turning method names as args into anonymous functions, but instead exposes this

phill17:06:16

A static method name might correspond to numerous Method objects (differing by arity) so it's not clear what Object to use . . . so the anonymous function would be inefficient

noisesmith17:06:48

if automatically generated? yeah

noisesmith17:06:38

wait, is there actually such thing as a Method object? (other than a representation used by reflection...)

phill17:06:33

I meant java.lang.reflect.Method

noisesmith17:06:44

OK - thanks for clarifying - because if Methods were directly things my logic (and my understanding of how any of this works) kind of falls apart

noisesmith17:06:55

that's a corner of the vm I keep intending to learn more about

cryan17:06:25

using cljs + figwheel + reagent. after adding a new dependency in a namespace using require, do i need to do anything else? if i reload the page i get errors about ReactDOM missing, despite everything being ok before the page load.

noisesmith18:06:09

if you changed project.clj to add a new dep, that often requires a clean restart of figwheel in my experience

cryan18:06:12

stop fig, lein clean then lein figwheel right?

noisesmith18:06:36

yeah, that's how I typically do it

noisesmith18:06:59

because figwheel uses your project.clj to start up, and I'm not sure it can hot-reload properly when it changes

noisesmith18:06:13

I admit, a lot of my workflow around figwheel is voodoo / habit

cryan18:06:17

i must have something else borked. i've had reagent anyway, was working until i reloaded the page

cryan18:06:36

removing react-datetime from project.clj seemed to fix it. maybe it was clobbering something in reagent

bradford21:06:01

OK, I think I've lost my mind with some core.async fun, but I've narrowed down the problem. I have a program that's 2 threads: One does put! to clients expecting work (it also does a heartbeat with alts!). It gets this work from some HTTP POSTs. The other does <!! expecting the work results. The problem is that the put! seems to be getting eval'd after the <!!, leading to all kinds of weird out-of-order problems. How do I force things to be eval'd immediately?

bradford21:06:25

I have large buffers so it's not like that's blocking...

noisesmith22:06:34

why would calling <!! in one thread and put! in another later cause any order problems?

noisesmith22:06:07

you don't provide enough info to know what the fix is, but the actual purpose of core.async is to coordinate between threads...

bradford22:06:43

That's what I'm wondering, too. (It's actually several layers deep involving Server-Sent events, but I'm trying to be brief. I wrote about it here: https://groups.google.com/forum/#!topic/pedestal-users/XPQ_OnRErDA)

noisesmith22:06:20

so that's just the code writing to the channels - I probably would need to understand pedestal to understand the consuming side...