Accessing Fantom class' members from a member function in a constructor it-block? - fantom

If I define this Fantom class
const class Mixed
{
const Int whole
const Int numerator
const Int denominator
const | -> Int[]| convertToFrac
new make( |This| func ) { func( this ) }
}
And I want to create an instance defining the convertToFrac function, like this:
class Example
{
Void main( Str args )
{
mixed := Mixed {
whole = 2
numerator = 3
denominator = 8
convertToFrac = |->Int[]| {
return [ whole * denominator + numerator, denominator ]
}
}
}
}
The compiler complains saying:
Unknown variable 'numerator'
Unknown variable 'denominator'
Unknown variable 'whole'
Is there any way to refer to the object "mixed" being created from within the function "convertToFrac", also being defined, without passing the "mixed" object as a parameter of the function?
If I prepend each variable with "mixed", like so:
return [ mixed.whole * mixed.denominator + mixed.numerator, mixed.denominator ]
The compiler complains: Unknown variable 'mixed'.
Using this.whole doesn't make sense as it refers to the Example class.
Using it.whole doesn't make sense either as it refers to the Function.
Can anyone please suggest the way to access the "mixed" object from within the "convertToFrac" function?

As you correctly assessed, the issue is that you're using an it-block inside an it-block, and because you're using an implicit it (i.e. you're don't have any it qualifiers) there is confusion as to what's being referenced.
I'll write out the it qualifiers out long hand so you can see what's going on:
mixed := Mixed {
// 'it' is the Mixed instance
it.whole = 2
it.numerator = 3
it.denominator = 8
it.convertToFrac = |->Int[]| {
// 'it' is now the func param
// 'it.whole' doesn't exist, because there is no func param
return [ it.whole * it.denominator + it.numerator, it.denominator ]
}
}
Your idea of using the mixed variable qualifier was a good one but, unfortunately, whilst processing the ctor the mixed variable hasn't been created yet so can't be referenced.
But you can create your own mixed variable in the it-block, and the following compiles and runs quite happily:
mixed := Mixed {
// 'mixed' doesn't exist here yet, because we're still creating a value to assign to it
it.whole = 2
it.numerator = 3
it.denominator = 8
// assign `it` to our own `mixed` variable
mixed := it
it.convertToFrac = |->Int[]| {
// use our own `mixed` variable
return [ mixed.whole * mixed.denominator + mixed.numerator, mixed.denominator ]
}
}

Related

Understanding constructors and final [duplicate]

class X extends Y {
X(int a, int b) : super(a,b);
}
Can someone give me an explanation about the syntax meaning of the colon :?
This feature in Dart is called "initializer list".
It allows you to initialize fields of your class, make assertions and call the super constructor.
This means that it is not the same as the constructor body. As I said, you can only initialize variables and only access static members. You cannot call any (non-static) methods.
The benefit is that you can also initialize final variables, which you cannot do in the constructor body. You also have access to all parameters that are passed to the constructor, which you do not have when initializing the parameters directly in the parentheses.
Additionally, you can use class fields on the left-hand of an assignment with the same name as a parameter on the right-hand side that refers to a parameter. Dart will automatically use the class field on the left-hand side.
Here is an example:
class X {
final int number;
X(number) : number = number ?? 0;
}
The code above assigns the parameter named number to the final field this.number if it is non-null and otherwise it assigns 0. This means that the left-hand number of the assignment actually refers to this.number. Now, you can even make an assertion that will never fail (and is redundant because of that, but I want to explain how everything works together):
class X {
final int number;
X(number): number = number ?? 0, assert(number != null);
}
Learn more.
It's ok to access non static member in initializer list.
class Point {
num x, y;
Point(this.x, this.y);
Point.origin(): this.x = 10, this.y = 10;
}
main() {
Point p = Point.origin();
print(p.x); // 10
}

Error: passing 'const xxx' as 'this' argument discards qualifiers

I am trying to implement bigint class in c++, it's not completed yet, i have encountered some errors that i am unable understand.
I have erased all other functions (as they are unnecessary in this case)
and karatsuba is not yet completed (but that should't pose a problem in this case).
In the multiply function (overloaded * ) my compiler gives an error:
passing 'const BigInt' as 'this' argument discards qualifiers [-fpermissive]
at line
ans.a = karatsuba(n,m);
I understand that this would occur when i am trying to change a constant object or object passed to a constant function, in my case i am merely creating a new vector and passing it to karatsuba function.
Removing const from overloded * gets rid of this error.
So,does this mean that a constant function can't change anything at all? (including local variables?)
class BigInt {
typedef long long int ll;
typedef vector<int> vi;
#define p10 1000000000;
#define range 9
vi a;
bool sign;
public:
BigInt operator * (const BigInt &num) const
{
vi n(a.begin(),a.end()),m(num.a.begin(),num.a.end());
BigInt ans;
ans.sign = !(sign ^ num.sign);
while(n.size()<m.size()) n.push_back(0);
while(n.size()>m.size()) m.push_back(0);
ans.a = karatsuba(n,m);
return ans;
}
vi karatsuba(vi a,vi b)
{
int n = a.size();
if(n <= 16)
{
// some code
}
// some code
return a;
}
};
Ok so after googling a bit more, i realized that this pointer is implicitly passed to the oveloaded * and then on to karatsuba (as it is a member function of the class), and as karatsuba is not a constant function, there is no guarantee that it won't change the object contents, hence this error is triggered.
One solution is to declare karatsuba as static, as static member functions don't receive this pointer (they can even be called with out a class object simply using :: operator) , read more about them from here Static data members and member functions.
All that is needed to be changed is :-
static vi karatsuba(vi a,vi b)
{
int n = a.size();
if(n <= 16)
{
// some code
}
// some code
return a;
}

Using local variables in function built with haxe macro

I have a LangBuilder macro class; it's used to build a langObjects:Map<String, Dynamic> of texts in various languages at compile time, and inject this structure in classes via #:build macro. Every item of the Map has a field for every language supported. So the result is:
#:build(LangBuilder.build())
class Lang{}
trace(Lang.langObjects["hello-world"].en); //outputs "Hello World!"
trace(Lang.langObjects["hello-world"].it); //outputs "Ciao Mondo!"
This works perfectly, but I thought I could make a cleaner job hiding the langObjects structure using a function getLangText with arguments the id of the text (e.g. "hello-world") and the language code (e.g. "it").
So I'm trying to add this function to classes:
public static function getLangText(id:String, lang:String)
Its non-macro version could be expressed as:
public static function getLangText(id:String, lang:String){
var _langObj_id = langObjects[id];
switch(lang){
case "it":
return _langObj_id.it;
case "en":
return _langObj_id.en;
}
return "Missing Translation";
If i translate this function as a macro with this code:
var code = macro {
var _langObj_id = langObjects[$i{"id"}];
switch($i{"lang"}){
case "it":
return _langObj_id.it;
case "en":
return _langObj_id.en;
}
return "Missing translation";
};
var myFunc:Function = {
args: [{
name: "id",
type: TPath({name: "String", pack: []}),
meta: null
},
{
name: "lang",
type: TPath({name: "String", pack: []}),
meta: null
}],
ret: (macro:String),
expr: macro $code
};
fields.push({
pos: Context.currentPos(),
name: "getLangText",
meta: null,
kind: FieldType.FFun(myFunc),
doc: null,
access: [Access.APublic, Access.AStatic]
});
... it works without problems. However I would like to know how it could be written without the switch, to make it more flexible and to learn something about haxe macros. I have seen some examples where fields could be accessed in macros with $p{} or with object.$fieldName. However the haxe manual warns that the second form could be used only for simple identifiers; for example object.${fieldName} would not work.
So I try this code:
var code = macro {
var l:String = $i{"lang"};
var _langObj_id = langObjects[$i{"id"}];
return _langObj_id.$l;
};
The compiler gives an error
Unknown identifier : l
on the line containing return _langObj_id.$l;.
Then i tried to use the $p{} reification:
var code = macro {
var _langObj_id = langObjects[$i{"id"}];
return macro $p{["_langObj_id", $i{"lang"}]};
};
But the error is similar:
Unknown identifier : lang
I can surely change the langObjects structure to Map<String, Map<String, String>> and then change the code to:
var code = macro {
return macro langObjects[$i{"id"}][$i{"lang"}];
};
I think this would work, but now i'm trying to understand why both _langObj_id.$lang and $p{["_langObj_id", $i{"lang"}]} wouldn't work, and what would be the correct way to access a field in a situation like that.
The value of the lang parameter is not known at compile- / macro-time, so I don't see how you could generate a field access expression like langObjects["mytext"].en. At runtime when getLangText() is actually called, lang could be "en", or anything else. So that would still require a switch-case, if-else-chain or reflection to handle all the possible values.
If instead of using being created by a build macro, getLangText() was an expression macro / a macro function, the function call would be evaluated at compile-time, and be replaced with the expression it returns. That would allow you to generate the appropriate field access expression based on the parameters. It could look something like this:
class Macro {
public static var langObjects = ["mytext" => {en: "hello", de: "hallo"}];
public static macro function getLangText(id:String, lang:String) {
return macro {
var langObject = Macro.langObjects[$v{id}];
langObject.$lang;
}
}
}
class Main {
static function main() {
trace(Macro.getLangText("mytext", "en"));
trace(Macro.getLangText("mytext", "de"));
}
}
Compiles to the following on the JS target:
Main.main = function() {
var langObject = Macro.langObjects.get("mytext");
console.log("source/Main.hx:3:",langObject.en);
var langObject1 = Macro.langObjects.get("mytext");
console.log("source/Main.hx:4:",langObject1.de);
};
Perhaps that's what you're looking for? Hard to say without knowing what problem you're trying to solve.

find variable Declaration reference Abstract syntax tree eclipse cdt C code

I have a c code like this
int x;
x = 5;
I used eclipse cdt to generate the AST, and traverse on it, so this is the code of the traversed class
public class RuleChk extends AbstractRule {
public RuleChk(IASTTranslationUnit ast) {
super("RuleChk", false, ast);
shouldVisitDeclarations = true;
shouldVisitParameterDeclarations = true;
}
#Override
public int visit(IASTSimpleDeclaration simpleDecl) {
//if this node has init, e.g: x = 5, do business
if(VisitorUtil.containNode(simpleDecl, CASTExpressionStatement){
// Now I have the x = 5 node,
// I want to get the reference node of it's declaration
// I mean (int x;) node
IASTNode declNode = ?????
}
return super.visit(parameterDeclaration);
}
}
what I want to visit the node that only has assignation(Initialization) and get the reference of declaration node for that varaiable.
I'm not sure how VisitorUtil works (it's not from the CDT code), but I assume it gives you a way to access the the found node. So:
Given the IASTExpressionStatement node that was found, use IASTExpression.getExpression() to get the contained expression.
See if it's an IASTBinaryExpression, and that is getOperator() is IASTBinaryExpression.op_assign.
Use IASTBinaryExpression.getOperand1() to get the assignment expression's left subexpression. Check that it's an IASTIdExpression, and get the variable it names via IASTIdExpression.getName().
Now that you have the name, use IASTName.resolveBinding() to get the variable's binding. This is the variable's representation in the semantic program model.
To find the variable's definition, use IASTTranslationUnit.getDefinitionsInAST(IBinding) if you only want it to look in the current file, or IASTTranslationUnit.getDefinitions(IBinding) if you want it to look in included header files as well (the latter requires the project to be indexed). The IASTTranslationUnit can be obtained from any IASTNode via IASTNode.getTranslationUnit().

Define a static variable in a function like c++

In my function, can I have a variable that
Retains its value between function calls.
Is only visible inside that function
Is unique for each thread i.e. if I'm calling the function from two threads then there are two variables that are static with regard to each thread.
Why I want that:
I have a function in which I fill in a list and return that list. The problem is that if I declare a variable normally, then I will have to allocate memory for it every time I call the function. I want to avoid that and allocate only once then every time I call the function it would fill in that variable with the proper values then return it.
I can do the following inside a class:
class MyClass {
val __readLineTemp = mutable.IndexedSeq.fill[Int](5)(-1)
def readLine() = {
var i = 0
while (i < __readLineTemp.length)
{
__readLineTemp(i) = Random.nextInt()
i += 1
}
__readLineTemp
}
}
My problems with this approach is that it doesn't satisfy the points 2 and 3 namely visibility only inside the method and being unique for each thread. However, for point 3 I can simply make each thread initialise its own object of MyClass.
I understand there is probably no way of achieving exactly what I want, but sometimes people come up with clever ideas to overcome this, specially that Scala seems quite deep and there is a lot of tricks you can do
You can use a closure to satisfy 1 and 2:
def foo = {
var a = 5
() => {
a = a + 1
a
}
}
i.e. create a closure that will contain the static variable (in your case, this is __readLineTemp) and return a function that's the only thing with access to the variable.
Then use it like this to satisfy the thread requirement:
val t1 = new Thread(new Runnable {
def run = {
val f = new DynamicVariable(foo)
println(f.value())
println(f.value())
}
})