Re: Alternative to Interfaces

2019-01-25 Thread Paul Backus via Digitalmars-d-learn
On Friday, 25 January 2019 at 19:34:02 UTC, Sebastien Alaiwan 
wrote:

On Saturday, 19 January 2019 at 09:24:21 UTC, Kagamin wrote:
On Friday, 18 January 2019 at 18:48:46 UTC, Jonathan M Davis 
wrote:

Yes, but some D features will use the GC


They would like to allocate, but they don't know nor care 
where it's allocated from, if the developer uses custom memory 
management, he will know how it's allocated and will be able 
to manage it.


Is it possible to get the raw context pointer from a given 
delegate?
If not, how to deallocate the context without garbage 
collection?


You can access the context pointer of a delegate using its `.ptr` 
property, but changing how it's allocated would require changes 
to druntime.


Some alternatives are discussed in this thread: 
https://forum.dlang.org/thread/mgbdrhcudlhsadnwz...@forum.dlang.org


Re: Alternative to Interfaces

2019-01-25 Thread Sebastien Alaiwan via Digitalmars-d-learn

On Saturday, 19 January 2019 at 09:24:21 UTC, Kagamin wrote:
On Friday, 18 January 2019 at 18:48:46 UTC, Jonathan M Davis 
wrote:

Yes, but some D features will use the GC


They would like to allocate, but they don't know nor care where 
it's allocated from, if the developer uses custom memory 
management, he will know how it's allocated and will be able to 
manage it.


Is it possible to get the raw context pointer from a given 
delegate?

If not, how to deallocate the context without garbage collection?



Re: Alternative to Interfaces

2019-01-19 Thread Kagamin via Digitalmars-d-learn
On Friday, 18 January 2019 at 18:48:46 UTC, Jonathan M Davis 
wrote:

Yes, but some D features will use the GC


They would like to allocate, but they don't know nor care where 
it's allocated from, if the developer uses custom memory 
management, he will know how it's allocated and will be able to 
manage it.



The list of such features is short, but delegates are on it.


Closures are, but not delegates. Delegate is just a pair of 
pointers, you don't need to allocate at all to keep them around, 
similar to slices. They even work in betterC.


get around the allocations in some cases, but in general, if 
you use delegates, you're going to allocate with the GC.


Custom memory management is obviously not the general case.

but the allocations that happen for delegates and lambdas is 
one of the biggest reasons that some folks avoid std.algorithm 
and complain that it allocates. That's what happens when you 
pass stuff that the compiler decides has to have closures 
allocated for it.


Is it really blocked? I got this to work with dip1000:

@safe @nogc:
alias int delegate(int) @safe @nogc dg;
struct Map(T)
{
private T a;
}
Map!dg map(return dg b)
{
Map!dg m;
m.a=b;
return m;
}
void f()
{
int a;
auto b=map(i=>a);
a=b.a(0);
}

Templated function can't infer closure type for some reason.


Re: Alternative to Interfaces

2019-01-18 Thread Jonathan M Davis via Digitalmars-d-learn
On Friday, January 18, 2019 8:08:47 AM MST Kagamin via Digitalmars-d-learn 
wrote:
> On Friday, 18 January 2019 at 00:08:00 UTC, 1001Days wrote:
> > It works, but I have two questions regarding its efficacy: is
> > it viable in the long run, and is it now possible to use
> > delegates without the GC?
>
> GC is just a handy memory management approach, it even works for
> C and C++, (example: gcc), nothing in D needs GC if you manage
> memory in a different way. In fact there are D libraries that
> rely solely on manual memory management.

Yes, but some D features will use the GC, and you can't really stop that
aside from simply not using those features. The list of such features is
short, but delegates are on it. scope will get around the allocations in
some cases, but in general, if you use delegates, you're going to allocate
with the GC. There are alternatives to using delegates which will get you
similar behavior allocating (e.g. functors), but the allocations that happen
for delegates and lambdas is one of the biggest reasons that some folks
avoid std.algorithm and complain that it allocates. That's what happens when
you pass stuff that the compiler decides has to have closures allocated for
it. Completely avoiding the GC with D is possible, but it tends to require
that you be very careful and have a good understanding of where D needs to
use the GC to do what it does (though the fact that we now have @nogc, and
it screams at you if the code allocates does help you catch GC usage when
you didn't realize that it was there).

- Jonathan M Davis





Re: Alternative to Interfaces

2019-01-18 Thread Kagamin via Digitalmars-d-learn

On Friday, 18 January 2019 at 00:08:00 UTC, 1001Days wrote:
It works, but I have two questions regarding its efficacy: is 
it viable in the long run, and is it now possible to use 
delegates without the GC?


GC is just a handy memory management approach, it even works for 
C and C++, (example: gcc), nothing in D needs GC if you manage 
memory in a different way. In fact there are D libraries that 
rely solely on manual memory management.


Re: Alternative to Interfaces

2019-01-17 Thread 1001Days via Digitalmars-d-learn

On Friday, 18 January 2019 at 01:00:33 UTC, H. S. Teoh wrote:
Maybe you could help us answer your question better by 
explaining a bit more what you're trying to achieve.  Generally, 
if you want to use an interface, that usually means you want (1) 
runtime polymorphism, i.e., the ability to swap one concrete 
implementation for another at runtime, and (2) pass around 
possibly different concrete objects to code that expects objects 
of a single type (the interface type).
I do apologize for my vagueness. In hindsight, it was quite a 
poor way to request for help. Anyway, for my current use case, 
the latter's functionality is what I am attempting to replicate.
If the reason you're using structs is just to avoid the GC, then 
you should look up emplace() in the docs.  It *is* possible to 
use classes without using the GC.  Just in case you didn't know.
Thank you for informing me of this. I didn't know. So from a 
cursory glance it would seem that I would, omitting details, make 
a wrapper function that combines an allocator (e.g. malloc) and 
emplace.
(Though you should also keep in mind the possible drawbacks of 
template bloat -- which may cause more instruction cache misses 
by making your code larger than it could have been.)

Yes, this is something I worried about too.
My personal tendency is to start with structs and compile-time 
introspection as an initial stab, but depending on what might be 
needed, I may use some classes / interfaces.  The two can be 
combined to some extent -- e.g., a template function can take 
both structs with compile-time introspection and also classes 
that allow runtime polymorphism.  A template function 
instantiated with a class type will be able to accept different 
concrete objects at runtime (as long as they are subclasses of 
that type).  However, it will only be able to "see" the static 
info of the class it was instantiated with, not any additional 
features of derived classes that it may receive at runtime, 
since there will be no runtime introspection.
Initially, I was going to use Classes when I needed to use 
Interfaces and use Structs for everything else, but I decided 
against that because I was worried it would make the program's 
structure "inconsistent," for the lack of a better word, and 
again the GC.
Though AFAIK, delegates probably still need heap allocation and 
depend on the GC, esp. if you have closures over local 
variables.  There may be some cases where the compiler will 
elide this, e.g., if you have a function literal passed via an 
alias that does not escape the caller's scope.  OTOH, you might 
be able to get around needing the GC if you put your delegates 
in an emplace()'d class as methods, and take their address 
(which produces a delegate).  Just make sure your class doesn't 
go out of scope while the resulting delegates are still around. 
Keep in mind that in this case, you will not be able to have 
closure over local variables (delegates can only have 1 context 
pointer, and in this case it's already used up by the `this` 
reference) and will have to store any such contextual 
information inside the class itself.
With regards to the emplaced class, this is interesting. My main 
use for the delegate was in achieving one of the effects of 
interfaces for Structs, so I don't think I'll be using them as 
much. I'll have to pay close attention to the profiler in any 
case.


With the information you gave me, I think I'll try Class & 
emplace as I really don't want to attempt replicate existing 
functionality--especially so considering my experience level.


With thanks,
1001Days


Re: Alternative to Interfaces

2019-01-17 Thread H. S. Teoh via Digitalmars-d-learn
On Fri, Jan 18, 2019 at 12:08:00AM +, 1001Days via Digitalmars-d-learn 
wrote:
> Hello,
> 
> Preface: I do apologize if this is too simplistic of a matter, and if
> I need to RTFM. I'm quite slow.
> 
> I want to use Structs instead of Classes, but I don't want to lose the
> abilities of Interfaces. So instead I used a combination of templates,
> constraints, the hasMember trait, and delegates to achieve a simple
> alternative.

Maybe you could help us answer your question better by explaining a bit
more what you're trying to achieve.  Generally, if you want to use an
interface, that usually means you want (1) runtime polymorphism, i.e.,
the ability to swap one concrete implementation for another at runtime,
and (2) pass around possibly different concrete objects to code that
expects objects of a single type (the interface type).

So the first question is, do you need runtime polymorphism? Do you need
to pass objects of different types to functions that only take a single
type?  Do you need the ability to change *at runtime* the type of object
passed to a function?

If so, you probably should stick with interfaces and classes.  While it
*is* possible to achieve equivalent functionality with structs and
templates, you'll basically end up reinventing classes, possibly poorly,
and spending coding / debugging time doing so when you could have just
used the built-in construct.

If the reason you're using structs is just to avoid the GC, then you
should look up emplace() in the docs.  It *is* possible to use classes
without using the GC.  Just in case you didn't know.

OTOH, if you don't need runtime polymorphism, then using classes and
templates would be the "more idiomatic" way to do it. (Though you should
also keep in mind the possible drawbacks of template bloat -- which may
cause more instruction cache misses by making your code larger than it
could have been.)


> It works, but I have two questions regarding its efficacy: is it
> viable in the long run, and is it now possible to use delegates
> without the GC? The latter is of particular importance as I'm using
> Structs for compatibility.
[...]

Whether or not it's viable really depends on whether you need runtime
polymorphism, and what you're trying to accomplish.

My personal tendency is to start with structs and compile-time
introspection as an initial stab, but depending on what might be needed,
I may use some classes / interfaces.  The two can be combined to some
extent -- e.g., a template function can take both structs with
compile-time introspection and also classes that allow runtime
polymorphism.  A template function instantiated with a class type will
be able to accept different concrete objects at runtime (as long as they
are subclasses of that type).  However, it will only be able to "see"
the static info of the class it was instantiated with, not any
additional features of derived classes that it may receive at runtime,
since there will be no runtime introspection.

Though AFAIK, delegates probably still need heap allocation and depend
on the GC, esp. if you have closures over local variables.  There may be
some cases where the compiler will elide this, e.g., if you have a
function literal passed via an alias that does not escape the caller's
scope.  OTOH, you might be able to get around needing the GC if you put
your delegates in an emplace()'d class as methods, and take their
address (which produces a delegate).  Just make sure your class doesn't
go out of scope while the resulting delegates are still around. Keep in
mind that in this case, you will not be able to have closure over local
variables (delegates can only have 1 context pointer, and in this case
it's already used up by the `this` reference) and will have to store any
such contextual information inside the class itself.


T

-- 
It always amuses me that Windows has a Safe Mode during bootup. Does that mean 
that Windows is normally unsafe?


Alternative to Interfaces

2019-01-17 Thread 1001Days via Digitalmars-d-learn

Hello,

Preface: I do apologize if this is too simplistic of a matter, 
and if I need to RTFM. I'm quite slow.


I want to use Structs instead of Classes, but I don't want to 
lose the abilities of Interfaces. So instead I used a combination 
of templates, constraints, the hasMember trait, and delegates to 
achieve a simple alternative. It works, but I have two questions 
regarding its efficacy: is it viable in the long run, and is it 
now possible to use delegates without the GC? The latter is of 
particular importance as I'm using Structs for compatibility.


With thanks,
1001Days