Fork me on GitHub
#clojure
<
2017-06-09
>
sophiago00:06:48

All I can tell from docs is "returns nil when input is not supported or not a collection" and we know it can't be the latter...

noisesmith00:06:10

it’s just an odd thing that I didn’t expect, not really relevant to your issue at all

sophiago00:06:21

Perhaps empty doesn't support MapEntrys where the values are colls themselves?

noisesmith00:06:40

I’m sure it has nothing to do with the values in the coll

sophiago00:06:24

Yes, to refine that: empty likely doesn't support MapEntry. If you think about it, what would it even return for that coll type?

noisesmith00:06:11

right, except clojure implicitly turns vectors into MapEntry in other contexts, and vector? on a MapEntry returns true iirc

noisesmith00:06:33

which is the source of my surprise

sophiago00:06:46

It doesn't even make sense to me why that works in the first place...

noisesmith00:06:34

it’s a key/value pair that happens to be somehow vaguely vectorish but is always exactly 2 elements in length I guess?

sophiago00:06:07

That behavior is occasionally useful, although not enough I don't forget about it, but that explains why vector? returns true. I'm just unsure what you mean about implicit conversion the other way. Where would you see that?

noisesmith00:06:51

it turns vectors into map-entries implicitly, but not other types (eg. lists)

sophiago00:06:00

That makes sense to me (lists can't be associative). I'm unsure where you saw it coming up in that test snippet.

noisesmith00:06:38

that’s a good point about associativity

sophiago00:06:02

That such conversion changes the semantics of testing for coll types is a wort, though, if you ask me. I'd rather have to explicitly convert everything and not have to ponder these issues 😛

joshjones00:06:04

https://clojurians.slack.com/archives/C03S1KBA2/p1496966626910635 because maps in clojure are Seqable and when first is called on the map, it seqs it. Conceptually it makes sense, as keys and values are joined at the hip. PersistentHashMap implements seq this way, so it decides how the world will view it as a seq -- all part of abstraction

public ISeq seq(){
	ISeq s = root != null ? root.nodeSeq() : null; 
	return hasNull ? new Cons(MapEntry.create(null, nullValue), s) : s;
}
@sophiago

sophiago00:06:55

Thanks @joshjones. I figured it out intuitively from Justin's next example, but your explanation is more concrete.

joshjones00:06:26

let's say you want to for a map, or loop over a map -- it's as easy as:

(for [[k v] your-map] ...)
anyway, just showing an example of how it's useful to view the map this way

sophiago01:06:45

I know, I've taken advantage of that occasionally. And it's hardly a big deal one way or another. But personally, I would have required an explicit conversion so as to avoid this entire confusion.

mbertheau09:06:37

Is there a more concise way of writing (let [{:keys [a b c]} (if foo? {:a "foo" :b "bar" :c "baz"} {:a "quux" :b "baaz" :c "gegl"})])?

mbertheau09:06:26

Preferably without having to repeat the condition or the keywords

leonoel09:06:47

(let [[a b c] (if foo? ["foo" "bar" "baz"] ["quux" "baaz" "gegl"])])

leonoel09:06:11

you may consider CPS as well

leonoel09:06:19

when a function returns many values, instead of wrapping the values in a collection, the function accepts an extra argument which is a multi-arity function that will be called with the values just before returning

leonoel09:06:31

in some cases it may be more elegant

mbertheau09:06:24

Ok, interesting. On first glance it doesn't seem to fit my situation very well, but I will ponder it. Thanks 🙂

leonoel09:06:25

anyway returning a vector of values is pretty idiomatic in most cases

gko09:06:58

I need to connect to Oracle 8.1.7 and newer version (like 11.x) and the drivers come as different jar (classes12.zip and ojdbc6.jar) but the used class is the same: oracle/jdbc/driver/OracleDriver.class => how would you deal with this? Currently, I generate two uberjar... Searching the web, there seems to be no simple solution, maybe playing with class loader, etc...

isaac09:06:12

Clojure support number as prefix for non-namespaced keyword, but not namespaced keyword

clojure
;; user> :1min
:1min
;; user> :period/1min
;; RuntimeException Invalid token: :period/1min  clojure.lang.Util.runtimeException (Util.java:221)
user>

mpenet09:06:01

nothing in core like (select-keys-by-ns {:foo/bar 1 :foo/baz 2 :foo/stg 3 :meh/1 :meh/2} "foo") -> {:foo/bar 1 :foo/baz 2 :foo/stg 3} right?

mpenet09:06:58

simple enough to do it manually, but I am wondering if this is possible via new destructuring or something else

rauh09:06:26

@mpenet specter can do that very effciently

mpenet09:06:48

I was sure it'd be suggested 🙂

mpenet09:06:27

well, I don't really care about perf here, I ll just do a reduce-kv based helper and be done with it (no specter on this project)

mpenet09:06:43

but thanks for the suggestion, it's a good one

pesterhazy10:06:55

Just discovered a way to print intermediate results inside arrow macros for debugging purposes:

(-> v transform)

;; with spy:

(-> v (doto prn) transform)
But what about thread-last?
(->> xs transform)

;; with spy:

(->> xs (#(doto % prn)) transform)
Essentially, this works like http://clojure.github.io/tools.logging/#clojure.tools.logging/spy but is universally available and doesn't require an extra dependency.

bherrmann11:06:23

I (or actually my manager wonders) how many active clojure developers are there today?

arnaud_bos12:06:27

The State of Clojure survey might give an idea, but it only takes into account the people that actually took the time to answer it

arnaud_bos12:06:28

The first figure I think is what you are asking for

arnaud_bos12:06:05

There are almost 10K people in this Slack, so I suspect there are actually more people doing Clojure than the survey surfaces

alexmiller12:06:35

@bherrmann based on a number of sources of data, I would confidently say it’s between 20k and 50k

alexmiller12:06:44

it matters a lot what you mean by “active”

bherrmann12:06:58

@alexmiller Thanks... I think my managers policy is to prefer technolgies where there is sufficent quantities of people working in the space. I presume his definition is "mostly working every workday primarily in X" ... but there is already so much fuzziness here...

jeff.terrell13:06:05

Yeah, what Alex said. I love Clojure and used it actively for several years, but my current job doesn't give me the opportunity. I'm still a Clojurian at heart, but I don't use it very often these days.

seancorfield16:06:29

I consider myself very lucky to have entered my current employer as a CFML developer (effectively) and been able to steer them to Clojure, and now we have a dedicated (but small) Clojure back end team and all new back end work is done in Clojure. We’ve replaced several “legacy” CFML apps (that were built after I joined) with Ring/Compojure apps already and hope to replace the largest remaining CFML app this year.

linicks17:06:33

How do you do "Hot Code" reloading with Clojure (clj). Figwheel seems to be (cljs) only?

hiredman17:06:13

you run a repl and input code in to it

linicks17:06:42

@hiredman So what if I want to use and editor, and have it recompile/execute on save?

hiredman17:06:24

gross, but it will depend on your editor

captainlexington17:06:33

Yeah, if you use Cursive you'll get pretty intuitive REPL-loading that's better than recompile on save

captainlexington17:06:47

Plus of course there's emacs and its historically great LISP support, and Vim has a surprisingly active Clojure ecosystem as well

linicks17:06:37

I normally use Atom, or VSCode 🙂 I may need to look into others with Clojure.. I was hoping for a simple lein command ex. -watch ... etc.

hiredman17:06:32

things like that exist, but that kind of cycle is for languages that don't have a repl

linicks17:06:46

Don't know why, but emacs and I never clicked... 🙂 I try every year to get into it, and ....

hiredman17:06:03

there is definitely clojure support for atom

hiredman17:06:41

I really hate physics engine embedding js graph libraries

captainlexington17:06:19

And nobody has any sense of how physics engines APIs should work

captainlexington17:06:37

It's such an easy pure function - seq of items in, seq of items in positions out

hiredman17:06:04

I tried to render a graph a few months ago, and the graph actually showed up the page, but then slowly turned in the z-axis and floated away

bfabry17:06:06

Cursive is life. I wouldn't recommend Atom if you're starting with clojure, it'll be a bit rough around the edges. Emacs if you're already an emacser, or vim if you're already a vimmer will work out pretty well. But if you don't have a previous allegiance to one of those two imo it's crazy to start with anything other than cursive

linicks17:06:17

Yes, i've been using proto-repl. But I'm not sure how to get it to work with my Pedestal app. It only wants to do block execution...? I'm sure I'm missing the obvious 🙂

linicks17:06:43

I've been doing code, lein uberjar, run the jar 😞

bfabry17:06:02

that is a painful workflow. you shouldn't need to lein uberjar to run

bfabry17:06:13

lein uberjar is for deployment

hiredman17:06:44

what do you mean by "block execution" ?

hiredman17:06:23

have you looked at the docs?

linicks17:06:40

proto-repl has a "Execute Block" function. So if you do (+ 1 2) then place the cursor at the parentheses, then you can send the code to the repl.

hiredman17:06:15

sure, that is what you want (but badly named)

linicks17:06:17

I can send the service function to the repl, but it doesn't daemonize it..

john17:06:45

Just having external figwheel repl up, and copying and pasting from a decent editor, is still a pretty efficient workflow

qqq17:06:59

how do I go from "I need org.apache.http.client.fluent.Content" to getting the group id , artifact id, and the latest version ?

noisesmith17:06:08

usually I google for “apache http fluent maven” and check for the latest relevant artifact

linicks17:06:38

@john So you copy and past the entire pedestal app?

qqq17:06:01

@noisesmith : I was missing the "maven" and getting API docs

qqq17:06:08

(well, that and I was typing the full classname)

noisesmith17:06:24

aha - yeah, maven is the magic word for finding the artifacts (that or sonatype)

qqq17:06:36

the 'nerdy' solution would be s/./ / , add maven 🙂

qqq17:06:44

err, s/\./ /

linicks17:06:24

Tried (def serv (run-dev)), but it doesn't re-run the service.clj after a change...

john17:06:18

Oops, not figwheel... wrong channel 🙂

linicks17:06:40

@john No problem.. 🙂

john17:06:04

@linicks Sure, you could probably launch a pedestal app in a repl, if it's set up right.

hiredman17:06:31

no it won't "rerun" after a change

hiredman17:06:46

when you change code and want to effect the running program you load it in

hiredman17:06:09

via the repl or your editors send to repl feature

hiredman17:06:51

if you load

(defn f [] 1)

(def serv (future (while true (println (f)) (Thread/sleep 1000))))

hiredman17:06:00

you will have 1 printed every seconde

linicks17:06:13

Ok... So from the repl I run: (def serv (run-dev)), Then make code change, and run (server/stop serv), Then (def serv (run-dev)) again. I wounder If I can setup webpack for a Clojure project..

hiredman17:06:31

if you then load (defn f [] 2) you will have 2 printed every second

hiredman17:06:04

depending on how you do things and how pedestal does things restarting may be optional

hiredman17:06:41

generally, if you change something referenced via a var (a global created with def), you don't need to do anything but re-def to have the new value used

retrazil17:06:29

Hi, can I ask clojure related questions here ? I am a beginner to clojure and I am stuck on a problem. I am learning from helsinki uni mooc (iloveponies)

noisesmith17:06:21

there’s also a #beginners channel

retrazil17:06:47

thank you !

linicks18:06:37

Does Boot have an auto re/build feature ?

qqq18:06:19

What is a good library for: * after a user has logged in, what do I store on client/server side so that all future GET/POST requests from this user are passed to the server as "authenticated as FooBar" ?

csm18:06:06

buddy is a good option if JWT is an option for you, and you don’t need to store anything

qqq18:06:47

I don't know what JWT is. I'm using AmazonLogin. Amazon handles auth, I ujuts need, after auth, to somehow store "this browser client has been authed as FooBar"

qqq18:06:57

(without making a call to Amazon on every GET/Post request from FooBar)

csm18:06:33

JWT == “JSON web token”, basically on login you issue a signed token to the client that identifies that user (like with a guid)

csm18:06:44

then the client sends the token with each request

donaldball18:06:02

JWT is a standard way for an authenticator to assert a set of claims, and for authenticating systems to be able to validate the authenticity of those claims

qqq18:06:42

okay, so let's sse if this works authentication: client -> server , msg = username + password // or some other oauth thingY servedr generates token matching username server sends token T_foobar to client_foobar due to some crypto magic, it's hard to guess/generate T_foobar using only foobar on all future requests: client -> server / every msg also has "i'm foobar, my token is T_foobar" server verifies T_foobar, then processes request as foobar this is all over https, so it's impossible for eavasdroppers to get T_foobar is this all correct ?

csm18:06:10

pretty much, yes

csm18:06:11

also consider adding a lifetime to tokens, so they’re rejected after some amount of time, and possibly have a renew call

qqq18:06:16

http://rundis.github.io/blog/2015/buddy_auth_part1.html lol buddy uses public key crypto for the token

noisesmith18:06:34

right, that’s standard for JWT

noisesmith18:06:10

fun fact! JWT has a special NONE cypher, which means no encryption, and at one point a client could just say “hey this is my token it is encrypted by method NONE” and JWT implementations would silently accept it

noisesmith18:06:40

now every JWT lib guides you toward explicitly whitelisting the cypher you accept

noisesmith18:06:23

the useful thing is that this means the server can put useful data in the JWT that the client can a) decrypt and use and b) verify that it was definitely made by the server

noisesmith18:06:04

(of course this isn’t foolproof because an attacher can just edit the code to check for a different signer so don’t count on this)

noisesmith18:06:31

but at least it protects an honest client from a malicious middleman

noisesmith18:06:02

(if they get the server’s public key over ssl - man, so many gotchas in crypto)

donaldball18:06:22

FWIW I use the Java Nimbus library for my JWT needs; I found buddy too fiddly for what I was trying to do

seancorfield19:06:51

@donaldball Looks like MS’s Azure OAuth libs use Nimbus. We are using Apache OLTU (Jose) library for JWT elsewhere.

val_waeselynck20:06:06

if Clojure's numbers are too low for him, ask him if he thinks it's easier to find housing in a big city than in a small one :)

urbank21:06:44

is there a function in the core library that does something like this:

urbank21:06:12

(fn [pred? x default] (if (pred? x) x default))

noisesmith21:06:44

I’ve looked for it, I don’t think it exists

tanzoniteblack21:06:55

if your pred? returns the arg when true and nil/false when not; you can use or for that (or (my-special-pred? x) default); but I don't think there's a core fn that does exactly what you're asking about

tanzoniteblack21:06:22

(and I don't actually recommend doing it the way I suggested)

urbank21:06:58

Yeah, that would require modified predicates. At that point I'd rather just define this function in my utils file 🙂

urbank21:06:11

Have actually found myself needing it quite a few times now

spei21:06:26

does if-let do what you want?

tanzoniteblack21:06:11

let-if has the same issues as or, where it captures the output of the your predicate function

tanzoniteblack21:06:14

I've never bothered to write a helper function for that, since (my-fn pred? x default) isn't really any shorter or easier to read than just (if (pred? x) x default); I guess if you had long variable names, or we're doing some kind of threading of predicates or something, it might make sense though

spei21:06:46

thats true. also the way the (my-fn pred? x default) function is defined, its just an if statement anyway

urbank22:06:57

@tanzoniteblack Well (if (pred? x) x default) is fine, but as soon as x because an expression it becomes a problem, IMO