Fork me on GitHub
#beginners
<
2020-11-25
>
voortuck06:11:53

does anyone have an example of using etaoin? https://github.com/igrishaev/etaoin I've tried lein new app etaoinexample and then adding the dependency.

:dependencies [[org.clojure/clojure "1.10.1"]
                 [etaoin "0.4.1"]]
but I get this error:
Unable to resolve symbol: firefox in this context
where I try to call this in core.clj: (def driver (firefox))

andy.fingerhut06:11:21

In the instructions that contain that expression, several lines above is this one: (use 'etaoin.api). Did you perhaps skip that?

andy.fingerhut06:11:00

It might be preferable to create a namespace where you write your code, e.g. (ns my.project.namespace (:require [etaoin.api :as api])) and then you can use api/firefox instead of just firefox

voortuck07:11:35

this helps me, thanks. It's one of the hardest parts of clojure to me: trying to figure out the ceremony of :require I'm not sure where I'm missing the explanation in the docs

voortuck07:11:43

I appreciate your help.

Aviv Kotek10:11:40

with lein, there is :dev and :test profiles, it's https://github.com/technomancy/leiningen/blob/master/doc/PROFILES.md#task-specific-profiles not to use :test profile, should the :dev profile be used for test purposes? i.e include test-lib dep, etc? then "lein with-profiles dev test"? I find it more intuitive just to run "lein test"(which merges :test profile if declared), what are the differences between :dev and :test profiles? which should I pick?

noisesmith16:11:39

lein test should already merge in the dev profile IIRC, and with-profile foo is almost always an error (it replaces the profile for the task), you usually want with-profile +foo (it merges new data to the profile for the task)

🙏 1
noisesmith16:11:43

Each profile should be dedicated to some task, and you might want a supplimental profile to enable integration as opposed to just unit tests for example. You shouldn't need to manipulate profiles for normal tasks.

Aviv Kotek08:11:23

there is one disadvantage of "test" not able to run in REPL (running tests), so in conclusion- it's common to use the :test profile for tests?

noisesmith16:11:39

the :test profile is always used for the :test task, if you want to run tests in your repl, you might want to add with-profile +test to your repl startup

neilyio15:11:13

What are my options when using NPM packages with Figwheel? I don’t have shadow-cljs as an option anymore, and figwheel’s NPM guide constantly leads to compilation errors for me.

neilyio15:11:19

I only need to use a single NPM package, is there a manual / hacky workaround with externs and the Closure Compiler?

neilyio15:11:23

The package is react-spring, I can’t find it on CLJSJS.

st3fan19:11:10

@seancorfield i look forward to your REPL presentation next month

seancorfield19:11:40

Thanks @st3fan -- if there's anything specific you'd like to see/hear about, LMK via DM and I'll see whether I can incorporate it. I want it to be an interactive talk/demo so folks can get as much out of it as possible!

👍 4
st3fan19:11:53

Just show us the magic 🙂

👍 3
zach21:11:02

Hi! I’m not sure if this is an appropriate question for the channel, but was wondering if y’all had advice on “code smells”, or moving toward more idiomatic clojure. I have a couple functions that map a map of a map, and the repetition is making me feel like i’m doing something incorrect…but am not quite sure how to best phrase the incorrectness beyond “doesn’t feel clojurey”.

zach21:11:31

For example, a fn “text->env-map” which takes text like CLOJURE=cool\nREPL=awesome\n and converts it to ({"CLOJURE" "cool"}{"REPL" "awesome"})

zach21:11:12

I have it written, and working, as so:

(defn text->env-map
  [text]
  (map #(conj {} %)
        (map #(clojure.string/split % #"=")
             (clojure.string/split-lines text))))

Lennart Buit21:11:47

You can use a transducer here, or threading

noisesmith21:11:52

for all f,g (map f (map g x)) can be replaced with (map (comp f g) x)

zach21:11:55

But i am still pretty new to clojure, and am not sure if i’m taking too blunt of an approach.

zach21:11:02

it’s just feeling increasingly unreadable.

noisesmith21:11:59

so in your case (comp #(conj {} %) #(string/split % #"=")) or just #(conj {} (string/split % #"="))

zach21:11:39

Ah! I had not used comp before, that’s really nice!

paul.legato21:11:11

Check out the threading macros for making deeply nested chains of calls like that more readable, too: https://clojure.org/guides/threading_macros

noisesmith21:11:02

(->> x (map f) (map g)) is worse than comp IMHO

noisesmith21:11:10

(though I see it more often)

zach21:11:24

Good point. I’ve used threading macros, but maps trip me up because of the order of the variable being put in.

zach21:11:07

(e.g. i have a set of functions where (-> ) works great, as the second position is perfect, but then i want to pass that to a map, and it now needs to be the last position)

paul.legato21:11:08

Agree in this specific case, comp is a better way to go

phronmophobic21:11:35

I still prefer the threaded version. for me, it's easier to read and extend

zach21:11:47

Thank you!

paul.legato21:11:54

There is also ->> to put the thread in the last position

paul.legato21:11:05

and some-> to short circuit in case a nil happens

👍 1
paul.legato21:11:48

I like comp more for named functions: (comp foo bar) reads nice and clean. With literal functions, I may go with -> and multiple maps for readability. Puts each unit of work on different lines.

paul.legato21:11:38

I suppose you can do that with comp, too

noisesmith21:11:48

or just do that inside the function literal

paul.legato21:11:52

yeah, or that

noisesmith21:11:28

#(-&gt; % (string/split #"=") (-&gt;&gt; (conj {})))

noisesmith21:11:58

OK never mind - the nesting works but it's dumb

😄 1
zach21:11:44

comp plus named functions seems to perhaps lend itself more nicely to spec and testing too? Or at least it’s encouraging a number of small, easy to reason about functions.

paul.legato21:11:22

It really depends on what exactly you’re doing.. judgement call which is better in a particular case

paul.legato21:11:59

Over-testing is as bad as under-testing IMO

paul.legato21:11:26

The natural question is then what’s the right balance? Well.. hard to answer in a general way.

paul.legato21:11:56

Adding ever more tests is diminishing returns, after some point. Each unit of resources to add a new test prevents fewer bugs. Bugs are, by definition, problems nobody thought of. Problems for which there was no test case. There are plenty of code bases with a million micro-unit tests for every (+ 2 2) level function, which still have large bugs anyway. It depends a lot on how much damage happens if there’s a failure. If you are launching a Space Shuttle or doing life-critical code like building a pacemaker, you should probably go overboard on testing every possible code path. Most commercial software has much less harsh failure modes, though.

zach21:11:25

hahaha, yah my scenario is a bit less mission critical.