Fork me on GitHub
#beginners
<
2016-02-03
>
gabehollombe01:02:58

@jonahbenton: it does work. the letfn macro lets you reference any of its bindings from any of the functions you define within it

jonahbenton01:02:30

@gabehollombe: excellent! there it is, right in the docs, intended for exactly that use case. very cool!

gabehollombe01:02:55

Yeah! I learned it yesterday 😃

udit06:02:30

Hiya! I am running into a problem while reading configurations via an edn file. I have created an atomic map in which all the configurations are inserted at the start of the application. This works fine if I load the configurations manually via repl. However when I run the entire application then the configuration is loaded later on, and the vars dependent on these configuration are initialized first. I seem to be missing out on something very basic.

seancorfield07:02:54

Sounds like laziness is biting you?

plexus07:02:17

@udit could you show some code of how you're reading this configuration, and you're setting up these vars that depend on it?

plexus07:02:11

I'm wondering if it's a difference between read/compile and run time

plexus07:02:09

and how are you using get-config?

plexus07:02:25

oh it's right up there in the run-server, right?

plexus07:02:36

is that where you get an error?

udit07:02:32

If I do lein run then I get the runtime exception that :bot-name key was not found; the one which I am throwing in the get-config function.

udit07:02:47

The dump of the config map along with the exception gives an empty map. So obviously the global-appconfig map hasnt been initialized. Shouldn’t it be initialized first since it is the first function to be called in main?

plexus07:02:08

where are you calling bot-name from?

udit07:02:13

Oh you mean the function? It’s being called in the bot.clj later on in other functions.

plexus07:02:30

and those functions are used inside your server code?

plexus07:02:21

I don't immediately see anything that's wrong. what's possible is that you're indirectly calling one of these functions at the top level, e.g. to define a var

plexus07:02:44

(def my-app-name (str (bot-name) "app"))

plexus07:02:21

in that case that will get executed immediately when Clojure "reads" that form, so even before it starts executing -main

udit07:02:55

Oh! Yes I am using it in another def.

udit07:02:21

So all the defs are evaluated even before the -main function?

plexus07:02:36

anything that's not inside a function is executed immediately

plexus07:02:05

in a way all Clojure code is executed immediately, but most of it will just set up functions to be called later

plexus07:02:30

when everything has been defined then -main starts executing, calling those functions

udit07:02:17

I understand it now. Thanks @plexus simple_smile

udit07:02:48

So the way forward for me would be: 1) Initialize the config at the time of definition of the global-appconfig or 2) Change the defs dependent upon this config map to be functions. Which one is the preferred approach?

plexus07:02:31

I would go with making them all functions

plexus07:02:11

you could even explicitly pass that config (or parts of it) into any function that needs it. Now you're setting it up as globally accessible state, which makes it easy to run into problems like these, because one part of your program is setting up that state, and another part reads it, and there's no connection between the two, so you the programmer are responsible for figuring out the timing to make that work

plexus07:02:03

if you read the config and then start passing it into the functions that rely on it, then the connection is explicit and clojure will make sure the reading happens before the code that depends on it

plexus07:02:54

of course that might mean a lot more work to pass that config around, so it might be a valid trade-off to do it the way you're doing it, it's just interesting to contrast those two approaches

samlinncon13:02:59

need help in luminusweb

jonahbenton14:02:48

hey @samlinncon do you have a specific issue or problem? there also is a #C077KDE3A channel

chrisetheridge16:02:08

i’ve got a vector of strings, and a vector of maps. the strings are an order that the maps need to be ordered in. how would i sort the vector of maps, by key, based on the order of the vector?

chrisetheridge16:02:23

don’t want the answer spoon fed, just looking for a nudge in the right direction simple_smile

akiva16:02:09

Look into sort-by.

chadhs19:02:47

is there a general consensus on if using clojure in place of shell scripts is good practice? experimenting has been fun but making system calls with clojure.java.shell/sh seems a little “hacky"

jeff.engebretsen20:02:09

I haven't heard anything but I've considered using it.

seriousbug20:02:05

I think the biggest problem is startup time

mfikes20:02:41

@chadhs: yeah, the sh aspect can be a little hacky, especially if dealing with piping and other things you'd get from, say, Bash. But if you have any logic or data processing, I'd much rather be in Clojure (or ClojureScript).

chadhs20:02:34

yeah that’s what i’m running into right now, im doing all this stuff with sed and found myself saying “man i wish i was in clojure right now” but then i found myself not being able to do the easy stuff i do in bash (due to ignorance / inexperience im sure) like just doing something to every file in a dir.

chadhs20:02:06

thanks guys, those look like interesting tools

mfikes21:02:44

(with-sh-dir “/path/to/somewhere"
  (doseq [file (rest (file-seq “/maybe/some/other/dir"))]
    (sh “somecmd” “anarg" (:path file)))

mfikes21:02:00

@chadhs: ^ file-seq and friends

chadhs21:02:38

@mfikes: yes i’ve recently discovered file-seq as well, thanks for that snippet. the example here is returning an “object” rather than file names for me https://clojuredocs.org/clojure.core/file-seq

chadhs21:02:37

… it may have been my incorrect assumption that ~ would expand to /Users/home/chadhs

mfikes21:02:33

Yeah. ~ is one of those things Bash does

chadhs21:02:31

(def d (io/file "/Users/chadhs/tmp/blocks/a"))
(def f (file-seq d))
(rest f)

chadhs21:02:50

that works for me and returns my two test files and not the dir itself

mfikes21:02:32

Yeah, I think the first of a file-seq is always the dir

chadhs21:02:37

looks like to define a working dir you need to use io/file as well

chadhs22:02:27

@mfikes: got this to work and just in time before having to run to pick up the kiddos 😛 thnx again

(def working-dir (io/file "/Users/chadhs/tmp/blocks/a"))
(def the-files (vec (map str (rest (file-seq working-dir)))))
(map #(shell/sh "ls" %) the-files)

Alex Miller (Clojure team)22:02:25

I'm not sure it's too actively maintained anymore, but https://github.com/Raynes/conch has a lot of useful utils for stuff like this

chadhs22:02:25

Sweet Alex thx; bookmarked