Fork me on GitHub
#beginners
<
2018-01-26
>
lilactown00:01:34

is there any literature on best practices for project/namespace organization?

lilactown01:01:39

for example, having a rule of thumb for a team that namespaces should only “reach down”, e.g. project.feature should only import things from or external libs

noisesmith01:01:58

yes, that’s reasonable

lilactown01:01:15

obviously this breaks down when you want to extract common functionality of features into a ns

noisesmith01:01:50

@lilactown common functionality can be done that way, in particular by having a protocol at a higher level, and then implementations at a level below (or multimethods, similar concept) and it’s brought together at the top level by pulling in both the abstraction and a specific implementation

noisesmith01:01:39

@lilactown this one is probably closer to what you wanted - an opinionated style guide for using namespaces https://stuartsierra.com/2016/clojure-how-to-ns.html

noisesmith01:01:24

oh, wait - that’s more about the semantics of the ns block itself, not the relationships between namespaces

lilactown01:01:04

interesting, not sure I completely understand how the protocol/multimethod provides the same code reuse as extracting the defn into a common namespace

noisesmith01:01:51

@lilactown the mechanics are that the protocol or multimethod is at the highest level, all the other code deeper down can refer to it

noisesmith01:01:08

then, no matter where the concrete implementation comes from in the tree of namespaces, it will work

noisesmith01:01:59

since nobody is reaching up or across (apart from protocol / multimethod - you do need to special case that one ns)

Michael Stokley01:01:04

anyone familiar with the little schemer? i'm reading the section where they express length without define, just a bunch of inscrutably nested functions that are applied to themselves

Michael Stokley01:01:43

i'd like to understand it more. can anyone provide some context for this exercise or point me towards another discussion of it?

Michael Stokley01:01:47

((lambda (mk-length)
  (mk-length mk-length))
 (lambda (mk-length)
   (lambda (f)
     (cond
       ((null? l) 0)
       (else (add1 ((mk-length mk-length) (cdr l))))))))

Michael Stokley01:01:12

"applicative-order Y combinator"

andy.fingerhut02:01:43

I haven't read the Little Schemer any time recently, but if that book's authors didn't find a clear way to present it, I don't know who could.

andy.fingerhut02:01:26

Not sure if the answers here are anything like what you may be looking for, but maybe: https://stackoverflow.com/questions/93526/what-is-a-y-combinator

andy.fingerhut02:01:38

I never studied lambda calculus, but this answer on that page is likely part of the reason why people who study the theory of computation might be interested in the Y combinator: "Fixed point combinators are used to show that lambda calculus is turing complete. This is a very important result in the theory of computation and provides a theoretical foundation for functional programming. Studying fixed point combinators has also helped me really understand functional programming. I have never found any use for them in actual programming though."

andy.fingerhut02:01:44

In languages like Clojure, Scheme, etc., they provide straightforward ways to write recursive functions, so little need (that I am aware of) to write code like this in practice.

anler09:01:38

Hi all, I want to disable clojure's assertions when building the production uberjar of my app, is there a recommended way of doing this?

delaguardo09:01:33

For leiningen you can modify :global-vars for production profile - https://github.com/technomancy/leiningen/blob/master/sample.project.clj#L285

anler10:01:01

thanks @delaguardo that will do 🙂

Kari Marttila14:01:11

I'm planning to use Compojure for a simple web server for managing certain processing X (a Clojure function, let's say e.g. that X continuously generates events and sends them somewhere as long as it is not told to stop processing). The Compojure web server has three commands: - start: Start X and keep it going until given command stop. - stop: Stop X. - status: Give status of X (whether running/stopped). I already wrote the Compojure skeleton for this, no problem with that. Here is my question: What would be idiomatic clojurian way in the Compojure application to start processing X (with start command) so that the web server itself does not block while X is running (in background).

Kari Marttila14:01:47

I don't need any fancy processing framework or anything like that. Just some idiomatic clojurian way to do this. Any suggestions are wellcome! I guess this is a good chance to learn some concurrent programming in Clojure.

Kari Marttila15:01:59

I think I got it: (async/go (while (= @server-state :running) (log/trace " INSIDE GO ")))

Kari Marttila15:01:31

Seems to be working, I can give stop command which sets atom server-state to :stopped ....

Victor Ferreira14:01:31

Hey guys how can I use atom as seq? Like this (def k (atom [1 2 3])) (seq k) output -> [1 2 3] when I do it return me one erro like this Don't know how to create ISeq from: clojure.lang.Atom

bronsa14:01:12

you can’t

bronsa14:01:24

you have to deref it to get to [1 2 3]

bronsa14:01:01

(def k (atom [1 2 3]))
@k ;=> [1 2 3] ;; @k == (deref k)
(seq @k) ;=> (1 2 3)

Victor Ferreira14:01:32

what is this operator @?

bronsa14:01:30

@ is deref

bronsa14:01:57

user=> (def a (atom 1))
#'user/a
user=> a
#object[clojure.lang.Atom 0x2e1ef60 {:status :ready, :val 1}]
user=> @a
1
user=> (deref a)
1

sova-soars-the-sora17:01:35

Hi, does anybody use Docker to seal up their Clojure apps? i am interested in cross-platform distribution and it would make life very easy to have some sort of "make-a-me-a-binary-please-a" command.

noisesmith18:01:41

depending on how it’s meant to be run an uberjar can get close to that - (each OS should know what to do with it if java is installed)

noisesmith18:01:15

but I guess docker is useful if you don’t want to depend on java, or need to daemonize, or need outside-jvm things as well

delaguardo18:01:19

@sova there is leiningen plugin for that - lein-bin.

noisesmith18:01:24

fun fact - on a properly configured linux system, it suffices to set the executable bit on an uberjar

noisesmith18:01:44

(binfmt-misc is the debian package that does this - might have other names in other distros)

prnc18:01:29

Hello good people 🎉 complete to clojure newbie here. In your editor of choice is there a way to evaluate forms inside let with the bindings declared before in let, if that makes sense? If so is it something cleverly provided by your editor/plugin (I am using vim+fireplace, don't hate ☮️ ❤️ :))

prnc18:01:51

This is quite useful for learning--understanding what a more complicated function is doing by breaking it into pieces. So far I was just doing that "manually" taking out certain parts I wanted available in the ns and defining them

noisesmith18:01:56

the idiom is (let [_ (some-side-effect) ...] ...) - oops, misread

prnc18:01:34

no worries

noisesmith18:01:49

I’m fond of this idiom: (def debug (atom [])) then inside the function (let [x (f y) _ (swap! debug conj {:y y :x x})] ...) - that lets me run the function in normal usage and also play with the values it sees in a repl

noisesmith18:01:11

and also it lets me catch values in the middle of the let block in case they get shadowed etc.

prnc18:01:38

maybe example would be useful

(defsynth deci-wobble []
  (let [temp-freq (/ 140 60 3)
        tr      (impulse temp-freq)
        note      (demand tr 0 (dseq [40 43 47 47 40 37 43 28] INF))])
  ...)
if I want to evaluate (demand ... just to see what it returns 🙂 I can't do it cause it references tr, a binding above

noisesmith18:01:11

you can capture tr

noisesmith18:01:33

oh wait - that’s defsynth, so all this is moot

noisesmith18:01:56

defsynth is magic, the code inside is not real clojure, it’s a DSL that looks like clojure that is translated to UDP commands sent to a C++ process

prnc18:01:58

mmm, yeah I figured that it wouldn't really work here

noisesmith18:01:10

right, nothing works like you expect in defsynth, period

prnc18:01:18

so the example might not be the best one (bit misleading maybe)

prnc18:01:29

but in general case the question stands

prnc18:01:50

@noisesmith your idiom looks promising need to play with that a bit to see if it's all I need 😉 thanks!

noisesmith18:01:23

I’m sharing what I do, there’s editors that allow some instrumentation but it requires changing how clojure compiles things so it’s never seamless - I find the most beneficial thing to be writing code such that this sort of debugging doesn’t require stepping (there’s design benefits)

prnc18:01:30

barring the defsynth definition ofc

noisesmith18:01:11

also I wrote a library for dumping data to disk (for unit tests or just debugging) - it eliminates soem of the gotchas that come up when naiively writing / reading edn https://github.com/noisesmith/poirot

prnc18:01:39

good name, will check it out!

noisesmith18:01:54

if you wanted to go a step further and capture data from an arbitrary process even if you can’t be at the repl (or if you want the data to be reusable without recreating all the preconditions)

noisesmith18:01:48

@prnc also, for real step debugging I have the impression that cursive is the editor / tool that gets closest to that experience for clojure

prnc18:01:23

cool, cheers @noisesmith I will play with the debug atom you suggested and see how far it can take me 🙂

javazquez19:01:54

Is there a good lib for testing my dom creation code from cljs? I was thinking something that could take html string and convert it into js objects to compare my code against? open to alternatives also

dpsutton19:01:06

i think you can turn html into hiccup. maybe you could rig something up with that?

joshkh20:01:22

i'm looking to create a clojure(script) desktop app that's both osx and windows friendly and powered by re-frame / reagent. should i be exploring re-natal or cljs-electron?

ackerleytng05:01:38

@U0GC1C09L the same question here, but i'd like to target just linux. does anyone have suggestions on how to get started?

ackerleytng05:01:48

isn't re-natal for mobile?

ackerleytng06:01:03

i'm looking into descjop

gklijs08:01:29

Depending on the use case, a runnable jar might be an option, with something like quil for the interface?

ackerleytng12:01:49

wow... quil won't be providing components at all

joshkh20:01:24

(mobile apps are out of scope)