-
Notifications
You must be signed in to change notification settings - Fork 10
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
require-r not working inside a function #66
Comments
|
It is working. But then later below I get errors that the namespaces are not defined. When I had it in a wrapper function, it would not work. |
Maybe something with |
I have no idea... Sorry. I just know that the code only works when is not in a function.
|
I will test it soon. |
Ok, the main issue with you function is that Below works on my setup (defn init-r []
(println "configuring clojisr ..")
(require-r '[base :as base :refer [$ <- $<-]]
'[utils :as u]
'[stats :as stats]
'[graphics :as g]
'[datasets :refer :all]))
(init-r)
(base/options :width 120 :digits 7)
;; => $width
;; [1] 120
;; $digits
;; [1] 7
(base/set-seed 11228899)
;; => NULL |
I have an idea:
What will happen here is that clojure analyzer will load the namespace and get the fuctions in it.
|
I am sorry for being a dick here. But how you have the syntax now makes it very difficult to write helper functions / libraries that use R functions. |
Ok, I leave it open. Yes, it's hard to write external helper functions since symbols are not available before requiring them in the live session. Maybe something like |
I tested around a little bit. So require is tighty coupled with jars. No way to use require For the short term, I think this might work: So you essentially do not use requires at all, and define the ns completely dynamic. So And then you can write a require-r macro that just redefines the functions you want to have Then all you need is one dynamic variable that is linked to the session, and then |
lein run
|
starting.. |
defs usage.
this is identical to
|
I would NOT do something like cljsjs. cljsjs is a thing of the past. shadow-cljs solved the poblem of npm dependencies and externals. r-deps.edn
Then you call
clojisr is an executeable (or a lein plugin, does not matter) then you adapt integrant.core to read target/r-modules.edn; and this means You just need to |
You can also do the interpreter approach that you do now; so it you have he startup cost at docstrings -> done! |
Thanks for the idea. I believe that when we decouple session from robjects all of this will be possible. What I see is that packages can differ between R version (R 3.x, R 4.x) so I don't think providing dummy namespaces (or edn) in library by us is an option. I need to rethink it, but generally the options we discuss are:
The only difference I see is "live R session", right? |
You are absolutely right! It definitely does not make sense to you inside the library will not provide a fixed module definition edn. Instead clojisr generates this on the users machine, with the r setup supplied by the user. However, this can be done BUILD TIME (say via a script that the can run user run,... ), Irrespective of BUILD TIME vs APP START TIME, the idea with in-ns,.. make sense. |
With my proposal, the syntax would change from:
to this:
quakes is a clojure def symbol, and refers RObject.
|
It's not as easy as it looks. There is stuff which often operate on symbolic level (like formulas). Also if you want to create R function from Clojure you have to make it on symbolic level. Also there are functions which contain forbiden symbols, also data types are different (named lists are not maps) etc. So removing symbolic calls removes part of the possible functionality. I agree that dummy handlers for R functions or values can be generated to enable clojure compilation without connection to R, but removing symbolic call is not possible. From your example (defn load-quakes-r [rmin rmax]
(-> 'quakes
(r.dplyr/filter `(& (>= mag ~rmin)
(<= mag ~rmax))))) Above code will be converted to a string and evaluated on the R side fully (dplyr/filter expects symbolic predicate and this predicate will be evaluated within But this: (defn load-quakes-r [rmin rmax]
(-> quakes
(r.dplyr/filter (& (>= mag rmin)
(<= mag rmax))))) Will not work. First This is how R works. Plenty of functions treat parameters as symbols and delay execution until needed. |
The forbidden Symbol problematic: totally agreed! There needs to be some kind of escaping. If I remember correctly this happens in cljs -> ks compilation also. (defn init! [] ...) Becomes init_bang (or similar) |
We escape using tick or backtick. |
(send-to-r :exec r-fun-name args-robject)
The example is a little difficult because it uses an Anonymous function as predicate. I have not yet executed the code I copied. @daslu did translate it for me. This is what I actually use in clojure only:
So the difficult part in this example is, that in my example it needs to generate and define in R an anonymous function (the predicate). And the definition of the function will have to be implemented ad a macro im Clojure. Because forms inside a function may not generate one wrapped r function for each form, and instead make the forms function calls inside the body of the r function Definition. |
Sorry for my most likely not precise R code. I am not an R expert. So most likely my R code is not correct. But I hope you get the idea. |
I think I'm missing something. How the last example is going to produce given above string? |
Did you test your code and is it working? |
I didn't test. I think you are right, and it will not work. As I said above.. I only tested the clj code I pasted above. |
We had a discussion with @daslu about using symbols (tick/backtics) or maybe use macros to mimic functional behaviour. And I agreed that parsing symbolic forms by |
In goldly I am using sci to compile short cljs functions to js. I think clojisr might want to use a similar compiler architecture that defines a few control functions (like if) in order to generate the string command to R. |
To not loose track of the main point here: the main usecace of clojisr Will be to call R functions. A simple function call, say (+ 1 2) would need to essentially check if it needs to convert each parameter to R, or use the R variable name if it is already known. When the R function had been mapped to a clojure function, then the rest becomes easy. |
But it's done: I don't agree that main use-case is calling a functions but also accessing the vars with different types (like S4 objects, data.frames, matrices), creating R functions and R datatypes. When you import a package - respective Clojure symbols are created, When called on the function position they act as functions. If you provide primitive parameters there are converted respectively. I have a feeling that we circle around the problem which I don't understand probably. We agreed that |
My 2-cents on this: |
When I have all the forms of this function direct in the namespace, then all works fine.
But if I wrap the initialization in a function to be more modular, then the r libraries
in require-r can no longer be found.
I am not sure if clj require works the same way or not.
The text was updated successfully, but these errors were encountered: