Why does clojurescript call some js functions with "-" and others not? - clojurescript

Some functions in clojurescript start with a hyphen - like .-onload injs/window context or .-fillstyle in canvas context while others like .getElementById do not start with a -hyphen. Why is this peculiarity? What am i missing here?

I do believe the .- signifies that you’re accessing a property. Read more about js-interop here http://www.spacjer.com/blog/2014/09/12/clojurescript-javascript-interop

Related

ClojureScript Eval. How to use libraries included in the calling code

I have a Clojurescript program running in the browser.
It imports a number of libraries, and then I want to allow the user to enter some small clojurescript "glue-code" that calls those libraries.
I can see (from https://cljs.github.io/api/cljs.js/eval) that you call eval with four arguments, the first being the state of the environment, which is an atom. But can I actually turn my current environment with all the functions I've required from elsewhere, into an appropriate argument to eval?
Update :
I thought that maybe I could set the namesspace for the eval using the :ns option of the third, opts-map, argument. I set it to the namespace of my application :
:ns "fig-pat.core"
But no difference.
Looking at the console, it's definitely the case that it's trying to do the evaluation, but it's complaining that names referenced in the eval-ed code are NOT recognised :
WARNING: Use of undeclared Var /square
for example. (square is a function I'm requiring. It's visible in the application itself ie. the fig-pat.core namespace)
I then get :
SyntaxError: expected expression, got '.'[Learn More]
Which I'm assuming this the failure of eval-ed expression as a whole.
Update 2 :
I'm guessing this problem might actually be related to : How can I get the Clojurescript namespace I am in from within a clojurescript program?
(println *ns*)
is just printing nil. So maybe Clojurescript can't see its own namespace.
And therefore the :ns in eval doesn't work?
Calling eval inside a clojurescript program is part of what is called "self-hosted clojurescript".
In self-hosted clojurescript, namespaces are not available unless you implement a resolve policy. It means that have to let the browser know how to resolve the namespace e.g. loads a cljs file from a cdn.
It's not so trivial to implement namespace resolving properly.
This is explained in a cryptic way in the docstring of load-fn from cljs.js namespace.
Several tools support namespaces resolving in self-host cljs running in the browser e.g Klipse and crepl

Clojurescript Add an Event Listener

(defn domready [handler]
(.addEventListener js/window "DOMContentLoaded" handler))
I borrowed this code from here. The problem is I don't totally understand what's going on. JS interop is still a bit of a mystery to me.
.addEventListener
So this is clearly a procedure call, but it's kind of generic. It's like Clojurescript took everything that was inside an object, took it out, and you use it to call that method on "objects". As long as that "object" has the ".addEventListener" property it will call this. Is that what it's doing? Why not use a keyword instead? like (:addEventListener domElement) that seems more logical to me.
js/window
What is this? Is it a namespace or an object? Are they the same thing?
"DOMContentLoaded"
A string, that's familiar.
handler
Also familiar, but does it have a notion of this? Not that I'm really going to miss this.
.addEventListener
So this is clearly a procedure call, but it's kind
of generic. It's like Clojurescript took everything that was inside an
object, took it out, and you use it to call that method on "objects".
As long as that "object" has the ".addEventListener" property it will
call this. Is that what it's doing? Why not use a keyword instead?
like (:addEventListener domElement) that seems more logical to me.
Your mental model about how this works is mostly fine. What it does when it compiles is move the function name to be run as a method on the first argument.
(.method obj ...args) get's transformed to obj.method(...args)
This type of interop comes from the parent language Clojure.
On why do we have an explicit version of calling the function that's not Clojure idiomatic, I think the idea is to have clear separation between what is native Clojure code with Clojure semantics (immutability, friendly to CLJ data structures, etc) and what is interoperating with the host environment (mutable, not friendly to CLJ data structures, etc).
In my opinion it is better to have clear separation between those two given how different the semantics of CLJS and the host platforms are. For me explicitness is better than implicit in this case (it is easy to spot looking at the code what is JS code in CLJS, and what is pure CLJS).
js/window
What is this? Is it a namespace or an object? Are they the same thing?
Both, js/ is accessing the namespace js, which is where CLJS puts the JS namespace (since there is only one and global). window is just grabbing the window variable from the js namespace.
This is no different from how you access variables in other namespaces in CLJS. If you (def a 1) in (ns cljs.test) and then run cljs.test/a that will give you 1. Same form, ns/something-in-that-ns.
"DOMContentLoaded"
A string, that's familiar.
\o/
handler
Also familiar, but does it have a notion of this? Not that I'm really going to miss this.
Not sure what this has to do with handler. It is just a higher order function passed into domready as a parameter, like you would do in JS: function domready (onReady) { window.addEventListener("DOMContentLoaded", onReady) }
I hope this helps, if you want to try it out live and learn some more, maybe visit the Talking with JS on the Diving into ClojureScript tutorial, or maybe check this section of the lt-cljs-tutorial.
I'm just learning clojurescript so I don't really know if it is the correct answer but I've done it in the following way:
(defn handler [] (js/console.log "ready"))
(js/document.addEventListener "DOMContentLoaded" handler)
which is then translated to
cljs.user.handler = (function cljs$user$handler(){
return console.log("ready");
});
document.addEventListener("DOMContentLoaded",cljs.user.handler);
to check how clojurescript translate code I've used KLIMPSE http://app.klipse.tech/
.addEventListener is a method call on the global Javascript object js/window. This method call takes two parameters: "DOMContentLoaded" and handler.
When you are doing interop (either Java or Javascript) you really are calling methods on objects. There are macros behind what is happening here. What is straight after the ( is a verb, which I usually think of as a function call (although it might also be a macro or a special form). When doing interop what comes after the verb is the instance, and after that the parameters.
If it were straight Javascript it would look like this:
function domready(handler){
window.addEventListener("DOMContentLoaded" handler);
}

Instantiate namespaced javascript class

I want to use google maps api v3, and it needs me to instantiate google.maps.LatLng. Using clojurescript this is what I do:
(ns foocljs.core)
(LatLng. (.-maps js/google) 100 100)
I got an error undefined is not a function, this is the culprit:
new foocljs.core.LatLng(foocljs.core.google.maps, // ... another args
I'm guessing this is because the compiler think that LatLng. is clojure namespaced class. How to deal with this? Thanks.
Using js/a.b.c.d is a bad practice and is likely to break in future versions of the compiler (because it is not a clojure compatible version of interop from what I know)
The good way would be:
(def LatLng (.. js/google -maps -LatLng))
(LatLng. 100 100)
Silly me, I can just do this:
(js/google.maps.LatLng. 100 100)

How do we wrap C++ variable argument parameter in WinRT components

I have a C++ method that takes variable argument as init param. Something like
MyMethod(std::wchar_t*, ...)
Can someone please let me know how can we write a WinRT component wrapper to expose the variable arguments?
WinRT metadata does not support vararg functions, so there is no good way to do this. The answer therefore depends on what the function actually does. Assuming it is some kind of string formatting function I would suggest wrapping it with something like:-
MyMethod(Platform::String^, Windows::Foundation::Collections::IVector<Platform::Object^>^ params);
This will allow you to take the variable arguments.
The problem of course is that this has completely different semantics from what you have. The caller is going to have to pack up an array, and you won't be able to call your existing method easily with the arguments from the vector.

Unable to use a matlab function

I wanted to move from one point to other on a spherical earth, and when I looked up, I found there is a function named reckon in matlab that does exactly what I need. But when I call it, it says Undefined function 'reckon' for input arguments of type 'double. Which means that maybe the function is not in my library. So I found the m-file from the internet and tried, but then it leads to same error with a different function, which I found the function reckon depends on. So I included that in my folder too, and then again there is a new function missing... and so on.
I have Matlab R2011b.
These functions seem to be in-built matlab functions as they show up in help, but as I'm new to matlab, maybe I'm wrong. What can be done?
As i just wanted to use the functions of the Mapping Toolbox,after some looking up, i found them all in a single package on a website. If any body else wants them too, and don't have the mapping toolbox, you can get all the functions here.
http://mooring.ucsd.edu/software/matlab/doc/toolbox/geo/index.html