Fork me on GitHub
#clojure
<
2019-03-02
>
didibus04:03:01

What user was that? Almost makes me want to avoid all funcool lib

didibus04:03:15

It could be a liability not to do so

seancorfield05:03:27

@didibus As far as I'm aware, it was just the one guy, called out in the thread I linked to...

victorbjelkholm42911:03:31

Can I somehow read the args of a function passed into a macro?

victorbjelkholm42912:03:53

Tried to see how #() does it with the variadic args but can't find the source for that macro

victorbjelkholm42912:03:53

(:arglists (meta #'my-symbol)) seems to do the trick, and I don't even need a macro

victorbjelkholm42913:03:01

So, got it to work with vars, but would like it to work with anonymous functions as well, if possible (feels like I need another way of reorganizing the forms in a different macro to solve this) Current implementation

(defmacro read-args [f]
  `(first (:arglists (meta #'~f))))

(defn use-log-func [log] (log true))

(read-args use-log-func) ;; Works
(read-args (fn [] (println "None"))) ;; Fails
(read-args (fn [one] (println "One"))) ;; Fails
;; Failure:
;; clojure.lang.PersistentList cannot be cast to clojure.lang.Symbol

didibus05:03:38

What the macro receives is not a function, but code. So you will need to parse the code yourself and identify the args within it.

didibus05:03:07

It might be possible for you to delegate back to def in this case.

didibus06:03:07

Actually, it seems only defn parses args into arglists

didibus06:03:36

You can try this:

(defmacro read-args [f]
  (if (symbol? f)
    `(:arglists (meta (var ~f)))
    `(do (defn ~'_ [email protected](rest f))
         (:arglists (meta (var ~'_))))))

victorbjelkholm42910:03:06

Nice! Thanks a lot, works perfectly for what I wanted it to do!

borkdude15:03:27

This:

(let [in (java.io.PushbackReader. (StringReader. "#<Namespace user>"))]
    (try (read in) (catch Exception e nil))
    [(read in) (read in)])
returns '[Namespace user>] How do I get the reader to skip over this thing entirely?

borkdude15:03:51

i.e. I’m not interested in anything #<foobar>

borkdude15:03:21

use case: I’m parsing REPL sessions that can be interleaved with valid clojure expressions and their output

borkdude16:03:28

Another issue. I’m generating code like this:

(defn example-104
    "clojure.core/extend"
    []
    (defprotocol Dateable
      (to-ms [t]))
    (extend java.lang.Number
      Dateable
      {:to-ms identity})
    (extend java.util.Date
      Dateable
      {:to-ms (fn* [p1__19578#] (.getTime p1__19578#))})
    (extend java.util.Calendar
      Dateable
      {:to-ms (fn* [p1__19579#] (to-ms (.getTime p1__19579#)))})
    (in-ns (quote speculative.clojuredocs-parser)))
but it seems that defprotocol is not supported well in defns: the symbol to-ms cannot be resolved.

borkdude16:03:43

A declare helps

mpenet17:03:29

Weird pattern

mpenet17:03:00

Just wondering, why isn't the defprotocol at top level?

borkdude17:03:42

I’m just reading examples from clojuredocs and generating a function for each example

borkdude17:03:08

I could just spit out all the code at the top level I guess

borkdude17:03:31

but this makes it a bit more manageable

borkdude17:03:56

I could also spit each example to their own namespace

ghadi22:03:21

@borkdude in your example to-ms cannot be resolved because you're referring to a symbol/var before the protocol is defined

ghadi22:03:33

It is the defprotocol that defines it

ghadi22:03:46

The protocol is defined at runtime of that function. The symbol is resolved at compilation time of that function

borkdude22:03:17

I fixed it now by emitting the defprotocol before the start of the function (same for import, require, etc.)

ghadi22:03:31

Yeah. That works

ghadi22:03:59

Some people call this the "Gilardi scenario" which sounds sort of creepy

andy.fingerhut22:03:52

Creepy? Does it remind you of something else with a similar name that is creepy, perhaps? If it reminds you of "The Cask of Amantillado", then agreed, but the only thing I can see common between those is that they contain an Italian name 🙂

borkdude22:03:48

what’s the origin of this name for this problem btw. I tried to look it up before, but couldn’t find it

ghadi23:03:16

I don't know the origin story, but it's about Stephen Gilardi, one of the OGs

andy.fingerhut04:03:15

@borkdude I get several hits via a Google search for the term: Gilardi scenario. Yes, it was named for Steve (Stephen? not sure of spelling) Gilardi, who was one of the first to describe it.

ghadi22:03:18

It's at least a variant of it

borkdude22:03:04

oh yeah, sounds familiar