sql

isak 2023-12-11T15:59:09.777769Z

If I reduce a next.jdbc plan without providing an init val (`(reduce f (next.jdbc/plan ...))`), I get this error: class next.jdbc.result_set$eval26051$fn$reify__26053 cannot be cast to class clojure.lang.IReduce Passing in nil for the init val makes it work as expected. Is that how it is supposed to work?

seancorfield 2023-12-11T16:02:31.668889Z

Yes. There is no sensible default so that form of reduce is not supported on plan. Pretty sure the docs explicitly call that out (but I'm on my phone right now).

πŸ‘Œ 1
dpsutton 2023-12-11T16:04:32.317119Z

doc doesn’t mention it > Returns a reducible that but source clearly indicates it

(^clojure.lang.IReduceInit
    [stmt]
    (p/-execute stmt [] {}))

πŸ‘Œ 1
seancorfield 2023-12-11T16:07:17.485749Z

In Getting Started, it says plan returns an IReduceInit but that's probably not quite clear enough. I'll update the docs and the docstring.

πŸ‘ 1
isak 2023-12-11T16:10:20.163029Z

Ok I see. Yea I checked what the clojure interfaces for reduce were after writing this, but wouldn't have known that that meant only the init val arity was supported.

isak 2023-12-11T16:11:10.817699Z

For a sensible default, would [] be wrong? (Since a result set is like a collection / seq)

dpsutton 2023-12-11T16:13:34.241739Z

if you intend to accumulate rows, yes. if you intend to sum something, no. If you intend to get stats in a map, no. etc.

isak 2023-12-11T16:14:32.004259Z

Right but that isn't the default thing you get from a result set, so it makes sense that you would override the default in such cases

isak 2023-12-11T16:15:57.039799Z

I think nil might be another value that some people would reasonably expect to be the default though, so the fact that there are 2 sensible values might be reason enough for the existing logic.

isak 2023-12-11T16:18:44.073769Z

@dpsutton isn't that an argument against IReduce in principle though?

dpsutton 2023-12-11T16:18:51.949859Z

yes it is πŸ™‚

😨 1
dpsutton 2023-12-11T16:19:27.991259Z

but here fits that general argument i think

seancorfield 2023-12-11T16:20:02.851009Z

Rich has said that the non-init form of reduce was a mistake.

isak 2023-12-11T16:20:43.692769Z

Ah, fair enough

dpsutton 2023-12-11T16:24:06.898569Z

nil as a default would accumulate rows in reverse order. a transient is probably a good call here as well but requires the reducing function to play along. far better to just own the initial value

isak 2023-12-11T16:28:29.802819Z

I see the benefits and generally do that. The downside is the surprise - not working like reduce normally.

dpsutton 2023-12-11T16:31:20.494939Z

reduce without an init is really weird

dpsutton 2023-12-11T16:33:52.940079Z

> If val is not supplied, > returns the result of applying f to the first 2 items in coll, then > applying f to that result and the 3rd item, etc. If coll contains no > items, f must accept no arguments as well, and reduce returns the > result of calling f with no arguments. If coll has only 1 item, it > is returned and f is not called. If val is supplied, returns the > result of applying f to val and the first item in coll, then > applying f to that result and the 2nd item, etc. If coll contains no > items, returns val and f is not called. the docstring of reduce is convoluted to talk about the lack of an init. and is quite surprising

isak 2023-12-11T16:38:58.720329Z

Hmm yea you're right, that is very strange

seancorfield 2023-12-11T17:25:31.534419Z

OK, docs and docstrings are updated for the next release.

πŸ’― 1