Clojurians
#clojure
<
2017-10-26
>

This page is not created by, affiliated with, or supported by Slack Technologies, Inc.

admay00:10:54

Woah, alright, that’s a lot to take in and process, haha! Thanks for all the input guys! I think I know how I’m going to approach the testing/refactoring for this!

ag01:10:16

what's the right way of dealing with clojure.edn/read-string reading strings as symbols? e.g.:

(type (clojure.edn/read-string "f8f2b6b3-39b8-4e76-a9f0-fa4a65ee225a")) -> clojure.lang.Symbol
; and I want it to be read as a string

hiredman01:10:15

it is a string

hiredman01:10:38

you passed it as a string in to read-string

ag01:10:55

no, because this works differently (type (clojure.edn/read-string "\"foo\""))

ag01:10:20

this time it's java.lang.string

hiredman01:10:24

because in edn notation a "foo" is a string, but foo is a symbol

hiredman01:10:07

reading foo as a string is not edn, so trying to get a library for parsing edn to do it is a fools errand

ag01:10:13

so that's what I'm saying, I have no way to know that this "{}" is a map until until it's "read"

ag01:10:53

I want: "{}" to be read as map; "[]" to be read as vector; "foo" to be read as "foo" -> string

hiredman01:10:35

you will have other problem as well, because not all uuids are going to be valid symbols

hiredman01:10:46

likely whatever file you are trying to read is invalid edn

hiredman01:10:19

my guess would be whoever produced it used println instead of prn

ag01:10:38

that's my point - I don't care about symbols - I want to parse maps and vectors and take everything else as strings

hiredman01:10:02

write your own parser then

ag01:10:39

look, the request wraps params like this,

{"customer-account-id" "f8f2b6b3-39b8-4e76-a9f0-fa4a65ee225a",
 "filter"              "{:date {:from nil, :to nil}, :search nil}",
 "sort"                "[:settled-at :desc]"}
on the server side I need to turn it into "normal' hash map a) need to keywordize keys - that's easy b) need to uwrap maps and vectors - what's the easiest way of doing that?

seancorfield01:10:30

I suspect you could (try (let [v (edn/read-string s)] (if (or (vector? v) (map? v)) v s)) (catch Throwable _ s))

seancorfield01:10:11

That would leave you with maps/vectors where the strings actually were EDN maps/vectors and leave you with the raw string everywhere else.

hiredman01:10:13

yeah, that is entirely different then what you first described

hiredman01:10:47

that is well formed edn, strings are quoted, you can process it with edn/read-string then walk it making whatever changes you want

sekao01:10:42

anyone have a go-to way of debouncing? in cljs i just use the google closure debounce fn, but i can't find anything for clj

ag01:10:50

I think I got slightly better idea.

(defn read-string*
  "reads-string by parsing only maps, vectors, keywords and leaving everything else as-is.
  Because `(type (clojure.edn/read-string \"foo\"))` => clojure.lang.Symbol"
  [v]
  (let [r (s/conform (s/or :r map? :r vector? :r keyword?) (read-string v))]
    (if (= r ::s/invalid) v (second r))))

seancorfield02:10:41

Bear in mind that if read-string throws an exception, you won't get back the original string -- in case v is not valid EDN.

ag02:10:47

daammmn...

nico.roos199404:10:22

Never got a fix unfortunately :disappointed:

mdrago102613:10:30

even after downgrading leiningen?

nico.roos199413:10:02

haven’t tried that yet

mdrago102613:10:36

i recommend trying it… lein downgrade 2.6.1 i think works

mdrago102613:10:43

that solved the leing ring issue for me at least

nico.roos199413:10:01

Yeah, problem is I have lein instlled through brew

nico.roos199413:10:07

and have no idea how to downgrade then :smile:

nico.roos199414:10:53

yeah, downgrading fixed the issue

nico.roos199414:10:55

thanks :slightly_smiling_face:

qqq15:10:02

is it an unofficial law in clojure that the first argument, if possible, be a collection? in order that things work nicely with swap!, update, update-in

chris15:10:55

first in some contexts, last in others

chris15:10:10

map/filter et al have it last

qqq15:10:25

ah, so it's "seq functions take seq last; collection funcs take collection first" ?

qqq15:10:34

that'd explain the filter/map case too

donaldball15:10:09

I tend to almost always order my arguments from least to most variable

qqq15:10:05

why does that make sense given: 1. clojure doesn't have nice partial application and 2. ppl generally optimzie for ->, ->>, update, swap, ...

dpsutton15:10:19

i partial a lot

donaldball15:10:37

I’m that weirdo that really like partial but mostly it’s just because I can keep track of my args cognitively easily with that heuristic

qqq15:10:13

weird; I don't think there's a single partial code in my code, I tend to use #(... %1 ... ), maybe I need to learn how to use 'partial' in clojure

donaldball15:10:51

For whatever reason my visual parser hangs on that literal lambda syntax. I’ll always either reach for partial or fn unless I’m writing throwaway

dpsutton15:10:11

update-display (partial display-error-in-zone errorzone)
          show-user (comp update-display alert-box auth/unify-response)
from a let binding. Then i can just call show-user on all of the callbacks. I unify the repsonses, turn them into the alert box map required and then update-display

alpox16:10:36

Did anyone bring re-natal with hot reloading to run? It all seems to work except the hot reloading

pesterhazy16:10:32

@alpox you need to disable the hot reloading feature in the react-native devtools; figwheel comes with its own hot reloading

pesterhazy16:10:01

all the RN packager sees is a stub that includes the JS requires; figwheel does the rest

alpox16:10:02

@pesterhazy ah alright, i’ll give it a try, thanks! I’m using intellij now and i’m not quite sure with what command i best start it. With the react-native task? Thats the only one which opens the app in my simulator.

pesterhazy17:10:14

lein figwheel and react-native run-ios or ... run-android should do the job

alpox17:10:37

Hmm since i’m working with intellij tasks and not the command line - i guess i’ll have to run both tasks - a leiningen task and a react-native one

pesterhazy17:10:41

don't forget to run re-natal use-figwheel once before that

pesterhazy17:10:01

forget about intellij for a minute and do it from the command line

pesterhazy17:10:19

you can build shortcuts for your IDE when you know it works

pesterhazy17:10:43

an IDE is only sugar for the command line

alpox17:10:04

@pesterhazy That i know, i’m usually more of a command line guy :slightly_smiling_face:

alpox17:10:09

I’ll give it a try

pesterhazy17:10:42

intellij will work fine as an editor though

scknkkrer17:10:27

You should look at Spacemacs. http://spacemacs.org — Terminal based or GUI. But powerfull. --end of commercials--

alpox17:10:12

@scknkkrer I just moved to intellij from spacemacs - for the good for that everyone working on the coming project can use the same environment

alpox17:10:21

We will have people which are not able to handle emacs right

alpox17:10:30

But thanks for the ad :smile:

scknkkrer17:10:43

No problem. :sunglasses:

scknkkrer17:10:59

Sorry for these guys, BTW.

alpox17:10:00

Well, older people have a hard time to learn a very new environment with less GUI than they are used to :smile: but yea, emacs is great

mdrago102617:10:29

great news :slightly_smiling_face:

scknkkrer17:10:02

Emacs is older than me. Maybe, older than you too. March 20, 1985 It’s birtdate. But, no problem if you return us back. Your real home. :joy:

scknkkrer17:10:46

Good luck with your project.

alpox17:10:53

@scknkkrer Thanks :slightly_smiling_face:

pesterhazy17:10:44

>>> The original EMACS was written in 1976 by David A. Moon and Guy L. Steele Jr. as a set of Editor MACroS for the TECO editor.

alpox17:10:49

I’m very new to the clojure environment, so i hope i won’t struggle too much. I want to take a go with react-native and fulcro. Hope I won’t run into too many problems :smile:

scknkkrer17:10:03

OMG. Sorry, my fault.

alpox17:10:44

Hey, hot-reload works! :smile: bit slow, but it works!

alpox17:10:56

@pesterhazy thank you :slightly_smiling_face:

noisesmith17:10:11

emacs was the first real program to use windows - which is why emacs terminology for windows and frames and such is totally different from all the apps that came later (and closer to how windows actually work in the real world)

bostonaholic17:10:38

#emacs is probably a better place for this discussion

qqq18:10:17

I have a piece of clojure data, representing hiccup. I need to go through the hiccup, andechange every ocurance of: :on-click :foo1 ==> :on-click (get kw->func-map :foo1) :on-click :handler2 ==> :on-click (get kw-func-map :handler2) Is there a standard way to do this ?

qqq18:10:27

this is the best I have so far:

(def kw->func {})


(def sample-data 
  [:div
   [:svg {:on-click :foobar}]])

(defn conv-function [x]
  (if (and (map? x)
           (:on-click x))
    (assoc x :on-click [:lookup (:on-click x)])
    x))

(clojure.walk/postwalk conv-function sample-data)

noisesmith18:10:33

@qqq I understand if the map? check is there for clarity, but it’s redundant - :on-click will only return non-nil if it can be looked up (I guess there’s a corner case of sets, but there’s nothing in hiccup that knows what to do with a set containing a keyword that I know of)

noisesmith18:10:06

also, for that general flavor of thing I have when-pred (defn when-pred [p? x] (when (p? x) x))

noisesmith18:10:30

(:on-click (when-pred map? x))

qqq18:10:12

good call on the map? // I may keep it for stylistic reasons as a "type sig" of "this is a map", but I agree with you that it's redundant

nathanmarz19:10:13

@qqq you can do that transformation much more precisely and efficiently with specter

qqq19:10:50

@nathanmarz: I agree. The problem I have with specter is that: 1. I can implement postwalk from scratch [so I understand it] 2. to this day, I haven't managed to implement a mini-specter from scratch, so it's still very magical to me

nathanmarz19:10:55

that's basically the original implementation without any of the optimizations that came later

qqq19:10:02

@nathanmarz: not until now; 30 lines is impressive; will look into it

nathanmarz19:10:13

essentially still how it works, especially transformation

qqq19:10:52

what are the complex transforms that makes it faster (and this version slower) ?

nathanmarz19:10:31

the transform implementations are still the same for the most part

nathanmarz19:10:53

ALL uses protocols to dispatch on each type, and esp. for maps uses a different implementation per map type

nathanmarz19:10:27

and then there's the inline compilation / caching system that removes most of the navigator composition overhead

nathanmarz19:10:16

that stuff doesn't matter when it comes to what's actually going on when you do transform – basic-specter captures that aspect

qqq19:10:07

right, I realize it doesn't change semnatics, I'm just curious what issues you ran into and how you overcame them

nathanmarz19:10:48

the inline compilation / caching stuff was extremely hard, optimizing the individual navigators was just a lot of digging into esoteric details of Clojure

nathanmarz19:10:33

ALL, MAP-VALS, MAP-KEYS were the most work to optimize

nathanmarz19:10:07

when specter outperforms idiomatic clojure code it's usually due to those navigators

adamfrey20:10:15

I'm seeing a weird problem with reading the new namespaced maps in a repl. I get this error in both a bare lein repl and boot repl:

user=> (defn foo []
         #:a{:b 1})
  #_=> #'user/foo
user=> (defn foo []
         #:a{:b 1}
         )
  #_=> 
user=>              java.lang.RuntimeException: EOF while reading, starting at line 1
clojure.lang.LispReader$ReaderException: java.lang.RuntimeException: EOF while reading, starting at line 1

             java.lang.RuntimeException: Unmatched delimiter: )
clojure.lang.LispReader$ReaderException: java.lang.RuntimeException: Unmatched delimiter: )

adamfrey20:10:48

it's the same exact code except the second version has a newline after the namespaced map. Can I bother someone else to try this code in their repl and see what they get? I'm on clojure 1.9.0-beta3

adamfrey20:10:29

I would like to try it in a bare (non lein/boot) clojure repl, but I'm on ubuntu and the installer only works for macos right now

adamfrey20:10:05

ok, so I tracked ^this down to being a problem with how the text is being read from the terminal

noisesmith21:10:46

it’s in the reply / nrepl layer right?

noisesmith21:10:12

you can use a bare repl by downloading the jar and running it with java, you don’t need deps to reproduce

noisesmith21:10:23

(oh - wait - the latest jars need deps, never mind)

adamfrey21:10:19

yeah @noisesmith I just followed the new instructions to get a bare clojure repl on linux and I do not see the problem there, only in lein/boot

noisesmith21:10:25

you can also make a project with only clojure.core as a dep and no code, and make and run an uberjar

noisesmith21:10:31

or lein trampoline repl

adamfrey21:10:34

so either in the reply/nrepl layer or it's a terminal thing?

noisesmith21:10:45

definitely not a terminal thing

noisesmith21:10:56

it’s a known thing in reply

noisesmith21:10:33

(unless coincidentally something else is causing the same error)

noisesmith21:10:02

I’m not certain, but it certainly looks like the issue, yes

adamfrey21:10:47

and for anyone following along it looks like the real issue isn't in reply, but actually one more dependency level down in sjacket: https://github.com/cgrand/sjacket/issues/25

qqq22:10:52

Is there a way to simplify:

(and (map? x)
                  (get x [:rewrite :on-click]))
There is no guarantee that x is a map.

noisesmith22:10:38

so that means you want false instead of nil?

noisesmith22:10:37

user=> (get "pretty much anything" [:rewrite :on-click])
nil

the2bears22:10:16

I've run into an interesting bug at work with an Apache Storm topology in Clojure. One of the bolts takes, as a :param, some seed data from a dB. This data, consisting of two queries, is done inside a pvalues expression, returning a map with two key/value pairs - one for each query essentially. Now, pvalues is implemented as a future if I'm not mistaken, and as such will cache its value for subsequent derefencing. The behavior I'm seeing is that upon a Storm restart we're getting old, stale data from this pvalues. It seems to be under circumstances when the topology is restarted round-robin with individual nodes restarted in a rolling fashion (hence the topology is never 100% off). So, could the pvalues 'state' be passed from a supervisor to another one? Curious if anyone else has run into a similar issue. We have a work-around, consisting of a complete take down of Storm and then a restart but... I guess that's SOP :slightly_smiling_face:

noisesmith22:10:48

it uses zookeeper, zookeeper is for sharing small values between processes for IPC

noisesmith22:10:08

typically one will create “ephemeral nodes” that disappear if nobody is using them

noisesmith22:10:44

there’s a program called zkCli that lets you explore the data in zookeeper as if it were a file system

the2bears22:10:21

@noisesmith thanks, I'll check that out. It's easy enough to reproduce :slightly_smiling_face:

noisesmith22:10:59

I wouldn’t be surprised if there was a command of workflow to clean-slate the Storm state

mnewhook23:10:09

can I print the address of a variable, or something which I can easily use to compare it with another instance later?

noisesmith23:10:49

@mnewhook if you var quote an argument, it’s the container and not the thing in the container. This only works for vars (usually owned by namespaces) and does not work for local bindings, which are immutable

noisesmith23:10:45

+ is the function bound to clojure.core/+, #'+ is the var that currently holds that value

noisesmith23:10:02

a convenient thing is that if you call a var, the var looks up it’s own contents and calls that for you; for values that aren’t being called you can use deref, the shorthand @, or var-get

noisesmith23:10:11

you can also look up a var by symbol via resolve, or look it up using the bindings set up in a specific namespace with ns-resolve - a tricky point is that ns-resolve doesn’t look up a var in a specific ns, it looks up a var using the rules that would be used in that ns, which includes bindings created by require, refer, use, etc.

rcustodio23:10:07

any sha1/sha256 lib recommendation?

noisesmith23:10:25

it’s like 3 lines of interop, max, you don’t need a lib

bfabry23:10:22

ya, this is our sha1 framework:

(DigestUtils/sha1Hex
                (str "classic_"
                     pcoll-name
                     "_"
                     (pr-str key-obj)))

rcustodio23:10:47

I see, thanks

bfabry23:10:01

(assuming you're in a project that already pulls in apache commons for one of the million reasons that you might)

rcustodio23:10:16

No, I don’t use apache common

bfabry23:10:25

well, that would be an option!

noisesmith23:10:27

yeah - that github gist works if you aren’t using commons, but most apps probably have commons already

bfabry23:10:47

it has loooots of really useful stuff if you don't care about jar size, and it's well maintained