How to call a function (requiring args) with string name - Clojurescript | d3 - d3.js

I'm trying to do some refactoring on a function (set-attr) that calls a function (.attr) on a d3 object (node). I want to be able to decouple the object function (.attr) from set-attr.
But I keep getting this error Cannot read property 'each' of null.
I'm hoping someone has experience with d3 interop in Cljs and knows of something that can work, because it works fine on regular js objects.
Function that works
(defn set-attr [node [attr settr]]
(.attr node attr settr))
What I think should work (but gives me the error)
(defn set-attr [node [attr settr]]
((aget node "attr") attr settr))
Works fine on a regular js object
((aget (clj->js {:foo (fn [x y] (str "hi" x y))}) "foo" ) "ryan" "lol")
;; => "hiryanlol"

d3 uses inheritance. Thus you cannot process this object as a mere hash-table. You have to reach to its prototype to get what you want, which is usually not a good idea: this would produce rather brittle code.

Related

Inside a function, how do I construct a new function based on original function parameters, in order to pass as an argument to another function

I'm having trouble with function declarations and scope in julia. I have a main function, let's call it mainfunc which accepts some arguments. Within this function, I would ultimately like to call a different function, say callfunc, which takes a function as an argument. This function I will call passfunc.
One further complication I have is that there is a final function which I define outside of the logic which depends on the arguments but still depends on the arguments in a different way. I can call this initfunc. This must be composed with some other function, depending on the arguments, to create passfunc.
Based on the arguments given to mainfunc, I will have different definitions of passfunc. Given the answer I got to a related question here, I initially tried to define my function logic in the following way, using anonymous functions which are apparently more efficient:
function mainfunc(args)
init_func = x -> funcA(x, args)
if args[1] == "foo"
anon_func = x -> func1(x, args)
elseif args[1] == "bar"
anon_func = x -> func2(x, args)
end
function passfunc(x)
return init_func(x) + anon_func(x)
end
# ... define other args...
callfunc(passfunc, other_args)
end
Defining my function in this way leads to errors in julia - apparently passfunc is an undefined variable when I run this code. Does the scope not allow the anonymous functions to be defined in the if statements? How else could I write code that achieves this?
I feel like a better understanding of functional programming principles would make the solution here obvious. Thank you in advance for any tips you can offer on improving this.
Also, I am running this with julia v0.7

Scala -> Ruby conversion: Confusing output

Ruby Code:
def fnAdd(x)
return ->(y) { x + y }
end
add1 = 1.method(:fnAdd)
puts add1.call(10)
Output: Proc:0x007f52658d3330#main.rb:2 (lambda)
I am having issues getting the desired output in the above code.
I'm basically trying to write the following Scala code (which calls a function that returns another function) in Ruby.
Scala Code:
def fnAdd (x:Int) = {
(y:Int) => x + y
}
var add1 = fnAdd (1)
var add2 = fnAdd (2)
println(add1(10))
println(add2(3))
Output: 11 5
I've made an attempt at converting the code to Ruby but I'm not sure if it is correct. I don't understand the output, which appears to be some kind of proc object.
Could someone please explain what I need to change to get the desired output?
I'm not sure how your first example is even running, as it produces a NameError on my machine. Regardless, #method is intended for accessing methods on specific objects. You've defined a standalone method which is already curried, not one inside of the Fixnum class. So you simply need to call it as a method.
add1 = fnAdd(1)
Also, Ruby has the same behavior as Scala with regard to returning the last expression in a method, so you don't need to use return in this case.
Edit:
Thanks to #JörgWMittag for pointing out a few flaws here. Defining #fnAdd at the top-level makes it a private instance method on Object. Since everything in Ruby is an object, Fixnum inherits from the Object class. Thus, 1.method(:fnAdd) is simply giving you the fnAdd method without actually passing it any arguments. Thus, it still expects to be called twice.
fnAddMethod = 1.method(:fnAdd)
add1 = fnAddMethod.call(1)
puts add1.call(10)
However, this would be extremely unidiomatic, so it's best to stick with the simpler solution.

Why the need to call resolve()?

I am looking at an example of Reason at A First Reason React app for Javascript developers
And I see that he is calling Js.Promise.resolve when using bs-fetch:
RepoData.fetchRepos()
|> Js.Promise.then_(repoData => {
handleReposLoaded(repoData);
Js.Promise.resolve();
})
|> ignore;
I have seen similar code in BuckleScript code as well. For example in Bucklescript Cookbook:
Js.Promise.(
Fetch.fetch "https://api.github.com/users/reasonml-community/repos"
|> then_ Fetch.Response.text
|> then_ (fun text ->
text
|> names
|> Array.iter Js.log
|> resolve)
|> ignore
In JS we usually call resolve when we create a new promise, not when using a function that returns a promise. So why do we need to call resolve in the cases above?
Js.Promise.then_ requires that a new promise is returned.
The reason is that es6 promises aren't soundly typed. The value returned in a then callback is dynamically either wrapped or (infinitely) flattened so that it always returns a promise, and never a nested promise. That means if we allow any value to be returned (let then_: ((_ => 'a), Js.Promise.t(_)) => Js.Promise.t('a)), and if that value is a promise ('a = Js.Promise.t('b)), it would have the return type Js.Promise.t(Js.Promise.t('b)), but the value returned will actually have been flattened to just a Js.Promise.t('b).
Having then_ accept only a promise from the callback alleviates this a bit by making it more obvious that you return a nested promise. It's still possible to resolve a promise however, so the type is still not sound, but it makes it a little bit harder to shoot yourself in the foot.
There will be a sound and elegant promise API in the (probably near) future, but since it's a non-trivial task to design and implement it'll take a bit of time to get it right.

How can I sort child nodes by property value in Scala.js?

The problem is to sort all child divs of a root node according to their top CSS property.
Here is my code:
val elements = global.document.getElementById("root").childNodes.asInstanceOf[dom.NodeList]
val clones = (for (i <- (0 to (elements.length - 1)) if (elements(i).isInstanceOf[dom.raw.HTMLDivElement])) yield {
val clone = elements(i).cloneNode(true)
val style = clone.attributes.getNamedItem("style").value
val parts = style.split("top: ")
val parts2 = parts(1).split("px")
val px = parts2(0).toDouble
Tuple2[dom.Node, Double](clone, px)
}).toList
val sorted = clones.sortWith((a, b) => a._2 > b._2)
global.document.getElementById("root").innerHTML = ""
for (e <- sorted) {
global.document.getElementById("root").appendChild(e._1)
}
I'm new to Scala.js and it took quite an effort to come up with this solution. It compiles and seems to work, however I'm not sure how legitimate it is.
For example I can only get the top property of the node in a very complicated way. Also I suspect that for deleting all child nodes global.document.getElementById("root").innerHTML = "" is a backdoor way. I'm not sure if this sorting can be done in place without creating clones. I welcome any suggestions for improvement and I hope that some beginner out there may find even this code useful.
Various suggestions, some pertaining to Scala and some to the underlying browser environment:
First, jQuery (actual JavaScript library) (Scala.js facade) is your friend. Trying to do anything with the raw DOM is a pain in the ass, and I don't recommend it for anything but the simplest toy applications. (This has nothing to do with Scala.js, mind -- that's just the reality of working in the browser, and is all true of JavaScript as well.)
Using jQuery, getting the elements is just:
val elements = $("root").children
Second, essentially nobody loops using indexes in Scala like that -- it's legal, but extremely rare. Instead, you get each element directly in the for. And you can stick the value assignments right into the for itself, keeping the yield clause clean.
jQuery lets you get at CSS properties directly. (Although I think you still have to parse out the "px".) Again, everything is much harder if you try to use the raw DOM functions.
And it's very rare to spell out Tuple2 -- you just use parens for a tuple. Putting it all together, it would look something like this:
for {
element <- elements
if (element.isInstanceOf[dom.raw.HTMLDivElement])
clone = element.clone()
top = clone.css("top")
px = top.dropRight(2).toDouble
}
yield (clone, px)
Mind, I haven't actually tried out the above code -- there are probably some bugs -- but that's more like what idiomatic Scala.js + jQuery code would look like, and is worth considering as a starting point.

Liftable for function literal

Is there a way to make a Liftable for a functional literal (with 2.11)? If I have
case class Validator[T](predicate: T => Boolean)
val predicate = (s: String) => s.startsWith("Hi")
then I want to be able to quasiquote predicate too:
q"new Validator($predicate)"
I hoped to magically create a Liftable with an underscore. But that was a little too optimistic:
implicit def liftPredicate[T: Liftable](f: T => Boolean) =
Liftable[T => Boolean]{ f => q"$f(_)" }
I couldn't figure out from looking at StandardLiftables how I could solve this one.
Another way of looking at it:
Say I want to create instances from the following class at compile time with a macro:
abstract class ClassWithValidation {
val predicate: String => Boolean
def validate(s: String) = predicate(s)
}
and I retrieve a functional literal from somewhere else as a variable value:
val predicate = (s: String) => s.startsWith("Hi")
Then I want to simply quasiquote that variable into the construction:
q"""new ClassWithValidation {
val predicate = $predicate
// other stuff...
}"""
But it gives me this error:
Error:(46, 28) Can't unquote String => Boolean, consider providing an
implicit instance of Liftable[String => Boolean]
Normally I can just make such implicit Liftable for a custom type. But I haven't found a way doing the same for a functional literal. Is there a way to do this or do I need to look at it another way?
From what I understand, you're trying to go from a function to an abstract syntax tree that represents its source code (so that it can be spliced into a macro expansion). This is a frequent thing that people request (e.g. it comes up often in DSLs), but there's no straightforward way of achieving that in our current macro system.
What you can do about this at the moment is to save the AST explicitly when declaring a function and then load and use it in your macro. The most convenient way of doing this is via another macro: https://gist.github.com/xeno-by/4542402. One could also imagine writing a macro annotation that would work along the same lines.
In Project Palladium, there is a plan to save typechecked trees for every program being compiled. This means that there will most likely be a straightforward API, e.g. treeOf(predicate) that would automatically return abstract syntax tree comprising the source of the predicate. But that's definitely not something set in stone - we'll see how it goes, and I'll report back on the progress during this year's ScalaDays.

Resources