It's possible to invoke a clojurescript function from javascript, for example:
cljs.core.keyword("foobar")
returns the :foobar keyword, positional arguments work as you would expect. I'm trying to invoke js->clj with the :keywordize-keys argument but so far I haven't been successful. I've tried:
cljs.core.js__GT_clj({'foo': 42}, {'keywordize-keys': true})
// and
var k = cljs.core.keyword('keywordize-keys')
cljs.core.js__GT_clj({'foo': 42}, {k: true})
but neither seem to work as I had hoped. In general how do you specify keyword arguments when calling from js into cljs?
In cljs you call the function like this:
(js->clj #js {"foo" 42} :keywordize-keys true)
And the corresponding js code:
var k = cljs.core.keyword('keywordize-keys')
cljs.core.js__GT_clj({'foo': 42}, k, true)
Related
I'm working with a crate which has a callback function mechanism. The callback is user defined but has a specific signature which does not allow for other values to be passed. For instance:
fn callback(id: u32, value: u32) -> u32;
// and would be used as such
library_function(callback);
So this would be fine If I only needed to save to a file or print for instance, however I need to save the values to a vector.
What I would've done in, for example Python, is using a lambda with "predefined" arguments:
def mycallback(predefined, id, value)
# and calling it as such
predefined = []
library_function(lambda *args: mycallback(predifined, *args)
The solution can involve other tricks of Rust, however it can't be write to file each time since that seems like too much of a performance issue.
Just use a closure:
let mut vec = Vec::new();
library_function(|id, value| {
vec.push(value);
id
});
The equivalent of your Python code would be:
fn callback(vec: &mut Vec<u32>, id: u32, value: u32) -> u32 {
vec.push(value);
id
}
fn main(){
let mut predefined = Vec::new();
library_function(|id, value| callback(&mut predefined, id, value));
}
The reason we call them closures is because they "close over" their environment. This allows us to use (and in this case modify) variables that are in the scope in which the closure is defined.
See:
Closures: Anonymous Functions that Can Capture Their Environment in the Rust Book.
I have such a environment to start from:
(defn field-name "blah")
(defn obj (js* "{
list: [1,2,3,4,5],
blah: \"vtha\",
o: { answer: 42 }
}")
How do I get (idiomatic way) blah field using field name var?
(aget obj field-name)
works, but it is intended for arrays (docs say)
You can use goog.object/get and I think this is idiomatic way to access the properties.
I would also recommend binaryage/cljs-oops that is addressing this very problem.
Is it possible to take an FSharp function and convert it to a Dynamic function, alternatively is something like this coming to FSharp in the future?
let func (a:int) (b:int) : int =
a + b
let dynamicFunc = FSharpFunc.ToDynamicFunc(func)
let argumentList = [1; 2]
let object = dynamicFunc argumentList
let result = object :?> int
It appears that you currently have to fall back to standard reflection (like this: calling a F# function by name) however, this approach seems very brittle. Mainly because there's no real guarantee it works, and you have to know what's going on under the covers.
Something like this could be used to wrap any function and do things dynamically.
let wrapFun (x:'f) : 'f =
let args = FSharp.Reflection.FSharpType.GetFunctionElements <| x.GetType()
let runner (any:obj list) : obj =
// Do extra things
FSharpFunc.DynamicInvoke x
FSharp.Reflection.FSharpValue.MakeFunction (typeof<'f>, runner) :?> 'f
F# does support the dynamic call operator. But you must implement yours. Here is a sample Implementation taken from http://www.fssnip.net/2U/title/Dynamic-operator-using-Dynamic-Language-Runtime
// Reference C# implementation of dynamic operations
#r "Microsoft.CSharp.dll"
open System
open System.Runtime.CompilerServices
open Microsoft.CSharp.RuntimeBinder
// Simple implementation of ? operator that works for instance
// method calls that take a single argument and return some result
let (?) (inst:obj) name (arg:'T) : 'R =
// TODO: For efficient implementation, consider caching of call sites
// Create dynamic call site for converting result to type 'R
let convertSite =
CallSite<Func<CallSite, Object, 'R>>.Create
(Binder.Convert(CSharpBinderFlags.None, typeof<'R>, null))
// Create call site for performing call to method with the given
// name and a single parameter of type 'T
let callSite =
CallSite<Func<CallSite, Object, 'T, Object>>.Create
(Binder.InvokeMember
( CSharpBinderFlags.None, name, null, null,
[| CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null);
CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null) |]))
// Run the method call using second call site and then
// convert the result to the specified type using first call site
convertSite.Target.Invoke
(convertSite, callSite.Target.Invoke(callSite, inst, arg))
You'd be able to use it as follows
// Dynamically invoke 'Next' method of 'Random' type
let o = box (new Random())
let a : int = o?Next(10)
As for the params you'd have to pass them as a Tuple something like
target?method(param1, param2) that would mean that the target method processes its argument as a Tuple and as such, some pattern matching may or may not be involved
It is my first day of learning F#. I am going through tryfsharp.org when I came across following example for topic Functions as Values
let chrisTest test =
test "Chris"
let isMe x =
if x = "Chris" then
"it is Chris!"
else
"it's someone else"
chrisTest isMe
Explanation on the site:-
chrisTest is a simple higher order function that executes a test against a string value. The isMe function checks to see if a string is equal to "Chris". Passing isChris to chrisTest passes the string "Chris" as an argument to the `isChris" function, and returns the result of "it is Chris!".
My thought:- Value of isMe function is passed to function chrisTest in the last line of program. However what I do not get is there is no value passed to isMe function. How does isMe function decide to execute what value to return?
For this case we can start by replacing everything in christest. Then you have
chrisTest isMe = isme "Chris" (as test=isme)
and then the rest follows by a similar procedure
Why don't you feed it into F# interactive so you can look at the types as you go:
let chrisTest test = test "Chris";;
val chrisTest : test:(string -> 'a) -> 'a
Here we have a function which we can supply another function as an argument (called test) from string -> 'a, it will call this supplied function with the argument "Chris", returning some result 'a.
let isMe x =
if x = "Chris" then
"it is Chris!"
else
"it's someone else";;
val isMe : x:string -> string
Here we have our simple name-checking function.
Notice that this isMe function is suitable to be supplied as an argument to the christTest function. Notice also that if the argument we supply chrisTest with is of type string -> string, we are going to get a string result. Hopefully you can see here how you can use the type signatures to help you reason about the behaviour of your program.
So, when we supply isMe as an argument to chrisTest, the chrisTest function runs the isMe function with the argument "Chris", returning the result "it is Chris!".
I want to suppress warning. But the following code does not suppress warnings.
import rpy2.robjects as robjects
kstest=robjects.r['ks.test']
suppressWarnings=robjects.r['suppressWarnings']
x=robjects.IntVector([1, 2, 3])
y=robjects.IntVector([1, 2, 4, 5])
result=suppressWarnings(kstest(x, y))
print result
print result[1][0]
If I can construct a function like in rpy2 and call the function instead, I think that the warning can be suppressed.
f=function(x, y) {
suppressWarnings(kstest(x, y))
}
But I don't find examples in rpy2 document. Does anybody have some examples?
When doing in rpy2 suppressWarnings(kstest(x, y)), the call kstest(x, y) is first evaluated (and is generating warnings), then the result returned is passed to suppressWarnings().
What is happening is that R's suppressWarning() silences warnings generated by the call passed as an argument. This is possible because in R the parameters are only evaluated when they are needed in the body of the function; a notable difference with Python.
The way to mimic that with rpy2 would be to construct an unevaluated call an pass it to suppressWarning(), or as you suggest push the call to R and create an R function that will wrap the call. The documentation shows how to evaluate a string as R code, with an example with a function.