Dart Metadata and symbols - dart

I am creating a library to emulate C's stdio library. Is working but the functions (2/3 of which are actually Function objects at the moment) look terrible. I am having a really difficult time figuring out Metadata, Symbols and Mirrors. From what I can tell, they are very useful and they might do what I need. So 3 questions:
Can InstanceMirrors be used like pointers?
Can either of them be used in a similar fashion to macros like those
in C (#define MAC / #define F_MAC(a, b))?
Is there a clean way to implement var_args* and polymorphic functions**? am hoping for something which the editor will actually recognize as a function.
Please include explanations and examples (I am pretty dense so if you don't include examples, you will likely be wasting your time).
*I already know about this: Creating function with variable number of arguments or parameters in Dart, I am hoping for something the editor will recognize as a function rather than an object.
**I am currently just using dynamic parameters and generating the behavior based on the types passed in at run-time, but that is, while effective, horrifying to look at and document.
Ideally I would like my documentation output to resemble this
// var_args hack
int printf (String format, ...) //C
// actually looks good
int vprintf (String format, List<dynamic> args) //C
// var_args hack
int fprintf (dynamic stream, String format, ...) //C
// var_args hack
int fnprintf (dynamic stream, int maxsize, String format, ...) //C
// actually looks good
int vfprintf (dynamic stream, String format, List<dynamic> args) //C
// actually looks good
int vfnprintf (dynamic stream, int maxsize, String format, List<dynamic> args) //C
// --1st first param optional so polymorphic is necessary, + var_args--
int sprintf (StringBuffer stream, String format, ...) //C
String sprintf (String format, ...)
// --1st first param optional so polymorphic is necessary, + var_args--
int snprintf (StringBuffer stream, int maxsize, String format, ...)//C
String snprintf (String format, int maxsize, ...)
// --1st first param optional so polymorphic is necessary--
int vsprintf (StringBuffer stream, String format, List<dynamic> args)//C
String vsprintf (String format, List<dynamic> args)
// --1st first param optional so polymorphic is necessary--
int vsnprintf(StringBuffer stream, int maxsize, String format, List<dynamic> args) //C
String vsnprintf(String format, int maxsize, List<dynamic> args)
// --1st first param optional so polymorphic is necessary--
int strftime(StringBuffer buffer, int maxsize, String format, DateTime date) //C
String strftime(int maxsize, String format, DateTime date)
int strftime(StringBuffer buffer, String format, DateTime date)
String strftime(String format, DateTime date)
// will need something like a pointer or reference
String vsprintf(String buffer, String format, List<dynamic> args) //C
Edit:
sorry, I was called away and didn't have time to my question. In order:
what I meant was something like this:
String f(String *arg0, int *arg1, double *arg2, bool *arg3)
currently I am doing:
String arg0 = ...;
int arg1 = ...;
double arg2 = ...;
bool arg3 = ...;
List<dynamic> args = [arg0, arg1, arg2, arg3];
f1(args);
arg0 = args[0];
arg1 = args[1];
arg2 = args[2];
arg3 = args[3];
List<dynamic> args0 = [arg0];
List<dynamic> args1 = [arg1];
List<dynamic> args2 = [arg2];
List<dynamic> args3 = [arg3];
f2(args0, args1, args2, args3);
arg0 = args0[0];
arg1 = args1[0];
arg2 = args2[0];
arg3 = args3[0];
I am hoping to find a better way
I would like to be able to do the equivalent of this:
#define private:
#define public:
#define enum class
so that I could:
enum E
{
static int VALUE_0 = 0;
static int VALUE_1 = 1;
static int VALUE_2 = 2;
static int VALUE_3 = 3;
int value;
}
class C
{
private:
int _private0;
int _private1;
int _private2;
int _private3;
public:
int _public0;
int _public1;
int _public2;
int _public3;
}
It essentially for commenting purposes (just curious)
yea, I know it works, I was just wondering if it was a better way.
P.S. Any good tutorials on mirrors, or Symbols?

Can InstanceMirrors be used like pointers?
import 'dart:math' as math;
import 'dart:mirrors' as mirr;
void main() {
math.Rectangle r = new math.Rectangle(10, 10, 20, 20);
mirr.InstanceMirror im = mirr.reflect(r);
var r2 = im.reflectee;
print('r top-left: ${r.topLeft}, r2 top-left: ${r2.topLeft}');
}
Can either of them be used in a similar fashion to macros like those in C (#define MAC / #define F_MAC(a, b))?
can you elaborate a bit more what you want to accomplish?
Is there a clean way to implement var_args* and polymorphic functions**? am hoping for something which the editor will actually recognize as a function.
I think the question/answer you linked to has all information about this topic

Related

Why a const list can't be used in a string literal when it can't be modified in any way?

void main() {
const list = [1, 2, 3];
const string = 'This is a $list'; // Error
}
When I can't assign list a new value and modify any of its elements, why can't I then use the list in my string literal?
Dart doesn't have a concept of saying that a method call can be evaluated at compilation time (in contrast to constexpr in C++). Therefore Dart cannot guarantee that calling a method on a const object returns another const object, and that includes the implicit call to .toString() when doing string interpolation.
For example, this is perfectly legal:
import 'dart:math';
final random = Random();
class Foo {
const Foo();
// Returns a string that is clearly not a compile-time constant.
#override
String toString() => random.nextInt(100).toString();
}
void main() {
const foo = Foo();
print('$foo');
const list = [foo, foo, foo];
print('$list');
}
Note that this doesn't apply to .toString() implementations for some built-in types (e.g. null, numeric, string, and boolean types) since they are known to produce constant values and because Dart does not allow creating derived classes from those types, so they cannot be overridden to do shenanigans like the above example.
It's an interesting question, because some const things can be interpolated into const strings. I checked out the Language Tour, and it gives this example, which is very close to your question:
// These work in a const string.
const aConstNum = 0;
const aConstBool = true;
const aConstString = 'a constant string';
// These do NOT work in a const string.
var aNum = 0;
var aBool = true;
var aString = 'a string';
const aConstList = [1, 2, 3];
const validConstString = '$aConstNum $aConstBool $aConstString';
// const invalidConstString = '$aNum $aBool $aString $aConstList';
The explanation given is that
Literal strings are compile-time constants, as long as any
interpolated expression is a compile-time constant that evaluates to
null or a numeric, string, or boolean value.
They don't explain why (what the technical reasons are, or the motivations for making the language work this way), but it's clear that a const list does not evaluate to "null or a numeric, string, or boolean value." So it just doesn't matter that your list is const—the string resulting from interpolation with that will not be a compile-time constant, so you can't use const with that string.

How to return two specific types from a generic method?

T getValue<T>(int i) {
if (T == String) return '$i'; // Error
return i; // Error
}
void main() {
var s = getValue<String>(1);
var i = getValue<int>(1);
}
I want getValue to return string if T is String and int otherwise. How to do that?
You can't restrict the type parameter to just int or String, so it will have to accept more than that (at least their least common supertype, Object, so basically any type).
It's not a particularly helpful way to code. It's possible, but not recommended:
T getValue<T>(int i) {
if (i is T) return i;
return "$i" as T;
}
This will return the int if T allows it (so T being any of int, or a super type of int, which is num, Object, dynamic or void, or any number of Comparable<X> wrappings around any any of those supertypes), and otherwise try to return a string. That will fail with a type error unless T is String (since we've already ruled out all supertypes of String).
You can still call it as getValue<bool>(42) and watch it fail, so the type argument doesn't help with correctness.
It's not particularly effective. I'd rather do:
dynamic getValue(int i, {bool toString = false}) {
if (toString) return "$i";
return i;
}
and call it as:
String x = getValue(42, toString: true); // Add `as String` if you disable downcasts.
int y = getValue(42); // And `as int` here.
The type parameter is really just making things harder. You are going to cast or type-check the result anyway, so might as well do it at the call point, rather than introduce type variables that aren't actually preventing misuse anyway.
(I'd probably just do two different functions, but I assume that there is a reason for wanting one function).
As I mentioned in the comments, I don't see any way that you could use your generic as the return type of your getValue function. Even assuming the return under the if statement worked, there is nothing that can be done about trying to return int i when List is passed as the type. You'll be trying to return an int as a List.
If you change it to dynamic, your code will work fine as it's just using the generic as another parameter.
dynamic getValue<T>(int i) {
if (T == String) return '$i';
return i;
}
void main() {
var s = getValue<String>(1);
var i = getValue<int>(1);
}

How to convert List<dynamic> to List<T> without getting warning from linter in Dart?

I wrote this code to convert dynamic list to Word list but linter says:
Omit type annotations for local variables. on 2nd line.
However if I omit type annotations, I get an error A value of type 'List<dynamic>' can't be returned from method 'convert' because it has a return type of 'List<Word>'.
It there any smarter way to convert?
static List<Word> convert(List<dynamic> words) {
final List<Word> wordsList = [];
words.forEach((v) {
final map = Map<String, dynamic>.from(v as Map<dynamic, dynamic>);
wordsList.add(Word.fromMap(map));
});
return wordsList;
}
Word.fromMap is:
Word.fromMap(Map<String, dynamic> map)
: text = map['text'] as String,
count = map['count'] as int;
To avoid the warning, and put the type on the right-hand side as the lint wants, just write:
final wordsList = <Word>[];
I assume words is JSON data, so the maps are already Map<String, dynamic>. Then you can also do everything in one line:
static List<Word> convert(List<dynamic> words) =>
[for (var v in words) Word.fromMap(v)];
Use the cast() method like this:
class Word {
final String text;
final int count;
static List<Word> convert(List<dynamic> words) {
final List<Word> wordsList = [];
words.cast<Map<dynamic, dynamic>>().forEach((v) { // <-- look here
final map = Map<String, dynamic>.from(v);
wordsList.add(Word.fromMap(map));
});
return wordsList;
}
Word.fromMap(Map<String, dynamic> map)
: text = map['text'] as String,
count = map['count'] as int;
}
It will ensure the casting are done on each element. Make sure the type are correct since it will else result in a type-cast error.

How to convert ascii value in integer to its character equivalent in flutter?

I am new to flutter and I just want to display a list of alphabets in a for loop. I just want to know how can I convert the integer to ascii character. I searched for this and I found dart:convert library, but I don't know how to use it.
I want something like -
for(int i=65; i<=90; i++){
print(ascii(i)); //ascii is not any method, its just to understand my question
}
It should print the letters from 'A' to 'Z'.
You don't need dart:convert, you can just use String.fromCharCode
print(String.fromCharCode(i));
More info: https://api.dartlang.org/stable/2.0.0/dart-core/String/String.fromCharCode.html
In Dart, use these 2 functions to convert from int (byte) to String (char) and vice versa.
int value = ';'.codeUnitAt(0); //get unicode for semicolon
String char = String.fromCharCode(value); //get the semicolon string ;
This ia exactly what you need to generate your alphabet:
import 'dart:core';
void RandomString() {
List<int> a = new List<int>.generate(26, (int index) => index + 65);
String f = String.fromCharCodes(a);
print(f);
}
void main() {
RandomString();
}
Also You can copy, paste and test it here https://dartpad.dartlang.org/

Extending Aero Glass in F# (PInvoke)

I'm working on a F# console application. In the properties I set the output type of application to Windows Application to hide the console. I also created a form to run in its place. Currently I only have a simple form with no controls. To make the form I added referances to System.Windows.Forms and System.Drawing and opened them along with System.Runtime.InteropServices.
The part that I don't know how to do is extending the aero-glass. There are loads of exaples on how to do it in C#. For example, here is the API call and MARGINS structure:
[StructLayout(LayoutKind.Sequential)]
public struct MARGINS
{
public int cxLeftWidth;
public int cxRightWidth;
public int cyTopHeight;
public int cyBottomHeight;
}
[DllImport("dwmapi.dll")]
pubic static extend int DwmExtendFrameIntoClientArea(IntPtr hWnd, ref MARGINS pMarInset);
The API call from Form_Load event:
MARGINS margins = new MARGINS();
margins.cxLeftWidth = 0;
margins.cxRightWidth = 100;
margins.cyTopHeight = 0;
margins.cyBottomHeight = 0;
int result = DwmExtendFrameIntoClientArea(this.Handle, ref margins);
This is what I've got so far in F#:
The API call and MARGINS structure:
[<StructLayout(LayoutKind.Sequential)>]
type MARGINS =
struct
val cxLeftWidth : int
val cxRightWidth : int
val cyTopHeight : int
val cyBottomHeigh t: int
new(left, right, top, bottom) = { cxLeftWidth = left; cxRightWidth = right; cyTopHeight = top; cyBottomHeigh = bottom } (*Is there any other way to do this?*)
end
[<DllImport("dwmapi.dll")>]
extend int DwmExtendFrameIntoClientArea(IntPtr hWnd, (*I need help here*))
The API call from Form_Load event:
let margins = new MARGINS(0, 100, 0, 0); (*Is there any other way to do this?*)
let result : int = DwmExtendFrameIntoClientArea(this.Handle, (*I need help here*))
I have been searching around but I can't find anything about using ref parameters like this in F#. I know this would be a lot easier to write in C# but the code behind the form will be easier to write int F# because it's a functional programing language and the whole program I'm writing is orientated around functions. I know this is purely decorative but please help.
In general, extern (AKA P/Invoke or platform invoke) definitions in F# use C-like syntax (and note that it's extern, not extend):
[<DllImport("dwmapi.dll")>]
extern int DwmExtendFrameIntoClientArea(nativeint hWnd, MARGINS& pMarInset)
This can then be used as follows:
let mutable margin = ...
let result = DwmExtendFrameIntoClientArea(this.Handle, &margin)
Note that the way that you have defined MARGINS is not quite analogous to the C# definition. The various val definitions are not mutable, and are actually properties rather than fields (though they're backed by fields, so it's probably not a big deal). If you want them to be mutable fields, you can add the mutable keyword after val for each field:
[<Struct; StructLayout(LayoutKind.Sequential)>]
type MARGINS =
val mutable cxLeftWidth : int
val mutable cxRightWidth : int
val mutable cyTopHeight : int
val mutable cyBottomHeight: int
(I've also used the Struct attribute instead of struct ... end, but that's just for brevity). You can initialize this like you do in C#, or using F#'s named arguments:
let mutable margin = MARGINS(cxRightWidth = 100)

Resources