clojisr icon indicating copy to clipboard operation
clojisr copied to clipboard

R functions arglist

Open genmeblog opened this issue 5 years ago • 6 comments

I prepared POC for adding arglist for RObjects acting as function using formals. It can be helpful for REPL driven development. Arglists conform calling way in clojuress (associative destructuring on variadic position)

Examples:

(formals base/mean)
;; => ([x & {:keys [...]}])
(formals stats/arima0) 
;; => ([x & {:keys [order seasonal xreg include.mean delta transform.pars fixed init method n.cond optim.control]}])
(formals dev/dev-off)
;; => ([& {:keys [which]}])
(formals base/Sys-info)
;; => ([])

formals can be used to create :arglists meta tag.

(I checked and it works on CIDER)

genmeblog avatar Feb 06 '20 14:02 genmeblog

Nice.

This is related to #8 .

daslu avatar Feb 06 '20 20:02 daslu

Just to leave it before pull request. Formals is defined as below:

(def ^:private empty-symbol (symbol ""))

(defn formals
  [{:keys [code class]}]
  (when (= class ["function"])
    (let [args (-> (format "formals(%s)" code)
                   r
                   r->clj)
          {:keys [obl opt]} (reduce (fn [m [k v]]
                                      (let [selector (if (and (= empty-symbol v)
                                                              (not (seq (:obl m)))) :obl :opt)]
                                        (update m selector conj (symbol k))))
                                    {:obl [] :opt []}
                                    args)]
      (cond
        (and (seq obl)
             (seq opt)) (list (conj obl '& {:keys opt}))
        (seq obl) (list obl)
        (seq opt) (list ['& {:keys opt}])
        :else '([])))))

(alter-meta! #'stats/arima0 assoc :arglists (formals stats/arima0))

(meta #'stats/arima0)
;; => {:asdf 12, :name arima0, :ns #namespace[stats], :arglists ([x & {:keys [order seasonal xreg include.mean delta transform.pars fixed init method n.cond optim.control]}])}

Adding metadata can be done during intern in require-r.

genmeblog avatar Feb 07 '20 14:02 genmeblog

Sorry for duplicate.

genmeblog avatar Feb 07 '20 14:02 genmeblog

Hi @genmeblog .

  1. This is great!

  2. Added some regression tests for the functions you mentioned: https://github.com/scicloj/clojisr/commit/aecefd3061720079aed7fda1d7bb4137e8fef17f

  3. Added support for primitive functions: https://github.com/scicloj/clojisr/commit/ef312b7306933ca75ca4888e4ab89b4cbd9a4613

  4. Thinking about it, maybe the handling of arglists could be done not only when doing require-r, but rather, every time we create an RObject. This way, when we create an R function with (r 'sum) or (r '[function [x y] (+ x y)]), we get the arglists too. What do you think? If this sounds good, I can do it tomorrow.

(edit: typo)

daslu avatar Feb 13 '20 23:02 daslu

Great! Regarding 4: this would be the best solution. But remember that meta are attached to symbol not to object itself.

genmeblog avatar Feb 14 '20 06:02 genmeblog