Re: D is dead

2018-08-28 Thread Walter Bright via Digitalmars-d

On 8/28/2018 6:39 AM, Iain Buclaw wrote:
Template emission strategy is a mess, we're better off just instantiating all 
templates in all compilation units, and let the compiler decide whatever to 
discard. Even -allinst does not instantiate enough to allow the compiler to make 
such decisions that C++ has no problem with (most of the time).


Martin and I proposed a simple strategy for that, but Kenji implemented a 
different algorithm that nobody understands, and has proved inadequate. There 
are a couple unresolved bug reports on that.


Re: Dicebot on leaving D: It is anarchy driven development in all its glory.

2018-08-28 Thread Tobias Müller via Digitalmars-d
H. S. Teoh  wrote:
> On Tue, Aug 28, 2018 at 10:20:06AM -0700, Manu via Digitalmars-d wrote:
> [...]
> Actually, I think C++ const is not very useful, because it guarantees
> nothing. At the most, it's just a sanity checker to make sure the
> programmer didn't accidentally do something dumb. But given an opaque
> C++ function that takes const parameters, there is ZERO guarantee that
> it doesn't actually modify stuff behind your back, and do so legally
> (per spec).

No, casting away const on pointers and references is only legal if the
object pointed to is actually mutable (not const). Everything else is UB.
Casting away const of a function parameter that is not under your control
will sooner or later lead to UB.

Tobi


Re: Is @safe still a work-in-progress?

2018-08-28 Thread Walter Bright via Digitalmars-d

On 8/23/2018 6:10 AM, Atila Neves wrote:

--
struct S {
     int x;
     @safe int* foo() { return  }
}
--

% dmd -o- -dip1000 foo.d
% echo $?
0


struct S {
int x;
@safe int* foo() { return  }
}

int* bar() {
S s;
return s.foo();
}

dmd test -dip1000
test.d(3): Error: returning  escapes a reference to parameter this, 
perhaps annotate with return





Oops:

--
int* gPtr;
void main() {
     auto s = S(42);
     gPtr = s.foo;
}
--


I get:

test.d(3): Error: returning  escapes a reference to parameter this, 
perhaps annotate with return




--
int[] gSlice;
void main() {
     auto s = S([42]);
     gSlice = s.foo;
}

struct S {
     int[] x;
     @safe int[] foo() return { return x; }
}
--


T[] is treated like T* as far as scope, etc., are concerned. You should see 
identical results.


And in a struct, `this` is a `ref`, yet `scope` on a member function applies to 
`this`.


Actually, it applies to fields of `this`.


Re: Is @safe still a work-in-progress?

2018-08-28 Thread Nicholas Wilson via Digitalmars-d

On Wednesday, 29 August 2018 at 05:04:22 UTC, Walter Bright wrote:

On 8/25/2018 4:09 AM, Nicholas Wilson wrote:
On Saturday, 25 August 2018 at 02:25:41 UTC, Walter Bright 
wrote:
I'm not hostile to debate. I just don't care for "this is 
uncharted territory, so let's do nothing" which has been 
going on for probably 4 years now, coincident with "scope is 
incomplete, D sux".


I.e. lead, follow, or get out of the way :-)


Document it


Already done: https://issues.dlang.org/show_bug.cgi?id=19097


Bugzilla is not documentation. These are language changes they 
need to be in release notes and the spec.


Re: Is @safe still a work-in-progress?

2018-08-28 Thread Walter Bright via Digitalmars-d

On 8/28/2018 6:12 AM, Steven Schveighoffer wrote:
So this would mean a member function would have to be refactored into a 
different function with a different calling syntax. i.e:


x.foo(target);

would have to be refactored to:

target.foo(x);

or foo(target, x);


Maybe it should be anyway.


But in terms of put, strictly speaking, any call of some.pipeline.put(x) is 
wrong. It should be put(some.pipeline, x), to avoid issues with how put was 
designed.


There are some of those in Phobos, too. It's covered by the proposed addition.



I don't know how to prove anything with programming languages.
I don't mean prove like mathematical proof. I mean try to consider how this 
affects all cases instead of just the one case that will make phobos compile.


"show" is a better verb than "prove".


I don't know how to find all cases, either, except by implementing it.


Re: Is @safe still a work-in-progress?

2018-08-28 Thread Walter Bright via Digitalmars-d

On 8/25/2018 4:09 AM, Nicholas Wilson wrote:

On Saturday, 25 August 2018 at 02:25:41 UTC, Walter Bright wrote:
I'm not hostile to debate. I just don't care for "this is uncharted territory, 
so let's do nothing" which has been going on for probably 4 years now, 
coincident with "scope is incomplete, D sux".


I.e. lead, follow, or get out of the way :-)


Document it


Already done: https://issues.dlang.org/show_bug.cgi?id=19097


Re: Is @safe still a work-in-progress?

2018-08-28 Thread Walter Bright via Digitalmars-d

On 8/25/2018 5:42 AM, Chris M. wrote:
What about my other point then on the syntax? I think something similar to what 
I suggested would be a much more flexible solution and is worth considering.


Much more work would be needed to make that a proposal.



Re: D now has a dangerous competitor

2018-08-28 Thread bauss via Digitalmars-d

On Tuesday, 28 August 2018 at 23:27:09 UTC, Nick Sabalausky wrote:
On Tuesday, 28 August 2018 at 21:57:28 UTC, solidstate1991 
wrote:


Thanks to my education, I first wanted to approach every 
problems in programming from an object-oriented viewpoint, 
since that was the only one we were taught.




Sounds like you were more or less lucky compared to average: 
For a long while, OOP wasn't just the only thing taught, it was 
frequent taught specifically to be "the one and only right way."


It's not so much OOP itself that's hated: It's the late 90's 
early 2000's obsession that OOP is the one right way to do 
EVERYTHING that gets a lot of (much deserved) hate.


I used to do a lot of OO myself (in fact, Tango was very 
heavily rooted in OOP design), but the more I use D2 and other 
things, the more convinced I am that there are just simply 
better mechanisms (provided the language in question supports 
them well enough) to get the benefits offered by traditional 
inheritance-based OOP, without so much of the now-well-known 
downsides. I'm 90% convinced that an equivalent of traditional 
Java-style OOP could be constructed out of these meachanisms 
without too much trouble, and is effectively a subset of them. 
If I were a grad student, I would totally do a thesis around 
that.


Honestly C++ did OOP somewhat right, because it wasn't forced 
upon you, but C++ itself has design issues, that I think D has 
solved very well.


D does OOP better than C++, but D is still missing some very 
common OOP patterns.


See: 
https://forum.dlang.org/thread/tjqxslxfxjgliyziz...@forum.dlang.org


In C#, Java etc. that's a perfectly common pattern. I don't know 
what C++'s behavior is, but I guess it doesn't matter in C++, 
because of friends.


[Issue 19203] alias this to a bool behaves both inconsistently and incorrectly with static assert

2018-08-28 Thread d-bugmail--- via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=19203

--- Comment #1 from Nicholas Wilson  ---
s/isArrayLike/hasPopBack

--


[Issue 19203] New: alias this to a bool behaves both inconsistently and incorrectly with static assert

2018-08-28 Thread d-bugmail--- via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=19203

  Issue ID: 19203
   Summary: alias this to a bool behaves both inconsistently and
incorrectly with static assert
   Product: D
   Version: D2
  Hardware: x86
OS: Mac OS X
Status: NEW
  Severity: enhancement
  Priority: P1
 Component: dmd
  Assignee: nob...@puremagic.com
  Reporter: iamthewilsona...@hotmail.com

struct BoolWithErr {
bool b;
string error;
alias b this;
}

struct Foo {}

template hasPopBack(T) {
static if (!is(typeof(T.init.popBack)))
enum hasPopBack = BoolWithErr(false, T.stringof~" does not have
popBack");
else
enum hasPopBack = BoolWithErr(true,"");
}

int main()
{   
// Fine:
auto a = isArrayLike!Foo && isArrayLike!Foo; // false
enum b = isArrayLike!Foo && isArrayLike!Foo; // false
pragma(msg, typeof(a)); // bool

// Fine:
// Error: static assert: b is false
static assert(b);

// Dubious: alias this b should work
// Error: expression isArrayLike!(Foo) of type BoolWithErr does not have a
boolean value
//   while evaluating: static assert(isArrayLike!(Foo))
static assert(isArrayLike!Foo);

// Bad: typeof the expression is bool
// Error: expression isArrayLike!(Foo) && isArrayLike!Foo of type
BoolWithErr does not have a boolean value
//while evaluating: static assert(isArrayLike!(Foo) && isArrayLike!Foo)
static assert(isArrayLike!Foo && isArrayLike!Foo);

return 0;
}

--


Re: Dicebot on leaving D: It is anarchy driven development in all its glory.

2018-08-28 Thread Manu via Digitalmars-d
On Tue, 28 Aug 2018 at 19:00, Walter Bright via Digitalmars-d
 wrote:
>
> There's been some talk of adding a "mutable" qualifier for fields, which would
> stop the transitivity of const at that point. But it has problems, such as 
> what
> happens with opaque types. The compiler can no longer check them, and hence 
> will
> have to assume they contain mutable members.

Exactly. And you arrive at C++.
'c-const' and 'turtles-const' probably need to be specified
differently from the top, not broken along the way with the likes of
mutable.


Re: Dicebot on leaving D: It is anarchy driven development in all its glory.

2018-08-28 Thread Manu via Digitalmars-d
On Tue, 28 Aug 2018 at 10:54, H. S. Teoh via Digitalmars-d
 wrote:
>
> On Tue, Aug 28, 2018 at 10:20:06AM -0700, Manu via Digitalmars-d wrote:
> [...]
> > The reality is though, that D's const is not actually very useful, and
> > C++'s const is.
>
> Actually, I think C++ const is not very useful, because it guarantees
> nothing. At the most, it's just a sanity checker to make sure the
> programmer didn't accidentally do something dumb.

I'd rate that as "pretty damn useful"™!

> But given an opaque
> C++ function that takes const parameters, there is ZERO guarantee that
> it doesn't actually modify stuff behind your back, and do so legally
> (per spec).

Well it can't modify the head-object... that's the point of head-const!

> I mean, how many times have you written const_cast<...>
> just to get a piece of code to compile?

Never in my life. That's a heinous crime. If it were removed from C++
and declared UB, I'd be fine with that.

> I know I've been guilty of this
> in many places, because it simply isn't worth the effort to track down
> all the places of the code that you need to fix to make it
> const-correct.  So basically, C++ const is nothing more than an
> annotation that isn't really enforced.

It could be enforced though. const_cast<> doesn't have to exist, and
`mutable` doesn't have to exist either.
That would strengthen C++'s design to make it more meaningful while
retaining a generally useful semantic.

That said, D's transitive const is a nice thing to be able to
express... I just recognise that it's mostly useless, and from that
perspective, I think being able to express the C++ meaning would be
useful, and certainly MORE useful.
I wonder if there's a design that could allow to express both options
selectively?

> But you're spot on about D's const, though.  While D's const *does*
> provide real guarantees (unless you tread into UB territory by casting
> it away), that also limits its scope so much that it's rarely useful
> outside of rather narrow confines.  Yet because it's so strict, using it
> requires investing significant effort.  So you end up with the
> unfortunate situation of "a lot of effort" + "limited usefulness" which
> for many people equals "not worth using".

And then that case of not being used (even if it could have) blocks
use somewhere else, and not(/unable-to)-const spreads like a virus >_<

> > D has no way to express head-const, and it turns out it's a
> > tremendously useful concept.
>
> I can live without head-const... but what *really* makes const painful
> for me is the lack of head-mutable. I.e., given a const container (which
> implies const objects), there is no universal way to obtain a mutable
> reference to said const objects,

... I think we're talking about the same thing.
In this context, the container is the 'head', and the elements would
be mutable beneath that unless declared const themselves.

> unless you tread into UB territory by
> forcefully casting it away.  This makes const so limited in
> applicability that, for the most part, I've given up using const at all,
> in spite of having tried quite hard to use it as much as possible for
> years.

Right. This appears to be the accepted recommendation for quite some
time, and no change in sight.
Tragically, the more people resign to this recommendation (and it's
practically official at this stage), the harder it becomes to use even
if you want to; any library code that you interact with that didn't
use const because 'recommendation' creates interaction blockages for
your own code, propagating can't-use-const into your client code,
despite your best intentions.

D's const is an objective failure. I don't think anyone could argue
otherwise with a straight face. It's sad but true; the surface area
and complexity of the feature absolutely doesn't justify its limited
(and actively waning) usefulness.



Re: Dicebot on leaving D: It is anarchy driven development in all its glory.

2018-08-28 Thread Walter Bright via Digitalmars-d
There's been some talk of adding a "mutable" qualifier for fields, which would 
stop the transitivity of const at that point. But it has problems, such as what 
happens with opaque types. The compiler can no longer check them, and hence will 
have to assume they contain mutable members.


Re: Dicebot on leaving D: It is anarchy driven development in all its glory.

2018-08-28 Thread Walter Bright via Digitalmars-d
Thanks, that's a good explanation of the point of the differences between const 
and immutable.


Re: Dicebot on leaving D: It is anarchy driven development in all its glory.

2018-08-28 Thread tide via Digitalmars-d

On Tuesday, 28 August 2018 at 20:32:29 UTC, H. S. Teoh wrote:
On Tue, Aug 28, 2018 at 07:39:20PM +, tide via 
Digitalmars-d wrote:

On Tuesday, 28 August 2018 at 17:02:46 UTC, H. S. Teoh wrote:
> On Tue, Aug 28, 2018 at 08:18:57AM +, Eugene Wissner via 
> Digitalmars-d wrote: [...]
> > There are still valid use cases where const should be 
> > "broken". One of them is mutex (another one caching). I 
> > have very little experiance in multi-threaded programming, 
> > but what do you think about "mutable" members, despite the 
> > object is const?
> 
> The problem with compromising const is that it would 
> invalidate any guarantees const may have provided.  Const in 
> D is not the same as const in languages like C++; const in D 
> means *physical* const, as in, the data might reside in ROM 
> where it's physically impossible to modify.  Allowing the 
> user to bypass this means UB if the data exists in ROM.


I feel that such a narrow use case, wouldn't you just use 
something like immutable instead.


The problem is that immutable implicitly converts to const.  
Basically, const means "I guarantee I will never modify this 
data (though someone else might", and immutable means "nobody 
will ever modify this data". You cannot allow const to mutate 
without risking breakage with immutable.  If the original data 
came from a mutable reference, you can probably get away with 
casting const away. But if it came from an immutable object, 
casting const away is UB.  Allowing const to be "sometimes" 
modified is also UB.



> Plus, the whole point of const in D is that it is 
> machine-verifiable, i.e., the compiler checks that the code 
> does not break const in any way and therefore you are 
> guaranteed (barring compiler bugs) that the data does not 
> change.  If const were not machine-verifiable, it would be 
> nothing more than programming by convention, since it would 
> guarantee nothing.  Allowing const to be "broken" somewhere 
> would mean it's no longer machine-verifiable (you need a 
> human to verify whether the semantics are still correct).


This is still not true, it is not machine verifiable as it is. 
It can be bypassed quite easily, as a const object can be 
assigned from an non-const one. There's no way to offer that 
guarantee.


You misunderstand. Const means "this code cannot modify this 
object no matter what".  It does not guarantee somebody else 
can't modify it (you want immutable for that).  Both mutable 
and immutable implicitly convert to const, therefore it is 
imperative that code that handles const never modifies the 
data, because you don't know the provenance of the data: it 
could have come from an immutable object.  Allowing const to 
"sometimes" modify stuff will violate immutable and cause UB.


Whether a piece of code modifies the data is certainly 
machine-verifiable -- but only if there are no backdoors to 
const. If there are, then the compiler cannot feasibly verify 
const, since it would need to transitively examine all code 
called by the code in question, but the source code may not be 
always available.


Even if the data came from a mutable object, it does not make 
it any less machine-verifiable, since what we're verifying is 
"this code does not modify this data", not "this data never 
changes".  For the latter, immutable provides that guarantee, 
not const.  It is possible, for example, to obtain a const 
reference to a mutable object, and have one thread modify the 
object (via the mutable reference) while another thread reads 
it (via the const reference).  You cannot guarantee that the 
data itself won't change, but you *can* guarantee that the code 
holding the const reference (without access to the mutable 
reference) isn't the one making the changes.



T


Point being, there is a huge difference between what you were 
saying, and what you are saying now. "This data never changes" is 
a much better guarantee and check than "this code does not modify 
this data". You use const to make sure the data doesn't change, 
if you can't guarantee it doesn't change from any other code then 
I wouldn't say it is machine-verifiable.


So we would need another qualifier "tantamount" to be implemented 
then it seems.




[Issue 19202] New: deprecated eponymous template prints no warning

2018-08-28 Thread d-bugmail--- via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=19202

  Issue ID: 19202
   Summary: deprecated eponymous template prints no warning
   Product: D
   Version: D2
  Hardware: All
OS: All
Status: NEW
  Severity: regression
  Priority: P1
 Component: dmd
  Assignee: nob...@puremagic.com
  Reporter: elpenguin...@gmail.com

```
void main() {
auto b = X!();
}

template X() {
deprecated enum X = true;
}
```
Since dmd 2.069, no warning is printed for this example.

--


Re: D now has a dangerous competitor

2018-08-28 Thread Nick Sabalausky via Digitalmars-d

On Tuesday, 28 August 2018 at 21:57:28 UTC, solidstate1991 wrote:


Thanks to my education, I first wanted to approach every 
problems in programming from an object-oriented viewpoint, 
since that was the only one we were taught.




Sounds like you were more or less lucky compared to average: For 
a long while, OOP wasn't just the only thing taught, it was 
frequent taught specifically to be "the one and only right way."


It's not so much OOP itself that's hated: It's the late 90's 
early 2000's obsession that OOP is the one right way to do 
EVERYTHING that gets a lot of (much deserved) hate.


I used to do a lot of OO myself (in fact, Tango was very heavily 
rooted in OOP design), but the more I use D2 and other things, 
the more convinced I am that there are just simply better 
mechanisms (provided the language in question supports them well 
enough) to get the benefits offered by traditional 
inheritance-based OOP, without so much of the now-well-known 
downsides. I'm 90% convinced that an equivalent of traditional 
Java-style OOP could be constructed out of these meachanisms 
without too much trouble, and is effectively a subset of them. If 
I were a grad student, I would totally do a thesis around that.




Re: Solving the impossible?

2018-08-28 Thread Paul Backus via Digitalmars-d-learn

On Tuesday, 28 August 2018 at 20:37:05 UTC, Everlast wrote:
Also, the biggest complaint is that when we use [] attached to 
a type it has a specific meaning as "an array of". e.g., int[] 
means an array of int's.


But int[] a... then changes as we don't have an array of int's 
any more but simply a sequence of ints. While internally it 
might not matter it just doesn't jive with normal type syntax 
IMO.


The parameter `int[] a...` is an an array of ints just like any 
other `int[]` in D. If you don't believe me, see for yourself 
here: https://run.dlang.io/is/IJdovg


I understand that the syntax does not align with your 
expectations. Instead of complaining about it, I would urge you 
to set your preconceptions aside and learn D with an open mind. 
You'll be less frustrated, more productive, and more successful.


Re: D now has a dangerous competitor

2018-08-28 Thread solidstate1991 via Digitalmars-d

On Tuesday, 28 August 2018 at 11:30:20 UTC, JN wrote:

On Tuesday, 28 August 2018 at 08:39:20 UTC, bauss wrote:

The following language is a dangerous competitor to D.

https://github.com/joaomilho/Enterprise


I often feel like this kind of 'jokes' are trying too hard. 
FizzBuzz Enterprise was fun when it first came out, and I know 
it's popular to hate on OOP programming, especially Java. But 
the fact is, a very big portion of software was built using 
OOP, and many of the hated design patterns have a place in 
programming. Sure, it doesn't provide witty one-liner quicksort 
examples, but when you have a group of people, having to 
integrate multiple webservices/databases, these kind of layered 
code architecture comes in handy.


Of course sometimes people go too far, trying to make the code 
generic and fit every usecase, breaking YAGNI.


Most of the hate towards OOP is misdirected. Java will be always 
slow because it always running in a VM, no structures so you have 
to rely on reference-type classes for everything. Other times 
it's on the developer. Thanks to my education, I first wanted to 
approach every problems in programming from an object-oriented 
viewpoint, since that was the only one we were taught (and I 
missed the classes on interfaces due to an incident, so I 
struggled to keep up).


You have to learn where to use what. I personally hate C and C++ 
precompiler macros more, which made porting LZHAM to D a 
nightmare sometimes. Some parts of the macros got completely 
eliminated since Fiber saves most things on the stack.


Re: Can you get typeof(this) in a mixin template - trying to mimic a Kotlin feature here.

2018-08-28 Thread Alex via Digitalmars-d-learn

On Tuesday, 28 August 2018 at 20:39:16 UTC, aliak wrote:

Hi,

I'm trying to do something similar to what Kotlin allows with 
assigning to member variables from a map. The syntax is very 
readable and looks like:


class User(val map: Map) {
val name: String by map
val age: Int by map
}

So I'm trying to do something similar in D:

mixin template MapMembers(alias aa) {
  foreach (name; typeof(this).tupleof) {
// if name is in aa, then mixin(m = aa[" ~ m ~ "]) ... ish
  }
}
struct User {
  this(Variant[string] aa) {
mixin MapMembers!aa;
  }
}

Seems I can't do typeof(this) inside the mixin.

One workaround is to explicitly pass the type "User" to the 
template mixin, but it feels like this is something that should 
work and I'm just unfamiliar with template mixins and their 
usage.


Cheers,
- Ali

[0] 
https://kotlinlang.org/docs/reference/delegated-properties.html#storing-properties-in-a-map


Isn't the problem, that inside a template a declaration is 
expected, and not a foreach?


This works as expected:

´´´
import std.experimental.all;

void main()
{
writeln("Edit source/app.d to start your project.");
}
mixin template MapMembers(alias aa) {
typeof(this) var;
/*
  foreach (name; typeof(this).tupleof) {
// if name is in aa, then mixin(m = aa[" ~ m ~ "]) ... ish
  }
*/
}
struct User {
  this(Variant[string] aa) {
mixin MapMembers!aa;
  }
}
//mixin MapMembers!(Variant[string].init);
´´´


Re: Solving the impossible?

2018-08-28 Thread Everlast via Digitalmars-d-learn

On Tuesday, 28 August 2018 at 19:40:36 UTC, Paul Backus wrote:

On Tuesday, 28 August 2018 at 19:09:38 UTC, Everlast wrote:
Yeah, I see the link paul posted. The actual syntax seems a 
bit strange to me...


We don't do

A[] a 

So it is not "logical".

foo(A...)(A a)

but if A is a specific type we must do

foo(int[] a ...)

The actual syntax then looks like we have an variadic set of 
parameters of type int[] rather than int.


In `foo(A...)(A a)`, a variadic set of template *arguments* is 
collected into a single template *parameter*, called `A`. In 
`foo(int[] a ...)`, a variadic set of runtime *arguments* is 
collected into a single runtime *parameter* called `a`.


(If you've used Python, it's also similar to how `*args` and 
`**kwargs` collect variadic positional and named arguments into 
a single list or dictionary parameter, respectively.)


It really is the same underlying principle in both cases. It 
just looks different because `foo(A...)(A a)` is a template, 
and `foo(int[] a...)` isn't, and templates use a different 
syntax than regular functions.


In fact, if you wanted to, you could combine the two and do 
something like this:


// All args must have the same type,
// but it can be any type you want.
foo(T)(T[] t...)



Yes, it is the same underlying principle but it is not visually 
consistent IMO.


e.g.,

foo(int[] a)

a is an array of int

foo(int[] a...)

suggests a is an array of an array of int.

I see ... as a generalization of the parameters simply extending 
it to an arbitrary number(which cannot be represented except in 
an arbitrary way).


so

a... means there is an arbitrary number of a's.

int a... means there is an arbitrary number of int.

T a... means there is an arbitrary number of T's

T[] a... means there is an arbitrary number of T[]'s.


For example, to represent an arbitrary number of arrays using the 
current syntax one must do T[][] a...


which looks funky.

Now, it's all not a big deal in the sense that it all works out 
by design, but the question is, is it really needed? It seems 
that requiring [] just adds extra unnecessary symbols that add no 
useful information.



Also, the biggest complaint is that when we use [] attached to a 
type it has a specific meaning as "an array of". e.g., int[] 
means an array of int's.


But int[] a... then changes as we don't have an array of int's 
any more but simply a sequence of ints. While internally it might 
not matter it just doesn't jive with normal type syntax IMO.


int[] a...

vs

int a...

the second one seems better. Simpler, more direct, more obvious, 
and inline with the standard non variadic syntax. The ellipses 
pretty much state that we are dealing with an array, no reason to 
add redundancy.


I'm only talking about syntax here and not semantics.

Of course, if you see a problem with int a... not being 
well-formed then that would be a case against it, but I don't 
think it has that issue.









Can you get typeof(this) in a mixin template - trying to mimic a Kotlin feature here.

2018-08-28 Thread aliak via Digitalmars-d-learn

Hi,

I'm trying to do something similar to what Kotlin allows with 
assigning to member variables from a map. The syntax is very 
readable and looks like:


class User(val map: Map) {
val name: String by map
val age: Int by map
}

So I'm trying to do something similar in D:

mixin template MapMembers(alias aa) {
  foreach (name; typeof(this).tupleof) {
// if name is in aa, then mixin(m = aa[" ~ m ~ "]) ... ish
  }
}
struct User {
  this(Variant[string] aa) {
mixin MapMembers!aa;
  }
}

Seems I can't do typeof(this) inside the mixin.

One workaround is to explicitly pass the type "User" to the 
template mixin, but it feels like this is something that should 
work and I'm just unfamiliar with template mixins and their usage.


Cheers,
- Ali

[0] 
https://kotlinlang.org/docs/reference/delegated-properties.html#storing-properties-in-a-map


Re: Dicebot on leaving D: It is anarchy driven development in all its glory.

2018-08-28 Thread H. S. Teoh via Digitalmars-d
On Tue, Aug 28, 2018 at 06:44:37PM +, aliak via Digitalmars-d wrote:
> On Tuesday, 28 August 2018 at 17:53:36 UTC, H. S. Teoh wrote:
> > On Tue, Aug 28, 2018 at 10:20:06AM -0700, Manu via
> > > D has no way to express head-const, and it turns out it's a
> > > tremendously useful concept.
> > 
> > I can live without head-const... but what *really* makes const
> > painful for me is the lack of head-mutable. I.e., given a const
> > container (which implies const objects), there is no universal way
> > to obtain a mutable reference to said const objects, unless you
> > tread into UB territory by forcefully casting it away.  This makes
> > const so limited in applicability that, for the most part, I've
> > given up using const at all, in spite of having tried quite hard to
> > use it as much as possible for years.
> 
> Simen's opHeadMutable [0] was pretty good solution to this const range
> stuff, but for some reason (not specified by anyone in the thread) it
> didn't seem to catch on :/
> 
> [0] https://forum.dlang.org/post/zsaqtmvqmfkzhrmrm...@forum.dlang.org
[...]

Probably because nobody pushed it hard enough to make it happen.


T

-- 
It only takes one twig to burn down a forest.


Re: Dicebot on leaving D: It is anarchy driven development in all its glory.

2018-08-28 Thread H. S. Teoh via Digitalmars-d
On Tue, Aug 28, 2018 at 07:39:20PM +, tide via Digitalmars-d wrote:
> On Tuesday, 28 August 2018 at 17:02:46 UTC, H. S. Teoh wrote:
> > On Tue, Aug 28, 2018 at 08:18:57AM +, Eugene Wissner via
> > Digitalmars-d wrote: [...]
> > > There are still valid use cases where const should be "broken".
> > > One of them is mutex (another one caching). I have very little
> > > experiance in multi-threaded programming, but what do you think
> > > about "mutable" members, despite the object is const?
> > 
> > The problem with compromising const is that it would invalidate any
> > guarantees const may have provided.  Const in D is not the same as
> > const in languages like C++; const in D means *physical* const, as
> > in, the data might reside in ROM where it's physically impossible to
> > modify.  Allowing the user to bypass this means UB if the data
> > exists in ROM.
> 
> I feel that such a narrow use case, wouldn't you just use something
> like immutable instead.

The problem is that immutable implicitly converts to const.  Basically,
const means "I guarantee I will never modify this data (though someone
else might", and immutable means "nobody will ever modify this data".
You cannot allow const to mutate without risking breakage with
immutable.  If the original data came from a mutable reference, you can
probably get away with casting const away. But if it came from an
immutable object, casting const away is UB.  Allowing const to be
"sometimes" modified is also UB.


> > Plus, the whole point of const in D is that it is
> > machine-verifiable, i.e., the compiler checks that the code does not
> > break const in any way and therefore you are guaranteed (barring
> > compiler bugs) that the data does not change.  If const were not
> > machine-verifiable, it would be nothing more than programming by
> > convention, since it would guarantee nothing.  Allowing const to be
> > "broken" somewhere would mean it's no longer machine-verifiable (you
> > need a human to verify whether the semantics are still correct).
> 
> This is still not true, it is not machine verifiable as it is. It can
> be bypassed quite easily, as a const object can be assigned from an
> non-const one. There's no way to offer that guarantee.

You misunderstand. Const means "this code cannot modify this object no
matter what".  It does not guarantee somebody else can't modify it (you
want immutable for that).  Both mutable and immutable implicitly convert
to const, therefore it is imperative that code that handles const never
modifies the data, because you don't know the provenance of the data: it
could have come from an immutable object.  Allowing const to "sometimes"
modify stuff will violate immutable and cause UB.

Whether a piece of code modifies the data is certainly
machine-verifiable -- but only if there are no backdoors to const. If
there are, then the compiler cannot feasibly verify const, since it
would need to transitively examine all code called by the code in
question, but the source code may not be always available.

Even if the data came from a mutable object, it does not make it any
less machine-verifiable, since what we're verifying is "this code does
not modify this data", not "this data never changes".  For the latter,
immutable provides that guarantee, not const.  It is possible, for
example, to obtain a const reference to a mutable object, and have one
thread modify the object (via the mutable reference) while another
thread reads it (via the const reference).  You cannot guarantee that
the data itself won't change, but you *can* guarantee that the code
holding the const reference (without access to the mutable reference)
isn't the one making the changes.


T

-- 
A program should be written to model the concepts of the task it
performs rather than the physical world or a process because this
maximizes the potential for it to be applied to tasks that are
conceptually similar and, more important, to tasks that have not yet
been conceived. -- Michael B. Allen


Re: D now has a dangerous competitor

2018-08-28 Thread Nick Sabalausky (Abscissa) via Digitalmars-d

On 08/28/2018 04:39 AM, bauss wrote:

The following language is a dangerous competitor to D.

https://github.com/joaomilho/Enterprise


Truly a visionary for this Millennial age. The cloud-plans for 
Enterprise Web 3.0 are particularly disruptive. I'm excited just 
imagining the possibilities it will open to bring onboard a significant 
plurality of contractors with upper-tier invoice payment structures.


Re: concurrency call to arms

2018-08-28 Thread Russel Winder via Digitalmars-d
On Tue, 2018-08-28 at 03:36 +, John Belmonte via Digitalmars-d
wrote:
> On Wednesday, 22 August 2018 at 16:49:01 UTC, Russel Winder wrote:
> > Have you tried asyncio in the Python standard library? Is Trio 
> > better?
> 
> The library that Guido admits is a disaster?  
> https://twitter.com/gvanrossum/status/938445451908472832
> 
> Trio and libraries like it have evolved out of frustration with 
> asyncio.

When I originally wrote the comment I was thinking of asyncore, which
is even worse than asyncio.

[…]
> 
> It's far more than "ensuring join".  It ensures that tasks 
> created by children are similarly constrained.  It allows the 
> normal try-catch of exceptions coming from any level of child 
> tasks.  It ensures that when a task has an error, all sibling 
> tasks are cancelled and the resulting multi-exception is 
> propagated to the parent.

Any fork/join framework will provide such guarantees.

> > – except Python is single threaded so the above is time
> > division multiplexing of tasks.
> 
> No, tasks can optionally be real threads (obviously constrained 
> by GIL).  Soon they can be tasks from the "multiprocessing" 
> library as well (separate process, either local or remote).
> 
> These are details of Trio's implementation and Python.  As 
> mentioned, the control structures apply to any concurrency model 
> (implicit or explicit context switching, OS or light threads, 
> etc.)

But that is the point, this is Python specific, and yet the motivating
example is a misunderstanding of how Go is used. This inconsistency
seriously undermines the general argument.

I have no problem with using with statement and context managers to
enforce fork/join abstractions in Python. But to say this is a new
general abstraction is  false claim.

[…]
> async/await is a means to explicitly mark points of context 
> switching in API's and code.  It applies to threads, coroutines, 
> remote processing, or anything else which may allow something 
> else to modify system state while you're waiting.

Certainly it is a language structure to support yield to the
appropriate scheduler, the question is whether a language structure is
required or it can be handled with library features. I suspect language
feature makes things easier of implementation.

> Local to a single thread, async/await with coroutines happens to 
> be wonderful because it eliminates a ton of explicit locking, 
> fretting about race conditions, etc. required of the programmer.  
> It's a building block-- e.g. you can then combine such threads in 
> careful ways with message passing within and among CPU cores to 
> get the best of all worlds.

I've never really worried about single threaded concurrency, nor used
C#, so I have no actual data to apply to this argument. In a multi-
threaded context, you can do all that is needed using processes and
channels. Having said this executors in single or multi threaded
contexts work fine at the library level without language constructs.

> While Go can certainly implement the nursery and cancellation 
> control structures, there is no turning back on Go's implicit 
> context switching (i.e. any old function call can cause a context 
> switch).  The human is back to fretting about locks and race 
> conditions, and unable to prove that even the smallest of 
> programs is correct.

Not if the user sticks to using processes and channels as is the idiom
on Go. Go has all the locks stuff, but if you use channels as the means
of communication between processes, the programmer never needs explicit
locks since everything is handled bu blocking on channels.

-- 
Russel.
===
Dr Russel Winder  t: +44 20 7585 2200
41 Buckmaster Roadm: +44 7770 465 077
London SW11 1EN, UK   w: www.russel.org.uk



signature.asc
Description: This is a digitally signed message part


Re: Solving the impossible?

2018-08-28 Thread Paul Backus via Digitalmars-d-learn

On Tuesday, 28 August 2018 at 19:09:38 UTC, Everlast wrote:
Yeah, I see the link paul posted. The actual syntax seems a bit 
strange to me...


We don't do

A[] a 

So it is not "logical".

foo(A...)(A a)

but if A is a specific type we must do

foo(int[] a ...)

The actual syntax then looks like we have an variadic set of 
parameters of type int[] rather than int.


In `foo(A...)(A a)`, a variadic set of template *arguments* is 
collected into a single template *parameter*, called `A`. In 
`foo(int[] a ...)`, a variadic set of runtime *arguments* is 
collected into a single runtime *parameter* called `a`.


(If you've used Python, it's also similar to how `*args` and 
`**kwargs` collect variadic positional and named arguments into a 
single list or dictionary parameter, respectively.)


It really is the same underlying principle in both cases. It just 
looks different because `foo(A...)(A a)` is a template, and 
`foo(int[] a...)` isn't, and templates use a different syntax 
than regular functions.


In fact, if you wanted to, you could combine the two and do 
something like this:


// All args must have the same type,
// but it can be any type you want.
foo(T)(T[] t...)


Re: Dicebot on leaving D: It is anarchy driven development in all its glory.

2018-08-28 Thread tide via Digitalmars-d

On Tuesday, 28 August 2018 at 17:02:46 UTC, H. S. Teoh wrote:
On Tue, Aug 28, 2018 at 08:18:57AM +, Eugene Wissner via 
Digitalmars-d wrote: [...]
There are still valid use cases where const should be 
"broken". One of them is mutex (another one caching). I have 
very little experiance in multi-threaded programming, but what 
do you think about "mutable" members, despite the object is 
const?


The problem with compromising const is that it would invalidate 
any guarantees const may have provided.  Const in D is not the 
same as const in languages like C++; const in D means 
*physical* const, as in, the data might reside in ROM where 
it's physically impossible to modify. Allowing the user to 
bypass this means UB if the data exists in ROM.


I feel that such a narrow use case, wouldn't you just use 
something like immutable instead.


Plus, the whole point of const in D is that it is 
machine-verifiable, i.e., the compiler checks that the code 
does not break const in any way and therefore you are 
guaranteed (barring compiler bugs) that the data does not 
change.  If const were not machine-verifiable, it would be 
nothing more than programming by convention, since it would 
guarantee nothing.  Allowing const to be "broken" somewhere 
would mean it's no longer machine-verifiable (you need a human 
to verify whether the semantics are still correct).


This is still not true, it is not machine verifiable as it is. It 
can be bypassed quite easily, as a const object can be assigned 
from an non-const one. There's no way to offer that guarantee.


import std.format : format;

struct Type
{
int value;
}

void test(const ref Type type, int* ptr)
{
int first = type.value;

*ptr = first + 1;

assert(type.value == first, format!"%d != %d"(type.value, 
first));

}

void main()
{
Type type = Type(10);
test(type, );
}


Re: Solving the impossible?

2018-08-28 Thread bauss via Digitalmars-d-learn

On Tuesday, 28 August 2018 at 19:09:38 UTC, Everlast wrote:

On Tuesday, 28 August 2018 at 12:00:50 UTC, bauss wrote:

On Sunday, 26 August 2018 at 02:26:58 UTC, Everlast wrote:

in fact, I'd rather see

void print(T)(T t, int... a)


You were actually close.

void print(T)(T t, int[] a ...);


Yeah, I see the link paul posted. The actual syntax seems a bit 
strange to me...


We don't do

A[] a 

So it is not "logical".

foo(A...)(A a)

but if A is a specific type we must do

foo(int[] a ...)

The actual syntax then looks like we have an variadic set of 
parameters of type int[] rather than int.


Yeah I agree with that, but unfortunately it cannot be changed.


Re: Solving the impossible?

2018-08-28 Thread Everlast via Digitalmars-d-learn

On Tuesday, 28 August 2018 at 12:00:50 UTC, bauss wrote:

On Sunday, 26 August 2018 at 02:26:58 UTC, Everlast wrote:

in fact, I'd rather see

void print(T)(T t, int... a)


You were actually close.

void print(T)(T t, int[] a ...);


Yeah, I see the link paul posted. The actual syntax seems a bit 
strange to me...


We don't do

A[] a 

So it is not "logical".

foo(A...)(A a)

but if A is a specific type we must do

foo(int[] a ...)

The actual syntax then looks like we have an variadic set of 
parameters of type int[] rather than int.





Re: Null-Coalescing Operator and Extensions

2018-08-28 Thread aliak via Digitalmars-d-learn

On Tuesday, 28 August 2018 at 13:27:28 UTC, Simen Kjærås wrote:
Now, as has been pointed out, that only work for 
null-coalescing, not null-propagation. It seems writers of 
Optional, Variant, SumType, and so on, have decided not to 
support this out of the box, but rather wrap it separately, 
like Basile B.'s SafeAccess[1] and aliak's dispatch[2]. There's 
no real obstacle to wrapping member access directly in 
Optional!T such that it always return a 
Optional!(typeof(member)), though.


I've been back and forth on this many times with an Optional 
type. I've come to the conclusion that providing a "safe" 
opDispatch in the optional type itself is worth if it the 
Optional type does not have any member functions. Otherwise it'll 
essentially cripple the user type if it has functions named the 
same. And since the optional types (presented around the forums) 
seem to support range access, it basically means you can't have 
an Optional!Range type - or any T that has a member called empty 
(which is not uncommon IMO). I can't figure out a way around this 
:(


Cheers,
- Ali


[Issue 19201] Error: func called with argument types (ulong) matches both: __c_long and __c_ulong

2018-08-28 Thread d-bugmail--- via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=19201

github-bugzi...@puremagic.com changed:

   What|Removed |Added

 Status|ASSIGNED|RESOLVED
 Resolution|--- |FIXED

--


Re: Dicebot on leaving D: It is anarchy driven development in all its glory.

2018-08-28 Thread aliak via Digitalmars-d

On Tuesday, 28 August 2018 at 17:53:36 UTC, H. S. Teoh wrote:

On Tue, Aug 28, 2018 at 10:20:06AM -0700, Manu via
D has no way to express head-const, and it turns out it's a 
tremendously useful concept.


I can live without head-const... but what *really* makes const 
painful for me is the lack of head-mutable. I.e., given a const 
container (which implies const objects), there is no universal 
way to obtain a mutable reference to said const objects, unless 
you tread into UB territory by forcefully casting it away.  
This makes const so limited in applicability that, for the most 
part, I've given up using const at all, in spite of having 
tried quite hard to use it as much as possible for years.


Simen's opHeadMutable [0] was pretty good solution to this const 
range stuff, but for some reason (not specified by anyone in the 
thread) it didn't seem to catch on :/


[0] 
https://forum.dlang.org/post/zsaqtmvqmfkzhrmrm...@forum.dlang.org





Re: Dicebot on leaving D: It is anarchy driven development in all its glory.

2018-08-28 Thread H. S. Teoh via Digitalmars-d
On Tue, Aug 28, 2018 at 10:20:06AM -0700, Manu via Digitalmars-d wrote:
[...]
> The reality is though, that D's const is not actually very useful, and
> C++'s const is.

Actually, I think C++ const is not very useful, because it guarantees
nothing. At the most, it's just a sanity checker to make sure the
programmer didn't accidentally do something dumb. But given an opaque
C++ function that takes const parameters, there is ZERO guarantee that
it doesn't actually modify stuff behind your back, and do so legally
(per spec).  I mean, how many times have you written const_cast<...>
just to get a piece of code to compile?  I know I've been guilty of this
in many places, because it simply isn't worth the effort to track down
all the places of the code that you need to fix to make it
const-correct.  So basically, C++ const is nothing more than an
annotation that isn't really enforced.

But you're spot on about D's const, though.  While D's const *does*
provide real guarantees (unless you tread into UB territory by casting
it away), that also limits its scope so much that it's rarely useful
outside of rather narrow confines.  Yet because it's so strict, using it
requires investing significant effort.  So you end up with the
unfortunate situation of "a lot of effort" + "limited usefulness" which
for many people equals "not worth using".


> D has no way to express head-const, and it turns out it's a
> tremendously useful concept.

I can live without head-const... but what *really* makes const painful
for me is the lack of head-mutable. I.e., given a const container (which
implies const objects), there is no universal way to obtain a mutable
reference to said const objects, unless you tread into UB territory by
forcefully casting it away.  This makes const so limited in
applicability that, for the most part, I've given up using const at all,
in spite of having tried quite hard to use it as much as possible for
years.


[...]
> I've also had occasional success refactoring to support const, but
> it's certainly the case that success is not guaranteed. And it's
> always time consuming regardless.

Yes, it's time-consuming.  And takes significant effort.  In spite of
being rather limited in applicability.  In my experience, it's useful
for isolated pieces of code near the bottom of the program's call chain,
where there is little or no additional dependencies.  But it's just too
cumbersome to use at any higher level, and a royal pain in generic code
(which I'm quite heavy on).  It probably *can* be made to work in most
cases, but it falls under my umbrella category of "too much effort
needed, only marginal benefits, therefore not worth it".


T

-- 
A linguistics professor was lecturing to his class one day. "In
English," he said, "A double negative forms a positive. In some
languages, though, such as Russian, a double negative is still a
negative. However, there is no language wherein a double positive can
form a negative." A voice from the back of the room piped up, "Yeah,
yeah."


Re: Dicebot on leaving D: It is anarchy driven development in all its glory.

2018-08-28 Thread Manu via Digitalmars-d
On Tue, 28 Aug 2018 at 00:55, Walter Bright via Digitalmars-d
 wrote:
>
> On 8/26/2018 11:16 PM, Manu wrote:
> >> The code looks the same, and in fact, is about 98% the same.
> > This code appears to be a mechanical translation.
>
> It's not. It's by hand. But I had a specific goal of minimizing the diffs, so
> that if the translation didn't work, it reduced the number of places to look 
> for
> the mistake. And in fact, this has saved me a LOT of grief :-)
>
>
> > That's not what
> > happened in this case; he wrote his game in D from scratch.
> > It was just that he arrived at mostly the same place. He was googling
> > for styling and sample material, but I suspect the problem was a lack
> > of topical material demonstrating how he might write his D code
> > differently.
>
> It takes time to learn how to write idiomatic D effectively. I'm still 
> learning
> how to do it right, too.
>
>
> > It's also the case that the significant difference between C++ and D
> > (in my experience) mostly come down to: D has modules, tidier meta,
> > UDA's, slices, and ranges/UFCS. In trade, D struggles with const, and
> > ref is broken.
> > If your code doesn't manifest some gravity towards one of those
> > features, it will tend to be quite same-ey, and advantage may not be
> > particularly apparent.
>
> I suspect that is still a bit stuck on looking at individual instruments and 
> not
> seeing the orchestra.
>
> Let's take the much-maligned D const. It isn't C++ const (let's call that
> "head-const", because that's what it is). Head-const for a function parameter
> tells us very little about what may happen to it in the function. You can 
> pass a
> head-const reference to a container, and have the function add/change/delete
> every element of that container, all without a peep from any C++ tool. Looking
> at the function signature, you've really got no clue whatsoever.
>
> The reason people have trouble with transitive-const is that they are still
> programming in C++, where they *do* add/change/delete every member of the
> "const" container.

We understand... really. I've spent a decade digesting this, and I'm
not one of those that has ever really complained about D's const. I've
always mostly bought into it philosophically.

The reality is though, that D's const is not actually very useful, and
C++'s const is. D has no way to express head-const, and it turns out
it's a tremendously useful concept.
As I said, I tend to create a head-const hack to use in its place, and
that gets me out of jail... but it's specified as undefined behaviour,
which isn't great.

> That includes me. I try to add transitive-const, and it won't compile, 
> because I
> as well am used to replacing the engine and tail lights in my head-const car. 
> In
> order to use transitive-const, it's forcing me to fundamentally re-think how I
> organize code into functions.

I often walk the same path, but sometimes it doesn't yield success,
and in many cases, it just doesn't actually model the problem.
If the problem is that I want a const container class; I don't want a
function I pass a vector to mutate the container structure, that is,
add/remove/reorder/reallocate the array, but I DO intend it to
interact with mutable elements.
That's a perfectly valid problem structure, and it turns out, it's
very common. I would attribute the given element type as const if I
wanted the const-ness to propagate to the elements, that's obvious and
convenient.

It might be that we can sufficiently rearrange all manner of
conventional wisdom to interact successfully with D's const, but I've
been watching this space for 10 years, and nobody has produced any
such evidence, or articles that we can read and understand how to
wrangle successful solutions.
This particular class of problem reeks of the typical criticism for
Rust... that is, I have better things to be doing with my time than
trying to find awkward alternative code structures to pacify the
const-checker, when in reality, const-container-of-mutable-elements is
simply the correct conceptual modeling of the problem.

Anyway, I'm not fighting that battle. I have enough of my own.

> For example, dmd is full of functions that combine data-gathering with
> taking-action. I've been reorganizing to separate data-gathering and
> taking-action into separate functions. The former can be transitive-const, 
> maybe
> even pure. And I like the results, the code becomes much easier to understand.

I've also had occasional success refactoring to support const, but
it's certainly the case that success is not guaranteed. And it's
always time consuming regardless.


[Issue 19201] Error: func called with argument types (ulong) matches both: __c_long and __c_ulong

2018-08-28 Thread d-bugmail--- via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=19201

Iain Buclaw  changed:

   What|Removed |Added

 Status|NEW |ASSIGNED
 CC||ibuc...@gdcproject.org
   Assignee|nob...@puremagic.com|ibuc...@gdcproject.org

--- Comment #1 from Iain Buclaw  ---
https://github.com/dlang/dmd/pull/8632

--


Re: D is dead (was: Dicebot on leaving D: It is anarchy driven development in all its glory.)

2018-08-28 Thread Joakim via Digitalmars-d

On Tuesday, 28 August 2018 at 13:39:40 UTC, Iain Buclaw wrote:

On Thursday, 23 August 2018 at 15:35:45 UTC, Joakim wrote:

On Thursday, 23 August 2018 at 07:37:07 UTC, Iain Buclaw wrote:

On Thursday, 23 August 2018 at 06:58:13 UTC, Joakim wrote:
On Thursday, 23 August 2018 at 03:50:44 UTC, Shachar Shemesh 
wrote:

[...]


Can you list what you or other Weka devs believe those fatal 
flaws to be? Because you've not listed any here, which makes 
you no better than some noob that comes in here, says D has 
to get better or it will die, then can't articulate what 
they mean by "better" or worse, mentions something trivial. 
Of course, you've actually used the language for years, so 
presumably you've got some real concerns, but do you really 
think the bug you just posted is "fatal" to the language?


If you think there are fatal flaws, you might as well list 
them, whether technical or the development process, or you 
will just be ignored like any other noob who talks big and 
can't back it up. You may be ignored anyway, ;) but at least 
you'll have made a case that shows you know what you're 
talking about.


I'd define fatal as some that can be fixed, but breaks 100% 
of everyone's code, even if the change is net positive all 
round.


However how big a problem really is is in the eye of the 
beholder. An example:


Symptom: The compiler can't discard unused symbols at compile 
time, and so it will spend a lot of time pointlessly 
optimising code.


Problem: D has no notion of symbol visibility.

Possible Solution: Make all globals hidden by default unless 
'export'.


Side effects: Everyone will be spending weeks to months 
fixing their libraries in order to only mark what should be 
visible outside the current compilation unit as 'export'.


Benefits: Faster compile times, as in, in the most extreme 
example I've built one project on github with gdc -O2 and 
build time went from 120 seconds to just 3!


So your example of a fatal flaw is that D could be 100X faster 
at compilation instead of just 10X than most every other 
native language out there?! C'mon.




But that's not true. D isn't a fast language to compile, dmd is 
just a fast compiler.


You may get a little leading edge with codebases that are 
effectively C. Once you throw templates into the mix though, 
your problems become exponential.


Spending 4 seconds in the front end and codegen, only to wait 2 
minutes in the optimizer is horrific.


The alternative of discarding what seem to be unused symbols 
only results in linker error of the obscure edge cases sort.


Template emission strategy is a mess, we're better off just 
instantiating all templates in all compilation units, and let 
the compiler decide whatever to discard. Even -allinst does not 
instantiate enough to allow the compiler to make such decisions 
that C++ has no problem with (most of the time).


I think I've hit a variation of this problem before, where 
pulling in a single selective import in Phobos somewhere meant 
the entire module was compiled into the executable (though I 
suppose that could be a linker issue?):


https://forum.dlang.org/thread/gmjqfjoemwtvgqrtd...@forum.dlang.org

I guess this is why scoped/selective imports didn't help that 
much in disentangling Phobos. I figured it wasn't a big deal if 
it was just causing bigger executables, but even though I 
mentioned compilation speed there, I didn't think of how that's 
slowing down the compiler too, as you now note.


Pruning what's evaluated by the compiler based on 
scoped/selective imports, rather than apparently including the 
whole module, and getting D compilers to compile parallelized 
without separately invoking each module/package, ie a -j flag for 
the compiler when you invoke it with all your source at once, 
might be good projects for us to crowdfund, as discussed in this 
and my earlier Nim thread. Separate parallel compilation works 
wonders on my octa-core Android/AArch64 phone, where I mostly 
build D now, would be good to be able to combine that with 
invoking ldc with all source at once.


Re: Dicebot on leaving D: It is anarchy driven development in all its glory.

2018-08-28 Thread H. S. Teoh via Digitalmars-d
On Tue, Aug 28, 2018 at 08:18:57AM +, Eugene Wissner via Digitalmars-d 
wrote:
[...]
> There are still valid use cases where const should be "broken". One of
> them is mutex (another one caching). I have very little experiance in
> multi-threaded programming, but what do you think about "mutable"
> members, despite the object is const?

The problem with compromising const is that it would invalidate any
guarantees const may have provided.  Const in D is not the same as const
in languages like C++; const in D means *physical* const, as in, the
data might reside in ROM where it's physically impossible to modify.
Allowing the user to bypass this means UB if the data exists in ROM.

Plus, the whole point of const in D is that it is machine-verifiable,
i.e., the compiler checks that the code does not break const in any way
and therefore you are guaranteed (barring compiler bugs) that the data
does not change.  If const were not machine-verifiable, it would be
nothing more than programming by convention, since it would guarantee
nothing.  Allowing const to be "broken" somewhere would mean it's no
longer machine-verifiable (you need a human to verify whether the
semantics are still correct).

Many of D's const woes can actually be solved if we had a
language-supported way of declaring the equivalence between const(U!T)
and U!(const(T)), AKA head-mutable.  The language already supports a
(very) limited set of such conversions, e.g., const(T*) is assignable to
const(T)*, because you're just making a copy of the pointer, but the
target is still unchangeable.  However, because there is no way to
specify such a conversion in a user-defined type, that means things like
RefCounted, or caches, or mutexes, cannot be made to work without either
ugly workarounds or treading into UB territory by casting away const.

But if there is a way for a user-defined template U to define a
conversion from const(U!T) to U!(const(T)) (the conversion code, of
course, would have to be const-correct and verifiable by the compiler),
then we could make it so that U!(const(T)) contained a mutable portion
(e.g., the refcount, mutex, cache, etc.) and an immutable portion (the
reference to the const object).


T

-- 
In order to understand recursion you must first understand recursion.


[Issue 19201] New: Error: func called with argument types (ulong) matches both: __c_long and __c_ulong

2018-08-28 Thread d-bugmail--- via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=19201

  Issue ID: 19201
   Summary: Error: func called with argument types (ulong) matches
both: __c_long and __c_ulong
   Product: D
   Version: D2
  Hardware: All
OS: All
Status: NEW
  Severity: blocker
  Priority: P1
 Component: dmd
  Assignee: nob...@puremagic.com
  Reporter: ibuc...@gdcproject.org

Bootstrap builds with gdc are broken in master.

Minimal version without dependencies.
---
enum __c_long : long;
enum __c_ulong : ulong;

void a(ulong r){}
void a(long r){}

void b(__c_long r){}
void b(__c_ulong r){}

void main()
{
a(0L);
b(0L);
}
---


Minimal version with dependencies.
---
import core.stdc.stdint;

void a(ulong r){}
void a(long r){}

void b(uint64_t r){}
void b(int64_t r){}

void main()
{
a(0L);
b(0L);
}
---


Places in dmd that don't compile as a result:

https://github.com/dlang/dmd/blob/05cdf2f55c9d6379e300382ab7af77837c6f4155/src/dmd/dcast.d#L377
https://github.com/dlang/dmd/blob/05cdf2f55c9d6379e300382ab7af77837c6f4155/src/dmd/dcast.d#L381
https://github.com/dlang/dmd/blob/05cdf2f55c9d6379e300382ab7af77837c6f4155/src/dmd/expressionsem.d#L9319
https://github.com/dlang/dmd/blob/05cdf2f55c9d6379e300382ab7af77837c6f4155/src/dmd/optimize.d#L938


The longdouble type has overrides for intXX_t and uintXX_t to be ABI compatible
with C++.

--


Re: Dicebot on leaving D: It is anarchy driven development in all its glory.

2018-08-28 Thread H. S. Teoh via Digitalmars-d
On Mon, Aug 27, 2018 at 06:11:14PM -0700, Walter Bright via Digitalmars-d wrote:
> On 8/27/2018 10:08 AM, H. S. Teoh wrote:
> > Const in D makes sense as-is.  Though, granted, its infectiousness means
> > its scope is actually very narrow, and as a result, we ironically
> > can't use it in very many places, and so its touted benefits only
> > rarely apply. :-(  Which also means that it's taking up a lot of
> > language design real estate with not many benefits to show for it.
> 
> D const is of great utility if you're interested in functional
> programming.  Using it has forced me to rethink how I separate tasks
> into functions, and the result is for the better.
> 
> I agree that D const has little utility if you try to program in C++
> style.

I am very interested in functional programming, yet ironically, one of
D's top functional programming selling points, ranged-based programming,
interacts badly with const.  Just ask Jonathan about using ranges with
const, and you'll see what I mean. :-)

The very design of ranges in D requires that the range be mutable.
However, because const is infectious, this makes it a royal pain to use
in practice.  Take, for example, a user-defined container type, let's
call it L. For argument's sake, let's say it's a linked list.  And let's
say the list elements are reference-counted -- we'll write that as
RefCounted!Elem even though this argument isn't specific to the current
Phobos implementation of RefCounted.

As experience has shown in the past, it's usually a good idea to
separate the container from the range that iterates over it, so an
obvious API choice would be to define, say, an .opSlice method for L
that returns a range over its elements.

Now, logically speaking, iterating over L shouldn't modify it, so it
would make sense that .opSlice should be const. So we have:

struct L {
private RefCounted!Elem head, tail;
auto opSlice() const {
...
}
}

The returned range, however, must be mutable, since otherwise you
couldn't use .popFront to iterate over it (and correspondingly, Phobos
isInputRange would evaluate to false).  But here's the problem: because
opSlice is declared const, that means `this` is also const, which means
this.head and this.tail are also const.  But since this.head is const,
that means you couldn't do this:

auto opSlice() const {
struct Result {
RefCounted!(const(Elem)) current;
... // rest of range API
void popFront() {
current = current.next;
// Error: cannot assign const(RefCounted!Elem) 
to RefCounted!(const(Elem))
}
}
return Result(head); // <-- Error: cannot assign 
const(RefCounted!Elem) to RefCounted!(const(Elem))
}

This would have worked had we used pointers instead, because the
compiler knows that it's OK to assign const(Elem*) to const(Elem)*.
However, in this case, the compiler has no way of knowing that it is
safe to assign const(RefCounted!Elem) to RefCounted!(const(Elem)).
Indeed, they are different types, and the language currently has no way
of declaring the head-mutable construct required here.

This is only the tip of the iceberg, of course.  If you then try to add
a method to RefCounted to make it convert const(RefCounted!T) to
RefCounted!(const(T)), then you'll be led down a rabbit hole of further
problems with const (e.g., how to implement ref-counting with const
objects in a way that doesn't violate the type system) until you reach
the point where it's impossible to proceed without casting away const
somehow.  Unfortunately, the spec says that's Undefined Behaviour.  So
you're on your own.

This is just one example among many, that const is hard to use in the
general case.  It works fairly well for a narrow number of cases, such
as for built-in types, but once you start generalizing your code, you'll
find brick walls in undesired places, the workarounds for which require
so much effort as to offset any benefits that const may have brought.

TL;DR: const is beautiful in theory, but hard to use in practice.  So
hard that it's often not worth the trouble, despite the benefits that it
undoubtedly does provide.

P.S. If D had the concept of head-mutable, a lot of this pain (though
not all) would have been alleviated.


T

-- 
"I'm running Windows '98." "Yes." "My computer isn't working now." "Yes, you 
already said that." -- User-Friendly


Re: D support for ChromeOS

2018-08-28 Thread Joakim via Digitalmars-d-announce
On Tuesday, 28 August 2018 at 12:34:50 UTC, Martin Tschierschke 
wrote:

On Wednesday, 22 August 2018 at 10:28:32 UTC, Joakim wrote:

https://play.google.com/store/apps/details?id=com.termux=en



$ apt search ldc
Sorting... Done
Full Text Search... Done
ipcalc/stable 0.41 aarch64
  Calculates IP broadcast, network, Cisco wildcard mask, and 
host ranges


ldc/stable 1.11.0 aarch64
  D programming language compiler, built with LLVM

http://termux.net/dists/stable/main/binary-aarch64/

You should post it, as an extra topic on announce:
  D on Android with Termux LDC now 32 and 64 Bit!
  ...

Thank you - it works!


I did, though not as a new topic:

https://forum.dlang.org/post/zgjzldisifhkgcgxk...@forum.dlang.org

I'm updating the wiki on how to use it and getting rid of the 
main function requirement, then I'll write up a post for Mike on 
the D blog.


Re: std.encoding:2554 - Unrecognized Encoding: big5 - Please help!

2018-08-28 Thread Kagamin via Digitalmars-d

On Tuesday, 28 August 2018 at 13:38:39 UTC, spikespaz wrote:
The problem arises when he types 
"google.com.hk/search?q={{query}}" (exact string)


AFAIK, google has a parameter to output results in utf8.


Weird (buggy) behaviour of "protected static" in classes

2018-08-28 Thread Arafel via Digitalmars-d-learn

Hi all,

I have noticed that "protected static" doesn't work currently with 
classes. In my case, I wanted to use "static immutable", but I have 
tried regular static members and methods, and the same issue happens. 
However, the puzzling part is that protected enums (which are a valid 
workaround for me, perhaps not for others) work.


The spec [1] is a bit unclear about how that's supposed to work, 
although I tend to thing that it allows them:


---
protected only applies inside classes (and templates as they can be 
mixed in) and means that a symbol can only be seen by members of the 
same module, or by a derived class. If accessing a protected instance 
member through a derived class member function, that member can only be 
accessed for the object instance which can be implicitly cast to the 
same type as ‘this’. protected module members are illegal.

---

Is that a bug? I have to say, I think so, since it can also affect other 
symbols that are defined... for *grandchild* classes! You can see the 
multiple problems in the snippet [1]:


```dio.d
module dio;

public class A {
public enum int a = 1;
protected enum int b = 2;
private enum int c = 3;
public static immutable int d = 4;
protected static immutable int e = 5;
private static immutable int f = 6;

protected static struct S { }
}

public class A2 {
protected static struct S { }
}
```


```main.d
import dio;

class B : A {
pragma(msg, "The value of A.a is: ", typeof(super).a);
pragma(msg, "The value of A.b is: ", typeof(super).b);
//pragma(msg, "The value of A.c is: ", typeof(super).c); // 
Expected failure

pragma(msg, "The value of A.d is: ", typeof(super).d);
pragma(msg, "The value of A.e is: ", typeof(super).e); // *BUG* 
Comment this line and *BOTH* errors will go away!!
//pragma(msg, "The value of A.f is: ", typeof(super).f); // 
Expected failure


S s;
}

class C : B {
S s;
}

class B2 : A2 {
S s;
}
class C2 : B2 {
S s;
}

void main()
{
}
```

The most shocking thing is that it is C's access to A.S that gets 
affected, I think that must be a compiler bug. Still, it would be nice 
to confirm that "protected static" is supposed to work as intuitively 
expected.


Best,

A.

[1]: https://glot.io/snippets/f4a1b3x4sf


Re: std.encoding:2554 - Unrecognized Encoding: big5 - Please help!

2018-08-28 Thread rikki cattermole via Digitalmars-d
We have a reasonably number (but quiet) Chinese user base, we should 
really support big5 and its extensions out-right.


Re: std.encoding:2554 - Unrecognized Encoding: big5 - Please help!

2018-08-28 Thread Steven Schveighoffer via Digitalmars-d

On 8/28/18 9:38 AM, spikespaz wrote:
I have a user who submitted a bug report for one of my projects. The 
error is in std\encoding.d on line 2554.


The problem arises when he types "google.com.hk/search?q={{query}}" 
(exact string) into this function:
https://github.com/spikespaz/search-deflector/blob/master/source/setup.d#L253-L278 



Here is the issue on GH:
https://github.com/spikespaz/search-deflector/issues/12

I really can't figure this one out and any help would be appreciated. 
Thanks.


The answer is: the encoding "big5" isn't supported by std.encoding.

You can add a new subclass and register it, to handle the encoding. 
Maybe this article can help you write one: 
https://en.wikipedia.org/wiki/Big5


You want to subclass EncodingScheme. See instructions at the top of 
https://dlang.org/phobos/std_encoding.html


-Steve


Re: std.encoding:2554 - Unrecognized Encoding: big5 - Please help!

2018-08-28 Thread rikki cattermole via Digitalmars-d

https://github.com/dlang/phobos/blob/master/std/net/curl.d#L1197

get!ubyte will disable encoding.


Re: Create constraint for each parameter in template arg pack

2018-08-28 Thread Andrey via Digitalmars-d-learn

On Tuesday, 28 August 2018 at 13:05:15 UTC, bauss wrote:
I'm not sure if there is a better way, but isInstanceOf 
(std.traits) seems to work with a static foreach and a static 
if.


template Qwerty(Values...)
{
static foreach (value; Values)
{
static if (!isInstanceOf!(Qaz, value))
{
static assert(0, "Values are not Qaz only ...");
}
}

// ...
}


Thank you everybody!



Re: std.encoding:2554 - Unrecognized Encoding: big5 - Please help!

2018-08-28 Thread spikespaz via Digitalmars-d

On Tuesday, 28 August 2018 at 13:38:39 UTC, spikespaz wrote:
I have a user who submitted a bug report for one of my 
projects. The error is in std\encoding.d on line 2554.


The problem arises when he types 
"google.com.hk/search?q={{query}}" (exact string) into this 
function:

https://github.com/spikespaz/search-deflector/blob/master/source/setup.d#L253-L278

Here is the issue on GH:
https://github.com/spikespaz/search-deflector/issues/12

I really can't figure this one out and any help would be 
appreciated. Thanks.


To add to the parent, I've recompiled with debugging and this is 
the full traceback. As I suspected, it's an error with curl:


0x7FF77A162F4D in std.encoding.EncodingScheme 
std.encoding.EncodingScheme.create(immutable(char)[])
0x7FF77A14300A in 
std.net.curl._decodeContent!char._decodeContent at 
C:\D\ldc2\import\std\net\curl.d(1213)
0x7FF77A143610 in std.net.curl._basicHTTP!char._basicHTTP at 
C:\Users\spike\Documents\github.com\spikespaz\search-deflector\source\common.d(1078)
0x7FF77A142C97 in std.net.curl.get!(std.net.curl.HTTP, 
char).get at 
C:\Users\spike\Documents\github.com\spikespaz\search-deflector\source\common.d(562)
0x7FF77A1411E0 in 
std.net.curl.get!(std.net.curl.AutoProtocol, char).get at 
C:\D\ldc2\import\std\net\curl.d(574)
0x7FF77A146635 in setup.getCustomEngine at 
C:\Users\spike\Documents\github.com\spikespaz\search-deflector\source\setup.d(264)
0x7FF77A145C8E in setup.setup at 
C:\Users\spike\Documents\github.com\spikespaz\search-deflector\source\setup.d(44)
0x7FF77A145AD0 in D main at 
C:\Users\spike\Documents\github.com\spikespaz\search-deflector\source\setup.d(26)
0x7FF77A1AAD8D in void rt.dmain2._d_run_main(int, char**, 
extern (C) int function(char[][])*).runAll()

0x7FF77A1AAC3A in d_run_main
0x7FF77A1C9658 in __scrt_common_main_seh at 
f:\dd\vctools\crt\vcstartup\src\startup\exe_common.inl(283)

0x7FFEC50687E4 in BaseThreadInitThunk
0x7FFEC701B311 in RtlUserThreadStart


Re: std.encoding:2554 - Unrecognized Encoding: big5 - Please help!

2018-08-28 Thread rikki cattermole via Digitalmars-d

import std.stdio : stdout, writeln;

writeln(__MODULE__, ":", __LINE__); stdout.flush;

Trace it that way. The flush is important.


std.encoding:2554 - Unrecognized Encoding: big5 - Please help!

2018-08-28 Thread spikespaz via Digitalmars-d
I have a user who submitted a bug report for one of my projects. 
The error is in std\encoding.d on line 2554.


The problem arises when he types 
"google.com.hk/search?q={{query}}" (exact string) into this 
function:

https://github.com/spikespaz/search-deflector/blob/master/source/setup.d#L253-L278

Here is the issue on GH:
https://github.com/spikespaz/search-deflector/issues/12

I really can't figure this one out and any help would be 
appreciated. Thanks.


Re: D is dead (was: Dicebot on leaving D: It is anarchy driven development in all its glory.)

2018-08-28 Thread Iain Buclaw via Digitalmars-d

On Thursday, 23 August 2018 at 15:35:45 UTC, Joakim wrote:

On Thursday, 23 August 2018 at 07:37:07 UTC, Iain Buclaw wrote:

On Thursday, 23 August 2018 at 06:58:13 UTC, Joakim wrote:
On Thursday, 23 August 2018 at 03:50:44 UTC, Shachar Shemesh 
wrote:

[...]


Can you list what you or other Weka devs believe those fatal 
flaws to be? Because you've not listed any here, which makes 
you no better than some noob that comes in here, says D has 
to get better or it will die, then can't articulate what they 
mean by "better" or worse, mentions something trivial. Of 
course, you've actually used the language for years, so 
presumably you've got some real concerns, but do you really 
think the bug you just posted is "fatal" to the language?


If you think there are fatal flaws, you might as well list 
them, whether technical or the development process, or you 
will just be ignored like any other noob who talks big and 
can't back it up. You may be ignored anyway, ;) but at least 
you'll have made a case that shows you know what you're 
talking about.


I'd define fatal as some that can be fixed, but breaks 100% of 
everyone's code, even if the change is net positive all round.


However how big a problem really is is in the eye of the 
beholder. An example:


Symptom: The compiler can't discard unused symbols at compile 
time, and so it will spend a lot of time pointlessly 
optimising code.


Problem: D has no notion of symbol visibility.

Possible Solution: Make all globals hidden by default unless 
'export'.


Side effects: Everyone will be spending weeks to months fixing 
their libraries in order to only mark what should be visible 
outside the current compilation unit as 'export'.


Benefits: Faster compile times, as in, in the most extreme 
example I've built one project on github with gdc -O2 and 
build time went from 120 seconds to just 3!


So your example of a fatal flaw is that D could be 100X faster 
at compilation instead of just 10X than most every other native 
language out there?! C'mon.




But that's not true. D isn't a fast language to compile, dmd is 
just a fast compiler.


You may get a little leading edge with codebases that are 
effectively C. Once you throw templates into the mix though, your 
problems become exponential.


Spending 4 seconds in the front end and codegen, only to wait 2 
minutes in the optimizer is horrific.


The alternative of discarding what seem to be unused symbols only 
results in linker error of the obscure edge cases sort.


Template emission strategy is a mess, we're better off just 
instantiating all templates in all compilation units, and let the 
compiler decide whatever to discard. Even -allinst does not 
instantiate enough to allow the compiler to make such decisions 
that C++ has no problem with (most of the time).


Re: Null-Coalescing Operator and Extensions

2018-08-28 Thread Simen Kjærås via Digitalmars-d-learn

On Monday, 27 August 2018 at 14:59:20 UTC, SG wrote:

On Monday, 27 August 2018 at 07:59:17 UTC, Simen Kjærås wrote:
That's the null propagation operator (?.). What SG asked for 
is the null-coalescing operator (??). Of course, this can also 
be implemented in D (albeit with a slight more horrible 
syntax):


Exactly, and I know it is an example, but it doesn't work for 
Variant.


I was trying something like below, I need to find a way to test 
for all Nullable types out there, right now only works for 
Nullable!int.


Sadly, Variant's operator overloading is problematic - there 
seems to be no way to write a struct such that its operator 
overloading is preferred over Variant's, and Variant's fails to 
compile. (issue 19200: 
https://issues.dlang.org/show_bug.cgi?id=19200)


Once that issue has been fixed, this should work:

// Support aliak's optional, if available:
static if (__traits(compiles, {import optional;})) import 
optional;


struct NullCoalesce {
static auto opBinaryRight(string op : "|", T)(T lhs) {
return NullCoalesceImpl!T(lhs);
}
}

struct NullCoalesceImpl(T) {
T value;
auto opBinary(string op : "|", R)(lazy R rhs) {
static if (is(typeof(value.peek!R))) {
if (auto tmp = value.peek!R)
return *tmp;
} else static if (is(typeof(value.isNull))) {
if (!value.isNull)
return value.get;
} else static if (is(typeof(value.unwrap))) {
if (auto tmp = value.unwrap)
return *tmp;
} else static if (is(typeof(value == null))) {
if (value != null)
return value;
} else {
static assert(false, "Cannot perform null-coalescing 
on non-nullable type "~T.stringof~".");

}
return rhs;
}
}

alias NullCoalesce _;

unittest {
import std.variant;
import std.typecons;

int* a = null;
auto b = new int;
assert((a |_| b) == b);
a = new int;
assert((a |_| b) == a);

Variant c;
assert((c |_| 3) == 3);
c = 4;
assert((c |_| 3) == 4);

Nullable!int d;
assert((d |_| 3) == 3);
d = 4;
assert((d |_| 3) == 4);

static if (is(typeof(Optional!int))) {
Optional!int e;
assert((e |_| 3) == 3);
e = 4;
assert((e |_| 3) == 4);
}
}

Now, as has been pointed out, that only work for null-coalescing, 
not null-propagation. It seems writers of Optional, Variant, 
SumType, and so on, have decided not to support this out of the 
box, but rather wrap it separately, like Basile B.'s 
SafeAccess[1] and aliak's dispatch[2]. There's no real obstacle 
to wrapping member access directly in Optional!T such that it 
always return a Optional!(typeof(member)), though.


I've written an Optional somewhere that does safe access out of 
the box, but it seems to be on my work computer, not this one.


--
  Simen

[1]: 
https://github.com/BBasile/iz/blob/master/import/iz/sugar.d#L1658

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


Re: Create constraint for each parameter in template arg pack

2018-08-28 Thread vit via Digitalmars-d-learn

On Tuesday, 28 August 2018 at 12:28:19 UTC, Andrey wrote:

Hello,
Let we have two variadic templates:

template Qwerty(Values...) {}
template Qaz(alias type, Data...) {}


Now I want to add a constraint to "Qwerty" so that each type in 
"Values" pack must be a "Qaz" template. I don't care about 
values of "type" or "Data" in "Qaz".

How to do it in D?


Generic solution:


template Qwerty(Values...)
if(allSatisfy!(isInstanceOf!Qaz, Values)){

}
class Qaz(alias type, Data...) {}



import std.meta : allSatisfy;
public import std.traits : isInstanceOf;
template isInstanceOf(alias T){
import std.traits : impl = isInstanceOf;
static enum isInstanceOf(alias X) = impl!(T, X);
static enum isInstanceOf(X) = impl!(T, X);
}






Re: Is @safe still a work-in-progress?

2018-08-28 Thread Steven Schveighoffer via Digitalmars-d

On 8/24/18 10:25 PM, Walter Bright wrote:

On 8/23/2018 6:32 AM, Steven Schveighoffer wrote:
Furthermore any member function (or UFCS function for that matter) 
REQUIRES the first parameter to be the aggregate. How do you make a 
member function that stuffs the return into a different parameter 
properly typecheck?


What I propose is that the function interface be refactored so it does 
fit into these patterns. Is that an unreasonable requirement? I don't 
know. But it doesn't seem to be, as I haven't run into it yet.


So this would mean a member function would have to be refactored into a 
different function with a different calling syntax. i.e:


x.foo(target);

would have to be refactored to:

target.foo(x);

or foo(target, x);

Aside from the adjustment in name that is necessary to make this read 
correctly, that may cause other problems (sometimes non-member functions 
aren't available if it's a template instantiation).


Phobos doesn't do this by accident. It's how constructors work (see 
above) and how pipeline programming works.


Constructors I agree are reasonable to consider `this` to be the 
return value. On that point, I would say we should definitely go ahead 
with making that rule, and I think it will lead to no confusion 
whatsoever.


pipeline programming depends on returning something other than `void`, 
so I don't see how this applies.


grep Phobos for instances of put() and see its signature. It's part of 
pipeline programming, and it's all over the place.


I stand partly corrected! Indeed you can put a void-returning function 
at the *end* of a pipeline call, I hadn't thought of that.


But in terms of put, strictly speaking, any call of some.pipeline.put(x) 
is wrong. It should be put(some.pipeline, x), to avoid issues with how 
put was designed.



It would restrict your legitimate calls.


Maybe that's a good thing. Having multiple simultaneous routes of data 
out of a function is not good practice (note that it is impossible with 
functional programming). If you absolutely must have it, the exit routes 
can be aggregated into a struct, then pass that struct as the first 
argument.


Maybe it's better to designate one sink, and have that be the result. I 
know that after inout was implemented, there were definitely cases where 
one wanted to have multiple inout routes (i.e. independent traces 
between multiple parameters for copying mutability). It may be the same 
for this, I don't know.


I want to stress that it may be a valid solution, but we should strive 
to prove the solutions are the best possible rather than just use 
duct-tape methodology.


I don't know how to prove anything with programming languages.


I don't mean prove like mathematical proof. I mean try to consider how 
this affects all cases instead of just the one case that will make 
phobos compile.


"show" is a better verb than "prove".

It should even be considered that perhaps there are better solutions 
even than the approach dip1000 has taken.


People have hypothesized that for several years, and so far none have 
been forthcoming beyond a few hand-wavy generalities.


I'm just saying if dip1000 cannot fix all the problems, that instead of 
adding weird exceptions, or the classic "you're just doing it wrong", 
maybe we should reconsider the approach.


Another case which was brought up and pretty much ignored was this one: 
https://forum.dlang.org/post/qkrdpmdqaxjadgvso...@forum.dlang.org


I also want to point out that the attitude of 'we could just fix it, 
but nobody will pull my request' is unhelpful. We want to make sure we 
have the best solution possible, don't take criticism as meaningless 
petty bickering. People are genuinely trying to make sure D is 
improved. Hostility towards reviews or debate doesn't foster that.


I'm not hostile to debate. I just don't care for "this is uncharted 
territory, so let's do nothing" which has been going on for probably 4 
years now, coincident with "scope is incomplete, D sux".


I.e. lead, follow, or get out of the way :-)


I'm opting for the latter, as the idea of band-aid PRs to get Phobos 
compiling with dip1000 just to see if dip1000 is going to work seems 
like the wrong approach to me.


The consequence of this is that getting out of the way means your PRs 
don't get pulled.


-Steve


Re: C++ Expected converted to idiomatic D

2018-08-28 Thread Per Nordlöw via Digitalmars-d

On Tuesday, 28 August 2018 at 10:18:29 UTC, John Colvin wrote:
I get the feeling from the talk that Andrei has some opinions 
about how it should be done that aren't completely in line with 
what has been proposed for the C++ standard.


Anyhow my implementation at

https://github.com/nordlow/phobos-next/blob/master/src/expected.d

should match his C++ code in the lecture, AFAICT.

My code doesn't depend on other modules an compiles very fast 
(~46 ms in my machine) (with DMD -debug -unittest).


Re: Create constraint for each parameter in template arg pack

2018-08-28 Thread Alex via Digitalmars-d-learn

On Tuesday, 28 August 2018 at 13:05:15 UTC, bauss wrote:

On Tuesday, 28 August 2018 at 12:28:19 UTC, Andrey wrote:

Hello,
Let we have two variadic templates:

template Qwerty(Values...) {}
template Qaz(alias type, Data...) {}


Now I want to add a constraint to "Qwerty" so that each type 
in "Values" pack must be a "Qaz" template. I don't care about 
values of "type" or "Data" in "Qaz".

How to do it in D?


I'm not sure if there is a better way, but isInstanceOf 
(std.traits) seems to work with a static foreach and a static 
if.


template Qwerty(Values...)
{
static foreach (value; Values)
{
static if (!isInstanceOf!(Qaz, value))
{
static assert(0, "Values are not Qaz only ...");
}
}

// ...
}


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

maybe...


Re: D is dead

2018-08-28 Thread Iain Buclaw via Digitalmars-d
On Thursday, 23 August 2018 at 09:29:30 UTC, Nicholas Wilson 
wrote:

On Thursday, 23 August 2018 at 07:00:01 UTC, Iain Buclaw wrote:
On Thursday, 23 August 2018 at 06:34:04 UTC, Shachar Shemesh 
wrote:

On 23/08/18 09:17, Jacob Carlborg wrote:
I don't see why we just can't add support for scoped lazy 
parameters. It's already in the language just with a 
different syntax (delegates). That would probably be an easy 
fix (last famous words :)). I guess it would be better if it 
could be inferred.


Here's the interesting question, though: is this *going* to 
happen?


We've known about this problem for ages now. No movement.

It's on my todo list, however I've instead been doomed to work 
on higher priority things.


More generally though, some time should be spent on trying out 
things in the spirit of "will it blend" just to see what 
happens.
 Putting effort towards having a more homogeneous environment 
in the language should in the long run pay its dividends.


Is there even any way to escape a lazy? If no, then lazy is 
identical to scope lazy.

E.g. https://run.dlang.io/is fails to compile


Link not found. I assume you tried something like returning a 
delegate that references a lazy parameter?


Re: Create constraint for each parameter in template arg pack

2018-08-28 Thread bauss via Digitalmars-d-learn

On Tuesday, 28 August 2018 at 12:28:19 UTC, Andrey wrote:

Hello,
Let we have two variadic templates:

template Qwerty(Values...) {}
template Qaz(alias type, Data...) {}


Now I want to add a constraint to "Qwerty" so that each type in 
"Values" pack must be a "Qaz" template. I don't care about 
values of "type" or "Data" in "Qaz".

How to do it in D?


I'm not sure if there is a better way, but isInstanceOf 
(std.traits) seems to work with a static foreach and a static if.


template Qwerty(Values...)
{
static foreach (value; Values)
{
static if (!isInstanceOf!(Qaz, value))
{
static assert(0, "Values are not Qaz only ...");
}
}

// ...
}


Re: Create constraint for each parameter in template arg pack

2018-08-28 Thread vit via Digitalmars-d-learn

On Tuesday, 28 August 2018 at 12:28:19 UTC, Andrey wrote:

Hello,
Let we have two variadic templates:

template Qwerty(Values...) {}
template Qaz(alias type, Data...) {}


Now I want to add a constraint to "Qwerty" so that each type in 
"Values" pack must be a "Qaz" template. I don't care about 
values of "type" or "Data" in "Qaz".

How to do it in D?



import std.meta : allSatisfy;

template Qwerty(Values...)
if(allSatisfy!(isQaz, Values)){

}
template Qaz(alias type, Data...) {}

enum isQaz(alias Q : Qaz!Args, Args...) = true;
enum isQaz(Args...) = false;

alias Foo = Qwerty!(Qaz!(i => i), Qaz!(i => i), Qaz!(i => i));


[Issue 19200] New: Variant operators don't overload correctly

2018-08-28 Thread d-bugmail--- via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=19200

  Issue ID: 19200
   Summary: Variant operators don't overload correctly
   Product: D
   Version: D2
  Hardware: x86
OS: Windows
Status: NEW
  Severity: normal
  Priority: P1
 Component: phobos
  Assignee: nob...@puremagic.com
  Reporter: simen.kja...@gmail.com

There are issues when using Variant with types that have their own overloaded
operators:

struct S {
static int opBinaryRight(string op : "|", T)(T rhs) {
return 3;
}
}

unittest {
import std.variant;
S s;
Variant v;
auto b = v | s;
}

std\variant.d(1004): Error: no property min for type S

In addition, Variant's operator overloads are of the old kind (opAdd, opMul,
and so on). These should be updated anyway.

--


Re: Is @safe still a work-in-progress?

2018-08-28 Thread Steven Schveighoffer via Digitalmars-d

On 8/24/18 10:28 PM, Walter Bright wrote:

On 8/23/2018 8:14 AM, Steven Schveighoffer wrote:
If I had to design a specific way to allow the common case to be easy, 
but still provide a mechanism for the uncommon cases, I would say:


1. define a compiler-recognized attribute (e.g. @__sink).
2. If @__sink is applied to any parameter, that is effectively the 
return value.
3. In the absence of a @__sink designation on non-void-returning 
functions, it applies to the return value.
4. In the absence of a @__sink designation on void returning 
functions, it applies to the first parameter.

5. Inference of @__sink happens even on non-templates.
6. If @__sink is attributed on multiple parameters, you assume all 
return parameters are assigned to all @__sink parameters for the 
purposes of verifying lifetimes are not exceeded.



'ref' is already @__sink.


No, otherwise we wouldn't need the patch you are pushing.

-Steve


Re: Pass Socket to new thread

2018-08-28 Thread Ivo via Digitalmars-d-learn

Thanks for all your answers.

I'll have a look at the design and use casting if necessary.




Re: D support for ChromeOS

2018-08-28 Thread Martin Tschierschke via Digitalmars-d-announce

On Wednesday, 22 August 2018 at 10:28:32 UTC, Joakim wrote:

https://play.google.com/store/apps/details?id=com.termux=en



$ apt search ldc
Sorting... Done
Full Text Search... Done
ipcalc/stable 0.41 aarch64
  Calculates IP broadcast, network, Cisco wildcard mask, and 
host ranges


ldc/stable 1.11.0 aarch64
  D programming language compiler, built with LLVM

http://termux.net/dists/stable/main/binary-aarch64/

You should post it, as an extra topic on announce:
  D on Android with Termux LDC now 32 and 64 Bit!
  ...

Thank you - it works!






Create constraint for each parameter in template arg pack

2018-08-28 Thread Andrey via Digitalmars-d-learn

Hello,
Let we have two variadic templates:

template Qwerty(Values...) {}
template Qaz(alias type, Data...) {}


Now I want to add a constraint to "Qwerty" so that each type in 
"Values" pack must be a "Qaz" template. I don't care about values 
of "type" or "Data" in "Qaz".

How to do it in D?


Re: Solving the impossible?

2018-08-28 Thread bauss via Digitalmars-d-learn

On Sunday, 26 August 2018 at 02:26:58 UTC, Everlast wrote:

in fact, I'd rather see

void print(T)(T t, int... a)


You were actually close.

void print(T)(T t, int[] a ...);


Re: Pass Socket to new thread

2018-08-28 Thread bauss via Digitalmars-d-learn

On Tuesday, 28 August 2018 at 10:48:20 UTC, Ivo wrote:
I'm writing a basic server program and I want to handle each 
connection received in a new thread.


So here is the code I'm trying to produce:

while(true) {
auto client = socket.accept();
spawn( , client);
}

void handleConnection(Socket client) {
//do stuff like receive and send
}

I get the error that I cannot pass "client" to "spawn" since it 
is not a "shared" or "immutable" object.
So I need to create an "immutable" (or "shared") copy of the 
socket in order to pass it to the "handleConnection" function. 
However doing so would prevent me from sending/receiving data. 
That is "client.receive" and "client.send" do not work if 
"client" is "shared" or "immutable".


Any suggestions to solve my problem? Thanks.


What you should do instead is using a non-blocking socket in a 
single thread and only if necessary use a thread-pool design to 
split multiple sockets into multiple threads, but each thread 
should still be shared by multiple sockets. Using fibers can help 
you do that without reinventing the wheel.


Usually it's __never__ a good idea to spawn a thread per 
connection. In fact it'll only come with synchronization issues 
in the end and then you end up putting mutexes everywhere, which 
is just going to put your performance downhill.


Especially with sockets and threading you want the design to be 
correct from the beginning, because once your application starts 
to depend on your design, then it's going to be hard to 
re-implement or replace the current system to do it the "right 
way".


Re: Pass Socket to new thread

2018-08-28 Thread Kagamin via Digitalmars-d-learn

while(true) {
auto client = socket.accept();
spawn(, cast(shared)client);
}

void handleConnection(shared Socket sclient) {
Socket client=cast()sclient;
//do stuff like receive and send
}


Re: "The D Way" to run a sequence of executables?

2018-08-28 Thread Kagamin via Digitalmars-d-learn

Maybe http://libpipeline.nongnu.org/ can be an inspiration.


Re: D now has a dangerous competitor

2018-08-28 Thread JN via Digitalmars-d

On Tuesday, 28 August 2018 at 08:39:20 UTC, bauss wrote:

The following language is a dangerous competitor to D.

https://github.com/joaomilho/Enterprise


I often feel like this kind of 'jokes' are trying too hard. 
FizzBuzz Enterprise was fun when it first came out, and I know 
it's popular to hate on OOP programming, especially Java. But the 
fact is, a very big portion of software was built using OOP, and 
many of the hated design patterns have a place in programming. 
Sure, it doesn't provide witty one-liner quicksort examples, but 
when you have a group of people, having to integrate multiple 
webservices/databases, these kind of layered code architecture 
comes in handy.


Of course sometimes people go too far, trying to make the code 
generic and fit every usecase, breaking YAGNI.


Pass Socket to new thread

2018-08-28 Thread Ivo via Digitalmars-d-learn
I'm writing a basic server program and I want to handle each 
connection received in a new thread.


So here is the code I'm trying to produce:

while(true) {
auto client = socket.accept();
spawn( , client);
}

void handleConnection(Socket client) {
//do stuff like receive and send
}

I get the error that I cannot pass "client" to "spawn" since it 
is not a "shared" or "immutable" object.
So I need to create an "immutable" (or "shared") copy of the 
socket in order to pass it to the "handleConnection" function. 
However doing so would prevent me from sending/receiving data. 
That is "client.receive" and "client.send" do not work if 
"client" is "shared" or "immutable".


Any suggestions to solve my problem? Thanks.


Re: C++ Expected converted to idiomatic D

2018-08-28 Thread John Colvin via Digitalmars-d

On Thursday, 16 August 2018 at 20:37:33 UTC, Per Nordlöw wrote:

In

https://www.youtube.com/watch?v=nVzgkepAg5Y

Andrei describes his proposal for STL `Expected` planned to be 
included in C++20.


Have anybody converted the C++ proposal to idiomatic D, yet?

Hopefully without the pointer-legacy which unfortunately was 
allowed into `std:optional`.


Andrei claims we should it as return types for non-throwing 
variants of parse() and to() in the works at


https://github.com/dlang/phobos/pull/6665


I get the feeling from the talk that Andrei has some opinions 
about how it should be done that aren't completely in line with 
what has been proposed for the C++ standard.


Re: Dicebot on leaving D: It is anarchy driven development in all its glory.

2018-08-28 Thread Mike Parker via Digitalmars-d

On Tuesday, 28 August 2018 at 08:44:26 UTC, Chris wrote:



Last but not least, if it's true that the D Foundation has 
raised only 3.2K, then there's something seriously wrong.


The Foundation has significantly more than 3.2k. The Open 
Collective account is relatively new and is but one option. 
People also donate via PayPal and other means [1], with several 
monthly contributors. The Foundation is paying two full-time 
developers, pays me for part-time work, pays out bounties for 
guest posts on the D Blog, pays out bounties for specific coding 
tasks, contributes to the funding of DConf, and more.


Soon there will be more fundraising drives for targeted 
initiatives, like the test drive we did with the VS Code plugin, 
to make up for the lack of donations of time. Some of them will 
be for paying people to fix onerous issues in Bugzilla. It's a 
long-term project for me.


[1] https://dlang.org/foundation/donate.html


Re: D is dead

2018-08-28 Thread Walter Bright via Digitalmars-d

On 8/27/2018 7:02 AM, Don wrote:

I can explain this, since I did the original implementation.
[...]

Thank you, Don. And you do have my mad respect for figuring out Windows SEH.


Re: D now has a dangerous competitor

2018-08-28 Thread Nicholas Wilson via Digitalmars-d

On Tuesday, 28 August 2018 at 08:39:20 UTC, bauss wrote:

The following language is a dangerous competitor to D.

https://github.com/joaomilho/Enterprise


Thats very funny, but I found Rockstar even funnier.


Re: Dicebot on leaving D: It is anarchy driven development in all its glory.

2018-08-28 Thread Chris via Digitalmars-d

On Tuesday, 28 August 2018 at 08:44:26 UTC, Chris wrote:


When people choose a programming language, there are several 
boxes that have to be ticked, like for example:


- what's the future of language X? (guarantees, stability)
- how easy is it to get going (from "Hello world" to a complete 
tool chain)

- will it run on ARM?
- will it be a good choice for the Web (e.g. webasm)?
- how good is it at data processing / number grinding
- etc.



I don't know if all their claims are 100% true, but let that sink 
in for a while:


https://julialang.org/.




Re: GDC with D frontend 2.081.2

2018-08-28 Thread Daniel Kozak via Digitalmars-d-announce
On Tue, Aug 28, 2018 at 8:40 AM Eugene Wissner via Digitalmars-d-announce <
digitalmars-d-announce@puremagic.com> wrote:

> On Tuesday, 28 August 2018 at 06:18:28 UTC, Daniel Kozak wrote:
> > On Mon, Aug 27, 2018 at 7:55 PM Eugene Wissner via
> > Digitalmars-d-announce < digitalmars-d-announce@puremagic.com>
> > wrote:
> >
> >> On Monday, 27 August 2018 at 17:23:04 UTC, Arun Chandrasekaran
> >> wrote:
> >> > 1. It would be good to print the DMD frontend version with
> >> > `gdc --version`. It is helpful in reporting bugs. LDC does
> >> > this.
> >> >
> >> Unfortunately it doesn't seem to be possible. GCC doesn't
> >> allow to change --version output:
> >> https://bugzilla.gdcproject.org/show_bug.cgi?id=89
> >>
> >>
> > This is not true, right now on archlinux if you type gdc
> > --version it will display d frontend version
> > https://bugzilla.gdcproject.org/show_bug.cgi?id=89#c1
>
> Is it set with --with-pkgversion? The same information will be
> displayed for gcc and g++ then. It is not always desirable if you
> ship the compiler as a whole (with libtool etc).
>

Yes and no. It is set with  --with-pkgversion but it is only for gdc.


Re: Dicebot on leaving D: It is anarchy driven development in all its glory.

2018-08-28 Thread Chris via Digitalmars-d

On Tuesday, 28 August 2018 at 07:30:01 UTC, Walter Bright wrote:

On 8/27/2018 2:14 AM, Chris wrote:



bad feeling about the way things are going atm.


I can quote you a lng list of problems that are obvious 
only in hindsight, by world leading development teams.


Start by watching the documentary series "Aviation Disasters", 
look at Challenger, Deepwater Horizon, Fukushima, Apollo 1, 
Apollo 13, the World Trade Centers, etc. Of course, there are a 
number of them in C, C++, Java, Javascript, basically every 
language I've worked with.


I'll guarantee every non-trivial project you've worked on has 
problems that are obvious only in hindsight, too. If you wait 
till it's perfect, you'll never ship, and yet it'll *still* 
have problems.


I'm not making excuses for mistakes - just don't have 
unworkable requirements.


This is all good and well and I know that anyone who develops 
software shoots him/herself in the foot sooner or later. But this 
is not the same situation. If you have to ship something till 
date X, then you are under pressure and naturally make mistakes 
that are obvious only on hindsight. But D is not under pressure 
to  include new features so frequently. There's absolutely no 
reason to rush into something that eats up a lot of your time 
(better spent on more urgent problems) and by so doing produce 
possible breakages.


The end of the day is, does D get the job done for you better 
than other languages? That's a decision only you can make.


It has done a better job until recently. The problem are not 
things like @safe, `const` and whatnot, the problem are very 
practical issues such as fear of breakage / time spent fixing 
things and running the code on ARM, integration into other 
technologies (webasm).


Since the D Foundation was founded I really thought that part of 
the effort would go into stabilizing the language and developing 
better tools for various aspects of programming (not just 
language features). Programming is so much more than just 
language features, and languages that offer the "so much more" 
part are usually the ones people adopt. But somehow D still seems 
to be in its hobby hacker days. Features are first and foremost, 
everything else comes second. But features get "ripped" by other 
programming languages and they can pick and choose, because they 
know what really worked in D, while D has to struggle with the 
things that didn't work or only half worked.


Laeeth was talking about being analytical about the whole thing. 
Why not find out what features are really being used? I.e. does 
the majority really need - for practical purposes - partially 
constructed objects?


When people choose a programming language, there are several 
boxes that have to be ticked, like for example:


- what's the future of language X? (guarantees, stability)
- how easy is it to get going (from "Hello world" to a complete 
tool chain)

- will it run on ARM?
- will it be a good choice for the Web (e.g. webasm)?
- how good is it at data processing / number grinding
- etc.

I think the D Foundation should focus on the more "trivial" 
things too. If a company is asked to develop a data grinding web 
application along with a smart phone app - will it choose D? If a 
company offers localization services and translations - will it 
choose D (autodecode)?


The D community / leadership is acting as if they had all the 
time in the world. But other languages are moving fast and they 
learn from D what _not_ to do.


Last but not least, if it's true that the D Foundation has raised 
only 3.2K, then there's something seriously wrong.




Re: Null-Coalescing Operator and Extensions

2018-08-28 Thread Kagamin via Digitalmars-d-learn

On Saturday, 25 August 2018 at 13:33:58 UTC, SG wrote:
1) I program in C# and I'm wondering if there is something like 
?? (Null-Coalescing Operator) in D? (I remember some proposals 
in the past).


Another example: 
https://github.com/aliak00/optional/blob/master/source/optional/optional.d#L340


D now has a dangerous competitor

2018-08-28 Thread bauss via Digitalmars-d

The following language is a dangerous competitor to D.

https://github.com/joaomilho/Enterprise


Re: Dicebot on leaving D: It is anarchy driven development in all its glory.

2018-08-28 Thread Eugene Wissner via Digitalmars-d

On Tuesday, 28 August 2018 at 07:53:34 UTC, Walter Bright wrote:
Let's take the much-maligned D const. It isn't C++ const (let's 
call that "head-const", because that's what it is). Head-const 
for a function parameter tells us very little about what may 
happen to it in the function. You can pass a head-const 
reference to a container, and have the function 
add/change/delete every element of that container, all without 
a peep from any C++ tool. Looking at the function signature, 
you've really got no clue whatsoever.


The reason people have trouble with transitive-const is that 
they are still programming in C++, where they *do* 
add/change/delete every member of the "const" container.


That includes me. I try to add transitive-const, and it won't 
compile, because I as well am used to replacing the engine and 
tail lights in my head-const car. In order to use 
transitive-const, it's forcing me to fundamentally re-think how 
I organize code into functions.


For example, dmd is full of functions that combine 
data-gathering with taking-action. I've been reorganizing to 
separate data-gathering and taking-action into separate 
functions. The former can be transitive-const, maybe even pure. 
And I like the results, the code becomes much easier to 
understand.


There are still valid use cases where const should be "broken". 
One of them is mutex (another one caching). I have very little 
experiance in multi-threaded programming, but what do you think 
about "mutable" members, despite the object is const?


Re: Dicebot on leaving D: It is anarchy driven development in all its glory.

2018-08-28 Thread Walter Bright via Digitalmars-d

On 8/26/2018 11:16 PM, Manu wrote:

The code looks the same, and in fact, is about 98% the same.

This code appears to be a mechanical translation.


It's not. It's by hand. But I had a specific goal of minimizing the diffs, so 
that if the translation didn't work, it reduced the number of places to look for 
the mistake. And in fact, this has saved me a LOT of grief :-)




That's not what
happened in this case; he wrote his game in D from scratch.
It was just that he arrived at mostly the same place. He was googling
for styling and sample material, but I suspect the problem was a lack
of topical material demonstrating how he might write his D code
differently.


It takes time to learn how to write idiomatic D effectively. I'm still learning 
how to do it right, too.




It's also the case that the significant difference between C++ and D
(in my experience) mostly come down to: D has modules, tidier meta,
UDA's, slices, and ranges/UFCS. In trade, D struggles with const, and
ref is broken.
If your code doesn't manifest some gravity towards one of those
features, it will tend to be quite same-ey, and advantage may not be
particularly apparent.


I suspect that is still a bit stuck on looking at individual instruments and not 
seeing the orchestra.


Let's take the much-maligned D const. It isn't C++ const (let's call that 
"head-const", because that's what it is). Head-const for a function parameter 
tells us very little about what may happen to it in the function. You can pass a 
head-const reference to a container, and have the function add/change/delete 
every element of that container, all without a peep from any C++ tool. Looking 
at the function signature, you've really got no clue whatsoever.


The reason people have trouble with transitive-const is that they are still 
programming in C++, where they *do* add/change/delete every member of the 
"const" container.


That includes me. I try to add transitive-const, and it won't compile, because I 
as well am used to replacing the engine and tail lights in my head-const car. In 
order to use transitive-const, it's forcing me to fundamentally re-think how I 
organize code into functions.


For example, dmd is full of functions that combine data-gathering with 
taking-action. I've been reorganizing to separate data-gathering and 
taking-action into separate functions. The former can be transitive-const, maybe 
even pure. And I like the results, the code becomes much easier to understand.


Re: tupleof function parameters?

2018-08-28 Thread aliak via Digitalmars-d-learn
On Tuesday, 28 August 2018 at 06:20:37 UTC, Sebastiaan Koppe 
wrote:
On Tuesday, 28 August 2018 at 06:11:35 UTC, Jon Degenhardt 
wrote:
The goal is to write the argument list once and use it to 
create both the function and the Tuple alias. That way I could 
create a large number of these function / arglist tuple pairs 
with less brittleness.


--Jon


I would probably use a combination of std.traits.Parameters and 
std.traits.ParameterIdentifierTuple.


Parameters returns a tuple of types and 
ParameterIdentifierTuple returns a tuple of strings. Maybe 
you'll need to implement a staticZip to interleave both tuples 
to get the result you want. (although I remember seeing one 
somewhere).


There's one in here -> https://code.dlang.org/packages/bolts
And the docs have a link to the particular forum post you're 
thinking of as well for details.


Re: Dicebot on leaving D: It is anarchy driven development in all its glory.

2018-08-28 Thread Walter Bright via Digitalmars-d

On 8/27/2018 2:14 AM, Chris wrote:

On Sunday, 26 August 2018 at 22:44:05 UTC, Walter Bright wrote:
Because nobody thought about that issue before. A lot of things only become 
apparent in hindsight.
QED. With this approach you do more harm than good. I have a bad feeling about 
the way things are going atm.


I can quote you a lng list of problems that are obvious only in hindsight, 
by world leading development teams.


Start by watching the documentary series "Aviation Disasters", look at 
Challenger, Deepwater Horizon, Fukushima, Apollo 1, Apollo 13, the World Trade 
Centers, etc. Of course, there are a number of them in C, C++, Java, Javascript, 
basically every language I've worked with.


I'll guarantee every non-trivial project you've worked on has problems that are 
obvious only in hindsight, too. If you wait till it's perfect, you'll never 
ship, and yet it'll *still* have problems.


I'm not making excuses for mistakes - just don't have unworkable requirements.

The end of the day is, does D get the job done for you better than other 
languages? That's a decision only you can make.


[Issue 18104] Alias example compiles where it states that it should be illegal

2018-08-28 Thread d-bugmail--- via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=18104

github-bugzi...@puremagic.com changed:

   What|Removed |Added

 Status|NEW |RESOLVED
 Resolution|--- |FIXED

--


[Issue 18104] Alias example compiles where it states that it should be illegal

2018-08-28 Thread d-bugmail--- via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=18104

--- Comment #1 from github-bugzi...@puremagic.com ---
Commits pushed to master at https://github.com/dlang/dlang.org

https://github.com/dlang/dlang.org/commit/9ad4c395470befec8293593fc8dfbdc906cfb56f
Fix Issue 18104: improve example showing that aliases cannot be used for
expressions

https://github.com/dlang/dlang.org/commit/92ff7aa56b7897d8545fe4f2882cc3165c338d3e
Merge pull request #2457 from ghost91-/fix-issue-18104

Fix Issue 18104: improve example showing that aliases cannot be used …
merged-on-behalf-of: Petar Kirov 

--


Re: Looking for a mentor for SAoC

2018-08-28 Thread Stefan Koch via Digitalmars-d

On Monday, 27 August 2018 at 21:32:10 UTC, David Nadlinger wrote:

On Monday, 27 August 2018 at 20:47:08 UTC, Stefam Koch wrote:
generating it is not the problem but linking it on windows 
currently requires the MS linker.


Is that true, though? DMD ships with LLD these days. — David


Really ... I am so out of touch these days.


Re: tupleof function parameters?

2018-08-28 Thread Jon Degenhardt via Digitalmars-d-learn
On Tuesday, 28 August 2018 at 06:20:37 UTC, Sebastiaan Koppe 
wrote:
On Tuesday, 28 August 2018 at 06:11:35 UTC, Jon Degenhardt 
wrote:
The goal is to write the argument list once and use it to 
create both the function and the Tuple alias. That way I could 
create a large number of these function / arglist tuple pairs 
with less brittleness.


--Jon


I would probably use a combination of std.traits.Parameters and 
std.traits.ParameterIdentifierTuple.


Parameters returns a tuple of types and 
ParameterIdentifierTuple returns a tuple of strings. Maybe 
you'll need to implement a staticZip to interleave both tuples 
to get the result you want. (although I remember seeing one 
somewhere).


Alex, Sebastiaan - Thanks much, this looks like it should get me 
what I'm looking for. --Jon


Re: Looking for a mentor for SAoC

2018-08-28 Thread rikki cattermole via Digitalmars-d

On 28/08/2018 9:32 AM, David Nadlinger wrote:

On Monday, 27 August 2018 at 20:47:08 UTC, Stefam Koch wrote:
generating it is not the problem but linking it on windows currently 
requires the MS linker.


Is that true, though? DMD ships with LLD these days. — David



And is 100% experimental on both LLD and on the D front.


Re: Is there a simple way to check if value is null for every case?

2018-08-28 Thread aliak via Digitalmars-d-learn

On Monday, 27 August 2018 at 21:48:04 UTC, Alex wrote:

On Monday, 27 August 2018 at 19:36:29 UTC, aliak wrote:


Then Nullable!(int*) would be the same as int*. Or even better 
maybe is to give a compiler error when you try and stuff a 
nullable type inside a Nullable. Because ... why?




Isn't it arguable, whether this is desired? I mean, in the 
present state you can separate the cases, whether the Nullable 
is set or not. This is a feature.
If Nullable!(int*) behaves like int*, it would be somewhat more 
straight forward, which is maybe also a feature. But you loose 
something you can do right now...


Certainly arguable :)

I'm unsure about of what you lose is worth having, is the 
problem. And I have trouble thinking of a use case?


If we implement opEquals(typeof(null)) as is now, then this code:

Nullable!(int*) n = null;
assert(n != null);

passes.

And if we have no opEquals then we can't test for native null on 
a 'null'able type O_o


Another options is:

bool opEquals(typeof(null)) {
  enum isNullInvalid = is(T == class) || is(T == interface) || 
isSomeFunction!T;

  static if (isNullInvalid)
return isNull || data is null
  else
return isNull;
}

I also did a quick search on google "allintext: "nullable" 
site:github.com filetype:d" and there were 0 instances of T* 
(just looked thorugh search results didn't click in).


Re: GDC with D frontend 2.081.2

2018-08-28 Thread Eugene Wissner via Digitalmars-d-announce

On Tuesday, 28 August 2018 at 06:18:28 UTC, Daniel Kozak wrote:
On Mon, Aug 27, 2018 at 7:55 PM Eugene Wissner via 
Digitalmars-d-announce < digitalmars-d-announce@puremagic.com> 
wrote:


On Monday, 27 August 2018 at 17:23:04 UTC, Arun Chandrasekaran 
wrote:
> 1. It would be good to print the DMD frontend version with 
> `gdc --version`. It is helpful in reporting bugs. LDC does 
> this.

>
Unfortunately it doesn't seem to be possible. GCC doesn't 
allow to change --version output: 
https://bugzilla.gdcproject.org/show_bug.cgi?id=89



This is not true, right now on archlinux if you type gdc 
--version it will display d frontend version 
https://bugzilla.gdcproject.org/show_bug.cgi?id=89#c1


Is it set with --with-pkgversion? The same information will be 
displayed for gcc and g++ then. It is not always desirable if you 
ship the compiler as a whole (with libtool etc).


Re: tupleof function parameters?

2018-08-28 Thread Sebastiaan Koppe via Digitalmars-d-learn

On Tuesday, 28 August 2018 at 06:11:35 UTC, Jon Degenhardt wrote:
The goal is to write the argument list once and use it to 
create both the function and the Tuple alias. That way I could 
create a large number of these function / arglist tuple pairs 
with less brittleness.


--Jon


I would probably use a combination of std.traits.Parameters and 
std.traits.ParameterIdentifierTuple.


Parameters returns a tuple of types and ParameterIdentifierTuple 
returns a tuple of strings. Maybe you'll need to implement a 
staticZip to interleave both tuples to get the result you want. 
(although I remember seeing one somewhere).


Re: tupleof function parameters?

2018-08-28 Thread Alex via Digitalmars-d-learn

On Tuesday, 28 August 2018 at 06:11:35 UTC, Jon Degenhardt wrote:
I'd like to create a Tuple alias representing a function's 
parameter list. Is there a way to do this?


[...]


Are you aware of
https://dlang.org/phobos/std_traits.html#Parameters


Re: GDC with D frontend 2.081.2

2018-08-28 Thread Daniel Kozak via Digitalmars-d-announce
On Mon, Aug 27, 2018 at 7:55 PM Eugene Wissner via Digitalmars-d-announce <
digitalmars-d-announce@puremagic.com> wrote:

> On Monday, 27 August 2018 at 17:23:04 UTC, Arun Chandrasekaran
> wrote:
> > 1. It would be good to print the DMD frontend version with `gdc
> > --version`. It is helpful in reporting bugs. LDC does this.
> >
> Unfortunately it doesn't seem to be possible. GCC doesn't allow
> to change --version output:
> https://bugzilla.gdcproject.org/show_bug.cgi?id=89
>
>
This is not true, right now on archlinux if you type gdc --version it will
display d frontend version
https://bugzilla.gdcproject.org/show_bug.cgi?id=89#c1


tupleof function parameters?

2018-08-28 Thread Jon Degenhardt via Digitalmars-d-learn
I'd like to create a Tuple alias representing a function's 
parameter list. Is there a way to do this?


Here's an example creating a Tuple alias for a function's 
parameters by hand:


import std.typecons: Tuple;

bool fn(string op, int v1, int v2)
{
switch (op)
{
default: return false;
case "<": return v1 < v2;
case ">": return v1 > v2;
}
}

alias fnArgs = Tuple!(string, "op", int, "v1", int, "v2");

unittest
{
auto args = fnArgs("<", 3, 5);
assert(fn(args[]));
}

This is quite useful. I'm wondering if there is a way to create 
the 'fnArgs' alias from the definition of 'fn' without needing to 
manually write out the '(string, "op", int, "v1", int, "v2")' 
sequence by hand. Something like a 'tupleof' operation on the 
function parameter list. Or conversely, define the tuple and use 
it when defining the function.


The goal is to write the argument list once and use it to create 
both the function and the Tuple alias. That way I could create a 
large number of these function / arglist tuple pairs with less 
brittleness.


--Jon