Re: Range with an alias parameter

2019-01-30 Thread Steven Schveighoffer via Digitalmars-d-learn

On 1/30/19 3:56 PM, Alex wrote:


Ok... strange... it doesn't in fact... as this works:

´´´
import std.experimental.all;

void main()
{
     S!42 s;
     auto res = s[];
     static assert(isInputRange!(typeof(res)));
     res.front.writeln;
}

//static assert(isInputRange!(ReturnType!(produceS!(42))[]));


Apples and oranges :)

ReturnType!(produceS!(42)) is a TYPE, not a variable. When you apply the 
brackets, it's not calling your opindex, but rather changing it to an 
array. So let's make it clearer by saying:


alias T = ReturnType!(produceS!(42));

So now, your assert becomes:

static assert(isInputRange!(T[]));

Which, is not coming up as a valid range, because you can't copy the 
front value (this(this) is disabled).


In the other expression, you are first calling the index operator on an 
instance of the type, which returns a DIFFERENT type, and then asserting 
the type of that is an input range.


The equivalent (still using T) is:

static assert(isInputRange!(typeof(T.init[])));

replacing T with the original is:

static assert(isInputRange!(typeof(ReturnType!(produceS!(42)).init[])));

-Steve


Re: How can I express the type of a function in D?

2019-01-30 Thread Steven Schveighoffer via Digitalmars-d-learn

On 1/30/19 1:39 PM, Ali Çehreli wrote:

On 01/30/2019 07:47 AM, Steven Schveighoffer wrote:
 > On 1/30/19 12:14 AM, Sobaya wrote:
 >> I want to get a mangled name of a D function by
 >> `core.demangle.mangle`, but I'm in trouble because there are no ways
 >> to express a type of a function, which is used for a template argument
 >> of `mangle`.
 >>
 >> For example, it is wrong to use the type `int function(int,int)` to
 >> express the type of `int add(int,int)`.
 >> Because it expresses the type of a function POINTER, not just a 
function.

 >>
 >> The fuction name in a binary compiled this function is "_D3addFiiZi",
 >> but `mangle!(int function(int,int))("add")` returns "_D3addPFiiZi",
 >> which includes "P" meaning POINTER.
 >>
 >> How can I get the former one?
 >
 > Why not use add.mangleof?
 >

add.mangleof includes the module name as well (_D6deneme3addFiiZi) but 
the OP wanted without (_D3addFiiZi). 


But he says `The fuction name in a binary compiled this function is 
"_D3addFiiZi"`. So whatever he compiles as must be what mangleof 
reports, as it's the same entity generating the mangle. I don't know 
what his source code is.


-Steve


Re: How can I express the type of a function in D?

2019-01-30 Thread Neia Neutuladh via Digitalmars-d-learn
On Wed, 30 Jan 2019 12:56:06 -0800, Ali Çehreli wrote:
> I remember names like _add. Is that a Windows thing?

A number of functions are implemented as manually-mangled names with 
preprocessor macros that forward to them. It's weird, but it happens.


Re: How can I express the type of a function in D?

2019-01-30 Thread Ali Çehreli via Digitalmars-d-learn

On 01/30/2019 11:42 AM, H. S. Teoh wrote:

On Wed, Jan 30, 2019 at 10:39:21AM -0800, Ali Çehreli via Digitalmars-d-learn 
wrote:
[...]

I wonder why the inconsistency. On the other hand, .mangleof produces
just "add" when the function is extern(C).  (?)

[...]

For extern(C), this is correct behaviour, because that's how a C
function would be mangled (i.e., not mangled at all).


T



I remember names like _add. Is that a Windows thing?

Ali



Re: Range with an alias parameter

2019-01-30 Thread Alex via Digitalmars-d-learn

On Wednesday, 30 January 2019 at 20:13:56 UTC, Alex wrote:

Given this:

´´´
import std.experimental.all;

void main(){}

static assert(isInputRange!(ReturnType!(produceS!(42))[]));

auto produceS(size_t param)() { return S!param(); }
struct S(size_t param)
{
//@disable this(this);
auto opIndex() { return produceRange!(this); }
}

auto produceRange(alias source)(){ return Range!source(); }

struct Range(alias source)
{
size_t front();
void popFront();
bool empty();
}
´´´

Why disabling copying of S removes the range property of Range?


Ok... strange... it doesn't in fact... as this works:

´´´
import std.experimental.all;

void main()
{
S!42 s;
auto res = s[];
static assert(isInputRange!(typeof(res)));
res.front.writeln;
}

//static assert(isInputRange!(ReturnType!(produceS!(42))[]));

auto produceS(size_t param)() { return S!param(); }
struct S(size_t param)
{
auto myParam(){return param; }
@disable this(this);
auto opIndex() { return produceRange!(this); }
}

auto produceRange(alias source)(){ return Range!source(); }

struct Range(alias source)
{
size_t front(){return source.myParam;}
void popFront();
bool empty();
}
´´´


Range with an alias parameter

2019-01-30 Thread Alex via Digitalmars-d-learn

Given this:

´´´
import std.experimental.all;

void main(){}

static assert(isInputRange!(ReturnType!(produceS!(42))[]));

auto produceS(size_t param)() { return S!param(); }
struct S(size_t param)
{
//@disable this(this);
auto opIndex() { return produceRange!(this); }
}

auto produceRange(alias source)(){ return Range!source(); }

struct Range(alias source)
{
size_t front();
void popFront();
bool empty();
}
´´´

Why disabling copying of S removes the range property of Range?


Re: How can I express the type of a function in D?

2019-01-30 Thread H. S. Teoh via Digitalmars-d-learn
On Wed, Jan 30, 2019 at 07:51:17PM +, Neia Neutuladh via 
Digitalmars-d-learn wrote:
> On Wed, 30 Jan 2019 10:39:21 -0800, Ali Çehreli wrote:
> > import core.demangle;
> > 
> > extern(C) int add(int, int);
> > 
> > void main() {
> >alias F = typeof(add);
> >pragma(msg, mangle!F("add"));
> >pragma(msg, add.mangleof);
> > }
> > 
> > Output:
> > 
> > _D3addUiiZi
> > add   <-- Is that correct?
> 
> `add.mangleof` is correct. In fact, it's definitively correct.
> 
> typeof(add) is extern(C) int function(int, int). Based on this output,
> core.demangle seems like it's not taking the extern(C) portion into
> account.

That would be a bug in core.demangle.


T

-- 
"I suspect the best way to deal with procrastination is to put off the 
procrastination itself until later. I've been meaning to try this, but haven't 
gotten around to it yet. " -- swr


Re: How can I express the type of a function in D?

2019-01-30 Thread Neia Neutuladh via Digitalmars-d-learn
On Wed, 30 Jan 2019 10:39:21 -0800, Ali Çehreli wrote:
> import core.demangle;
> 
> extern(C) int add(int, int);
> 
> void main() {
>alias F = typeof(add);
>pragma(msg, mangle!F("add"));
>pragma(msg, add.mangleof);
> }
> 
> Output:
> 
> _D3addUiiZi
> add   <-- Is that correct?

`add.mangleof` is correct. In fact, it's definitively correct.

typeof(add) is extern(C) int function(int, int). Based on this output, 
core.demangle seems like it's not taking the extern(C) portion into 
account.


Re: How can I express the type of a function in D?

2019-01-30 Thread H. S. Teoh via Digitalmars-d-learn
On Wed, Jan 30, 2019 at 10:39:21AM -0800, Ali Çehreli via Digitalmars-d-learn 
wrote:
[...]
> I wonder why the inconsistency. On the other hand, .mangleof produces
> just "add" when the function is extern(C).  (?)
[...]

For extern(C), this is correct behaviour, because that's how a C
function would be mangled (i.e., not mangled at all).


T

-- 
In a world without fences, who needs Windows and Gates? -- Christian Surchi


Re: How can I express the type of a function in D?

2019-01-30 Thread Ali Çehreli via Digitalmars-d-learn

On 01/30/2019 07:47 AM, Steven Schveighoffer wrote:
> On 1/30/19 12:14 AM, Sobaya wrote:
>> I want to get a mangled name of a D function by
>> `core.demangle.mangle`, but I'm in trouble because there are no ways
>> to express a type of a function, which is used for a template argument
>> of `mangle`.
>>
>> For example, it is wrong to use the type `int function(int,int)` to
>> express the type of `int add(int,int)`.
>> Because it expresses the type of a function POINTER, not just a 
function.

>>
>> The fuction name in a binary compiled this function is "_D3addFiiZi",
>> but `mangle!(int function(int,int))("add")` returns "_D3addPFiiZi",
>> which includes "P" meaning POINTER.
>>
>> How can I get the former one?
>
> Why not use add.mangleof?
>
> -Steve

add.mangleof includes the module name as well (_D6deneme3addFiiZi) but 
the OP wanted without (_D3addFiiZi). I wonder why the inconsistency. On 
the other hand, .mangleof produces just "add" when the function is 
extern(C). (?)


import core.demangle;

extern(C) int add(int, int);

void main() {
  alias F = typeof(add);
  pragma(msg, mangle!F("add"));
  pragma(msg, add.mangleof);
}

Output:

_D3addUiiZi
add   <-- Is that correct?

Ali



Re: Should I prefix package names with the name of my program?

2019-01-30 Thread H. S. Teoh via Digitalmars-d-learn
On Mon, Jan 28, 2019 at 05:07:35PM -0500, Steven Schveighoffer via 
Digitalmars-d-learn wrote:
> On 1/28/19 4:57 PM, Steven Schveighoffer wrote:
> > On 1/28/19 3:16 PM, H. S. Teoh wrote:
[...]
> > > > I use a package nearly every time because if you don't, you run
> > > > into weird quirks of the language for top-level modules.
> > > 
> > > Really? Such as?  I've never heard of said quirks.
[...]
> OK, so it's because top-level packages and modules imported are put
> into the namespace. But modules under packages are not.
> 
> So for instance, if you have:
> 
> module a;
> 
> void a() {}
> 
> 
> 
> import a;
> 
> void main()
> {
>a(); // error can't call module a
> }
> 
> whereas if a is changed to:
> 
> module pkg.a;
> 
> void a() {}
> 
> and the import changed to import pkg.a; then it works.

Argh... I've been running into this problem *so* often, that I've
settled with deliberately naming modules differently from any symbols
contained therein.  So *this* is what I've been doing wrong... sigh...


> But this doesn't solve the problem of having a simple library/app with
> a simple module name. What do you put it under? It can't be a.a,
> because that doesn't help.
> 
> It really is a quirk of D that I don't like, the top level packages
> should not conflict with other symbols in most cases.
[...]

I'm guessing this has to do with D's symbol lookup rules. Yet another
"counterintuitive" case for Walter's highly-symmetric, idealistic lookup
rules. :-P


T

-- 
It is widely believed that reinventing the wheel is a waste of time; but I 
disagree: without wheel reinventers, we would be still be stuck with wooden 
horse-cart wheels.


Re: Is there something special required to use Appender.clear

2019-01-30 Thread Steven Schveighoffer via Digitalmars-d-learn

On 1/30/19 7:32 AM, FeepingCreature wrote:

On Monday, 28 January 2019 at 15:16:54 UTC, Steven Schveighoffer wrote:
It will inspect the allocated length from the GC if the array is 
appendable from the beginning. So it's not always going to reallocate.


e.g.:

string x = "abc".idup;

auto app = x.appender;

app ~= "xyz"; // does not reallocate.



Fair enough.


Wow, I take this back. I tried it, and it DOES reallocate.

In fact, appender when given data that's not mutable avoids the check 
for appendability, and extension into the block.


So indeed, using appender on a string that is appendable reallocates on 
first append. I agree with you now, Appender on an existing string is 
near useless.


Looks like there were some changes that fix one problem, but may have 
inadvertently created this problem. And I'm rereading my comments in 
this PR, finding that I was not exactly correct on my analysis: 
https://github.com/dlang/phobos/pull/2046


In short, there's a question of purity, which was already on the 
Appender's functions, causing issue with immutable data. I think this 
won't be strong pure anyway, because appender's functions are not 
strong-pure (there's always mutable data inside it).


I think we should avoid the mutability check in that call.


My problem is this.

const and immutable are *not* well supported in the standard library at 
the moment. What I want is that I can use the idioms of the stdlib, 
semantically, in a way that lets me *not care* about const or immutable, 
that lets me express the patterns I want without having to worry about 
whether some type deep inside my code, a dub library, or phobos itself 
decided to declare a field immutable.


Appender covers two usecases: "capacity caching" and "memory reuse." 
Both of those usecases have two const variations: "possibly immutable" 
and "mutable".


   mutable capacity caching | mutable memory reuse
---+-
immutable capacity caching | immutable memory reuse

But instead of cutting between capacity caching and memory reuse, down 
the middle, Appender cuts between mutable and immutable, left to right. 
I think this is a symptom of a broad negligence of constness as a 
first-class property - constness works sometimes, and it's nice if it 
does, but it can't be *relied* on to be well supported. This makes using 
const in D an eternal uphill struggle. Why even go to all the trouble to 
make a new major version of the language just to introduce constness, if 
it's not going to be treated as a first-class concern? I don't want to 
have to sprinkle static if(isAssignable!T) everytime I want to use a 
library type. If Phobos offers me as generic a data structure as 
Appender, parameterized on T, it should work for T, regardless of what T 
is doing, and *certainly* regardless of what fields in T are marked 
const. Especially considering that if a field is not marked as const, 
that hardly means it's not going to lead to bugs if its memory is reused 
while you're referencing it!


Appender covers appending, which works for both mutable and immutable 
data. The clear function, if called on immutable data, would allow for 
immutable data to be overwritten, which is undefined behavior. This 
should be harder to do than just calling a member function.


Note that if we fix the above problem, there is a workaround:

app = app.data[0 .. 0].assumeSafeAppend.appender;

Which includes the greppable assumeSafeAppend property.

The biggest problem I see is not necessarily that immutable arrays 
should be clearable, but that arrays of types with const items should be 
clearable. I can't say I agree with immutable pieces, as again, that 
leads to potential UB. I know it's a PITA, but we have to consider as a 
library type all possible usages, not just focused ones.


I can see a PR that allows clear for types that are not assignable, but 
only have const data, being accepted. Const doesn't guarantee no 
mutability, so it's not UB to modify data that in some other alias has a 
const reference. I don't know if we have a way to determine this 
separate from immutability.


-Steve


Re: How can I express the type of a function in D?

2019-01-30 Thread Steven Schveighoffer via Digitalmars-d-learn

On 1/30/19 12:14 AM, Sobaya wrote:
I want to get a mangled name of a D function by `core.demangle.mangle`, 
but I'm in trouble because there are no ways to express a type of a 
function, which is used for a template argument of `mangle`.


For example, it is wrong to use the type `int function(int,int)` to 
express the type of `int add(int,int)`.

Because it expresses the type of a function POINTER, not just a function.

The fuction name in a binary compiled this function is "_D3addFiiZi", 
but `mangle!(int function(int,int))("add")` returns "_D3addPFiiZi", 
which includes "P" meaning POINTER.


How can I get the former one?


Why not use add.mangleof?

-Steve


Re: Status of BetterC

2019-01-30 Thread rikki cattermole via Digitalmars-d-learn

On 31/01/2019 3:12 AM, Pavel Vozenilek wrote:
I am interested in viability of using BetterC (and only BetterC) for a 
project.


1. Is BetterC supported by GDC and LDC compilers?


LDC yes, dunno about GDC but it'll depend upon the version.


2. Is there debugger/editor/IDE support?


Not required. Use any up to date IDE/editor and it'll already work.


3. The only language specific documentation seems to be
    https://dlang.org/spec/betterc.html
    Is more documentation planned?


Not required. Same language just some bits are left out implementation 
wise. Basically anything that relies on druntime. Easy!


Status of BetterC

2019-01-30 Thread Pavel Vozenilek via Digitalmars-d-learn
I am interested in viability of using BetterC (and only BetterC) 
for a project.


1. Is BetterC supported by GDC and LDC compilers?
2. Is there debugger/editor/IDE support?
3. The only language specific documentation seems to be
   https://dlang.org/spec/betterc.html
   Is more documentation planned?


Re: Is there something special required to use Appender.clear

2019-01-30 Thread FeepingCreature via Digitalmars-d-learn
On Monday, 28 January 2019 at 15:16:54 UTC, Steven Schveighoffer 
wrote:
It will inspect the allocated length from the GC if the array 
is appendable from the beginning. So it's not always going to 
reallocate.


e.g.:

string x = "abc".idup;

auto app = x.appender;

app ~= "xyz"; // does not reallocate.

-Steve


Fair enough.

My use case is simply the standard usecase of Appender: I want 
to build up an array in a way that reduces GC churn. Maybe 
it's an array of structs that contain const members that I'll 
serialize to JSON and send on a socket. In that case, I know 
for a fact that no references will hang around past the 
serialization. That's what clear _is for._ I don't see why 
this would be different with const or immutable data; if you 
hold references past .clear being called you're in trouble 
*anyways.*


Right, this does seem like a big limitation. Keeping with the 
spirit of how slices don't own the memory in question, Appender 
is being conservative with what it doesn't know.


I wonder if it may be more appropriate to instead of preventing 
clear() on immutable/const arrays, to make it @system. Or maybe 
call it something different "dangerousClear" or something ;)


There definitely should be some way to fail if clear is called 
on an array that was passed into the constructor.


But I'm still not sure we should allow overwriting immutable 
memory without a cast, even in @system code.




My problem is this.

const and immutable are *not* well supported in the standard 
library at the moment. What I want is that I can use the idioms 
of the stdlib, semantically, in a way that lets me *not care* 
about const or immutable, that lets me express the patterns I 
want without having to worry about whether some type deep inside 
my code, a dub library, or phobos itself decided to declare a 
field immutable.


Appender covers two usecases: "capacity caching" and "memory 
reuse." Both of those usecases have two const variations: 
"possibly immutable" and "mutable".


  mutable capacity caching | mutable memory reuse
---+-
immutable capacity caching | immutable memory reuse

But instead of cutting between capacity caching and memory reuse, 
down the middle, Appender cuts between mutable and immutable, 
left to right. I think this is a symptom of a broad negligence of 
constness as a first-class property - constness works sometimes, 
and it's nice if it does, but it can't be *relied* on to be well 
supported. This makes using const in D an eternal uphill 
struggle. Why even go to all the trouble to make a new major 
version of the language just to introduce constness, if it's not 
going to be treated as a first-class concern? I don't want to 
have to sprinkle static if(isAssignable!T) everytime I want to 
use a library type. If Phobos offers me as generic a data 
structure as Appender, parameterized on T, it should work for T, 
regardless of what T is doing, and *certainly* regardless of what 
fields in T are marked const. Especially considering that if a 
field is not marked as const, that hardly means it's not going to 
lead to bugs if its memory is reused while you're referencing it!


Re: Can't build vibed:tls project

2019-01-30 Thread WebFreak001 via Digitalmars-d-learn

On Monday, 28 January 2019 at 20:08:31 UTC, Suliman wrote:

If I am specifying (sic! TLS):
dependency "vibe-d:tls" version="0.8.4" in my dub.sdl I am 
getting error when building simple project:


module `vibe` is in file 'vibe\vibe.d' which cannot be read

But I need to get vibed build with OpenSSL support


I assume your code looks like this:
import vibe.vibe;

...

the module vibe.vibe that imports nearly all of vibe.d comes with 
the vibe-d root package (not :tls)


vibe-d:tls gives you vibe.stream.tls (and some other vibe.stream 
stuff) and depends on vibe-core which gives you vibe.core with 
networking, logging, fibers and some other stuff


If you want to make a http server you either need to depend on 
vibe-d:http or just depend on vibe-d as a whole (which then you 
get the vibe.vibe module)


Re: How can I express the type of a function in D?

2019-01-30 Thread Ali Çehreli via Digitalmars-d-learn

On 01/29/2019 09:14 PM, Sobaya wrote:
I want to get a mangled name of a D function by `core.demangle.mangle`, 
but I'm in trouble because there are no ways to express a type of a 
function, which is used for a template argument of `mangle`.


For example, it is wrong to use the type `int function(int,int)` to 
express the type of `int add(int,int)`.

Because it expresses the type of a function POINTER, not just a function.

The fuction name in a binary compiled this function is "_D3addFiiZi", 
but `mangle!(int function(int,int))("add")` returns "_D3addPFiiZi", 
which includes "P" meaning POINTER.


How can I get the former one?

Thanks.



typeof works:

import core.demangle;

int add(int, int);

void main() {
  alias F = typeof(add);
  pragma(msg, mangle!F("add"));
}

Ali