Re: What is difference between struct and class?

2019-06-02 Thread Rnd via Digitalmars-d-learn

On Monday, 3 June 2019 at 00:47:27 UTC, Adam D. Ruppe wrote:

On Monday, 3 June 2019 at 00:17:08 UTC, Rnd wrote:

What additional features do classes offer in D?


Classes support built-in runtime polymorphism through 
inheritance. structs don't.


As a result of this, classes are a little bit heavier 
resource-wise and are semantically always object references.


I am not clear if structs can have constructors (this) and 
whether they can be multiple? Also can data be made private and 
getters and setters used to access them?




Re: What is difference between struct and class?

2019-06-02 Thread Adam D. Ruppe via Digitalmars-d-learn

On Monday, 3 June 2019 at 00:17:08 UTC, Rnd wrote:

What additional features do classes offer in D?


Classes support built-in runtime polymorphism through 
inheritance. structs don't.


As a result of this, classes are a little bit heavier 
resource-wise and are semantically always object references.


What is difference between struct and class?

2019-06-02 Thread Rnd via Digitalmars-d-learn
I see that struct can have data as well as member functions and 
instances can be created. So they sound like classes only.


What additional features do classes offer in D?


Re: import and call

2019-06-02 Thread Adam D. Ruppe via Digitalmars-d-learn

On Sunday, 2 June 2019 at 19:38:11 UTC, Amex wrote:
I thought importing single functions were suppose to be faster. 
Am I wrong?


That is wrong. Importing is always done of the whole module.

All the `: func` thing does is limit the things introduced to the 
namespace.





Re: Very simple null reference escape

2019-06-02 Thread Basile B. via Digitalmars-d-learn

On Sunday, 2 June 2019 at 07:55:27 UTC, Amex wrote:

A.B

If A is null, crash.

A?.B : writeln("HAHA");

No crash, ignored, equivalent to

if (A is null) writeln("HAHA"); else A.B;


safeAccess from iz does this : 
https://github.com/Basile-z/iz/blob/master/import/iz/sugar.d#L1666


Re: import and call

2019-06-02 Thread Basile B. via Digitalmars-d-learn

On Sunday, 2 June 2019 at 19:38:11 UTC, Amex wrote:


Tired of having to import a single function to call it.

Since

mod.foo(x);

doesn't work since mod is not defined.

we have to do

import mod : foo;
foo(x);

Why not

mod:foo(x)?

or

mod#foo(x)

or

mod@foo(x)

or whatever

Reduces 50% of the lines and reduces the import symbol.

I realize that we could do

import m = mod;

m.foo(x);

but the idea is to only import the single function. I'm not 
sure if it matters. I thought importing single functions were 
suppose to be faster. Am I wrong?


The idea is to reduce having to litter the code with imports 
which I find I'm always having to do, or to make them global... 
just for a few calls in to them.


Expression based import is possible using mixin, see 
https://dlang.org/blog/2017/02/13/a-new-import-idiom/


Re: 'version'-based code selection

2019-06-02 Thread Jonathan M Davis via Digitalmars-d-learn
On Sunday, June 2, 2019 11:43:09 AM MDT Anonymouse via Digitalmars-d-learn 
wrote:
> On Saturday, 1 June 2019 at 07:46:40 UTC, Jonathan M Davis wrote:
> > For the most part though, you don't declare your own version
> > identifiers. It sometimes makes sense, but usually, version
> > identifiers are used for versioning code based on the platform
> > or architecture that it's compiled on. They're really only
> > intended to be a saner version of #ifdefs, and if you're doing
> > anything fancy with them, you're really not using them as
> > intended and are probably going to have problems.
>
> I use versioning pervasively to make features opt-in/opt-out at
> compile-time.
>
> Like so, from dub.json:
>
>  "versions":
>  [
>  "AsAnApplication",
>  "WithAdminPlugin",
>  "WithAutomodePlugin",
>  "WithBashQuotesPlugin",
>  "WithChanQueriesService",
>  "WithChatbotPlugin",
>  "WithConnectService",
>  "WithCTCPService",
>  "WithHelpPlugin",
>  "WithNotesPlugin",
>  "WithPersistenceService",
>  "WithPipelinePlugin",
>  "WithPrinterPlugin",
>  "WithQuotesPlugin",
>  "WithSedReplacePlugin",
>  "WithSeenPlugin",
>  "WithWebtitlesPlugin"
>  ],
>
> ---
>
> module foo;
>
> version(WithFoo):
>
> // ...
>
> Is this recommended against? It's a very convenient way of
> enabling and disabling modules outright, since (by default) dub
> eagerly compiles everything it sees. I haven't had any problems
> with it as of yet, at the very least.

Personally, I wouldn't be in favor of doing much in the way of enabling or
disabling features in a library or application in such a manner, but if
you're going to do it, then version identifiers would be appropriate.

However, you do need to watch out, because such an approach runs the risk of
problems if you end up with a project depending on libraries that depend on
your library, because they may not be compiled with the same set of version
identifiers. I'm not sure how dub handles that (probably by considering it a
conflict), but without any form of conflict resolution (or you have a form
of conflict resolution that doesn't catch this issue), you run the risk of
modules being imported with one set of version identifiers but actually
compiled with another. In some situations, that will result in a linker
error, but in others, it's just going to result in the code not behaving as
expected. It's less of an issue if the version identifiers are for an
application rather than a library. Also, if you're versioning out entire
modules rather than pieces of modules, you're likely to be less at risk of
subtle problems, since then you'll just get large stuff missing, and linking
will fail, whereas if you're using such version identifiers within code
(e.g. changing the body of a function), then you run a high risk of subtle
problems.

Personally, if I were writing a library with optional stuff, I'd make the
optional stuff into sub-modules and try to avoid using version identifiers.
I might do it for an application though, since in that case, you wouldn't be
dealing with sub-modules, and you're not dealing with anything depending on
your code, just controlling what ends up in the executable.

- Jonathan M Davis





Re: Very simple null reference escape

2019-06-02 Thread Amex via Digitalmars-d-learn

On Sunday, 2 June 2019 at 14:37:48 UTC, Paul Backus wrote:

On Sunday, 2 June 2019 at 07:55:27 UTC, Amex wrote:

A.B

If A is null, crash.

A?.B : writeln("HAHA");

No crash, ignored, equivalent to

if (A is null) writeln("HAHA"); else A.B;


The "optional" package on dub [1] has a .dispatch method that 
does this:


auto d = some(A());

// Dispatch to one of its methods

d.dispatch.f(); // calls a.f, returns some(4)
d.dispatch.inner.g(); // calls a.inner.g, returns some(7)

// Use on a pointer or reference type as well
A* e = null;

// If there's no value in the reference type, dispatching
// works, and produces an optional
assert(e.dispatch.f() == none);
assert(e.dispatch.inner.g() == none);


Full example: https://run.dlang.io/is/SmsGQu

[1] https://code.dlang.org/packages/optional


thanks.


Error: module `M.Q` from file M\Q.d conflicts with another module Q from file M\Q.d

2019-06-02 Thread Amex via Digitalmars-d-learn
main.d(217): Error: module `M.Q` from file M\Q.d conflicts with 
another module Q from file M\Q.d


the line is simply

import Q : foo;

the problem is that it should have been

import M.Q : foo;

There is no module Q.

The error message is in error! There is no other module.

the module is named

module M.Q;

where M is a subdirectory. This is probably suppose to be module 
Q; but everything works out.


The error message could be more accurate(took me a min to figure 
out what was going on).







import and call

2019-06-02 Thread Amex via Digitalmars-d-learn



Tired of having to import a single function to call it.

Since

mod.foo(x);

doesn't work since mod is not defined.

we have to do

import mod : foo;
foo(x);

Why not

mod:foo(x)?

or

mod#foo(x)

or

mod@foo(x)

or whatever

Reduces 50% of the lines and reduces the import symbol.

I realize that we could do

import m = mod;

m.foo(x);

but the idea is to only import the single function. I'm not sure 
if it matters. I thought importing single functions were suppose 
to be faster. Am I wrong?


The idea is to reduce having to litter the code with imports 
which I find I'm always having to do, or to make them global... 
just for a few calls in to them.







Re: hasElaborateCopyConstructor bug?

2019-06-02 Thread Jonathan M Davis via Digitalmars-d-learn
On Sunday, June 2, 2019 1:29:22 PM MDT Jonathan M Davis via Digitalmars-d-
learn wrote:
> On Sunday, June 2, 2019 8:32:16 AM MDT Paul Backus via Digitalmars-d-learn
> wrote:
> > On Sunday, 2 June 2019 at 06:59:02 UTC, Jonathan M Davis wrote:
> > > Almost certainly, hasElaborateCopyConstructor should be updated
> > > to test for both postblit constructors and copy constructors,
> > > since its purpose is to test for whether the type has a
> > > user-defined copying function [...] Whether
> > > hasElaborateCopyConstructor was the best name is debatable, but
> > > it _does_ involve "elaborate" copying, and copy constructors
> > > weren't actually in the language at the time. The documentation
> > > is wonderfully confusing though in that it talks about copy
> > > constructors and then says that a copy constructor is
> > > introduced by defining this(this) for a struct. So, it
> > > basically calls a postblit constructor a copy constructor.
> >
> > I've made the mistake in the past of trying to use
> > hasElaborateCopyConstructor to test for the presence of
> > __xpostblit, and I'm sure I'm not the only one. The name is quite
> > misleading--even more so now that D has real copy constructors.
> >
> > If std.v2 ever materializes, we'll have an opportunity to fix
> > papercuts like this. Until then, my preferred workaround is to
> > use a renaming import:
> >
> > import std.traits: hasNontrivialCopy =
> > hasElaborateCopyConstructor;
>
> Why is it a mistake to use hasElaborateCopyConstructor to test for
> __xpostblit? Because you're trying to test for __xpostblit for some
> purpose other than determining whether the type is blittable? I'm not
> sure what other reason there would be to test for __xpostblit though.
> Either way, hasElaborateCopyConstructor currently checks for exactly that
> (with the addition that it checks whether a static array has elements
> with __xpostblit):
>
> template hasElaborateCopyConstructor(S)
> {
> static if (__traits(isStaticArray, S) && S.length)
> {
> enum bool hasElaborateCopyConstructor =
> hasElaborateCopyConstructor! (typeof(S.init[0]));
> }
> else static if (is(S == struct))
> {
> enum hasElaborateCopyConstructor = __traits(hasMember, S,
> "__xpostblit");
> }
> else
> {
> enum bool hasElaborateCopyConstructor = false;
> }
> }
>
> My point was that given the purpose of hasElaborateCopyConstructor,
> updating it to test for both a postblit constructor and copy constructor
> would be appropriate. In fact, the fact that it hasn't been means that
> the introduction of copy constructors has broken existing code (or at
> least that such code won't interact correctly with structs that have copy
> constructors). There should be no need to rename the trait, just update
> it, and whether it uses the name "elaborate" or "non-trivial" is pretty
> much irrelevant. Personally, I probably would have chosen hasNonTrivial
> over hasElaborate, but they mean the same thing, and we have
> hasElaborateDestructor for the corresponding test for destructors and
> hasElaborateAssign for the corresponding test for assignment. It really
> doesn't make sense to change the name at this point.

It looks like Manu already reported a bug on this:

https://issues.dlang.org/show_bug.cgi?id=19902

- Jonathan M Davis





Re: hasElaborateCopyConstructor bug?

2019-06-02 Thread Jonathan M Davis via Digitalmars-d-learn
On Sunday, June 2, 2019 8:32:16 AM MDT Paul Backus via Digitalmars-d-learn 
wrote:
> On Sunday, 2 June 2019 at 06:59:02 UTC, Jonathan M Davis wrote:
> > Almost certainly, hasElaborateCopyConstructor should be updated
> > to test for both postblit constructors and copy constructors,
> > since its purpose is to test for whether the type has a
> > user-defined copying function [...] Whether
> > hasElaborateCopyConstructor was the best name is debatable, but
> > it _does_ involve "elaborate" copying, and copy constructors
> > weren't actually in the language at the time. The documentation
> > is wonderfully confusing though in that it talks about copy
> > constructors and then says that a copy constructor is
> > introduced by defining this(this) for a struct. So, it
> > basically calls a postblit constructor a copy constructor.
>
> I've made the mistake in the past of trying to use
> hasElaborateCopyConstructor to test for the presence of
> __xpostblit, and I'm sure I'm not the only one. The name is quite
> misleading--even more so now that D has real copy constructors.
>
> If std.v2 ever materializes, we'll have an opportunity to fix
> papercuts like this. Until then, my preferred workaround is to
> use a renaming import:
>
> import std.traits: hasNontrivialCopy =
> hasElaborateCopyConstructor;

Why is it a mistake to use hasElaborateCopyConstructor to test for
__xpostblit? Because you're trying to test for __xpostblit for some purpose
other than determining whether the type is blittable? I'm not sure what
other reason there would be to test for __xpostblit though. Either way,
hasElaborateCopyConstructor currently checks for exactly that (with the
addition that it checks whether a static array has elements with
__xpostblit):

template hasElaborateCopyConstructor(S)
{
static if (__traits(isStaticArray, S) && S.length)
{
enum bool hasElaborateCopyConstructor = hasElaborateCopyConstructor!
(typeof(S.init[0]));
}
else static if (is(S == struct))
{
enum hasElaborateCopyConstructor = __traits(hasMember, S, 
"__xpostblit");
}
else
{
enum bool hasElaborateCopyConstructor = false;
}
}

My point was that given the purpose of hasElaborateCopyConstructor, updating
it to test for both a postblit constructor and copy constructor would be
appropriate. In fact, the fact that it hasn't been means that the
introduction of copy constructors has broken existing code (or at least that
such code won't interact correctly with structs that have copy
constructors). There should be no need to rename the trait, just update it,
and whether it uses the name "elaborate" or "non-trivial" is pretty much
irrelevant. Personally, I probably would have chosen hasNonTrivial over
hasElaborate, but they mean the same thing, and we have
hasElaborateDestructor for the corresponding test for destructors and
hasElaborateAssign for the corresponding test for assignment. It really
doesn't make sense to change the name at this point.

- Jonathan M Davis





Re: What does ! Stand for in map! and filter! function calls?

2019-06-02 Thread Dennis via Digitalmars-d-learn

On Sunday, 2 June 2019 at 16:39:57 UTC, Rnd wrote:
Is it not possible in the language to have template map 
function also to called as map(x=>... ?


That would be slower, and std.algorithm generally disallows easy 
but slow functions.


In Java, you can sort a linked list. In D, sort requires an array 
(or random access range).
D's `uniq` removes duplicates, but assumes the input range is 
sorted.


Of course you can do myLinkedList.array.sort.uniq but it's not as 
easy as myLinkedList.uniq because that hides all the stuff that 
is required to happen behind the scenes.


It may be less beginner friendly, but I've also seen newcomers 
come with a question among the lines of 'I'm trying out the 
language, why is my little benchmark slower than equivalent 
Javascript' after which they're told 'don't use dmd, don't use 
80-bit floats, use these compiler flags' etc. So it's a trade-off 
between ease of use by default and performance by default.


A clear error message on `map` without ! is the way to go in my 
opinion.


Re: 'version'-based code selection

2019-06-02 Thread Anonymouse via Digitalmars-d-learn

On Saturday, 1 June 2019 at 07:46:40 UTC, Jonathan M Davis wrote:
For the most part though, you don't declare your own version 
identifiers. It sometimes makes sense, but usually, version 
identifiers are used for versioning code based on the platform 
or architecture that it's compiled on. They're really only 
intended to be a saner version of #ifdefs, and if you're doing 
anything fancy with them, you're really not using them as 
intended and are probably going to have problems.


I use versioning pervasively to make features opt-in/opt-out at 
compile-time.


Like so, from dub.json:

"versions":
[
"AsAnApplication",
"WithAdminPlugin",
"WithAutomodePlugin",
"WithBashQuotesPlugin",
"WithChanQueriesService",
"WithChatbotPlugin",
"WithConnectService",
"WithCTCPService",
"WithHelpPlugin",
"WithNotesPlugin",
"WithPersistenceService",
"WithPipelinePlugin",
"WithPrinterPlugin",
"WithQuotesPlugin",
"WithSedReplacePlugin",
"WithSeenPlugin",
"WithWebtitlesPlugin"
],

---

module foo;

version(WithFoo):

// ...

Is this recommended against? It's a very convenient way of 
enabling and disabling modules outright, since (by default) dub 
eagerly compiles everything it sees. I haven't had any problems 
with it as of yet, at the very least.




Re: What does ! Stand for in map! and filter! function calls?

2019-06-02 Thread Paul Backus via Digitalmars-d-learn

On Sunday, 2 June 2019 at 16:39:57 UTC, Rnd wrote:


Is it not possible in the language to have template map 
function also to called as map(x=>... ?


This will reduce complexity which will attract more people to 
this language.


Easy languages have great mass appeal as has been shown with 
Ruby and Python.


It's possible, but I believe the version that takes the function 
as a template argument is easier for the compiler to optimize, so 
doing it that way is a better choice for the standard library.


Reducing complexity for first-time learners is a noble goal, but 
templates are used so pervasively in D that there's really no 
sense in trying to avoid them. If you'd like to learn more about 
D's templates, Philippe Sigaud has written an excellent tutorial:


https://github.com/PhilippeSigaud/D-templates-tutorial/blob/master/D-templates-tutorial.md


Re: What does ! Stand for in map! and filter! function calls?

2019-06-02 Thread Adam D. Ruppe via Digitalmars-d-learn

On Sunday, 2 June 2019 at 16:39:57 UTC, Rnd wrote:
Is it not possible in the language to have template map 
function also to called as map(x=>... ?


It could be done pretty easily, but you will have to learn what 
template arguments are eventually anyway. You'll see this pattern 
all over, like `to!string(...)` among others that come up pretty 
early using D.





Re: What does ! Stand for in map! and filter! function calls?

2019-06-02 Thread Rnd via Digitalmars-d-learn

On Sunday, 2 June 2019 at 15:55:46 UTC, Paul Backus wrote:

On Sunday, 2 June 2019 at 15:48:54 UTC, Rnd wrote:
I have recently started using Dlang, hence this basic 
question. Thanks for your insight.


map and filter are templates in D, and !(...) is D's syntax for 
passing arguments to templates:


map!(x => x*x)([1, 2, 3, 4, 5])
 ^ ^
 | |
 | +- This array is a normal function argument
 |
 +- This lambda is a template argument


Is it not possible in the language to have template map function 
also to called as map(x=>... ?


This will reduce complexity which will attract more people to 
this language.


Easy languages have great mass appeal as has been shown with Ruby 
and Python.


Re: What does ! Stand for in map! and filter! function calls?

2019-06-02 Thread Cym13 via Digitalmars-d-learn

On Sunday, 2 June 2019 at 15:48:54 UTC, Rnd wrote:
I have recently started using Dlang, hence this basic question. 
Thanks for your insight.


To know more about D you should take the time to do the D tour 
[1] which provides you with general knowledge of most of D's 
functionalities and vocabulary.


To know more about templates specifically, check out this 
tutorial [2].


[1]: https://tour.dlang.org/
[2]: http://nomad.uk.net/articles/templates-in-d-explained.html


Re: What does ! Stand for in map! and filter! function calls?

2019-06-02 Thread Paul Backus via Digitalmars-d-learn

On Sunday, 2 June 2019 at 15:48:54 UTC, Rnd wrote:
I have recently started using Dlang, hence this basic question. 
Thanks for your insight.


map and filter are templates in D, and !(...) is D's syntax for 
passing arguments to templates:


map!(x => x*x)([1, 2, 3, 4, 5])
 ^ ^
 | |
 | +- This array is a normal function argument
 |
 +- This lambda is a template argument


What does ! Stand for in map! and filter! function calls?

2019-06-02 Thread Rnd via Digitalmars-d-learn
I have recently started using Dlang, hence this basic question. 
Thanks for your insight.


Re: hasElaborateCopyConstructor bug?

2019-06-02 Thread Paul Backus via Digitalmars-d-learn

On Sunday, 2 June 2019 at 14:44:47 UTC, H. S. Teoh wrote:
On Sun, Jun 02, 2019 at 02:32:16PM +, Paul Backus via 
Digitalmars-d-learn wrote: [...]
If std.v2 ever materializes, we'll have an opportunity to fix 
papercuts like this. Until then, my preferred workaround is to 
use a renaming import:


import std.traits: hasNontrivialCopy = 
hasElaborateCopyConstructor;


Couldn't we just rename hasElaborateCopyConstructor to 
hasNontrivialCopy and leave a deprecated alias from the former 
to the latter? (Or perhaps without the deprecation, but the 
documentation would use the new name and hopefully new code 
would, too.)



T


My impression was that a pure name change would be unlikely to 
pass review (see for example 
https://github.com/dlang/phobos/pull/6227). But perhaps it's 
worth submitting the PR anyway just to see what happens.


Re: hasElaborateCopyConstructor bug?

2019-06-02 Thread H. S. Teoh via Digitalmars-d-learn
On Sun, Jun 02, 2019 at 02:32:16PM +, Paul Backus via Digitalmars-d-learn 
wrote:
[...]
> If std.v2 ever materializes, we'll have an opportunity to fix
> papercuts like this. Until then, my preferred workaround is to use a
> renaming import:
> 
> import std.traits: hasNontrivialCopy = hasElaborateCopyConstructor;

Couldn't we just rename hasElaborateCopyConstructor to hasNontrivialCopy
and leave a deprecated alias from the former to the latter? (Or perhaps
without the deprecation, but the documentation would use the new name
and hopefully new code would, too.)


T

-- 
Unix was not designed to stop people from doing stupid things, because that 
would also stop them from doing clever things. -- Doug Gwyn


Re: Very simple null reference escape

2019-06-02 Thread Paul Backus via Digitalmars-d-learn

On Sunday, 2 June 2019 at 07:55:27 UTC, Amex wrote:

A.B

If A is null, crash.

A?.B : writeln("HAHA");

No crash, ignored, equivalent to

if (A is null) writeln("HAHA"); else A.B;


The "optional" package on dub [1] has a .dispatch method that 
does this:


auto d = some(A());

// Dispatch to one of its methods

d.dispatch.f(); // calls a.f, returns some(4)
d.dispatch.inner.g(); // calls a.inner.g, returns some(7)

// Use on a pointer or reference type as well
A* e = null;

// If there's no value in the reference type, dispatching
// works, and produces an optional
assert(e.dispatch.f() == none);
assert(e.dispatch.inner.g() == none);


Full example: https://run.dlang.io/is/SmsGQu

[1] https://code.dlang.org/packages/optional


Re: hasElaborateCopyConstructor bug?

2019-06-02 Thread Paul Backus via Digitalmars-d-learn

On Sunday, 2 June 2019 at 06:59:02 UTC, Jonathan M Davis wrote:
Almost certainly, hasElaborateCopyConstructor should be updated 
to test for both postblit constructors and copy constructors, 
since its purpose is to test for whether the type has a 
user-defined copying function [...] Whether 
hasElaborateCopyConstructor was the best name is debatable, but 
it _does_ involve "elaborate" copying, and copy constructors 
weren't actually in the language at the time. The documentation 
is wonderfully confusing though in that it talks about copy 
constructors and then says that a copy constructor is 
introduced by defining this(this) for a struct. So, it 
basically calls a postblit constructor a copy constructor.


I've made the mistake in the past of trying to use 
hasElaborateCopyConstructor to test for the presence of 
__xpostblit, and I'm sure I'm not the only one. The name is quite 
misleading--even more so now that D has real copy constructors.


If std.v2 ever materializes, we'll have an opportunity to fix 
papercuts like this. Until then, my preferred workaround is to 
use a renaming import:


import std.traits: hasNontrivialCopy = 
hasElaborateCopyConstructor;


Re: Reading .pem files for secured

2019-06-02 Thread Dukc via Digitalmars-d-learn

On Friday, 31 May 2019 at 12:17:14 UTC, Sebastiaan Koppe wrote:
Just base64 decode the PEM data (without the ) and feed it 
to RSA.this(ubyte[] publicKey). Ought to be that simple.


I assume the same should apply with private key and private key 
constructor (along with a random password of course)?




Re: Reading .pem files for secured

2019-06-02 Thread Dukc via Digitalmars-d-learn

On Friday, 31 May 2019 at 12:17:14 UTC, Sebastiaan Koppe wrote:
Just base64 decode the PEM data (without the ) and feed it 
to RSA.this(ubyte[] publicKey). Ought to be that simple.


That's logic of SSL? Okay, I'll try that first.


Re: How to create an overwriteable struct that is always const?

2019-06-02 Thread David Zhang via Digitalmars-d-learn

Ah, fair enough.


Re: 'version'-based code selection

2019-06-02 Thread Yatheendra via Digitalmars-d-learn

On Saturday, 1 June 2019 at 07:46:40 UTC, Jonathan M Davis wrote:


Like static ifs, version statements are completely a 
compile-time construct and having nothing to do with runtime 
beyond how they affect the code that's generated.

...
- Jonathan M Davis


Thanks for taking the time.

That's it then for selecting between malloc/free implementations 
at runtime (program start-up time, usually) in such a way. There 
might still be hope in the form of a separate dynamic library 
with re-implemented malloc, and equivalent wrapper API's around 
libc in another library (whole program, including Phobos, relying 
on the same malloc library).


Re: How to create an overwriteable struct that is always const?

2019-06-02 Thread ag0aep6g via Digitalmars-d-learn

On 02.06.19 04:22, David Zhang wrote:

On Saturday, 1 June 2019 at 13:00:50 UTC, ag0aep6g wrote:


How is setting/replacing different from modifying?


e.g.:

     S s;

     this() { s = ...; }

     update(S s) { this.s = s; }

     mod(int i) { s.i = i; } // illegal

Kinda like how strings can be copied and assigned to, but not modified.


The `string` itself can be modified: You can change its length, and you 
can make it refer to other characters. That's modifying.


You can't modify the string's characters, because the string refers to 
them with an `immutable(char)*` pointer. That means the pointer itself 
is mutable (can be modified), but the data it points to is immutable 
(can't be modified).


You can do the same in your struct: `const(char)* pointer;`. Then you 
can modify the pointer but you can't modify the data it points to.


Very simple null reference escape

2019-06-02 Thread Amex via Digitalmars-d-learn

A.B

If A is null, crash.

A?.B : writeln("HAHA");

No crash, ignored, equivalent to

if (A is null) writeln("HAHA"); else A.B;



Re: hasElaborateCopyConstructor bug?

2019-06-02 Thread Jonathan M Davis via Digitalmars-d-learn
On Saturday, June 1, 2019 5:29:08 PM MDT SrMordred via Digitalmars-d-learn 
wrote:
> On Saturday, 1 June 2019 at 21:39:33 UTC, SImen Kjærås wrote:
> > On Saturday, 1 June 2019 at 21:05:32 UTC, SrMordred wrote:
> >
> > hasElaborateCopyConstructor checks if the type defines a
> > postblit[0].
>
>   Yes, I know this.
>
> But since dmd 2.086 we have copy ctors:
> https://dlang.org/changelog/2.086.0.html#copy_constructor
>
> And its seem logical that if I want a trait that check if copy
> ctors exists I will use this name 'hasElaborateCopyConstructor'
>
> So it looks like a naming issue for me.
> Unless postblits will be eventually replaced by copy ctors.

Effectively, postblit constructors are being replaced by copy constructors.
Ideally, no new code would be written with postblit constructors, and all
existing postblit constructors would eventually be replaced with copy
constructors. However, because of how long postblit constructors have
existed in the language, Walter has no interest in actually deprecating them
until he actually has to (so potentially never) in order to avoid code
breakage.

Almost certainly, hasElaborateCopyConstructor should be updated to test for
both postblit constructors and copy constructors, since its purpose is to
test for whether the type has a user-defined copying function (be it
explicitly or because the type contains a type with a user-defined copying
function) - and thus whether copying the type involves anything other than
simply blitting. Historically, the user-defined copying function has been
the postblit constructor, but whether it's a postblit constructor or a copy
constructor is pretty much irrelevant to the purpose of the trait.

It does make _some_ sense that it's not hasPostblit or
hasPostblitConstructor, because that could easily be misconstrued as being
whether it explicitly has a user-defined postblit constructor, which isn't
what it tests. If a type has a postblit constructor in it directly, it has
the member __postblit and the member __xpostblit (where __postblit is the
explicitly declared postblit constructor and __xpostblit is what calls the
postblit constructor). However, if the type does not directly declare a
postblit constructor but it has a member that does declare one (directly or
indirectly), then it will just have __xpostblit, which will in turn deal
with copying each member correctly. So, calling the trait hasPostblit could
easily have given the wrong impression. Whether hasElaborateCopyConstructor
was the best name is debatable, but it _does_ involve "elaborate" copying,
and copy constructors weren't actually in the language at the time. The
documentation is wonderfully confusing though in that it talks about copy
constructors and then says that a copy constructor is introduced by defining
this(this) for a struct. So, it basically calls a postblit constructor a
copy constructor.

Regardless, as long as changing hasElaborateCopyConstructor to test for both
the postblit constructor and the copy constructor isn't likely to break
anything (and I don't _think_ that it will, but I'd have to think about it
more to say for sure), then it should just be updated to take copy
constructors into account. And if we ever do reach the point that we
actually fully get rid of postblit constructors, then
hasElaborateCopyConstructor can be updated to not test for postblit
constructors any longer.

- Jonathan M Davis






Re: How to create an overwriteable struct that is always const?

2019-06-02 Thread Jonathan M Davis via Digitalmars-d-learn
On Saturday, June 1, 2019 8:23:58 PM MDT David Zhang via Digitalmars-d-learn 
wrote:
> On Saturday, 1 June 2019 at 16:30:12 UTC, Jonathan M Davis wrote:
> > If any member variable of a struct is const, then you can't
> > modify that member ever, and assignment isn't possible unless
> > you override opAssign so that it overwrites only the mutable
> > members. It's very rare that it makes sense to make any member
> > variables of a struct const or immutable, because then you
> > basically can't use assignment anymore.
> >
> > You could make all of the member variables private and provide
> > no functions that set any of them, then the only way to change
> > any of their values would be to construct a new value of that
> > type and assign it to the variable.
> >
> > - Jonathan M Davis
>
> Ideally, I'd like for member functions to be checked against
> modifying s also, not just externally.

If the member functions are const or inout, then they won't be able to
modify any members.

- Jonathan M Davis