Fork me on GitHub
#clojure
<
2016-07-18
>
adamw06:07:46

folks, is there a way to apply maps to become keyword arguments to functions? The case I'm thinking of is a fn that consumes a keyword and passes the remainder down to another function. For example:

(defn bar [x & {:keys [bar-arg] :as attrs :or {bar-arg 5}}]
    (prn x bar-arg attrs)
    )

  (defn foo [x & {:keys [foo-arg] :as attrs :or {foo-arg 1}}]
    (bar x (dissoc attrs :foo-arg)))

  (foo 5 :foo-arg 5 :bar-arg 4)
At the moment I have to either destructure the full map in foo and appropriately pass kw arguments, or pass the whole thing as a map argument, which seems... wrong.

adamw06:07:18

I saw this: http://dev.clojure.org/jira/browse/CINCU-3 but haven't seen any discussion on it, so don't know if it was accepted or done in another way

hans06:07:31

@adamw: clojure does not actually have keyword arguments, and destructuring rest (&) arguments like they were a map is really just a hack. the common style nowadays is to pass maps if you want something similar to keyword arguments, as maps compose more easily (like you discovered).

adamw06:07:59

@hans: ok thanks makes sense!

jjcomer09:07:03

@adamw (apply bar x (-> attrs (dissoc :foo-arg) seq flatten))

octahedrion11:07:43

I often use a hand-written 'partial-right' as described here http://stackoverflow.com/questions/34285565/clojure-partial-right, but the first answer there says it's a bad idea, why ?

m1dnight11:07:04

I think that partial is fine to use. But the reason that it is not in the standard library is because it would be an arduous task to implement it. I misinterpreted the question. Nvm.

m1dnight11:07:27

In other functional languages like Haskell, ML, or Racket partial is just a way of programming using swap and the likes.

Ertugrul Cetin11:07:58

Hi guys, https://clojure.news is out! HackerNews clone written entirely in Clojure & ClojureScript

genRaiy12:07:53

guys - does anyone have any experience trying to interop with JDK8 syntax (like Lambdas) … am trying to call into the Kafka Streams LIbrary and with the Lambda there’s a lot of boiler plate that is difficult to plaster over

genRaiy12:07:14

I’ve had a look at https://github.com/ike-tools/ike.cljj but it does not quite fit the bill as I cannot see a way to create an anonymous Lambda

genRaiy13:07:45

also looked at https://github.com/ohpauleez/jloj but for usage - he says ‘shield your eyes’ 😉

agile_geek13:07:29

Never tried it but as Java 8's implementation of lambda's is reliant on implementing the java.util.function interfaces I suspect you can't pass a completely anonymous lambda as you'd have to reify one of those interfaces to interop with streams

genRaiy13:07:55

yes - that’s what I have read. I guess we are going to have to live without simple / elegant interop until cognitect are ready to mandate 1.8

agile_geek13:07:05

That seems to be what ike is doing for you with defsam

genRaiy13:07:33

er yes @agile_geek cough, splutter I knew that 😊

seancorfield16:07:56

@octo221: we have a flip function that accepts everything except the first argument and returns a function of one argument, but it's not a general "partial-right".

seancorfield16:07:58

We don't use it very often tho' because idiomatic argument usage tends to favor partial instead or using threading macros to avoid anonymous functions altogether.

seancorfield16:07:06

So, as that SO answer hints, it would make me question why I was trying to reach for such a function.

daveliepmann16:07:47

Hey folks, I’ve got an issue where it appears that my Clojure stacktraces aren’t returning all the information that I see identical exceptions returning in pure Java. I’m trying to get a handle on how I would go about debugging this. Is this a known thing? (For example, in Java people get something like “com.marklogic.xcc.exceptions.XQueryException: XDMP-UNEXPECTED: (err:XPST0003) Unexpected token syntax error, unexpected QName_on line 1” but in Clojure I get only “Unhandled com.marklogic.xcc.exceptions.XQueryException Unexpected token”)

octahedrion16:07:59

@seancorfield: ok, I really don't get why it's not idiomatic. I use partial all the time. If a function's parameters aren't ordered conveniently for partial, why not partial them from the other direction? what's the difference ? For example, I often need to partial get, with a path or default value, but get's first parameter is the map, not the path or default value, so be it, partial from the other direction

dg16:07:37

I'm not sure what "idiomatic" really means here, but I'd also be interested in hearing why it's not a good idea.

octahedrion17:07:23

@dg: nor me, I thought one of the lovely things about LISP was higher-order functions, well -> macro isn't composable, why is it idiomatic to use partial if the function's parameters are in the "right" order, but not if they're in some other order ?

octahedrion17:07:09

I must be missing something

Lambda/Sierra17:07:32

@daveliepmann: It's not usually the exception that's missing things, but whatever is printing the exception. The canonical way to print an exception is Throwable.printStackTrace

daveliepmann17:07:13

@stuartsierra: Aha! That indeed gets me the whole shebang. Thank you!

daveliepmann17:07:40

...strange that the exception returned via cider would omit information present in toString and printStackTrace. I wonder if reformatting the full exception from those methods is common in situations like this.

dpsutton17:07:18

cider has a button at the top to show the full stack trace

dpsutton17:07:22

can you try clicking that?

dpsutton17:07:35

i htink it tries to hide some java internals but allows you to see it all if you would like

dg18:07:30

That's just filtering stack frames

dpsutton18:07:09

ah ok. thought he was not seeing the java parts. but i think i misread it

Lambda/Sierra18:07:49

Almost every exception printer tries to be helpful by omitting something it thinks is irrelevant. Sooner or later, that thing will be relevant.

daveliepmann18:07:20

Yeah, it looks like somewhere (cider?) is using getClass and getLocalizedMessage rather than the more complete toString. I think part of the issue seems to be that somewhere in the implementation of this particular Exception, more info is added to toString than java.lang.Throwable describes https://docs.oracle.com/javase/8/docs/api/java/lang/Throwable.html#toString-- —which is just classname : localized-message

daveliepmann18:07:54

Actually, I'm not sure it's cider. Even (try ... (catch Exception e e)), which I assume doesn't get modified by cider, has none of the info added by the toString override in this Exception: https://github.com/marklogic/xcc-java/blob/master/com/marklogic/xcc/exceptions/XQueryException.java

dpsutton19:07:50

@daveliepmann: does that have different behavior in a lein repl from cider?

seancorfield19:07:50

@octo221: I remember reading that a function which is idiomatic in (Clojure) usage will have an argument order that lends itself to either partial, ->>, or ->… I’ll see if I can find the reference for that /cc @dg

seancorfield19:07:22

Well, there’s a hint in that direction here http://clojure.org/guides/threading_macros where it talks about functions that operate on sequences have the sequence as the last argument but functions that operate on data structures have it as the first argument… rather than other positions. I’ve seen this expanded to argument order based on what varies most...

seancorfield19:07:22

This mailing list thread is helpful: https://groups.google.com/forum/#!topic/clojure/iyyNyWs53dc — Rich talks about argument order (back in 2008!).

daveliepmann19:07:08

@dpsutton: good question; it will take a few minutes to get a minimum example into the repl. I'm curious—what do you expect?

dpsutton19:07:31

i'm expecting that cider is just parsing what is given to it, so this would be a problem with leiningen

dpsutton19:07:46

but its possible that somewhere in the cider-nrepl they are not getting all the information that they could

seancorfield19:07:47

(and this blog post from 2010 seems to go along with that line of thinking https://kotka.de/blog/2010/08/Did_you_know_VII.html )

daveliepmann19:07:25

@dpsutton: That was an enlightening exercise. lein repl omits the same info that cider does!

dpsutton19:07:56

well, now it is clear which project needs the issue opened

dpsutton19:07:04

good snopping dave

dpsutton19:07:24

it might be fun to go look around in there and see how this all works

dpsutton19:07:33

maybe its some repl middleware somewhere

daveliepmann19:07:32

Fascinating. I have never run into an error so deep in my tooling before, so I'm a bit surprised to see how much is under the hood.

josh_tackett19:07:29

@seancorfield: Hey what is the best way to get this into a date time structure: (t/minus (t/today) (t/days 90))

seancorfield19:07:04

@josh_tackett: Not quite sure what you’re asking there… what do you mean by "a date time structure"?

josh_tackett19:07:32

sorry Date time format

josh_tackett19:07:50

field 'LastReferencedDate' must be of type dateTime

josh_tackett19:07:54

message from saleforce

seancorfield19:07:16

Do you mean you need a java.util.Date?

seancorfield19:07:37

Look at clj-time.coerce.

josh_tackett19:07:54

ya there isn’t anything that get’s it to the proper format

josh_tackett19:07:00

sorry proper type

Chris O’Donnell19:07:16

clj-time.coerce/to-date returns a java.util.Date

seancorfield19:07:17

There absolutely is a coercion to java.util.Date

josh_tackett20:07:22

#<DateTime 1998-04-25T00:00:00.000Z>

josh_tackett20:07:39

@seancorfield: this is the type I am looking for ^^^

josh_tackett20:07:00

what is the easiest way from here :#<LocalDate 2016-04-19>

josh_tackett20:07:11

local date to datetime

seancorfield20:07:28

I’d have to go read the Joda Time docs to figure that out.

josh_tackett20:07:47

@seancorfield: I’m asking if you have a function to do it in your clj-time lib

josh_tackett20:07:53

you wrote the library correct?

seancorfield20:07:04

I maintain it. I did not write it.

seancorfield20:07:20

I do not use LocalDate.

seancorfield20:07:49

I use clj-time extensively but for UTC date/time stuff.

josh_tackett20:07:08

so what is the best way to get (t/today) but not in localDate?

seancorfield20:07:42

(t/now) is probably what you want.

seancorfield20:07:29

boot.user=> (t/minus (t/now) (t/days 90))
#object[org.joda.time.DateTime 0x65bd99a5 "2016-04-19T20:04:14.276Z"]

seancorfield20:07:43

FWIW, clj-time has a large enough API that I would never bother trying to memorize it — I go read the docs any time someone asks me a question about it 🙂

josh_tackett20:07:10

Awesome (t/now) exactly what I was looking for

dg20:07:02

@seancorfield: Rich's answer seems to support the idea that there's not much special about partial's favoring left:

dg20:07:12

> Ditto partial. Every library eventually ends up with a more order- > independent partial binding method. For Clojure, it's #().

seancorfield20:07:51

@dg: Yeah, I haven’t yet found the piece I remember about ordering arguments based on what varied most...

wilkerlucio23:07:33

@octo221: if you need -> with variadic argument position, check the documentation for as-> https://clojuredocs.org/clojure.core/as-%3E