Fork me on GitHub
#beginners
<
2018-05-08
>
hiredman00:05:41

':use' is kind of old fashioned, ':require' is what is pretty much always used these days, and it has a super set of use's functionality

4
4
madstap00:05:34

Also there's no :use in clojurescript

mfikes00:05:37

@madstap Sadly, there is :use in ClojureScript, but it must be combined with :only

mfikes00:05:48

In terms of ns forms, this is a good pattern to "just follow", IMHO: https://stuartsierra.com/2016/clojure-how-to-ns.html

☝️ 12
4
sova-soars-the-sora00:05:21

Oh hey @mfikes thanks! That's actually a very nice breakdown. Haha, I adore the line "Summary: make it look like this." that's exactly what I was hounding for.

Smith01:05:30

Guys, how do i use a native function from ReactNative with Reagent? like fetch() for example

Drew Verlee04:05:48

Can someone point me to the docs on calling clojure from java? I’m assuming the two steps are: 1. add a gen class function that describes the functions you want to generate a class for… though im not sure of the specifics 2. Use the clojure.java.api.Clojure to call these java classes.

seancorfield06:05:41

Don't use gen-class would be my recommendation!

seancorfield06:05:00

The Var/invoke API is fine. You don't need to compile code. AOT is the devil 🙂

Drew Verlee11:05:54

Thanks sean. Some docs seemed to imply i didn’t need to, but i wasn’t sure if they were just omitting it because it was commonly understood.

hawari08:05:11

Does anybody ever had a problem when dealing with curly brackets in clojure regex? I'm trying to extract a word inside a curly bracket:

(re-matches #"\{\w+\}" "/user/{type}:{id}")
But it can't find the type and id string and resulted nil. I've tried double escaping the { and } but then it resulted in RuntimeException, clojure complaining that there's an unmatched ). Why does my seemingly innocent regex can interfere with Clojure reader?

danm08:05:51

Your string doesn't match

danm08:05:59

re-matches only matches if the entire string given matches, and your regex fails to match the /user/ or the :{id}

danm08:05:15

re-find will get the first match, so return {type}

orestis08:05:47

Is there a quick-start template based on tools.deps that includes nRepl support (so it can be used with CIDER?)

orestis09:05:26

Oh, cider can run its own nRepl? AWESOME

gon09:05:54

you are lucky, the latest release 0.17 adds support just for that! 🙂

orestis11:05:39

Yeah, I saw that announcement but I thought I had to do add some stuff to my deps.edn file 🙂

danm08:05:44

re-seq would return a list of {type} and {id}

danm08:05:05

Your escaping is correct though

hawari08:05:23

Ah you're right @carr0t, should've read it in clojuredocs:

;; The distinction is that re-find tries to find _any part_ of the string
;; that matches the pattern, but re-matches only matches if the _entire_
;; string matches the pattern.

4
hawari08:05:46

Thank you very much for pointing it out

orestis09:05:57

I want to model some tree-like data with internal links using basic map/vector/set structures. For example, I might have articles and users and each article could have an author link back to the users vector, in such a way that there is no duplication of the user data. (This is just a modelling experiment, not something that will live in production). I guess the various “mutable” stuff like vars and atoms help here but I wonder if there is a proven way of doing this kind of in-memory modelling?

sundarj11:05:18

i'm a big fan of the way Om Next and Fulcro do it (a normalized in-memory graph): http://book.fulcrologic.com/#_the_secret_sauce_normalizing_the_database https://github.com/omcljs/om/wiki/Components,-Identity-&amp;-Normalization so for your example it might look something like:

{:articles [[:article/by-id 1]]
 :users [[:user/by-id 91]]
 :article/by-id {1 {:db/id 1, :article/title "foo", :article/author [:user/by-id 91]}}
 :user/by-id {91 {:db/id 91, :user/name "billy"}}}

orestis11:05:26

Oh, that’s neat — now how to get this to the server? I guess DataScript could also be helpful for a first draft?

sundarj11:05:20

with Fulcro/Om Next what happens is that you have that kind of in-memory database on the client, and each component has a query that it sends to a 'remote' (which could either be a server or a client-side database like datascript). then the remote responds to the query however it chooses - so for example if a component queries for :user/name, then the remote gets asked for that, and does the appropriate action for whatever the underlying database is to return that specific piece of data

orestis11:05:26

Right, yes. What I want to do (to start with) is being able to model my data server-side without worrying too much about storage, structure and so on. Perhaps using plain maps/vectors but not be enough given the relations between entities. I now see though that DataScript can be run on the server side and be like a baby Datomic…

sundarj11:05:50

yeah that's what ends up happening with Fulcro - you start by just hard-coding an in-memory database on the server (or just the client) and respond to queries from that, then later on you change it to an actual database

sundarj11:05:21

the client-side code is the same regardless

orestis11:05:17

Nice — though to clarify, I’m not even thinking about UI at this point. Just the most canonical and ideal representation of my domain as data that I can come up with.

sundarj11:05:52

right. there's a good library for building these kinds of graph query parsers: https://github.com/wilkerlucio/pathom

orestis12:05:35

Ah, this is what walkable is built on? I’ll have a look, thanks.

4
orestis09:05:32

I’ve expanded my thoughts here: https://clojureverse.org/t/data-modelling-approaches/2118 — any feedback appreciated!

joshkh13:05:27

java interop question.. how can i reference / get a handle on the http constant in this class? https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/cloudfront/util/SignerUtils.Protocol.html#http

joshkh13:05:44

(say, pass it as an argument to another constructor)

schmee13:05:24

you should be able to use (:import [com.amazonaws.services.cloudfront.util.SignerUtils Protocol]) and then use Protocol$http

joshkh13:05:07

so that's what i thought, but then...

(:import [com.amazonaws.services.cloudfront.util.SignerUtils Protocol])
CompilerException java.lang.RuntimeException: Unable to resolve symbol: Protocol in this context, compiling:(/private/var/folders/tx/nvfg34312m31g7gsbkjyxxqh0000gn/T/form-init7297532591394822523.clj:1:1)

joshkh13:05:51

and i've confirmed i'm on the latest version. hmmm.

schmee13:05:52

ahh, try (:import [com.amazonaws.services.cloudfront.util SignerUtils SignerUtils$Protocol]) and then SignerUtils$Protocol/http

schmee13:05:13

there is always a bit of guesswork involved to make stuff like this work (at least for me), it’s easier if you can use auto-complete in the REPL 😛

joshkh13:05:24

🙃

(:import [com.amazonaws.services.cloudfront.util SignerUtils SignerUtils$Protocol])
CompilerException java.lang.ClassNotFoundException: com.amazonaws.services.cloudfront.util, compiling:(/private/var/folders/tx/nvfg34312m31g7gsbkjyxxqh0000gn/T/form-init7297532591394822523.clj:1:1) 

joshkh13:05:39

autocomplete never gets farther than SignerUtils

schmee13:05:13

user=> (import [com.amazonaws.services.cloudfront.util SignerUtils SignerUtils$Protocol])
com.amazonaws.services.cloudfront.util.SignerUtils$Protocol
user=> SignerUtils$Protocol/http
#object[com.amazonaws.services.cloudfront.util.SignerUtils$Protocol 0x238d27ef "http"]

schmee13:05:47

ahh, I think the : at the beginning threw you for a loop

schmee13:05:52

that is for the ns declaration, not the REPL 🙂

joshkh13:05:21

whoops, yeah - copied an example from the ns and not the repl

joshkh13:05:33

but yes, that one did the trick! thanks a lot.

👍 4
joshkh14:05:26

out of curiosity, what stops me from importing all the way down to the Protocol class?

schmee14:05:18

Protocol is an inner class of SignerUtils, but inner classes don’t exist at the class file level, they just get renamed to OuterClass$InnerClass and then there are a bunch of hacks in the Java compiler to make private variable access and stuff like that work

schmee14:05:00

since Clojure operates on class files it must import it with actual name in the class file, which is SignerUtils$Protocol

schmee14:05:17

incidentally, the inner class hacks will not be required once the concept of “nestmates” are introduced: http://openjdk.java.net/jeps/181

👍 4
joshkh14:05:18

thanks for the excellent explanation

Casey15:05:27

I can never remember the order of arguments to the f in reduce

Casey15:05:46

is val the first argument or the 2nd?

Alex Miller (Clojure team)15:05:32

-2nd, the first is always the accumulator-

Casey15:05:03

Ah, just saw the handy source link on the docs entry.

Alex Miller (Clojure team)15:05:11

oh, sorry I’m mixing terms - here val is the initial accumulator, so 1st :)

joelsanchez15:05:25

I always begin a reduce with (reduce (fn [acc itm]

Casey15:05:55

"the first is always the accumulator" <---- gotta remember that

sundarj16:05:40

if you think about a reduce like starting with an initial value, then continually adding new values to it, then the argument order starts to make more sense 🙂

👍 4
Alex Miller (Clojure team)15:05:30

I often use fn over #() for reducing functions too - I think it helps to name those

👍 8
gklijs17:05:28

I rather like to have to function for reduce separately defined above. Sometimes taking an extra argument, using partial. Is that an anti-pattern?

tbaldridge17:05:58

Infact I often consider complex reduce bodies to be a anti-pattern,

tbaldridge17:05:30

(reduce group-by-products {} coll)
is often much more readable than the alternative

justinlee17:05:05

i’ve often wondered why clojure and other languages like javascript put the function first. if it were last, it would be easier to deal with complex function bodies because there wouldn’t be so much code before the initial value & collection

tbaldridge17:05:27

Btw, this is why arguments in clojure functions are ordered by "most likely to be partially applied"

justinlee17:05:44

oh well maybe that’s why 🙂

tbaldridge17:05:02

For example, in Datomic: (map (partial d/entity db) list-of-ids)

meow19:05:05

Hi, while doing some scouting around I found that Leiningen is top consensus choice to get a Clojure + Clojurescript learning environment going, is that still the case?

noisesmith19:05:35

yeah, even if you eventually use boot it's easier to learn leiningen first

meow19:05:01

Is there a go-to guide that still reflects how the community feels is best to get "up and going"?

meow19:05:05

(setup-wise)

noisesmith19:05:01

this is an open discussion still, but most would agree that you should use your favorite editor (whether it integrates with clojure or not, but it probably does if it's any good) and leiningen

noisesmith19:05:26

I'm sure people will contradict me if I'm off base on that

meow19:05:27

I see, thanks!

Alex Miller (Clojure team)19:05:21

depending what you want, the clj tool may be sufficient - see https://clojure.org/guides/getting_started

meow19:05:57

How foolish is it to explore Clojure without first familiarizing with Java and JVM?

Alex Miller (Clojure team)19:05:03

Clojure doesn’t hide its host so you will be starting the jvm and may see jvm stack traces, but otherwise, you can largely ignore it at the beginning. over time there are some parts of the JDK that are useful to know about and interop for leveraging Java libs, but you can push that off quite a while

meow19:05:15

I see, thanks!

Alex Miller (Clojure team)19:05:29

there are some “jvm for clojurists” type posts out there too

meow19:05:29

I'm trying to transition from a Lisp onto Clojure

meow19:05:43

I'd first want to do Clojure as long as possible before I have to deal with underlying Java

meow19:05:49

I was just curious as to how much one could ignore Java (for awhile)

Alex Miller (Clojure team)19:05:14

^^ that page is probably sufficient

Alex Miller (Clojure team)19:05:34

probably more than sufficient actually

naijeru19:05:22

i’m finding it’s impossible to ignore java

hiredman19:05:05

there are kind of three parts to java 1. the jvm 2. the libraries that are part of the jre 3. popular 3rd party java libraries

hiredman19:05:10

and that is also the order of usefulness of the knowledge about those things

tstelzer19:05:53

are there alternatives to using nrepl? i got it to work with my editor-setup, but it breaks on the newest version (using the nrepl-middleware)

naijeru19:05:42

yeah i haven’t gotten up to java interop yet, just dealing with interpreting stack traces and the current bane of my existence which is the NullPointerException

dpsutton19:05:50

are you using CIDER by any chance?

dpsutton19:05:00

i only mention that since it has some good ways to filter stacktraces and nav to code

naijeru19:05:30

no just atom and nrepl

naijeru19:05:56

i haven’t explored many tools yet, still coming to grips with the language

naijeru19:05:44

i managed to implement a* with little difficulty so i’m very excited about learning more!

dpsutton19:05:10

don't change anything right now. just if you happened to be using it

rodrigojuarez20:05:41

Hi! Is there a better way to do this kind of destructuring?

(let [new-shape-size (:new-shape-size state)
        current-shape (:current-shape state)
        shape-angle (:shape-angle state)
I wonder if there’s something like
(let [new-shape-size from state]

Alex Miller (Clojure team)20:05:42

(let [{:keys [new-shape-size current-shape shape-angle]} state] ... )

🙌 4
meow20:05:42

How do people typically install and manage Java?

tbaldridge20:05:13

it's normally part of the OS install

mfikes20:05:49

On macOS, I've been doing brew cask install java as of late

meow20:05:55

mmm I must've removed it some time ago -_-a

tbaldridge20:05:00

depends on what you mean though. In production I've never had to manage it, the server VMs came with it

tbaldridge20:05:16

ditto for OSX it comes with a recent enough version

schmee20:05:01

I’ve been using jenv on osx to great effect lately

meow20:05:07

I mean manage like what nvm does for the Node / JS world

meow20:05:22

I was also looking into asdf, which apparently some people use to manage Java versions

tbaldridge20:05:31

osx comes with that

tbaldridge20:05:39

but very rarely do you need mroe than one jvm on a single box

schmee20:05:37

I use Java 8 for work, Java 10 + Graal for personal project so I switch around a lot

meow20:05:37

ah, I'm on Ubuntu, and I must've somehow deleted my installation

tbaldridge20:05:45

apt is what you want then

meow20:05:49

and the Oracle website comes with an archive format that confuses me 😄

mfikes20:05:43

There is a ppa for Ubuntu.

mfikes20:05:46

Or you can just apt-get install default-jdk

dpsutton20:05:37

Isn't asdf the common lisp package system?

😄 4
justinlee22:05:08

is there a nice chart cheatsheet out there of map vs mapv vs run vs doseq, in particular the lazy vs nonlazy versions? i have some kind of mental block about remembering what’s lazy and what to do when i need a nonlazy version

noisesmith22:05:54

it's` run!` btw, "do", "!" in the name, and returning a vector all mean "not lazy" if that helps

justinlee22:05:08

and the difference between run! and doall is whether the sequence i returned? anything else?

noisesmith22:05:27

you are thinking dorun

justinlee22:05:31

i feel like i’ve read you give the same advice a million times and i feel bad for not absorbing it

noisesmith22:05:39

the difference between dorun and doall is that doall returns the sequence

noisesmith22:05:13

now that run! exists I rarely find a use for dorun, fwiw - maybe others have coding styles where it still comes up though

justinlee22:05:17

i see so when i moved from mapv to map-indexed this is why i got screwed up because vectors are nonlazy (?)

noisesmith22:05:44

for your actual question, there's no cheatsheet that I know of, but if I made one it would have dorun, doall, doseq, dotimes, run! on one side, and for / map / mapcat on the other

noisesmith22:05:57

right, vectors are never lazy

justinlee22:05:16

maybe i’ll make my own gist and solicit input from you 🙂

noisesmith22:05:51

in fact we can fudge the specifics and say "only lazy seqs are lazy" (strictly speaking there's a few lazy types but they all act like lazy seqs, that is, linked lists, in being unindexed and having a first and rest)