Fork me on GitHub
#beginners
<
2021-12-16
>
Daniel Craig02:12:35

I love this channel, I learn so much from other people's questions

gratitude 7
👍 2
jeffy12:12:49

Hey guys, am looking for a clojure library to access elasticsearch. Am using latest version of elasticsearch (7.16.1) and already tried https://github.com/clojurewerkz/elastisch, but it looks like it does not support elasticsearch version 7. For example when I create an index I get 405 error message and it looks like elastich uses POST for creating index and since elasticsearch version 6, index is created using PUT and not POST. If anyone knows any other library that can be used with elasticsearch version 7, please let me know 🙂

Cora (she/her)15:12:16

you can always use the java library for elasticsearch

jeffy16:12:47

thanks, will try.

Filip Strajnar15:12:23

I'm going through book Clojure for the brave and true, and they mention this is operation

Filip Strajnar15:12:58

are operators something that only a language can specify, or can a macro make a new operator?

Cora (she/her)15:12:01

you can make new operators

Cora (she/her)15:12:11

or via functions

Cora (she/her)15:12:21

operators are just functions/macros

Filip Strajnar15:12:25

so what i considered a function, is really just an operator?

Cora (she/her)15:12:50

assuming this is what they mean

Filip Strajnar15:12:36

I don't think that's the same, because in the book, they mention branching constructs as operators too

Cora (she/her)15:12:05

ah, well, then it's all functions and macros then

Ben Sless15:12:19

Any form (rator rand ...) The first element is the operator. It can be a function which means it will be evaluated at run time, or a macro which will be evaluated at compile time

Ben Sless15:12:48

Generic term to mean either function or macro

Filip Strajnar15:12:50

or a built in operator? or is in built operator just a function?

Filip Strajnar15:12:18

i think it's fine if i just assume in built operator is just a functions really

Ben Sless15:12:55

Some are directly compiled, special forms. They include def fn* let* loop*, if, do

Ben Sless15:12:08

There are a few

alexmiller16:12:29

"Operators" are not a thing in Clojure - that tutorial is wrong (or trying to give you a story that might relate from another language)

💯 1
Filip Strajnar16:12:22

what is a thing then

Filip Strajnar16:12:31

Cora recommended that book

Cora (she/her)16:12:24

I'm actually not a big fan of that book. I love Getting Clojure, though.

alexmiller16:12:08

in other languages, there are syntactic operators defined in the language syntax

alexmiller16:12:01

in Clojure the first element in a parenthesized expression is "a thing that can be invoked". if you want to call that position the "operator" that's ok, but it's important that it's not a fixed set of things in the syntax

Filip Strajnar16:12:01

so, if we decide to call the first position operator, operator is either a function or a macro, either pre-defined or in built in the language?

alexmiller16:12:09

generally the things to be invoked are either functions (almost everything) or special forms (defined by the language)

alexmiller16:12:45

things like + are just functions provided in clojure.core

Filip Strajnar16:12:11

it's also safe to assume that every time i use (), i'm invoking / evaluating an expression?

Filip Strajnar16:12:36

except for '(), which is un evaluated list?

quoll21:12:15

There’s actually a special case for () Whenever you see (a b c) then that means to evaluate something (treating a as a function and the others as arguments). Whenever you see '(a b c) then the quote has prevented evaluation, and it’s a list of 3 elements. Whenever you want an empty list, you can say '(), but the special case I mentioned is: () The empty list can’t be calling a function, so instead it’s just treated as a literal empty list. So (= () '()) returns true. (identical? () '()) also returns true

andy.fingerhut22:12:39

I would be a little cautious about promising that identical? returns true in such cases. It might happen to in the current implementation, but I wouldn't be surprised if you can find ways to construct two non-identical empty lists.

andy.fingerhut22:12:20

That is a minor side-nitpick comment, though, not the main point.

quoll22:12:03

TBH, I wasn’t sure if it would, but I thought it might, and sure enough, it did. After all, they’re both just clojure.lang.PersistentList/EMPTY (this isn’t a conversation to have in this thread though)

alexmiller16:12:54

lists are evaluated by invoking the first element with the rest of the elements as args

alexmiller16:12:19

'() is special only because of the quote, which says to read, but not evaluate

Filip Strajnar16:12:43

but other than that, when i see (), clojure is evaluating?

alexmiller16:12:52

you might find https://clojure.org/guides/learn/syntax a helpful starting point on the basics

alexmiller16:12:06

it covers most of this

Filip Strajnar16:12:53

i already read this, but coming back to it, i understand it better

dpsutton16:12:54

On a pedagogical note, it’s also generally beneficial to get a basic working model that is not comprehensive, and let your understanding and complexity of your model increase with time. Chemistry, math, physics, economics, probably everything, all work like this when we learn. Understanding that image you just posted is probably a great starting point for a good while

pavlosmelissinos16:12:22

I have a vector of words and I want to remove the empty ones, which of the following would you use?

(remove empty? words) ;; close to the semantics of the goal but uses a double negative

(filter seq words) ;; common idiom but not sure if the intent is as clear to the casual reader

vanelsas16:12:50

Depending on what the empty ones are, you can also use

vanelsas16:12:10

(filter identity words)

vanelsas16:12:18

to get rid of nil values

dpsutton16:12:48

(filter seq words) is what i’d go with. that idiom is clear to the casual Clojure reader

👍 1
alexmiller16:12:59

I always prefer remove over filter - I think as the verb here it says what you want most closely

alexmiller16:12:29

"I want to remove the empty ones" -> (remove empty? words)

👍 3
alexmiller16:12:06

"filter" as a word is always a little ambiguous as to whether you are filtering things out or in. clearly it's "in" in Clojure, but from an English point of view I think it causes a moment of mental hesitancy that I do not get from "remove"

👍 2
pavlosmelissinos16:12:17

@U01M742UT8F I don't expect any nils but there can definitely be empty strings in the vector, so identity won't cut it unfortunately... 😞 e.g. ["Elvis" "has" "" "left" "the" nil "building"] @alexmiller that's what I thought, generally I'm with @U11BV7MTK but in this case remove does sound more natural to me as well, thank you both 🙂

Darin Douglass16:12:46

str/blank? to the rescue!

dpsutton16:12:54

alex always gives thoughtful advice 🙂

1
sheluchin16:12:46

(def x {:a 1 :b 2})
How do I subsequently qualify this map to something like
#:foo {:a 1 :b 2}

alexmiller16:12:57

an important thing to note is that the map is not qualified, that is just a syntax that can be used when all keys (or symbols) share the same namespace

alexmiller16:12:36

the map is {:foo/a 1 :foo/b 2}

sheluchin16:12:00

Good point. Is there any sugar to qualify each key in the map to the same namespace or do I need to reduce it?

alexmiller16:12:24

there is no core function that can magically do this ( update-keys is coming in 1.11 though) so you would need to transform the starting map into a target map

alexmiller16:12:28

(reduce-kv #(assoc %1 (keyword "foo" (name %2)) %3) {} x) is one option

sheluchin16:12:42

Sounds like 1.11 has some nice stuff in it. Thanks as always @alexmiller.

Michael W16:12:48

This is something I still struggle with, how to represent as edn a mixed map using the literal for the namespace.

(def d {:blah/name "my blah name" :id 1})
This doesn't work and I am not sure why.
{#:blah{:name "my blah name"} :id 1}

alexmiller16:12:32

well that particular outer map only has 3 elements in it

alexmiller16:12:09

those two things are not the same - you've introduced a nesting level

alexmiller16:12:54

#:blah{:name "my blah name" :_/id 1} can be used for this

alexmiller16:12:11

although I can pretty confidently say almost no one is even aware that exists

😄 4
🤯 2
Michael W17:12:05

Thank you that works perfectly.

stopa17:12:31

Hey team, I’m trying to convert a curl request, into a clj-http call:

curl '' \
  -H 'pragma: no-cache' \
  -H 'cache-control: no-cache' \
  -H 'sec-ch-ua: "Not A;Brand";v="99", "Chromium";v="96", "Google Chrome";v="96"' \
  -H 'sec-ch-ua-mobile: ?0' \
  -H 'sec-ch-ua-platform: "macOS"' \
  -H 'upgrade-insecure-requests: 1' \
  -H 'user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.93 Safari/537.36' \
  -H 'accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9' \
  -H 'sec-fetch-site: none' \
  -H 'sec-fetch-mode: navigate' \
  -H 'sec-fetch-user: ?1' \
  -H 'sec-fetch-dest: document' \
  -H 'accept-language: en-US,en;q=0.9,fr;q=0.8,ka;q=0.7' \
  -H 'cookie: ajs_anonymous_id=...; notice_behavior=...; <redacted>' \
  --compressed
Now the question is, how to get the cookie into a ClientCookie I have the following in a file:
ajs_anonymous_id=...; notice_behavior=...; <redacted> converted to a ClientCookie. 
Then, if I write:
(clj-http.cookies/decode-cookie (slurp (io/resource "mfp_cookie.txt")))                                                                                                             
It only seems to ge the “first part” of the cookie (the ajs_anonymous_id) Does anyone know how I can get it to parse the whole thing?

Cora (she/her)17:12:59

split on semicolon and decode each separately?

❤️ 1
Cora (she/her)17:12:41

I mean you can more or less split on semicolon and then split each on the first =, taking into account that some cookie values aren't key=val

Cora (she/her)17:12:15

here's one I used for decoding cookies in an app

Cora (she/her)17:12:32

or it looks like you could split on ; and pass that to the plural function? https://github.com/dakrone/clj-http/blob/3.12.1/src/clj_http/cookies.clj#L79-L83

Filip Strajnar17:12:23

is there parhaps a tool that'd auto suggest possible namespaces/ classes to import?

Filip Strajnar17:12:36

and methods of specific instance of object?

Filip Strajnar17:12:47

(interop with java libraries)

Filip Strajnar18:12:28

i can imagine chances of this existing being slim but i figured i'd ask

seancorfield18:12:00

@filip.strajnar do you mean in the context of an editor/IDE? If so, I believe IntelliJ/Cursive does that and so does VS Code/Calva to some extent (with LSP support).

ericdallo20:12:58

@filip.strajnar https://clojure-lsp.io/ has a really good support for requires/refers but not for imports/classes as we don't have support for java classes yet on clj-kondo, but it's on the radar

1
stopa18:12:53

Thanks @corasaurus-hex! Worked like a charm. For future reference, here’s what I did:

(clj-http/get
   (str ""
        username "?from=" from-date-str "&to=" to-date-str)
   {:throw-entire-message? true
    :headers mfp-headers
    :cookies (->> (-> (slurp (io/resource "mfp_cookie.txt"))
                      (string/split #";"))
                  (map cookies/decode-cookie))})

metal 1
Jane18:12:18

#beginners

Jane18:12:07

Can someone please tell me where exactly I should start to get my hands on clojure, I'm a beginner

practicalli-john11:12:39

Where you start is shaped by what you want to achieve. Some common steps include • set up clojure and run a repl • choose a Clojure aware editor • learn the basic syntax and start learning about common functions (https://clojuredocs.org/, https://practical.li/clojure/coding-challenges/4clojure/, http://exercism.io) • start working on projects / building apps and services Hopefully you find https://practical.li/clojure/ a useful resource to help you get started (its freely available) There are also 100+ hours of Clojure coding videos at https://practical.li/ , the https://www.youtube.com/playlist?list=PLpr9V-R8ZxiDB_KGrbliCsCUrmcBvdW16 and https://www.youtube.com/playlist?list=PLpr9V-R8ZxiClng6zv2wqIEd_tOQB7gKx videos are especially useful for beginners

❤️ 1
Jane16:12:32

Will do, Thanks

seancorfield18:12:00

@jabeen2699 Welcome! Are you a beginner to programming as a whole or just to Clojure? Also, are you on Windows or Linux/macOS?

Jane18:12:00

Just to clojure, and I'm on macOS

seancorfield18:12:33

Cool. So https://www.clojure.org/guides/getting_started should get you up and running with the basics.

seancorfield18:12:41

A lot of folks also recommend https://www.braveclojure.com/ but it introduces Emacs which can be a bit daunting (you can ignore the Emacs stuff if you have an alternative editor with Clojure integration).

seancorfield18:12:14

What editor/IDE do you use today, and what language(s) are you normally working with?

Jane18:12:53

I've just installed intellij

Jane18:12:05

And worked on c,c++ and python

seancorfield19:12:49

You'll probably want to join the #cursive channel -- the maintainer of that IntelliJ plugin is very responsive, as are other users there.

❤️ 1
pez19:12:01

@jabeen2699 , I’ve created an interactive guide for that. Would love to know if you think it does the job: https://calva.io/get-started-with-clojure/

❤️ 2
Cora (she/her)19:12:31

on macos you can install clojure through homebrew, fwiw

👍 1
Antonio Bibiano19:12:37

the getting started repl in calva it's fantastic to get a feeling for the language 🙂

❤️ 2
2
👍 1
mister_m20:12:34

sort of a loaded question, but should I use lein or the clojure cli tools? Does one offer some functionality that the other does not?

alexmiller20:12:39

should use them for what ? :)

mister_m20:12:29

Really the main thing I guess is dependency management for me atm - not necessarily packaging

dpsutton20:12:48

I think the clojure cli really shines at that

dpsutton20:12:53

packaging is a bit more configuration and often a small script with clojure cli. But so are the lein based versions, they are just baked in for you and are very difficult to diagnose or change. It is nice when they just work™ but very annoying if their defaults about what to include in a jar aren’t what you need

lsenjov23:12:43

Personally: lein is batteries included for a lot of things, but the moment you try doing something a bit more complicated you’ll usually start hitting walls. clj has very little magic to it, which sometimes means doing a bit more work than its lein counterpart, but anything more difficult becomes far simpler. I started with lein, and moved over because of this. But also note I moved over because I started doing things that didn’t need batteries included. As a beginner, either will serve you pretty well.