Undo in D

2018-06-22 Thread DigitalDesigns via Digitalmars-d-learn
Is there any idiomatic undo designs in D that give a more natural 
implementation than the standard techniques?


Re: typeof on protected field

2018-06-17 Thread DigitalDesigns via Digitalmars-d-learn

On Sunday, 17 June 2018 at 02:29:12 UTC, Adam D. Ruppe wrote:

On Saturday, 16 June 2018 at 08:32:38 UTC, DigitalDesigns wrote:
I need to get the protected and private members for 
serialization.


This breaks encapsulation.

A better design would be to have a class know how to serialize 
itself via a serializable interface.


Yeah, but that is a lot of extra work when it is generally 
unnecessary and breaks encapsulation far more than a CT 
reflection based scheme. CT reflection should not have these same 
restrictions and encapsulation does not technically apply.


Encapsulation cannot reflect in a generic way. Reflection can be 
generic and hence handle any case.  OOP and Reflection are two 
different things and encapsulation is mainly for OOP. After all, 
encapsulation is optional and one can code so things are highly 
dependent... so why should reflection break in one case but not 
the other? One can easily deal with encapsulation in reflection 
if they desire but it shouldn't be forced as it take away many 
useful possibilities.



With proper CT reflection one does not have to touch any code and 
it can just work. With oop one has to modify the classes to 
support serialization. That's a huge difference.






Re: How do you test whether a variable is static or not?

2018-06-16 Thread DigitalDesigns via Digitalmars-d-learn

On Saturday, 16 June 2018 at 21:41:37 UTC, Jonathan M Davis wrote:
On Saturday, June 16, 2018 14:55:51 Steven Schveighoffer via 
Digitalmars-d- learn wrote:
On 7/30/16 8:47 AM, Jonathan M Davis via Digitalmars-d-learn 
wrote:
> I'm writing some serialization code where I need to skip 
> static variables. So, I have a symbol from a struct, and I'd 
> like to test whether it's static or not. Ideally, I'd be 
> able to do something like

>
> is(field == static)

std.traits.hasStaticMember ?

https://dlang.org/phobos/std_traits.html#hasStaticMember


Yeah. I wrote that, and it got added to Phobos. If you'll note, 
my post in this thread was from almost two years ago.


- Jonathan M Davis


doesn't work:

..\..\src\phobos\std\traits.d(3823): Error: class `app.A` member 
`z` is not accessible.


What is the point of introspection if one can't get information 
about a type due to it's protection level?


For example, how is one suppose to serialize a class that has 
protected and private members, which are common, when using 
properties?




Re: How do you test whether a variable is static or not?

2018-06-16 Thread DigitalDesigns via Digitalmars-d-learn

On Saturday, 30 July 2016 at 13:04:56 UTC, Ali Çehreli wrote:
On 07/30/2016 05:47 AM, Jonathan M Davis via 
Digitalmars-d-learn wrote:

> I'm writing some serialization code where I need to skip
static variables.
> So, I have a symbol from a struct, and I'd like to test
whether it's static
> or not.

static variables don't have the .offsetof property:

struct S {
int a;
static int b;
}


// Bonus question: should field be alias or string?
template isStaticVar(T, alias field)
{
enum isStaticVar = !__traits(compiles, mixin("T." ~ field ~ 
".offsetof"));

}

void main() {
static assert (!isStaticVar!(S, "a"));
static assert (isStaticVar!(S, "b"));
}

Ali


This doesn't work, treats fields in base classes as static.

One way to test if a member is static is if it it doesn't exist 
in tupleof... but this only returns the immediate members and so 
will fail.  I guess one will have to check all base types too and 
if it doesn't exist in any of then it should be static.


Why is it so hard to be able to get basic information like if a 
type is static or not?


typeof on protected field

2018-06-16 Thread DigitalDesigns via Digitalmars-d-learn

mixin(`foo!(typeof(T.`~m~`));

gives me an error about m being protected.

Error: class `X` member `name` is not accessible.

this also happens when using __traits(getMember, T, m); X is in 
another module. Works fine when X is in the same module.


I need to get the protected and private members for serialization.


Re: Get static fields!

2018-06-16 Thread DigitalDesigns via Digitalmars-d-learn

On Saturday, 16 June 2018 at 07:56:22 UTC, Bauss wrote:

On Saturday, 16 June 2018 at 05:05:19 UTC, DigitalDesigns wrote:
tupleof does not return static fields as does not Fields. 
Currently the only method seems to be use allMembers, but that 
returns members requiring filtering, which there is no good 
filtering checks. I'd simply like to get all the fields of a 
type, static and non-static.


What about derivedMembers?


But I don't want derived members!



Get static fields!

2018-06-15 Thread DigitalDesigns via Digitalmars-d-learn
tupleof does not return static fields as does not Fields. 
Currently the only method seems to be use allMembers, but that 
returns members requiring filtering, which there is no good 
filtering checks. I'd simply like to get all the fields of a 
type, static and non-static.


Storing temp for later use with ranges

2018-06-15 Thread DigitalDesigns via Digitalmars-d-learn
Does ranges have the ability to store a temp value in a "range 
like way" that can be used later?


The idea is to avoid having to create temp variables. A sort of 
range with "memory"





returning to thrown

2018-06-12 Thread DigitalDesigns via Digitalmars-d-learn
I have to modify preexisting code. As of now, the code fails and 
throws an exception at some point. I need to prevent the code 
from throwing(easy) but signal to the user of the code some 
notification(hard).


It would be cool if I could throw an exception as if the code 
yielded and it could be continued if I want.


simplified pseudoscope

void load()
{
  read(somefile);  <-- throws if somefile does not exist

  ...
}

goes in to

void load()
{
  try
  {
file = read(somefile);  <-- throws if somefile does not exist
  }
  catch
  {
 file = null;
 throw new yeildException!4("File not found!");
  }

  yieldException!4:

  ...
}


then when one catches a yieldException somehow they can resume at 
the proper location to continue the function as if the exception 
never happened.


Because I don't have access to all the code nor do I want to 
rewrite large portions of it, it is impossible to redesign 
everything to make things work correctly.



I believe throw unwinds the stack which makes a yield semantic 
impossible?


I can't use a callback(too ugly and it would require modify huge 
amounts of code to add them everywhere unless it were global):



void load()
{
  try
  {
file = read(somefile);  <-- throws if somefile does not exist
  }
  catch
  {
 file = null;
 userCallback("File not found!");
  }


  ...
}


Any devious D tricks that can be used to give the sort of 
yieldThrow I'm looking for?



BTW, if D had a yieldThrow which behaved like throw but saved the 
stack to rewind back to the point of yieldThrow, then one could 
simply do



void load()
{
  try
  {
file = read(somefile);  <-- throws if somefile does not exist
  }
  catch
  {
 yieldThrow new yeildException!4("File not found!");
 // code returned back to this point when yieldThrow finished 
doing what it does.

 file = null;
  }


  ...
}


Remember, these errors occur inside some large processing(of a 
file) which might error depending on dependencies.  Some of these 
errors are not critical and I can't reparse the file each time 
because the same error will occur. I simply need to ignore the 
errors. I have access to the code where I can ignore them but I 
need some nice way to inform the user of the process that 
something didn't go as planed. Again, this wasn't defined in to 
the original code and it it already has it's own error handling.


Re: Orange check failling all of a sudden

2018-06-12 Thread DigitalDesigns via Digitalmars-d-learn
Also, is there any way to have a field as optional? Right now 
when I update a filed in a serialized type the app crashes 
because it can't find the field in the serialized data(since it 
was just added in the code). This requires either regenerating 
the data or manually adding the serialized field to each entry... 
both are impractical.


It would be nice to disable missing fields from throwing. While I 
could catch one error it would be a pain to try and catch an 
arbitrary number of them.


Maybe an attribute is better used:

@allowDefaultSerialized






Re: Orange check failling all of a sudden

2018-06-11 Thread DigitalDesigns via Digitalmars-d-learn
I also get a lot of inout's attached to key names. Seems 
excessive but

inout(inout(double)[])


/>




Maybe they are necessary but seems like they are redundant.


Orange check failling all of a sudden

2018-06-11 Thread DigitalDesigns via Digitalmars-d-learn
Changed some things in my app but unrelated to serialization and 
now my app fails when trying to read the xml that was generated 
at the output of the previous run.


Where it is failing is here:

void checkSpace(ref string s) @safe pure // rule 3
{
import std.algorithm.searching : countUntil;
import std.ascii : isWhite;
import std.utf : byCodeUnit;

mixin Check!("Whitespace");
ptrdiff_t i = s.byCodeUnit.countUntil!(a => !isWhite(a));
if (i == -1 && s.length > 0 && isWhite(s[0]))
s = s[$ .. $];
else if (i > -1)
s = s[i .. $];
if (s is old) fail();
}

s =
="1.0" encoding="UTF-8"?>



Actual xml data(first 3 lines):






It seems odd that it should fail when munching whitespace. It 
seems that the checker is getting off to a bad start from the get 
go.




-		[orange.xml.PhobosXml.CheckException]	0x03135880 
{err=0x, tail="="1.0" encoding="UTF-8"?>



orange.xml.PhobosXml.CheckException
+		orange.xml.PhobosXml.XMLException	0x03135880 
{}	orange.xml.PhobosXml.XMLException

err 0x  orange.xml.PhobosXml.CheckException
+   tail"="1.0" encoding="UTF-8"?>


   ...  const(char)[]
+   msg "Whitespace"  const(char)[]
line0   uint
column  0   uint


This was all working fine before and I'm not sure how it broke. 
The xmllint shows the xml is well formed so this is buggy code.



Note that if I also remove all the xml inside data then the same 
error occurs, so this is my xml:








that still fails when checking whitespace.


Re: Orange check failling all of a sudden

2018-06-11 Thread DigitalDesigns via Digitalmars-d-learn

and if I completely remove the check then everything works fine.


*/
class DocumentParser : ElementParser
{
string xmlText;

/**
* Constructs a DocumentParser.
*
* The input to this function MUST be valid XML.
* This is enforced by the function's in contract.
*
* Params:
*  xmlText_ = the entire XML document as text
*
*/
this(string xmlText_)
in
{
assert(xmlText_.length != 0);
try
{
// Confirm that the input is valid XML
//check(xmlText_); // COMMENTED OUT!
}
catch (CheckException e)
{
// And if it's not, tell the user why not
assert(false, "\n" ~ e.toString());
}


Re: WTF! new in class is static?!?!

2018-06-07 Thread DigitalDesigns via Digitalmars-d-learn
On Thursday, 7 June 2018 at 23:08:22 UTC, Steven Schveighoffer 
wrote:

On 6/7/18 6:58 PM, DigitalDesigns wrote:
On Thursday, 7 June 2018 at 21:57:17 UTC, Steven Schveighoffer 
wrote:

On 6/7/18 5:07 PM, DigitalDesigns wrote:

class A;

class B
{
    A a = new A();
}

auto b1 = new B();
auto b2 = new B();

assert(b1.a == b2.a)!!


Yep, long-standing issue: 
https://issues.dlang.org/show_bug.cgi?id=2947


Almost a decade old!



wait! everyone is saying it is a feature! So, which is it, a 
feature or a bug?!?!?


It's a feature that you can assign a static initializer to a 
class or struct member and have that work at compile time 
(using CTFE).


But when it's a reference to mutable data, it's a bug. Just the 
idea that you have implicitly shared data if you create 
instances in multiple threads should make it obviously a bug.


Even back then it was a debate, look at the bug report. But 
it's definitely a bug. Just hard to close since it will 
probably break a lot of code.


-Steve


I would expect that using a static initialize would not break as 
much code going from immutable to mutable than the other way 
around. Someone should have been smart enough to create a static 
new so both methods could have been implemented in a sane way.


Re: WTF! new in class is static?!?!

2018-06-07 Thread DigitalDesigns via Digitalmars-d-learn
On Thursday, 7 June 2018 at 21:57:17 UTC, Steven Schveighoffer 
wrote:

On 6/7/18 5:07 PM, DigitalDesigns wrote:

class A;

class B
{
    A a = new A();
}

auto b1 = new B();
auto b2 = new B();

assert(b1.a == b2.a)!!


Yep, long-standing issue: 
https://issues.dlang.org/show_bug.cgi?id=2947


Almost a decade old!

-Steve


wait! everyone is saying it is a feature! So, which is it, a 
feature or a bug?!?!?


WTF! new in class is static?!?!

2018-06-07 Thread DigitalDesigns via Digitalmars-d-learn

class A;

class B
{
   A a = new A();
}

auto b1 = new B();
auto b2 = new B();

assert(b1.a == b2.a)!!


I'm glad I finally found this out! This is not typical behavior 
in most languages is it?


I'd expect it to be translated to something like

class B
{
   A a;
   this()
   {
   a = new A();
   }
}

In C# it is different, can't remember if it is different in C++. 
This has caused bugs in my code because the fields are all 
pointing to the same data when I expected them to each have 
unique data ;/


This method is error prone and the behavior should be reversed, 
it should not break the majority of code. If one wants the 
current behavior then static new could be used or something else.





Re: New programming paradigm

2018-06-03 Thread DigitalDesigns via Digitalmars-d-learn

On Sunday, 3 June 2018 at 16:36:52 UTC, Simen Kjærås wrote:

On Sunday, 3 June 2018 at 14:57:37 UTC, DigitalDesigns wrote:

On Sunday, 3 June 2018 at 09:52:01 UTC, Malte wrote:
You might want to have a look at 
https://wiki.dlang.org/Dynamic_typing
This sounds very similar to what you are doing. I never 
really looked into it, because I prefer to know which type is 
used and give me errors if I try to do stupid things, but I 
think it's a cool idea.


No, this is not what I'm talking about, although maybe it 
could be related in some way.


Actually, it sort of is. Your mapEnum is essentially the same 
as std.variant.visit 
(https://dlang.org/phobos/std_variant#.visit), and 
std.variant.Algebraic is the type that encapsulates both the 
runtime tag and the void[] containing the data of unknown type.


Now, there may be many important differences - Algebraic 
encapsulates the data and tag, which may or may not be what you 
want, visit only takes one algebraic argument, mapEnum may be 
faster, more or less generic, etc. The idea of converting a 
run-time value to a compile-time value is the same, though.


--
  Simen


I didn't know that variants had those functions! pretty nice. 
Yes, it is similar to what I'm doing. Same principles but just a 
little different perspective. I use enums, UDA's, and templates 
rather than a Algebraic and delegates.


The difference is that the enum stores only the type information 
rather than the variable and the type info that Algebraic stores.


If I were to have know about this before I might have used it 
instead and everything would have probably been fine.


The only thing is that the enum version lets me store the type 
info separately than with the data. When several variables depend 
on the type id I think it will make it a little easier than 
having to manage several Algebraic type info's across several 
variables to sync them.


For example

dataType type;
void[] in, out;

rather than

Algebraic!(type1,..., typen) in, out;

and then having to make sure the types are synced between in and 
out. At least in my case it might be a little easier. Also my way 
uses a templated function directly rather than an array of 
lambads, although they are equivalent:


Algebraic!(string, int) variant;

variant.visit!((string s) => cast(int) s.length, (int i)=> 
i)();


which could be written as

variant.visit!((string s) => foo(s), (int i)=> foo(i))();

auto foo(T)(T t) { }


would become

enum variant
{
@("int") _int,
@("string") _string,
}

mixin(variant.MapEnum!("foo")());

auto foo(T)(T t) { }


So, they definitely are very similar and actually might be 
identical. I haven't used Algebraic and visit any to know.


What I do know is that for several Algebraics you would have to 
do something like


variant.visit!((string s) => variant2.visit!((double d) => { 
foo(s,d); })), (int i)=> foo(i))();


etc. Which is creating the nested switch structure and can become 
complicated while my method still remains one line but foo just 
takes more than one template parameter. My feeling is mine is a 
little less robust since it's more for specific types of code 
while visit is a little more general. Mainly because of the hard 
coding of the mixin structure.







pipeProcess failing

2018-06-03 Thread DigitalDesigns via Digitalmars-d-learn

I'm calling pipe process using

pipeProcess([AliasSeq!args], Redirect.stdout | Redirect.stdin);

where args is a tuple.


Everything works when I pass each argument individually. If I 
combine any args using a space it fails or if I pass an argument 
with "".


So I guess something like this

pipeProcess(["dmd", "", "-m32 -JC:\"], Redirect.stdout | 
Redirect.stdin);


will fail while

pipeProcess(["dmd", "-m32", "-JC:\"], Redirect.stdout | 
Redirect.stdin);


works.

Is this a bug or something else going on I'm not aware of?

I'm just wrapping pipe process in a function foo(Args...)(Args 
args) and calling it like foo("dmd", "", "-m32 -JC:\").


The reason why it is a problem is that it will simplify some code 
to be able to combine some arguments.






Re: New programming paradigm

2018-06-03 Thread DigitalDesigns via Digitalmars-d-learn

On Sunday, 3 June 2018 at 09:52:01 UTC, Malte wrote:

On Saturday, 2 June 2018 at 23:12:46 UTC, DigitalDesigns wrote:

On Thursday, 7 September 2017 at 22:53:31 UTC, Biotronic wrote:

[...]


I use something similar where I use structs behaving like 
enums. Each field in the struct is an "enum value" which an 
attribute, this is because I have not had luck with using 
attributes on enum values directly and that structs allow 
enums with a bit more power.


[...]


You might want to have a look at 
https://wiki.dlang.org/Dynamic_typing
This sounds very similar to what you are doing. I never really 
looked into it, because I prefer to know which type is used and 
give me errors if I try to do stupid things, but I think it's a 
cool idea.


No, this is not what I'm talking about, although maybe it could 
be related in some way.


What I am talking about is hooking up a runtime variable that can 
take a few values, such as from an enum and have those be mapped 
to a compile time template value.


This way you get full static time checking of runtime code. Seems 
impossible? It's not!


What it does is leverage D's meta programming engine to deal with 
all the routine possiblities.


A large switch statement is what makes the runtime to compile 
time magic happen


int x;

switch(x)
{
default: foo!void();
case 0: foo!int();
case 1: foo!double();
etc...
}

See how the switch maps a runtime value x to a templated function 
foo?


we then can handle the x values with foo

void foo(T)()
{
   // if x = 0 then T = int
   // if x = 1 then T = double


}

But inside foo we have T, the template variable that is the 
compile time representation of the dynamic variable x. Remember, 
x's value is unknown at compile time... the switch is what maps 
the runtime to the compile time.


But in foo, because we have T, the type system all works fine.

What makes this very useful that we can call templated functions 
using T and the meta engine will pick the right template function 
specialization.


e.g.,

void bar(S)()
{

}


can be used inside foo by calling bar!T(). It doesn't seem like 
much here if you had to use x it would be a pain. Either you 
would have to manually create switches or create a rats nest of 
if statements. But we never have to worry about that stuff when 
using the above method because it is exactly like programming at 
compile time as if x a compile time value(like say, just int).


It works great when you have several template variables and just 
want everything to work together without having to go in to much 
trouble:



foo(A,B)()
{
   B b = 4;
   bar!(A)(b)
}


suppose A can come from int, double, and B from float and long

That is 4 different combinations one would normally have to 
represent. Not a big deal until you have to handle every 
combination.



Suppose you are working with void arrays. They contain types but 
you don't know the type except after compile time.


Without using this technique you have to use casts and tricks and 
you'll find out if you screwed up some typing stuff at runtime. 
Using this technique you will not have a void array but a T[] 
with T being any of the possible types that you specify using 
UDA's.


if you could

if (x == 0)
{
foo(cast(int[])a);
} else

if (x == 1)
{
foo(cast(double[])a);
} else


but I can do that with one line which simply generates the switch 
for me. Really all I'm doing is hiding the switch so it all looks 
like some magic is happening in one line. But the fact that it 
becomes really simple to do seems to open up the use of it and 
conceptually on can then think of "x" as a compile time variable 
that can take on several possibilities.






Re: New programming paradigm

2018-06-02 Thread DigitalDesigns via Digitalmars-d-learn

On Thursday, 7 September 2017 at 22:53:31 UTC, Biotronic wrote:
On Thursday, 7 September 2017 at 16:55:02 UTC, EntangledQuanta 
wrote:
Sorry, I think you missed the point completely... or I didn't 
explain things very well.


I don't think I did - your new explanation didn't change my 
understanding at least. This indicates I'm the one who's bad at 
explaining. Ah well.


The point of my post was mostly to rewrite the code you'd 
posted in a form that I (and, I hope, others) found easier to 
understand.



I see no where in your code where you have a variant like type.


True. I've now rewritten it to use std.variant.Algebraic with 
these semantics:


auto foo(T1, T2)(T1 a, T2 b, int n) {
import std.conv;
return T1.stringof~": "~to!string(a)~" - "~T2.stringof~": 
"~to!string(b);

}

unittest {
import std.variant;
Algebraic!(float, int) a = 4f;
Algebraic!(double, byte) b = 1.23;

auto res = varCall!foo(a, b, 3);
assert(res == "float: 4 - double: 1.23");
}

template varCall(alias fn) {
import std.variant;
auto varCall(int n = 0, Args...)(Args args) {
static if (n == Args.length) {
return fn(args);
} else {
auto arg = args[n];
static if (is(typeof(arg) == VariantN!U, U...)) {
foreach (T; arg.AllowedTypes) {
if (arg.type == typeid(T))
return varCall!(n+1)(args[0..n], 
arg.get!T, args[n+1..$]);

}
assert(false);
} else {
return varCall!(n+1)(args);
}
}
}
}

Sadly, by using std.variant, I've given up on the elegant 
switch/case in exchange for a linear search by typeid. This can 
be fixed, but requires changes in std.variant.


Of course, it would be possible to hide all this behind 
compiler magic. Is that desirable? I frankly do not think so. 
We should be wary of adding too much magic to the compiler - it 
complicates the language and its implementation. This is little 
more than an optimization, and while a compiler solution would 
be less intrusive and perhaps more elegant, I do not feel it 
provides enough added value to warrant its inclusion.


Next, I'm curious about this code:


void bar(var t)
{
writeln("\tbar: Type = ", t.type, ", Value = ", t);
}

void main()
{
   bar(3); // calls bar as if bar was `void bar(int)`
   bar(3.4f); // calls bar as if bar was `void bar(float)`
   bar("sad"); // calls bar as if bar was `void bar(string)`
}


What does 'var' add here, that regular templates do not? 
(serious question, I'm not trying to shoot down your idea, only 
to better understand it) One possible problem with var here (if 
I understand it correctly) would be separate compilation - a 
generated switch would need to know about types in other source 
files that may not be available at the time it is compiled.


Next:


var foo(var x)
{
   if (x == 3)
   return x;
   return "error!";
}


This looks like a sort of reverse alias this, which I've argued 
for on many occasions. Currently, it is impossible to implement 
a type var as in that function - the conversion from string to 
var would fail. A means of implementing this has been discussed 
since at least 2007, and I wrote a DIP[1] about it way back in 
2013. It would make working with variants and many other types 
much more pleasant.


[1]: https://wiki.dlang.org/DIP52


I use something similar where I use structs behaving like enums. 
Each field in the struct is an "enum value" which an attribute, 
this is because I have not had luck with using attributes on enum 
values directly and that structs allow enums with a bit more 
power.


When a runtime value depends on these structs one can build a 
mapping between the values and functional aspects of program. 
Since D has a nice type system, one can provide one templated 
function that represents code for all the enum values.



E.g.,

enum TypeID // actually done with a struct
{
   @("int") i, @("float") f
}


struct someType
{
   TypeID id;
}

someType.id is runtime dependent. But we want to map behavior for 
each type.


if (s.id == TypeID.i) fooInt();
if (s.id == TypeID.f) fooFloat();

For lots of values this is tedius and requires N functions. 
Turning foo in to a template and autogenerating the mapping using 
mixins we can get something like


mixin(MapEnum!(TypeID, "foo")(s.id))

which generates the following code:

switch(s.id)
{
   case TypeID.i: foo!int(); break;
   case TypeID.f: foo!float(); break;
}


and of course we must create foo:

void foo(T)()
{

}


but rather than one for each enum member, we just have to have 
one. For certain types of code, this works wonders. We can treat 
runtime dependent values as if they were compile time values 
without too much work. MapEnum maps runtime to compile time 
behavior allowing us to use use templates to handle runtime 
variables. T in foo is actually acting in a runtime fashion 
depending on the value of id.



Re: Setter chaining

2018-05-30 Thread DigitalDesigns via Digitalmars-d-learn

The above idea can be emulated in code, abiet ugly and useless:

https://dpaste.dzfl.pl/bd118bc1910c




import std.stdio;

struct CT(A,B)
{
A v;
B t;
alias v this;

B opUnary(string s)() if (s == "~")
{
return t;
}

A opUnary(string s)() if (s == "*")
{
return v;
}

}


class C
{
int q;
	CT!(int, typeof(this)) foo() { q = 3; CT!(int, typeof(this)) v; 
v.t = this; v.v = q; return v; }
	CT!(int, typeof(this)) bar(int y) { q = q + y; CT!(int, 
typeof(this)) v; v.t = this; v.v = q; return v; }

}


void main()
{
C c = new C();

auto x = *((~c.foo()).bar(6));



writeln(x);
}

With a language implementation, all one would need is a symbol, 
using #,


everything would simplify to


class C
{
int q;
int foo() { q = 3; return q; }
int bar(int y) { q = q + y; return q;}
}

auto x = c.#foo().bar(6);






Re: Setter chaining

2018-05-30 Thread DigitalDesigns via Digitalmars-d-learn
On Wednesday, 30 May 2018 at 15:46:36 UTC, Steven Schveighoffer 
wrote:

On 5/30/18 10:49 AM, DigitalDesigns wrote:

Does it sound good?

class X
{
    double x;
    @property X foo(double y) { x = y; return this; }

    @property X bar(double y) { x = y + 5; return this; }
}

void main()
{
 X x = new X();
 x.foo(3).bar(4);
}


It sort of emulates UFCS but I'm not sure if it's more trouble 
than it's worth.



I figure it would be better than just returning void as it 
provides the option to chain but not sure if it will come back 
to bite me.


Yes, I do this kind of stuff, but you need to word your 
functions correctly.


I would avoid @property there, as this implies you should use 
it like:


x.foo = 5;

and if you return a reference to the type itself, it will read 
weird if you do it that way:


auto five = (x.foo = 5);

Here the name of the function is really really important.

In my use case, I am kind of using it in an SQL builder type, 
where each time you call a method it adds some piece of the 
query. Like:


auto query = table.select("id, name").where("foo = 
5").orderBy("name");


-Steve


Well, what I mean is to be able to have the ability to assign 
like a field or a function.



sometimes I might want to use it as a property like

x.foo = 5;

and sometimes like a method

x.foo(5).foo(8);

for chaining.

Rather than having to to create setfoo and such.

Since D allows both syntaxes to be used, rather than returning 
void, turning parenting object allows the chaining to take place.


Since the trick here is to be consistent, all setters must follow 
this principle, it shouldn't be a problem with consistency.




auto five = (x.foo = 5);


I wouldn't do that,just doesn't look right but I see your point.

What would be cool is if D had some special way to return the 
object of the class the setter was in.


auto x = (@x.foo = 5);

Here @ returns x but first computes x.foo = 5;.

In a way, it is like "this". @ gets the "this" of the function. 
Could work on any function:


class Y
{
   void foo();
   @property int baz();
   @property double bar(int x);
}

y.@foo() returns y;
y.@baz() returns y;
y.@bar(3) returns y;

Essentially one could few all functions as returning this and the 
value in a tuple and be default the value is returned and using a 
"selector" character will return this.


class Y
{
   Tuple!(void, typeof(this)) foo();
   Tuple!(int, typeof(this)) baz();
   Tuple!(double, typeof(this)) bar(int x);
}

y.foo()[1] returns y;
...

The compiler could simplify all this and by putting this in a 
register it could be be quite fast. In fact, since these are 
member functions and this is passed it will just fall through so 
very little overhead. The compiler can also optimize the code. 
Might take a bit to verify all the corner cases but would 
probably be useful once people could use it and get used to it.


@, $, |, ?, ! or many symbols could be used without ambiguity 
because a dot will always preceded them.











Setter chaining

2018-05-30 Thread DigitalDesigns via Digitalmars-d-learn

Does it sound good?

class X
{
   double x;
   @property X foo(double y) { x = y; return this; }

   @property X bar(double y) { x = y + 5; return this; }
}

void main()
{
X x = new X();
x.foo(3).bar(4);
}


It sort of emulates UFCS but I'm not sure if it's more trouble 
than it's worth.



I figure it would be better than just returning void as it 
provides the option to chain but not sure if it will come back to 
bite me.






Re: Build interface from abstract class

2018-05-30 Thread DigitalDesigns via Digitalmars-d-learn

On Wednesday, 30 May 2018 at 10:31:27 UTC, Simen Kjærås wrote:

On Monday, 28 May 2018 at 20:13:49 UTC, DigitalDesigns wrote:
I do not think this is a problem in D. Infinite recursion can 
always be terminated with appropriate means.


1. Use attributes. methods in class A should be marked as 
being for the interface. When added to the interface they will 
not have the attribute so will not be picked up again.


2. Your method of function creation does not pick up 
attributes and other factors so it is weak.


Here is my solution that does not solve problem 2:

[Neat stuff]


Neat, but as you say it doesn't handle attributes or UDAs. The 
use of stringof is also a red flag - the same name can apply to 
different types in different scopes, and aliases may confuse 
it. Here's a version that solves both of those issues:



import std.array : join;
import std.meta : ApplyLeft, staticMap, Filter, Alias;
import std.traits;

enum isPublic(alias overload) = Alias!(__traits(getProtection, 
overload) == "public");


interface InterfaceFromClass(T, alias filter = isPublic)
{
static foreach (overload; Filter!(filter, 
staticMap!(ApplyLeft!(MemberFunctionsTuple, T), 
__traits(derivedMembers, T
mixin("@(__traits(getAttributes, overload)) 
"~attributes!overload~" ReturnType!overload 
"~__traits(identifier, overload)~"(Parameters!overload);");

}

string attributes(alias overload)()
{
enum attrs = Filter!(ApplyLeft!(hasFunctionAttributes, 
overload),
"pure", "nothrow", "ref", "@property", "@trusted", 
"@safe", "@nogc", "@system", "const", "immutable", "inout", 
"shared", "return", "scope");

return [attrs].join(" ");
}

alias A = InterfaceFromClass!C;

abstract class C : A
{
int n;
@("InterfaceMembers")
{
@(3) ref int foo(ref int a) { return n; }
@(19) @safe void bar() { }
}
}

// https://issues.dlang.org/show_bug.cgi?id=18915
// class D : C {}

static assert([__traits(allMembers, A)] == ["foo", "bar"]);
static assert(functionAttributes!(A.foo) == 
functionAttributes!(C.foo));
static assert(functionAttributes!(A.bar) == 
functionAttributes!(C.bar));

static assert(is(Parameters!(A.foo) == Parameters!(C.foo)));
static assert(is(Parameters!(A.bar) == Parameters!(C.bar)));

Note the link to issue 18915 (that's your 'string mixin output 
works...' post). I believe if we can fix that, the above should 
work.


--
  Simen


Yeah! with a little work you can include fields in the 
interfacemembers because they will be ignored.


I see no reason to have to declare an interface in D except in 
rare occasions! One should be able to abstract out an interface 
from a class or abstract class and use it as the base only for 
others to use. If a program was "sealed" there would be no real 
point in using interfaces(assuming it was designed to perfection) 
except to get around the diamond problem, which is what 
interfaces solve but in the process have forced us to duplicate 
code.


The above technique alleviates that problem greatly. It's still 
bring the members inside the interface because it allows one to 
add final, static, and normal members if desired, although, this 
can be done by using another interface and inheriting from that.




Re: Build interface from abstract class

2018-05-29 Thread DigitalDesigns via Digitalmars-d-learn

On Wednesday, 30 May 2018 at 01:46:30 UTC, Chameleon wrote:

On Monday, 28 May 2018 at 20:13:49 UTC, DigitalDesigns wrote:



Here is my solution that does not solve problem 2:


import std.stdio;

[...]



this is not programming. this is witchcraft!



Just call me Dandalf the D Slayer!

At least I finally got it to work. It's terrible that I have to 
use import and read the file in directly to do this ;/ It is 
working though.


Re: Build interface from abstract class

2018-05-29 Thread DigitalDesigns via Digitalmars-d-learn

On Tuesday, 29 May 2018 at 20:53:14 UTC, DigitalDesigns wrote:

On Tuesday, 29 May 2018 at 20:26:52 UTC, arturg wrote:

On Tuesday, 29 May 2018 at 19:06:24 UTC, DigitalDesigns wrote:

On Monday, 28 May 2018 at 22:15:40 UTC, arturg wrote:

this might help you,
https://dpaste.dzfl.pl/2cf844a11e3f

you can use them to generate the functions as strings.


Thanks,

So, the problem I'm having is that I cannot use the generated 
interface for the abstract class because the abstract class 
needs the interface defined. I need to be able to forward 
define the interface then extend it.


D doesn't like this

main.d(10): Error: interface `main.B` base `A` is forward 
referenced


interface A;
mixin(Generate!(B,A));
interface B : A
{

}

abstract class C : B
{

}



would it work if you define the interface but mixin the 
members?


interface A
{
mixin(InterfaceFromClass!C);
}


Yes, I made a post about it but it didn't get through or I 
forgot to send ;/


Doing it this way solves the original problems but creates a 
new problem in that any class that inherits from an abstract 
class that implements A doesn't work.


interface A
{
mixin(InterfaceFromClass!C);
}

abstract class B : A
{
A foo() { return this; }
int bar() { return 3; }
}


class C : B
{
// compiler says foo, bar not implemented
}


so, instead

interface A
{
mixin(InterfaceFromClass!C);
}

abstract class B
{
A foo() { return this; } // requires cast
int bar() { return 3; }
}


class C : B, A
{

}


works but requires casting this in B which happens to work in 
C. So It is a fessible solution but I'm not sure why the 
compiler things the first case doesn't implement the methods 
when it clearly does. I think it looks at A and doesn't compute 
the mixin first when parsing C because if I put the output of 
the mixin directly it works. Probably a bug...




This method, which imports the source code and extracts the 
members works but is very fragile and requires using -J:




// Directly copies the data to the interface with a few hacks to 
fix the bug from the original, it excepts a well formatted input



template InterfaceFromClass(alias T)
{

string InterfaceFromClass(string file = __FILE_FULL_PATH__)()
{
string res;
import std.path, std.string, std.algorithm;
enum data = import(file.baseName);
enum mc = "abstract class "~T.stringof~" : ";
enum im = `@("InterfaceMembers")`;
int level = 0;
auto baseIndentLevel = -1;
int funcIndentLevel = -1;
foreach(v; data.splitLines)
{
string l = v;
auto indentLevel = l.length - l.stripLeft().length;
auto ll = l.strip();
if (ll.length == 0) continue;

			//res ~= to!string(l.length) ~"\n" ~ l[0..min(mc.length, 
l.length)] ~ "\n";
			if (level == 0 && ll.length >= mc.length && 
ll[0..min(mc.length, ll.length)] == mc) { baseIndentLevel = 
indentLevel; level = 1; continue; }	// Finds "abstract class  
: "
			if (level == 1 && ll.length >= im.length && 
ll[0..min(im.length, ll.length)] == im) { level = 2; continue; 
}	// Finds "@("InterfaceMembers))" near by

if (level >= 2 && l == "}") break;
if (level == 2 && ll.length > 1)
{
if (funcIndentLevel < 0) funcIndentLevel = 
indentLevel;
if (funcIndentLevel < indentLevel) continue;

// A simple function definition(ends with a 
');')
if (!ll.canFind("=") && l.length > 2 && l[$-2..$] == ");") { 
res ~= l ~ "\n"; continue; }

// ignore fields(assumes it has no {, } but 
ends with a ';')
if (!ll.canFind("{") && l[$-1] == ';' && ll[$-2..$] != "};") 
continue;


// ignore functions with inline blocks
if (ll.canFind(") {")) { l = l[0..$ - ll.find(") {").length] 
~ ")"; }


// must get function signature only(ignore 
body)
res ~= l ~ ((ll[$] != ';') ? ";" : "") ~ "\n";

}
}


return res;
}
}


Why the original code is being broke by using D's traits to build 
the functions properly is beyond me. I'm pretty sure it is a bug 
given the example I gave earlier.





Re: full path to source file __FILE__

2018-05-29 Thread DigitalDesigns via Digitalmars-d-learn

On Tuesday, 29 May 2018 at 21:41:37 UTC, Ali Çehreli wrote:

On 05/29/2018 02:34 PM, DigitalDesigns wrote:
 > auto x(string fp = __FULL_FILE_PATH__)()

{
    pragma(msg, fp);
}

?


__FILE_FULL_PATH__

  https://dlang.org/spec/expression#specialkeywords

Ali


Lol, thanks:




Re: full path to source file __FILE__

2018-05-29 Thread DigitalDesigns via Digitalmars-d-learn

On Wednesday, 27 July 2016 at 13:58:22 UTC, Jonathan Marler wrote:
On Thursday, 21 July 2016 at 19:54:34 UTC, Jonathan Marler 
wrote:
Is there a way to get the full path of the current source 
file? Something like:


__FILE_FULL_PATH__

I'm asking because I'm rewriting a batch script in D, meant to 
be ran with rdmd.  However, the script needs to know it's own 
path.  The original batch script uses the %~dp0 variable for 
this, but I'm at a loss on how to do this in D.  Since rdmd 
compiles the executable to the %TEMP% directory, thisExePath 
won't work.


BATCH
-
echo "Directory of this script is " %~dp0


DLANG
-
import std.stdio;
int main(string[] args) {
writeln("Directory of this script is ", ???);
}


For others who may see this thread, the __FULL_FILE_PATH__ 
special trait was added to the dmd compiler with this PR: 
https://github.com/dlang/dmd/pull/5959


At the time of this post, the latest released version of D is 
2.071.1, so this trait should be available on any release after 
that.


Except it doesn't?

auto x(string fp = __FULL_FILE_PATH__)()
{
   pragma(msg, fp);
}

?


string mixin output works when directly used but when generator is used D fails

2018-05-29 Thread DigitalDesigns via Digitalmars-d-learn

https://dpaste.dzfl.pl/67691db19ce8

Just delete 9 to 29 for the code to work. Note that none of the 
code effects the output but D gives strange errors. In my code it 
says the interface members are not implemented(which they are)


foreach (member; __traits(allMembers, T))
{
static foreach (overload; MemberFunctionsTuple!(T, 
member))
{
static if (__traits(getProtection, __traits(getMember, T, 
member)) == "public")

{
foreach(a; __traits(getAttributes, 
overload))
		static if (is(typeof(a) == string) && a.length > 0 && a == 
"InterfaceMembers")

{   
string q;
foreach(b; 
__traits(getAttributes, overload))
static if (is(typeof(b) == string) && b.length > 0 && b 
== "InterfaceMembers")


continue;
else
q ~= 
"@("~b.stringof~") ";

//s ~= 
"\t"~q~cloneFunction!(overload, T) ~ ";\n";
}
}
}
}

is somehow breaking the interface. It should have no effect on it 
at all. Seems like a bug to me.


Re: Build interface from abstract class

2018-05-29 Thread DigitalDesigns via Digitalmars-d-learn

On Tuesday, 29 May 2018 at 20:26:52 UTC, arturg wrote:

On Tuesday, 29 May 2018 at 19:06:24 UTC, DigitalDesigns wrote:

On Monday, 28 May 2018 at 22:15:40 UTC, arturg wrote:

this might help you,
https://dpaste.dzfl.pl/2cf844a11e3f

you can use them to generate the functions as strings.


Thanks,

So, the problem I'm having is that I cannot use the generated 
interface for the abstract class because the abstract class 
needs the interface defined. I need to be able to forward 
define the interface then extend it.


D doesn't like this

main.d(10): Error: interface `main.B` base `A` is forward 
referenced


interface A;
mixin(Generate!(B,A));
interface B : A
{

}

abstract class C : B
{

}



would it work if you define the interface but mixin the members?

interface A
{
mixin(InterfaceFromClass!C);
}


Yes, I made a post about it but it didn't get through or I forgot 
to send ;/


Doing it this way solves the original problems but creates a new 
problem in that any class that inherits from an abstract class 
that implements A doesn't work.


interface A
{
mixin(InterfaceFromClass!C);
}

abstract class B : A
{
A foo() { return this; }
int bar() { return 3; }
}


class C : B
{
// compiler says foo, bar not implemented
}


so, instead

interface A
{
mixin(InterfaceFromClass!C);
}

abstract class B
{
A foo() { return this; } // requires cast
int bar() { return 3; }
}


class C : B, A
{

}


works but requires casting this in B which happens to work in C. 
So It is a fessible solution but I'm not sure why the compiler 
things the first case doesn't implement the methods when it 
clearly does. I think it looks at A and doesn't compute the mixin 
first when parsing C because if I put the output of the mixin 
directly it works. Probably a bug...


Re: Build interface from abstract class

2018-05-29 Thread DigitalDesigns via Digitalmars-d-learn

On Monday, 28 May 2018 at 22:15:40 UTC, arturg wrote:

this might help you,
https://dpaste.dzfl.pl/2cf844a11e3f

you can use them to generate the functions as strings.


Thanks,

So, the problem I'm having is that I cannot use the generated 
interface for the abstract class because the abstract class needs 
the interface defined. I need to be able to forward define the 
interface then extend it.


D doesn't like this

main.d(10): Error: interface `main.B` base `A` is forward 
referenced


interface A;
mixin(Generate!(B,A));
interface B : A
{

}

abstract class C : B
{

}

I could see that D wants A so it can have the complete picture 
for B, but this is one of those problems where it shouldn't 
matter.



This requires hoops and ultimately does not solve the problem. 
Any time A is used it will be treated as undefined by the 
compiler and throw an error.


For example:




pragma(msg, InterfaceFromClass!(C, "A"));

mixin(InterfaceFromClass!(C, "A"));

interface B : A
{

}

abstract class C
{
@("InterfaceMembers")
{
int xe = 3;
@(3) void foo() { }

@property int x() { return 3; };

B bar() { return null; }
}

}

abstract class D : C, B
{

}

fails because C.bar returns a B, which has not yet fully been 
defined because A has not yet fully been defined. Now, if I could 
just get the function signature without using the type system, 
this wouldn't be a problem. I don't really care if B is defined 
yet, I just need to know it's name. I guess D tries to enforce 
consistency at all steps, which is a problem here because C uses 
a yet to be defined type, even though it will be defined soon 
enough without problems.


One of the main culprits is isCallable which is what errors out 
because of the yet to be defined B.


So, I guess some other method will have to work.




Re: Build interface from abstract class

2018-05-28 Thread DigitalDesigns via Digitalmars-d-learn

On Monday, 28 May 2018 at 11:51:20 UTC, Simen Kjærås wrote:

On Monday, 28 May 2018 at 09:59:50 UTC, DigitalDesigns wrote:

Implementing interfaces can be a pain but are necessary.

I like to use abstract classes and provide a base 
implementation. It would be cool if I could use D's awesome 
meta features to extract the interface from the abstract class 
then build it. This requires some funky stuff which I'm not 
sure D can do


Creating an interface based on a class is no big deal in D:

interface Interface(T)
{
import std.traits;
static foreach (fn; __traits(allMembers, T))
static foreach (overload; MemberFunctionsTuple!(T, fn))
mixin("ReturnType!overload 
"~fn~"(Parameters!overload);");

}

class A
{
   void fun() {}
}

alias IA = Interface!A;

However, you run into a problem when A is expected to implement 
IA: in order to figure out which functions should be in the 
interface, we need to know which functions are in A. And in 
order to figure out which functions are in A, we need to know 
which functions are in IA. It's a loop with no real solution.


In this specific case, one could consider only members of A, 
ignoring any interfaces or base classes. This isn't currently 
possible, but it's not an entirely unreasonable enhancement 
request.


--
  Simen


I do not think this is a problem in D. Infinite recursion can 
always be terminated with appropriate means.


1. Use attributes. methods in class A should be marked as being 
for the interface. When added to the interface they will not have 
the attribute so will not be picked up again.


2. Your method of function creation does not pick up attributes 
and other factors so it is weak.



Case 1 should be easy to deal with. Case 2, I am not so sure how 
to build the signature exactly as it is expressed. This is, of 
course, just a copy an paste mechanism but it would require D to 
provide us the signature in some way.


Maybe an easy and direct way would be to pass __FILE__ and 
__LINE__ and extract the line? This seems a bit risky and slow.


Case 1 Will not work if UDA's are required to be exactly the same 
between interface and class. I do not know if D enforces that but 
if it does it seems a bit overkill.



Here is my solution that does not solve problem 2:


import std.stdio;



template InterfaceFromClass(alias T, string id)
{
auto InterfaceFromClass()
{
string s;
import std.traits;
foreach (member; __traits(allMembers, T))
{
static foreach (overload; MemberFunctionsTuple!(T, 
member))
{
enum attr = __traits(getAttributes, overload);
static if (__traits(getProtection, __traits(getMember, T, 
member)) == "public")

{
	mixin(`enum attrs = __traits(getAttributes, T.` ~ member ~ 
`);`);

foreach(a; attrs)
		static if (is(typeof(a) == string) && a.length > 0 && a == 
"InterfaceMembers")

{   

			s ~= (ReturnType!overload).stringof ~" 
"~member~""~(Parameters!overload).stringof~";";

}
}
}
}

return "interface "~id~"\n{\n "~s~"\n}";
}
}



Which you can see it at work here: 
https://dpaste.dzfl.pl/f49be5dd7daa


Build interface from abstract class

2018-05-28 Thread DigitalDesigns via Digitalmars-d-learn

Implementing interfaces can be a pain but are necessary.

I like to use abstract classes and provide a base implementation. 
It would be cool if I could use D's awesome meta features to 
extract the interface from the abstract class then build it. This 
requires some funky stuff which I'm not sure D can do


mixin(InterfaceFromAbstractClass!(MyAbstraction, "MyInterface"));

interface MyInterface2 : MyInterface
{
final static void baz() { }
}

abstract class MyAbstraction : MyInterface2
{
@InterfaceMembers
{
void foo() { };
}
}

InterfaceFromAbstractClass will get all the @InterfaceMembers 
members and declare them in an interface MyInterface.


This avoids all the duplicate code that interfaces has to create.

Is this possible in D?