Scala.js native Javascript constructors - scala

Scala.js facade for a native JS types can look like this (from Three.js facade):
#js.native
#JSName("THREE.Vector3")
class Vector3 extends Vector {
def this(x: Double = js.native, y: Double = js.native, z: Double = js.native) = this()
var x: Double = js.native
var y: Double = js.native
var z: Double = js.native
/* ... */
}
The corresponding Javascript definition of a function constructing Vector3 is:
function Vector3( x, y, z ) {
this.x = x || 0;
this.y = y || 0;
this.z = z || 0;
}
I have read docs about creating Scala.js facades, however constructors are only briefly mentioned there. The code from the facade works fine in real code, however I am unsure if the definition is correct and why and how it works.
the facade lets no argument constructor exist.
the constructor with arguments just calls a no argument constructor. Still the object seems to be constructed fine, with the member set to the values passed.
the constructor uses js.native as default value for all arguments. Should all facades define constructors this way?
Esp. the second point is confusing to me. How can this be working? In all three cases I would like to know what JS code is generated for the constructor and why.
One could also imagine a different way how to write the facade. Would that be more correct?
class Vector3(var x: Double = js.native, var y: Double = js.native, var z: Double = js.native) extends Vector {
/* ... */
}

The definition is correct. The rules of facades for JavaScript constructors are quite simply stated: when encountering a call such as
new C(arg1, ..., argN)
and C is a JavaScript class, this translates to
new Cconstr(arg1, ..., argN)
where Cconstr is the result of evaluating js.constructorOf[C]. For a native JavaScript class, js.constructorOf[C] looks up the name of C in the global scope (or applies #JSName or #JSImport rules). Concretely, in your example, a call such as
new Vector3(3, 4, 5)
translates to
new <global>.THREE.Vector3(3, 4, 5)
Note, in particular, that the body of the constructor definitions is completely irrelevant, since the call site directly calls JavaScript code in the Three.js library. Hence, the fact that the 3-arg constructor calls the 0-arg constructor and ignores its arguments is simply disregarded by the semantic rules. The call is necessary to comply with Scala's type checking rules, but is semantically irrelevant.
Similarly, the actual value of default parameter values are semantically irrelevant. Their presence makes the parameters optional, but their value is otherwise ignored by the compiler. A call such as
new Vector3(3)
translates in JavaScript to
new <global>.THREE.Vector3(3)
in which the y and z parameters are altogether not given, leaving to JavaScript to decide what to do with them.
Finally, your alternative definition:
class Vector3(var x: Double = js.native, var y: Double = js.native, var z: Double = js.native)
is just equally valid. It doesn't have an explicit 0-arg constructor, but it can also be "accessed" by giving 0 argument to the constructor, which has 3 optional parameters anyway. This definition is certainly more concise, though, and looks a bit more Scala-esque, so I would personally define it that way. But it is not any more correct than the initial one.

Related

How can I combine this context with invokeFunction in Nashorn?

I am trying to call a function in Javascript from Java/Nashorn (in Scala, but that's not material to the question).
// JS
var foo = function(calculator){ // calculator is a Scala object
return this.num * calculator.calcMult();
}
The context on the Scala side is like this:
case class Thing(
num: Int,
stuff: String
)
case class Worker() { // Scala object to bind to calculator
def calMult() = { 3 } // presumably some complex computation here
}
I start by getting foo into the JS environment:
jsengine.eval("""var foo = function(calculator){return this.num * calculator.calcMult();}"""
To use this I need two things to be available: 1) 'this' context to be populated with my Thing object, and 2) the ability to pass a Java/Scala object to my JS function (to call calcMulti later). (If needed I can easily JSON-serialize Thing.)
How can I do both and successfully call foo() from Scala?
This may not be the only or cleanest solution, but it does work.
Turns out javascript has the ability to bind a given 'this' context to a function, which creates a "bound function" that has your 'this' visible within it. Then you use invoke() as you normally would on the bound function.
val inv = javascript.asInstanceOf[Invocable]
val myThis: String = // JSON serialized Map of stuff you want accessible in the js function
val bindFn = "bind_" + fnName
javascript.eval(bindFn + s" = $fnName.bind(" + myThis + ")")
inv.invokeFunction(bindFn, args: _*)
If you passed myThis into the binding to include {"x":"foo"} then when invoked, any access within your function to this.x will resolve to "foo" as you'd expect.

Why are auxilary constructors forced to call the main constructor in Scala?

... and supply it with all necessary arguments even if they where not required for the auxiliary constructor. (Source: http://joelabrahamsson.com/learning-scala-part-four-classes-and-constructors/) This is not the case in Java. What is the reasoning behind that?
In Scala, the primary constructor's parameters are available anywhere inside the class (among other reasons, so you don't have to repeat Java's this.x = x; this.y = y; this.z = z;). If the parameter isn't used, it has no reason to be a parameter in the first place, so consider only the case where it is used. So if you could avoid supplying these parameters, and then got to the place where they are used, what should happen?
The compiler could use default values (null/0/false/etc), which is very likely not what the user wants. Or throw an exception, turning a compilation error into a runtime error, which is the opposite of what we want.
Easy: if a parameter is not required, don't add it to the main constructor.
In java, all constructors also execute the code in the body of the class:
public class Foo {
String x = mkX();
public Foo() { System.out.println("THIS"); }
public static String mkX() { System.out.println("THAT"); return "";}
}
new Foo(); // prints THAT, then THIS
The requirement in scala is actually more relaxed: your main constructor is allowed to have arguments.

Can I dynamically construct a trait in Scala that is computed based on the class it extends?

I want to accomplish something a little different from standard mixins. I want to construct a trait whose new fields are computed based on the fields of the class (or trait) it extends.
For instance, if I had a class like this:
class Point {
var x: Int = 0
var y: Int = 0
}
and I wanted to produce a class like this:
class Point' {
var x: Int = 0
var y: Int = 0
var myx: Int = 0
var myy: Int = 0
}
I'd like to be able to write a function that computes the field names myx and myy and then mixes them into the class using a trait. Here's some made up psuedo-Scala for what I want to do:
def addMy(cls: Class) {
newFields = cls.fields.map( f => createField("my" + f.name, f.type) )
myTrait = createTrait(newFields)
extendClass(cls, myTrait)
}
The easiest way I can think of to achieve such a behavior would be to use Scala 2.10's Dynamic feature. Thus, Point must extend Dynamic and you can "mix in" arbitrary fields by adding the calculation logic to the member functions selectDynamic and updateDynamic. This is not quite what "mix in" actually refers to, but it nevertheless allows you to add functionality dynamically.
To ensure that it is possible to check whether a specific functionality has been mixed in, you can for instance use the following convention. In order to check whether a field is mixed in, a user can call hasMyx or has... in general. By default your implementation returns false. Each time you mix in a new field the corresponding has... function would return true.
Please note that the return type of all your mixed in fields will be Any (unless all your fields are of the same type, see for instance this question). I currently see no way to avoid a lot of casting with this design.

What is the apply function in Scala?

I never understood it from the contrived unmarshalling and verbing nouns ( an AddTwo class has an apply that adds two!) examples.
I understand that it's syntactic sugar, so (I deduced from context) it must have been designed to make some code more intuitive.
What meaning does a class with an apply function give? What is it used for, and what purposes does it make code better (unmarshalling, verbing nouns etc)?
how does it help when used in a companion object?
Mathematicians have their own little funny ways, so instead of saying "then we call function f passing it x as a parameter" as we programmers would say, they talk about "applying function f to its argument x".
In mathematics and computer science, Apply is a function that applies
functions to arguments.
Wikipedia
apply serves the purpose of closing the gap between Object-Oriented and Functional paradigms in Scala. Every function in Scala can be represented as an object. Every function also has an OO type: for instance, a function that takes an Int parameter and returns an Int will have OO type of Function1[Int,Int].
// define a function in scala
(x:Int) => x + 1
// assign an object representing the function to a variable
val f = (x:Int) => x + 1
Since everything is an object in Scala f can now be treated as a reference to Function1[Int,Int] object. For example, we can call toString method inherited from Any, that would have been impossible for a pure function, because functions don't have methods:
f.toString
Or we could define another Function1[Int,Int] object by calling compose method on f and chaining two different functions together:
val f2 = f.compose((x:Int) => x - 1)
Now if we want to actually execute the function, or as mathematician say "apply a function to its arguments" we would call the apply method on the Function1[Int,Int] object:
f2.apply(2)
Writing f.apply(args) every time you want to execute a function represented as an object is the Object-Oriented way, but would add a lot of clutter to the code without adding much additional information and it would be nice to be able to use more standard notation, such as f(args). That's where Scala compiler steps in and whenever we have a reference f to a function object and write f (args) to apply arguments to the represented function the compiler silently expands f (args) to the object method call f.apply (args).
Every function in Scala can be treated as an object and it works the other way too - every object can be treated as a function, provided it has the apply method. Such objects can be used in the function notation:
// we will be able to use this object as a function, as well as an object
object Foo {
var y = 5
def apply (x: Int) = x + y
}
Foo (1) // using Foo object in function notation
There are many usage cases when we would want to treat an object as a function. The most common scenario is a factory pattern. Instead of adding clutter to the code using a factory method we can apply object to a set of arguments to create a new instance of an associated class:
List(1,2,3) // same as List.apply(1,2,3) but less clutter, functional notation
// the way the factory method invocation would have looked
// in other languages with OO notation - needless clutter
List.instanceOf(1,2,3)
So apply method is just a handy way of closing the gap between functions and objects in Scala.
It comes from the idea that you often want to apply something to an object. The more accurate example is the one of factories. When you have a factory, you want to apply parameter to it to create an object.
Scala guys thought that, as it occurs in many situation, it could be nice to have a shortcut to call apply. Thus when you give parameters directly to an object, it's desugared as if you pass these parameters to the apply function of that object:
class MyAdder(x: Int) {
def apply(y: Int) = x + y
}
val adder = new MyAdder(2)
val result = adder(4) // equivalent to x.apply(4)
It's often use in companion object, to provide a nice factory method for a class or a trait, here is an example:
trait A {
val x: Int
def myComplexStrategy: Int
}
object A {
def apply(x: Int): A = new MyA(x)
private class MyA(val x: Int) extends A {
val myComplexStrategy = 42
}
}
From the scala standard library, you might look at how scala.collection.Seq is implemented: Seq is a trait, thus new Seq(1, 2) won't compile but thanks to companion object and apply, you can call Seq(1, 2) and the implementation is chosen by the companion object.
Here is a small example for those who want to peruse quickly
object ApplyExample01 extends App {
class Greeter1(var message: String) {
println("A greeter-1 is being instantiated with message " + message)
}
class Greeter2 {
def apply(message: String) = {
println("A greeter-2 is being instantiated with message " + message)
}
}
val g1: Greeter1 = new Greeter1("hello")
val g2: Greeter2 = new Greeter2()
g2("world")
}
output
A greeter-1 is being instantiated with message hello
A greeter-2 is being instantiated with message world
TLDR for people comming from c++
It's just overloaded operator of ( ) parentheses
So in scala:
class X {
def apply(param1: Int, param2: Int, param3: Int) : Int = {
// Do something
}
}
Is same as this in c++:
class X {
int operator()(int param1, int param2, int param3) {
// do something
}
};
1 - Treat functions as objects.
2 - The apply method is similar to __call __ in Python, which allows you to use an instance of a given class as a function.
The apply method is what turns an object into a function. The desire is to be able to use function syntax, such as:
f(args)
But Scala has both functional and object oriented syntax. One or the other needs to be the base of the language. Scala (for a variety of reasons) chooses object oriented as the base form of the language. That means that any function syntax has to be translated into object oriented syntax.
That is where apply comes in. Any object that has the apply method can be used with the syntax:
f(args)
The scala infrastructure then translates that into
f.apply(args)
f.apply(args) has correct object oriented syntax. Doing this translation would not be possible if the object had no apply method!
In short, having the apply method in an object is what allows Scala to turn the syntax: object(args) into the syntax: object.apply(args). And object.apply(args) is in the form that can then execute.
FYI, this implies that all functions in scala are objects. And it also implies that having the apply method is what makes an object a function!
See the accepted answer for more insight into just how a function is an object, and the tricks that can be played as a result.
To put it crudely,
You can just see it as custom ()operator. If a class X has an apply() method, whenever you call X() you will be calling the apply() method.

About Scala's assignments and setter methods

Edit: The bug which prompted this question has now been fixed.
In the Scala Reference, I can read (p. 86):
The interpretation of an assignment to
a simple variable x = e depends on the
definition of x. If x denotes a
mutable variable, then the assignment
changes the current value of x to be
the result of evaluating the
expression e. The type of e is
expected to conform to the type of x.
If x is a parameterless function
defined in some template, and the same
template contains a setter function
x_= as member, then the assignment x =
e is interpreted as the invocation
x_=(e) of that setter function.
Analogously, an assignment f .x = e to
a parameterless function x is
interpreted as the invocation f.x_=(e).
So, for instance, something like this works fine:
class A {
private var _a = 0
def a = _a
def a_=(a: Int) = _a = a
}
I can then write
val a = new A
a.a = 10
But if I define the class like this, adding a type parameter to method a:
class A {
private var _a = 0
def a[T] = _a
def a_=(a: Int) = _a = a
}
then it doesn't work any more; I get an error: reassignment to val if I write a.a = 10. Funny enough, it still works with no type parameter and an implicit parameter list, for instance.
Arguably, in this example, the type parameter is not very useful, but in the design of DSLs, it would be great to have the setter method called even if the getter has type parameters (and by the way, adding type parameters on the setter is allowed and works fine).
So I have three questions:
Is there a workaround?
Should the current behavior be considered a bug?
Why does the compiler enforce a getter method to allow using the syntactic sugar for the setter?
UPDATE
Here's what I'm really trying to do. It's rather long, sorry, I meant to avoid it but I realized it was more confusing to omit it.
I'm designing GUIs with SWT in Scala, and having huge fun using Dave Orme's XScalaWT, which immensely reduces the amount of needed code. Here's an example from his blog post on how to create an SWT Composite that converts °C to °F degrees:
var fahrenheit: Text = null
var celsius: Text = null
composite(
_.setLayout(new GridLayout(2, true)),
label("Fahrenheit"),
label("Celsius"),
text(fahrenheit = _),
text(celsius = _),
button(
"Fahrenheit => Celsius",
{e : SelectionEvent => celcius.setText((5.0/9.0) * (fahrenheit - 32)) }
),
button(
"Celsius -> Fahrenheit",
{e : SelectionEvent => fahrenheit.setText((9.0/5.0) * celsius + 32) })
)
)
The argument to each of the widget-constructing methods is of type (WidgetType => Any)*, with a few useful implicit conversions, which for instance allow to directly specify a string for widgets that have a setText() method. All constructor functions are imported from a singleton object.
In the end, I'd like to be able to write something along these lines:
val fieldEditable = new WritableValue // observable value
composite(
textField(
editable <=> fieldEditable,
editable = false
),
checkbox(
caption = "Editable",
selection <=> fieldEditable
)
)
This would bind the editable property of the textfield to the selection of the checkbox through the WritableValue variable.
First: named arguments are not applicable here, so the line editable = false has to come from somewhere. So, along the widget-constructing methods in the singleton object, I could write, conceptually,
def editable_=[T <: HasEditable](value: Boolean) = (subject: T) => subject.setEditable(value)
... but this works only if the getter is also present. Great: I'd need the getter anyway in order to implement databinding with <=>. Something like this:
def editable[T <: HasEditable] = new BindingMaker((widget: T) => SWTObservables.observeEditable(widget))
If this worked, life would be good because I can then define <=> in BindingMaker and I can use this nice syntax. But alas, the type parameter on the getter breaks the setter. Hence my original question: why would this simple type parameter affect whether the compiler decides to go ahead with the syntactic sugar for calling the setter?
I hope this makes it a bit clearer now. Thanks for reading…
UPDATE Deleted the entire previous answer in light of new information.
There's a lot of very odd stuff going on here, so I'm going try try and explain my understanding of what you have so far:
def editable_=[T <: HasEditable](value: Boolean) = (subject: T) => subject.setEditable(value)
This is a setter method, and exists purely so that it can give the appearance of beinng a named parameter
in your DSL. It sets nothing and actually returns a Function.
textField(
editable <=> fieldEditable,
editable = false
)
This is calling the textField factory method, with what looks like a named param, but is actually the setter method defined previously.
Amazingly, the approach seems to work, despite my initial concern that the compiler would recognize this as a named parameter and produce a syntax error. I tested it with simple monomorphic (non-generic) methods, though it does require the getter method to be defined for the setter to be seen as such - a fact that you've already noted.
Some amount of "cleverness" is often required in writing a DSL (where it would otherwise be totally forbidden), so it's no surprise that your original intent was unclear. This is perhaps a completely new technique never before seen in Scala. The rules for setter and getter definitions were based on using them as getters and setters, so don't be surprised if things crack a little when you push at the boundaries like this.
It seems the real problem here is the way you're using type params. In this expression:
def editable_=[T <: HasEditable](value: Boolean) = (subject: T) => subject.setEditable(value)
The compiler has no way of inferring a particular T from the supplied argument, so it will take the most general type allowed (HasEditable in this case). You could change this behaviour by explicitly supplying a type param when using the method, but that would seem to defeat the entire point of what you're seeking to achieve.
Given that functions can't be generic (only methods can), I doubt that you even want type bounds at all. So one approach you could try is to just drop them:
def editable_=(value: Boolean) = (subject: HasEditable) => subject.setEditable(value)
def editable = new BindingMaker((widget: HasEditable) => SWTObservables.observeEditable(widget))