Re: Is it possible to "overload" based on visibility?

2020-09-25 Thread Steven Schveighoffer via Digitalmars-d-learn

On 9/25/20 3:43 AM, 60rntogo wrote:
On Wednesday, 23 September 2020 at 19:27:13 UTC, Steven Schveighoffer 
wrote:

This is a bug in the language.


Is this a known bug? If not, it should be reported.


I don't know, you can search for and report it here: 
https://issues.dlang.org




I came up with an answer to my original question that sort of works:

---
module foo;

struct Foo
{
   private int x;
}

int x(Foo f)
{
   return f.x;
}
---

The downside is that if I don't want to import all of foo at once, then 
I have to import both Foo and x, but then I can read x from outside the 
module and modify it form inside as I wanted. Are there any drawbacks of 
this approach that I'm not seeing?


Wow, this is actually quite clever! I think it's a very valid solution. 
The only thing I would caution is that it takes Foo by value, which 
means it's going to make a copy of everything. Your toy example, that's 
OK, but if Foo is complex or has a significant copy constructor, it 
might be slow.


You can use auto ref to alleviate that:

int x()(auto ref Foo f) // needs to be a template for auto ref to work

-Steve


Re: Is it possible to "overload" based on visibility?

2020-09-23 Thread Steven Schveighoffer via Digitalmars-d-learn

On 9/23/20 2:38 PM, 60rntogo wrote:

So my questions are:

1. Can I achieve my original goal of being able to refer to _x by one 
name, so that I have read only access from outside the module and 
read/write access from inside?


I would guess no. You have to use different names.

2. Is the behavior that allows me to call the private method intended? 
This is such a blatant violation of encapsulation that it feels like a 
bug either in the language or the implementation.


This is a bug in the language. Either varying ONLY by visibility of an 
overload should be disallowed, or you shouldn't have access to the 
private x. I don't know which one the answer is, but certainly the 
current behavior is erroneous.


-Steve


Re: uda pattern foo and foo(val)

2020-09-22 Thread Steven Schveighoffer via Digitalmars-d-learn

On 9/22/20 11:31 PM, Steven Schveighoffer wrote:


I thought it had something to do with the optional parentheses.



I think it does have something to do with this. I think it works if you 
do attrs[0], because you really get an alias to the function symbol, and 
that calls it.


I still think I can work with this anyway.

-Steve


Re: uda pattern foo and foo(val)

2020-09-22 Thread Steven Schveighoffer via Digitalmars-d-learn

On 9/22/20 10:20 PM, Adam D. Ruppe wrote:
On Wednesday, 23 September 2020 at 02:07:04 UTC, Steven Schveighoffer 
wrote:

I just said pragma(msg, __traits(getAttributes, z))


Ah, ok, this is weird, `pragma(msg, __traits(getAttributes, z)[0])` 
works just fine!


Oh, yeah, weird! I see that now. So it will actually work, it's just my 
method of testing "will this work", which actually isn't how I would use 
it, triggers some obscure bug, lol.


But that might be adequate for you - just loop over the attributes and 
use them one by one. Which you'd do anyway.


Yep, exactly what I would be doing anyway.

I suspect this is overload resolution not happening yet when you 
getAttributes but then it happens when it is forced evaluated with the 
index. (prolly one of those order-of-semantic bugs in dmd)


I thought it had something to do with the optional parentheses.

Thanks anyway for helping!

-Steve


Re: uda pattern foo and foo(val)

2020-09-22 Thread Steven Schveighoffer via Digitalmars-d-learn
On Wednesday, 23 September 2020 at 01:57:08 UTC, Adam D. Ruppe 
wrote:
On Wednesday, 23 September 2020 at 01:45:46 UTC, Steven 
Schveighoffer wrote:
@foo int z; // Error: cannot interpret foo(T)(T val) at 
compile time


Where do you get that error? Is it from phobos' thing? cuz I 
copy/pasted your code and it compiled.


You can also just use a struct as the uda if your detection 
function checks for both the type and a value of the type, so 
it really depends on which search method you using.


I just said pragma(msg, __traits(getAttributes, z))

Well actually the thing I tried is slightly different. As usual I 
dumbed it down to post here (maybe was a bad idea).


A struct won’t work because the foo(val) form needs to hold any 
type and ifti doesn’t work on constructors.


-Steve


uda pattern foo and foo(val)

2020-09-22 Thread Steven Schveighoffer via Digitalmars-d-learn

I want to set up a way to use the following patterns:

@foo
@foo(val)

Is there a way I can define foo such that this works?

I tried this:

struct Foo(T)
{
   T val;
}

auto foo(T)(T val) { return Foo!T(val); }

@property foo() { return Foo!int(0); }

So this works:

@foo() int x;
@foo(1) int y;

But this doesn't:

@foo int z; // Error: cannot interpret foo(T)(T val) at compile time

Is there a way I can do this while keeping the name the same for both 
options?


If I have different names, I can get it to work also.

-Steve


Re: Why private methods cant be virtual?

2020-09-22 Thread Steven Schveighoffer via Digitalmars-d-learn

On 9/22/20 10:11 AM, Arafel wrote:

My guess is that this was taken from Java, as in fact most of the D 
class system seems to be (see `synchronized`, reference semantics, etc). 
There it makes sense, because there is only one class per compilation 
unit, so the `private` members are in effect hidden from any child 
classes and it wouldn't make sense to override them.


This is a very good guess. Specifically, I think classes (and the 
mechanisms for inner classes and anonymous classes) were added to D1 to 
allow porting of JWT to D.


-Steve


Re: Why private methods cant be virtual?

2020-09-22 Thread Steven Schveighoffer via Digitalmars-d-learn

On 9/22/20 5:00 AM, claptrap wrote:
IE the compiler is supposed to make methods non-virtual automatically, 
it should be easy to do for private as all the relevant info be in the 
one compilation unit.



class A
{
  private void foo() {}
}

class B(T) : A
{
   static if(T.stringof == "BlahBlahBlah") private override foo() {}
}

-Steve


Re: Why private methods cant be virtual?

2020-09-21 Thread Steven Schveighoffer via Digitalmars-d-learn

On 9/21/20 7:52 PM, H. S. Teoh wrote:

On Mon, Sep 21, 2020 at 07:43:30PM -0400, Steven Schveighoffer via 
Digitalmars-d-learn wrote:
[...]

No, it's not a bug. It's intentional.

private and package functions are final, and we aren't going to change
that now, even if it makes sense to make them virtual.

[...]

Whoa.  But why??  What's the reasoning behind private being non-virtual?


You'd have to confirm with Walter. This is a relic from D1. I think it 
has something to do with the expectation of whether a private function 
makes sense to override. The use case is pretty narrow -- allow 
overriding only within the current package/module. But I can see the use 
case being valid.


However, changing it now means a slew of code becomes virtual that is 
currently not virtual. This could be a problem for existing code.


If we ever got a virtual keyword, then it might be possible to allow 
them to become virtual if you opt-in. But I don't see it happening 
without that.


If you do a search on the general forum, you will find a few 
conversations about this in the way past. It's been discussed, but never 
changed.


-Steve


Re: Why private methods cant be virtual?

2020-09-21 Thread Steven Schveighoffer via Digitalmars-d-learn

On 9/21/20 7:30 PM, H. S. Teoh wrote:

On Mon, Sep 21, 2020 at 11:17:13PM +, claptrap via Digitalmars-d-learn 
wrote:

Seems like a completely pointless restriction to me.

[...]

It looks like a bug to me.  Please file one if there isn't already one:

https://issues.dlang.org/


T



No, it's not a bug. It's intentional.

private and package functions are final, and we aren't going to change 
that now, even if it makes sense to make them virtual.


-Steve


function to tell if a string could be an identifier

2020-09-21 Thread Steven Schveighoffer via Digitalmars-d-learn
Excepting keywords (though it's OK if that's checked also), is there a 
function in Phobos or druntime to tell me if a string could be a valid 
identifier?


I can write my own, but I was hoping this was already done.

-Steve


Re: Is there a way to return an lvalue and also an rvalue from the same member function?

2020-09-20 Thread Steven Schveighoffer via Digitalmars-d-learn

On 9/20/20 11:52 AM, realhet wrote:

On Sunday, 20 September 2020 at 14:54:09 UTC, Steven Schveighoffer wrote:

On 9/20/20 9:30 AM, realhet wrote:
ref inout(int) x() inout { return array[0]; }


This doesn't work when I type:
v.x++;


It should, as long as v is mutable.

I want to make a similar type like the GLSL vectors. Where the following 
thing is valid:

vec4 a, b;
a.yzw = b.xzy;


This should be straight-up opDispatch I would think. You might need a 
helper return that reroutes the correct items.


The only thing I don't want  to implement from the GLSL spec is those 
non-contigous swizzle assignments like:

a.zyx = vec3(1,2,3) ***
but
a.xyz = vec3(1,2,3) should work.


What you could do, in this case, is make your return type either a 
helper type that uses a slice of the original, or one that contains a 
copy of the data in the right order, but is not assignable.




*** maybe with a struct that refers to the original vector and the 
swizzle code it could be also possible. :D


Yeah, I think this might work.

-Steve


Re: Building LDC runtime for a microcontroller

2020-09-20 Thread Steven Schveighoffer via Digitalmars-d-learn

On 9/20/20 10:51 AM, Dylan Graham wrote:

On Saturday, 19 September 2020 at 20:39:38 UTC, aberba wrote:

Do you attend our monthly D online meetups?


We have monthly online meetups? I would love to join of course!


Happening next weekend! 

https://forum.dlang.org/post/rjjcl4$30sm$1...@digitalmars.com

Would love to hear about your work!

-Steve


Re: Is there a way to return an lvalue and also an rvalue from the same member function?

2020-09-20 Thread Steven Schveighoffer via Digitalmars-d-learn

On 9/20/20 9:30 AM, realhet wrote:

Hi,

struct S{
   int[2] array;

   ref  x()   { return array[0]; }
   auto x() const { return array[0]; }
}

If there a way to write the function 'x' into one function, not 2 
overloads.


I tried auto/const/ref mindlessly :D, also remembered 'inout', but 
obviously those weren't solve the problem.


Your original code is an odd situation -- you want to return by ref if 
it's mutable, but not if it's const?


Why not return by ref always, and just forward the constancy? This is 
what inout is made to do:


ref inout(int) x() inout { return array[0]; }



(This is going to be a swizzling 'system' that mimics GLSL, later I will 
make a template that takes 'x'as a template parameter, just wondering 
that the support for const and non-cons can be done easier.)


If you want to differ behavior by const, but write one function, you can 
use a `this` template parameter. But without seeing your real use case, 
you might end up writing the same amount of code.


-Steve


Re: vibe.d: How to get the conent of a file upload ?

2020-09-19 Thread Steven Schveighoffer via Digitalmars-d-learn

On 9/19/20 3:36 PM, IGotD- wrote:

On Saturday, 19 September 2020 at 19:27:40 UTC, Steven Schveighoffer wrote:


I used Kai's book, and yeah, you have to do things the vibe way. But 
most web frameworks are that way I think.




Do you have a reference to this book (web link, ISBN)?




Sure:

https://www.packtpub.com/product/d-web-development/9781785288890

It might be a bit dated, but most of the concepts are the same.

-Steve


Re: vibe.d: How to get the conent of a file upload ?

2020-09-19 Thread Steven Schveighoffer via Digitalmars-d-learn

On 9/19/20 6:59 AM, wjoe wrote:

Handling file uploads is one example, another is command line arguments.
The presumption here is there is vibe and there can only be vibe. It 
takes them from Runtime.args. Duh?
This didn't make sense to me until I saw example where the 
initialization of vibe was done in a module constructor.


This used to be the expected way to set up vibe (using module 
constructors). And vibe would provide its own main function.


I *think* the idea was to allow registration of different handlers in 
their respective modules.


Nowadays, you just run the setup wherever you want (I do everything in 
main).


By using vibe I feel like I need to bend myself like a snake and jump 
through the hoops of vibe's one way to do it. You save a lot of time 
here and there and then you lose half a day because of some stupid road 
block like the above.


I used Kai's book, and yeah, you have to do things the vibe way. But 
most web frameworks are that way I think.


I recommend getting the book if you plan on doing a lot with vibe.d

Where vibe really shines are the diet templates and the web interface 
stuff. To not have to handle anything from forms, or query parameters, 
and just write normal D functions is really great. You can even do a lot 
of authentication and stuff using UDAs. It helps you write consistent 
web applications.


And I LOVE diet templates. So much less verbose than actual HTML. I have 
a hard time writing actual HTML now.


When you want to do stuff manually, I think it's not as well supported.

-Steve


Re: vibe.d: How to get the conent of a file upload ?

2020-09-19 Thread Steven Schveighoffer via Digitalmars-d-learn

On 9/19/20 7:15 AM, ikod wrote:

On Saturday, 19 September 2020 at 11:11:21 UTC, ikod wrote:

On Friday, 18 September 2020 at 13:13:16 UTC, wjoe wrote:
On Friday, 18 September 2020 at 12:58:29 UTC, Steven Schveighoffer 
wrote:

On 9/18/20 8:39 AM, Steven Schveighoffer wrote:
But again, solved with an enhancement that allows you to process 
the data in your code. I'll file the enhancement request for you, 
as I think it's a nice addition.


https://github.com/vibe-d/vibe.d/issues/2478



Awesome! Thanks a ton :)


My preferable way to handle such thing is: convert incoming data into 
input range of immutable(ubyte)[] and let user to consume this range 
(and handle it as it wish - transform, store in memory as is, or dump 
to disk)


sorry, this looks exactly like it described in proposal (and this is how 
requests works).




You mean for each file, right? Yeah, that is the proposal, though it 
uses Vibe's io type (necessary I think).


-Steve


Re: Question about linker errors when using slices

2020-09-19 Thread Steven Schveighoffer via Digitalmars-d-learn

On 9/18/20 10:45 PM, tspike wrote:

If you only compile platform.d, the linker will complain about 
“undefined references.” This is true when using dmd and gdc, though 
platform.d compiles just fine when using ldc. But the file only fails to 
compile when the “items” member of AppData is a slice; if “items” is an 
int* platform.d will compile.


The linker spits the following:

     platform.o:(.data._D22TypeInfo_S3app7AppData6__initZ+0x30): 
undefined reference to `_D3app7AppData9__xtoHashFNbNeKxSQBeQBdZm'
     platform.o:(.data._D22TypeInfo_S3app7AppData6__initZ+0x38): 
undefined reference to `_D3app7AppData11__xopEqualsFKxSQBdQBcKxQjZb'


I was just wondering if anyone knows if this behavior is expected or if 
this is a compiler bug. Thank you in advance for your time!


On one hand, I don't necessarily expect it. These are symbols that are 
used to build an appropriate TypeInfo instance.


I wouldn't expect it, because you aren't using TypeInfo anywhere.

However, it does happen quite a bit, because the conditions under which 
D generates or expects a generated TypeInfo are somewhat obscure and not 
documented. It's probably why LDC works and the others don't.


I hope Andrei's recent push to demystify TypeInfo stuff makes this a lot 
more tractable.


The answer is -- just build with all the files. The linker should throw 
out stuff that isn't needed.



PS: I hope this is the right sub-forum for asking this sort of question!


Of course!

-Steve


Re: dub: Is it possible to have a library target and depend on it in the same dub config?

2020-09-18 Thread Steven Schveighoffer via Digitalmars-d-learn

On 9/18/20 7:38 AM, wjoe wrote:

Something like this:

configuration "lib" {
   targetType "dynamicLibrary"
   sourceDir "source/lib/"
}

configuration "app" {
   targetType "executable"
   sourceFiles "source/app.d"
   linkWith "lib"
}

I found subConfiguration in the docs but that seems to be related to 
external dependencies.


app.d merely provides a CLI to the library as well as an option to run 
as a server. I don't want to have the overhead of an entire git repo and 
such for something that is a single file and also closely related to the 
library.




There are other options.

for instance dub (the project) has a library and an application. the 
config looks like this:


configuration "application" {
targetType "executable"
mainSourceFile "source/app.d"
libs "curl"
versions "DubUseCurl" "DubApplication"
}

configuration "library" {
targetType "library"
excludedSourceFiles "source/app.d"
	copyFiles "bin/libcurl.dll" "bin/libeay32.dll" "bin/ssleay32.dll" 
platform="windows"

versions "DubUseCurl"
}

You can also build a subproject in the same repository. In that case, 
you would probably want the app to be the main project, and you then 
depend on the library project via "foo:lib"


-Steve


Re: DDoc generation

2020-09-18 Thread Steven Schveighoffer via Digitalmars-d-learn

On 9/18/20 7:41 AM, Russel Winder wrote:

Hi,

I am trying to get to grips with DDoc for documenting an application. Getting
the individual module HTML files seems to be the easy bit. The question is how
to get an index.html (or equivalent) so as to have an application level entry
point to the generated documentation.
  



You can make explicit ddoc files, and compile those along with your 
application.


https://dlang.org/spec/ddoc.html#using_ddoc_for_other_documentation

-Steve


Re: vibe.d: How to get the conent of a file upload ?

2020-09-18 Thread Steven Schveighoffer via Digitalmars-d-learn

On 9/18/20 8:39 AM, Steven Schveighoffer wrote:
But again, solved with an enhancement that allows you to process the 
data in your code. I'll file the enhancement request for you, as I think 
it's a nice addition.


https://github.com/vibe-d/vibe.d/issues/2478

-Steve


Re: vibe.d: How to get the conent of a file upload ?

2020-09-18 Thread Steven Schveighoffer via Digitalmars-d-learn

On 9/17/20 8:07 PM, wjoe wrote:


Not a reply to this post in particular but to all the ones I've read so 
far.


If I understand correctly. Vibe parses the form data and writes all 
files to disk. Where to ?


See the code here: 
https://github.com/vibe-d/vibe.d/blob/ebebfa827f568cc9bced4bec2b66edc043a8adf7/inet/vibe/inet/webform.d#L311


Can I configure it ? I don't want libraries to just write data to my 
file systems without me setting this up. Nowhere did I find this 
behavior described in the docs.


No, not at the moment. Which is why I was saying, it could be an 
enhancement request to vibe.


And if not, how is data processed with a 10mb file upload followed by a 
few number fields ?


All the data is processed before the accessor to the form data or the 
file data. It HAS to be this way, as the data is still on the incoming 
network socket.


It needs to read all of the file data to get to the other data fields, 
doesn't it ?


Yes



I'm sorry this is completely counter intuitive. I can understand the 
memory/security risks and all but I have no intention to hack, DOS or 
however else disrupt my private server in my private network with 
garbage data. I just want to get the data in a byte[].


Again, enhancement request needed. The code currently is hard-coded to 
write to disk.




Why does the lib not simply reject files that are unreasonably 
(configurable) big ?


If you had 1000 requests being processed simultaneously, and each of 
those requests provided 10MB files, then you now need potentially 10GB 
of RAM to hold those requests. This doesn't scale when the application 
is unknown to vibe.


But again, solved with an enhancement that allows you to process the 
data in your code. I'll file the enhancement request for you, as I think 
it's a nice addition.


Writing files to disk in order to then needing to copy them somewhere 
else or to read them back into memory for further processing sounds, 
above all else, incredibly inefficient.


Agreed. In my case, it was an actual copy, as the location of the stored 
data was on a different filesystem than the temporary files.



I might not even want to keep the file and drop it.


Yep, it's a waste in that case.



I guess it's no problem to parse the data myself, but then what's the 
point in using a framework ?


Agreed.


Are there other frameworks besides vibe that can do what I want ?


In D, I'm not sure what the other frameworks do. I believe there are 
others if you search on code.dlang.org, you should be able to find some.


I'm sorry for the rant, developing this kind of software is a pain in 
the drain and stresses me out to no end. It sucked hard in the past with 
php and decades later with python, ruby, D, you name it it still sucks ;)


web development sucks in general ;) Yet, we all still do it.

-Steve


Re: vibe.d: How to get the conent of a file upload ?

2020-09-17 Thread Steven Schveighoffer via Digitalmars-d-learn

On 9/17/20 6:13 PM, aberba wrote:

On Thursday, 17 September 2020 at 21:57:37 UTC, Steven Schveighoffer wrote:

On 9/17/20 1:08 PM, wjoe wrote:

[...]


the `files` property actually does the processing only when you call it.

If you access the `bodyReader` property directly, you can process that 
data yourself. You can even register a web interface function with an 
`InputStream` parameter type, and it will be bound to the body data.


I'm not sure I understand how to do this and parser the files in memory.


So an HTTP request with form data will come in with the headers parsed, 
but the data is still on the network stream.


The first time you access `files`, it processes the stream data, and 
splits it into form data and file data, saves the files, and then gives 
you back the file dictionary so you can use them.


If instead, you access `bodyReader`, YOU get to process the form data 
and file data.




I've done this with my REST interface, though that's not form data.

That's not a great API, though. I would love to see vibe.d allow a 
direct call to vibe.inet.webform.parseFormData with a specific handler 
for files and form data.
Can we file an issue for this? Because I'm very interested in having 
this resolved


You can always file an issue! https://github.com/vibe-d/vibe.d/issues

There may already be one in there.

There's potential to results in out of memory condition. Its a know 
issues. A complete parser (like multer in nodejs) allowance you to limit 
file size as well for error handling.


Meh, this is D :) we should be able to just process the data and do 
whatever we want with it. What I would like to see is vibe provide the 
parsing of form data, and just give me the data as it comes (kind of 
like a SAX parser). Maybe just a property in the HTTPServerRequest that 
I can set that says "use this callback when you get Form File data".



I've done this with my REST interface, though that's not form data.


Can you share your code for this?


Heh, this is not form data, it's just file data, raw on the stream. So I 
have a function like:


```
class FileRestImpl
{
@path(":cat/:id/:uuid/upload")
@getAuth
void postUpload(HTTPServerResponse res, string _cat, int _id, 
string _uuid, InputStream stream, Nullable!string md5sum, NRMAuthInfo 
_authInfo)

{
...
}
}
```

You can see, I take an InputStream as a parameter -- the data comes in 
there. I just read it and save it to a file (in the correct location) 
anyway, verifying the md5sum is valid.


-Steve


Re: enum and const or immutable ‘variable’ whose value is known at compile time

2020-09-17 Thread Steven Schveighoffer via Digitalmars-d-learn

On 9/17/20 9:13 AM, Simen Kjærås wrote:

To be clear: I don't mind 'enum' being used this way, but if I were to 
do things over again, I would have used 'alias'.


fun fact: for a (very) brief time, D had a `manifest` keyword that did 
exactly what enum does in this instance (not even sure it made it into a 
release).


enum is a head scratcher of a name, for sure. But it works out just fine 
once you get used to it. I think of it as "compile time". To be honest, 
for what it does, enum is a very poor name. But because it's consistent, 
it works.


-Steve


Re: vibe.d: How to get the conent of a file upload ?

2020-09-17 Thread Steven Schveighoffer via Digitalmars-d-learn

On 9/17/20 1:08 PM, wjoe wrote:
Every post or example I found copies the file, like your code does, too. 
Why is that ? The content of the file upload is embedded in the form 
data. There's no need for temporary files or copying at all.


On top of that, if I upload a file to a server which is on a different 
PC on a different file system, how am I supposed to read the file from 
disk on a remote file system ?


This makes no sense.

What I want is something like this:


~$ cat /var/log/temperatures.log

temp_1=22;temp_2=28
temp_1=21;temp_2=25



~$ curl -F "temperature_log=@/var/log/temperatures.log" 
192.168.1.1:20222/temperature_upload



~$ nc -l 127.0.0.1 20222

POST /temperature_upload HTTP/1.1
Host: 192.168.1.1:20222
User-Agent: curl/7.72.0
Accept: */*
Content-Length: 245
Content-Type: multipart/form-data; 
boundary=c73c71472ff9e7d5


--c73c71472ff9e7d5
Content-Disposition: form-data; name="temperature_log"; 
filename="/var/log/temperatures.log"

Content-Type: application/octet-stream

temp_1=22;temp_2=28
temp_1=21;temp_2=25

--c73c71472ff9e7d5--



void upload(HttpRequest.. req, blah)
{
    auto file = "temperature_log" in req.files;
    if (file) {
   string temp_data_raw = file.data;
   assert ("temp_1=22;temp_2=28\ntemp_1=21;temp_2=25" == 
temp_data_raw);

    }
}



the `files` property actually does the processing only when you call it.

If you access the `bodyReader` property directly, you can process that 
data yourself. You can even register a web interface function with an 
`InputStream` parameter type, and it will be bound to the body data.


I've done this with my REST interface, though that's not form data.

That's not a great API, though. I would love to see vibe.d allow a 
direct call to vibe.inet.webform.parseFormData with a specific handler 
for files and form data.


I think you can agree that it's not feasible to store arbitrary sized 
file contents in memory. But it certainly can provide a mechanism to 
handle it as it's read.


-Steve


Re: Why is BOM required to use unicode in tokens?

2020-09-15 Thread Steven Schveighoffer via Digitalmars-d-learn

On 9/15/20 8:10 PM, James Blachly wrote:

On 9/15/20 10:59 AM, Steven Schveighoffer wrote:

Thanks to Paul, Jon, Dominikus and H.S. for thoughtful responses.

What will it take (i.e. order of difficulty) to get this fixed -- 
will merely a bug report (and PR, not sure if I can tackle or not) do 
it, or will this require more in-depth discussion with compiler 
maintainers?


I'm thinking your issue will not be fixed (just like we don't allow 
$abc to be an identifier). But the spec can be fixed to refer to the 
correct standards.




Steve: It sounds as if the spec is correct but the glyph (codepoint?) 
range is outdated. If this is the case, it would be a worthwhile update. 
Do you really think it would be rejected out of hand?




I don't really know the answer, as I'm not a unicode expert.

Someone should verify that the character you want to use for a symbol 
name is actually considered a letter or not. Using phobos to prove this 
is kind of self-defeating, as I'm pretty sure it would be in league with 
DMD if there is a bug.


But if it's not a letter, then it would take more than just updating the 
range. It would be a change in the philosophy of what constitutes an 
identifier name.


-Steve


Re: Why is BOM required to use unicode in tokens?

2020-09-15 Thread Steven Schveighoffer via Digitalmars-d-learn

On 9/15/20 10:18 AM, James Blachly wrote:

On 9/15/20 4:36 AM, Dominikus Dittes Scherkl wrote:

On Tuesday, 15 September 2020 at 06:49:08 UTC, Jon Degenhardt wrote:

On Tuesday, 15 September 2020 at 02:23:31 UTC, Paul Backus wrote:
Identifiers start with a letter, _, or universal alpha, and are 
followed by any number of letters, _, digits, or universal alphas. 
Universal alphas are as defined in ISO/IEC 9899:1999(E) Appendix D 
of the C99 Standard.


I was unable to find the definition of a "universal alpha", or 
whether that includes non-ascii alphabetic characters.


ISO/IEC 9899:1999 (E)
Annex D

Universal character names for identifiers
-



---

This is outdated to the brim. Also it doesn't allow for letter-like 
symbols (which is debatable, but especially the mathematical ones like 
double-struck letters are intended for such use).
Instead of some old C-Standard, D should better rely directly on the 
properties from UnicodeData.txt, which is updated with every new 
unicode version.




Thanks to Paul, Jon, Dominikus and H.S. for thoughtful responses.

What will it take (i.e. order of difficulty) to get this fixed -- will 
merely a bug report (and PR, not sure if I can tackle or not) do it, or 
will this require more in-depth discussion with compiler maintainers?


I'm thinking your issue will not be fixed (just like we don't allow $abc 
to be an identifier). But the spec can be fixed to refer to the correct 
standards.


-Steve


Re: Get enum value name as string at compile time?

2020-09-14 Thread Steven Schveighoffer via Digitalmars-d-learn

On 9/14/20 2:25 AM, Simen Kjærås wrote:

On Monday, 14 September 2020 at 03:48:51 UTC, Steven Schveighoffer wrote:

Consider the enum:

enum Foo { a, b }

Foo.a.stringof => "a"
enum x = Foo.a;
x.stringof => "cast(Foo)0"

Is there another way I can take an enum value that's known at compile 
time (but not the actual identifier), and get the name of it? I know I 
can use a switch, or to!string. But I was hoping this was easy for the 
compiler to figure out some way without involving CTFE.


It is a bit weird that x.stringof doesn't simply return the name like 
Foo.a.stringof does. Anyways, this works:


template enumName(alias a) {
     import std.meta : staticIndexOf, staticMap;

     alias T = typeof(a);
     enum getValue(string name) = __traits(getMember, T, name);
     alias enumValues = staticMap!(getValue, __traits(allMembers, T));

     enum enumName = __traits(allMembers, T)[staticIndexOf!(a, 
enumValues)];

}

enum Foo { a = 2, b = 19 }

enum x = Foo.a;
pragma(msg, enumName!x); // "a"



Thanks.

I never considered doing something like that. Not sure I like that 
better than the CTFE version. I just punted and used to!string in my 
code anyway.


A CTFE linear search in a compile-time array probably wouldn't be too 
bad, especially when the list of elements is not long.


Again, we could use that ... DIP to make things a lot less complex.

-Steve


Get enum value name as string at compile time?

2020-09-13 Thread Steven Schveighoffer via Digitalmars-d-learn

Consider the enum:

enum Foo { a, b }

Foo.a.stringof => "a"
enum x = Foo.a;
x.stringof => "cast(Foo)0"

Is there another way I can take an enum value that's known at compile 
time (but not the actual identifier), and get the name of it? I know I 
can use a switch, or to!string. But I was hoping this was easy for the 
compiler to figure out some way without involving CTFE.


-Steve


Re: Call C variadic function from D variadic function

2020-09-13 Thread Steven Schveighoffer via Digitalmars-d-learn

On 9/13/20 2:35 PM, Paul Backus wrote:

On Sunday, 13 September 2020 at 17:23:42 UTC, Steven Schveighoffer wrote:

On 9/13/20 12:55 PM, James Blachly wrote:


```
 /// Add a single line to an existing header
 auto addLine(T...)(RecordType type, T kvargs)
 if(kvargs.length > 0 && isSomeString!(T[0]))
 {
 static assert (kvargs.length %2 == 0);   // K-V pairs => 
even number of variadic args


 string varargMagic(size_t len)
 {
 string args = "sam_hdr_add_line(this.h, type.ptr, ";
 for(int i=0; iInterestingly, compilation fails if the mixin consists only of the 
comma-separated parameters ("Comma expression" [1])



Question:
If a variadic template, despite presenting to the user a "dynamic 
array", MUST know its parameter list at compile-time, is there a way 
(other than with mixins as shown) to pass this parameter list to 
extern(C) linkage function with variadic parameters?


Was just talking about this exact problem with Adam Ruppe. 
Unfortunately, because the parameters are an expression tuple, and not 
a compile-time tuple, you can't use stuff like staticMap.


You actually can, if you define the right kind of helper function:

     /// Add a single line to an existing header
     auto addLine(T...)(RecordType type, T kvargs)
     if(kvargs.length > 0 && isSomeString!(T[0]))
     {
     static assert (kvargs.length %2 == 0);   // K-V pairs => even 
number of variadic args

     immtuable(char)* argToStringz(alias arg)()
     {
     return toStringz(arg);
     }

     return sam_hdr_add_line(this.h, this.ptr, 
staticMap!(argToStringz, kvargs), null);

     }

The clever trick here is that, because of optional parentheses [1], 
`argToStringz!(kvargs[i])` can be interpreted either as the name of a 
function or a function call, depending on the context it appears in.


That's cool. And horrific at the same time :) I mean the templates that 
you have to instantiate for this...


I would prefer the mixin solution, even though it's uglier. I think 
something that abstracts that out would be a nice thing to have for 
std.meta.


-Steve


Re: Call C variadic function from D variadic function

2020-09-13 Thread Steven Schveighoffer via Digitalmars-d-learn

On 9/13/20 12:55 PM, James Blachly wrote:

Summary:
Can a typesafe D variadic function, or D variadic template pass its 
parameters to a C variadic function?


Background:
I maintain a library binding [0] to htslib, a high-performance and very 
widely used C library for high-throughput sequencing (hts) data files. 
We use this internally and haven't polished it for a release on the 
announce forum or biomed twitter, etc. yet.


In the course of upgrading it to support the latest API/ABI (htslib-1.10 
/ so.3), I need to add support for several new functions.


One of these is a variadic function with the signature:

`int sam_hdr_add_line(sam_hdr_t *h, const char *type, ...);`

Of course, we can call this directly from D with hardcoded parameters. 
However, one of the focuses of our library is "bindings + wrappers" to 
make this feel more like native D. Thus, we want a variadic function to 
which we may pass D strings (it is also a struct member function).


With help from Herringway on IRC, we came up with a solution using mixin:


```
     /// Add a single line to an existing header
     auto addLine(T...)(RecordType type, T kvargs)
     if(kvargs.length > 0 && isSomeString!(T[0]))
     {
     static assert (kvargs.length %2 == 0);   // K-V pairs => even 
number of variadic args


     string varargMagic(size_t len)
     {
     string args = "sam_hdr_add_line(this.h, type.ptr, ";
     for(int i=0; iInterestingly, compilation fails if the mixin consists only of the 
comma-separated parameters ("Comma expression" [1])



Question:
If a variadic template, despite presenting to the user a "dynamic 
array", MUST know its parameter list at compile-time, is there a way 
(other than with mixins as shown) to pass this parameter list to 
extern(C) linkage function with variadic parameters?


Was just talking about this exact problem with Adam Ruppe. 
Unfortunately, because the parameters are an expression tuple, and not a 
compile-time tuple, you can't use stuff like staticMap.


Manu's ... dip would be perfect for this:

return sam_hdr_add_line(this.h, this.ptr, toStringz(kvargs)..., null);

I think the only way it works today is if you use the mixin technique.

-Steve


Re: Initialize to None

2020-09-05 Thread Steven Schveighoffer via Digitalmars-d-learn

On 9/5/20 11:42 PM, N.S. wrote:
I'd like to check whether a variable is initialized or not. And I'd also 
like to uninitialize a variable that is already initialized. Thanks!


int x = void;

if (x == void)


There isn't a way to check this.


{
     writeln("x not initialized");
}
else
{
     // OK, use x
}

// Uninitialize x
x = void;



When you set the initial value of x to void, it means "don't do 
anything, let whatever data is already on the stack be the value of x".


So "uninitialize" doesn't really mean anything. It would technically 
mean "do nothing".


-Steve


Re: I think Associative Array should throw Exception

2020-09-04 Thread Steven Schveighoffer via Digitalmars-d-learn

On 9/4/20 1:48 AM, Jesse Phillips wrote:

On Thursday, 3 September 2020 at 15:12:14 UTC, Steven Schveighoffer wrote:

int[int] aa;
aa[4] = 5;
auto b = aa[4];

How is this code broken? It's valid, will never throw, and there's no 
reason that we should break it by adding an exception into the mix.




int foo() nothrow {
     return "1".to!int;
}

The following code is valid, will never throw, why does the compiler 
prevent it?


You are still missing the point ;)

Your example doesn't compile today. Mine does. It's not a question of 
which way is better, but that we already have code that depends on the 
chosen solution, and changing now means breaking all such existing code.


My point of bringing up the example is that your assertion that "it is 
already broken" isn't true.


To put it another way, if the above to!int call compiled, and we 
switched to exceptions, it would be the same problem, even if the right 
choice is to use Exceptions.


-Steve


Re: I think Associative Array should throw Exception

2020-09-03 Thread Steven Schveighoffer via Digitalmars-d-learn

On 9/3/20 10:43 AM, Jesse Phillips wrote:

On Tuesday, 1 September 2020 at 18:55:20 UTC, Steven Schveighoffer wrote:

On 9/1/20 2:20 PM, Jesse Phillips wrote:

Using RangeError is nice as it allows code to use array index inside 
`nothrow.`


This is the big sticking point -- code that is nothrow would no longer 
be able to use AAs. It makes the idea, unfortunately, a non-starter.


What is wrong with using `in`? I use this mostly:

if(auto v = key in aa) { /* use v */ }



I think that actually might be my point. If you need nothrow then this 
is what you need to do.


For breaking nothrow code using the [] syntax, I'd say it is already 
broken because the behavior is to throw and the above is how you would 
check that it won't.


int[int] aa;
aa[4] = 5;
auto b = aa[4];

How is this code broken? It's valid, will never throw, and there's no 
reason that we should break it by adding an exception into the mix.


The issue is, associative arrays throw an "uncatchable" error. Meaning 
code is written to catch the error (because it works). And correctly 
written `nothrow` code needs to use `in` to be properly nothrow.


The big issue is -- is accessing an invalid index a programming error or 
an environmental error? The answer is -- it depends. D has declared, if 
you use the indexing syntax, then it's a programming error. If you want 
it not to be a programming error, you use the key in aa syntax, and 
handle it.


The other thing you can do is use a different type, if you don't want to 
deal with the verbose syntax, but still want to catch environmental 
errors. A wrapper type is possible.


-Steve


Re: Annotating SortedRange.empty const: Best way to auto-deduce annotations?

2020-09-02 Thread Steven Schveighoffer via Digitalmars-d-learn

On 9/2/20 5:23 PM, SimonN wrote:

Hi,

About this issue in Phobos:
https://issues.dlang.org/show_bug.cgi?id=21216
SortedRange.empty should be const, .front should be inout

Just adding const/inout to SortedRange's methods won't be enough; if we 
add const/inout here, then many other Phobos ranges need to become 
const/inout-correct to keep the tests passing. Before I dive deeper into 
annotating their methods, I would like to verify my assumptions on how 
template function attribute deduction works:


1) I know that templated functions deduce their own attributes on 
instantiation. But front()/empty() are non-templated methods within the 
templated struct SortedRange. Will attribute deduction happen here?


mutability attributes are not deducted for templates.

wrapping ranges such as SortedRange can't really specify const or inout 
on their methods via introspection of the underlying range. What they 
can do is template the `this` parameter. Then if the underlying range 
supports calling that way, it will work, otherwise it won't.


using `template this` should be compatible with the existing code I 
would think.


-Steve


Re: Bug in import(...) on Windows?

2020-09-02 Thread Steven Schveighoffer via Digitalmars-d-learn

On 9/2/20 4:48 PM, Andrey Zherikov wrote:

On Wednesday, 2 September 2020 at 20:23:15 UTC, Steven Schveighoffer wrote:
What I'm wondering is if it needs to be ./file instead of .\file. Can 
you hard code that and see if it works?


This actually works:
     pragma(msg, import("file"));
     pragma(msg, buildPath(".", "file"));
     pragma(msg, import("./file"));

Result on Ubuntu:
===
hello

../file
hello

===

Result on Windows:
===
hello

..\file
hello

===

This seems weird that I can't use std.path functions or use valid 
"foo\bar" paths on Windows.


I don't know why it wouldn't work with native paths on Windows. But I'm 
not a DMD maintainer, so I don't know where to look in the code to see 
why it doesn't work.


It might be worth filing a bug. https://issues.dlang.org

-Steve


Re: Bug in import(...) on Windows?

2020-09-02 Thread Steven Schveighoffer via Digitalmars-d-learn

On 9/2/20 1:47 PM, Adam D. Ruppe wrote:

On Wednesday, 2 September 2020 at 17:39:04 UTC, Andrey Zherikov wrote:

Is this a bug in dmd?


I think it is an old bug filed (I can't find it though) about 
inconsistent platform behavior but it is allowed by spec for the 
compiler to reject any path components.


import("") is supposed to just give a filename, no directory path.

See: https://dlang.org/spec/expression.html#import_expressions

"Implementations may restrict the file name in order to avoid directory 
traversal security vulnerabilities. A possible restriction might be to 
disallow any path components in the file name."


Is this the problem though? It works on DMD Linux, which shares the same 
front end.


What I'm wondering is if it needs to be ./file instead of .\file. Can 
you hard code that and see if it works?


FYI, I know vibe diet templates DEPEND on this behavior, and I'd be 
surprised if it doesn't work at all on Windows.


-Steve


Re: How to create compile-time container?

2020-09-02 Thread Steven Schveighoffer via Digitalmars-d-learn

On 9/2/20 5:56 AM, Andrey Zherikov wrote:


==
Everything works well until I have included scripts in subdirectories:
├── dir1
│   ├── dir2
│   │   └── script
│   └── script
└── script
Content:
== script
msg hello
include dir1/script
== dir1/script
msg hello from dir1
include dir2/script
== dir1/dir2/script
msg hello from dir1/dir2
==

Compilation fails with "Error: file `"dir2/script"` cannot be found or 
not in a path specified with `-J`" (I used simple dmd -J. -run parser.d) 
which is expected because parse* functions do not track the directory 
where the script is located.


In this simple example the issue can be fixed by passing path to script 
as a parameter to parseScript function. But this doesn't seem to be 
flexible and extendable solution because there can be other commands 
that might call parseFile indirectly (they can even be in other modules).


Theoretically this can be solved by doing something like this but it 
doesn't work because "static variable `paths` cannot be read at compile 
time":

==
string[] paths;
void parseFile(string file)()
{
     enum path = paths.length > 0 ? buildPath(paths[$-1], 
file.dirName()) : file.dirName();


     paths ~= path;
     scope(exit) paths = paths[0..$-1];

     enum script = import(buildPath(path, file));
     mixin(parseScript(script));
}
==
Note that the whole point is to do this parsing at compile time.



OK, NOW I see where your code is coming from. The issue is that you need 
the directory of the script imported to be the "local directory". Your 
solution will not work -- you can't mixin code that is not available at 
compile time.


Here is what I would do instead:

string parseScript(string filename, string script)
{
string code;
string base = dirName(filename);
if(base[$-1] != '/') base ~= '/';
foreach(line; script.lineSplitter())
{
auto idx = line.indexOf(' ');

switch(line[0..idx])
{
case "msg":
code ~= "writeln(\"" ~ line[idx+1..$] ~ "\");";
break;
case "include":
{
code ~= `parseFile!"`;
string importfile = line[idx+1 .. $];
if(!importfile.startsWith('/')) // relative path
 code ~= base;
code ~= importfile ~ `";`;
break;
}
default: break;
}
}
return code;
}

And pass the filename to this function in addition to the script source.

-Steve


Re: I think Associative Array should throw Exception

2020-09-02 Thread Steven Schveighoffer via Digitalmars-d-learn

On 9/1/20 10:46 PM, James Blachly wrote:

On 9/1/20 2:55 PM, Steven Schveighoffer wrote:

On 9/1/20 2:20 PM, Jesse Phillips wrote:

Using RangeError is nice as it allows code to use array index inside 
`nothrow.`


This is the big sticking point -- code that is nothrow would no longer 
be able to use AAs. It makes the idea, unfortunately, a non-starter.



Steve, are there not several (probably better, faster) alternatives to 
the built-in AA that are nothrow? I think a nice way to look at the 
built-in AA is an easy default for quick scripts, new users, etc., much 
like the default of `throw` status of a function or code block.


Advanced users, (i.e. those using nothrow annotation) could select a 
more efficient AA implementation anyway.


The problem is not the requirement but the resulting code breakage if 
you change it now.


-Steve


Re: How to create compile-time container?

2020-09-01 Thread Steven Schveighoffer via Digitalmars-d-learn

On 9/1/20 3:09 PM, Andrey Zherikov wrote:
Unfortunately this won't work if there is a function 'bar' in different 
module that calls 'foo':


You should post a full example you expect to work or not work, then we 
can discuss.


I think it should work (I've tried it), but there are several problems 
that could possibly happen with your code, and it's hard to tell what 
you mean by "won't work" with the incomplete code that you posted.


-Steve


Re: How to create compile-time container?

2020-09-01 Thread Steven Schveighoffer via Digitalmars-d-learn

On 9/1/20 2:19 PM, Andrey Zherikov wrote:

On Monday, 31 August 2020 at 20:44:16 UTC, Adam D. Ruppe wrote:

On Monday, 31 August 2020 at 20:39:10 UTC, Andrey Zherikov wrote:

How can I do that?


You can use a normal string[] BUT it is only allowed to be modified 
inside its own function.


Then you assign that function to an enum or whatever.


string[] ctGenerate() {
   string[] list;
   list ~= "stuff";
   return list;
}

enum list = ctGenerate();


That's all allowed. But CTFE is now allowed to read or modify anything 
outside its own function; you can't have two separate function calls 
build up a shared list (unless you can somehow call them both together 
like `enum list = ctGenerate() ~ other_thing();`



The thing I'm trying to implement is: I have a function foo(string s)() 
and some "state"; this function should override this "state" (using "s" 
param) for all code within this function (note that code can execute 
other modules that can refer to the same "state"). The problem is that I 
need this overridden "state" to be compile-time constant to be used in 
mixin. Any ideas how I can do this?


string overrideState(string s)
{
   // work your magic here, it's normal D code!
}

void foo(string s)()
{
   mixin(overrideState(s));
}

-Steve


Re: I think Associative Array should throw Exception

2020-09-01 Thread Steven Schveighoffer via Digitalmars-d-learn

On 9/1/20 2:20 PM, Jesse Phillips wrote:

Using RangeError is nice as it allows code to use array index inside 
`nothrow.`


This is the big sticking point -- code that is nothrow would no longer 
be able to use AAs. It makes the idea, unfortunately, a non-starter.


What is wrong with using `in`? I use this mostly:

if(auto v = key in aa) { /* use v */ }

Note, that in certain cases, I want to turn *normal* array access errors 
into exceptions, because I always want bounds checking on, but I don't 
want a (caught) programming error to bring down my whole vibe.d server.


So I created a simple wrapper around arrays which throws exceptions on 
out-of-bounds access. You could do a similar thing with AAs. It's just 
that the declaration syntax isn't as nice.


-Steve


Re: Template argument deduction fails with alias

2020-08-31 Thread Steven Schveighoffer via Digitalmars-d-learn

On 8/31/20 9:11 PM, Ben Jones wrote:

I have an alias that looks like

static if(...){
   alias AliasType = SumType!(...);
}

which I use in a template constraint for a function template:

bool func(T: AliasType!Args, Args...)(T t){ ... }


When I try to call func with an AliasType object, the argument deduction 
fails with a message saying that the argument type (a SumType) doesn't 
match the template constraint (an AliasType)


Things do work if I change the template constraint to be a SumType 
rather an an AliasType


Is there a workaround to this?  Here's a complete example: 
https://run.dlang.io/is/buRGTs




Very old enhancement request (I doubt this will ever happen): 
https://issues.dlang.org/show_bug.cgi?id=1807


-Steve


Re: How do I convert an ISO 8601 datetime into a unix timestamp - at compile-time?

2020-08-28 Thread Steven Schveighoffer via Digitalmars-d-learn

On 8/27/20 9:54 PM, Andrej Mitrovic wrote:

-
import std.datetime;

void main ()
{
     static time =
SysTime(DateTime.fromISOString("20220101T00")).toUnixTime;
}
-

-
/Library/D/dmd/src/phobos/std/concurrency.d(2574): Error: static 
variable lock cannot be read at compile time
/Library/D/dmd/src/phobos/std/concurrency.d(2574):    called from 
here: atomicLoad(lock)
/Library/D/dmd/src/phobos/std/concurrency.d(2600):    called from 
here: initOnceLock()
/Library/D/dmd/src/phobos/std/concurrency.d(2600):    called from 
here: initOnce(delegate shared(bool)() pure @nogc @safe => init(), 
initOnceLock())
/Library/D/dmd/src/phobos/std/datetime/timezone.d(1106): called from 
here: initOnce(delegate shared(bool)() pure nothrow @nogc @safe => 
(*function () nothrow @nogc @safe => true)())
/Library/D/dmd/src/phobos/std/datetime/timezone.d(546): called from 
here: (*& singleton)()
/Library/D/dmd/src/phobos/std/datetime/systime.d(524): called from here: 
opCall()
/Library/D/dmd/src/phobos/std/datetime/systime.d(472): called from here: 
this.this(dateTime, zero(), tz)
test.d(6):    called from here: SysTime(0L, Rebindable(null, 
)).this(fromISOString("20220101T00"), null)

-

I'm sure there must be a better way to do this. But I couldn't find it 
in the documentation.


It's trying to look up the local timezone at compile time.

You need to specify a time zone:

static time =
SysTime(DateTime.fromISOString("20220101T00"), 
UTC()).toUnixTime;


-Steve


Re: How to get the element type of an array?

2020-08-25 Thread Steven Schveighoffer via Digitalmars-d-learn

On 8/25/20 4:38 AM, Jon Degenhardt wrote:

On Tuesday, 25 August 2020 at 05:02:46 UTC, Basile B. wrote:

On Tuesday, 25 August 2020 at 03:41:06 UTC, Jon Degenhardt wrote:

What's the best way to get the element type of an array at compile time?

Something like std.range.ElementType except that works on any array 
type. There is std.traits.ForeachType, but it wasn't clear if that 
was the right thing.


--Jon


I'm curious to know what are the array types that were not accepted by 
ElementType ( or ElementEncodingType ) ?


Interesting. I need to test static arrays. In fact 'ElementType' does 
work with static arrays. Which is likely what you expected.


Also note that due to autodecoding, ElementType says `dchar` for 
strings. ElementEncodingType should be the choice if you are looking for 
the array element type. But you could also use the techniques specified 
here (and might be less confusing).


But, if std.range is imported, a static array does indeed get a 'front' 
member. It doesn't satisfy isInputRange, but it does have a 'front' 
element.


Because you can't pop the front of a static array. front works because a 
static array automatically casts to a normal array (there is no 
specialized overload for static arrays).


The situation is still confusing though. If only 'std.range.ElementType' 
is imported, a static array does not have a 'front' member, but 
ElementType still gets the correct type. (This is where the 
documentation says it'll return void.)


You are maybe thinking of how C works? D imports are different, the code 
is defined the same no matter how it is imported. *your* module cannot 
see std.range.primitives.front, but the range module itself can see that 
UFCS function.


This is also why ElementType will fail on types that have UFCS front 
defined, but not imported directly from std.range.primitives.


-Steve


Re: __FILE__ and __LINE__ in case of import expression

2020-08-23 Thread Steven Schveighoffer via Digitalmars-d-learn

On 8/23/20 8:42 AM, Andrey Zherikov wrote:

On Saturday, 22 August 2020 at 03:43:10 UTC, Steven Schveighoffer wrote:

On 8/21/20 6:34 PM, Adam D. Ruppe wrote:

On Friday, 21 August 2020 at 22:12:48 UTC, Steven Schveighoffer wrote:
And honestly, if it says the source is "mixin-50, line 1", I think 
people will get it.


I could probably live with that too, but the status quo is pretty 
useful as-is.


I wonder if the compiler could detect when you are using a string 
literal vs. a generated or imported string, and change the behavior 
accordingly.


As far as I understand behavior of this is that mixin() changes __FILE__ 
to point to the location of this mixin. But import expression doesn't do 
so. So if import("file") could change __FILE__ to "file" and __LINE__ to 
1 internally that will make sense IMHO.

I mean something like this:
     //__FILE__='test', __LINE__=1
mixin(  //__FILE__='test-mixin-2', __LINE__=2
     //__FILE__='test-mixin-2', __LINE__=3
import("file")  //__FILE__='file', __LINE__=1   - only inside 
import()  !!!

     //__FILE__='test-mixin-2', __LINE__=5
)
     //__FILE__='test', __LINE__=7



import("file") returns a string, the source of the string is no longer 
available for the compiler after it's done importing it as a string.


However, you can easily use the #line directive to automate this...

string getImport(string file)()
{
   return "#line 1 " ~ file ~ "\n" ~ import(file);
}

mixin(getImport!"file");

-Steve


Re: __FILE__ and __LINE__ in case of import expression

2020-08-21 Thread Steven Schveighoffer via Digitalmars-d-learn

On 8/21/20 6:34 PM, Adam D. Ruppe wrote:

On Friday, 21 August 2020 at 22:12:48 UTC, Steven Schveighoffer wrote:
And honestly, if it says the source is "mixin-50, line 1", I think 
people will get it.


I could probably live with that too, but the status quo is pretty useful 
as-is.


I wonder if the compiler could detect when you are using a string 
literal vs. a generated or imported string, and change the behavior 
accordingly.


-Steve


Re: __FILE__ and __LINE__ in case of import expression

2020-08-21 Thread Steven Schveighoffer via Digitalmars-d-learn

On 8/21/20 5:56 PM, Adam D. Ruppe wrote:

On Friday, 21 August 2020 at 21:42:21 UTC, Steven Schveighoffer wrote:

While not necessarily a "bug", it's not very useful.


Maybe not in this case, but it is perfectly accurate for cases like:

mixin(q{
    some code here
});

Where it will actually line back up to the original file's line number 
perfectly.





Who does that though? Why not just write "some code here" right in the 
file? (I know that the string interpolation DIP might make this more likely)


And honestly, if it says the source is "mixin-50, line 1", I think 
people will get it.


Whereas, if the code is like:

mixin(generateTheMixin());

and it says the line is 67, and line 67 has nothing to do with the mixin 
source or the location it's mixed in, but instead, you need to subtract 
the line number of mixing in from 67 to get the *real* line number, I 
think the utility is really gone at that point.


-Steve


Re: __FILE__ and __LINE__ in case of import expression

2020-08-21 Thread Steven Schveighoffer via Digitalmars-d-learn

On 8/21/20 5:08 PM, Adam D. Ruppe wrote:

On Friday, 21 August 2020 at 21:06:11 UTC, Steven Schveighoffer wrote:
The hybrid line number (original source line number + mixin line 
number) seems like a bug to me.


I'm not so sure without seeing all the code. Remember to the compiler, 
the mixin thing is just a big string literal at the location of the 
import statement.


So it adds the number of \n's in the string literal to the original line 
number to get the mixin line number.


Look at the OP. It says line 22. Neither test.d nor the imported foo.d 
has 22 lines.


While not necessarily a "bug", it's not very useful. The compiler should 
output a useful line number. I shouldn't have to do math to figure out 
what it "really" means.


I'd argue that should be the line number based on the mixin source. The 
file name already is based on the line the string was mixed in, so both 
items contain useful data.


To be fair to the compiler, when you are mixing in an import, the mixin 
doesn't know that the string came from an imported file, so it can't 
really determine the file automatically. But the line number should be 
reasonable.


-Steve


Re: __FILE__ and __LINE__ in case of import expression

2020-08-21 Thread Steven Schveighoffer via Digitalmars-d-learn

On 8/21/20 4:54 PM, Andrey Zherikov wrote:

On Friday, 21 August 2020 at 20:44:27 UTC, Andrey Zherikov wrote:
Thanks for this link! I can use "#line" to fix line number but not 
file name:


file: 'foo.d-mixin-1', line: '6', module: 'test',
function: 'test.main', pretty function: 'int test.main(string[] args)',
file full path: 'C:\Users\andrey\foo.d-mixin-1'


I can actually fix this issue as well.

Changes in test.d:

     test();  // line #16 (1)
     mixin("#line 1 \"foo.d\"\n" ~ import("foo.d"));  // line #17 (2)
     test();  // line #18 (3)

Output:

file: 'test.d', line: '16', module: 'test',
function: 'test.main', pretty function: 'int test.main(string[] args)',
file full path: 'C:\Users\andrey\test.d'
file: 'foo.d', line: '6', module: 'test',
function: 'test.main', pretty function: 'int test.main(string[] args)',
file full path: 'C:\Users\andrey\foo.d'
file: 'test.d', line: '18', module: 'test',
function: 'test.main', pretty function: 'int test.main(string[] args)',
file full path: 'C:\Users\andrey\test.d'


Was just in the process of responding with this technique!

I think what you probably did first is:

int main(string[] args)
{
test();
#line 1 "foo.d"
mixin(import("foo.d"));
return 0;
}

Which sets the line and file of test.d at that point. But when the mixin 
happens, I believe the parser/lexer sets the filename, but does not set 
the line number to something different.


The hybrid line number (original source line number + mixin line number) 
seems like a bug to me.


-Steve


Re: __FILE__ and __LINE__ in case of import expression

2020-08-21 Thread Steven Schveighoffer via Digitalmars-d-learn

On 8/21/20 10:01 AM, Andrey Zherikov wrote:
How can I get __FILE__ and __LINE__ values correct in case of import 
expression?

...


So the output from line #16 (1) is correct although from line #17 (2) is 
not: file name is neither 'test.d' not 'foo.d' and line number is 22 
although both test.d and foo.d are shorter.


You can override the filename and line number to the lexer: 
https://dlang.org/spec/lex.html#special-token-sequence


vibe.d does this so when errors from the trans-piled diet files happen, 
they match (mostly) back to the diet file, not the source file where 
they are mixed in.


I understand that I can create a workaround but want to check first 
whether this is desired behavior or a bug that should be fixed?


That's a good question. I would say it should say line 17 or line 6 
(preferably the latter). That may be considered a bug, I don't know.


-Steve


Re: SIGUSR1 in clock_nanosleep()? how to isolate this issue?

2020-08-20 Thread Steven Schveighoffer via Digitalmars-d-learn

On 8/20/20 2:58 PM, mw wrote:

Hi,

I run into an issue: it's SIGUSR1 in clock_nanosleep()


The GC uses SIGUSR1 (and SIGUSR2). Maybe that's the issue?

https://github.com/dlang/druntime/blob/e1fb19829ebef0419782de43ce4b0e2a1ba140be/src/core/thread/osthread.d#L1946

-Steve


Re: how stdin stream works?

2020-08-19 Thread Steven Schveighoffer via Digitalmars-d-learn

On 8/19/20 1:44 PM, Flade wrote:
Hi everyone! I'm trying to do error handling (with the try block) and 
when I give a wrong value to the variable (it is an integer and I give a 
non-number value), then It doesn't let me re get input. The code:



int x;

bool not_accepted = false;

while (!not_accepted) {

     try {

     write("x: ");

     readf("%d\n", x);

     not_accepted = true;

} catch (Exception msg) {

     writeln("Please give a right coordinate");

     }


Probably readf stops as soon as it encounters an error, meaning that 
your input is still present.


Try instead getting a line via readln, and then trying to read that into 
your expected input.


-Steve


Re: `enum x;` - what is it?

2020-08-19 Thread Steven Schveighoffer via Digitalmars-d-learn

On 8/19/20 10:06 AM, Victor Porton wrote:

This declaration does compile:

enum x;

But what is it? Is it an equivalent of

enum x { }

?

What in the specification allows this looking a nonsense

enum x;

?


I use it as a symbol for UDAs.

enum required;

struct S
{
   @required int x;
}

which can then easily be found.

What is it? I have no idea. I'm just using the name.

I think it's treated as a forward declaration. Kind of like

void foo();

-Steve


Re: Types of lambda args

2020-08-16 Thread Steven Schveighoffer via Digitalmars-d-learn

On 8/16/20 8:27 PM, Adam D. Ruppe wrote:

On Monday, 17 August 2020 at 00:20:24 UTC, Cecil Ward wrote:
In a lambda, how do we know what types the arguments are? In something 
like

    (x) => x * x


In that the compiler figures it out from usage context. So if you pass 
it to a int delegate(int), it will figure x must be int.


It's actually a template, with some special benefits. It relies on IFTI 
to work.


-Steve


Re: Autodecode?

2020-08-16 Thread Steven Schveighoffer via Digitalmars-d-learn

On 8/16/20 4:53 PM, JN wrote:
Related to this thread: 
https://forum.dlang.org/post/xtjzhkvszdiwvrmry...@forum.dlang.org


I don't want to hijack it with my newbie questions. What is autodecode 
and why is it such a big deal? From what I've seen it's related to 
handling Unicode characters? And D has the wrong defaults?


Aside from what others have said, autodecode isn't really terrible as a 
default. But what IS terrible is the inconsistency.


Phobos says char[] is not an array, but the language does.

e.g.:

char[] example;
static assert(!hasLength!(typeof(example))); // Phobos: no length here!
auto l = example.length; // dlang: um... yes, there is.
static assert(!hasIndexing!(typeof(example))); // P: no index support!
auto e = example[0]; // D: yes, you can index.

And probably my favorite WTF:

static assert(is(ElementType!(typeof(example)) == dchar)); // P: char is 
a range of dchar!
foreach(e; example) static assert(is(typeof(e)) == char)); // D: nope, 
it's an array of char


This leads to all kinds of fun stuff. Like try chaining together several 
char[] arrays, and then converting the result into an array. Surprise! 
it's a dchar[], and you just wasted a bunch of CPU cycles decoding them, 
not to mention the RAM to store it.


But then Phobos, as it's telling you that all these things aren't true, 
then goes behind your back and implements all kinds of special cases to 
deal with these narrow strings *using the array interfaces* because it 
performs better.


We will be much better off to be done with autodecoding. And for many 
cases, autodecoding is just fine! Most of the time, you only care about 
the entire string and not what it's made of. Many other languages do 
"autodecoding", and in fact the string type is opaque. But then it gives 
you ways to use it that aren't silly (like concatenating 2 strings knows 
what the underlying types are and figures out the most efficient way 
possible). If `string` was a custom type and not an array, we probably 
wouldn't have so many issues with it.


-Steve


Re: Cannot call @system funciton (stdout)

2020-08-16 Thread Steven Schveighoffer via Digitalmars-d-learn

On 8/16/20 6:07 AM, Simen Kjærås wrote:

On Saturday, 15 August 2020 at 23:59:36 UTC, Joel wrote:
../../JMiscLib/source/jmisc/base.d(176,2): Error: @safe function 
jmisc.base.upDateStatus!string.upDateStatus cannot call @system 
function std.stdio.makeGlobal!"core.stdc.stdio.stdout".makeGlobal
/Library/D/dmd/src/phobos/std/stdio.d(4837,20): 
std.stdio.makeGlobal!"core.stdc.stdio.stdout".makeGlobal is declared here


I got around it by avoiding 'stdout'.


First, what's wrong with using writeln and friends instead of directly 
mucking about with stdout? :p


stdout is __gshared, so it's available on any thread at any time. That's 
not @safe, so it's @system.


If you know you're not using stdout from multiple threads, or don't care 
(it might be perfectly safe even though it's possible to misuse), you 
can use this code:


@property File trustedStdout() @trusted
{
     return stdout;
}

That's a @trusted wrapper that you can call from @safe code. It's not 
actually safe though, as multiple threads could be using trustedStdout 
at the same time. In many use cases, this is unlikely to matter, but 
it's wroth keeping in mind.


Technically, there's nothing unsafe about reading stdout, as long as you 
are not setting it. Otherwise, writeln wouldn't be @safe (as all it does 
is call a private trustedStdout).


The whole thing is messy IMO, and should be revisited.

-Steve


Re: Leaving a pointer to it on the stack

2020-08-13 Thread Steven Schveighoffer via Digitalmars-d-learn

On 8/13/20 4:51 PM, Andre Pany wrote:

On Thursday, 13 August 2020 at 20:11:50 UTC, Steven Schveighoffer wrote:
The garbage collector scans all of the stack as if it were an array of 
pointers. So if you have a pointer to it anywhere on the stack, it 
won't be collected.


However, it only scans threads that the runtime knows about.



If I understand it right, this paragraph doesn't help in my real 
scenario where sample (Dll) is called from a delphi executable.


So in your real world scenario, a non-D thread/program is calling 
sample, and it controls the location of *i? If so, then no, you can't 
depend on D not collecting that data, because D might not scan that 
location.


It is another runtime (delphi). But on the other side, as D GC only runs 
if something new should be allocated on D side, I can safely assume that 
the Delphi caller can access the heap variables? Of course as long as it 
doesn't store the references and use it later...


As long as you aren't allocating again later, yes. You can also disable 
collections and only run them when you know it's safe to do so.


-steve


Re: Leaving a pointer to it on the stack

2020-08-13 Thread Steven Schveighoffer via Digitalmars-d-learn

On 8/13/20 4:04 PM, Andre Pany wrote:

Hi,

in the specification 
https://dlang.org/spec/interfaceToC.html#storage_allocation there is 
this paragraph:
"Leaving a pointer to it on the stack (as a parameter or automatic 
variable), as the garbage collector will scan the stack."


I have some trouble to understand what does this mean. Given this example:

```
import std;

void main()
{
 int* i;
 sample();
 writeln(*i);
}

extern(C) export void sample(int** i)
{
 *i = new int();
 **i = 42;
}
```

Int variable is created on the heap. How do I leave a pointer on the stack?
(In the real coding, sample function will be called from Delphi)



The garbage collector scans all of the stack as if it were an array of 
pointers. So if you have a pointer to it anywhere on the stack, it won't 
be collected.


However, it only scans threads that the runtime knows about.

-Steve


Re: vibe.d and my first web service

2020-08-13 Thread Steven Schveighoffer via Digitalmars-d-learn

On 8/13/20 3:28 AM, WebFreak001 wrote:

On Wednesday, 12 August 2020 at 21:11:54 UTC, Daniel Kozak wrote:

[...]

Unfortunately, I think vibe-d is dead. With every release it is worse 
than before and it seems there is almost no activity. So D really need 
new champion here maybe hunt will be next champion.


Can you give an example how vibe.d gets worse? It's really stable right 
now and while I would enjoy the feature PRs to go in more quickly, I 
think they are pretty well reviewed when they get reviewed and 
eventually once merged it's only good code that makes it in.


The environment just updated and made previous versions more unstable, 
most of which is inherited into current versions too, but these things 
are getting fixed. Like for example a lot of linux distros changed to 
OpenSSL 1.1 which broke HTTPS client calls in vibe.d and was fixed in 
0.8.6 or MongoDB 3.4+ changed a lot of things like indexes which were 
then broken which was fixed in 0.9.0 now though.


I haven't had a really big problem with vibe.d, except for the ctrl-c 
bug (which I've worked around as described).


I agree with the OP of this subthread that it is the most important 
problem for vibe.d (and vibed-core really).


I wish I knew how to fix it...

My experience with getting features into vibe.d has been good, I've 
added a few and Sonke has been very receptive, even if his responses are 
delayed (he must be really busy). I've been there too.


-Steve


Re: DMD: how to restore old unittest+main

2020-08-13 Thread Steven Schveighoffer via Digitalmars-d-learn

On 8/13/20 5:02 AM, Nils Lankila wrote:

On Thursday, 13 August 2020 at 08:49:21 UTC, WebFreak001 wrote:

On Thursday, 13 August 2020 at 07:52:07 UTC, novice3 wrote:

Hello.

I don't use dub.
I use Windows and *.d file association to compile small apps by dmd 
with "-i -unittest -g" switches.
Now i update dmd, and found, that apps compiled with "-unittest" not 
runs main().


How i can restore old behaviour (run all unittests then main())
*without use "--DRT-testmode=run-main" switch every time then i start 
compiled app.exe*?

I want just press Enter on app.d file, then press Enter on app.exe.
Any advises?

Thanks.


Try

version (unittest) extern(C) __gshared string[] rt_options = [ 
"testmode=run-main" ];


Yeah that works but we should really have a way to do this 
programmatically, in a way it is already, but by calling function, not 
by the bias of a string that get parsed.


https://dlang.org/phobos/core_runtime.html#.Runtime.extendedModuleUnitTester

Though I highly recommend using the rt_options mechanism if all you are 
after is the original behavior, it's much simpler.


-Steve


Re: Reading from stdin significantly slower than reading file directly?

2020-08-13 Thread Steven Schveighoffer via Digitalmars-d-learn

On 8/12/20 6:44 PM, methonash wrote:

Hi,

Relative beginner to D-lang here, and I'm very confused by the apparent 
performance disparity I've noticed between programs that do the following:


1) cat some-large-file | D-program-reading-stdin-byLine()

2) D-program-directly-reading-file-byLine() using File() struct

The D-lang difference I've noticed from options (1) and (2) is somewhere 
in the range of 80% wall time taken (7.5s vs 4.1s), which seems pretty 
extreme.


For comparison, I attempted the same using Perl with the same large 
file, and I only noticed a 25% difference (10s vs 8s) in performance, 
which I imagine to be partially attributable to the overhead incurred by 
using a pipe and its buffer.


So, is this difference in D-lang performance typical? Is this expected 
behavior?


Was wondering if this may have anything to do with the library 
definition for std.stdio.stdin 
(https://dlang.org/library/std/stdio/stdin.html)? Does global 
file-locking significantly affect read-performance?


For reference: I'm trying to build a single-threaded application; my 
present use-case cannot benefit from parallelism, because its ultimate 
purpose is to serve as a single-threaded downstream filter from an 
upstream application consuming (n-1) system threads.


Are we missing the obvious here? cat needs to read from disk, write the 
results into a pipe buffer, then context-switch into your D program, 
then the D program reads from the pipe buffer.


Whereas, reading from a file just needs to read from the file.

The difference does seem a bit extreme, so maybe there is another more 
complex explanation.


But for sure, reading from stdin doesn't do anything different than 
reading from a file if you are using the File struct.


A more appropriate test might be using the shell to feed the file into 
the D program:


dprogram < FILE

Which means the same code runs for both tests.

-Steve


Re: __vector(ubyte[32]) misalignment

2020-08-10 Thread Steven Schveighoffer via Digitalmars-d-learn

On 8/10/20 2:53 PM, Bruce Carneal wrote:

No biggee but it looks like there is some duplicate code at the end of 
the __alignPad unittest.


Hah! I think I copy-pasted that intending to write a new test, but then 
tried it separately and found another issue 
(typeid(__vector(ubyte[32])).talign returned 16!)


So I forgot to go back in and delete that case.

Thanks

-Steve


Re: __vector(ubyte[32]) misalignment

2020-08-10 Thread Steven Schveighoffer via Digitalmars-d-learn

On 8/9/20 8:46 AM, Steven Schveighoffer wrote:

On 8/9/20 8:37 AM, Steven Schveighoffer wrote:


I think this has come up before, there may even be a bug report on it.


Found one, I'll see if I can fix the array runtime:

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



Bruce, I have a PR to hopefully fix these issues, if you want to test 
against it:


https://github.com/dlang/druntime/pull/3192

-Steve


Re: Factory pattern for classes

2020-08-09 Thread Steven Schveighoffer via Digitalmars-d-learn

On 8/9/20 10:27 AM, lexxn wrote:

On Sunday, 9 August 2020 at 12:24:05 UTC, Steven Schveighoffer wrote:



Object getClassById(uint id)
{
    if (id == 0) {
    return new A;
    } else if(id == 1) {
    return new B;
    } else {
    return new C;
    }
}



I assume that the correct syntax for the getClassById is
Object getClassById(uint id) {
     if (id == 0) {
     return new A();
     } else if (id == 1) {
     return new B();
     } else {
     return new C();
     }
}
or maybe I'm wrong.


If the constructor has no parameters, classes can be new'd without 
parentheses, so your modification results in identical code as my example.


-Steve


Re: Factory pattern for classes

2020-08-09 Thread Steven Schveighoffer via Digitalmars-d-learn

On 8/9/20 10:58 AM, lexxn wrote:

On Sunday, 9 August 2020 at 12:24:05 UTC, Steven Schveighoffer wrote:


If you know what your class is going to be, I'd just import the file 
that contains it and avoid the whole Object.factory deal. It's going 
to go away anyways.


Not sure if it's a good idea in my case. I'm going to be using all of 
the classes eventually in my loop, but I just need to initialize them in 
a conditional way depending on the use case.


My point is -- it's a good idea to not use Object.factory, because it's 
going to go away.


It doesn't work in all cases anyway.

-Steve


Re: __vector(ubyte[32]) misalignment

2020-08-09 Thread Steven Schveighoffer via Digitalmars-d-learn

On 8/9/20 8:37 AM, Steven Schveighoffer wrote:

I think this has come up before, there may even be 
a bug report on it.


Found one, I'll see if I can fix the array runtime:

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

-Steve


Re: __vector(ubyte[32]) misalignment

2020-08-09 Thread Steven Schveighoffer via Digitalmars-d-learn

On 8/9/20 8:09 AM, Bruce Carneal wrote:

On Sunday, 9 August 2020 at 09:58:18 UTC, Johan wrote:

On Sunday, 9 August 2020 at 01:03:51 UTC, Bruce Carneal wrote:
The .alignof attribute of __vector(ubyte[32]) is 32 but initializing 
an array of such vectors via an assignment to .length has given me 16 
byte alignment (and subsequent seg faults which I suspect are related).


Is sub .alignof alignment expected here?  IOW, do I have to manually 
manage memory if I want alignments above 16?


Do you have a code example?
And what compiler are you using?

-Johan


At run.dlang.io recent runs of both dmd and lcd compilations of the 
below revealed misalignment.


import std;

void main() @safe
{
     alias V = __vector(ubyte[32]); // requires -mcpu=native or other on 
cmd line

     V[] va;
     size_t misalignments;
     foreach(N; 1..101) {
     va.length = N;
     const uptr = cast(ulong)va.ptr;
     misalignments += (uptr % V.alignof) != 0;
     }
     writefln("misaligned %s per cent of the time", misalignments);
}


All blocks in the GC that are more than 16 bytes are aligned by 32 
bytes. You shouldn't have any 16 byte blocks here, because each element 
is 32 bytes long.


However, if your block grows to a page size, the alignment will be 16 
bytes off (due to the metadata stored at the front of the block).


A page size is 4096 bytes. So anything larger than 2048 will require a 
page-sized block or larger.


I would guess that once your array gets longer than 63 elements, 
it's always misaligned?


The current code ensures a 16 byte alignment. That really should go to 
32 (for this reason). I think this has come up before, there may even be 
a bug report on it.


See: 
https://github.com/dlang/druntime/blob/660d911bbd3342c1f1c1478d12e3e943c6038da0/src/rt/lifetime.d#L35


The other thing you can do is avoid allocating using the array runtime, 
and just allocate using the GC calls directly. This means appending 
won't work, and neither will destructors (though that shouldn't be 
important here).


Question for those in the know: are there any other alignments that we 
should ensure are possible?


-Steve


Re: String argument with optional value in std.getopt

2020-08-09 Thread Steven Schveighoffer via Digitalmars-d-learn

On 8/8/20 7:58 PM, Hassan wrote:

Hello

I'm trying to get getopt to recognize an argument that may or may not 
take a value. Here's an example :


../hashtrack --list
../hashtrack --list filter

The problem is that if I point list to a string variable, the first call 
fails with "Missing value for argument --list".


I tried having it point to a callback with an optional second parameter :

void cb(string option, string value = "")
{
     writeln("--list");
     option.writeln();
     value.writeln();
}

But I get the same error. I also tried having two callbacks with the 
same name. The first one takes a single argument, and the second one 
accepts two :


void cb(string option)
{
     writeln("--list");
     option.writeln();
}

void cb(string option, string value)
{
     writeln("--list");
     option.writeln();
     value.writeln();
}

But it only calls the first one. I'm using DMD64 D Compiler v2.090.0. 
Any pointers ?


getopt doesn't support optional parameters.

Two things I can think of:

1. Have 2 options that do the same thing, but only one accepts a 
parameter (e.g. `--list` and `--listf filter`)
2. If your optional parameters are not tied to the option itself, then 
don't accept them via getopt. In other words, if `hashtrack filter` is 
supposed to be valid, then filter isn't an option after all, it's a 
standard parameter.


-Steve


Re: Factory pattern for classes

2020-08-09 Thread Steven Schveighoffer via Digitalmars-d-learn

On 8/9/20 5:16 AM, lexxn wrote:

I'm trying to get the factory pattern going with classes
class A {}

class B {}

class C {}

auto getClassById(uint id)
{
     if (id == 0) {
     return cast(A)Object.factory("A");
     } else if(id == 1) {
     return cast(B)Object.factory("B");
     } else {
     return cast(C)Object.factory("C");
     }
}

I'm getting 2 errors:
main.d(69): Error: Expected return type of main.A, not main.B:
main.d(67):    Return type of main.Ainferred here.


Change your return type to Object.

Also is it possible to completely skip the getClassById function and if 
I've and array string classes = ["A", "B"] to just 
cast(classes[0])Object.factory(classes[0]);. I understand that I need to 
cast classes[0].


This won't work.

If you know what your class is going to be, I'd just import the file 
that contains it and avoid the whole Object.factory deal. It's going to 
go away anyways.


In other words:

Object getClassById(uint id)
{
if (id == 0) {
return new A;
} else if(id == 1) {
return new B;
} else {
return new C;
}
}

-Steve


Re: problem using std.format on Arm

2020-08-08 Thread Steven Schveighoffer via Digitalmars-d-learn

On 8/8/20 1:00 PM, Jeremiah Glover wrote:

What can I do to fix this and get the most recent version of phobos that 
will compile?


You are using an old version of the compiler. formattedRead used to 
accept only pointers, not by ref.


See https://github.com/dlang/phobos/pull/5009

Try doing:
formattedRead(line, "%d\t%s", , );

Figure out which version of the compiler you have, and then use the docs 
for that version by downloading the compiler and using the local html 
documentation.


Alternatively, see if you can find a newer compiler that suports ARM.

-Steve


Re: iopipe code to count lines in gzipped file works with v 0.1.7 but fails with 0.2.1

2020-08-07 Thread Steven Schveighoffer via Digitalmars-d-learn

On 8/7/20 9:31 PM, Steven Schveighoffer wrote:

On 8/7/20 8:57 PM, Steven Schveighoffer wrote:
I think this is an issue with dub when using an inline recipe file, 
but I don't know?


ugh. This is an issue with iopipe specifying io version 0.2.x. I will 
fix this.


OK, iopipe 0.2.2 is released, with no specific io dependency.

It should work with io 0.3.1 as a separate listed dependency.

-Steve


Re: iopipe code to count lines in gzipped file works with v 0.1.7 but fails with 0.2.1

2020-08-07 Thread Steven Schveighoffer via Digitalmars-d-learn

On 8/7/20 8:57 PM, Steven Schveighoffer wrote:

I tried adding

dependency "io" version="~>0.3.0"

But it fails with:

Got no configuration for dependency io ~>0.3.1 of hello ~master!?

If I add

dependency "io" version="*"

it works.

I think this is an issue with dub when using an inline recipe file, but 
I don't know?


ugh. This is an issue with iopipe specifying io version 0.2.x. I will 
fix this.


-Steve


Re: iopipe code to count lines in gzipped file works with v 0.1.7 but fails with 0.2.1

2020-08-07 Thread Steven Schveighoffer via Digitalmars-d-learn

On 8/7/20 9:40 AM, Andrew wrote:

Hi,

This code to count lines in a gzipped file exits with "Program exited 
with code -9" when run with the latest version of the library, I guess 
because I am doing unsafe things.


BTW the safety improvements only change whether it compiles as @safe or not.

If it's building but running is exiting with a code then it's possible 
there's a bug somewhere.


I did have to change a lot of code to get it to build properly.

If you have it building, but it's exiting with an error, then please 
file an issue with an example file and sample source that causes the issue.


-Steve


Re: iopipe code to count lines in gzipped file works with v 0.1.7 but fails with 0.2.1

2020-08-07 Thread Steven Schveighoffer via Digitalmars-d-learn

On 8/7/20 9:40 AM, Andrew wrote:

Hi,

This code to count lines in a gzipped file exits with "Program exited 
with code -9" when run with the latest version of the library, I guess 
because I am doing unsafe things. Could someone tell me how to change it 
to make it work? The actual program I'm writing processes a file line by 
line, so ideally I'd like to keep the structure of open a file, then 
foreach over it.


Thanks very much


As of iopipe v0.2.0, io is no longer a required dependency, it's 
optional. So you must also add a dependency for io.


I tried adding

dependency "io" version="~>0.3.0"

But it fails with:

Got no configuration for dependency io ~>0.3.1 of hello ~master!?

If I add

dependency "io" version="*"

it works.

I think this is an issue with dub when using an inline recipe file, but 
I don't know?


Note that in this simple example, the line count is stored in the line 
pipe, you can retreive the number of lines by accessing the `segments` 
member of the pipe (undocumented, I have to fix that). So my code looks 
like:


---
/+ dub.sdl:
name "hello"
dependency "iopipe" version="~>0.2.0"
dependency "io" version="*"
+/

import std.stdio;
//import std.typecons; // refCounted not @safe
import iopipe.textpipe;
import iopipe.zip;
import iopipe.bufpipe;
import iopipe.refc; // refCounted that is @safe
import std.io : File = File; // just a note, I don't know why you are 
renaming here...


void main() @safe // yay @safe!
{
  auto counter = 0;
  auto fileToRead = File("file.gz").refCounted.bufd
  .unzip(CompressionFormat.gzip)
  .assumeText
  .byLine;

  fileToRead.process();
  writeln(fileToRead.segments);
}
---

FYI, I noticed that in my simple test, this outputs one less than the 
actual lines. I'll have to look into *that* too.


That dependency on writeln also irks me ;) I need to get working on that 
iopipe replacement for it...


-Steve


Re: Is there an alternative of `go get`

2020-08-07 Thread Steven Schveighoffer via Digitalmars-d-learn

On 8/7/20 3:28 AM, Cogitri wrote:

On Friday, 7 August 2020 at 07:17:25 UTC, Ky-Anh Huynh wrote:

Hi everyone,

`go get` in Golang world has a simple way to fetch and install binary

```
$ go get github/foo/bar.git
$ export PATH=$PATH:$(go env GOPATH)/bin
$ bar --help
```

This saves a lot of time and setup. Is that an alternative when using 
dub?




Hello,

you can use `dub build $name` to build the package. The resulting binary 
should be in $HOME/.dub/$name-$version/$name/bin then. You can also run 
the binary via `dub run $name -- $additional_args`, then you won't have 
to add that path to your PATH. If you haven't run `dub build $name` 
previously, `dub run $name` will do that for you.


Having a way to configure the path would be really helpful. I'll add a 
request for dub.


-Steve


Re: Non-recursive maxSizeOf

2020-08-06 Thread Steven Schveighoffer via Digitalmars-d-learn

On 8/6/20 9:23 AM, Adam D. Ruppe wrote:

On Thursday, 6 August 2020 at 13:18:40 UTC, Per Nordlöw wrote:

    mixin(T.stringof ~ " _store" ~ T.mangleof ~


Never ever use mixin(T.stringof). Always just use mixin("T") instead.

mixin("T _store", T.mangleof /* or just idx is gonna be better */,";");

Though I doubt this is going to win a benchmark anyway getting this 
complicated.


Well, one *could* do:

static if(is(union { Ts t; }))

and use the union for "normal" cases.

I think the CTFE solution is cleaner. Is there a good reason to avoid it?

-Steve


Re: std.conv.ConvException from double to uint64_t, but only locally in a large project

2020-08-04 Thread Steven Schveighoffer via Digitalmars-d-learn

On 8/4/20 2:15 PM, Steven Schveighoffer wrote:

I'll file a bug.


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

-Steve


Re: std.conv.ConvException from double to uint64_t, but only locally in a large project

2020-08-04 Thread Steven Schveighoffer via Digitalmars-d-learn

On 8/4/20 1:36 PM, drathier wrote:

I'm getting a crash when I'm converting a double to an uint64_t.

```
std.conv.ConvException@/usr/local/opt/dmd/include/dlang/dmd/std/conv.d(2054): 
Value (1596) does not match any member value of enum '__c_ulonglong'

```

I've narrowed down the code to this:
```
static import std.conv;
double thing = 42.0;
std.conv.to!(uint64_t)(thing);
```
which works just fine on https://run.dlang.io/ or in a single-file dmd 
invocation. When I compile and run it locally on my mac as part of a 
specific large app using dub, it always crashes like this.


Where would I even start debugging this?

DMD64 D Compiler v2.093.0
DUB version 1.22.0, built on Jul  9 2020



So a common way to typedef something is to use enum:

enum uint64_t : ulong;

This gives you a new type that works pretty much just like ulong, but 
will not implicitly convert from ulong.


However, std.conv.to is likely interpreting this as an enumeration type, 
where it has to match one of the enum members. But since this isn't an 
enumeration in the standard way, it fails (it has no members!)


This code reproduces the problem on run.dlang.io:

void main()
{
import core.stdc.config;
import std.conv;
auto x = 0.5;
auto y = x.to!__c_ulonglong;
}

Note the code in druntime which defines __c_ulonglong: 
https://github.com/dlang/druntime/blob/0db2e65bba7cc319309bd32957763882870d5b03/src/core/stdc/config.d#L121


I'll file a bug.

-Steve


Re: Template functions inside interface

2020-08-04 Thread Steven Schveighoffer via Digitalmars-d-learn

On 8/4/20 9:39 AM, Adam D. Ruppe wrote:

On Tuesday, 4 August 2020 at 13:36:15 UTC, Zans wrote:
Is there any way to declare template functions inside interface and 
then override them in a class?


No, the templates in the interface are automatically considered `final`. 
So the body must be in the interface too to avoid that undefined 
reference error.


You can have them forward to normal methods in the interface though, 
just there needs to be a fixed number of them with concrete types.


I was kind of surprised the compiler didn't complain about override 
there. Is override ever a valid attribute for a template function? Is 
there a reason we ignore it for templates?


I can imagine a lot of confusion for something like:

import std.stdio;

interface MyInterface
{
T doAndReturnSomething(T)(T param){return T.init;}
}

class MyClass : MyInterface
{
override T doAndReturnSomething(T)(T param)
{
return param;
}
}

void main()
{
MyInterface myClass = new MyClass();
writeln(myClass.doAndReturnSomething("Hello"));
}

Which compiles, runs, and prints nothing.

-Steve


Re: safety and auto vectorization

2020-08-03 Thread Steven Schveighoffer via Digitalmars-d-learn

On 8/3/20 3:22 PM, Bruce Carneal wrote:


Thanks Steve (and Chad).  Summary: underspecified, varying behavior 
across versions, buggy.


Steve, what's the best way for me to report this?  Are spec issues 
lumped in with the other bugzilla reports?


Yep. You can file under dlang.org with the spec keyword.

Although this looks like it's not exactly a spec issue. I'd start it as 
a dmd bug (I don't know the exact interaction with the compiler and the 
library). It might also be a druntime bug.


-Steve


Re: safety and auto vectorization

2020-08-03 Thread Steven Schveighoffer via Digitalmars-d-learn

On 8/2/20 1:31 PM, Bruce Carneal wrote:

import std;

void f0(int[] a, int[] b, int[] dst) @safe {
     dst[] = a[] + b[];
}

void f1(int[] a, int[] b, int[] dst) @trusted {
     const minLen = min(a.length, b.length, dst.length);
     dst[0..minLen] = a[0..minLen] + b[0..minLen];
     assert(dst.length == minLen);
}

I was surprised that f0 ran just fine with a.length and b.length geq 
dst.length.  Is that a bug or a feature?


Assuming it's a feature, are f0 and f1 morally equivalent?  I ask 
because f1 auto-vectorizes in ldc while f0 does not.  Not sure why.  As 
a guess I'd say that the front end doesn't hoist bounds checks in f0 or 
at least doesn't convey the info to the back end in a comprehensible 
fashion.  Non-guesses welcome.


First, I think this is a bug. A regression in fact. As of 2.077 this 
works, and before it did not. There is nothing in the spec that says the 
behavior is defined for this case.


Second, it's more than just that. This also runs currently:

void main()
{
auto a = [1, 2, 3];
auto b = [4, 5, 6];
int[] dst = new int[4]; // note the extra element
dst[] = a[] + b[];
writeln(dst[3]);
}

Prior to 2.077, this fails with array length problems.

After that it prints (at the moment): 402653184

If I up the size to 5, it fails with a range violation. I strongly 
suspect some off-by-one errors, but this looks unsafe.


-Steve


Re: Idiomatic D code to avoid or detect devision by zero

2020-08-03 Thread Steven Schveighoffer via Digitalmars-d-learn

On 8/3/20 5:53 AM, Martin Tschierschke wrote:

On Friday, 31 July 2020 at 14:18:15 UTC, Steven Schveighoffer wrote:

On 7/31/20 9:55 AM, Martin Tschierschke wrote:

What would be the idiomatic way to write a floating point division
occuring inside a loop and handle the case of division by zero.

c = a/b; // b might be zero sometimes, than set c to an other value (d).

(In the moment I check the divisor being zero or not, with an 
if-than-else structure,

but I find it ugly and so I ask here.)


c = b == 0 ? d : a/b;

I don't think a function would be shorter or clearer...

c = div(a, b, d);

Alternatively, you could use a type to effect the behavior you want.



Thanks, for the hints.
I find the ? :  - expressions sometimes hard to reed, especially when a 
and b are not so  simple expressions.


I prefer putting additional bracket around:
c = (b_expression == 0) ? (d_longer_expression) : 
(a_expression/b_expression);


Yes, that is fine, and up to your preference. You may actually need the 
parentheses if the expressions somehow override the precedence of the ?: 
operator.


Even with symbol uses, I personally would do actually:

c = (b == 0 ? d : a/b);

Just because the ` = b == ` looks really bad to me.

-Steve


Re: dynamic array .length vs .reserve - what's the difference?

2020-08-01 Thread Steven Schveighoffer via Digitalmars-d-learn

On 7/31/20 12:32 PM, wjoe wrote:
On Friday, 31 July 2020 at 04:28:57 UTC, Ali Çehreli wrote: 
Another option, which is curiously said to be more performant in 
memory allocation than native arrays, is std.array.Appender. I've used 
function-local static Appenders to cut down on memory allocation. Here 
is an uncompiled pseudo code:


[...]


This looks like an even better way to do it.

Thanks, Ali :)


Just FYI, the reason this is faster is because there is no need to go 
through the opaque calls into druntime to figure out if 
appending-in-place is possible. The reserved length is stored directly 
in the struct.


-Steve


Re: Idiomatic D code to avoid or detect devision by zero

2020-07-31 Thread Steven Schveighoffer via Digitalmars-d-learn

On 7/31/20 9:55 AM, Martin Tschierschke wrote:

What would be the idiomatic way to write a floating point division
occuring inside a loop and handle the case of division by zero.

c = a/b; // b might be zero sometimes, than set c to an other value (d).

(In the moment I check the divisor being zero or not, with an 
if-than-else structure,

but I find it ugly and so I ask here.)


c = b == 0 ? d : a/b;

I don't think a function would be shorter or clearer...

c = div(a, b, d);

Alternatively, you could use a type to effect the behavior you want.

-Steve


Re: dynamic array .length vs .reserve - what's the difference?

2020-07-30 Thread Steven Schveighoffer via Digitalmars-d-learn

On 7/30/20 11:58 AM, wjoe wrote:

I just stumbled upon code like this:

struct Foo(T)
{
     T[] b;

     this(int n)
     {
     b.reserve(n);
     b.length = n;
     }
}

..reserve looks redundant.


It is, in this case. Reserve will extend the allocated length to n, but 
not adjust the slice, and setting the length will adjust the slice and 
consume that data from the block. Just setting length has the same effect.




The docs are explaining .length nicely, however lack any specifics about 
reserve.


Changing the length of an array may relocate and copy. New items are 
initialized with T.init - is that true for both length and reserve ?


reserve preallocates data for use in appending, but does not alter the 
length of the specified array.


It's like saying, "I'm going to append enough elements to this array so 
the total length is N." It's very much tied to appending.


Note that reserve may do nothing, if there is already at least N 
elements available.



Also there's .capacity - is that equivalent to reserve ?


Capacity tells you how many total elements the current reserved space 
can hold. If the array is not appendable, then this returns 0.


Another curiosity I noticed is that the docs say that the runtime tries 
to resize in place, however:


b = b[0..$-1]; if length==1 seems to collect the memory at once because 
if it's immediately followed by b.length = 1; or b ~= someT; b.ptr 
points to a new address.

Why ?


Because you would be overwriting the data already in the array.

For example:

auto a = b;
b = b[0 .. $-1];
b ~= someT;

If that last line is done in-place, then it overwrites a[$-1].

If you know that it's OK to do this, then you should call 
assumeSafeAppend on the array (which will adjust the "used" space down 
to the current array).



I know that b=b[0..0]; is equivalent to b = null;


No, if slicing b to b[0 .. 0], b.ptr does not change. b = null sets the 
pointer to null. In the former case, if you called assumeSafeAppend on 
it, then it could append in-place at that point. With the null pointer, 
it would reallocate.


-Steve


Re: dub build to generate different kinds of libs

2020-07-28 Thread Steven Schveighoffer via Digitalmars-d-learn

On 7/28/20 5:50 PM, jeff thompson wrote:

Hello

Im brand new to D (loving it btw!) and have decided to build a largish 
windows project in the language. First question, is there a dub.json 
setup to have a dub build to generate multiple binaries in one call? 
Like a dll and a static lib. Seems like it would be easy maybe im 
missing something obvious? Like a configuration with multiple targetTypes.


Yes, just do that (make multiple configurations)

You just have to build them separately:

dub build --config=library
dub build --config=application

-Steve


Re: Why are std.bitmanip.bitfields so big ?

2020-07-28 Thread Steven Schveighoffer via Digitalmars-d-learn

On 7/28/20 5:46 AM, MoonlightSentinel wrote:

On Tuesday, 28 July 2020 at 09:28:27 UTC, wjoe wrote:
It was run on the doc page. I suppose the examples are wrapped in a 
unittest block?


Indeed, see 
https://github.com/dlang/phobos/blob/cd2ba0d2c378a893ec0eaefc57b87d0770a1990c/std/bitmanip.d#L293-L314 



It doesn't necessarily need to be in a unittest block (AFAIK, the 
example executer isn't actually running the unittests of phobos), but it 
does need to be inside a function, because you have executable code 
there. Either way, yes, it's run inside a function, so you need to apply 
static to the struct to avoid the frame pointer. I tested that, and it 
prints 1 instead of 16.


-Steve


Re: Help with Ranges

2020-07-27 Thread Steven Schveighoffer via Digitalmars-d-learn

On 7/27/20 1:10 PM, Charles wrote:

Still, I'm confused since, as 
far as I know, map wraps its source, i.e. the array in this case, which 
is sortable. It seems to me the only reason I can't sort MapResult is 
because it doesn't have the proper interface.


Let's talk about a concrete example, so you can see why:

int[] arr = [21, 83, 45, 60];

auto m = arr.map!(a => a % 10);

Sort is going to look at m as a random-access range of integers. But the 
integer you get from m[2] for instance is going to be 5. So you can 
compare e.g. m[2] and m[3] (5 and 0), but how do you *WRITE* back to the 
original array? All you have as an interface is non-writable 5 and 0, 
not the original array members 45 and 60. In other words, if you swapped 
5 and 0, map can't do the inverse transform here (and even if it could, 
0 and 5 map to millions of possible original values).


What it seems like you are possibly interested in doing is to sort the 
original array based on a transformation. But in your original post you 
said "doSomething is some predicate that does a lot of processing on 
each element", so I assumed, e.g. something like this is not valid for 
your use case:


arr.sort!((a, b) => doSomething(a) < doSomething(b))

as it would be very expensive assuming doSomething is expensive.

You can use H.S. Teoh's suggestion and use schwartzSort (in fact, it 
does something almost exactly the same as what I wrote, except it sorts 
the original elements).


However, for something like a % 10, I'd much rather just do it without 
allocating another array.


So it really depends on what your requirements are, which you haven't 
fully identified.


-Steve


Re: Why are std.bitmanip.bitfields so big ?

2020-07-27 Thread Steven Schveighoffer via Digitalmars-d-learn

On 7/27/20 5:49 AM, wjoe wrote:

struct A
{
     mixin(bitfields!(
    bool, "flag1",    1,
    bool, "flag2",    1,
    uint, "", 6));
}


Is this inside a function? If so, put `static` on it.

What you are seeing is the 8-byte frame pointer that comes from inner 
structs so you can access stack variables inside the struct.


-Steve


Re: Help with Ranges

2020-07-26 Thread Steven Schveighoffer via Digitalmars-d-learn

On 7/26/20 3:10 AM, Charles wrote:
Suppose I have the following line of code where arr is an array, 
doSomething is some predicate that does a lot of processing on each 
element, sort must come after the mapping, and there are more operations 
done to the range after sort:


arr.map!doSomething.sort. ...;

Sort fails to instantiate because the range it's receiving doesn't 
support element swapping. This may and might be resolved by calling array:


arr.map!doSomething.array.sort. ...;

However, this might trigger an allocation, and there's still more to do! 
Is there something I'm missing with regards to ranges that could help me 
make the first line work without using array, or is it more of an issue 
with my code's design?


That is what you need to do.

A map that returns an lvalue would be sortable, but you would be sorting 
the processed elements, and probably not the original elements.


I have found this handy tool quite useful in my code where I need a 
temporary array:


// creates a concrete range (std.container.array.Array range) out of the
// original range that is eagerly fetched, and then can be processed, 
without

// allocating extra garbage on the heap.
auto concreteRange(Range)(Range r)
{
import std.range : ElementType;
import std.container.array : Array;
return Array!(ElementType!Range)(r)[];
}

Slicing an Array will keep the reference count correctly, and destroy 
the memory automatically after you're done using it. So it's perfect for 
temporary arrays in pipelining.


-Steve


Re: Returning range of inout objects from inout method

2020-07-25 Thread Steven Schveighoffer via Digitalmars-d-learn

On 7/25/20 4:07 PM, Steven Schveighoffer wrote:

On 7/25/20 3:16 PM, FreeSlave wrote:

On Saturday, 25 July 2020 at 14:19:15 UTC, Steven Schveighoffer wrote:


The only way to do this without code duplication (but with generated 
code duplication) is to template the byAction function on the type of 
`this`:


auto byAction(this This)() { /* same implementation */ }

Note that this ONLY works if your base range type is an array. If you 
have a custom range type, you need to parameterize that based on the 
constness of `This`.




Thanks. I thought this template is useful only in inheritance.
Is constness of member function inferred automatically in this case?


In this case, yes. I don't know actually if this is documented.


It should be now.

https://github.com/dlang/dlang.org/pull/2835

-Steve


Re: Returning range of inout objects from inout method

2020-07-25 Thread Steven Schveighoffer via Digitalmars-d-learn

On 7/25/20 3:16 PM, FreeSlave wrote:

On Saturday, 25 July 2020 at 14:19:15 UTC, Steven Schveighoffer wrote:


The only way to do this without code duplication (but with generated 
code duplication) is to template the byAction function on the type of 
`this`:


auto byAction(this This)() { /* same implementation */ }

Note that this ONLY works if your base range type is an array. If you 
have a custom range type, you need to parameterize that based on the 
constness of `This`.




Thanks. I thought this template is useful only in inheritance.
Is constness of member function inferred automatically in this case?


In this case, yes. I don't know actually if this is documented.

-Steve


Re: Returning range of inout objects from inout method

2020-07-25 Thread Steven Schveighoffer via Digitalmars-d-learn

On 7/25/20 8:26 AM, FreeSlave wrote:
I want to be able to return a range of const objects from the const 
object and a range mutable objects from the mutable object.


inout comes to mind, but not applicable in this case, because inout must 
be applied to the return type as whole, which does not make much sense 
for the range. Defining range of inout objects does not work too. See 
the example.


import std.range;
class A
{
     string name;
}

class B
{
     A[] _actions;
     ForwardRange!(inout(A)) byAction() inout { // can't instance this type
     import std.algorithm : filter;
     return inputRangeObject(_actions.filter!(a => a !is null && 
a.name.length));

     }
}

So how can I achieve the intended effect without code duplication? (like 
making separate mutable and const versions of the method).


You can't exactly. The limitation that inout cannot be applied to a 
struct member is a crappy limitation, one which I wish I never advocated 
for.


The only way to do this without code duplication (but with generated 
code duplication) is to template the byAction function on the type of 
`this`:


auto byAction(this This)() { /* same implementation */ }

Note that this ONLY works if your base range type is an array. If you 
have a custom range type, you need to parameterize that based on the 
constness of `This`.


-Steve


Re: Feedback to stdout when a specific unittest is run

2020-07-23 Thread Steven Schveighoffer via Digitalmars-d-learn

On 7/23/20 11:10 AM, Per Nordlöw wrote:
Is it possible to activate some feedback print to stdout when a unittest 
is started and ended to track which unittests that take the longest to 
execute?


Alternatively inject a hook being run before each test is run.


Yes, you can copy the code [1], and handle the unittest runtime yourself 
[2], putting in whatever outputs you wish.


-Steve

[1] 
https://github.com/dlang/druntime/blob/d19c70b6130d70e6d727cd573230e4519eb0ef55/src/core/runtime.d#L602-L641
[2] 
https://dlang.org/phobos/core_runtime.html#.Runtime.extendedModuleUnitTester


Re: Alternative to std.range.choose

2020-07-22 Thread Steven Schveighoffer via Digitalmars-d-learn

On 7/22/20 12:33 AM, James Gray wrote:

Is there a better way to achieve behaviour similar to rangeFuncIf
below? f gives a contrived example of when one might want this. g is
how one might try and achieve the same with std.range.choose.

import std.stdio;
import std.range : only, chain, join, choose;
import std.algorithm : map;

auto rangeFunctIf(alias F1, alias F2)(bool c)
  if ( __traits(compiles,F1().chain(F2(
{
    return only(true).repeat(c?1:0).map!(x=>F1()).join
   .chain(only(true).repeat(c?0:1).map!(x=>F2()).join);
}

auto f(ulong n) {
  return (n!=0uL).rangeFuncIf!(()=>only(100/n), ()=>only(0));
}
auto g(ulong n) {
  return choose(n!=0uL,only(100/n),only(0));
}

void main()
{
  writeln(f(2));
  writeln(f(0));
  writeln(g(2));
  //writeln(g(0)); < runtime error
}


I know this is a contrived example, but choose is not good for such a 
thing. It should only be used if the range types are different.


g could be:

auto g(ulong n) {
  return only(n != 0L ? 100/n : 0)
}

But in any case, changing choose to use lazy is probably a good answer.

-Steve


Re: miscellaneous array questions...

2020-07-21 Thread Steven Schveighoffer via Digitalmars-d-learn

On 7/21/20 8:34 AM, Adam D. Ruppe wrote:

The others aren't wrong about stack size limits playing some role, but 
the primary reason is that it is a weird hack for @safe, believe it or not.

...
I don't recall exactly when this was discussed but it came up in the 
earlier days of @safe, I'm pretty sure it worked before then.


I think this was discussed, but was not the reason for the limitation. 
The limitation exists even in D1, which is before @safe: 
https://digitalmars.com/d/1.0/arrays.html#static-arrays


I have stressed before that any access of a pointer to a large object in 
@safe code should also check that the base of the object is not within 
the null page (this is not currently done). This is the only way to 
ensure safety.


-Steve


Re: std/process.d: nothrow functions which throw (in struct ProcessPipes)

2020-07-21 Thread Steven Schveighoffer via Digitalmars-d-learn

On 7/21/20 8:49 AM, Adam D. Ruppe wrote:

On Tuesday, 21 July 2020 at 12:44:23 UTC, Drone1h wrote:

Would it be possible to explain this, please ?


nothrow only applies to Exception and its children. Error is a different 
branch.


Error means you have a programming error and cannot be caught and 
recovered (though the compiler allows it anyway, it reserves the right 
to just abort the program instead of actually going through the 
try/catch system), so it doesn't count as a normal exception, even 
though it is still thrown.


You are supposed to prevent Errors by fixing the bugs in your code, so 
in a final build they never happen.


We need a way to mark posts like "I got this one", so we don't spend the 
same time saying the same thing lol.


-Steve


Re: std/process.d: nothrow functions which throw (in struct ProcessPipes)

2020-07-21 Thread Steven Schveighoffer via Digitalmars-d-learn

On 7/21/20 8:44 AM, Drone1h wrote:

Hello All,

In phobos/std/process.d, in the ProcessPipes struct, we can see a few 
functions which are marked with "nothrow", but which (under some 
conditions) throw:


     @property File stdout() @safe nothrow
     {
     if ((_redirectFlags & Redirect.stdout) == 0)
     throw new Error("Child process' standard output stream 
hasn't "

     ~"been redirected.");
     return _stdout;
     }

Would it be possible to explain this, please ? Or point me to some 
relevant documentation, please ?


Thank you.


nothrow only pertains to Exceptions, not Errors.

Throwing an Error isn't guaranteed to unwind the stack properly (which 
is why it can be done within nothrow), and the program should exit if it 
ever happens. An Error is a programming mistake (it should never happen 
if you wrote your code correctly), whereas an Exception can happen due 
to environmental issues or user input.


-Steve


Re: miscellaneous array questions...

2020-07-21 Thread Steven Schveighoffer via Digitalmars-d-learn

On 7/21/20 7:10 AM, IGotD- wrote:

On Monday, 20 July 2020 at 22:05:35 UTC, WhatMeWorry wrote:


2) "The total size of a static array cannot exceed 16Mb" What limits 
this? And with modern systems of 16GB and 32GB, isn't 16Mb excessively 
small?   (an aside: shouldn't that be 16MB in the reference instead of 
16Mb? that is, Doesn't b = bits and B = bytes)




I didn't know this but it makes sense and I guess this is a constraint 
of the D language itself. In practice 16MB should be well enough for 
most cases. I'm not sure where 16MB is taken from, if there is any OS 
out there that has this limitation or if it was just taken as an 
adequate limit.


I believe it stems from a limitation in the way the stacks are 
allocated? Or maybe a limitation in DMC, the basis for DMD.


Also, you CAN actually have larger arrays, they just cannot be put on 
the stack (which most static arrays are):


struct S
{
ubyte[17_000_000] big;
}

void main()
{
auto s = new S; // ok
S s; // crash (signal 11 on run.dlang.io)
}

This may not work if `big` had a static initializer, I'm not sure.

-Steve


  1   2   3   4   5   6   7   8   9   10   >