This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2020-01-24
Channels
- # aleph (1)
- # announcements (22)
- # atom-editor (11)
- # babashka (46)
- # beginners (60)
- # calva (44)
- # cider (18)
- # circleci (1)
- # cljdoc (12)
- # cljs-dev (5)
- # cljsrn (19)
- # clojars (3)
- # clojure (162)
- # clojure-dev (9)
- # clojure-europe (6)
- # clojure-italy (2)
- # clojure-losangeles (2)
- # clojure-nl (5)
- # clojure-spec (7)
- # clojure-uk (23)
- # clojureremote (1)
- # clojurescript (55)
- # community-development (14)
- # core-async (234)
- # cursive (14)
- # data-science (3)
- # datomic (32)
- # fulcro (5)
- # graalvm (20)
- # graphql (2)
- # hugsql (4)
- # jobs (11)
- # jobs-discuss (2)
- # joker (1)
- # juxt (3)
- # kaocha (1)
- # luminus (1)
- # off-topic (33)
- # pathom (3)
- # pedestal (1)
- # reagent (24)
- # remote-jobs (3)
- # shadow-cljs (38)
- # spacemacs (4)
- # specter (4)
- # speculative (54)
- # tools-deps (62)
- # vim (8)
- # vscode (14)
I want to iterate through a value-delimited binary file like it's a seq, is a modified version of line-seq
still the best way to go about it?
(defn line-seq
"Returns the lines of text from rdr as a lazy sequence of strings.
rdr must implement .BufferedReader."
{:added "1.0"
:static true}
[^.BufferedReader rdr]
(when-let [line (.readLine rdr)]
(cons line (lazy-seq (line-seq rdr)))))
It certainly sounds like a reasonable way to start, at least. There are certainly tradeoffs that could be made between performance and simplicity of code, but if you are not worried about performance to the Nth degree, I'd start with something simple and measure it to see if it is fast enough for your needs.
hi all, given the following kind of pattern:
(-> (sorted-map)
(parse-first-line first)
(parse-second-line second)
(parse-trace trace)
(parse-locks locks))
I would like to find a way to only call say parse-first-line
if first
is non-nil and I would like to apply that across all the steps in the threading expression. some->
comes to mind but as far as I can tell does not quite fit this case. Also I could naturally add nil checks to all the parse methods but would like to avoid that duplication. Also considered writing a function which takes the parse function and args as params and I think that wuold work but might affect readability of the above block negatively. What would be an idiomatic way to solve this in clojure?cond->
is good for this general shape, but won't DRY out the repeated nil checks, so could do something over that
@alexmiller that feels promising, thank you. Will mull this over.
it's kind of a combination of some-> and cond->
I think it turns out like this, not bad:
(cond-> (sorted-map)
first (parse-first-line first)
second (parse-second-line second)
trace (parse-trace trace)
locks (parse-locks locks))
and yet again clojure comes up with something beautiful...I think I'm still in love after x years
thanks again @alexmiller
hey guys, I believe I'm running into an issue with jdbc inserts where my hyphenated keynames are causing a syntax error - is there a standard way of dealing with this?
(jdbc/insert-multi! spec :test [ {:test-underscore "string"} ])
=> ERROR: syntax error at or near "-"
(jdbc/insert-multi! spec :test [ {:test_underscore "string"} ])
=> ({:id 4, :data nil, :test_underscore "string"})
https://github.com/seancorfield/next-jdbc/blob/master/doc/friendly-sql-functions.md#table--column-entity-names might help if you're using next.jdbc
I seem to be reaching for the top-down threading macro (`->` ) very frequently -- are
there any heuristics y'all use to mediate the use of these kinds of constructs?
For example, this barely structured exploration of enlive
is just littered with
->
; for the most part, when composing a bunch of functions, it feels like the
right thing to do https://github.com/qzdl/clj-samplify/blob/master/src/clj_samplify/scraper.clj
Looks fine. One sign that you'd want to break out from a threading macro is when you start having to jump hoops to be able to continue in the same thread.
Thanks for taking the time! I suspect I'm just second guessing myself due to lack of knowledge ๐
> ...jump hoops to be able to continue in the same thread.
I'm not sure I fully understand the above; maybe through positional arguments where ->
or ->>
are just a pain, or where some branching logic will make the organisation a mess?
For anyone with the similar questions, this is a good read https://clojure.org/guides/threading_macros
I sometimes have trouble with English idioms. I'll try again. You know how well functions like map, filter and reduce line up inside a ->> macro? Then you need to use that one function where it's not the last argument you want to pass to the function. Like one assoc in there somewhere. Before you know it the beautiful thread is full of anonymous functions and as-> so that you can shoehorn one more function in. That's when you might want to break from one long threading macro to multiple parts.
Stuart Sierra wrote an article on the topic a couple of years ago: https://stuartsierra.com/2018/07/06/threading-with-style
I feel like I'm still really naive about error handling in programming. Any good resources you would recommend? I don't seem to stumble upon it when reading clojure stuff. Like just something simple like if a user inputs a string when you need an integer. Try/catch is the thing right? So if an exception is triggered, it "catches" it and you tell your function what to do in that case?
Since such errors would be occurring with side effect-y things like user input and such, is the clojure way to push these things to the boundaries and out of pure functions? Is that maybe why I don't see it too much in the code I read?
I think you have the right idea in putting those things at a boundary. I found this article and discussion from HN to be an interesting read related to what you're thinking about. https://news.ycombinator.com/item?id=21476261 Sample from the comments. > Another good example of this is having separate classes for something like unsafe strings vs. safe strings in a web app. The functions which interact with the outside world accept unsafe strings and emit safe strings to the rest of the application. Then the rest of the application only works with safe strings. > Anything that accepts a safe string can make an assumption that it doesn't need to do any validation (or "parsing" in the context of the OP), which lets you centralize validation logic. And since you can't turn an unsafe string into a safe string without sending it through the validator, it prevents unsafe strings from leaking into the rest of the app by accident. > This concept can be used for pretty much anything where you are doing data validation or transformation. Also the "functional core, imperative shell" talk by Gary Bernhardt. https://www.destroyallsoftware.com/talks/boundaries
I also tried to read through that Parse, Don't Validate article when it was first published and her followup but it was a bit above my head right now. And I keep getting distracted by the dynamic vs static debate stuff
The last time I was trying to do my own hacky error handling I think it was like (if (string? x) do-what-I-want recurse-back-and-ask-for-the-string)
I think I've seen something where there's a shortcut for using qualified keywords in a map.
^:foo {:bar "baz" :buz "fizz"}
would be equivalent to
{:foo/bar "baz :foo/buz "fizz"}
Is there something like that? I can't find it now.#:person{:first "Han"
:last "Solo"
:ship #:ship{:name "Millennium Falcon"
:model "YT-1300f light freighter"}}
is read as
{:person/first "Han"
:person/last "Solo"
:person/ship {:ship/name "Millennium Falcon"
:ship/model "YT-1300f light freighter"}}
from https://clojure.org/reference/reader (see "map namespace syntax")Hi guys, I have the following code in my application:
(ns tinytimer.db
(:require [next.jdbc :as jdbc]
[environ.core :refer [env]]))
(def datasource
(jdbc/get-datasource (env :database-url)))
Iโm using def
to create the datasource, since I suppose I should only create it once instead of using defn
and create the datasource each timeโฆ
However with the above code, when compiling he tries to connect to the database.I found on stackoverflow, that I can do something like (when-not *compile-files*)
to not evaluate the def
during compile time..is that what you would usually do ?
don't do that
some options:
a) don't def this at all - put it in whatever starts your app and pass it to those who need it, either directly or via other component injection means
b) use a delay
and deref when using
I generally try to avoid using def
at all for anything stateful
These are what you mean by other component injection means
?
https://puredanger.github.io/tech.puredanger.com/2014/01/03/clojure-dependency-injection/
https://github.com/stuartsierra/component
^ that's definitely one of the things alex is referring to. IMO when you're just starting out I would just do something like this for stuff like that
(defn the-app []
(let [datasource (jdbc/get-datasource (env :database-url))]
...))
yeah, component or integrant etc
when you find yourself doing that with like 10 different services and they have order dependent initialisations. then I would look into component etc
A component like library adds a reverse order stop lifecycle management and sometimes the ability to swap out some parts from the outside
as in, they take care of ordered initialisation because they have to be declared in the correct order?
Even if you declare them in the wrong order, their body is delayed until something requests it.
So if you want to use X, when you deref X, X will deref the resources it needs and they the one they do, etc.
As a bonus, the compiler will force you to define them in the right order, since otherwise it won't find the symbol.
As @U051SS2EU showed in the other thread, you could use declare if you wanted to define them out of order. I think that would be unidiomatic, but it would still work, since they get initialized as they are realized, not as they are defined.
yeah, delays until you run the risk of cyclical delays and then switch to stuartsierra/component or integrant which do proper topo sorting
(ins)user=> (declare a b)
#'user/b
(ins)user=> (def a (delay (cons @b ())))
#'user/a
(ins)user=> (def b (delay @a))
#'user/b
(ins)user=> @a
Execution error (StackOverflowError) at user/fn (REPL:1).
null
๐ it's nice that clojure's declare order and no-circular-ns-dependencies requirements at least make this hard
indeed!
I've been happily using delay for 3 years on multiple systems without a single issue related to them
I think they're undervalued and are quite a simple solution that gets overlooked often in preference of more complicated solutions
For example, in Spring, you get a BeanCurrentlyInCreationException at runtime as it tries and initialize things and detects the circular dependency. While here with delay, if you don't use declare, you get nice compile time error from the Clojure compiler telling you it can't resolve the symbol. And , if you go ahead and add a declare to solve the compiler error, you then get a runtime error StackOverFlow. The only difference here is the error says StackOverFlow intead of BeanCurrentlyInCreationException.