Fork me on GitHub
#clojure
<
2017-11-23
>
Bravi00:11:00

is reloaded.repl supposed to run the server at the same time?

Bravi00:11:27

it says

Started server on 8080
:resumed
but then localhost:8080 isn’t working

Bravi00:11:42

that’s when I run (reset) in my repl

Bravi00:11:50

this is my simple user.clj

(ns ring-it.user
  (:require [reloaded.repl :refer [system reset stop]]
            [ring-it.core]))

(reloaded.repl/set-init! #'ring-it.core/create-system)

Bravi00:11:51

has no one ever used reloaded.repl? 😕

noisesmith00:11:52

@bravilogy I’m guessing the channel is going to be less active right now because the US has a big holiday which for many people starts with traveling tonight or early tomorrow morning

noisesmith00:11:25

I bet you’ll get replies if you ask this weekend or Monday

lovuikeng01:11:16

reloaded workflow coined by stuartsierra, a clojure workflow as demonstrated with Component https://cb.codes/a-tutorial-of-stuart-sierras-component-for-clojure/ weavejester adopted the workflow with https://github.com/weavejester/reloaded.repl, https://github.com/weavejester/integrant

Bravi01:11:54

@lovuikeng, I went through all of those 🙂 perhaps there’s an issue with the version.. thanks anyway

lovuikeng01:11:27

sorry, Bravi, didn't see you raise issue but a general question

Bravi02:11:32

all good, I figured it out 🙂

qqq01:11:33

is there a way to say {:keys [ .... ]} AND assert that none of them are nil ?

christos03:11:13

only default values

seancorfield04:11:17

@qqq I can't think of a way that doesn't involve duplication... can you give a bit more context?

seancorfield04:11:56

For example, you can do {:keys [a b c] :as data} but data will be the whole of what you bind, not just those keys...

seancorfield04:11:23

(or maybe (every? some? [a b c]) for whatever keys you destructure?)

qqq06:11:40

sorry, I meant to say: (let [{:keys [a b c]} ... ] (assert a) (assert b) (assert c)) ^-- is there a shorthand for this

seancorfield06:11:58

@qqq Well, I'd say (assert (every? some? [a b c])) is going to be clearer as the number of keys increases.

igrishaev06:11:01

@qqq maybe try :or syntax: {:keys [foo bar baz] :or {foo 42 baz 1 baz 99}}

seancorfield06:11:30

@igrishaev That's not what he's asking tho' -- he doesn't want defaults, he wants failure-on-nil.

qqq06:11:35

I don't want default values -- if a field is nil, it should assert and die, as something went wrong

qqq06:11:14

@seancorfield: I think your solution is opt, if I try to write amacro, it becomes very messy as I have to basically parse destructuring

igrishaev06:11:59

Ah I see now. So, you could either to assert every value or use clojure.spec

seancorfield06:11:26

You could probably write a macro that expands to (let {{:keys ~keys} ~value] (assert (every? some? ~keys)) ...)

seancorfield06:11:58

That would remove the repetition...

qqq06:11:01

yeah, but this wouldn't play well with multi part let-destructs, like

(let [{:keys [...]} objA
  {:keys [...]} objB]
...)

seancorfield06:11:38

You'd have to have it nested... which I think logically it would need to be, given the fail-on-nil requirement?

qqq06:11:58

oh; I'm okay with destructure all the things, then do fail on hnil

qqq06:11:15

it's okay to destructure objB even if some part of objA is nil, they're not 'nested', they're two separate objects

seancorfield06:11:32

Well, then write the macro to do that 🙂

qqq06:11:58

I was hoping I could to {:keys [a b c] :no-nil true} objA 🙂

igrishaev06:11:54

But still, take a look at clojure.spec. It has useful instrument function that wraps another function with data checks. And having schemes declared explicitly makes your code more clear. Instead, checking data every time in place leads to spagetty code.

seancorfield06:11:34

@qqq You could indeed write such a macro... @igrishaev instrument has an overhead that you might not want to pay in production. It is better to be explicit with s/valid? or s/assert.

seancorfield06:11:16

And relying on instrument when you actually want the nil-checks performed explicitly in production is definitely not something I'd recommend (as a heavy user of spec myself).

qqq06:11:24

I'm familiar with spec

qqq06:11:38

I'd actually want something even morespecy- .... only allows keys taht are part of s/keys of the spec

igrishaev06:11:42

@seancorfield yes, agree with your points.

qqq06:11:43

but I don't know how to formulate that

seancorfield06:11:25

If you have a spec with s/keys, you can call s/form on it and destructure to get the list of :req or :req-un keys. Then you can programmatically use that key list to validate the data.

seancorfield06:11:13

(if the spec is more complex -- say s/and over s/keys -- then you'll need to do some work there... and maybe you'll need to parse s/merge etc so it depends how "smart" you might want to be?)

seancorfield06:11:28

You could of course write a spec for those keys where each value was specified as non-`nil`able... but you'd still have to call s/valid? or something...

seancorfield07:11:30

boot.user=> (s/def ::foo (s/keys :req-un [::a ::b ::c]))
:boot.user/foo
boot.user=> (s/form ::foo)
(clojure.spec.alpha/keys :req-un [:boot.user/a :boot.user/b :boot.user/c])
boot.user=> (let [[_ _ keys] (s/form ::foo)] (println (map name keys)))
(a b c)
nil

qqq07:11:13

1. @seancorfield: this is very cool, s/form is awesome and I will be using it in the future 2. asserting that the value associated with the key is non-nil does NOT solve my problem my problem is that I sometimes specify the wrong key -- i.e. the key doesn't even exist in the map -- that's the problem I'm trying to solve

gklijs08:11:22

I use s/form a lot, both in my spec serialize library, and to be able to edit a map based on the spec, it’s great.

ikitommi10:11:46

@qqq metosin/spec-tools has a s/form parser, it extracts the keys from s/keys (also s/merge ones), and utilities for dropping out undefined keys.

borkdude11:11:09

Hmm, maybe cycle could also have an n argument, like repeat has

dominicm12:11:29

@bronsa is 1412 like take? I somehow expected it to be like doing (take (* n (count s)) (cycle s))

dominicm12:11:40

But I'm not sure that's what it does based on reading it

bronsa12:11:17

yes that's what it does

noisesmith12:11:29

so that would change its degree of laziness

noisesmith12:11:51

but of course if you count on a precise amount of laziness, you are probably doing something wrong

bronsa12:11:28

what do you mean?

noisesmith12:11:38

because you count the collection argument

noisesmith12:11:04

so I would assume it would realize the full input if it was lazy, right away, where the original would be lazier

noisesmith12:11:39

hmm, never mind, looks like cycle already forces the arg

noisesmith12:11:31

oh, a chunk, of course

+user=> (def c (cycle (map print (range 1000))))
012345678910111213141516171819202122232425262728293031#'user/c

noisesmith12:11:45

so that would change from realizing 32 items to realizing 1000

Bravi19:11:06

hi everyone. if anyone uses spacemacs, could you tell me how to switch between open panes please? 😄 there’s literally no tutorial I could find that says this

shaun-mahood21:11:38

Pretty sure you do space 1 for the first pane, space 2 for the second and so on - unless I misunderstand the question.

bronsa19:11:05

@noisesmith the impl in that ticket doesn't actually count anyway

Bravi19:11:09

I know I can mouse-click, but there’s gotta be a keyboard shortcut I think

William Oliveira19:11:01

Hello people! We making a study group about Clojure in Brazil. This table of contents is good to beginners learn the language? https://github.com/training-center/clojure-study-group/blob/master/material/roadmap.md

noisesmith20:11:31

@w.oliveira542 maybe interacting with the JVM could be earlier? (or at least an intro to the useful stuff about figuring out how java stuff works - what to look for in javadoc for example?)

William Oliveira21:11:13

Maybe into second session, @noisesmith?

noisesmith21:11:49

Sure - it's hard for me to say without seeing a more detailed curriculum of course, just a thought. I think people could save a lot of trouble if they were more pragmatic about using host interop