debugging functions in the clojurescript repl - clojurescript

Does anybody know a good way to debug functions in the clojureScript REPL?
The default, behavior is that the generated JS code of the function is printed.
midi.lib=> (defn f [] (println "hello"))
#'midi.lib/f
midi.lib=> f
#object[midi$lib$f "function midi$lib$f(){
return cljs.core.println.call(null,"hello");
}"]
With longer functions this gets annoying. For many debugging cases, simply the name of the function would be sufficient..

There is currently no support for controlling how function values print in ClojureScript.
But, if you are OK with extending the JavaScript function type, you can evaluate the following in a REPL
(extend-type js/Function
IPrintWithWriter
(-pr-writer [obj writer _]
(let [name (.-name obj)
name (if (empty? name)
"Function"
name)]
(write-all writer "#object[" name "]"))))
and then your example function value would print as #object[midi$lib$f].

Try using the Figwheel REPL, it doesn't print out the generated JS, and behaves similarly to a Clojure REPL.

Related

Compile ClojureScript in Java application

I'm trying to compile String that contains Clojure Script code in Java/Groovy. I'm not really happy with using "java -jar ...".execute().
Is there any way to invoke clojurescript library (version 1.8.51) to compile code?
Edit:
So combining these two links I got this code (Groovy):
IFn require = Clojure.var("clojure.core", "require");
require.invoke(Clojure.read("cljs.analyzer.api"))
require.invoke(Clojure.read("cljs.compiler.api"))
IFn emptyEnv = Clojure.var("cljs.analyzer.api", "empty-env")
IFn analyze = Clojure.var("cljs.analyzer.api", "analyze")
IFn emit = Clojure.var("cljs.compiler", "emit-str")
final inputText = "(defn plus [a b] (+ a b))"
emit.invoke(
analyze.invoke(emptyEnv.invoke(), "'$inputText"
)
)
My problem is that emit function return empty string :/. Is there anything I'm doing wrong?
Edit2: The analyze method return this:
{
:op :constant,
:env {:ns {:name cljs.user},
:context :statement,
:locals {},
:fn-scope [],
:js-globals ...removed...,
:form #object[org.codehaus.groovy.runtime.GStringImpl 0x37816ea6 "'(defn plus [a b] (+ a b))"],
:tag any
}
It should be very easy to call ClojureScript Compiler API from Clojure, for example as presented in answers to a similar question on how to do it from Clojure.
But as you want to do it from Java or Groovy, you will have to use some Clojure Java API for calling Clojure from Java.

Why the strong difference between closures and functions in Rust and how to work around it?

I just ran into a problem with how Rust handles closures.
Let's assume I'm a library author and have written this method
fn get(&mut self, handler: fn() -> &str){
//do something with handler
}
Now if a user wants to call this method like this
let foo = "str";
server.get(|| -> &str { foo });
It won't work because Rust, according to it's documentation makes a strong difference between regular functions and closures.
Do I as a library author always have to make such methods accept closures instead of regular functions to not restrict library users too much?
Also it seems to me as if closures are the only way to write anonymous functions or am I mistaken?
Currently, fn() types can be automatically "promoted" to || types. (A closure with an empty environment, I suppose.) For example, this works:
fn get(handler: || -> &str) -> &str {
handler()
}
fn main() {
fn handler_fn() -> &str { "handler_fn" }
let handler_cl = || -> &str "handler_cl";
println!("{}", get(handler_fn));
println!("{}", get(handler_cl));
}
So if your library function get doesn't care whether handler is a closure or not, then it seems reasonable to just accept closures for maximum flexibility. But this isn't always possible. For example, if you wanted to execute handler in another task, then I believe it must be a fn or a proc type. (I'm not 100% certain here---I may be missing a detail.)
With regard to anonymous functions, yes, a || or a proc closure are the only two ways to write anonymous functions.

For unit tests written in F# with mstest in vs2012, how do I assert that an exception is raised?

I'm writing unit tests in F# using MSTest, and I'd like to write tests that assert that an exception is raised. The two methods that I can find for doing this are either (1) write the tests in C# or (2) don't use MSTest, or add another test package, like xunit, on top of it. Neither of these is an option for me. The only thing I can find on this is in the MSDN docs, but that omits F# examples.
Using F# and MSTest, how do I assert that a particular call raises a particular exception?
MSTest has an ExpectedExceptionAttribute that can be used, but it is a less than ideal way to test an exception has been thrown because it doesn't let you assert the specific call that should throw. If any method in the test method throws the expected exception type, then the test passes. This can be bad with commonly used exception types like InvalidOperationException. I use MSTest a lot and we have a Throws helper method for this in our own AssertHelper class (in C#). F# will let you put it into an Assert module so that it appears with all the other Assert methods in intellisense, which is pretty cool:
namespace FSharpTestSpike
open System
open Microsoft.VisualStudio.TestTools.UnitTesting
module Assert =
let Throws<'a> f =
let mutable wasThrown = false
try
f()
with
| ex -> Assert.AreEqual(ex.GetType(), typedefof<'a>, (sprintf "Actual Exception: %A" ex)); wasThrown <- true
Assert.IsTrue(wasThrown, "No exception thrown")
[<TestClass>]
type MyTestClass() =
[<TestMethod>]
member this.``Expects an exception and thrown``() =
Assert.Throws<InvalidOperationException> (fun () -> InvalidOperationException() |> raise)
[<TestMethod>]
member this.``Expects an exception and not thrown``() =
Assert.Throws<InvalidOperationException> (fun () -> ())
[<TestMethod>]
member this.``Expects an InvalidOperationException and a different one is thrown``() =
Assert.Throws<InvalidOperationException> (fun () -> Exception("BOOM!") |> raise)
Like this?
namespace Tests
open Microsoft.VisualStudio.TestTools.UnitTesting
open System
[<TestClass>]
type SomeTests () =
[<TestMethod; ExpectedException (typeof<InvalidOperationException>)>]
member this.``Test that expects InvalidOperationException`` () =
InvalidOperationException () |> raise |> ignore

How to load-string to current namespace (not core)?

I can load arbitrary Clojure source using:
(load-string source)
However, if namespace wasn't provided, it loads code to clojure.core namespace.
For example, following code:
(load-string "(defn add [a b] (+ a b))")
defines a function:
#'clojure.core/add
Now, is there a way to load that code to some other namespace, preferably the same one in which load-string function is called?
(Other than prepending a namespace declaration to source string before evaluation. I know that it would solve the problem - I'd like to know is there a preferred way)
when def needs to decide what namspace a new function should go in it looks at the the current value of the ns var and adds the new function to that namespace. because ns is a var you can dynamically bind it before you call load-string
user> (binding [*ns* (find-ns 'foo)] (load-string "(defn f [] 4)"))
#'foo/f
user> (foo/f)
4

Setting DataLoadOptions for DataContext in F#

Is it possible to set the DataLoadOptions on a data context in F#? So far I have had no luck because the DataLoadOptions.LoadWith() takes a System.Linq.Expressions.LambdaExpression which seems impossible to instantiate in F#
I believe this should be possible. You'll need to reference FSharp.PowerPack.Linq.dll which adds support for translating F# quotations (written using <# fun x -> x.Foo #>) to C# expression trees. Something like this should do the trick:
#r #"FSharp.PowerPack.Linq.dll"
open System
open System.Linq.Expressions
open Microsoft.FSharp.Linq.QuotationEvaluation
let e = <# Func<int, int>(fun x -> 1 + x) #>
let lambda = e.ToLinqExpression() :?> LambdaExpression
Note that the quotation creates a Func<...> delegate, which is translated to expression tree that can be converted to LambdaExpression (normal F# functions are represented differently).