This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2015-07-22
Channels
- # admin-announcements (22)
- # boot (109)
- # cider (119)
- # cljs-dev (19)
- # clojure (181)
- # clojure-berlin (3)
- # clojure-dev (10)
- # clojure-japan (10)
- # clojure-korea (2)
- # clojure-russia (105)
- # clojure-sg (1)
- # clojure-spain (2)
- # clojurescript (53)
- # code-reviews (2)
- # core-async (4)
- # datomic (2)
- # editors (21)
- # instaparse (5)
- # jobs (1)
- # ldnclj (12)
- # off-topic (2)
- # onyx (146)
Hi if I have a fn called foo, and then I want to memoize it, what is the conventions for naming the original fn, and the memoized fn var?
@jonpither: http://clojuredocs.org/clojure.core/memoize they use postfix "-memo" and prefix "m-" in the examples
jonpither: i do a normal defn and then a separate (def memo-name (memoize that defn)) so that i can easily switch between the two during dev
for the cases where you know you’re good with memoized only, i’ve seen (def fn-name (memoize (fn [args] …))) too
like reading template from disk, that sort of thing
tangential, but cool: we’re using https://github.com/strongh/crache to provide core.memoize a redis backend
ok, my mistake was probably to hide the memoization from the caller, but having a fn like memo-foo or m-foo makes things more explicit and sounds good to me
yeah. as with any cache, you want a hard-refresh button
@robert-stuttaford: sounds cool, we did a similar thing with memcached once
did it work? i looked for a memcached one but found nothing
we’d actually prefer that as we already have MC for Datomic
it’d mean one less piece of infrastructure
oh you legend
(you mean there are people who don’t? 😁)
that’d be dandy, thank you!
The MailOnline used to have this public, so I don't think they will shoot me for publishing that innocuous code. It's since been converted to stuarts pattern
where does it become a core.cache / core.memoize backend?
that’s the piece i was missing
we didn't port it to core.cache, we just had fns (get-from-cache, and cache-miss). with (:client component), you can easily do .get, .set and .delete - you can easily take that and do a memoize thing I would think
gotcha, thanks
we had a ns that was a custom cache thing, but yeah we prob should've ported it to something more standard
anyone know of an ‘expect’ type of library for Clojure? Googling mostly brings up testing related libraries.
looks like there is expect4j
Java lib
nah, that’s a testing framework
I’m talking about the classic expect library from TCL, for working with interactive shell commands
There is a Java lib: https://code.google.com/p/expect4j/
oh, interesting
was hoping there was something more Clojurey
what usage do you have in mind? expect seems to be very shell oriented, why do you want it to be Clojurey?
calling out to keytool/openssl
both prompt for user input
Ah cool.
the java API looks horrible
cpmcdaniel: I have thought about how nice it would be to have a clojury expect
timothypratley: I would want a clojure expect because expect is about scripting what are meant to be interactive programs, so having a good high level language that can concisely express conditions without adding unneeded complexity is a major bonus
of course expect would not be needed if people did the sensible thing and wrote the non-interactive batch util first, then built the interactive tool on top of it
@cpmcdaniel: Interacting with command-line processes from Java can be difficult, e.g. http://blog.headius.com/2013/06/the-pain-of-broken-subprocess.html
"Unfortunately, the cake is a lie."
bronsa: have you played with running Clojure's tests as part of the (load "/clojure.core")
test?
seems like TEMJVM will happily emit all of Core, but some stuff breaks and sniffing out what is a pain point.
@arrdem: no, there is some stuff that's known to be broken by temjvm. e.g. ns-interns or one of the ns- functions, don't really remember which one
@arrdem: this because temjvm enforces type hints on args. will probably need to change in the future or be optional
well, I wouldn't say wrong -- the doc is clear that type hints are not enforced so it's technically ok to type hint with a wrong class if you never use interop on that arg
@bronsa: I don't remember, an obvious test case I wrote yesterday didn't function as expected and it looks like I chucked it. I'll try to get you a new case and a ticket in a minute.
@bronsa: waiting on the next thing at work so TEMJVM is my top prio. would you rather get respond eventually emails or slack pings.
@arrdem I don't understand the english of your question, you might need even more coffee
since I don't expect you to be online and taking questions all day would you rather that I just email you crud rather than optimistically pinging you here
@arrdem you don't use good ol' irc anymore? anyway either is fine, I get slack notifications on my mobile when I'm offline
ianbishop: well those strings don't match in the second example do they?
ianbishop: destructuring is weird (let [{:keys {a b c d}} {:a 0 :b 1 :c 2 :d 3}] [a b c d]) => [nil nil nil nil]
it doesn't really detect errors, or do sensible things when you make errors even
Yeah, I just noticed the new [:a :b] destructuring. Seems like a bad idea imo. Symbol hiding + has really weird results (i.e. ":a" example)
"the new [:a :b] destructuring" -> it isn't new, it's a crappy thing that works by accident
there's lots of crappy things that work by accident in destructuring (or things that fail and give no indication they did so)
It isn't new? I tried it in tryclj and it didn't work but it did work on a 1.7 repl. I assumed it had just been added.
hmm... I don't think it's especially recent, I could be wrong though
@bronsa: okay I got emitter test coverage up to about 76% without doing anything too crazy. gonna need some help and odd class access cases to go above this so calling it here. found an issue with recur, but locking is behaving for me.
@ianbishop: but destructuring has allowed weird unreported errors for as long as it has existed
@ianbishop: my example (accidental usage of {} instead of [], leading to all keys binding to nil) has identical behavior in tryclj
@noisesmith: I've seen people use the nested map destructuring and that even blew me away that it works. Craziness
that, at least, is intentional and useful
oh for sure, it gets pretty weird given that you can also rebind it to a different symbol. I'll probably keep mandating just keeping it simple (i.e. :keys, :strs, vector destructring etc.)
in project.clj I specified it as 1.7.0, but the repl is using 1.6.0 and lein deps :tree shows no sign of clojure 1.6.0
I'm pretty sure some dependency is pulling it in but not showing the conflict in lein deps :tree
Here is a gist with the project.clj and lein deps :tree https://gist.github.com/bensu/7d533b90c3e6e3907df2
@bensu what happens if you rm -rf ~/.m2/repository/org/clojure/clojure/
and start your repl again?
@rauh: something weid. It downloads 1.7.0, 1.7.0-RC1, and 1.4.0, and then shows me the same 1.6.0 repl
Destructuring with keywords like (let [{:keys [:a :b]} ...]
is not accidental. It was a feature introduced in Clojure 1.6: https://github.com/clojure/clojure/blob/clojure-1.6.0/changes.md#22-map-destructuring-extended-to-support-namespaced-keys
@stuartsierra his example is using :strs, not :keys
the problem is that I'm very lein dependent and I don't know how to start a repl without lein while populating the path with deps
@bensu: it's possible one of your dependencies did a naughty thing and AOT'ed clojure 1.6 inside the jar
Yeah may as well just try a lein clean
and a mv ~/.m2 ~/.m2-naughty
and see what that does
i've shell-scripted up a way to find out which, when i've run into this in the past
but it will take a long times. Thanks @rauh @trptcolin
something like for jar in $LIST_OF_JARS; do echo $jar; jar tf $jar | grep "clojure/core__init.class"
@trptcolin: I'll try your script later thanks!
here's the real thing that'd find the issue i'm talking about if it's there: for jar in $(lein classpath | tr ':' '\n' | grep ".jar$"); do echo Checking $jar...; jar tf $jar | grep "clojure/core__init.class"; done
DEBUG=1 lein repl
shows a bit of info... and have you tried to create a new project with no dependencies, then add the ones from the project in chunks doing a binary search, to find if it's one of them?
@trptcolin: that script is genius, but it only grepped clojure 1.7
@bensu: sorry - i jumped to the fancy obscure issue instead of reading your gist. you have :eval-in-leiningen true
in your project.clj
i believe that'll put leiningen on the bootclasspath, so lein's deps will take precedence over any of yours
I’ve been debugging some code and put in log statements that have helped me find what’s going on. I’m thinking of leaving them in, but commented out, so if I need to later do something simliar they are already there. Thoughts on pros and cons?
magnars: most of the nil punners are collection operations. There is a history in lisp of treating an empty collection as if it were nil and visa-versa.
there's no such tradition for strings/numbers (unlike eg C, with empty string and 0)
Nil punning (mentioned at http://clojure.org) http://clojure.org/lazy#Making Clojure Lazier--The victim - nil punning
The victim - nil punning One of the nice things about CL's cons using nil for end-of-list is that, when coupled with nil's testability in conditionals, cons-returning functions could be used like predicates. Now only seq and next can be used in that manner - map, filter etc cannot. Note that much of the economy of the seq/nil dyad still applies, e.g. the use of when in map above.
it's considered idiomatic to call seq when checking for not-empty. I prefer to do that to make it obvious rather than call seq on a return value of some seq stuff and use the return value in an if
directly.
(clojure.walk/postwalk
#(if (:type %) %)
[{:fruit :apple :color :red}
{:fruit :orange :color :orange}
{:children [{:fruit :apple :color :green}]}])
I want this output: [{:type :apple :color :red} {:type :orang :color :orange} {:type :apple :color :green}]
how about something like (defn nested-map-seq [m] (mapcat (fn [e] (if (map? (val e)) (nested-map-seq (val e)) [e])) m))
nice, that works with maps but not vectors, guess I didn’t specify that it should work with any nested clojure data structure
Not super elegant, but seems to do the trick:
(defn flatten-map-entries [x]
(cond
(map? x) (mapcat (fn [[_ v :as e]]
(if (or (map? v) (coll? v))
(flatten-map-entries v)
[e]))
x)
(coll? x) (mapcat flatten-map-entries x)
(instance? clojure.lang.IMapEntry x) [x]
:else nil))
(flatten-map-entries {:a {:b 1 :c [{:d :e} {:f {:g :h}} “blah”]} :i :j})
;; => ([:b 1] [:d :e] [:g :h] [:i :j])
i think using clojure.walk might be wrong approach because it preserves original types
thanks @loganlinn, trying it out now