Fork me on GitHub
#clojure
<
2019-07-31
>
Alex02:07:58

Hey guys I had a question regarding core.async/chan. If I want to create a channel that accumulates a result before it let's a take take the accumulated value, for example accumulate till number is >= 10, using a stateful transducer. Is that possible? Thanks in advance.

Alex20:07:53

Ah that's it! Thank you very much, core.async is quite cool.

Alex Miller (Clojure team)06:07:24

different options about what to do when the threshold is reached - whether to stop, whether to emit and restart, whether to emit, but restart with the amount >= x, etc. those are all possible, depends what you want.

dpsutton14:07:04

jumping into fixed-width files at work. anyone know of a clojure lib before spelunking into java?

thomascothran14:07:16

I've run into an issue where refresh from tools.namespace (v. 0.3.0) seems to work with Java 8 but not Java 11. I tried with both Clojure 1.10.0 and 1.10.1. I was able to reproduce the problem on a clean virtual machine. In both cases, I was able to reload the namespaces on Java 8 but not Java 11. It's weird though -- in some of my other projects, I can reload namespaces on Java 11. I haven't been able to track down the difference. (I'm also new to tools.deps, so it could be I'm doing something wrong there.) I put together a reproduction here: https://github.com/thomascothran/namespace-repro Seems like an an error on my end, but way I've been able to reproduce it is by Java version.

Alex Miller (Clojure team)14:07:37

the (now) preferred place to log something like this is on https://ask.clojure.org with the problem tag in the contrib-libs/tools-namespace category

Alex Miller (Clojure team)14:07:52

and we will promote it to a dev jira if needed

thomascothran14:07:28

Ah, sorry. Didn't know about that. I'll post it over there.

vemv23:07:28

might it have to do with having chosen user as the "setup" ns? user has a special meaning to the Clojure compiler - its code can be loaded earlier. By renaming it to dev you remove those special semantics, which IME is desirable and has fixed various issues in the past.

Alex Miller (Clojure team)14:07:36

one place we saw problems was with https://clojure.atlassian.net/browse/CLASSPATH-8 on Java 9+ in java.classpath, which tools.namespace depends on

Alex Miller (Clojure team)14:07:24

although those patches should be included in latest version that you're using

seancorfield18:07:55

I was able to repro locally very easily based on that @thomas559 but I haven't yet had time to dig into any of the code to figure out why it doesn't work on JDK 11...

thomascothran14:08:27

Thanks for taking a look, @seancorfield. @andy.fingerhut pointed out on the new forum that adding an explicit dependency on org.clojure/java.classpath will make tools.namespace/refresh work.

Mark Addleman19:07:51

I'd like to use nrepl and rebl together with cursive. I found a couple of nrepl middlewares out there (https://github.com/RickMoynihan/nrebl.middleware and https://github.com/DaveWM/nrepl-rebl). I've tried both and I get similar error messages when I try to start using tools.deps. Wrong number of args (5) passed to: cognitect.rebl/-main when I try to use RickMoynihan's middleware and command line `clj -A:nrepl:rebl-11:nrepl-rebl -m nrepl.cmdline --middleware '[nrebl.middleware/wrap-nrebl cider.nrepl/cider-middleware]' -i `

Mark Addleman19:07:37

What are people doing to use nrepl and rebl together?

noisesmith19:07:54

@mark340 it's passing all the args from -m on to rebl (which is your actual entrypoint), and those args are designed for clojure itself

Mark Addleman19:07:42

Oh, I see. I'm using @seancorfield’s great deps.edn and his rebl profiles include main-opts.

Mark Addleman19:07:46

Thanks for the pointer

timsgardner19:07:28

hey, I'm assessing some repl stuff for our CLR-based Clojure variant. The NREPL implementation is rudimentary at the moment, I'm trying to get a sense of the effort involved in supporting more Cider features like breakpoints. Wondering how Cider deals with multiple breakpoints being hit on different threads simultaneously? Thanks

neupsh19:07:41

Hello, how do I get urls with space to work with bidi? https://github.com/juxt/bidi

(def routes ["/" {"" :index
                  "users" {"" :users
                           ["/" :name] :user}
                  true :four-o-four}])
=> #'cljs.user/routes

(bidi/path-for routes :user :name "Hello World")
=> "/users/Hello World"

(bidi/match-route routes (bidi/path-for routes :user :name "Hello World"))
=> {:handler :four-o-four}

neupsh19:07:26

May be better to ask #juxt , i will cross post it there

noisesmith19:07:55

@neupsh you could try Hello%20World - that's what would get sent to your http server if it said Hello World in the browser bar

noisesmith20:07:30

in general I wouldn't make any assumptions about what a router would do for a route that isn't actually possible given the protocol

neupsh20:07:35

@noisesmith it is actually trying Hello%20World in the browser. it does not work with that either

noisesmith20:07:48

that's odd - I would expect that to work with the routes definition you have

neupsh20:07:51

(bidi/path-for routes :user :name "Hello%20World")
=> "/users/Hello%20World"

(bidi/match-route routes "/users/Hello%20World")
=> {:handler :four-o-four}

noisesmith20:07:13

that looks like a bidi bug? strange

neupsh20:07:49

yeah strange.. both forms don't work:

(bidi/match-route routes "/users/Hello World")
=> {:handler :four-o-four}

noisesmith20:07:13

I assume "Hello" without the space or %20 does work

neupsh20:07:51

yes

(bidi/match-route routes "/users/Hello")
=> {:route-params {:name "Hello"}, :handler :user}

noisesmith20:07:08

yeah, that really seems like a bug in bidi then

neupsh20:07:48

hmm. let me see if there are any bug already filed for it. if not i think i will file one

lilactown20:07:50

bidi has a lot of matching bugs that are annoying

lilactown20:07:58

I would suggest using reitit if you're not already heavily invested

👍 4
neupsh20:07:26

I am just starting, I will check it out

markgdawson21:07:26

I've been using clojure for small projects, and boy is it fun! Now I'm turning to web projects. I really buy the "pure functions make for happy developers" argument, but how do we maximise pure functions and localise statefulness in practice for real Web apps when database reads/updates are king? I've done Web dev in the past with OOP/ORMs and it hasn't been pleasant, I can see there is a better way out there, it just isn't obvious to me what it is!!

markgdawson21:07:49

I can imagine a system that reads at the start of a request and defers writes right to the end, and is pure between, is this what people do? Or an I entirely missing the point?

vemv23:07:07

When using https://github.com/jkk/honeysql or Datomic, your business logic (in form of DB reads and writes) is pure data:

{:select [:a :b :c]
 :from [:foo]
 :where [:= :f.a "baz"]}
By placing the data part and the side-effectful parts in different functions (or even ns's), you can stick to the "side-effect-free" ideal, gaining a more testable app. (name of the pattern: imperative shell, functional core) e.g. you can test that an HTTP handler (a pure function) emits the right SQL (pure data) without involving actual I/O at all. It's faster and more reliable than an integration-ish test

seancorfield21:07:13

@markgdawson You can do that for fairly simple CRUD around web requests but it can also get messy when you have more complex database activity going on.

lewix21:07:21

clojure is still living?

lewix21:07:33

@seancorfield well you’re still here too 😮

seancorfield21:07:35

As much as possible, when you can structure your code into "read the data you need", "run the (pure) business logic transforms", "write the data that needs updating" it is worth doing. But a lot of web apps require conditional actions to be taken after database updates...

lewix21:07:06

thanks for helping me out a bunch of time while i was learning clojure a few years ago @seancorfield (probably you cant remember)

seancorfield21:07:19

Welcome back 🙂

noisesmith21:07:35

I clearly haven't done the formal work to prove it, but it seems like there would be a reliable transform that would be similar to continuation passing style, where a "continuation" or trampoline target for the top level doing IO could be invoked on exit of each pure step

noisesmith21:07:45

maybe I'm reinventing monads there

andy.fingerhut21:07:47

Are there books or articles folks have written on those kinds of application design choices when dealing with multiple reads and writes to a database, and you kind of wish they were one big transaction, but for performance or database limitations they are not? Especially one that compares/contrasts Datomic to SQL in that regard?

8
markgdawson21:07:53

I'd be interested in reading along these lines. Especially around the practical/pragmatic/real-world solutions.

hiredman21:07:17

@noisesmith or free monads or algebraic effects

👍 4
seancorfield21:07:30

This was my experiment (in Clojure) of pushing side-effects to the edges using a monadic sort of abstraction https://github.com/seancorfield/engine

hiredman21:07:46

I think facebook's ml (reason ml?) has something like a free monad but allows for parallel io operations instead of sequential (which I think free monads require)

yen05:08:35

It’s Haxl you’re thinking of

seancorfield21:07:48

We actually used it at work for a while. A short while.

lilactown21:07:12

reasonml is just a diff syntax for OCaml, so whatever OCaml offers

hiredman21:07:49

I could be misremembering which niche language out of facebook had it

SgtZdog21:07:43

Hey guys, I was wondering what is the general preference on (.contains) vs (includes?)? I looked in (includes?) and it's literally just a (.contains? (.tostring)), so it seems like there's no functional difference (since the java library should stringify the object before attempting the contains anyway).

seancorfield21:07:31

clojure.string/includes? means it's portable between Clojure and ClojureScript.

SgtZdog00:08:49

Ah, thanks, I work in an all backend application where I don't think of CojureScript at all, thanks for bringing that up though, it is important to consider and a good reason to use (includes?).

markgdawson21:07:41

I see, so it sounds like (as I suspected) for complex database logic, our hands are (mostly) tied. But thanks everyone for the interesting insights, I'll certainly have a play with some of them.

andy.fingerhut21:07:30

Datomic does make it straightforward to read a consistent snapshot of the entire database, as much or as little of the data as you want, all representing the state at the time of one transaction completing. Doing so means that any transactions you create for updates might be based on old state. I suspect others know much better than I what kinds of good choices exist for dealing with that.

markgdawson21:07:52

Yeah, it seems that the datomic way would allow one to adopt a much cleaner style of programming, but it's something I've yet to play with. Maybe that's a direction I should explore more.

markgdawson21:07:55

Extending immutability to the database and keeping hold of data is something I could definitely get on board with if it was also a practical solution. I'll dig into Datomic some more.

sogaiu22:07:58

@timsgardner in case you haven't checked already, you might have more luck at #cider

timsgardner22:07:33

@sogaiu thanks I'll check that

thomascothran14:08:27

Thanks for taking a look, @seancorfield. @andy.fingerhut pointed out on the new forum that adding an explicit dependency on org.clojure/java.classpath will make tools.namespace/refresh work.