What is the syntax for declaring a constant string[char] AA? - constants

The following declaration:
const(string[char]) AA1 = [
'a' : "fkclopel",
'b' : "poehfftw"
];
void main(string args[]){}
gives me:
C:...\temp_0186F968.d(1,27): Error: non-constant expression ['a':"fkclopel", 'b':"poehfftw"]
while it would work with other type kinds.

You can initialize associative array constants inside a module constructor:
const /+ or immutable +/ (string [char]) AA1;
static this () {
AA1 = [
'a' : "fkclopel",
'b' : "poehfftw"
];
}
import std.stdio;
void main () {writeln (AA1);}
The manual section on associative array literals explicitly states that "An AssocArrayLiteral cannot be used to statically initialize anything.", though it does not give clues as to why it is so.

Related

Invalid initialization of reference type 'Class&' from expression of type 'Class'

Ok guys , so I have a list of objects and I want to sort my list by a boolean function I created .
Function ->
bool funct(Student &s1,Student &s2)
{
return s1.calculMedie()<s2.calculMedie();
}
I got this list:
list<Student*> list;
list.push_back(sx[0]);
list.push_back(sx[1]);
list.push_back(sx[2]);
sx is comming from this declaration-> Student **sx=new Student*[3];
I created 3 objects of the type class Student.
I want to sort them by 'calculMedie()' which is a function that returns their average grade.
double Student::calculMedie()
{
int nr=0;
double s=0;
for(auto i : note)
{
nr++;
s=s+i;
}
return s/nr;}
^ thats how it looks.
And when I tried to do a list.sort(list.begin(),list.end(),funct) it gets me this error : " Invalid initialization of reference type 'Class&' from expression of type 'Class'"
It looks like you mixed std::sort algorithm with list<T>::sort method. List can be sorted only by using its sort method.
There are two overloads of list::sort:
void sort();
template< class Compare >
void sort( Compare comp ); // [2]
if you want to sort by comparator, write as follows:
list<Student*> list;
list.sort (funct);
because list stores pointers to Student, you need to modify signature of funct function, it must takes pointers not references:
bool funct(Student* s1,Student* s2)
{
return s1->calculMedie()<s2->calculMedie();
}
good practice is to pass s1,s2 as pointers to const object, when you change s1,s2 to be const Student* s1, const Student* s2 you need also to make calculMedie as const member function.

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

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 ]
}
}

Creating a function in a macro

I am trying to add a static variable and a static function to all instances of a class and its child classes using the #:build and #:autoBuild macros.
I managed to get the static variable working, but I have no idea how to "build" the function from the various EFunction, EFor, etc.
Here is the code I have so far:
macro static public function addGetId() :Array<Field>
{
var fields : Array<Field> = Context.getBuildFields();
// The static _id field
var idField = {
name : "_id",
doc : null,
meta : [],
access : [AStatic, APrivate],
kind : FVar(macro : Int, macro -1),
pos : Context.currentPos()
};
// The getId function field
var getIdField = {
name : "getId",
doc : "Returns the ID of this command type.",
meta : [],
access : [AStatic, APublic],
kind : FFun({
params : [],
args : [],
expr: // What do I have to write here???
ret : macro : Int
}),
pos : Context.currentPos()
};
fields.push(idField);
fields.push(getIdField);
return fields;
}
Here is how the function that I want to add would look like in normal code, if it was actually in the .hx file:
public static function getId() : Int
{
if (_id == -1)
{
_id = MySingleton.getInst().myGreatFunction()
}
return _id;
};
So it references the newly added _id variable as well as some singleton class function.
So: How would the complete getIdField() look like?
Bonus Question:
My biggest problem with this is the complete lack of documentation on these features as well as any useful examples in the manual. Is there any actually useful tutorial for creating functions like this?
Bonus Bonus Question:
What is the difference between params and args in FFun?
You can make use of reification to write the body of the function like you would in regular Haxe code:
expr: macro {
if (_id == -1) {
_id = 0;
}
return _id;
},
params is a list of type parameters, args is the list of arguments the function receives. There's a trivia section about this on the Haxe Manual:
Trivia: Argument vs. Parameter
In some other programming languages, argument and parameter are used interchangeably. In Haxe, argument is used when referring to methods and parameter refers to Type Parameters.

Return_value_policy for method with void return type and optional parameter

I have class with void method and optional argument looking like this:
class A
{
public:
void method(int par1, bool par2 = false) { ... }
};
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(method, A::method, 1, 2)
class_<A>("A")
.def("method", &A::method, return_value_policy<reference_existing_object>(),method())
;
What is correct return_value_policy in this case? I've tried to avoid return policy completely however I've received following compile error then.
'boost::mpl::vector17<RT,most_derived<Target,ClassT>::type&,T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14> boost::python::detail::get_signature(RT (__cdecl ClassT::* )(T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14) volatile const,Target *)' : expects 2 arguments - 1 provided
Any suggestion appreciated.
I've scrambled few things together. Bur I realized I do not need to use BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS but rather named arguments something like:
def("method", &A::method, (arg("par1"), arg("par2") = false))

How to check return type in xtext using xbase

With xtext I'm trying to develop a small language.
def sum(Integer a, Integer b):Integer {
return (a+b)
}
This is the grammar I use for this:
Function:
'def' name=ValidID
'('(params+=FullJvmFormalParameter (',' params+=FullJvmFormalParameter)*)? ')'
':' type=JvmTypeReference
body=XBlockExpression;
For reasons obvious to me it complains that "Void functions cannot return a value". How do I link the type of the return expression with the type in my function declaration?
You have to put the expression into the context of a JvmOperation. Please refer to the domain model example, the docs and the 7-languages if you want to learn more about the inferred JVM model.
Basically, what you have to do is something along these lines:
def dispatch infer(MyLanguageConcept concept, IJvmDeclaredTypeAcceptor acceptor, boolean prelinking) {
acceptor.accept(
concept.toClass( concept.fullyQualifiedName )
).initializeLater [
for ( definition : concept.getDefinitions ) {
members += definition.toMethod(
definition.name,
definition.type) [
for (p : definition.params) {
parameters += p.toParameter(p.name, p.parameterType)
}
body = definition.body
]
}
]
}