Fork me on GitHub
#beginners
<
2019-05-28
>
sova-soars-the-sora00:05:17

I'm trying to figure out the max number of days in the current month...

sova-soars-the-sora00:05:24

but I keep getting org.joda.time.DateTime cannot be cast to java.lang.Character

seancorfield00:05:03

@sova share your code...?

penryu03:05:15

@sova Not familiar with joda time, but in clojure.java-time (if you have the luxury of java 8+):

(require '[java-time :as t])
(let [today (t/local-date)
      leap (.isLeapYear today)]
  (.. today getMonth (length leap)))

Nazral03:05:16

How can I get two completely different jar built from the same project? I have my main program that is currently build, and in the same project/repo I'd like to have a secondary program that is not built when the main jar is built, but can be build on the side

gnzlrm03:05:14

project or repo? Also, what build tool you use?

Nazral03:05:21

I use leiningen

Nazral03:05:13

I have one project, and two profiles in it, but I would like one of the profiles to consider only a subset of the sources (e.g. myproject.entrypointB and myproject.stuffrelated.toB)

Nazral03:05:12

Maybe a clearer example of what I want to do is that I have a dependency that is fairly heavy (600Mb+) and I'd like to make it optional at build time, by not building some classes and including the dependencies in the uberjar unless explicitly required

Nazral03:05:43

But then it would also mean removing some require in some files depending on profiles

gnzlrm03:05:40

Have you taken a look at 'lein sub'?

Nazral04:05:23

I don't think it tackles my problem, it more separate one project into a few smaller projects

Nazral03:05:57

thank you, will check it out

JanisOlex06:05:04

@mfm I think it was some discussion on forum about maintainable code, and one discussed, that having to maintain code, where there is one global state, and all the app works on it is like antipattern of globals in any language...

zlrth13:05:07

very well. if somebody made a specific claim in their book like, “clojurescript single state atoms are a bad way to maintain state” i’d hear them out. otherwise i don’t know what to do with “atoms are bad”. i mean, your postgres database is global and mutable.

Ahmed Hassan10:05:02

While using Clojure Tools Deps I'm getting following error. How can I resolve it?

Alo12:05:27

Hi there! I'm looking for some tutorials to get started. Ideally it would be a tutorial to build a web app (maybe with database?) in clojure/clojurescript or both. Is there anything you would strongly suggest?

Ahmed Hassan12:05:58

Have a look at "Clojure for Brave and True".

Ahmed Hassan12:05:31

For ClojureScript there's book "ClojureScript Unraveled".

Alo14:05:00

Thanks!! 🙂

gklijs20:05:48

Not sure what your looking for exactly but open-bank-mark does fit the description https://github.com/openweb-nl/open-bank-mark but it may be to much.

felipebarros22:05:05

@U26FJ5FDM any chance you commented on the wrong thread? hehe interesting project though, I may try to read it to learn more.

Sy Borg13:05:22

is there any list with online resources for practical Clojure learning like 4Clojure, project Euler, http://exercism.io? what would you recommend?

evocatus13:05:26

How to start using ClojureScript? You setup a Leiningen project and add some dependencies and then do lein build and it generates JS code or else? Are there any good tutorials on that?

evocatus13:05:37

Also I couldn't find any information on how to manipulate DOM (i.e. use ClojureScript for traditional JS tasks) on the official site

evocatus13:05:41

@sy_borg Project Euler is not Clojure-specific. I don't know of any such list. But you can add http://codewars.com and http://codesignal.com to it - you can solve programming katas in Clojure in browser there.

Sy Borg14:05:09

thanks, Roman

pavlosmelissinos14:05:47

In terms of software design, what are your thoughts on using a single map as function input as well as function output (at least in non-trivial functions) instead of positional arguments? e.g. 1

(defn combine [top-section mid-section bottom-section] ...)
(combine top-section mid-section bottom-section)
would become
(defn combine [{:keys [top-section mid-section bottom-section]}] ...)
(combine {:top-section top-section :mid-section mid-section :bottom-section bottom-section}
e.g. 2 Given (def summary {:title "This is a title" :body "This is the summary body"})
(defn render [title body] ...)
(render (:title summary) (:body summary))
would become
(defn render [{:keys [title body] :as summary}] ...)
(render summary)
EDIT: Or rather, what is the clojure way?

Sy Borg14:05:04

reminds me of parameters splatting in PowerShell 🙂

pavlosmelissinos14:05:48

Is that meant as a good or a bad thing? 😛

Sy Borg14:05:16

good practice, at least

👍 4
evocatus14:05:06

I believe eliminating unnecessary entanglement in the form of argument order if you have, let's say, more than 3 parameters is a good thing. But I'm a newbie.

manutter5114:05:19

I very definitely prefer a map--avoids bugs from getting something in the wrong spot, and it’s very powerful, especially when used in connection with destructuring.

pavlosmelissinos14:05:50

I seeee... I've had a sliiight disagreement about it at work (I'm for eliminating positional arguments whenever possible) but the first example does look ugly indeed, so I'm not sure.

manutter5114:05:04

One small gotcha is the potential for bugs due to typos in map keys, but :man-shrugging:

manutter5114:05:51

which one looks ugly? The destructured one?

pavlosmelissinos14:05:09

building the literal map on the spot (combine {:top-section top-section :mid-section mid-section :bottom-section bottom-section} vs (combine top-section mid-section bottom-section)

johnj14:05:10

there's also the question of keyword args vs maps

sova-soars-the-sora14:05:52

gosh, do you want to remember what you're doing 6 months down the road?

pavlosmelissinos14:05:47

What are you referring to?

manutter5114:05:02

Write it like this:

sova-soars-the-sora14:05:16

(just in general, not a jab at any code, friends)

evocatus14:05:17

why do you have to construct a map in place ?

danielneal14:05:21

I definitely prefer open maps, preferably with namespaced keys these days

sova-soars-the-sora14:05:44

i'd love to see some examples of maps vs sequential arguments. it'd hammer home some good design principles. like don't rely on sequence when you don't have to

manutter5114:05:46

(combine {:top-section top-section
          :mid-section mid-section
          :bottom-section bottom-section})

👍 4
pavlosmelissinos14:05:02

Sure, that's definitely cleaner, but still I don't think there's a way to get rid of that repetition 😞

danielneal14:05:28

what does combine do?

manutter5114:05:15

Heh, I have a keyboard shortcut in my IDE — I type ==<tab>, and then just “foo” and it types :foo foo for me.

manutter5114:05:45

I’m assuming the combine is just an arbitrary example.

pavlosmelissinos14:05:32

It's repetition for the viewer though! (minor point, sure, but nonetheless it's practically junk) yeah, combine is arbitrary, doesn't really matter what it does (it does nothing) 🙂

manutter5114:05:22

Yeah, it’s a bit repetitive when it happens. Usually the value isn’t quite exactly the same as the key in practice, e.g.

(combine {:top-section (get-top-section)
          :mid-section (get-mid-section)
          :bottom-section (get-bottom-section})

👍 4
danielneal15:05:12

yeah - especially if you have namespaced keys already that you're passing through - you might e.g. then just select-keys from some other source

👍 4
manutter5115:05:34

most of the time when I have the key and the value exactly the same is when I’m debugging:

(cljs.pprint/pprint {:id id
                    :username username
                    :role role})

manutter5115:05:56

and that’s kind of throwaway code anyway.

manutter5114:05:01

I think that’s very readable

sova-soars-the-sora14:05:15

it's a different philosophy than C/++ making a little DNA transcriber that can run real fast down the data...

johnj14:05:53

if you are writing the input manually wouldn't keyword args be more appropriate?

👍 4
pavlosmelissinos14:05:25

keyword args might be a nice compromise indeed :thinking_face:

manutter5114:05:42

I vaguely remember reading that there was something problematic about keyword args. I’ve never used them myself. Do they play nicely with Clojure spec for example?

johnj14:05:50

no idea, on the other hand, adding two chars {} is not much 🙂

manutter5114:05:23

Or just the first { if you’ve got an IDE/editor that automatically inserts the closing }

johnj14:05:15

yeah, thinking about it, can't find anything keyword args can have over maps

manutter5115:05:34

You may have seen in the #clojure channel, but I’ll repeat it here for completeness: the disadvantage of keyword params is they get in the way when you try to compose 2 fns, and the inner fn takes keyword params.

👍 4
dharrigan15:05:56

If I have a map, say {:foo 1: bar 2} and I desctucture like so (let [{:keys [foo bar]} map] (+ foo bar)), is there a way to destructure, but also rename at the same time?, i.e., something like (let [{:keys [a :as wibble b :as wobble]} map] (+ wibble wobble))?

sova-soars-the-sora15:05:52

@dharrigan in the same line? you can add another line to your (let [..]) statement (let [foo wibble, bar wobble])

dharrigan15:05:17

I see, so like this (let [{:keys [a b]} x wibble a wobble b] (+ wibble wobble))

dharrigan15:05:23

that seems to work

dharrigan15:05:46

(a and b are foo bar, I've been paying at the repl)

hiredman15:05:43

You can just use the destructuring sysntax instead of the :keys sugar

4
hiredman15:05:09

{whatever :a}

dharrigan15:05:50

(let [{wibble :a wobble :b} x] (+ wibble wobble))

4
lilactown15:05:14

it's unfortunate that destructuring using keys with namespaced keywords, loses the namespace

noisesmith16:05:14

what would you do with a namespaced local?

noisesmith16:05:34

afaik there's no way to create a namespaced local binding

noisesmith16:05:09

my mental model is that a namespace is a property that belongs to some named object (symbol, keyword), with a local binding you don't have a reified container, just a name for a scoped value

Daniel Hines17:05:20

Is there a way to create a “default profile” for the clj cli? Such that whenever I run clj, certain deps are always merged in?

Jakub Holý (HolyJak)18:05:24

You can also ask in #tools-deps for more targeted audience

lilactown20:05:47

I'm not sure what the solution is, but I know the problem is:

(let [{:keys [foo/thing bar/thing]} big-ball-of-things]
  (println thing))

lilactown20:05:13

it makes namespaced keywords less ergonomic than un-namespaced ones

lilactown20:05:53

I infer that the general design direction is to encourage namespacing

noisesmith20:05:58

I can't think of a clean syntax for that, and namespaced locals seem like a really weird feature. you are of course free to use {thing1 :foo/thing thing2 :bar/thing}

ghadi20:05:39

it's paradoxical in a way

ghadi20:05:05

you have symbols that are distinct because they're in different namespaces

ghadi20:05:38

but you want them together in the same namespace (no namespace)

ghadi20:05:24

you can either do what was suggested (manually rename) or just use the fully-qualified names

dangercoder22:05:18

What project structure do you guys prefer? Having all the routes for a web-app under a namespace called routes or to structure your app according to the different "parts" i.e project.payments.routes instead of project.routes.payments This can be expanded even more but i hope you get the point.

dangercoder22:05:34

I am a bit burnt from an old monolith I worked on in C#, 300 controller-classes under the "Controller" namespace 🙂.

dangercoder22:05:44

maybe there were even more..

nedcg13:05:07

module.* is a modern approach, and can benefit you in the case for a transition to a micro-services architecture

dangercoder14:05:40

exactly my thought @UJC0L7T5H 🙂 !

👍 4
Eric Ervin19:05:02

routes under routes. I just checked to see where I got that idea and it looks like that is how it is done in Sotnikov's Web Development with Clojure book.

johnj23:05:36

Is making a function call in an arg anti-pattern? ex: (fun-a x y (fun-b z)) - trying to convert some side-effecting functions to pure ones