Fork me on GitHub
#clojure
<
2019-05-12
>
deva04:05:33

anybody used toucan? I am looking for help on alias name. Ex: SELECT column_name AS alias_name FROM table_name;

seancorfield05:05:27

@gdrte Not sure I see the point of using toucan. It doesn't look very idiomatic to me.

👍 1
seancorfield05:05:48

Why not use pure SQL?

andrethehunter05:05:20

@gdrte the great thing about toucan is that you can use honeysql

(-> (select :a [:b :bar] :c [:d :x])
    (from [:foo :quux])
    (where [:= :quux.a 1] [:< :bar 100])
    sql/format)
=> ["SELECT a, b AS bar, c, d AS x FROM foo quux WHERE (quux.a = ? AND bar < ?)" 1 100]

deva17:05:28

@andrethehunter It worked for me like this (db/select [m/Facility :id [:facility_name :facilityName] [:standing_orders :standingOrders]])

seancorfield05:05:37

Well, that doesn't use toucan at all -- that's the great thing about HoneySQL and clojure.java.jdbc 🙂

😂 1
andrethehunter05:05:00

@seancorfield how is toucan not idiomatic?

seancorfield05:05:14

It tries hard to be an ORM 😞

😱 1
seancorfield05:05:12

The fact that someone has to ask about something as basic as a column alias says there's a problem with toucan if it doesn't support that.

andrethehunter05:05:17

Yes that's the good thing about toucan (vs korma for example), it's still data driven

andrethehunter05:05:08

Use toucan where it makes sense, otherwise use honeysql

seancorfield05:05:12

It uses a lot of global dynamic variables as well, which is terrible practice. It makes using multiple databases nigh on impossible.

andrethehunter05:05:12

Agreed, the globals aren't nice. PRs welcome 🙂

deva05:05:24

@seancorfield @andrethehunter Thanks for the reply. First I looked at hugsql, but my team felt it is too much laborious which contradicted my reasoning to go with Clojure (our app is in Kotlin). I find toucan is enough to avoid too much of repetition and also I am convinced in case of more complex SQL there is HoneySql.

👍 1
seancorfield05:05:05

Yeah, I'm not a fan of HugSQL because I don't like the SQL separate from the code that uses it.

curtis.summers16:05:38

It's worth noting that, although the primary workflow of HugSQL is to allow separate SQL files, the library contains all of the necessary functions to use SQL inline in your code or at the repl. Specifically, db-run and db-fn accomplish this and give you the same HugSQL parameter replacement abilities. https://www.hugsql.org/#using-other-fns

seancorfield05:05:19

But there's nothing wrong with SQL. It's a pretty good DSL 🙂

andrethehunter05:05:43

Using data is a lot more reusable and composable. A logical data translation layer really helps (like honeysql vs SQL, hiccup vs HTML). SQL strings have various limitations and can cause security issues (if parameters aren't used)

seancorfield05:05:01

(sql/get-by-id connectable :table-name the-key) seems a pretty concise way to get a hash map of a single row by primary key (one of Toucan's misleading examples makes it looks like this needs to be a lot of work).

seancorfield05:05:29

@andrethehunter Sure, HoneySQL provides composability. We use it heavily.

👍 1
seancorfield05:05:14

My point is that Toucan makes a lot of strawman comparisons to try to show it is "better" than an unrealistic alternative that nobody would actually use anyway.

andrethehunter05:05:32

Toucan adds a lot of useful things. For example, how would you do hydration easily using SQL? It also has nice post and pre process functionality.

seancorfield05:05:13

datafy/`nav` provides that feature out-of-the-box in both clojure.java.jdbc and next.jdbc.

2
andrethehunter05:05:10

Ahh in next.jdbc. That wasn't available when we implemented or DB layer. I'll check it out 🙂

seancorfield05:05:13

But you'd be better off doing a join in SQL in the first place instead. That sort of "convenience" is one of the bad/misleading things that ORMs try to make "easy" for you.

👍 1
andrethehunter05:05:54

Yes but joins don't create nested structures. Is there a way to do that easily?

seancorfield05:05:26

(I'm very down on ORMs after decades of work with them)

andrethehunter05:05:43

I don't like ORMS either. Toucan doesn't add a .save method on the data. You pass on the model definition and just data.

1
andrethehunter05:05:24

So toucan isn't the least ORM "ORM" I've used

andrethehunter05:05:02

@gdrte is better to use the specific channel for questions. See #toucan, #honeysql, and #sql channels

1
Ivan Koz06:05:27

When we create a sub-vector it holds on original vector, but what happens to original if we conj onto sub-vector and throw it away?

kulminaator06:05:50

hopefully nothing, otherwise i have to rewrite all my code

Ivan Koz06:05:04

right, nothing happens

kulminaator06:05:06

if you have a moment maybe you can watch the video from here ? https://youtu.be/wASCH_gPnDw?t=1753 , it explains some things very well

Ivan Koz06:05:12

v.assocN(end, o) is being called on original, new subvector returned

Ivan Koz06:05:03

so almost the same thing as creating subvector of a subvector

dominicm06:05:26

I'm banging my head against a jetty server that after a (.stop svr) and (.join svr) is still using the port. The server is configured for websockets, so I'm not sure if that's related at all. Hoping this sounds vaguely familiar to someone who can help me out 🙂

kulminaator06:05:16

is it still listening after the stop ?

kulminaator06:05:26

or is the port just in some wait linger and not listening ?

kulminaator06:05:34

and just to make sure, you are trying that on windows, are you ? 🙂

dominicm06:05:35

That's a good question, I'm not certain. I think it resolves it itself given a little time (human typing time) this only happens on (reset). Nope, linux!

kulminaator06:05:51

just check netstat -anp | grep LISTEN

kulminaator07:05:12

if it's still there listening for real after the join

kulminaator07:05:27

i use the same pattern myself in some integration tests and i don't remember it misbehaving

dominicm07:05:30

I'm pretty sure this is related to websockets somehow, because it only happens if the server-side component of that is activated. Well, more specifically, if figwheel is trying to start a repl.

kulminaator07:05:58

netstat's output also lists the process id's , there's always a chance you have forgotten another process around that lives on the same port 😉

dominicm07:05:59

Na, I've got a "mostly reproducible" (because it's racey) echo '(future (cljs-repl)) (go)' | clj -A:dev which succeeds for one of them, and fails for the other with "Address in use"

dominicm07:05:11

I stuck a clojure.java.shell/sh in after the .join and I can't see the port in there at all 😞

dominicm07:05:17

so what on earth is going on!

kulminaator07:05:28

i think join itself is just there to wait for the thread to stop after the server has been shut down ... join itself shouldn't do anything with the port by itself

dominicm07:05:15

The join may well not be necessary, it was a guess I added. I suspected that the server wasn't completely shutdown yet.

kulminaator07:05:07

tested here locally, right after i do (.stop server) the port is not being listened on anymore

kulminaator07:05:22

so it does sound like there is indeed something racey going on in your machine , but i wouldn't blame it on jetty right away 😉

dominicm07:05:05

it's definitely racey. With the addition of ss it's much less likely to happen.

kulminaator07:05:54

if it solves in little time then perhaps make the server restart thingy more persistent in it's actions 🙂

kulminaator07:05:09

we used to that on servers too before all the operating systems started to support the reuse flags on sockets

kulminaator07:05:37

then you'd see an apache server going down and having to wait a minute before a you could do a rebind (on a badly configured linux server)

dominicm07:05:48

This is in development, and is pretty much just the internal figwheel stuff being stopped/started quickly via the api.

dominicm07:05:00

the thing is, I'm not seeing 9900 in time-wait either.

dominicm07:05:13

http://hea-www.harvard.edu/~fine/Tech/addrinuse.html I only get this if I try and start a cljs repl (server side). I don't think that's a websocket client, but maybe it is (or maybe it just alters the timing just so)

dominicm07:05:26

but I should still be seeing time_wait if that's the case.

kulminaator07:05:44

and you are sure there is no accidental duplicate process trying to rebind at the same time either ? 🙂

dominicm07:05:15

That would also show up in the ss I'm running just before starting (or, at least it should once)

dominicm07:05:51

I have no java processes open, and I don't write any other code 😄

kulminaator07:05:37

no funny macro business going on either evaluated at a different time than you think ? 🙂

dominicm07:05:47

Nope. Functions and multi-methods here only.

roklenarcic12:05:41

Hm... could not closing chan async channel cause a memory leak?

roklenarcic12:05:11

I have code that is passed a channel, reads an item from the channel and throw it away.

roklenarcic12:05:12

and the code that creates the channel doesn't hold on to it

alexmiller17:05:59

If no one is using it, should be gc’ed

dominicm18:05:28

I'm looking for libraries which enable suspendable evaluations in clojure. Nothing in mind too much, just looking at implementing something which parallels excel.

rickmoynihan08:05:42

an à la carte build system perchance?

dominicm10:05:47

Actually for aero, but ideas from that yeah

dominicm10:05:51

I'd love to implement that paper, I don't think it's as general as it suggests, it's evaluation behaviour is pretty dependent on various haskell things like applicative

rickmoynihan11:05:24

> Actually for aero Ahh ok, so you’re trying to manage a graph of effects inside an immutable edn tree?

dominicm12:05:53

I'm trying to model the completely dynamic dependency graph without setting my hair on fire. The first two implementations have set my hair on fire 🔥

dominicm12:05:46

I'm trying to add macro support at the same time, where macro means that #profile stops running all paths.

dominicm12:05:31

The interface needs to stay fairly similar because it is easy to use

rickmoynihan12:05:38

ahh so dynamic dependencies as in that talk too

lilactown18:05:50

like continuations?

dominicm18:05:55

That's what I was thinking of, yes!

emccue18:05:51

not to say the m word

emccue18:05:04

but maybe something close to this?

lilactown18:05:44

@dnolen made a delimited continuations lib awhile ago

lilactown18:05:34

there’s another library that people were talking about on clojureverse a few months ago

emccue18:05:28

for something like excel it feels like "lazy evaluation" might not be enough

emccue18:05:57

or rather, even if it technically represents what is happening it isnt super useful beyond actually computing the values

dominicm18:05:43

excel has a "restarting scheduler" where it pauses evaluation on request of a cell, and re-orders the evaluation, then starts again. A little bit like what pedestal does with interceptors I guess.

respatialized21:05:13

I don't know whether it has the ability to "pause evaluation" in the way you're describing, but I immediately thought of Matrix when I thought of "excel-like" dataflow in Clojure https://github.com/kennytilton/matrix

dharrigan18:05:55

Is there anything you can learn from the way Kotlin does it, their coroutine support, via libraries, is very well developed.

dharrigan18:05:03

I believe they use a state machine

dharrigan18:05:22

Of course, when Project Loom makes its way into the JVM, I'm sure the approach may change then too!

dominicm19:05:20

a state machine? sounds like how the go-block works :thinking_face:

dharrigan19:05:21

I'm not that familiar with the depths of the approach that they took

emccue19:05:50

I think the "reordering" part is cruicial

dharrigan19:05:10

There are quite a few videos from the designer of the coroutine support of kotlin on youtube.

emccue19:05:13

you basically need to make sure that the computations are a DAG and that you do them in topological order

emccue19:05:47

so if someone makes a change you could do a "virtual dom" for each cell

emccue19:05:58

and only recompute the values that have changed

emccue19:05:18

or you could compute the whole batch of values

dominicm19:05:48

excel is slightly heavy-handed with it's approach to dependencies, but it does generally satisfy minimality.

dharrigan19:05:55

I do recall too that they (kotlin guys) changed the way coroutines worked, before making it public (i.e, non-experimental). Here's the post from Roman about it: https://medium.com/@elizarov/structured-concurrency-722d765aa952.

dominicm19:05:59

If you use INDIRECT then you'll be recomputed very often.

dharrigan19:05:16

I think it would be exciting to have coroutine support in Clojure 🙂

leonoel06:05:14

Have a look at https://github.com/leonoel/cloroutine it's a low-level macro that can be used to implement the patterns mentioned in the articles you linked. I'm not aware of any clojure implementation of trio-like structured concurrency but that lib would definitely be a good start if you're willing to explore this path.

emccue19:05:46

(go to town with macros)

kulminaator19:05:03

dharrigan what problem would it solve ?

holyjak22:05:02

Hello! I use deps.edn with cognitect/test-runner / Kaocha and cannot figure out how to get some namespaces AOT-compiled (needed due to gen-class in test files). Any [googling/solution] tips? Thank you!

1
kszabo22:05:28

hey, I just asked the same questions few days ago over at the #tools-deps room: https://clojurians.slack.com/archives/C6QH853H8/p1557397085170000

❤️ 1
Cora23:05:39

is there a way to generate a hash-map with test.check.generators where one of the values is calculated from two of the other values?

Cora23:05:04

basically I don't know how to do the gen for the :frame-rate

Cora23:05:40

hmm maybe with a gen/let?

Cora23:05:40

yeah, that should work