Why Fantom compiler complains about a class that has a Func field? - fantom

I wrote a Fantom script that defines a bunch of classes. As I could run the script successfully, I decided to convert this into a proper Fantom project, but one of the classes cannot be compiled and the error message is:
Expected expression, not '|'
The class has this form:
class MyClass
{
const Func myFunc := |Foo foo, Bar bar| {
// do stuff
}
MyType myVar := MyType()
Void main() {
// do more stuff
}
}
I don't understand why the compiler complains when this class is part of a Fantom project, but doesn't if is part of a Fantom script instead. Can anyone shed some light, please?
Thank you

It's a just a bad error message on Fantom's behalf. It is actually complaining that the classes Foo and Bar don't exist. Add the following to your project and all should compile okay.
class Foo {}
class Bar {}
class MyType {}

Related

What's the scope of a private top-level class with access qualifier set to the same package where the class is defined in Scala?

I have read this article to better understand Scala scoping rules.
Everything seemed clear until I ran into some code on GitHub that was like this:
package x.y.z
private[z] class ExampleClass {
// class body
}
As you can see, we have a private top-level class, and there's an access qualifier to modify the scope of that class, but it's set to the very same package where the class is defined. If the access qualifier was set to an enclosing scope (e.g. package y) I would perfectly get it, but like this I can't understand the difference with simply declaring the class as private:
package x.y.z
private class ExampleClass {
// class body
}
So what is the difference between the two snippets posted above?
NOTE: I don't know if it's of any relevance, but in the same file a companion object for the class was defined and simply declared as private (with no access qualifiers).
In the example you provided both modifiers have the same effect. Difference would be more apparent if you had an enclosing class/object.
Compiles:
package x.y.z
object OuterExampleClass {
private[z] class ExampleClass()
}
object AnotherObject {
val ec = new OuterExampleClass.ExampleClass()
}
Fails to compile:
package x.y.z
object OuterExampleClass {
private class ExampleClass() // no [z] !!!
}
object AnotherObject {
val ec = new OuterExampleClass.ExampleClass() // error
}
with message:
class ExampleClass in object OuterExampleClass cannot be accessed in
object x.y.z.OuterExampleClass

Enforce compiler error when naming a parameter of a java method when called from scala

I have a java class like the following:
public class Foo {
public void foo(boolean flag) {}
}
And a scala class like the following:
class Bar {
def bar(): Unit = {
val foo = new Foo()
foo.foo(flag = true)
}
}
This causes a compiler error to be displayed inside intellij (as it should, since there are no parameter names stored in java classes), but when building from the command line with maven, there is no compiler error. Is there a setting to cause this to be an error in the maven build?

Scala interop with Java questionmark generics

EDIT I have made the example self-contained.
Suppose in java I have
src/main/java/FooFactory.java
interface FooFactory {
Foo<?> create();
<T> void enhance(Foo<T> foo, FooEnhancer<? super T> enhancer);
}
and src/main/java/Foo.java
interface Foo<T> {}
and src/main/java/FooEnhancer.java
interface FooEnhancer<T> {}
(and you can't change these interfaces because they belong to someone else.)
Then in scala you have
object DummyFooEnhancer extends FooEnhancer[Any]
trait FooHdlr {
def fooFactory: FooFactory
val foo = fooFactory.create
fooFactory.enhance(foo, DummyFooEnhancer)
}
This doesn't compile because FooEnhancer and Foo are invariant but foo is a Foo<?> whereas DummyFooEnhancer is a Foo[Any]. Changing Any to AnyRef doesn't work for the same reason.
Then I reasoned that, well, ? is a specific type that is certainly not known at compile time and that may not necessarily be AnyRef/Object, so what if I do this?
case class DummyFooEnhancer[T] extends FooEnhancer[T]
trait FooHdlr {
def fooFactory: FooFactory
val foo = fooFactory.create
fooFactory.enhance(foo, new DummyFooEnhancer)
}
But this causes scalac to stackoverflow! It's looping with
at scala.reflect.internal.Types$TypeVar.isGround(Types.scala:3082)
calling itself.
Interestingly if I replace ? super T with T it works fine, but in real life I can't do this because it's in code I don't control

Extend a CoffeeScript class loaded with RequireJS inside a TypeScript code

Currently I have a large codebase developed with CoffeeScript and want to extend it with some TypeScript.
Let's say I have the following code in the CoffeeClass.coffee file:
define 'CoffeeClass', ->
class CoffeeClass
foo: () -> 1
It is meant to be loaded through require in the following manner (let's call this file CoffeeUser.coffee):
require ['CoffeeClass'], (CoffeeClass) ->
class MyClass extends CoffeeClass
foo: () -> super() + 1
console.log (new MyClass().foo()) # => 2
Now it can be loaded in browser with the standard RequireJS markup:
<script data-main="CoffeeUser.js" src="require.js"></script>
I want to extend the CoffeeClass from the TypeScript code. That's what I've tried:
First write a CoffeeClass.d.ts definiton file (I know it is wrong but it's showing what I'm trying to achieve):
export class CoffeeClass {
foo(): number;
}
And then try to use it from TypeScriptUser.ts:
import CoffeeClass = require('CoffeeClass');
class TypeScriptUser extends CoffeeClass {
foo(): number {
return super.foo() + 1;
}
}
But it won't compile partly because I cannot find the right syntax for the d.ts file and partly because I cannot properly tell the compiler how to extend the CoffeeClass (as far as I can tell the compiler cannot understand that CoffeeClass is really a class and not just a module).
So can I tell the TypeScript compiler that the module is a class here? If no, how would you recommend me to change the CoffeeClass design to extend it from TypeScript code and don't lose all the type safety?
Finally I've found the solution. That's the special export = syntax. Here it is. CoffeeClass.d.ts:
declare class CoffeeClass {
foo(): number;
}
export = CoffeeClass;
And TypeUser.ts:
/// <reference path="CoffeeClass.d.ts" />
import CoffeeClass = require('CoffeeClass')
class MyClass extends CoffeeClass {
foo() {
return super.foo() + 1;
}
}
console.log(new MyClass().foo()); // => 2
Note that the compiler will infer the proper require call when compiling the code.

Scala package delcaration - one way causes package objects visible, other makes it not?

In foo/bar/my_package/package.scala:
package foo.bar
package object my_package {
type SomeType = java.lang.String
}
Then, in foo/bar/my_package/my_sub/MyClass.scala
package foo.bar.my_package.my_sub
class MyClass {
var x: SomeType = _
}
This fails to compile; SomeType isn't found. If I change MyClass.scala to
package foo.bar.my_package
package my_sub
class MyClass {
var x: SomeType = _
}
Everything works fine. What is the difference!?!??!
(This is Scala 2.8.1)
Package declarations, like imports, give you access to everything inside them. So when you
package foo.bar.my_package
then you have everything available that you would if you did
import foo.bar.my_package._
Furthermore, declaring a package on a single line means that everything below belongs to that package:
package foo.bar.my_package {
package my_sub {
class MyClass { var x: SomeType = _ }
}
}
(which is equivalent to:
package foo.bar.my_package
package my_sub
class MyClass { var x: SomeType = _ }
)
so you can see how the contents of foo.bar.my_package ought to be in scope in this case. In the other case, you only have the contents of foo.bar.my_package.my_sub available, which does not include SomeType.
It's a visibility question.
package foo.bar.my_package.my_sub
class MyClass {
var x: SomeType = _
}
When you declare x, the following things are visible:
Every member of MyClass
Everything inside foo.bar.my_package.my_sub
Every member of scala.Predef
Everything inside scala
Everything inside java.lang
The type SomeType is not inside any of those.
On the other hand, when you do:
package foo.bar.my_package
package my_sub
class MyClass {
var x: SomeType = _
}
Then the visibility is:
Every member of MyClass
Everything inside foo.bar.my_package.my_sub
Everything inside foo.bar.my_package
Every member of scala.Predef
Everything inside scala
Everything inside java.lang
And SomeType is inside foo.bar.my_package, which is the second line.
A related question is why it works this way. You can get a start here, though there's a question precisely about that. I don't much like the answer to that question, though, as it really doesn't touch the reasons for it. It does link to a page on scala-lang about new features of Scala 2.8, in which Odersky explains the reasons.