Fork me on GitHub
#clojure
<
2017-07-11
>
tjscollins00:07:14

Is there some kind of shortcut for programmatically associating a symbol with it's same-name key? Sort of the inverse of {:keys [a b c d]}, instead of having to type {:a a :b b :c c :d d} to create a map.

noisesmith00:07:48

and it's totally legit to just copy/paste one function from that lib if you don't need the rest IMHO

tjscollins01:07:02

Thanks, just what I was looking for

tjscollins01:07:11

No, zipmap still requires you to write you your keys. I was looking for something equivalent to JS's {a, b, c, d} notation which produces the equivalent of {:a a :b b :c c :d d} The keyed macro in flatland does exactly that.

tjscollins01:07:06

With the macro (keyed [a b c d]) becomes {:a a :b b :c c :d d}

razum2um05:07:18

@schmee @hiredman I’m the author, but frankly speaking, haven’t used it for long πŸ™‚ can we solve this?

seancorfield05:07:12

@razum2um looks like you'd need exclusions in there to avoid certain sym values (any primitive Java type symbols)

srinidagda05:07:12

I am new to clojure-api. I develop small app using clojure-api. I have done DB connection, Logs capturing mechanism in my APP. I need help in exception handling mechanism. Is there any library to catch exception all types of exception and to send exception to developer mail?

seancorfield05:07:21

@srinidagda A Google/Bing search reveals lots of Clojure wrappers for SMTP mail but, to be honest, I'd just use javax.mail directly. It's not hard.

srinidagda05:07:08

@seancorfield Okay. Thanks for quick reply.

seancorfield05:07:21

Sending email to developers every time you get an exception is... less than best practice... You could cause a denial of service attack on your own email provider if you app goes wrong. I definitely would not recommend that approach.

mccraigmccraig06:07:17

@srinidagda we use http://sentry.io for such exception capturing purposes... and there are many similar services out there

srinidagda06:07:34

@mccraigmccraig, @seancorfield Okay. Thanks for valuable suggestions.

shidima_07:07:33

How would I wrap this in a swap! ?

(map #(make-boolean! %) @items)

pkova07:07:36

(swap! items #(map make-boolean! %))

shidima_11:07:17

Tnx, that did the trick

pkova07:07:40

that's one way to do it

nha09:07:18

Is there a way to tell lein repl to not go check the dependencies? (if I have no internet or the artefact server is down?)

bnvinay9209:07:28

-o for offlinemode

nha09:07:26

export LEIN_OFFLINE=true && lein repl seems to work. Tried lein -o repl and lein repl -o but they still seem to go look for dependencies

pesterhazy10:07:29

@nha, do you have SNAPSHOT dependencies in your project.clj?

nha10:07:22

Had one, thanks πŸ™‚

nha10:07:32

Yes, just did that πŸ™‚

pesterhazy10:07:19

@kunzler looks great as a series of forms typed into the repl. For me the next step would be to copy it to a file and refactor into functions. Idiomatic clojure meant for .clj files (i.e. not typed ad hoc into a repl) eschews dynamic defs

pesterhazy10:07:59

in this case, it could look like this:

(let [cc (read-line), startswith (first cc), credit-card (case ...)] (println "credit card:" credit-card))

pesterhazy10:07:24

(of course you shouldn't type it all in a single line, I was too lazy to use an editor)

kunzler10:07:10

@pesterhazy thanks for that. I'm stuck on a my chromebook using an online repl So I think I'll have to try it on an editor later. I appreciate the insight

pesterhazy10:07:36

ah nice, which online repl do you use?

kunzler10:07:30

It has its limitations but is sufficient enough to play a bit with clojure

pesterhazy10:07:06

it's quite fast

kunzler10:07:30

It's the best I've found

kunzler10:07:31

It's been a bit rough learning clojure. Probably because it's new enough that there aren't as many resources available compared to other languages

kunzler10:07:03

a lot of what I find seems to be targeted at more advanced users

kunzler10:07:00

anyway, thanks again. I'll have to pop in some more

shidima_11:07:54

https://www.reddit.com/r/Clojure/ also has a nice list of resources

lwhorton12:07:56

if I want to implement an n-node tree structure in clj, where each node can be one of a few different β€œtypes”, and wanted to use spec to describe the data. what’s a good option for polymorphism on the standard tree functions? 1) define a node that can be one of (s/def ::node #{:node/a :node/b :node/c ...etc}) , and each node has a corresponding spec and defrecord. these records all implement some sort of INode protocol for insertion, lookup, etc. 2) define a node that’s a simple map with a :type property. standard tree functions will all be multimethods dispatching on the type of a node. define a more generic spec that uses a lot of (s/multi-spec). 3) … ?

hcarvalhoaves17:07:23

lwhorton: 2) map and multimethod dispatch on some key. any code can consume nested maps and mutate it conforming to the spec. I would avoid the 1) OO trap

lwhorton17:07:31

what’s the issue with using records and protocols in #1?

hcarvalhoaves18:07:06

unnecessary bundling data + behaviour.

lwhorton19:07:24

hmm. i always seem to have a hard time pinning down when to use a protocl

hcarvalhoaves20:07:37

generally, it's useful when 1) you're interop-ing w/ java (so you can use extend-protocol and do type-based dispatch) 2) you create a protocol + record to manage state lifecycle

hcarvalhoaves20:07:42

otherwise, if you're just manipulating data (not state), simple data structures + the ad-hoc dispatch available w/ multimethods works nice and is more flexible/open

hcarvalhoaves20:07:41

in other words... type-based (in Clojure case, actual Java types) dispatch = nominal typing, ad-hoc dispatch = more like structural typing

lwhorton20:07:22

much to ponder. thanks for letting me take your time, btw

lwhorton12:07:36

the problem i’m trying to model is a hierarchy-tree with directories, files, drives, etc.

axl31614:07:42

What's a good lightweight way of managing configurations in a clojure project? Like environment type stuff? Urls, user/passwords, etc?

michaellindon14:07:29

" Expresso makes great use of clojure’s abstraction mechanism like protocols and multimethods and uses a datadriven approach where possible." what does "datadriven" mean in this context? πŸ™‚

sundarj15:07:15

to me, data-driven means that the most fundamental abstraction in your code is just clojure's data structures, rather than functions, or macros, or protocols, etc your program is controlled and organised in terms of data, with map, assoc and so forth being your tools of choice http://www.lispcast.com/data-functions-macros-why http://blog.cognitect.com/blog/2016/6/28/the-new-normal-data-leverage

sundarj15:07:16

you could say that datascript and datomic are data-driven databases, compared to something like MariaDB

sundarj16:07:31

there's also this interview with Rich - https://gist.github.com/rduplain/c474a80d173e6ae78980b91bc92f43d1 (ctrl-f for "information")

michaellindon02:07:38

Hey @U61HA86AG , thanks for the links

michaellindon02:07:06

Sorry for the late reply, I took some time to read the articles. I think I get the gist of what is meant by data-driven. I never learned Object Oriented design patterns anyway, so its hard for me to contrast what I'm doing in clojure against say, java.

michaellindon02:07:39

I am curious about the following, isn't creation of a record and association protocols a more object oritented, less data-driven approach?

michaellindon02:07:13

For example, a data-driven approach to me would just be an associated map. Maybe it has a type keyword. I can write a function which looks up :type in the map and does something with the corresponding value

michaellindon02:07:36

whereas creating a new record seems similar to creating a new object, and writing protocols seems to me to be like creating methods

michaellindon02:07:15

i find it hard to reconcile my use of records and protocols with a data-driven approach

michaellindon02:07:20

can you explain?

sundarj15:07:56

yes, you have that correct. Protocols and Records arent simple data-types, you should only use them when you need something more abstract/powerful/clear than simple data-types can offer

sundarj15:07:07

data-driven doesnt mean only use simple data types

sundarj15:07:33

it means reach for them first, and use more meaty abstractions where data falls down

sundarj15:07:50

Records and Protocols exist for a reason, the key is to use them when they make sense and are needed, but to use simple data as much as you can (within reason)

mpenet15:07:06

+1 for aero

axl31615:07:53

Thanks guys! I'll check them out

fenton19:07:11

Anything more idomatic?

bfabry19:07:08

aside from "I hope this isn't a real system" the clojure looks good

joshjones19:07:12

@fenton it is clear and you will find different opinions on this as it’s largely a question of style and idioms. personally, I would either pass in the valid users:

(defn valid-user? [users username password] ...
or, close over them and return a function:
(defn valid-user-fn [users]
  (fn [username password]

joshjones19:07:36

this way you avoid the global def and it becomes more easily testable

joshjones19:07:37

stylistically, I don’t like the threading macro as you’re not really transforming a piece of data, threading it, as it’s often used. I’d prefer some:

(defn valid-user-fn [users]
  (fn [username password]
    (some (fn [{u ::user/name p ::user/password}]
            (and (= u username)
                 (= p password)))
          users)))

zetafish19:07:08

(defn valid-users
  [username password]
  (->> users
       (map (juxt :user/name :user/password))
       (some #(= [username password] %))))

joshjones19:07:14

Now you can make your function:

(let [valid-user? (valid-user-fn master-users-list)]
  ;; now use valid-user? as you wish...
  (if (valid-user? "bob" "abc123")
    ...
and if you want to use a different set of username/passwords, you’re not tied to any particular one. just make the new valid-user? function by calling valid-user-fn with your list

fenton19:07:32

@zetafish @joshjones thanks this is what I was looking for... both great suggestions. @bfabry lol, right not a real system...lol... just creating an om-next tutorial, so just for edification purposes! πŸ™‚

rinaldi21:07:50

How can I get the total bytes of an input stream in Clojure?

hlolli21:07:32

Is this a bug?

(defn callable
  [fun]
  (proxy [clojure.lang.IFn] []
    (invoke [& args] (apply fun args))))

((callable +) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18) => 171

((callable +) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19)
1. Unhandled java.lang.UnsupportedOperationException
   invoke

bfabry21:07:49

of an input stream? that's kind of impossible by definition

hlolli21:07:21

@rinaldi count a byte-array

rinaldi22:07:10

hlolli: Interesting, I will give it a shot. Thank you.

hlolli21:07:50

U4SKJCP3K change your name

hcarvalhoaves22:07:40

@rinaldi I guess this works (if you have memory) (-> stream slurp .getBytes alength)

hcarvalhoaves22:07:54

otherwise use

rinaldi22:07:34

hcarvalhoaves: Nice, I will try this. Thanks πŸ‘

hlolli22:07:07

aaah sorry, I got a slack bug, your guy's name was for a moment some hash haha

rinaldi22:07:15

@bfabry Yeah, that does sound weird. What I am doing now is: 1. Make an HTTP request and get back a JSON file 2. Convert that to a ZIP file (gives me back an input stream) 3. Need to know the size of this payload

dpsutton22:07:39

@hlolli i think you're running into the limitation that you can only have 20 arguments to a function

dpsutton22:07:41

and i 've heard someone talk about "trivial" functions through the repl are not invoked in the same way as normal functions

hcarvalhoaves22:07:03

@rinaldi are you're trying to determine the file size to send on the response?

hlolli22:07:15

any hacks to bypass it? It's a bug in overtone, changeing the implementation where this is defined would be pain

rinaldi22:07:36

@hcarvalhoaves Precisely. I'm trying to do all these steps without performing IO.

dpsutton22:07:57

i'm way out of my depth on that one. I think @hiredman or @noisesmith would know way more than me

hcarvalhoaves22:07:05

@rinaldi you would have to hold all response in memory, use a buffered reader + this instead -> http://greenbytes.de/tech/webdav/rfc2616.html#rfc.section.3.6.1

rinaldi22:07:08

hcarvalhoaves: Oh God, this looks crazy πŸ™‚

hcarvalhoaves22:07:56

otherwise you have to make sure you don't OOM πŸ˜‰

rinaldi22:07:07

I am sending this payload to S3 and one of the requirements is to pass in the content length alongside the payload

rinaldi22:07:55

I guess temp files are the simple solution to this here

hiredman22:07:19

yeah, proxy doesn't rest args like that

hiredman22:07:27

doesn't support

hiredman22:07:05

I surprised the first thing works at all

hiredman22:07:24

maybe proxy does sort of support that, I am not sure, depends on how you read the docstring, but I have never read it has supporting that

hlolli22:07:42

https://github.com/overtone/overtone/blob/master/src/overtone/helpers/lib.clj#L146 here when the range is changed I bump into the same error as I posted above.

hlolli22:07:34

the proxy is defined on line 100.

hiredman22:07:00

I was going to say, that is defrecord which is a different beast entirely from proxy

hlolli22:07:44

I think this hack could have been done better when this was written way back.

hlolli22:07:14

a macro that takes all arguments and puts them into a map or vector.

hiredman22:07:59

it is also likely really old code, given that it uses proxy instead of reify there

hlolli22:07:59

Yes, reify a protocol would maybe be a better solutin?

hiredman22:07:42

no, I mean, those are all interfaces it is proxying so reify is likely a better choice

dpsutton22:07:11

(~invoke_fn this# ~@args). does this have to many arguments with (range 21)?

hiredman22:07:17

I am not familiar with the codebase, but from scratch I might prefer to pass around a map with a key that maps to a function

hiredman22:07:58

the issue is, the last arity of invoke needs to call applyTo, or something like that, you should check out AFn.java

hlolli22:07:09

the limit is 10 arguments because in overtone they come in pairs.

hlolli22:07:49

this limit has been there for long time, nobody has taken the time to fix this

hiredman22:07:16

if it is going to use proxy, it shouldn't proxy IFn, it should proxy AFn

hiredman22:07:48

there are invoke arities from 0 to 21, the 21st arity takes 20 args + an array as the 21st

hlolli22:07:11

I see what you mean, but I can't see how that would be implemented. It's macroexpanding to a argument pyramid of invoke.

hlolli22:07:56

Or just somehow collect all the arguments as one parameter.

hlolli22:07:37

ah ok, read better, last arity invokeing applyTo, I see

hiredman22:07:39

you can't do it with proxy

hiredman22:07:45

or anything really

hlolli22:07:24

this macro defrecord-ifn has always some function or macro wrapped around it, there an &rest sequence could be used.

hlolli22:07:53

no, sorry, forget what I wrote, it's the defrecord that gets called in the end

hlolli22:07:59

macros, brainfuck