Fork me on GitHub
#clojure
<
2017-01-10
>
zane00:01:48

This is huge. > Writing navigators or higher-order navigators is much simpler now. If you want to write a regular Clojure function that returns an anonymous navigator, you can now do that without sacrificing performance.

qqq00:01:50

@nathanmarz : does the following get the higher level ideas: (transform selector func data), modulo pseudo selectors like LAST and pseudo funcs like NONE, ops as follows: using selector, creates a list of "references" into data for each ref, we fun (func) on it, and put the new value in so old style coding = I need to update this data structure I "drill down" to the pieces I want to modify, update them, and "rebuild everything else" in spectre, I specify the "drill down" with the selector, and specter takes care of rebuilding/drilling down, and thus I need only specify the update function

nathanmarz00:01:18

@qqq: not sure why you call LAST pseudo, it's no different than anything else

qqq00:01:38

it's weird that it's "one location" but you can insert multiple elements there

qqq00:01:54

so you're not pointing at the last element of the list, you're pointing at the region after the alst element

nathanmarz00:01:59

i think you're referring to END

nathanmarz00:01:29

location can mean more than a specific value inside a data structure, the empty subsequence at the end of a sequence is a perfectly valid location

qqq00:01:47

Yes; appears I am confusing the two.

nathanmarz00:01:14

manipulating data structures using their inherent substructure is extremely useful and leads to very elegant code

qqq00:01:05

@nathanmarz : I'm sold; specter is awesome. Thanks for your explainations.

sova-soars-the-sora01:01:26

Hi all, my lein repl is not savvy to a .clj file I added into my /src/clj directory. It shows me plenty of autocomplete options, but not the namespace I just added. Thoughts?

jvtrigueros02:01:59

You may also need to "require" that namespace to be able to use it.

joshjones02:01:12

(use 'proj.core) OR (require '[proj.core :refer :all]) now you can (foo) all you like @sova

akiva03:01:40

Actually, I’d go with (require '[proj.core :as pcore]). It’s a good idea to use namespace aliasing for clarity.

qqq07:01:54

specter is life changing; I don't want to ask individuals to suggest other awesome libs, as that'd clog up the channel -- is there a list of other really impressive ltools? (not so much libraries for handling specific tasks, like db bindings of web servbers; but generic libraries that changes everday clojure development)

qqq09:01:37

https://clojure.org/guides/destructuring <-- when destructuring with {:keys [ ... ]} is there a way to also use an :as field ?

bronsa09:01:18

{:keys [..] :as foo}

qqq09:01:54

lol; thanks!

qqq10:01:33

I'm writing a spec. How can I check if something is an atom ? (Perferably reagent/atom should also return true).

bronsa10:01:19

there's an IAtom interface

bronsa10:01:22

or protocol in cljs

bronsa10:01:34

clojure.lang.IAtom/`cljs.core/IAtom`

qqq10:01:04

(defn my-atom? [x]
  (instance-of x clojure.lang.IAtom))
?

bronsa10:01:22

instancce-of is not a thing

bronsa10:01:29

(instance? clojure.lang.IAtom x)

qqq10:01:11

appears to work; thanks!

ustunozgur11:01:40

@qqq search for "awesome clojure" on github. there are a couple of repos.

luxbock13:01:08

is there a way to detect if I'm currently running inside a REPL (as opposed to running a JAR file via java -jar ...)?

rgorrepati13:01:42

@luxbock .. Use different entry points

luxbock13:01:53

My use case is that I want certain functions to exit when ran as a script but I don't want this to happen when I'm playing around in the REPL

rgorrepati14:01:50

@luxbock Use start/stop functions in -main, which would close any resources etc. See mount

karol.adamiec14:01:57

i have a fn with two args. One of them must be supplied. i need a default action in a let, similiar to javascript let data = arg1 ? arg1 : arg2

karol.adamiec14:01:29

any nice idiomatic way to do that? fumbling through if seems like a lot to ask...

robert-stuttaford14:01:05

(or arg “default”)

karol.adamiec14:01:23

i simplified too much 🙂. i need a transformed arg1 into a [:user/email arg1] and if no arg1 i need [:user/uuid arg2] 🙂

robert-stuttaford14:01:48

(if arg1 [:user/email arg1] [:user/uuid arg2]) 🙂

robert-stuttaford14:01:03

Clojure has no ternary operator. doesn’t need one

karol.adamiec14:01:20

still stumbling 🙂

robert-stuttaford14:01:36

you’re doing fine. keep trucking

cgrand14:01:57

@robert-stuttaford or rather Clojure has no if statement 🙂

peeja16:01:54

core.unify hasn't been touched in a while. Is it still recommended over core.logic for little bits of unification when a full logic programming system isn't needed, or should I skip straight to core.logic?

h.elmougy16:01:49

(mount/start) works just fine from repl but not loading any states from lein run or uberjav -main

tolitius16:01:51

@luxbock, @h.elmougy: > My use case is that I want certain functions to exit when ran as a script but I don't want this to happen when I'm playing around in the REPL I think the question is more about a design rather than a tool. Regardless what tool you use JVM will exit unless there are threads that are doing something. If you want "functions to exit when ran as a script" they just should not wait for anything (i.e. occupy threads / have servers running, etc.), and the program/JVM will exit. You can run the same functions form the REPL, and depending on whether they use any threads / sync / async they will run and give the control back to the REPL.

h.elmougy16:01:29

I already starting (mount/start) on a separate thread but no defstates marcos called

h.elmougy16:01:54

and the thread is a deamon thread

tolitius16:01:10

@h.elmougy, not following. is it related to @luxbock's question. and what is the problem? 🙂

h.elmougy16:01:22

@tolitius (mount/start) works just fine from repl but not loading any states from lein run or uberjav -main

tolitius17:01:56

@h.elmougy: (mount/start) is just a function. if called from -main, it will start any state that is on a classpath.

tolitius17:01:40

we can discuss it further in #mount if you'd like

h.elmougy17:01:08

@tolitius Thanks it is not started, I got them to start by importing certain states into the core namespace.

tolitius17:01:59

@h.elmougy: yep, all you need is to :require states you care about, so it is visible to the namespace you use them in. same as any other var/function. i.e. https://github.com/tolitius/stater/blob/master/neo/src/neo/app.clj

beppu18:01:32

@tolitius Those are nice examples. It makes it easier to get started with mount.

tolitius19:01:38

@beppu: great, thanks for the feedback!

sova-soars-the-sora19:01:56

Where is an appropriate channel to ask for ring help?

ghosss19:01:15

What's the proper way to generate edn from clojure data? pr-str can't be it, because (clojure.edn/read-string (pr-str #"foo")) throws. Or is there no good way to deal with regular expressions in edn?

schmee19:01:45

but you can add it as a tagged element

ghosss19:01:28

if I wrote a data reader that could read them, how could I make sure regular expressions were written with my tag?

jr19:01:24

pr-str will print it as a tagged literal

jr19:01:48

user=> (pr-str (re-pattern "foo[abc]"))
"#\"foo[abc]\""

ghosss19:01:58

sure, but clojure.edn/read-string can't handle that output, and you can't write your own edn data reader for #"

schmee19:01:44

just use your own tag like #foobar/regex instead of # and you’re good to go

ghosss19:01:18

so it sounds like I have to generate the edn myself instead of relying on anything clojure provides

ghosss19:01:57

if it were regular expressions alone, that might not be so bad, but I'm dealing with large data structures that may have regular expressions anywhere within them

schmee19:01:36

if you use your own tag instead of #, everything will work ou

ghosss19:01:27

hmm... I wonder if I can convince my team to used a patched version of Clojure

jr19:01:23

transit+edn might work

schmee19:01:28

ghosss why do you insist on making this more complicated then it is?

ghosss19:01:58

I hope I'm not. Some process gives my code some data structure that has regular expressions in it, I need to write it out to edn and have that edn read later. Before regular expressions showed up in the data structures, I could use pr-str on it and clojure.edn/read-string would read it just fine. But now that regular expressions showed up, pr-str's output isn't good anymore, and I don't see how I could tell it to output regular expressions differently. Is there a way to do that?

schmee19:01:38

ahh, now I see, lemme think a bit

bfabry19:01:14

you'll need to replace the regexes with a custom object which implements the printer protocol I think. it's a little bit of annoyance

jr19:01:32

serialize regex with transit

schmee19:01:38

ghosss sorry for sounding like an ass when I was then one who didn’t get it 🙂

ghosss19:01:20

@bfabry seems like I could use something in clojure.walk to do that, right?

bfabry19:01:42

yeah a postwalk-replace with a check on its type would do it

jr19:01:46

that's how clojurescript handles caching of analysis with regex

ghosss20:01:11

thanks all

gfredericks20:01:23

@ghosss you can override print-method for regexes if you don't mind the global change

qqq21:01:25

I have a clojure data made up of vectors, lists, and maps. I want to update each "leaf node" with "the path to the leaf node", for example

{:a {:b [:apple :orange :pear]
     :c [:juice]}
 :e [:cat :dog]}

to

{:a {:b [[[:a :b 0] :apple]
         [[:a :b 1] :orange]
         [[:a :b 2] :pear]]
     :c [[[:a :c 0] :juice]]}
 :e [[[:e 0] :cat]
     [[:e 1] :dog]
     ]}
^^ what is the simplest way to do this?

selfsame21:01:21

@qqq

(defn path-inject 
  ([col] (path-inject [] col))
  ([path col]
    (cond 
      (map? col) (into {} (map (fn [[k v]] [k (path-inject (conj path k) v)]) col))
      (vector? col) (vec (map-indexed #(path-inject (conj path %1) %2) col))
      :else [path col])))

qqq22:01:39

@selfsame: nice, thanks!

qqq22:01:04

=================================== Is there a clojure builtin for the following:

(defn const [f & args]
  (fn [& rest] (apply fa rgs)))

schmee22:01:09

do you have an example application of that function?

schmee22:01:17

just curious

manutter5122:01:48

looks like constantly

manutter5122:01:17

only not quite

jjfine22:01:57

also kinda looks like partial

bfabry22:01:38

behaviour is the same as (constantly (f args))

scriptor22:01:44

so is the idea that it'll just ignore the extra arguments in rest?

bfabry22:01:45

(assuming f is pure)

seylerius22:01:29

What's a better way to express this set of specs? Basically, I need to be able to pass a map specifying a shift or shifts (with an optional count) and an optional follower-shift(s) (again with an optional count).

(spec/def ::shift-shorthand #{:other :out :off :shift})

(spec/def ::shift (spec/and int?
                       #(> % -3)))

(spec/def ::shifts (spec/or :shifts (spec/coll-of ::shift)
                            :shift-shorthand ::shift-shortand))

(spec/def ::shifts? (spec/or ::shift ::shifts))

(spec/def ::count (spec/and int?
                       #(> % 0)))

(spec/def ::counted-shift (spec/cat ::shifts? ::count))

(spec/def ::follower ::shift)

(spec/def ::followers ::shifts)

(spec/def ::followers? ::shifts?)

(spec/def ::counted-follower ::counted-shift)

(spec/def ::rule
  (spec/keys :req [(spec/or :shift ::shifts?
                            :counted-shift ::counted-shift)]
             :opt [(spec/or :follower ::followers?
                            :counted-follower ::counted-follower)]))

seylerius22:01:03

Technically, the :other and :shift shorthands are defined relative to the shift specified for the rule.

seylerius23:01:04

And really the rules should be defined in terms of a single shift (optionally counted) and an optionally-counted follower or followers.

seylerius23:01:11

Technically, since I'm building the interface, I could simple require counts.

joshjones23:01:38

why are you defining ::follower (all versions) to be the same as ::shift (all versions)?

seylerius23:01:39

A follower is only different for the purposes of these rules in that it's the shift that follows the specified shift.

seylerius23:01:31

Basically, we're defining rules like "The same employee works shift 1 five days in a row, and then has a day :off.

bfabry23:01:09

do you need all these levels of indirection? seems like a lot could be defined inline. also there is an int-in-range?

seylerius23:01:16

Where :off references shifts [0 -1], corresponding to "unassigned" and "personal time-off request" respectively.

seylerius23:01:17

@bfabry Didn't know about int-in-range?. As for indirection, I don't know.

seylerius23:01:33

Basically, the user picks a shift from the set of shifts they've defined, specifies a count of however many in a row, optionally specifies the following shifts (what the previously specified shift gets followed by) as either a specific shift, a shorthand (`[:other :off :out]` where :other is everything that isn't the first shift), or a custom set of shifts that don't include the first shift.

seylerius23:01:47

And an optional count for the follower.

seylerius23:01:03

(counts default to 1)

joshjones23:01:30

gotta go now but may look at it later if you are still working on it -- IMO yes you can simplify most likely

seylerius23:01:35

These rules are used to solve a generalized nurse-scheduling problem.