Fork me on GitHub
#beginners
<
2019-04-15
>
tabidots02:04:05

@gr.evocatus How did your prime number adventure work out? I ended up having to use this yesterday on Problem 437, because 10^8 was just too high of an upper bound for my homemade function. https://stackoverflow.com/a/48137788/4210855 It generates primes up to 10^8 in ~35s on my computer, which is far faster even than this very fancy implementation: https://github.com/hypirion/primes/ It’s pretty readable considering the complexity of what it’s doing, but I would still consider this fairly advanced Clojure (to me, anyway)

kenj02:04:12

Do people leave some sort of network enabled repl like nRepl enabled on their production deployments just in case?

seancorfield02:04:57

We have a Socket REPL running in several of our production processes, yes. But those ports are not open on those boxes except via loopback so it requires an ssh tunnel over the VPN in order to access them (and if someone can get into our VPN, we have bigger problems than an open REPL).

kenj03:04:38

Is socket repl the way to go for that sort of thing?

seancorfield03:04:28

I prefer that to having nREPL etc as a dependency in production.

seancorfield03:04:49

You can use nc/`telnet` or unrepl or Atom/Chlorine....

kenj04:04:06

Gotcha, thanks!

mathpunk02:04:51

I'm so close to getting my data in outline form, but I'm a little off. The goal is to create a sublist under any of the strings that are repeated, such that it's correctly shaped to be fed to hiccup to make it into html:

mathpunk02:04:55

;; Preamble
    (use 'clojure.walk)

    (defn map-entry [k v] (clojure.lang.MapEntry/create k v))

    ;; Test data
    (def stories
      '(("Node" "is defined")
        ("Node" "breadcrumb" "links to the parent process")
        ("Node" "breadcrumb" "links to the parent workflow")
        ("Node" "breadcrumb" "when following the parent process link" "reaches the expected process")
        ("Workflow" "is defined")))


    ;; Nest the data structure
    (defn branching-rule [node]
      (cond
        (and (list? node) (every? list? node)) (group-by first node)
        (map-entry? node) (let [[k v] node]
                            (when k
                              (map-entry k (group-by first (map rest v)))))
        (map? node) (when-not (every? nil? (keys node))
                      (cons :ul (seq node)))
        :else node))

    (def outlined
      (prewalk branching-rule stories))


    ;; Format for hiccup
    (defn formatting-rule [node]
      (cond
        (string? node) [:li node]
        (and (map-entry? node) (nil? (second node))) (first node)
        :else node))

    (def formatted
      (postwalk formatting-rule outlined))

mathpunk02:04:29

formatted looks like this:

{[:li "Node"]
 (:ul
  [:li "is defined"]
  [[:li "breadcrumb"]
   (:ul
    [:li "links to the parent process"]
    [:li "links to the parent workflow"]
    [[:li "when following the parent process link"] (:ul [:li "reaches the expected process"])])]),
 [:li "Workflow"] (:ul [:li "is defined"])}

mathpunk02:04:40

goal state is, I think, something like this:

([:li "Node"
         [:ul
          [:li "is defined"]
          [:li "breadcrumb"
           [:ul
            [:li "links to the parent process"]
            [:li "links to the parent workflow"]
            [:li "when following the parent process link"
             [:ul
              [:li "reaches the expected process"]]]]]]]
        [:li "Workflow"
         [:ul
          [:li "is defined"]]])

rascio12:04:35

Hi all! I'm struggling with a very strange problem, I'm doing dirty stuffs, using clojure from maven (using just the exec plugin I was able to do the build, repl, etc.. so for some use cases it works very well. I've tried to integrate gorilla repl in the project, but when configuring the exec task I found that doing it like:

java clojure.main -m gorilla-repl.core
works fine, if I try to do it like
java clojure.main -e '(println "Clojure" (clojure-version))
                    (println gorilla-repl.core/run-gorilla-server)'
It fails with:
Caused by: java.lang.ClassNotFoundException: gorilla-repl.core
Do you have any hint to help me understand why is this happening?

alexmiller12:04:37

You have to load the namespace before you use the function from it

alexmiller12:04:05

requiring-resolve can be helpful in this case

rascio12:04:27

I'm too used to java complexity to look for the simple reasons 😕

rascio12:04:12

yep, with the require works fine...

rascio12:04:34

thank you!

skykanin14:04:26

So I’m trying to instantiate a JavaFX KeyFrame class with this constuctor KeyFrame​(Duration time, KeyValue... values), but I keep getting java.lang.ClassCastException: class clojure.lang.PersistentVector cannot be cast to class [Ljavafx.animation.KeyValue; and I’m not sure why. Isn’t it correct to use a vector for java varargs?

manutter5114:04:26

That last argument is a varargs argument, so you need to pass it in as a Java array rather than as a Clojure vec

skykanin15:04:46

I tried using to-array but now I’m getting a different cast class exception class [Ljava.lang.Object; cannot be cast to class [Ljavafx.animation.KeyValue;

manutter5116:04:52

Hmm, you need a type cast on the to-array, but I’m not sure how to do that one.

skykanin16:04:05

into-array did the trick! Thanks

👍 1
Ivan Koz15:04:42

can i have an alias for imported java class like we do with require :as?

Ivan Koz16:04:32

@alexmiller any explanation why? Overhead? At first glance it looks like nice feature.

alexmiller16:04:52

there's not a lot of value in doing so. imports are inherently a much different scenario than requires, despite their similar-looking syntax.

alexmiller16:04:27

all fully-qualified Java class names are always in scope

Ivan Koz16:04:28

yeah i was looking for something like java.lang.Math :as m ... m/pow

Ivan Koz16:04:50

for now the only reasonable option is wrapping with macros

alexmiller16:04:13

Clojure import serves only to make an unqualified name easier to write in the source, but the ability to alias classes is not a feature that Java has or that we want to add in interop support

Ivan Koz16:04:34

unqualified name easier to write <- this

alexmiller16:04:35

you don't need a macro - you can use a function

Ivan Koz16:04:59

but macro is faster

Ivan Koz16:04:16

i mean i understood thank you, not trying to be annoying

alexmiller16:04:18

but can't be applied, so is more limited

alexmiller16:04:22

or use memfn

alexmiller16:04:34

(although be wary of introducing reflection with it)

alexmiller16:04:00

Math/pow is only 3 more chars... :)

Ivan Koz16:04:43

i was thinking if we already have import to make fully qualified names shorter, why not add aliasing, to make it like 1 character long 😃

ghadi16:04:19

now you have two problems names

Ivan Koz16:04:31

yeah as always 😃

Ivan Koz16:04:54

solve one bug to get ten more

Cas Shun17:04:04

hello, I have a collection of namespaced keywords like (:tree/pine :tree/maple :bush/rose :bush/cherry). I wish to either extract all keywords of a given namespace like :tree or :bush, or to partition the collection by their namespace. Is there a shortcut to this, or is filter/remove based on the name space the way to go?

donaldball17:04:12

group-by would help with the latter

kari17:04:25

I'm starting a new Clojure project and I'd like to learn to use deps.edn. A couple of questions. 1. Is deps.edn just for dependency management? Do I still need e.g. Leiningen to create uberjars for my application? 2. Am I able to use IntelliJ IDEA / Cursive REPL as fluently as with Leiningen? 3. Is there some document which provides light to these questions?

jaihindhreddy18:04:36

1. Yes. tools.deps.alpha is a library that does dependency management, and nothing else. Creates a classpath traversing deps.edn files recursively. The command-line tool clojure uses this and adds a convenient way to invoke code (aliases come in here) 2. I'm not sure what you mean by fluently. tools.deps.alpha currently doesn't have the ability to understand project.clj files if that's what you mean. But there are tools to create deps.edn files from project.clj files. 3. The reference https://clojure.org/reference/deps_and_cli, provides an in-depth explanation of all the above, and more. Here's a list of libraries that leverage deps.edn https://github.com/clojure/tools.deps.alpha/wiki/Tools Also checkout Sean Corfield's deps.edn file for inspiration. It has a bunch of neat things. https://github.com/seancorfield/dot-clojure

didibus18:04:11

Ya, deps.edn only manages dependencies. You can define dependent libraries, and it will pull them down on your machine and create a Java class path which points to them for you.

didibus18:04:45

It currently supports maven repos, and git as places from which it can pull down dependencies.

noisesmith18:04:58

by fluency I assume @U76D9RZRR means repl/editor integration, there are tools that try to build an ecosystem around tools.deps but eg. cider or cursive are easier to use with leiningen

didibus18:04:40

You still need a way to perform any kind of build tasks you would want, independently of tools.deps

didibus18:04:02

The Clojure CLI is a launcher for Clojure programs. When you launch a Clojure programs which require namespace or imports classes that are not part of the main namespace, you need to give the JVM (the runtime for Clojure programs) a path where it can search for them.

didibus18:04:40

tools.deps can pull dependencies and generate the path to them.

didibus18:04:02

Thus, the Clojure CLI is able to use tools.deps to get the path for your program.

didibus18:04:02

You can still use leiningen as a build tool, but swap out its dependency manager for tools.deps by using this:

kari18:04:03

@U051SS2EU: Yep, I mean fluent repl/editor integration with Cursive.

didibus18:04:46

lein-tools-deps

kari18:04:49

I really love cursive and all my hot keys with it, e.g. how to jump between editor windows and repl etc.

kari18:04:52

So, basically with those tools (lein-tools-deps) etc. I can start using deps.edn as main dependency mechanism and still use Leiningen to build my uberjars etc?

kari18:04:20

Or is there some new standard way to create uberjars, use profiles etc. with deps.edn?

didibus18:04:31

That said, a lot of people prefer using normal Clojure programs as tasks.

didibus18:04:58

Basically, leiningen is like a framework for writing build tasks.

didibus18:04:30

Where as there are now lightweight Clojure programs as independent tasks, all using tools.deps to grab the dependencies

didibus18:04:23

The difference is that, each of these tools are independent. So they don't share any convention or structure.

didibus18:04:50

Where as lein tasks have more convention and structure, as they have to follow the lein plugin mechanisms

kari18:04:55

Ok. I think I got the general picture.

didibus18:04:03

I think where it matters is when you need customization. If you need to write custom build tasks, the pure Clojure program way is simpler to a lot of people, because you don't need to learn a framework like lein or boot.

didibus18:04:41

But if you don't, lein is probably better, because you don't need to re-learn conventions of every single tasks.

didibus18:04:08

Now, as to IDE support. It has started, but it's still not as solid as lein.

didibus18:04:00

IDEs rely more on the dependency management of lein then its build tasks. They used lein to setup a REPL with the right dependencies of your project and to inject additional dependencies into the REPL.

didibus18:04:49

Cursive has added support for tools.deps instead of lein, same with Cider. But its newer, not as battle tested, and there might still be some features missing.

kari18:04:33

Any experience using deps.edn with Cursive?

didibus18:04:18

Sorry. I don't. But what I do know is that the feature hasn't been documented in the official Cursive doc yet.

didibus18:04:36

Which should tell you a bit about its current state.

kari18:04:54

And how do you build uberjars with deps.edn? Just manually compiling classes and gather dependencies and calling jar tool or something like that? Or do you use e.g. Leiningen with lein-tools-deps to build uberjar anyway?

didibus18:04:19

Like I think you need to use the beta release of Cursive to get the support

noisesmith18:04:30

deps.edn itself will never do uberjar or other build tasks - it's just a dep manager. People have released libraries / tools to be used with deps.edn to replicate the most common leiningen tasks

didibus18:04:32

You just use lein-tools-deps

didibus18:04:55

Or any other uberjar tool with support for tools.deps as its dependency resolver

didibus18:04:58

Such as depstar

didibus18:04:05

You can also manually compile classes and jar them. You don't need to manually gather them though, that's the part you can use tools.deps for

didibus18:04:32

Basically, if you wrote a program that did that, you'd have created a new uberjarring tool for tools.deps

didibus18:04:45

And so some people have done just that and released their tool.

kari18:04:57

Maybe I just start using deps.edn with Cursive and let's see how it unfolds. 🙂

kari18:04:29

This clojurians slack is awesome (a bit unnatural for me to use that word as a Finn, but it is awesome 🙂 ).

kari18:04:49

And you guys are also awesome the way you help us beginners.

kari18:04:39

I have now a much better understanding about these tools.

didibus19:04:41

Eh, our pleasure. I definitly love the Clojure community as well. And a few years back, they helped me out a lot as a beginner. So just trying to give back!

Cas Shun17:04:38

ahh, (group-by namespace coll) works then. Thank you @donaldball

CyberSapiens9718:04:37

anybody here that uses clj-http library? i'm trying to create a get request with more than one :query-params, and it's not working, tried to look on the documentation but didn't found anything there

Nate Sutton19:04:15

anyone have a handy way to remember the difference between cons and conj?

ghadi19:04:42

cons is for lists, conj is for everything else

ghadi19:04:02

conj on a list is cons

Nate Sutton19:04:53

well sure, that's what the docs say, but remembering which is which

Nate Sutton19:04:04

their order of args are different even

Nate Sutton19:04:19

just a thing you eventually remember, I guess?

ghadi19:04:25

just one of those things

dpsutton19:04:25

ignore cons for two months and get used to conj.

dpsutton19:04:58

in my experience it is used very infrequently. conj is used constantly

1
seancorfield20:04:52

@nate_clojurians It may help to think cons is a sequence operation (associate the s with sequence) and sequence functions take the sequence as the last argument; conj is a collection operation and collection functions take the collection as the first argument.

Nate Sutton20:04:35

ah, that's another thing to learn. the order of args was a head-scratcher

seancorfield20:04:44

cons converts its argument to a sequence and produces a sequence; conj produces a collection that is the same type as its argument.

seancorfield20:04:27

map/`filter`/`reduce` etc are all sequence functions -- sequence as the last argument; nth/`conj` etc are collection functions -- collection as the first argument. It's pretty consistent once you know that's the driver for it.

Nate Sutton20:04:58

I'll try to keep that in mind

Nate Sutton20:04:56

so take would be a sequence function

hipster coder20:04:37

The cons artists switched the order of the jewls on you hahahaha

hipster coder20:04:37

user=> (cons 4 x)
(4 1 2 3)

Nico20:04:16

what would be the function to return a seq with the item at a specific index changed for another one?

hiredman20:04:25

don't do that

Mno20:04:00

I guess an array is made for specifically this

hiredman20:04:05

seqs are not indexed, if you want to do things by index you want something else

Nate Sutton20:04:35

for vector you can use assoc to update a value at an index

Nico20:04:03

ah, I can use assoc as it's a vector

sotrhraven21:04:52

Has anyone taken any of the clojure courses on Udemy?