Fork me on GitHub
#beginners
<
2017-11-13
>
athomasoriginal00:11:14

I have a folder structure like this:

src/
   cljc/
      events/
          core.cljc
   cljs/
      fun/
          core.cljs
My build.boot file looks like this:
(set-env!
  :source-paths #{"src/cljs" "src/cljc" "test/cljc"}
  :resource-paths #{"resources"}

  :dependencies '[[org.clojure/clojure       "1.8.0"]
                             ;; ....
Everything works, except now I want to (:require [events.core :refer :all]) into my fun.core.cljs file. This breaks the compiler though. Am I missing something?

athomasoriginal00:11:02

okay, problem seemed to be I included :gen-class at the top of my cljc. It was there from when it was just a clj file

derpocious00:11:03

thanks a lot guys!

derpocious00:11:13

I'm now having another slight issue

derpocious00:11:38

Trying to figure out why this yields "Can't recur here at line 9"

derpocious00:11:43

(defn integersLessThan 
  "Returns a vector of integers less than
  the number passed in."
  [n]
  (loop [x 0
         acc []]
    (when (< x n)
      (let [newNum (+ x 1)]
      (recur newNum 
        (if (not= x (- n 1))
            (conj acc newNum)
               acc))))
     (when (= x n) acc)))

(integersLessThan 10)

madstap13:11:49

Don't know if you figured this out already, but it's because recur is not in a tail position. That means that there's still work left to do after recur has returned.

madstap13:11:55

When you want to calculate a value, as opposed to doing side effects, there should only be one form inside of the loop. In your case there are two when forms.

madstap13:11:33

A quick fix for this version of your code:

(defn integersLessThan
    "Returns a vector of integers less than
  the number passed in."
    [n]
    (loop [x 0
           acc []]
      (cond (< x n)
            (let [newNum (+ x 1)]
              (recur newNum
                     (if (not= x (- n 1))
                       (conj acc newNum)
                       acc)))
            (= x n) acc)))

madstap13:11:33

And a fix for your first version with the printing stuff taken out:

(defn integersLessThan
    "Returns a vector of integers less than
  the number passed in."
    [n]
    (loop [x 0
           acc []]

      (if (> x n)
        acc
        (let [newNum (+ x 1)]
          (recur newNum (conj acc newNum))))))

madstap13:11:20

As you can see, both fixed have exactly one form inside the loop. a cond and an if, respectively

adi16:11:27

@derpocious apart from playing with loop/recur for this particular problem, or rather, as a consequence of it: the basic idea is to iterate up to a certain limit. So we can:

(defn ints-less-than
  [n]
  (take n (iterate inc 0)))
As it turns out, the zero-arity implementation of range is simply
(iterate inc' 0)
; i.e. produce an infinite, lazy stream of ints starting at 0.

madstap17:11:23

Yeah, the whole thing can be condensed down to (defn integers-less-than [n] (range n))

pablore02:11:48

What is the main advantage of using .edn files instead of json?

jumar07:11:00

@pablore check https://vimeo.com/223240720 the EDN is mentioned at the beginning

val_waeselynck10:11:10

@pablore Advantages: - extensibility, without needing the intermediaries to understand the extensions - richer set of default supported types (keywords, dates, ...) - supports comments - arguably, more ergonomic syntax. Drawbacks: - slower (de)serialization libraries - consumers must be able to represent a richer set of data structures (e.g keywords, maps with composite keys)

chang02:11:33

@pablore Reading the spec: https://github.com/edn-format/edn/wiki I think the commenting, keyword lookups and the other features make it much more powerful/pleasant.

seancorfield02:11:57

@pablore EDN is extensible through tagged literals (and data readers)

seancorfield02:11:12

And it supports more data types than JSON.

seancorfield04:11:31

Nice to see a steady stream of new people joining the community! Welcome!

deg15:11:37

I need to define a spec for a map that holds keys owned by multiple parts of my code. So, looking a a tasteful way to build it incrementally from multiple files. (So that each namespace adds in the parts it understands). This strikes me as non-trivial, especially since I can't just have a defonce'd atom that I assoc into. Because s/keys is a macro, I need to assemble only after I've gathered all the parts. Sounds like I need to think about file loading order and other issues that I've ignored until now in my Clojure/Script. Is there a straightforward way to do this? Or am I barking up the wrong trees?

manutter5116:11:43

@deg I do this routinely for setting up my app-db in re-frame. You do need to manage your namespace dependencies by having the namespace with the top-level map require the namespaces for the bits that are farther down the tree

reborg17:11:34

@oliv unsure if it's useful or not, but had some time to write down a commented version of your example from last week. Sorry for the delay ๐Ÿ™‚ The topic was vars, indirection and redefinition. https://gist.github.com/reborg/401dc12e59a514cbd5bcdff9ca2dbfa0

tdantas19:11:51

thank you so much @U054W022G

reborg19:11:59

Hopefully it makes sense. There's a bit of implementation details, which is kind of difficult to leave outside.

derpocious19:11:16

Hey all, I'm trying to install leiningen on windows 7. I ran self install, added everything to my PATH, but still whenenver I run lein anything it returns this:

derpocious19:11:18

"Could not find or load main class clojure.main"

derpocious19:11:41

has anyone encountered this before? I can't seem to find any solution online.

deg19:11:03

@manutter51 Thanks. I'm already doing something similar. I'd like to take it one step further and not have to, e.g., put the :foo foo/foo in the top file. And, this is further complicated by spec. In your example, a solution might be to have top be an atom and then each file could assoc into it. But, for spec, it needs to squeeze into a macro: `(s/keys :req [:foo/foo ...])

manutter5119:11:06

Well, re-frame does store the app-db in an atom, however, that structure I showed you is how I build the immutable initial/default value for the tree. So thatโ€™s all defโ€™ed up front, with sub-trees added in at def time, not assoced in later.

manutter5119:11:21

Once I have that initial structure, I put it in the atom, and it getโ€™s swap!ed and assoced as needed to keep track of the current app state. But all that happens after I build the initial tree with def.

manutter5119:11:06

For spec, unfortunately, Iโ€™m not experienced enough to be able to advise you

deg19:11:57

Righto, thanks. For re-frame, I'm doing exactly the same as you. Spec gets uglier, though. (And, sadly, I even simplified away parts of the full question, which is even uglier).

deg19:11:53

I'll move this question over to the spec channel.

seancorfield19:11:08

@derpocious Have you tried asking in the #leiningen channel? I don't know how active it is but maybe there will be a Leiningen / Windows user there who has some insight. I don't think many Clojure folks use Windows 7 as a percentage overall and, historically, Clojure tooling has lagged behind on Windows, compared to Mac/Linux ๐Ÿ˜

derpocious19:11:18

Thanks @seancorfield, sadly I work at a bank where we're forced to use these archaic machines ๐Ÿ˜ซ

seancorfield19:11:36

I can't remember whether I've gotten Leiningen running on Windows 7. I remember getting it running on Windows 8/8.1, and I run it now on Windows 10 (and in the Ubuntu bash on WSL). But mostly I develop on OS X and we deploy to Linux. I just have a bunch of VMs for testing Windows stuff.

seancorfield19:11:26

I did eventually get Leiningen working on XP (ages ago) so it should work on 7. I just don't remember what I had to do for that.

dpsutton19:11:37

i had it on win7 at my old job

seancorfield19:11:05

Do you have to set an additional env var?

dpsutton19:11:56

yeah i think that was it

dpsutton19:11:17

i never got it working in git bash, sadly only cmd.exe

dpsutton19:11:29

@derpocious can you open up cmd.exe and run lein

dpsutton19:11:06

sorry just saw this: > "Could not find or load main class clojure.main" lein is starting. it seems like there's some type of java issue underneath

derpocious20:11:14

the process just ends immediately

dpsutton20:11:54

what version of lein are you running?

derpocious20:11:15

hmm how can I find out without something like lein -v?

derpocious20:11:06

Also, I am using jdk 1.8.0_144. Should that be ok?

seancorfield20:11:02

(that's 2.8.1)

derpocious20:11:53

I was trying to install it with the windows installer

derpocious20:11:08

When I try to run lein.bat I get this error: "You can try running "lein self-install" or change LEIN_JAR environment variable or edit lein.bat to set appropriate LEIN_JAR path."

seancorfield20:11:47

If you open lein.bat in a text editor, what version does it say in the file? I just want to be sure you're on a fairly recent version of the batch file.

seancorfield20:11:29

And if you're getting the recommendation to run lein self-install then you need to run that command in a cmd.exe window.

rinaldi20:11:30

[["Total impressions" "1,433,794" "1,718,701" "9,358,041"]
 ["Total Actions" "12,743" "12,982" "91,596"]
 ["Total funding" "2,500.00" "2,500.00" "5,000.00"]
 ["โ€” % achieved" "50.00%" "50.00%" "50.00%"]
 [["Display โ€” Impressions" "1,433,794" "1,718,701" "9,358,041"] ["Display โ€” Give Actions" "12,743" "12,982" "91,596"]]
 [["Question 1: How does the campaign make you feel" "92%" "92%" "92%"]
  ["โ€” More positive than before" "5%" "5%" "5%"]
  ["โ€” About the same" "3%" "3%" "3%"]
  ["โ€” Respondents" "65" "65" "130"]]]
What would be the best way to make this a single level vector and "trim" instances like "Display" and "Question" here?

madstap21:11:38

Don't know about the "best" way, but here's one:

(defn vector-of-vectors? [x]
  (every? vector? x))

(defn f [data]
  (reduce (fn [acc x]
            (if (vector-of-vectors? x)
              (into acc x)
              (conj acc x)))
          [], data))

rinaldi21:11:03

Thanks @madstap. Liked the idea of vector-of-vectors?. I came up with something else:

(mapv (fn [item] (if (vector? (first item)) (-> (apply concat item) (vec)) item)) list)

madstap21:11:47

Yeah, that's another way to do it. There are many ways to do it, as they say in perl land.

ghadi21:11:00

easiest thing is to use a map, not vectors

ghadi21:11:17

sequences where the position matters is syntax

ghadi21:11:23

you wanna avoid that game

rinaldi21:11:32

@ghadi I know, I usually go with lazy seqs, but this data structure I'm dealing with it's all about vectors

ghadi21:11:55

still -- easier to use maps pervasively and transform to vectors at the last possible step

ghadi21:11:31

Might be an indication that you're converting to vectors too early

derpocious21:11:28

@seancorfield I am running it in a cmd.exe window. Do I need to do anything after running lein self-install?

seancorfield22:11:54

@derpocious If lein self-install seemed to work, try lein repl and see if that works.

derpocious22:11:05

It does not work. That's what I did before I came to this room with the clojure. main error.

seancorfield22:11:19

@derpocious I was just checking whether the uninstall / reinstall fixed it. It sounds like an environment variable / path issue to me, but without a Windows 7 machine to try a fresh install, I can't offer much help. Sorry.