Fork me on GitHub
#beginners
<
2018-04-17
>
fmn00:04:41

@gcast Thanks for the answer! Seems like at this point using transducer is just better overall(?), advantages of dealing with small number of items seems negligible to me.

andy.fingerhut00:04:58

Assuming this is a Clojure-on-Java project (not ClojureScript), maybe Eastwood might be able to help you find namespace/file weirdness in your project. No promises. This advice may be worth more than you paid for it, but maybe not.

alice00:04:52

I have no clue why it didn't tell me in the error message

alice00:04:02

I went through every file in my app and found a circular dependency

alice00:04:10

and every error I got pointed everywhere else

alice00:04:14

solved but confused why it happened

alice00:04:39

And yes, it was JVM

andy.fingerhut00:04:57

ns-tracker would certainly be more helpful if it reported the cycle of dependencies that it found.

alice00:04:27

Well now that that's through, how can I write a spec for a map that will only take certain keys? For example I want {:a .. :b ..} to be valid, but not {:a .. :b .. :c}

mfikes00:04:39

@alice Spec doesn't provide support for that pattern, by design

dadair00:04:51

You could use “keys” and “and” with another predicate to enforce that. But spec is generally designed to discourage that practice

alice00:04:33

Ah, alright

hoopes01:04:57

hi - is it possible to return something like the entire path from a bidi match? (Ignoring params for a moment) It seems like the return is always {:handler :some-kw} - I could do some lookup to "unconvert" it, but is there some way to return arbitrary data from a bidi match? thanks to anyone in advance

Kari Marttila08:04:51

I'm not able to find a way how to redirect a user to another page using ClojureScript + secretary library. E.g. I have a login page in url "http://localhost:3445/#/login". Once the login is successful I'd like the user automatically get redirected to the next page, e.g. "http://localhost:3445/#/productgroups". If I call "(secretary/dispatch! "/productgroups")" in the login page's handler this will render the productgroups page, but the page url still stays on "http://localhost:3445/#/login". Maybe I'm missing something simple since I'm learning frontend development and SPA.

Kari Marttila08:04:43

Rubber duck effect seems to be working again. Once I wrote the question I was wondering whether I should do the new location using Javascript. I added in login page's handler: "(set! (.-location js/document) "/#/productgroups")" and it did the trick. I guess this is the righ way to redirect the user to the next page in SPA?

sveri08:04:26

@kari.marttila This looks like it should be handled by the library. I use bidi with pushy and the uri is set automatically for me.

alice09:04:54

Anyone ever feel like they regress in skill a little bit? I wrote clojure every day for months and I made an entire imgur-esque website to host my personal image uploads in a few days, I got distracted by life for a few months and 400 lines takes me a week. I have to get everything refreshed in my head @_@

joelsanchez09:04:51

that teaches you one valuable lesson: never stop writing clojure

😆 4
alice09:04:56

True that

alice09:04:33

Spec's just killing me recently, it's hard to be caught up

joelsanchez09:04:07

I imagine spec would be the first to forget, followed by the order of the arguments to the map-indexed function (was it [item index] or [index itm]? 🙂 )

sveri09:04:49

Thats just normal, I have been writing java for almost 10 years now and still have to lookup stuff that would seem common knowledge, but if you never use it and are unsure 😄

Kari Marttila09:04:28

I just realized that if I create a SPA using ClojureScript and Reagent + Secretary and use r/atom for app-state and store the current page and JSON Web Token in the app-state, a refresh in any page resets the app-state. This is a bit of a nuisance since the user needs to login again to get a valid JSON Web Token. Is there any way to handle this in ClojureScript/Reagent/Secretary or should I store the JSON Web Token in browser's local / session storage?

sveri09:04:07

@kari.marttila you would need to store it in localstorage anyway to persist between closing the browser tab. Unless you want your user to login all the time anyway.

joelsanchez09:04:36

don't store JWT in local storage

joelsanchez09:04:02

> When storing your JWT in a cookie, it's no different from any other session identifier. But when you're storing your JWT elsewhere, you are now vulnerable to a new class of attacks (...)

joelsanchez09:04:22

disclaimer: I'm actually doing this in my own app for now. it's still terrible and I should fix it

Kari Marttila10:04:05

@sveri and @joelsanchez: thanks for hints. I'm just learning ClojureScript and creating a demo SPA for learning purposes so I'm not that worried about to make the demo app 100% secure. I'll store the session to local storage for now.

sveri10:04:21

There are lengthy discussions about this topic and everything has pro and cons. You need to secure your app against XSS attacks and transport everything over https if you store it in localstorage. On the other hand, storing it on server side you need to make sure you are safe of CRFS attacks.

grierson18:04:43

What are some good beginner Datomic tutorials?

ghadi18:04:50

I collected some links and videos on my pinboard https://pinboard.in/u:ghadi/t:datomic

sundarj19:04:23

there are the Day of Datomic videos at https://vimeo.com/cognitect too

oVerde19:04:43

This is baffling me, so gonna ask you guys. So far I cant’ find on google for a Clojurescript implementation of a Live Chat Been looking after Clojurescript "live chat" with no luck

adc1720:04:52

What’s the reason for preferring

`(:identity ~'foo-map))
over
`(:identity foo-map)
It’s used in a compojure-api example here: https://github.com/metosin/compojure-api/wiki/Creating-your-own-metadata-handlers
(defmethod compojure.api.meta/restructure-param :roles [_ roles acc]
  (update-in acc [:lets] into ['_ `(require-role! ~roles (:roles ~'+compojure-api-request+))]))

Alex Miller (Clojure team)20:04:43

foo-map will resolve the symbol foo-map in the context of the current namespace, returning a namespaced symbol. ~'foo-map will quote, then evaluate, returning the bare un-namespaced symbol.

adc1720:04:46

@alexmiller right, so you want the un-namespaced variant if, for example, you’re quoting a symbol that will be evaluated in another ns where that symbol is already defined?

Alex Miller (Clojure team)20:04:07

I didn’t read all the context

adc1720:04:09

I think in the compojure example, into’s param will be later expanded within a macro, so that would make sense.

alice23:04:47

So, are :pre and :post conditions worth using? If I want to validate input and output of a function and return descriptive errors in that kind of manner can I use spec? What's the deal here

alice23:04:53

Oh, thanks. Appreciate it

lambdalove 4
spiralganglion23:04:28

Is there an idiomatic way to do (rest [1]), so that it returns [] instead of ()?

spiralganglion23:04:51

I'd go for (vec (rest [1])), but that doesn't work if I'm doing (update some-map :key rest)

spiralganglion23:04:27

I'd go for (update some-map :key -> rest vec), but -> isn't a function

mfikes23:04:11

As in (subvec v 1)

spiralganglion23:04:56

Perf! Thanks Mike.

mfikes23:04:16

O (1) as well 🙂

spiralganglion23:04:51

Yeah, that was my big desire, otherwise I'd have just done something dumb like (update some-map :key #(vec (rest %))

sundarj23:04:21

note that you could define that function as (comp vec rest):

=> ((comp vec rest) [1 2 3])
[2 3]

spiralganglion00:04:51

Totes! But that's still generating a new function instance every time that code is evaluated. This is some inner loop code, so I'm trying to keep things static.

spiralganglion00:04:13

Thanks for the tip.

sundarj00:04:15

actually, as far as i know, at runtime the JVM class for the function has already been generated; all it does at that point is new that class up, which is handily pretty cheap. but point taken! 🙂

andy.fingerhut00:04:36

You can bind the function (comp vec rest) to a local name in a let and use it wherever, with no re-calculation of the function, of course.

4
andy.fingerhut00:04:14

Well, assuming the 'let' was outside the place that caused repeated use of the function. Either that or just defn yourself up a new function in the namespace and use that.

spiralganglion00:04:15

Yep, all valid options. Thanks guys.

mfikes23:04:56

Just be sure to check for the empty vector case

👍 4