This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2018-09-18
Channels
- # 100-days-of-code (10)
- # announcements (2)
- # aws (3)
- # beginners (120)
- # boot (6)
- # calva (6)
- # cider (22)
- # cljsrn (3)
- # clojure (145)
- # clojure-greece (1)
- # clojure-italy (7)
- # clojure-nl (24)
- # clojure-russia (90)
- # clojure-spec (21)
- # clojure-uk (80)
- # clojurescript (175)
- # core-async (1)
- # datomic (17)
- # emacs (8)
- # ethereum (5)
- # figwheel (1)
- # figwheel-main (140)
- # fulcro (137)
- # jobs (6)
- # jobs-discuss (3)
- # luminus (3)
- # mount (1)
- # nyc (3)
- # off-topic (39)
- # onyx (1)
- # pedestal (1)
- # re-frame (21)
- # reagent (13)
- # shadow-cljs (60)
- # spacemacs (25)
- # test-check (4)
- # tools-deps (14)
- # uncomplicate (3)
- # vim (18)
I want to start a new clojure project to mainly for learning purposes, but even deciding how to do that is a bit overwhelming. Should I use leiningen, boot, or deps.edn? Is there a wrong answer?
If you are learning on a beginning project, I suspect picking any of those 3 will work out reasonably well for you. If and when you hit some point of the project where one of those is clearly better for your purposes than another, you will probably be better positioned at that time to see why switching might be to your advantage.
All of them can get you to the point of starting a REPL and setting up your environment (e.g. Java class path) to be able to load your code and that of libraries you may want to use.
I haven't used boot yet, but I believe the places where it vs. Leiningen will become most evident is when you have specific needs for building an application from multiple kinds of source files, e.g. not only Clojure/ClojureScript, but also Java, JavaScript, CSS, etc. If you expect to have needs like that on your beginning project, then you might want to get more people's advice than mine on your choice.
Thank you for the information. I'm going to try lein for now. I've used it before and I don't think I'll need a complicated build process.
@scott.archer tldr is that lein will get you more functionality out of the box and lets you leverage way more templates built for lein, etc. boot is considerably easier to extend and customize since your boot tasks are just straight clojure code, but you generally gotta know more about internals and there aren't plugins (or, in boot's case, pre-made tasks) for as much. Which I like because it simplifies the dev deps, but it does mean more initial work putting a project together
how can I get a full qualified function name and call it. For example, something similar to the importlib
from python?
@iagwanderson You'll need to require
the namespace it is in and then resolve
the fully-qualified name to a var, then you can call it.
For example
user=> (def f "clojure.set/union")
#'user/f
user=> (namespace (symbol f))
"clojure.set"
user=> (require (symbol (namespace (symbol f))))
nil
user=> (resolve (symbol f))
#'clojure.set/union
user=> (*1 #{1 2} #{2 3})
#{1 3 2}
user=>
Are there any benefits of having one leiningen project for the UI and one for the API which the UI communicates with?
It feels unnecessary to me, I do have it split today though.
If I were to target several plattforms it would be nice though.
Just want to give out a shoutout to https://www.codingame.com/home since they support Clojure for their puzzles, coding battles, etc. Great learning resource, even for advanced coders. 🙂
hackerrank supports Clojure as well. For almost all of their problems. Not only from the FP domain
If i want to call from clojure side (clj) a JavaScript code directly or trigger clojurescript code (trigger eg. add-watch at clj side > cljs trigger) then possible without websocket and rest api?
I can write fully eg atoms at clj side, call functions. I would like to solve the clj>cljs way like a websocket. I saw intern function not implemented at cljs side, any idea how to connect? So change clj atom then send to cljs part? Now, i set intervals, but not so good idea.
@sb I don’t fully understand what you want, but if you want websockets, sente is a nice library to work with
@borkdude i used sente, rest api. I solved from cljs side with macros like core.async the Vars (atoms) at clj side. I can read, write. Run clj commands from cljs part. One thing missing, if eg at clj side a websocket channel eg Slack.. when change the data I cant send to cljs just with sente.
Maybe that is impossible, just i prefer use data communication without extra layer eg rest api or socket
is it common sense to write pre/postconditions in your function definitions? They throw exception on false, right?
@denisgrebennicov many functions throw exceptions anyway, e.g. if you call subs with out of bounds index. in that case a pre might give you some more information of what might have gone wrong anyway
do you write these pre/postconditions with spec or what?
> If any of the conditions evaluate to false and assert is true, an assertion failure exception is thrown. https://clojure.org/reference/special_forms#toc10
this is more or less the question, since AFAIK spec is kinda replacing pre-/postconditioning, right?
but is it idiomatic. AFAIUnderstood spec is pushed and is the "new" way to go instead of precondition tests Dunno if you can use spec for postconditioning though
spec doesn’t verify the :ret value unless you use clojure.spec.test. some libraries offer a workaround and do turn it on. but you can also hook it up yourself using :post
I usually write an fdef, but that’s because pre and post are not in my system, maybe I should use them more
this is a nice feature, IMO, but question is if this is just-nice-to-have-nobody-does-it, or nice-to-have-you-should-use-it
I’ve never heard someone refuse a PR because he/she didn’t write enough pre/post/specs.
there are multiple ways to do it. I could have used pre now I think of a case I handled lately in a macro where I asserted that the input should meet some form, but I just used assert
.
(require '[clojure.walk :refer [macroexpand-all]])
(macroexpand-all
'(defn foo [x]
{:pre [(pos? x)]}
x))
=>
(def
foo
(fn*
([x]
(if
(pos? x)
nil
(do
(throw
(new
java.lang.AssertionError
(clojure.core/str "Assert failed: " (clojure.core/pr-str '(pos? x)))))))
x)))
there’s a difference between (:test "example")
, '(:test "example")
and (list :test "example")
(:test "example")
as a literal in code means 'invoke :test as a function with the argument "example"'
that’s the difference between an unquoted or quoted list. the reader interprets an unquoted list as a function call
internally the object is stored as a list - it's just when you define it in the code that the quote means it is a literal object- not an s-expression
https://www.braveclojure.com/read-and-eval/ This chapter may be useful for understanding the reader! It goes fairly in depth on how expressions are evaluated
I would find a tutorial somewhere for writing a lisp. it will go really fast in clojure, and once you've done it, it makes this kind of thing very apparent and easy to understand
Hey everyone, the main man himself Rich Hickey makes a lot of jokes about monads in his presentations. I am struggling to understand what they are, could anyone explain or link me to a resource where I could learn?
a monad is 1. a thing in math 2. a pattern that emerges in a lot of functional programs that has some similarities to #1 so the same name is used for both
The source of the monad jokes is that they are famously unintuitive and amateur attempts to explain them tend to make people even more confused. They aren't a concept you need for clojure. That said, category theory involves some nice patterns for thinking about computation if you want to learn some math that would inform application design.
Google for "burrito". You'll find 100 tutorials on monads 🙂
and 10,000 bad jokes about tutorials about monads
(aside from the joke and the various attributions of it, it actually explains the math)
One of my favorite jokes (no idea who said it) on monads is paraphrased "When you learn enough to understand monads, you lose the ability to explain them to people who do not yet understand them."
Crockford maybe ? https://www.youtube.com/watch?v=dkZFtimgAcM&t=50
I think gigasquid did quite a good job in one of her talks (at either a Clojure conference or Strange Loop)... let me see if I can find that...
Gottfried Leibniz or GTFO
@deanjohnson03 I hope some of that helps! 🙂
Is this the gigasquid talk you were thinking of? https://www.infoq.com/presentations/Why-is-a-Monad-Like-a-Writing-Desk
The goal of an uberjar is to create a single deployment artifact. You can open the uberjar in your editor or with a file manager - it's a special zip file.
the js will also be created outside the uberjar before packaging it
@noisesmith you still need an external sh script for jvm options etcc no?
right - that's outside the scope of uberjar
there is a trick for turning the jar into a #!/bin/sh
script that runs java but usually you don't need that
I usually don't think of the runner script as part of the deploy, but rather part of the infrastructure deployed to - but I guess not everybody does it that way.
I would think too, makes more sense, since you also need to setup the app as a service, etc.. I guess that is why some convert the app to a distro pkg
After opening the uberjar I notice that my site.js
file isn't under the public folder anymore.
After removing :clean-targets ^{:protect false} ["resources/public/js/site.js" :target-path]
I think uberjar implicitly cleans
one way to do this is to make the optimized cljsbuild a prep-task for uberjar
because usually you want a different kind of cljs output for prod vs. dev
like this but inside the :uberjar
profile https://github.com/technomancy/leiningen/blob/master/sample.project.clj#L262
:uberjar {:prep-tasks [["cljsbuild" "once" "opt"]]}
or something like that
Thank you @noisesmith
@seancorfield @hiredman @noisesmith @andy.fingerhut thank you all for your responses, I will check out all the links and info you gave me 🙂
@mario.cordova.862 you might need to manually add "clean" or any other prep tasks since that gets overwritten rather than merged (because order is important)
not sure what you mean there, but literally thousands of companies do this every day, even from public repos.
@noisesmith Would adding :disable-implicit-clean true
to my project.clj achieve the same effect?
the difference would be no longer needing to run the cljsbuild yourself (or the clean)