IronScheme: How do you 'or' enumeration entries - ironscheme

How do you 'or' enum entries in IronScheme, ex:
(import
(rnrs)
(ironscheme clr))
(clr-using System.Reflection)
(define public-class-attributes
(bitwise-ior
(clr-static-field-get
TypeAttributes Public)
(clr-static-field-get
TypeAttributes Class)))
(display public-class-attributes)
This causes an error, I haven't found an alternative in the documentation.

I am not sure what your use case is, but as mentioned in the comment, when using clr-call a list of symbols can be used for an OR'd enum. Example here.
Internally, the compiler will wrap the list with a call to Helpers.SymbolToEnum<T>().
Note: The case is ignored.
To illustrate in a small example:
C# code:
[Flags]
enum Foo
{
Bar = 1,
Baz = 2
}
class AType
{
static void Kazaam(Foo foo) { ... }
}
Scheme code:
; same as Bar | Baz
(clr-static-call AType Kazaam '(Bar Baz))
; single value
(clr-static-call AType Kazaam 'Baz)
; same thing
(clr-static-call AType Kazaam '(Baz))
; no value (iow zero)
(clr-static-call AType Kazaam '())
If these are just simple flag, lists should suffice, else you can redefine the enum as an enum-set in Scheme which allows many set operations. Finally, you just use enum-set->list to get the list to pass as an argument as shown above.

Related

Comparing underlying (derived) types pointed-to by std::unique_ptr

I am writing unit tests to exercise various code paths involving a factory class.
The factory returns a std::unique_ptr to a base type:
class Base {};
class Derived1 : public class Base {};
class Derived2 : public class Base {};
std::unique_ptr<Base> Type::Factory(enum rtype) const {
switch(rtype) {
case d1: return std::make_unique<Derived1>();
case d2: return std::make_unique<Derived2>();
default: return std::make_unique<Derived1>();
}
}
So in the test I want to ensure that the correct type is returned (factories are breeding ground for cut'n'paste bugs).
Is there a way of checking what type is returned?
This: EXPECT_TRUE(typeid(Derived1), typeid(type.get()); is false because the type.get() is that of Base and not the rtype that was passed in.
This: EXPECT_TRUE(typeid(Derived1), typeid(type.get()); is false because the type.get() is that of Base and not the rtype that was passed in.
typeid( type.get() ) will get the typeid of the base pointer, i.e. the type that get() is declared as returning. To get the real dynamic type of the pointed-to object, whatever that may be, you should dereference the pointer:
typeid( *type.get() )
You need to use RTTI. The type is erased to Base when used.
You can do a dynamic cast to get the proper type, something like:
EXPECT_FALSE(dynamic_cast<Derived1*>(type.get()) == nullptr)
If dynamic_cast fails (type is not of Derived1) dynamic_cast will return a nullptr.

TypeError while attempting to sort a list of custom objects

I'm new to Dart and tried to get a class to implement List using the answers here, and tried to sort a list of these objects using the docs here. I deleted most of my code in an effort to post a MWE:
import 'dart:collection';
class Transaction<E> extends ListBase<E>{
DateTime when;
Transaction(this.when);
List innerList = new List();
int get length => innerList.length;
void set length(int length){
innerList.length = length;
}
void operator[]=(int index, E value){
innerList[index] = value;
}
E operator [](int index) => innerList[index];
void add(E value) => innerList.add(value);
void addAll(Iterable<E> all) => innerList.addAll(all);
}
class Forecaster{
var transactions;
Forecaster(){
this.transactions = new List<dynamic>();
}
void tabulate(){
transactions.sort((a,b) => a.when.compareTo(b.when)); //problem line?
for(var d in transactions){
d.asMap().forEach((index,content){
int len = content.toStringAsFixed(2).length;
});
}
}
void forecast(var forWhen){
var first = new Transaction(DateTime.now());
first.addAll([5,9]);
transactions.add(first);
}
}
void main(){
Forecaster myTest = new Forecaster();
var dub = myTest;
dub..forecast(DateTime.now())
..tabulate();
}
Running with the problem line results in an exception (Uncaught exception: TypeError: Closure 'Forecaster_tabulate_closure': type '(dynamic, dynamic) => dynamic' is not a subtype of type '(dynamic, dynamic) => int') I don't understand. If I comment out the problem line, the TypeError goes away. Is the TypeError because I did something wrong when defining Transaction? I'm attempting this with DartPad.
I'm new to Dart too, so my explanation might not be 100% on the money, but I believe, yes, the main issue is the type assignment of transactions. I think because you initialize it as a var, it is having trouble deducing the type of a.when, which is means it also doesn't know the type of a.when.compareTo(), and assumes dynamic. You are feeding the output of compareTo into List.sort() which is expecting an int from the anonymous function. Thus the error that it wanted an int but got dynamic.
The easiest way to address this is to initialize transactions with a more explicit type rather than as var:
List<Transaction> transactions;
Forecaster(){
this.transactions = new List<Transaction>();
}
Also, to confirm that it is an issue with it not being able to infer the return type of compareTo, I tried leaving your code as-is, but explicitly casting the result as int, and that also worked:
transactions.sort((a,b){
return (a.when.compareTo(b.when) as int);
});
Note: code like the above and using lots of dynamics and vars is in general not great practice with Dart - you lose a lot of the benefits of having a typed language. You might also notice that when you type in an IDE, you don't get methods auto-suggested when you do stuff like this - for example, until I changed transactions to an explicit type of list, typing a.when did not trigger autocomplete, and my IDE thought the type was dynamic, not DateTime.
Your problem is with the types. The code:
var transactions;
Forecaster(){
this.transactions = new List<dynamic>();
}
void tabulate(){
transactions.sort((a,b) => a.when.compareTo(b.when));
first declares transactions to have type dynamic.
Then you call sort on that with an argument which is inferred to have type dynamic Function(dynamic, dynamic) (because there is no clue available to say otherwise in the type of transactions).
However, the actual run-time type of transactions is List<Transaction>, and that requires a function argument of type int Function(Transaction, Transaction). The type dynamic Function(dynamic, dynamic) is not a sub-type of int Function(Transaction, Transaction) (the return type has to be a subtype of int for that to be the case) so you get a run-time error.
If you change transactions to have type List<Transaction>, then the type inference will have a clue when it gets to the function literal. It will infer that (a, b) => a.when.compareTo(b.when) in a context expecting int Function(Transaction, Transaction) will have that type.
Even if you just change transactions to List<dynamic>, it will still work, it will just make a.when.compareTo(b.when) be dynamic invocations.

Absolute addressing fields in a record type [duplicate]

This question already has answers here:
How do I translate a C union into Delphi?
(2 answers)
Closed 7 years ago.
I am attempting to interface with an embedded system that transmits and receives data with a fairly simple format but has strict sizing requirements.
In C, you would use a union type to expose some variable data with potentially different types located at the same spot in memory. Add a variable of this union type to a struct, and then you can (carefully) refer to that struct field with various names and types:
for simplicity, please ignore byte alignment and packing
typedef enum { F1_V1, F1_V2, F1_V3 } FLAG_1_T;
typedef enum { F2_V1, F2_V1 } FLAG_2_T;
typedef union
{
FLAG_1_T flag_1;
FLAG_2_T flag_2;
}
FLAG_T;
typedef struct
{
BYTE_T id;
INT32_T value;
FLAG_T flag;
}
DATA_ITEM_T;
So now I can interpret the flag field as either FLAG_1_T or FLAG_2_T.
I would like to use this same sort of approach in Delphi 2010. I've tried to accomplish this by using absolute addressing for fields of a record:
type
FLAG_1_T = ( F1_V1, F1_V2, F1_V3 );
FLAG_2_T = ( F1_V1, F1_V2 );
type
DATA_ITEM_T = record
id : BYTE_T;
value : INT32_T;
flag_1 : FLAG_1_T;
flag_2 : FLAG_2_T absolute flag_1;
end;
But this fails to compile with syntax error E2029 ';' expected but identifier 'absolute' found.
If I bring those flag declarations outside of the record type definition (but at the same scope as the record type def), it compiles fine:
note that this is useless for what I'm trying to accomplish
type
FLAG_1_T = ( F1_V1, F1_V2, F1_V3 );
FLAG_2_T = ( F1_V1, F1_V2 );
type
DATA_ITEM_T = record
id : BYTE_T;
value : INT32_T;
end;
var
flag_1 : FLAG_1_T;
flag_2 : FLAG_2_T absolute flag_1;
So why can't I do this within a record? Is there another way to accomplish this?
You can translate a C union to Delphi using a record type with a variant part:
type
FLAG_T = record
case Boolean of
False: (flag_1: FLAG_1_T);
True: (flag_2: FLAG_2_T);
end;

How can I see what the default value of a visit is?

Assume I have:
visit(p) {
case ...
default:
println("This should not happen. All elements should be catched. Check: <x>");
};
How can I print out (in this case as x) what could not be matched?
I tried:
x:default:
\x:default:
default:x:
\default:x:
Tx,
Jos
We have a library named Traversal that allows you to get back the context of a match. So, you can do something like this:
import Traversal;
import IO;
void doit() {
m = (1:"one",2:"two",3:"three");
bottom-up visit(m) {
case int n : println("<n> is an int");
default: {
tc = getTraversalContext();
println("Context is: <tc>");
println("<tc[0]> is not an int");
if (str s := tc[0]) {
println("<s> is a string");
}
}
}
}
tc is then a list of all the nodes back to the top of the term -- in this case, it will just be the current value, like "three", and the entire value of map m (or the entire map, which will also be a match for the default case). If you had something structured as a tree, such as terms formed using ADTs or nodes, you would get all the intervening structure from the point of the match back to the top (which would be the entire term).
For some reason, though, default is matching the same term multiple times. I've filed this as bug report https://github.com/cwi-swat/rascal/issues/731 on GitHub.
You could also try this idiom:
visit(x) {
case ...
case ...
case value x: throw "default case should not happen <x>";
}
The value pattern will catch everything but only after the others are tried.

Using __arglist with a varying set of named parameters

in my application I have 2 layers. The first layer is a C legacy exposing cdecl functions that use the "..." syntax for a varying parameter list. The only way I found to call these functions from my .Net layer (the second one) is using the DllImport technics. For example the C function below:
int myFunc(char* name, ...);
looks like that in C#:
[DllImport("MyDll.dll"),
CharSet = CharSet.Ansi,
CallingConvention = CallingConvention.Cdecl]
int myFunc(string name, __arglist);
My problem is that sometimes I want to call this function with 2 extra parameters but if one of them is NULL it won't be included in the argument list (my legacy code fails on NULL values). For example I want this call:
int foo(string name, string a, string b)
{
myFunc(name, __arglist(a, b));
}
{
foo("john", "arg1", null);
}
to be interpreted by C as
myFunc("john", "arg1");
Unfortunately doing something like that:
int foo(string name, string a, string b)
{
List<string> args = new List<string>();
if(a != null) args.Add(a);
if(b != null) args.Add(b);
myFunc(name, __arglist(args));
}
{
foo("john", "arg1", null);
}
is interpreted by C like that:
myFunc(name, args);
and not:
myFunc(name, args[0]);
Does anybody have any idea?
How does the C function know which one is the last parameter? It cannot know a priori how many parameters there are. It needs additional information. One common way for functions get the information they need is by parsing the included string parameter to count format specifiers, as in printf. In that case, if the format string only indicates that there is one extra parameter, then the function doesn't know the difference between a call that really had just one extra parameter and a call that had two or a call that had 20. The function should have the self-discipline to only read one parameter, since that's all the format string said there was. Reading more would lead to undefined behavior.
If what I've described is not the way your function works, then there's not much you can do on the calling end to solve it. But if it is how your function works, then there's nothing to do on the calling end, because there's no problem.
Another option, since you indicate that your "legacy code fails on null values," is to fix your legacy code so it doesn't fail anymore.
A third option is to simply write all four possibilities:
if (a != null) {
if (b != null)
return myFunc(name, a, b);
else
return myFunc(name, a);
} else {
if (b != null)
return myFunc(names, b);
else
return myFunc(names);
}
More than two optional parameters, though, and the code starts getting unwieldy.
Try converting your System.List ToArray() before wrapping it in __arglist
myFunc(name, __arglist(args.ToArray()));

Resources