Accessing static properties in Coffeescript - coffeescript

With the following code in mind
a.coffee
B = require './b'
C = require './c'
console.log B.someStaticVar
C.checkB()
b.coffee
C = require './c'
class B
#someStaticVar: 1
module.exports = B;
c.coffee
B = require './b'
class C
#checkB: ->
console.log B.someStaticVar
module.exports = C
I am trying to understand why the static property of b is undefined when accessed by c but returning 1 when accessed by a
Output:
$ coffee a.coffee
1
undefined

It looks like you have a circular reference.
A loads B
B loads C
C loads B
But B isn't done loading, so here it's an empty object
C finishes loading
B finishes loading
A loads C - it's already loaded so it just gets a reference.
A finishes loading, your console.log lines at the end of the file are executed.
Here is a version of your 3 modules that illustrates this better:
a.coffee
B = require './b'
C = require './c'
console.log B.someStaticVar
C.checkB()
b.coffee
C = require './c'
console.log 'in b.coffee, we have loaded C: ', C
class B
#someStaticVar: 1
module.exports = B;
c.coffee
B = require './b'
console.log 'in c.coffee, we have loaded B: ', B
class C
#checkB: ->
console.log B.someStaticVar
module.exports = C
You have two options for fixing this cyclic dependency in commonjs:
1. Lazy loading
Don't require ./b in c.coffee until you execute your function. By the time you call C.checkB inside a.coffee B will have been fully loaded and the correct class will be returned from the require call
class C
#checkB: ->
B = require './b'
console.log B.someStaticVar
module.exports = C
2. Refactoring
B and C are tightly coupled. Consider rewriting them to be contained within a single file. You could just remove the require './c' from b.coffee. Though I'm guessing it's in this example as your code is more complex and does have a need for it.
a.coffee
{ B, C } = require './b'
console.log B.someStaticVar
C.checkB()
b.coffee
class B
#someStaticVar: 1
class C
#checkB: ->
console.log B.someStaticVar
module.exports =
C: C
B: B

Related

Assign same value to multiple variables in Scala

I have 3 variables that have already been initialized, and I want to assign a new value to all three of them. e.g.
var a = 1
var b = 2
var c = 3
and I want to reassign them to the same value e.g.
a = b = c = 4
But the above expression is invalid. Is there a right way to do this in Scala?
It is possible to slightly shorten the var definition code as follows
var (a, b, c) = (1, 2, 3)
This works because of extractor objects in scala. A tuple of 3 is extracted into 3 components it was created with.
But following does not work becase the extraction is applied on val or var definitions.
(a, b, c) = (4, 4, 4)
You can do this:
var Seq(a, b, c) = Seq.fill(3)(4)
As with Ivan's solution, this only works when declaring vars or vals, not when reassigning. Since the second parameter is computed for each element, it even works well for mutable objects:
import scala.collection.mutable.ListBuffer
var Seq(a, b, c) = Seq.fill(3)(ListBuffer[Int]())
a += 1 // Only modifies a, not b or c.
By contrast, something like a = b = c = [] will only create one list in most programming languages (e.g. Python, JavaScript, Java). If you don't want to create your object each time (perhaps because it is immutable and creation is expensive), declare it as val first to prevent this behavior:
val largeObject = ???
var Seq(a, b, c) = Seq.fill(3)(largeObject)

Scala closure Lexical Scope

class Cell(var x: Int)
var c = new Cell(1)
val f1 = () => c.x /* Create a closure that uses c */
def foo(e: Cell) = () => e.x /* foo is a closure generator with its own scope */
// f2 wont do any reference/deep copy
val f2 = foo(c) /* Create another closure that uses c */
val d = c /* Alias c as d */
c = new Cell(10) /* Let c point to a new object */
d.x = d.x + 1 /* Increase d.x (i.e., the former c.x) */
// now c.x refers to 10
println(f1()) /* Prints 10 */
println(f2()) /* Prints 2 */
Here the f2() prints 2 , As scala wont do deep copy, why the value is still persisted as 1, it should be 10.. where i am going wrong
2) I had read smomehere, Closure in scala dont deep copy the objects, they just keep reference to the object. what do it exactly mean
Your example is somewhat tough to understand due to the way you copied it in (it looks like all the code is run when a Cell is created, but you'd get infinite recursion if that were true). The reason f1 and f2 return different results is that they are pointing at different Cells. You are right that when you write:
val d = c
both c and d contain the same reference. But when you write:
c = new Cell(10)
c is now a reference to a new cell, and d won't copy over that reference.
It's easier to see this with REPL, which can print hexadecimal reference locations.
scala> class Cell(var x: Int)
defined class Cell
scala> var a = new Cell(5)
a: Cell = Cell#368239c8
scala> val b = a
b: Cell = Cell#368239c8
We can see that a and b contain references to the same cell.
scala> a.x = 10
a.x: Int = 10
scala> b.x
res0: Int = 10
When we update the class referenced by a, it also updates for b.
scala> a = new Cell(7)
a: Cell = Cell#5b87ed94
scala> b
res1: Cell = Cell#368239c8
scala> a.x
res2: Int = 7
scala> b.x
res3: Int = 10
When we assign our variable a to a new cell, it has a different reference location (it is a different instance of Cell). b still has the same reference (why wouldn't it?).

Linearization order in Scala

I have difficulties in understanding the linearization order in Scala when working with traits:
class A {
def foo() = "A"
}
trait B extends A {
override def foo() = "B" + super.foo()
}
trait C extends B {
override def foo() = "C" + super.foo()
}
trait D extends A {
override def foo() = "D" + super.foo()
}
object LinearizationPlayground {
def main(args: Array[String]) {
var d = new A with D with C with B;
println(d.foo) // CBDA????
}
}
It prints CBDA but I can't figure out why. How is the order of the traits determined?
Thx
An intuitive way to reason about linearisation is to refer to the construction order and to visualise the linear hierarchy.
You could think this way. The base class is constructed first; but before being able of constructing the base class, its superclasses/traits must be constructed first (this means construction starts at the top of the hierarchy). For each class in the hierarchy, mixed-in traits are constructed left-to-right because a trait on the right is added "later" and thus has the chance to "override" the previous traits. However, similarly to classes, in order to construct a trait, its base traits must be constructed first (obvious); and, quite reasonably, if a trait has already been constructed (anywhere in the hierarchy), it is not reconstructed again. Now, the construction order is the reverse of the linearisation. Think of "base" traits/classes as higher in the linear hierarchy, and traits lower in the hierarchy as closer to the class/object which is the subject of the linearisation.
The linearisation affects how `superĀ“ is resolved in a trait: it will resolve to the closest base trait (higher in the hierarchy).
Thus:
var d = new A with D with C with B;
Linearisation of A with D with C with B is
(top of hierarchy) A (constructed first as base class)
linearisation of D
A (not considered as A occurs before)
D (D extends A)
linearisation of C
A (not considered as A occurs before)
B (B extends A)
C (C extends B)
linearisation of B
A (not considered as A occurs before)
B (not considered as B occurs before)
So the linearization is: A-D-B-C.
You could think of it as a linear hierarchy where A is the root (highest) and is constructed first, and C is the leaf (lowest) and constructed last. As C is constructed last, it means that may override "previous" members.
Given these intuitive rules, d.foo calls C.foo, which returns a "C" followed by super.foo() which is resolved on B (the trait on the left of B, i.e. higher/before, in the linearization), which returns a "B" followed by super.foo() which is resolved on D, which returns a "D" followed by super.foo() which is resolved on A, which finally returns "A". So you have "CBDA".
As another example, I prepared the following one:
class X { print("X") }
class A extends X { print("A") }
trait H { print("H") }
trait S extends H { print("S") }
trait R { print("R") }
trait T extends R with H { print("T") }
class B extends A with T with S { print("B") }
new B // X A R H T S B (the prints follow the construction order)
// Linearization is the reverse of the construction order.
// Note: the rightmost "H" wins (traits are not re-constructed)
// lin(B) = B >> lin(S) >> lin(T) >> lin(A)
// = B >> (S >> H) >> (T >> H >> R) >> (A >> X)
// = B >> S >> T >> H >> R >> A >> X
The accepted answer is wonderful, however, for the sake of simplification, I would like to do my best to describe it, in a different way. Hope can help some people.
When you encounter a linearization problem, the first step is to draw the hierarchy tree of the classes and traits. For this specific example, the hierarchy tree would be something like this:
The second step is to write down all the linearization of the traits and classes that interferes the target problem. You will need them all in the one before the last step. For this, you need to write just the path to reach the root. The Linearization of traits are as following:
L(A) = A
L(C) = C -> B -> A
L(B) = B -> A
L(D) = D -> A
The third step is to write the linearization of the problem. In this specific problem, we are planning to solve the linearization of
var d = new A with D with C with B;
Important note is that there is a rule by which it resolves method invocation by first using right-first, depth-first search. In another word, you should start writing the Linearization from most right side. It is as follow:
L(B)>>L(C)>>L(D)>>L(A)
Fourth step is the most simple step. Just substitute each linearization from second step to third step. After substitution, you will have something like this:
B -> A -> C -> B -> A -> D -> A -> A
Last but not least, you should now remove all duplicated classes from left to right. The bold chars should be removed:
B -> A -> C -> B -> A -> D -> A -> A
You see, you have the result: C -> B -> D -> A
Therefore the answer is CBDA.
I know it is not individually deep conceptual description, but can help as an complementary for the conceptual description I guess.
And this part explains by relying on formula:
Lin(new A with D with C with B) = {A, Lin(B), Lin(C), Lin(D)}
Lin(new A with D with C with B) = {A, Lin(B), Lin(C), {D, Lin(A)}}
Lin(new A with D with C with B) = {A, Lin(B), Lin(C), {D, A}}
Lin(new A with D with C with B) = {A, Lin(B), {C, Lin(B)}, {D, A}}
Lin(new A with D with C with B) = {A, Lin(B), {C, {B, Lin(A)}}, {D, A}}
Lin(new A with D with C with B) = {A, Lin(B), {C, {B, A}}, {D, A}}
Lin(new A with D with C with B) = {A, {B, A}, {C, {B, A}}, {D, A}}
Lin(new A with D with C with B) = {C,B,D,A}
Scala's traits stack, so you can look at them by adding them one at a time:
Start with new A => foo = "A"
Stack with D => foo = "DA"
Stack with C which stacks with B => foo = "CBDA"
Stack with B does nothing because B is already stacked in C => foo = "CBDA"
Here's a blog post about how Scala solves the diamond inheritance problem.
The process by which scala resolve the super call is called Linearization
In your example you create Object as
var d = new A with D with C with B;
So as specified scala reference docs Here call to super will be resolved as
l(A) = A >> l(B) >> l(c) >> l(D)
l(A) = A >> B >> l(A) >> l(C) >> l(D)
l(A) = A >> B >> A >> C >> l(B) >> l(D)
l(A) = A >> B >> A >> C >> B >> l(A) >> l(D)
l(A) = A >> B >> A >> C >> B >> A >> l(D)
l(A) = A >> B >> A >> C >> B >> A >> D >> l(A)
l(A) = A >> B >> A >> C >> B >> A >> D >> A
Now Start from left and remove duplicate construct in which right will be winning one
e.g. remove A and we get
l(A) = B >> C >> B >> D >> A
remove B and we get
l(A) = C >> B >> D >> A
Here we don't have any duplicate entry
Now starting calling from C
C B D A
super.foo in class C will call foo in B and foo in B call foo in D and so on.
P.S. here l(A) is linearization of A
Well Actually I see you just reversed the Constructor linearization, which I think is pretty simple, so First let's understand constructor linearization
First Example
object Linearization3 {
def main(args: Array[String]) {
var x = new X
println()
println(x.foo)
}
}
class A {
print("A")
def foo() = "A"
}
trait B extends A {
print("B")
override def foo() = super.foo() + "B" // Hence I flipped yours to give exact output as constructor
}
trait C extends B {
print("C")
override def foo() = super.foo() + "C"
}
trait D extends A {
print("D")
override def foo() = super.foo() + "D"
}
class X extends A with D with C with B
Which outputs:
ADBC
ADBC
So to calculate the output I just take the class/traits one by one from left to right then recursively write outputs (without duplicates) here is how:
Our class signature is : class X extends A with D with C with B
So the first is A, since A has no parents (deadend) just print its constructor
Now D, which extends A, since we already printed A, then let's print D
Now C, which extends B, which extends A, so we skip A because it's already have been printed, we then print B , then print C (it's like a recursive funtion)
Now B, which extends A, we skip A, and we also skip B (nothing printed)
and you got ADBC !
Reversed Example (Your example)
object Linearization3 {
def main(args: Array[String]) {
var x = new X
println()
println(x.foo)
}
}
class A {
print("A")
def foo() = "A"
}
trait B extends A {
print("B")
override def foo() = "B" + super.foo()
}
trait C extends B {
print("C")
override def foo() = "C" + super.foo()
}
trait D extends A {
print("D")
override def foo() = "D" + super.foo()
}
class X extends A with D with C with B
The Output is:
ADBC
CBDA
I hope that was simple enough for beginners like me
In addition to other anwsers you can find step-by-step explanation in snippet result below
hljs.initHighlightingOnLoad();
<script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.0.0/highlight.min.js"></script>
<link href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.0.0/styles/zenburn.min.css" rel="stylesheet" />
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet" />
<table class="table">
<tr>
<th>Expression</th>
<th>type</th>
<th><code>foo()</code> result</th>
</tr>
<tr>
<td><pre><code class="scala"> new A </code></pre>
</td>
<td><pre><code class="scala"> A </code></pre>
</td>
<td><pre><code class="scala">"A"</code></pre>
</td>
</tr>
<tr>
<td><pre><code class="scala"> new A with D </code></pre>
</td>
<td><pre><code class="scala"> D </code></pre>
</td>
<td><pre><code class="scala">"DA"</code></pre>
</td>
</tr>
<tr>
<td><pre><code class="scala"> new A with D with C </code></pre>
</td>
<td><pre><code class="scala"> D with C </code></pre>
</td>
<td><pre><code class="scala">"CBDA"</code></pre>
</td>
</tr>
<tr>
<td><pre><code class="scala"> new A with D with C with B </code></pre>
</td>
<td><pre><code class="scala"> D with C </code></pre>
</td>
<td><pre><code class="scala">"CBDA"</code></pre>
</td>
</tr>
</table>
explanation, how the compiler sees a class Combined which extends the traits A with D with C with B
class Combined extends A with D with C with B {
final <superaccessor> <artifact> def super$foo(): String = B$class.foo(Combined.this);
override def foo(): String = C$class.foo(Combined.this);
final <superaccessor> <artifact> def super$foo(): String = D$class.foo(Combined.this);
final <superaccessor> <artifact> def super$foo(): String = Combined.super.foo();
def <init>(): Combined = {
Combined.super.<init>();
D$class./*D$class*/$init$(Combined.this);
B$class./*B$class*/$init$(Combined.this);
C$class./*C$class*/$init$(Combined.this);
()
}
};
reduced example
You can read from left to right. Here is a small example. The three traits will print their name when initialized i.e. extended:
scala> trait A {println("A")}
scala> trait B {println("B")}
scala> trait C {println("C")}
scala> new A with B with C
A
B
C
res0: A with B with C = $anon$1#5e025e70
scala> new A with C with B
A
C
B
res1: A with C with B = $anon$1#2ed94a8b
So this is the basic linearization order. So the last one will overwrite the previous one.
Your problem is a little more complex. As you traits already extend other traits that themselves override some values of the previous traits.
But the initialization order left to right or right will override left.
You have to keep in mind that the trait itself will be initialized first.

How to unpack first-class module to module for object with class declaration?

I have:
module type A = sig end
This code is valid:
let f x =
let module X = (val x : A) in
object end
and this:
let f (module X : A) =
object end
But this is invalid:
class c x =
let module X = (val x : A) in
(* ^^^ Error: Syntax error *)
object end
and this:
class c (module X : A) =
(* ^^^^^^^^^^^^^ Error: Modules are not allowed in this pattern. *)
object end
And I can not understand: Why?
How to unpack first-class module to module for object in class context?
My compiler version = 4.01.0
Thank you
Any form of local module for a class definition is not allowed:
class c =
let module L = List in
object end;;
Characters 18-24:
let module L = List in
^^^^^^
Error: Syntax error
I'm not certain of the exact reason, but I have it on very good authority that it would be very difficult to implement.
However, it is possible to accept a first-class module argument to a class and unpack it within the methods and values that actually use it. For example:
class c d = object
method foo =
let module D = (val d : A) in
D.b + 5
end

Identity operators in Swift

If a is identical to c, b is identical to c, why a is not identical to b?
var a = [1, 2, 3]
var b = a
var c = a[0...2]
a === c // true
b === c // true
a === b // false
If a, b, c are constants:
let a = [1, 2, 3]
let b = a
let c = a[0...2]
a === c // true
b === c // true
a === b // true
You can remove the import Cocoa or import UIKit if you are playing with PlayGround to make it correct. It seems there is some type map thing in the Cocoa framework to mess things up. It should be a bug, I think.
As #onevcat said, it's might be a bug of Playground. And if you change a to objects of reference type, all the identity tests will be true.
class K {}
var a = [K(), K(), K()]
var b = a
var c = a[0...2]
a === c // true
b === c // true
a === b // true
it means that a, b & c share the same storage and elements.
Interesting, my guess is that since c is a var in the first case, its mutable and thus it has to make a copy. That way if you add on to c it wouldn't modify a. In the second case, they are all immutable so they can point to the same memory space