Fork me on GitHub
#beginners
<
2018-06-20
>
vnctaing00:06:46

Hey, coming from the JS community and formatter like prettier https://github.com/prettier/prettier , is there like one formatter considered as a standard in clojure, so far I found clfmt https://github.com/weavejester/cljfmt

vnctaing00:06:46

Hey, coming from the JS community and formatter like prettier https://github.com/prettier/prettier , is there like one formatter considered as a standard in clojure, so far I found clfmt https://github.com/weavejester/cljfmt

brandon.ringe00:06:14

You can look for extensions to your editor like Parinfer which will auto indent/format code for you and manage parentheses. I use VSCode and use the Parinfer extension for that, but it's for many different editors. https://shaunlebron.github.io/parinfer/#editor-plugins

seancorfield00:06:27

@ cljfmt is pretty much the de facto standard I believe, as far as taking existing source code and reformatting it. There's a plugin for Leiningen to run cljfmt on your code. As @ indicates tho', most Clojure-savvy editors will auto-format your code as you type it in.

seancorfield00:06:23

And this is the community style guide that most everyone adheres to https://github.com/bbatsov/clojure-style-guide

seancorfield00:06:25

Some of the things that are hard to get used to at first, coming from other languages, include not using { .. } block style indentation like C-family languages.

seancorfield00:06:35

So we write

(defn foo
  "My docstring"
  [args]
  (some-call args))
rather than
(defn foo
  "My docstring"
  [args]
  (some-call args)
)
for example.

vnctaing01:06:27

That’s prefectly fine to me ! I don’t have much opinion on styling, I was looking a formatting library for the sake of consistency, good I’ll look into it thanks !

vincent.cantin02:06:50

Hi. I have seen someone using a keyword like that: :a/b/c 1. is it normal? 2. what is the semantic of a, b, c ?

alexmiller02:06:04

no, that’s wrong, don’t do it

seancorfield03:06:33

I must admit, I was a bit surprised at just how permissive the reader is about keywords...

user=> :a//
:a//
user=> :a:b
:a:b
user=> :
:
I knew that the keyword function accepted any string and produced keywords that you couldn't type in, but I was pretty surprised those three above are accepted by the reader! 🙂

vincent.cantin03:06:52

I saw it in a recent JEE conf in a talk about clojure. https://youtu.be/Svhhga9Rxnc?t=1448

vincent.cantin03:06:05

Does the '/' in the keyword have only a conventional meaning or a real technical meaning? What other character we should use to replace it if we want to represent a kind of directory or tree in the keyword?

michael.gaare03:06:05

@vincent.cantin It has a technical meaning as well. It separates the two parts of the keyword - the namespace and the name. These are separately accessible through functions with those same names, and are provided as separate arguments to the keyword function. If you want to have a namespace with deeper hierarchy, you should use "." separators like regular Clojure namespaces.

vincent.cantin04:06:35

What is the internal representation of keywords, flat string or structure with a namepace and a local id?

michael.gaare04:06:44

Internally they're objects with a bunch of stuff

michael.gaare04:06:52

but the short answer is, the latter

orestis04:06:24

Are there any good libraries for testing external REST APIs? I could just use clojure.test with some generic http client, but I wonder if there are ergonomics/conciseness out there that I might be missing.

relan09:06:00

Hi. Could you suggest Clojure quick start book or website?

val_waeselynck09:06:32

What you should choose really depends on your learning preferences and background

suryapjr10:06:11

(defn health [level]

(if (= level :low) "Go to doc" "You are fine"))

suryapjr10:06:22

How do I call health function

suryapjr10:06:38

(health [:low]) is giving and error

mping10:06:50

you should call (health :low)

mping10:06:54

without the []

suryapjr10:06:12

Thanks anyway

suryapjr10:06:01

Clojure's syntax is simple if we look beyond the parentheses :)

suryapjr11:06:18

Too good !!

suryapjr11:06:51

(def mylist '(1 2 3 ) )

(map inc mylist) 

suryapjr11:06:19

Kindly explain the above snippet

bronsa11:06:25

you’re defining the Var mylist to be the list with elements 1, 2 and 3, and then mapping over it applying inc over every argument

suryapjr12:06:59

So to use two functions for the same data structure u use ; (first function second function data-structure)

suryapjr12:06:19

Is it correct?

ajay.rivendell12:06:23

the simple rule is to call a function, you start with a list, first argument is function that you want to call, followed by arguments (fn arg1 arg2)

ajay.rivendell12:06:39

the arguments depend on the function, in case of map [https://clojuredocs.org/clojure.core/map] first argument is function followed by a collection

madstap12:06:58

Clojure is evaluated inside out, so to use two functions on the same data structure you do (second-fn (first-fn data-structure)), which is like secondFn(firstFn(dataStructure)) in a c-like lang.

bronsa12:06:01

you always do (my-fun arg1 arg2 arg3)

bronsa12:06:17

map is a function that takes a function as its first argument and a collection as its second

bronsa12:06:28

it’s called a higher order function

suryapjr13:06:58

Can u provide another example ?

bjr13:06:05

what are you trying to do?

bjr13:06:37

i.e. are you calling a function for its side-effects or to transform some data to be used in a later fn?

suryapjr13:06:44

Transform some data to be used in a later fn

bjr13:06:48

are you looking for something like this?

(let [mylist '(1 2 3)
      a (func-a mylist)
      b (func-b mylist)]
  .. use `a` and `b` here
  )

bjr13:06:28

(let [mylist '(1 2 3)
      a (func-a mylist)
      b (func-b a)]
  .. use `a` and `b` here
  )

bjr13:06:31

and as @madstap mentioned if you don’t need to reference the value a separately, you can do:

(let [mylist '(1 2 3)
      b (func-b (func-a mylist))]
  .. use `b` here
  )

suryapjr13:06:33

@bjr whats happening in the first code ?

suryapjr13:06:55

I see that mylist gets (1 2 3)

suryapjr13:06:06

After that..i didnt get it

bjr13:06:08

func-a is executed with the value of mylist and the result is bound to the symbol a

bjr13:06:31

then the same is done with func-b

bjr13:06:48

the value bound to the symbol mylist does not change

bjr13:06:15

and the symbols mylist, a and b can all be used within the body of the let expression

suryapjr13:06:02

Okay..got it now !

suryapjr13:06:26

Btw..as per my understanding ..clojure has Own standard library + Clojar + java ecosystem ?

bjr13:06:29

yeah, something like that

akiroz15:06:42

super late to the party but here's my 2c anyway: I love elixir's pattern matching support in functions (especially symbolic equality matching) and like clojure, it also supports macros (you can manipulate code as data structures). It's great if you want to play with the erlang OTP. However, the biggest advantage for Clojure is the libraries from both the Java and JS world.

akiroz15:06:17

Example of what I mean by symbolic equality, this function in elixir returns true if the 2 arguments are equal:

def equal(a,a), do: true
def equal(_,_), do: false

akiroz15:06:03

and since elixir supports applying fn without parens (for better or worse), you can actually write elixir in lispy syntax: (myFn foo, bar)

michael.gaare15:06:40

I gather those loathsome commas are required? 😉

akiroz15:06:48

yes, unfortunately

seancorfield15:06:46

In case folks want to dig deep into non-Clojure languages, there's a #other-languages channel.

mfm22:06:30

I have a large sequence of maps (with some nested values), for which most of the values are the same, and therefore uninteresting. i’d like to see the different values in the map.

mfm22:06:42

so for the input:

[{:a 1, :b "something", :c "same"} {:a 1, :b "else", :c "same"}]
i’d like the output
[{:b ["something" "else"]}]
or something like that. that is, {:a 1} and {:c "same"} are dropped.

lilactown22:06:17

clojure.data/diff might be what you're looking for

mfm22:06:52

oh golly. i was writing a hairy reduce, but that looks great. thanks.

lilactown22:06:22

there still might be a slightly hairy reduce - not sure if you can just diff each element to it's neighbor, or if you need something more advanced than that

mfm22:06:58

clojure.data/diff works for comparing two arguments. yeah, is getting it to work on a seq of args as easy as (reduce clojure.data/diff my-seq)?

mfm22:06:02

(def a [{:a 1 :b "unique" :c "same"} {:a 1 :b "differe" :c "same"} {:a 1 :b "three" :c "same"}])
(clojure.data/diff (first a) (second a)) <-- works as intended

(reduce clojure.data/diff {} a) produces:
[[(nil {:a 1, :b "unique", :c "same"} nil) {:a 1, :b "differe", :c "same"} nil] {:a 1, :b "three", :c "same"} nil]
i don’t understand that.

sundarj22:06:01

you end up diffing the next map against a diff that way

mfm22:06:03

and when it compares the diff against the next map in the seq, they look competely different

mfm22:06:00

i’ll have to keep thinking about this a little bit. thanks lilactown and sundarj for your help so far

lilactown22:06:16

if comparing each el to the previous in the seq, then you can probably reduce it to a value that's like [prev-map seq-of-diffs]

lilactown22:06:33

(reduce (fn [[prev diffs] cur] [cur (conj diffs (clojure.data/diff prev cur))]) 
        [{} []] 
        my-seq)
or something similar