Re: Is there a way to use Object.factory with templated classes? Or some way to construct templated classes given RTTI of an instance?

2018-09-26 Thread Chad Joan via Digitalmars-d-learn
On Wednesday, 26 September 2018 at 21:25:07 UTC, Steven 
Schveighoffer wrote:

...
Object.factory is a really old poorly supported type of 
reflection. I would not depend on it for anything.




Roger that.  Will avoid :)


You are better off using your own registration system.

As far as choosing the design for your problem, you can use:

auto obj = typeid(obj).create();

which is going to work better, and doesn't require a linear 
search through all modules/classes like Object.factory.




How does this work?

The language reference states that typeid(Type) returns "an 
instance of class TypeInfo corresponding to Type".

(https://dlang.org/spec/expression.html#typeid_expressions)

But then the TypeInfo class doesn't seem to have a .create() 
method, or at least not one in the documentation:

https://dlang.org/phobos/object.html#.TypeInfo

It looks like what I want, so it might be very helpful.

If it were me, I'd probably instead implement a clone virtual 
method. This way if any custom things need to occur when 
copying the data, it can be handled.


-Steve


I'm thinking I want to avoid the virtual method in this case, for 
reasons I wrote about in my response to Adam 
(https://forum.dlang.org/post/zovficijurwhuurrr...@forum.dlang.org).  But I think it's probably a good suggestion in most cases; I suspect that most of the time wanting to write a "deepCopy" method is going to be in response to some problem that will respond well to just virtualizing the method.


Thanks for the advice!


Re: Is there a way to use Object.factory with templated classes? Or some way to construct templated classes given RTTI of an instance?

2018-09-26 Thread Jonathan M Davis via Digitalmars-d-learn
On Wednesday, September 26, 2018 10:20:58 PM MDT Chad Joan via Digitalmars-
d-learn wrote:
> On Wednesday, 26 September 2018 at 23:32:36 UTC, Jonathan M Davis
>
> wrote:
> > On Wednesday, September 26, 2018 3:24:07 PM MDT Adam D. Ruppe
> >
> > via Digitalmars-d-learn wrote:
> >> Object.factory kinda sux and I'd actually like to remove it
> >> (among other people). There's no plan to actually do that, but
> >> still, just on principle I want to turn people away.
> >
> > While there may not currently be plans to be remove it, as
> > there _are_ plans to add ProtoObject as the new root class
> > underneath Object, at some point here, it's likely that a large
> > percentage of classes won't have anything to do with Object, so
> > relying on Object.factory to be able to construct class Objects
> > in general isn't likely to be a viable path in the long term -
> > though presumably it would work for a code base that's written
> > specifically with it in mind.
> >
> > Personally, I'm hoping that we eventually get to the point
> > where Walter and Andrei are willing to outright deprecate
> > Object itself, but I expect that ProtoObject will have to have
> > been in use for a while before we have any chance of that
> > happening. Either way, I think that it's clear that most code
> > bases should go with a solution other than Object.factory if at
> > all reasonably possible.
> >
> > - Jonathan M Davis
>
> That's interesting!  Thanks for mentioning.
>
> If you don't mind, what are the complaints regarding Object?  Or
> can you link me to discussions/issues/documents that point out
> the shortcomings/pitfalls?
>
> I've probably run into a bunch of them, but I realize D has come
> a long way since that original design and I wouldn't be surprised
> if there's a lot more for me to learn here.

I can point you to the related DIP, though it's a WIP in progress

https://github.com/andralex/DIPs/blob/ProtoObject/DIPs/DIP.md

There are also these enhancement requests for removing the various member
functions from Object (though they're likely to be superceded by the DIP):

https://issues.dlang.org/show_bug.cgi?id=9769
https://issues.dlang.org/show_bug.cgi?id=9770
https://issues.dlang.org/show_bug.cgi?id=9771
https://issues.dlang.org/show_bug.cgi?id=9772

Basically, the problems tend to come in two areas:

1. Because of how inheritance works, once you have a function on a class,
you're forcing a certain set of attributes on that function - be it type
qualifiers like const or shared or scope classes like pure or @safe. In some
cases, derived classes can be more restricted when they override the
function (e.g. an overide can be @safe when the original is @system), but
that only goes so far, and when you use the base class API, you're stuck
with whatever attributes it has. Regardless, derived classes can't be _less_
restrictive. In fact, the only reason that it's currently possible to use ==
with const class references in D right now is because of a hack. The free
function opEquals that gets called when you use == on two class references
actually casts away const so that it can then call the member function
opEquals (which doesn't work with const). So, if the member function
opEquals mutates the object, you actuall get undefined behavior. And because
Object.opEquals defines both the parameter and invisible this parameter as
mutable, derived classes have to do the same when they override it;
otherwise, they'd be overloading it rather than overriding it.

Object and its member functions really come from D1 and predate all of the
various attributes in D2 - including const. But even if we could just add
all of the attributes that we thought should be there without worrying about
breaking existing code, there would be no right answer. For instance, while
in the vast majority of cases, opEquals really should be const, having it be
const does not work with types that lazily initialize some members (since
unlike in C++, D does not have backdoors for const - when something is
const, it really means const, and it's undefined behavior to cast away const
and mutate the object). So, having Object.opEquals be const might work in
99% of cases, but it wouldn't work in all. The same could be said for other
attributes such as pure or nothrow. Forcing a particular set of attributes
on these functions on everyone is detrimental. And honestly, it really isn't
necessary.

Having them on Object comes from a Java-esque design where you don't have
templates. With proper templates like D2 has, there normally isn't a reason
to operate on an Object. You templatize the code rather than relying on a
common base class. So, there's no need to have Object.toString in order have
toString for all classes or Object.opEquals to have opEquals for all
classes. Each class can define it however it sees fit. Now, once a
particular class in a hierarchy has defined a function like opEquals or
toString, that affects any classes derived from it, but then only the
classe

Re: Is there a way to use Object.factory with templated classes? Or some way to construct templated classes given RTTI of an instance?

2018-09-26 Thread Chad Joan via Digitalmars-d-learn
On Wednesday, 26 September 2018 at 21:24:07 UTC, Adam D. Ruppe 
wrote:
On Wednesday, 26 September 2018 at 20:41:38 UTC, Chad Joan 
wrote:
I'm implementing a deep-copy method for a tree of templated 
class instances.  As part of this, I need some way to copy 
each node.

[...]
that isn't already handled by their deepCopy method.


I would strongly suggest just using that virtual method and 
having the child classes override it, then you call it from any 
of them and get the right result.




The tree nodes are potentially very diverse, but the tree 
structure itself will be very homogeneous.  I'm writing a parser 
generator backend and the tree is expressions of various 
operators (Sequence, OrderedChoice, UnorderedChoice, Repetition, 
etc).  I'm trying to keep it simple: everything is an expression, 
and expressions can contain other expressions (though some are 
always leaves in the tree).  At some level, if I let things 
implement their own deepCopy, then it means there are potentially 
other classes and state out there to iterate that the rest of the 
code doesn't know about.  That could be bad, and expressions 
shouldn't contain anything besides expressions!


This probably contrasts a lot with other use-cases, like 
serialization.  And I wouldn't be surprised if things change 
later on and I end up with some kind of auxiliary virtual copy 
function that does what you suggest, but is specifically for 
handling special out-of-band mutable reference data that the 
expressions might need to carry someday.


I suppose I've never considered just how hard/impossible it is to 
have a generic way to copy things.  Well, maybe a little bit at 
various points, but not this bad ;)  There are so many dimensions 
to the problem and it seems like the context and requirements 
will always be really important.  So it can be made simple under 
the right constraints (ex: everything is immutable!), but the 
constraints are always different depending on the requirements 
(ex: ... but in this hypothetical, we need mutability, so then 
it's gotta happen a different way).


Object.factory kinda sux and I'd actually like to remove it 
(among other people). There's no plan to actually do that, but 
still, just on principle I want to turn people away.


But even as you can see, the implementation is lacking and it 
isn't great design anyway - the interface with virtual methods 
does better work. It also wouldn't work in ctfe anyway, 
object.factory relies on runtime stuff.




Good to know!

I don't think I've even used it much, if at all.  I suppose I 
won't miss it if it goes ;)


If Object.factory is incapable of this, is there some other 
CTFE-friendly way to copy templated class instances?


I think you can copy typeinfo().init and then call 
typeinfo().defaultConstructor - this is iirc what 
Object.factory does, but once you already have the typeinfo you 
can use it directly and bypass the string lookup.




I'm having trouble looking this up.  Could you link me to the 
docs for this?


But you'd really be better off with a virtual copy method. I 
say those string factory things should only be used if you are 
starting with a string, like deserialization.



interface Copyable {
   Copyable copy();
}

class Whatever(T) : Copyable {
   Whatever!T copy() {
   auto c = new Whatever!T();
   c.tupleof = this.tupleof;
   return c;
   }
}


that kind of method. the template implements the interface so 
little boilerplate and it works and can be customized etc and 
fits in well. If you call it from the interface, you get an 
instance of the interface (tho note since it is virtual, the 
underlying type is still what you need). If you call from the 
child static type, you get it right back. Yay, fits liskov and 
works!




As above, I think this might be a very clean and effective 
solution for a different class of use-cases :)  I'll keep it in 
mind though.


If I have to, I can probably make these things register 
themselves in some list of delegates that can be used to 
instantiate the correct class.  Or something like that.  But I 
am hoping that there is a better way that involves less 
boilerplate.


that's not a terrible idea if you need delegates keyed to 
strings...


Right.  At some level I just need a function that I can call like 
this:


auto newThing = makeAnother(originalThing);

and perhaps makeAnother(...) can just lookup originalThing's 
classname in an associative array of delegates.  Or maybe I can 
just hash some part of originalThing's type information.  I can 
put all of the ugly registration boilerplate into a mixin 
template and somehow force that to always be mixed-into any 
descendant classes.  OK, it's probably getting too far into the 
weeds now, but it seems doable and I'll reach for that if I need 
to.


...

Things at least seem much more clear already.  Thanks a bunch!


Re: Is there a way to use Object.factory with templated classes? Or some way to construct templated classes given RTTI of an instance?

2018-09-26 Thread Chad Joan via Digitalmars-d-learn
On Wednesday, 26 September 2018 at 23:32:36 UTC, Jonathan M Davis 
wrote:
On Wednesday, September 26, 2018 3:24:07 PM MDT Adam D. Ruppe 
via Digitalmars-d-learn wrote:
Object.factory kinda sux and I'd actually like to remove it 
(among other people). There's no plan to actually do that, but 
still, just on principle I want to turn people away.


While there may not currently be plans to be remove it, as 
there _are_ plans to add ProtoObject as the new root class 
underneath Object, at some point here, it's likely that a large 
percentage of classes won't have anything to do with Object, so 
relying on Object.factory to be able to construct class Objects 
in general isn't likely to be a viable path in the long term - 
though presumably it would work for a code base that's written 
specifically with it in mind.


Personally, I'm hoping that we eventually get to the point 
where Walter and Andrei are willing to outright deprecate 
Object itself, but I expect that ProtoObject will have to have 
been in use for a while before we have any chance of that 
happening. Either way, I think that it's clear that most code 
bases should go with a solution other than Object.factory if at 
all reasonably possible.


- Jonathan M Davis


That's interesting!  Thanks for mentioning.

If you don't mind, what are the complaints regarding Object?  Or 
can you link me to discussions/issues/documents that point out 
the shortcomings/pitfalls?


I've probably run into a bunch of them, but I realize D has come 
a long way since that original design and I wouldn't be surprised 
if there's a lot more for me to learn here.


Re: Is there a way to use Object.factory with templated classes? Or some way to construct templated classes given RTTI of an instance?

2018-09-26 Thread Jonathan M Davis via Digitalmars-d-learn
On Wednesday, September 26, 2018 3:24:07 PM MDT Adam D. Ruppe via 
Digitalmars-d-learn wrote:
> Object.factory kinda sux and I'd actually like to remove it
> (among other people). There's no plan to actually do that, but
> still, just on principle I want to turn people away.

While there may not currently be plans to be remove it, as there _are_ plans
to add ProtoObject as the new root class underneath Object, at some point
here, it's likely that a large percentage of classes won't have anything to
do with Object, so relying on Object.factory to be able to construct class
Objects in general isn't likely to be a viable path in the long term -
though presumably it would work for a code base that's written specifically
with it in mind.

Personally, I'm hoping that we eventually get to the point where Walter and
Andrei are willing to outright deprecate Object itself, but I expect that
ProtoObject will have to have been in use for a while before we have any
chance of that happening. Either way, I think that it's clear that most code
bases should go with a solution other than Object.factory if at all
reasonably possible.

- Jonathan M Davis





Re: Is there a way to use Object.factory with templated classes? Or some way to construct templated classes given RTTI of an instance?

2018-09-26 Thread Steven Schveighoffer via Digitalmars-d-learn

On 9/26/18 4:41 PM, Chad Joan wrote:

Hi all,

I'm implementing a deep-copy method for a tree of templated class 
instances.  As part of this, I need some way to copy each node. I want 
to avoid code that does things like casting objects into byte arrays and 
then copying raw bytes; I want all operations to be memory safe things 
that I can use at compile-time.  So I planned to make all of these have 
default constructors and use Object.factory to at least create the 
correct instance type at the destination.  The classes can implement 
auxiliary copy methods if they need to copy anything that isn't already 
handled by their deepCopy method.


But I ran into a problem: Object.factory doesn't seem to be compatible 
with templated classes.


Object.factory is a really old poorly supported type of reflection. I 
would not depend on it for anything.


You are better off using your own registration system.

As far as choosing the design for your problem, you can use:

auto obj = typeid(obj).create();

which is going to work better, and doesn't require a linear search 
through all modules/classes like Object.factory.


If it were me, I'd probably instead implement a clone virtual method. 
This way if any custom things need to occur when copying the data, it 
can be handled.


-Steve


Re: Is there a way to use Object.factory with templated classes? Or some way to construct templated classes given RTTI of an instance?

2018-09-26 Thread Adam D. Ruppe via Digitalmars-d-learn

On Wednesday, 26 September 2018 at 20:41:38 UTC, Chad Joan wrote:
I'm implementing a deep-copy method for a tree of templated 
class instances.  As part of this, I need some way to copy each 
node.

[...]
that isn't already handled by their deepCopy method.


I would strongly suggest just using that virtual method and 
having the child classes override it, then you call it from any 
of them and get the right result.


Object.factory kinda sux and I'd actually like to remove it 
(among other people). There's no plan to actually do that, but 
still, just on principle I want to turn people away.


But even as you can see, the implementation is lacking and it 
isn't great design anyway - the interface with virtual methods 
does better work. It also wouldn't work in ctfe anyway, 
object.factory relies on runtime stuff.


If Object.factory is incapable of this, is there some other 
CTFE-friendly way to copy templated class instances?


I think you can copy typeinfo().init and then call 
typeinfo().defaultConstructor - this is iirc what Object.factory 
does, but once you already have the typeinfo you can use it 
directly and bypass the string lookup.


But you'd really be better off with a virtual copy method. I say 
those string factory things should only be used if you are 
starting with a string, like deserialization.



interface Copyable {
   Copyable copy();
}

class Whatever(T) : Copyable {
   Whatever!T copy() {
   auto c = new Whatever!T();
   c.tupleof = this.tupleof;
   return c;
   }
}


that kind of method. the template implements the interface so 
little boilerplate and it works and can be customized etc and 
fits in well. If you call it from the interface, you get an 
instance of the interface (tho note since it is virtual, the 
underlying type is still what you need). If you call from the 
child static type, you get it right back. Yay, fits liskov and 
works!


If I have to, I can probably make these things register 
themselves in some list of delegates that can be used to 
instantiate the correct class.  Or something like that.  But I 
am hoping that there is a better way that involves less 
boilerplate.


that's not a terrible idea if you need delegates keyed to 
strings...


Is there a way to use Object.factory with templated classes? Or some way to construct templated classes given RTTI of an instance?

2018-09-26 Thread Chad Joan via Digitalmars-d-learn

Hi all,

I'm implementing a deep-copy method for a tree of templated class 
instances.  As part of this, I need some way to copy each node.  
I want to avoid code that does things like casting objects into 
byte arrays and then copying raw bytes; I want all operations to 
be memory safe things that I can use at compile-time.  So I 
planned to make all of these have default constructors and use 
Object.factory to at least create the correct instance type at 
the destination.  The classes can implement auxiliary copy 
methods if they need to copy anything that isn't already handled 
by their deepCopy method.


But I ran into a problem: Object.factory doesn't seem to be 
compatible with templated classes.


Here is an example:

import std.stdio;

class Root(T)
{
T x;
}

class Extended(T) : Root!T
{
T y;
}

void main()
{
Root!int foo = new Extended!int();

auto name = foo.classinfo.name;
writefln("foo's name is '%s'", name);
// foo's name is 'main.Extended!int.Extended'

Object   obj = Object.factory(name);
writefln("Is obj null? %s", obj is null);

Root!int bar = cast(Root!int)obj; // Still going to be null.
writefln("Is bar null? %s", obj is null);

//bar.x = 3; // crash!
}


I had a look at Object.factory.  It seems very simple.  Perhaps 
too simple.  I think this might be a dead end.  Have I missed 
something?  Can it actually handle templates somehow, but I just 
don't know how to calculate the correct string to hand it?


If Object.factory is incapable of this, is there some other 
CTFE-friendly way to copy templated class instances?


If I have to, I can probably make these things register 
themselves in some list of delegates that can be used to 
instantiate the correct class.  Or something like that.  But I am 
hoping that there is a better way that involves less boilerplate.


Thanks!
- Chad


Weird compilation error only as static library

2018-09-26 Thread Márcio Martins via Digitalmars-d-learn

Hi!

I am getting this error when compiling my code as a static 
library.

It works fine as an executable. I have no idea what's happening.
Has someone seen something like this before? What could be 
different?


This is the error:
/usr/include/dmd/druntime/import/core/stdc/stdint.d(159,26): 
Error: undefined identifier cpp_ulong

/usr/include/dmd/druntime/import/core/sys/posix/sys/types.d(109,11): Error: 
undefined identifier c_long
../../../.dub/packages/libuv-1.20.3/libuv/deimos/libuv/uv.d(367,2): Error: 
mixin `deimos.libuv.uv.uv_stream_s.UV_STREAM_FIELDS!()` error instantiating

It's a small library with libuv as the only dependency. It works 
fine compiling it's own example, but fails when I compile it as a 
dub dependency.


Re: Can I create static c callable library?

2018-09-26 Thread Mike Parker via Digitalmars-d-learn
On Wednesday, 26 September 2018 at 09:54:22 UTC, John Burton 
wrote:


Is there any documentation anywhere that deals with calling D 
from C? I could find plenty the other way round. I think I'll 
give up on the idea though, and rewrite the whole thing in D :)


Rewriting it in D is a great idea ;) But for the record, much of 
what you've read about calling C from D applies the other way, 
too. You just need to write your D functions as extern(C), 
following the same approach to function signatures and types as 
you've read about, then declare the crossover functions and types 
in C.


One gotcha to look out for is when you call a D function that 
allocates GC memory. In that case, you need to keep a reference 
to it alive on the D side. If it's only being allocated for use 
in C, you can call GC.addRoot [1] when you allocate the memory on 
the D side and GC.removeRoot [2] when you no longer need it.


Also keep in mind that D variables thread-local, and if you need 
to access any of them in C from multiple threads they would 
better be declared as __gshared in D.


[1] https://dlang.org/phobos/core_memory.html#.GC.addRoot
[2] https://dlang.org/phobos/core_memory.html#.GC.removeRoot


Re: Can I create static c callable library?

2018-09-26 Thread John Burton via Digitalmars-d-learn
On Tuesday, 25 September 2018 at 12:05:21 UTC, Jonathan M Davis 
wrote:

[...]


Thanks everyone.

Is there any documentation anywhere that deals with calling D 
from C? I could find plenty the other way round. I think I'll 
give up on the idea though, and rewrite the whole thing in D :)


Re: is there something like `stm32-rs` in D?

2018-09-26 Thread Radu via Digitalmars-d-learn
On Wednesday, 26 September 2018 at 05:55:49 UTC, dangbinghoo 
wrote:

On Wednesday, 26 September 2018 at 05:24:08 UTC, Radu wrote:
On Wednesday, 26 September 2018 at 03:46:21 UTC, dangbinghoo 
wrote:

hi,

https://github.com/adamgreig/stm32-rs looks great, is there 
something like this in Dlang?


thanks!
---
dangbinghoo


You might take a look at

https://github.com/JinShil/stm32f42_discovery_demo
and
https://github.com/JinShil/stm32_datasheet_to_d


thanks, Radu, I knew that there's a minimal D demo on STM32 
exist for years. But, what I'm talking about is that rust 
community is doing a rust library for very production use. If 
you look at stm32-rs, you will found that stm32-rs is covering 
the whole STM32 MCU product line and making a promising 
peripherals library.


The library was generated using CMSIS-SVD files which were 
maintained by MCU vendors.


Anyway, I don't know what's the runtime size situation D vs 
rust. for those kinds of MCU devices, a runtime code size 
greater than 5KB may even not suitable for  L0 lines MCU from 
ST.


It's not quite clear that whether D or rust is valuable for MCU 
development, but C is really lacking lots of things for quick 
development, today MCU is interfacing more IoT modules using AT 
command, and deal with these string things is quite painful in 
C. Maybe this is an opportunity for D?


Thanks!

---
dangbinghoo


I think you should get in touch with Mike Franklin and see what 
are his plans with the demo code. I know there were some blocking 
issues and he was working to solve them.


Maybe the tool-chain and language is mature enough to revisit 
this project and make it production ready. I'm not an MCU expert 
but maybe you can join in with ideas and some insights and help 
boot-strap a new project.