Re: Questions about D

2020-11-27 Thread Steven Schveighoffer via Digitalmars-d-learn

On 11/27/20 2:56 PM, Walter wrote:

On Friday, 27 November 2020 at 19:46:52 UTC, Ola Fosheim Grostad wrote:

Why not? What are you looking for?

I'm looking for a general purpose which I can use everywhere


Depends on how you define "everywhere".

If you mean can it be used in all manner of purposes, yes, it can. It is 
used in video games, in web development, in command line tools, high 
performance computing, server software, etc.


If you mean can it be used on all the platforms you want to use, it 
depends on the platform. In general, if gcc or llvm supports your 
platform, you can probably get it to work. Some platforms are not as 
mature in D as others, or may require more effort.


So it's hard to definitively answer your question.

-Steve


Re: vibe.d and my first web service

2020-11-27 Thread Steven Schveighoffer via Digitalmars-d-learn

On 8/12/20 9:46 AM, James Blachly wrote:

On 7/18/20 8:16 AM, Andre Pany wrote:

On Saturday, 18 July 2020 at 09:10:04 UTC, Mr. Backup wrote:

 >> ...
I started the program with "dub" command and everything worked as I 
expected. Except that there were a lot "deprecation" warnings and 
long time to compile.But when I exit the service by ctrl + c and 
start again the program cannot start again with error message:

...


I assume you are using vibe.d 0.8.4 or older. Please check whether 
adding this to dub.json solves your problem:


​"versions": [ "VibeHighEventPriority" ]

(Restart your pc)

Vibe.d 0.9 0 will be released soon. I hope it will work out of the box 
there.


Unfortunately the problem still occurs with Vibe.d 0.9.0

IMO **this is the single most important problem to fix** for vibe.d -- 
if the most basic of examples (indeed, supplied by dub itself) fails so 
spectacularly, the casual new user will not spend the time to find out 
why this is happening, but instead move on. The ctrl-C non-termination 
bug has existed since at least 2015 from what I can tell from the forums.


Tangent:

Does Sönke have a Patreon or the project an OpenCollective etc. ? I 
would be willing to support fixing of some of these bugs.


Alternatively, could we vote on whether a web framework is worthy of 
foundation support? Having an ergonomic, workable web framework is 
absolutely essential to surviving as a language in 2020 (notable 
exception being 800# gorilla incumbents C/C++).


FYI, this bug was just fixed (eventcore version 0.9.11). I tested it and 
it works.


Thanks Sönke for fixing this!

-Steve

https://github.com/vibe-d/vibe-core/issues/205


Re: How to unit-test a phobos module?

2020-11-26 Thread Steven Schveighoffer via Digitalmars-d-learn

On 11/25/20 7:17 PM, Q. Schroll wrote:

On Wednesday, 25 November 2020 at 21:57:12 UTC, H. S. Teoh wrote:
On Wed, Nov 25, 2020 at 09:49:12PM +, Paul Backus via 
Digitalmars-d-learn wrote:

On Wednesday, 25 November 2020 at 21:16:06 UTC, Q. Schroll wrote:
> On Wednesday, 25 November 2020 at 21:11:24 UTC, Paul Backus > wrote:
> > On Wednesday, 25 November 2020 at 20:58:20 UTC, Q. Schroll > > 
wrote:

> > > My setup:
> > > * A fresh DMD installed a few minutes ago.
> > > * Clone of my Phobos fork with up-to-date changes from
> > > dlang/phobos/master.
> > > > Do you have clones of dmd and druntime too?
> > Why would I need those? I haven't needed them back then.

copyEmplace isn't in druntime 2.094.2.


My guess is that the problem is caused by trying to compile Phobos 
with a compiler that uses an incompatible version of druntime.


One of the issues is, I don't know what DRuntime really is. As far as I 
understand on the surface-level, it's functionality one would expect to 
be implemented by the compiler, but actually implemented in plain D 
code. A low-level Phobos if you want. So I'm a little confused why 
there's even a need for it to be "built". Isn't it "just code" like Phobos?


Druntime is in many respects the library portion of the language. It's 
the glue that allows some language pieces to work (e.g. Object, 
associative arrays, TypeInfo, etc.). There are also pieces that are 
purely independent of the compiler.


But it used to be that just Phobos existed, and no Druntime. Druntime is 
actually the runtime portion of Tango, factored out so that both Phobos 
and Tango could use the same underlying runtime. It used to be, if you 
wanted to use a Tango-based library, you couldn't use a Phobos-based one 
as well.


At this point, it's a nice separation of the Language features that must 
be library implemented from the user library (Phobos).




I'm increasingly frustrated because, honestly, it seems I don't know 
enough about the build processes or build tools used. The Wiki expects 
Digital Mars make to be there, also says explicitly not to confuse it 
with GNU make, but in my DMD folder there is none. Since it's a plain 
install, I suspect the Wiki is outdated. How am I expected to figure 
things out? It seems like everyone else knows how to do it, just I'm too 
stupid.


Like any projects that are built over decades, Phobos and Druntime have 
accumulated esoteric build systems, and things you just "have to know". 
I honestly can't help you with your troubles, because I only ever use 
Windows when I have to. But I'm sure there are ways to get done what you 
want to get done. This might involve wrestling with the build system, or 
figuring out the correct command line based on the build system.


-Steve


Re: How to unit-test a phobos module?

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

On 11/25/20 3:58 PM, Q. Schroll wrote:
When trying to unit-test an unchanged phobos module from phobos/master, 
I get errors such as


     module core.lifetime import copyEmplace not found

and template instantiation errors. What is the correct arguments to pass 
to (r)dmd? I know it worked for me some years ago, but somehow, it 
doesn't work now.


I've looked at [1], [2], [3] which didn't work (maybe outdated?). How do 
you do it and what am I doing wrong?


My setup:
* A fresh DMD installed a few minutes ago.
* Clone of my Phobos fork with up-to-date changes from dlang/phobos/master.

In the clone's folder, ~/dlang/phobos, I tried the following commands:

     $ dmd -main -unittest -version=StdUnittest -I. -run std/.d

and

     $ rdmd -main -unittest -version=StdUnittest -I. std/.d

I have the feeling I'm missing something quite obvious.

[1] 
https://wiki.dlang.org/Contributing_to_Phobos#Test_a_single_Phobos_module

[2] https://wiki.dlang.org/Building_under_Windows#Building_Phobos_2
[3] https://github.com/dlang/phobos/blob/master/CONTRIBUTING.md


I typically do:

make -f posix.mak std/.test

-Steve


Re: implementing default opCmp

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

On 11/18/20 6:06 PM, ag0aep6g wrote:

On Wednesday, 18 November 2020 at 22:29:17 UTC, Steven Schveighoffer wrote:
How do I do something really simple for opCmp? I tried this it didn't 
work:


return this == other ? 0 :
    this.tupleof < other.tupleof ? -1 : 1;


std.typecons.Tuple has opCmp. So this works:

     int opCmp(S other)
     {
     import std.typecons: tuple;
     return tuple(this.tupleof).opCmp(tuple(other.tupleof));
     }



Ah, excellent solution! I hadn't thought of that.

-Steve


Re: implementing default opCmp

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

On 11/18/20 6:02 PM, Paul Backus wrote:

On Wednesday, 18 November 2020 at 22:29:17 UTC, Steven Schveighoffer wrote:

I have a struct like this:

struct S
{
   int x;
   int y;
}

and I want a default comparison. The problem is, that comparison 
doesn't have a default, and requires I implement opCmp. While this is 
useful for the compiler, there's no default I know of that is an easy 
one-liner.


Here's a stab at a totally generic version that I haven't unit tested at 
all, except to verify that it works for your example struct S:


auto cmp(T, U)(auto ref T lhs, auto ref U rhs)
{
     import core.lifetime: forward;

     static if (__traits(compiles, lhs.opCmp(rhs)))
     return forward!lhs.opCmp(forward!rhs);
     else static if (__traits(compiles, rhs.opCmp(lhs)))
     return -forward!rhs.opCmp(forward!lhs);
     else
     return lhs < rhs ? -1 : lhs > rhs ? 1 : 0;
}

mixin template defaultOpCmp()
{
     import std.traits: isAggregateType;

     static assert(isAggregateType!(typeof(this)),
     "opCmp can only be overloaded for aggregate types.");

     auto opCmp()(auto ref typeof(this) other)
     {
     import std.traits: ReturnType, CommonType, Fields;
     import std.meta: Map = staticMap;

     alias cmpType(T) = ReturnType!((T lhs, T rhs) => cmp(lhs, rhs));
     alias Result = CommonType!(Map!(cmpType, Fields!(typeof(this;

     Result result;

     static foreach (i, _; typeof(this).tupleof)
     if (result == 0)
     result = cmp(this.tupleof[i], other.tupleof[i]);

     return result;
     }
}


Yeah, something like this might be useful in druntime. But it makes you 
wonder if we wouldn't be better off without opCmp but instead with 
opBinary(string s : "<") and friends.


One thing that sucks is that opCmp might do more operations than are 
necessary for the actual comparison, because it has to generate the 
numeric result.


-Steve


implementing default opCmp

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

I have a struct like this:

struct S
{
   int x;
   int y;
}

and I want a default comparison. The problem is, that comparison doesn't 
have a default, and requires I implement opCmp. While this is useful for 
the compiler, there's no default I know of that is an easy one-liner.


The truth is, I'm not entirely caring what order these things come out 
in. I just want them to be defined as having an order given that all the 
members have a defined order. My expectation is that a default opCmp 
would look like:


int opCmp(S other)
{
   if(x == other.x)
   {
   if(y == other.y) return 0;
   return y < other.y ? -1 : 1;
   }
   return x < other.x ? -1 : 1;
}

But really, as long as there is something to do this easily I don't care 
what the ordering turns out to be.


I can do equality like:

return this.tupleof == other.tupleof;

I can do assignment like:

this.tupleof = other.tupleof;

How do I do something really simple for opCmp? I tried this it didn't work:

return this == other ? 0 :
this.tupleof < other.tupleof ? -1 : 1;

-Steve


Re: presence of function template prevents diagnostic

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

On 11/14/20 5:44 PM, kdevel wrote:


$ dmd -version=X -i foo
$ ./foo
void A.bar(int s)

Is the latter behavior intended or a bug?


That seems like a bug. It shouldn't be less ambiguous because you 
*added* an overload that can also handle it...


-Steve


Re: Missing stacktrace on memory allocation failure

2020-11-12 Thread Steven Schveighoffer via Digitalmars-d-learn

On 11/12/20 4:22 AM, Per Nordlöw wrote:

Why don't I get a stack trace on Memory allocation exceptions?

In my case I only get:

src/core/exception.d(647): [unittest] Memory allocation failed
core.exception.OutOfMemoryError@src/core/exception.d(647): Memory 
allocation failed




Certain errors are flagged as not able to allocate memory. So you don't 
get a stack trace.


I think it's a huge mistake, and we don't need memory allocation to do 
stack trace printing. But that's the way it is.


-Steve


Re: How to get address of a nested function?

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

On 11/10/20 5:51 AM, Max Samukha wrote:
We can get the compile time equivalent of a member function's address by 
applying '&' to the function in a static context:


struct S {
     void foo() {}
}

enum pfoo =  // ok

void main() {
     // now we can use the pointer to create, for example, a delegate
     S s;
     void delegate() dg;
     dg.ptr = 
     dg.funcptr = pfoo;
     dg();
}

However, we can't do that to a nested function:

void main() {
     void foo() {
     }
     enum pfoo =  // weird kind of an enum delegate; pfoo.funcptr 
can't be accessed at compile time.

}

Is there a way to get a pointer to a non-static nested function?


I don't think you can do it at compile time. You can at runtime by 
accessing the funcptr of the delegate.


-Steve


Re: DMD: invalid UTF character `\U0000d800`

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

On 11/8/20 5:47 AM, Per Nordlöw wrote:

On Saturday, 7 November 2020 at 17:49:54 UTC, Jacob Carlborg wrote:

[1] https://en.wikipedia.org/wiki/UTF-16#U+D800_to_U+DFFF


Thanks!

I'm only using these UTF characters to create ranges that source code 
characters as checked against during parsing. Therefore I would like to 
just convert these to a `dchar` for now using a `cast`. Can I just do, 
for instance,


     cast(dchar)0xd8000

for

     `\Ud800`

to accomplish this?


Yes, use the cast. It should work.

It's just the D grammar that is stopping you, a dchar is just an integer 
under the hood, so the cast should be fine.


-Steve


Re: vibe.d get body of HTTPServerResponse

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

On 11/2/20 10:10 AM, JG wrote:

I am trying to get the body the response generated by:

res.render!("index.dt");

where res is of type HTTPServerResponse

Does anyone know how I might go about this?



That is a convenience wrapper to diet-ng:

https://github.com/vibe-d/vibe.d/blob/70b50fdb9cd4144f1a5007b36e6ac39d4731c140/http/vibe/http/server.d#L337-L346

Instead, create your own output range (maybe a char[] appender?) and 
compile to that yourself:


import diet.html : compileHTMLDietFile;
import std.array : appdender;

auto app = appender!(char[]);
compileHTMLDietFile!("index.dt")(app);

auto resultingHTML = app.data;

-Steve


Why is vibe.d json serializer/deserializer so complex?

2020-10-30 Thread Steven Schveighoffer via Digitalmars-d-learn
I was looking to report an enhancement request to vibe.data.json (filed 
here: https://github.com/vibe-d/vibe.d/issues/2490), and I started 
looking at the serialization code for vibe. It's really really 
complicated, and I'm just wondering if this is a case of 
overengineering, or if there's a logic behind making this so 
complicated. My iopipejson serializer is super simple comparatively.


Is there a benefit to having all the complexity? I know they support 
both json and bson, but I cannot follow the code very well, and I'm not 
sure what happens where, and which types are responsible for what.


-Steve


Re: What is the difference between enum and shared immutable?

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

On 10/29/20 10:39 AM, H. S. Teoh wrote:

On Thu, Oct 29, 2020 at 09:50:28AM -0400, Steven Schveighoffer via 
Digitalmars-d-learn wrote:
[...]

D frequently allows no-op attributes.

[...]

I find that to be a bad smell in terms of language design, actually.
Either something should be allowed and have a definite effect, or it
should not be allowed.  Not this murky grey area where you can write
something and it seems to be allowed, but doesn't actually have any
effect.


I think it's to aid in things like:

@safe:

// lots of things, but only functions are tagged as @safe

-Steve



Re: What is the difference between enum and shared immutable?

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

On 10/28/20 6:28 PM, IGotD- wrote:

On Wednesday, 28 October 2020 at 21:54:19 UTC, Jan Hönig wrote:


shared immutable x = 1;



Is there a point to add shared to an immutable? Aren't immutable 
implicitly also shared?


You are correct:

pragma(msg, typeof(x)); // immutable(int)

D frequently allows no-op attributes.

-Steve


Re: `unittest` placement in code?

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

On 10/26/20 9:16 AM, Vladimirs Nordholm wrote:

Hello.

I have a class which I have written some tests for, to ensure if I ever 
change some code it will still work as intended.


The documentation https://dlang.org/spec/unittest.html says it is can be 
placed both in the class or outside it.


I come from a background of having a completely separate tests folder 
with only tests, so I do not know what the general best-practice is with 
D. Where should the `unittest` code block go?


Wherever you want. Generally people put it right after the thing being 
tested to keep files organized.


When the compiler runs unittests it runs them all in the sequence they 
are in the file.


One place to be cautious though -- if you put them inside a template, 
they will be created for every instantiation of that template.


-Steve


Re: Can we do compile time reading part of a file using import?

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

On 10/23/20 12:42 PM, data pulverizer wrote:

Hi all,

the `import` function allows a file to be read at compile time, which 
opens up great opportunities for (mostly binary) file IO, where data 
types can be coded into files - the user doesn't need to know data types 
ahead of time. As specified in my old blog article: 
https://www.active-analytics.com/blog/reading-idx-files-in-d/.


Binary files can be very large and reading the whole file at compile 
time is often unnecessary.


This isn't exactly the intended use for the function, but there it is. 
Since compile time read capability already exists and is useful, adding 
capability to be able to read only a portion of the file at compile time 
in a given location is advantageous and has utility.


For me it's not make-or-break, it just something very useful and I think 
has clear use case. Please let me know if there are aspects or 
alternatives I am missing.


I see no reason why the compiler can't do something special with:

enum slicedFile = import("foo.bin")[0 .. 100];

One thing that comes to mind -- most OSes support memory-mapped files. 
If import simply did a memory mapped file internally, and duplicated the 
string once actually used somewhere, then you can avoid full reading of 
the data until it's necessary.


-Steve


Re: mysql-native Help required

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

On 10/22/20 11:00 AM, Vino wrote:

On Thursday, 22 October 2020 at 14:08:30 UTC, Steven Schveighoffer wrote:

On 10/22/20 7:04 AM, Vino wrote:

Hi All,


   Request your help on the below code as it is not working as expected.

GetConnections.d

module common.GetConnections;
import mysql;

class Connections
{
   private Connection conn;
   auto constr = 
"host=localhost;port=3910;user=user;pwd=password#;db=testdb";


I'd declare this immutable, so it's not stored in the class:

immutable constr = "...";


   this.conn = new Connection(constr);


You are trying to assign an instance member at compile time, with no 
actual instance.


You need a constructor

 this() { this.conn = new Connection(constr); }

}

GetHost.d

import common.GetConnections;
import std.array : array;
import std.variant;
import mysql;
import std.stdio: writeln;

void main()
{
  auto conn = new Connections();
  Row[] data = conn.query("SELECT * FROM hostlog").array;
  writeln(data[]);
}


The rest should work.

-Steve


Hi Steve,

    Thank you very much, I tried your solution, still not working

File: GetConnections.d
module common.GetConnections;
import mysql;

class Connections
{
   private Connection conn;
   immutable constr = 
"host=localhost;port=3910;user=user;pwd=password#;db=testdb";

   this() { this.conn = new Connection(constr); }
}

Error:
source/common/GetHost.d(11,25): Error: none of the overloads of query 
are callable using argument types (Connections, string), candidates are:
/root/.dub/packages/mysql-native-3.0.0/mysql-native/source/mysql/commands.d(321,13):
mysql.commands.query(Connection conn, const(char[]) sql, 
ColumnSpecialization[] csa = null)
/root/.dub/packages/mysql-native-3.0.0/mysql-native/source/mysql/commands.d(334,13):
mysql.commands.query(Connection conn, const(char[]) sql, VariantN!32LU[] 
args)
/root/.dub/packages/mysql-native-3.0.0/mysql-native/source/mysql/commands.d(342,13):
mysql.commands.query(Connection conn, ref Prepared prepared)
/root/.dub/packages/mysql-native-3.0.0/mysql-native/source/mysql/commands.d(357,13):
mysql.commands.query(Connection conn, ref Prepared prepared, 
VariantN!32LU[] args)
/root/.dub/packages/mysql-native-3.0.0/mysql-native/source/mysql/commands.d(364,13):
mysql.commands.query(Connection conn, ref BackwardCompatPrepared prepared)

source/common/GetParams.d(11,25):    ... (2 more, -v to show) 



Different error:

 Row[] data = conn.query("SELECT * FROM hostlog").array;

This is trying to call mysql-native's UFCS query function on 
Connections, which isn't valid. You need to call it on conn.conn.


But there's no access to the private Connection conn inside the 
Connections class. I'm not sure what the class is for anyway, so it's 
hard for me to suggest a proper alternative. Are you just trying to 
encapsulate the connection string? I'd suggest instead of a whole class, 
just a factory function:


Connection getConnection()
{
   return new Connection("...");
}

-Steve


Re: mysql-native Help required

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

On 10/22/20 7:04 AM, Vino wrote:

Hi All,


   Request your help on the below code as it is not working as expected.

GetConnections.d

module common.GetConnections;
import mysql;

class Connections
{
   private Connection conn;
   auto constr = 
"host=localhost;port=3910;user=user;pwd=password#;db=testdb";


I'd declare this immutable, so it's not stored in the class:

immutable constr = "...";


   this.conn = new Connection(constr);


You are trying to assign an instance member at compile time, with no 
actual instance.


You need a constructor

 this() { this.conn = new Connection(constr); }

}

GetHost.d

import common.GetConnections;
import std.array : array;
import std.variant;
import mysql;
import std.stdio: writeln;

void main()
{
  auto conn = new Connections();
  Row[] data = conn.query("SELECT * FROM hostlog").array;
  writeln(data[]);
}


The rest should work.

-Steve


Re: Packing of Struct Fields

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

On 10/17/20 9:00 AM, Per Nordlöw wrote:

On Saturday, 17 October 2020 at 12:51:21 UTC, ag0aep6g wrote:
c does come directly after s. The padding between b and c is part of 
s. If you don't want that padding, you can use `align(1)` to define S 
without padding. But then 75% of the ints in an S[] will be misaligned.


I understand that. I don't want the alignment of `S` to change. I want 
the padding after `s` in `T` to be avoided and have `c` start at 
byte-offset 7. I don't see why this padding is needed in the case where 
only a single (1-element array of) `S` is stored as a field inside 
another aggregate.


Ali's code prints:

=== Memory layout of 'T' (.sizeof: 12, .alignof: 4) ===
    0: S s
    8: char c
    9: ... 3-byte PADDING


There might be some good reasons for this.

For one, what happens if you copy the s? Does it copy the c too?

For another, this is how C does it, so I would expect it to at least 
match C for compatibility.


I think it *should* be possible to do this, if it's not already, just 
with pragmas. (i.e. pack T but not S).


-Steve


Re: Why is `Appender._data` a pointer to its `Data`-store?

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

On 10/17/20 12:00 AM, Paul Backus wrote:

On Saturday, 17 October 2020 at 00:06:31 UTC, Steven Schveighoffer wrote:


Appender is ref counted IIRC.



It's not; it uses the GC.


Oh yeah. In fact, it was me who did that (in 2010!).

My point should have been that the appender is a pImpl to avoid memory 
corruption. If you have multiple copies of an appender, and each has its 
own idea of what the capacity is, then you will get corruption.


See the original bug report here: 
https://issues.dlang.org/show_bug.cgi?id=4681


-Steve


Re: How convert String to Fixed wchar Array?

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

On 10/16/20 8:23 PM, Marcone wrote:

How convert String to Fixed wchar Array?

import std;

void main(){
     string name = "Marvin";
     wchar[255] wtext = name.to!(wchar[]); // Can not convert.
     writeln(wtext);
}


void main()
{
string name = "Marvin";
wchar[255] wtext;
import std.range;

wchar[] buf = wtext[];
put(buf, name);
auto setLen = wtext.length - buf.length; // number of wchars set in 
wtext.

writeln(wtext[0 .. setLen]);
}

A little bit of explanation: wchar[] is an output range that can accept 
any form of text. When you use `put` on it, it writes to it, AND shrinks 
from the front to allow remembering where it was. So at the end, buf is 
pointing at what is *left* in the buffer.


There may be better ways to do this, but this way will avoid any extra 
GC allocation.


-Steve


Re: Why is `Appender._data` a pointer to its `Data`-store?

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

On 10/16/20 5:40 PM, Per Nordlöw wrote:

Why is `Appender`'s store `Data` put directly as

     `private Data* _data;`

instead of

     `private Data _data;`

?

Removing the pointer indirection would give better locality.

If it's about optimizing for empty `Appender`s then a `Appender*` should 
be used in those cases instead.


Appender is ref counted IIRC.

-Steve


Re: Forward referencing functions in D

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

On 10/16/20 4:47 PM, wilcro wrote:



Thanks to all for your responses; as a related followup question, would 
there be any reason to avoid placing the majority of code for a program 
outside of the main function?


Inner functions have benefits:

1. They are only accessible inside the function. Which means you only 
have to worry about correctness while INSIDE that function.

2. inner functions have access to the outer function's stack frame.

Often, I use inner functions to factor out a common piece of code that I 
don't want to have to write multiple times in the same function.


-Steve


Re: Packing of Struct Fields

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

On 10/16/20 4:44 PM, ag0aep6g wrote:

On 16.10.20 22:32, Per Nordlöw wrote:
Why is `T.sizeof` 12 instead of 8 when `U.sizeof` is 8 in the 
following example?


struct S
{
 int i;
 bool b;
}

struct T
{
 S s;
 char c;
}

struct U
{
 int i;
 bool b;
 char c;
}

?


S.sizeof: 4 bytes for the int + 1 byte for the bool + 3 bytes padding so 
that the int is aligned = 8 bytes.


T.sizeof: 8 bytes for the S + 1 byte for the char + 3 bytes padding so 
that the S is aligned = 12 bytes.


U.sizeof: 4 bytes for the int + 1 byte for the bool + 1 byte for the 
char + 2 bytes padding so that the int is aligned = 8 bytes.


To further explain this -- the padding is added so things like pointer 
arithmetic on an array work.


For example, if you have a T* t, and you say t += 1, you want it to go 
to the next T, not to a misaligned spot.


You can also override this with align keyword. But I don't recommended 
this unless you know what you are doing. Misaligned reads/writes are 
different on different architectures, but even if they work and don't 
crash your program, they are going to be slower.


https://dlang.org/spec/attribute.html#align

-Steve


Re: Struct field destructor not called when exception is thrown in the main struct destructor

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

On 10/16/20 11:11 AM, Ali Çehreli wrote:

On 10/16/20 6:12 AM, tchaloupka wrote:

 > struct Foo {
 >  Bar bar;
 >  bool err;
 >
 >  ~this() {
 >  // scope(failure) destroy(bar); // < this fixes the Bar
 > destructor call
 >  enforce(!err, "Test err");

Well, that check means "cannot continue", which means the compiler stops 
executing the destruction code because it can't. (It would a serious bug 
if it continued execution in a state that the program knows to be invalid.)


The destruction of members is outside the destructor's purview. It can't 
turn the destruction off, so it should logically be considered part of 
an enclosing function.


Note that enforce is throwing an *Exception*, not an *Error*, it does 
not mean the program is in an invalid state. Throwing an Error, the 
compiler is allowed to not clean up after itself.


Imagine if throwing an Exception disabled RAII in any enclosing function 
scopes because it considered that an invalid state.


Conceptually, bar's destructor is called on that closing brace but we 
decided to abort mission earlier. Your calling destroy(bar) may or may 
not be wrong in case of 'err'. Only you know at that point.


If that is the case, a hand written destructor should turn off automatic 
destruction of members. Either the compiler handles member destruction 
or it doesn't.


-Steve


Re: Struct field destructor not called when exception is thrown in the main struct destructor

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

On 10/16/20 9:12 AM, tchaloupka wrote:

So when the exception is thrown within Foo destructor (and it's bad on 
it's own but can easily happen as destructors aren't nothrow @nogc by 
default).


Is this behavior expected?


I would say it's a bug. The compiler is going to call the member 
destructor even if the hand-written destructor does it too. If the 
compiler wants to take responsibility for cleaning up members, it should 
take full responsibility. In fact, there is no way to instruct the 
compiler "I'm handling the destruction of this member", so I don't see 
why it should matter if you exit the function via exception it should be 
any different.


-Steve


Re: Error on dub build - Trying Vibe-d for the first time

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

On 10/15/20 10:22 AM, Steven Schveighoffer wrote:

On 10/15/20 9:55 AM, Andre Pany wrote:



I meant this one:
https://github.com/vibe-d/eventcore/pull/154

I testing it at the moment, while there still "leaking" warnings, the 
ports are released after terminating the application with Ctrl+c. So 
far I was not able to reproduce the issue with vibe.d 0.9.2 (eventcore 
0.9.9).


Soo if you try to print a warning it keeps the process alive? I 
can't understand how this would fix it. It is still printing too, so how 
could that have fixed the problem?




Not fixed. I just did the same test (dub init -t vibe.d) and it fails to 
kill the process. Still have to kill with -9.


-Steve



Re: Error on dub build - Trying Vibe-d for the first time

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

On 10/15/20 9:55 AM, Andre Pany wrote:



I meant this one:
https://github.com/vibe-d/eventcore/pull/154

I testing it at the moment, while there still "leaking" warnings, the 
ports are released after terminating the application with Ctrl+c. So far 
I was not able to reproduce the issue with vibe.d 0.9.2 (eventcore 0.9.9).


Soo if you try to print a warning it keeps the process alive? I 
can't understand how this would fix it. It is still printing too, so how 
could that have fixed the problem?


-Steve


Re: Error on dub build - Trying Vibe-d for the first time

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

On 10/14/20 2:25 PM, Andre Pany wrote:

On Wednesday, 14 October 2020 at 18:08:40 UTC, H. S. Teoh wrote:
On Wed, Oct 14, 2020 at 05:30:37PM +, Andre Pany via 
Digitalmars-d-learn wrote:

On Wednesday, 14 October 2020 at 16:39:39 UTC, Imperatorn wrote:
> On Wednesday, 14 October 2020 at 15:27:46 UTC, Andre Pany > wrote:

[...]

> > [...]

[...]

> Where is this documented?

I dont know whether it is documented somewhere. It was asked multiple 
times in the forum therefore I remembered.


Maybe it could be documented in the vibe.d github wiki or on the 
vibe.d website. But hopefully the bug is solved soon.

[...]

Yeah, this is a problem.  Things like these need to be put in the docs 
in an easy-to-find way. Like collected in a Troubleshooting page or 
something.  If a bug isn't filed yet, I'd file a bug on vibe.d so that 
this will get resolved instead of forgotten, and then it will bite the 
next newcomer all over again.



T


https://github.com/search?q=VibeHighEventPriority=issues

It seems with eventcore 0.9.9 there was some fix, but I do not know 
whether this solves the bug or s.th. related to the bug.




Is this the commit you are talking about?

https://github.com/vibe-d/eventcore/pull/122

I haven't tested turning the version definition off. But it probably 
should be easy enough to do a vanilla vibe-d install and see if it works.


I hope this is the fix, because this bug has been a huge problem, 
especially for people trying vibe for the first time.


-Steve


Re: Error on dub build - Trying Vibe-d for the first time

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

On 10/13/20 8:40 PM, Bruno Rodrigues wrote:

So, I tried building a simple hello world with Vibe-d and got this error


/usr/bin/ld: cannot find -lssl
/usr/bin/ld: cannot find -lcrypto
collect2: error: ld returned 1 exit status
Error: linker exited with status 1
/usr/bin/dmd failed with exit code 1.


I have absolutely no ideia what these libraries are.

I'm using linux 20.04

The project was created with dub the same way the dependency was added.

Thanks, this language seems to be really interesting.


sudo apt-get install libssl-dev

That should get you running.

-Steve


Re: Renaming Flag!"" in API

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

On 10/12/20 7:34 AM, Vladimir Panteleev wrote:

On Monday, 12 October 2020 at 10:24:44 UTC, FreeSlave wrote:

Can this issue overcome somehow?


Why not add a deprecated overload for your function which takes the old 
Flag value?


Or even not deprecated (if it still makes sense).

-Steve


Re: question on dub and postgresql

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

On 10/5/20 6:01 AM, Alaindevos wrote:

On Monday, 5 October 2020 at 09:24:33 UTC, Mike Parker wrote:

On Monday, 5 October 2020 at 09:05:16 UTC, Alaindevos wrote:


[...]


You don't need to install dpq2 if you are using dub to build your 
project. Add it as a dependency to your dub.json (or dub.sdl if you 
prefer that format). When you build your project, dub will download 
the version you configured as your dependency and compile it along 
with your project.


[...]


Thanks for this clear explanation. I'll try first using the dub tooling.
PS : Manual does not look easy with different versions in the 
/home/myhome/.dub/packages directory.


dub will automatically download any version that is used as a 
dependency. You don't have to worry about it.


So let's say one project depends on version 2.0.0 of a package, and 
another depends on 1.0.0. Both will be downloaded, compiled, and used as 
the appropriate dependency that the project requests.


Compare to a build system where you need to install the dependencies 
manually, now you have to install the right one to get the right version.


However, keep in mind that dub only deals with D packages, not external 
dependencies (like libpq, which is required for dpq2).


-Steve


Re: QuickSort on ranges

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

On 10/4/20 6:50 AM, jerome wrote:

Thanks you very much Ali,

I will try to wrap my head around your inputs, and get a better 
understanding of ranges in the process. I feel there is a lot of power 
in D ranges, and like the hammer of Thor, I am not worthy yet :)




Just to elaborate a bit further: Templates work by pattern matching. 
When you say


quickSort(T)(T[] r)

You are saying, match the parameter T[] to what is passed, and if it's a 
match, set T to the part of the parameter that matches. Therefore:


int[] => T = int
ubyte[] => T = ubyte

But if you leave off the array brackets:

quickSort(T)(T r)

Now T matches *any type* that you pass in, including ranges. Most range 
functions use templates because there is no supertype for ranges. They 
are checked by trying to compile the range primitives on them.


How you do more advanced checks other than pattern matching, is to use a 
template constraint, as Ali suggests.


In fact, since you are just using std.algorithm.pivotPartition, you can 
just look at the constraints it uses:


if (isRandomAccessRange!Range && hasLength!Range && hasSlicing!Range && 
hasAssignableElements!Range)


-Steve


Re: Whats going on with this?

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

On 10/3/20 4:46 PM, Daniel Kozak wrote:



On Sat, Oct 3, 2020 at 10:40 PM Daniel Kozak > wrote:


I would say it is here you just need to read it carefully:

https://dlang.org/spec/struct.html#static_struct_init


For case specification is change I will paste it here:
'''
If a StructInitializer is supplied, the fields are initialized by the 
StructMemberInitializer syntax. StructMemberInitializers with the 
Identifier : NonVoidInitializer syntax may be appear in any order, where 
Identifier is the field identifier. StructMemberInitializers with the 
NonVoidInitializer syntax appear in the lexical order of the fields in 
the StructDeclaration.

'''

And StructMemberInitializer is defined as:

'''
StructMemberInitializer:
     NonVoidInitializer
     Identifier : NonVoidInitializer
'''

And NonVoidInitializer is defined as:

'''
NonVoidInitializer:
     ExpInitializer
     ArrayInitializer
     StructInitializer
'''

And as you can see there is ArrayInitializer

And there is definition of Array literals here
https://dlang.org/spec/expression.html#array_literals

and in section 2. there is this text:

'''
By default, an array literal is typed as a dynamic array, but the 
element count is known at compile time. So all array literals can be 
implicitly converted to static array types.

'''


"StructMemberInitializers with the NonVoidInitializer syntax appear in 
the lexical order of the fields in the StructDeclaration" seems to 
suggest it will not call the constructor, but instead initialize the 
fields according to the list.


The fields are not a static array, so clearly it is calling the 
constructor, and not initializing the fields.


I really don't think this case is in the spec.

But I know it works, for instance:

Variant v = anything;

If this required an explicit Variant constructor, it would be quite 
annoying.


-Steve


Re: Getting Field Names of a specific UDA in compile time.

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

On 10/3/20 10:16 AM, realhet wrote:


I tried it to put into a function:

auto getSymbolNamesByUDA(T, string uda)(){
     string[] res;
     static foreach(a; getSymbolsByUDA!(T, uda)) res ~= a.stringof;
     return res;
}


D __traits give you strings, the std.traits thing is giving you symbols. 
Don't use it, just use the compiler traits:


// note, not tested
auto getSymbolNamesByUDA(T, string uda)(){
 string[] res;
 static foreach(n; __traits(allMembers, T)) {
// static, but don't use static foreach so you can break
foreach(u; __traits(getAttributes, __traits(getMember, T, n))
   static if(is(typeof(u) == string) && u == uda) {
   res ~= n;
   break;
   }
 }
 return res;
}

-Steve


Re: Whats going on with this?

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

On 10/3/20 6:52 AM, claptrap wrote:

On Saturday, 3 October 2020 at 00:15:02 UTC, Steven Schveighoffer wrote:

On 10/2/20 7:28 PM, claptrap wrote:

Why would putting in the writeln cause it to fail? Is it maybe trying 
to create the foo at compile time?




Yes, it is. Any static initialization of static variables happens at 
compile-time.


https://dlang.org/spec/declaration.html#global_static_init



Ah.. ok, any idea why this works?

Foo foo = [300,300];


Yeah, it's calling the constructor. I agree with Adam, there's nothing 
in the spec that talks about this that I can find.


-Steve


Re: Whats going on with this?

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

On 10/2/20 7:28 PM, claptrap wrote:

Why would putting in the writeln cause it to fail? Is it maybe trying to 
create the foo at compile time?




Yes, it is. Any static initialization of static variables happens at 
compile-time.


https://dlang.org/spec/declaration.html#global_static_init

-Steve


Re: Can opDollar support a jagged 2D array?

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

On 10/2/20 1:24 PM, James Blachly wrote:

On 10/2/20 9:32 AM, Steven Schveighoffer wrote:

This seems like an oversight. But it's not impossible.


Thank you Steve. Is there any chance that this mechanism will ever be 
revised? Presumably it would require a DIP.


The problem is, how do you pass enough context to the opDollar? The nice 
thing about opDollar is it's a simple mechanism. But as a simple 
mechanism, it's hard to say how to give it enough context in this case. 
In this specific case, you would need to know the index of the first 
parameter. But what if the first parameter depended on the index of the 
second? Really, you need opIndex to get the whole expression, with the 
dollar sign being processed there. But that's really hard to do, because 
now you are delaying the expression evaluation until later.


What I meant by an oversight is, at one point, opDollar just was a 
single property. And opIndex did not take a slice parameter, but rather 
you just had opSlice(beg, end), which wasn't a template. The 
multi-parameter version of opIndex (and the column-specialized version 
of opSlice version) was added to aid in building the Mir library (I 
think), and I don't know if anyone brought up the possibility of a 
jagged array like this.




Just curry the information to the receiver. opDollar doesn't have to 
return a size_t.


This is indeed pretty clever; I would not have ever though to have 
opDollar return a non-integral value. This again suggests the whole 
thing needs to be revised, but this will work for now -- thanks again!




I think this is probably the best solution you are going to get. Maybe 
someone already has done something like this and has a better answer? 
Maybe Mir does something like this too, I'd take a look at it if I were you.


Long ago, I used opDollar to return something other than a size_t for 
dcollections, which worked awesome. I had asked for an opCaret, so that 
you could use slicing from beginning when `0` isn't the first element.


Like imagine a RBTree, I might like to say "range of all elements up to 
key 5" like rbt[^ .. 5] instead of rbt[rbt.begin .. 5].


But opCaret was deemed to be not useful enough. Oh well.

-Steve


Re: Can opDollar support a jagged 2D array?

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

On 10/1/20 10:34 PM, James Blachly wrote:

Suppose I have a data structure encoding sequence lengths:

seq1: 0 1 2 ... N
seq2: 0 1 2 3 4 ... M
seq3: 0 1 ... P

I would like to write opIndex and opDollar to support the notation 
obj[seq, x .. $] to retrieve sequences.


However, given that opDollar is templated on dimension (always 1 in this 
example) and has no information calling function's context/dimension 0 
parameter, this seems impossible.


Am I missing an easy solution?


This seems like an oversight. But it's not impossible.

Just curry the information to the receiver. opDollar doesn't have to 
return a size_t.


Something like:

struct FromEnd
{
  ptrdiff_t offset;
  FromEnd opBinary(string s, T)(T val)
  {
  mixin("return FromEnd(offset " ~ s ~ " val);");
  }
}

struct MyStructure
{
   FromEnd opDollar(size_t col)() if(col == 1) { return FromEnd.init; }
}

And then inside your opIndex, you have to handle that type specially 
according to context.


The saving grace here is that opDollar doesn't exist except in an 
indexing operation, so you don't need to worry about it except in that 
context. opDollar is really kind of a hacky way to do this. It was added 
back when multi-dimensional indexing was not yet solid.


-Steve


Re: Fiber based HTTP client for load testing

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

On 9/30/20 8:35 PM, Arun wrote:

As seen, the downside is that the more threads we use the more memory 
the app consumes. Is there a way to replace the threads with fibers in 
this particular case so that instead of spawning 1000 threads, we spawn 
1000 fibers with just 1 thread?




Right on the main page, it says it can work with vibe.d. So that would 
be with fibers.


How you create a fiber task for use in vibe.d I don't know. I've only 
ever used it with the web framework in mind.


"just using fibers" isn't going to make it any faster. You still need an 
event framework to yield the fibers when they are waiting on i/o.


-Steve


Re: Deprecation in traits

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

On 9/29/20 1:08 PM, Frak wrote:

Hi folks,

I've this:

/Users/frak/dlang/ldc-1.23.0/bin/../import/std/traits.d(3711): 
Deprecation: function `std.typecons.Nullable!long.Nullable.get_` is 
deprecated - Implicit conversion with `alias Nullable.get this` will be 
removed after 2.096. Please use `.get` explicitly.


I'm trying to find out WHERE this is generated to fix it, dependency 
included, without success.


Suggestions?


Because it's probably coming from a constraint, you probably can't 
figure out the exact usage. What's more annoying is that likely it is a 
spurious warning. A lot of traits "try something", and then alias to 
false or true depending on what works. But it's not going to make a 
difference in your code.


It's one of the most annoying things in the library. If you see this 
warning coming from *your* code, then you should fix it. But it will 
tell you the location if that was the case, not std.traits.


-Steve


Re: App hangs, GC.collect() fixet it. Why?

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

On 9/28/20 3:28 PM, Bastiaan Veelo wrote:
I’m leaning towards ditching the memory mapped I/O on the D end, and 
replace it by regular serialisation/deserialisation. That will be a 
manual rewrite though, which is a bit of bummer as memory mapped files 
are widely used in our Pascal code. But this will probably give the best 
end result.


2 things:

1. I agree this is the answer. If you ever ditch the old Pascal code, 
then you can reactivate the memory-mapped code.
2. You can possibly do the translation outside of your programs. That 
is, it wouldn't be entirely impossible to simply have a process running 
that ensures the "D view" and the "Pascal view" of the same file is kept 
in sync. Then you can keep the memory mapped code the same, and just 
define sane structures in your D code.


If you aren't required to have both Pascal and D programs reading and 
writing the file at the same time, this shouldn't be a problem.


BTW, one further thing I don't understand -- if this is memory mapped 
data, how come it has issues with the GC? And what do the "pointers" 
mean in the memory mapped data? I'm sure there's good answers, and your 
actual code is more complex than the simple example, but I'm just curious.


-Steve


Re: Safe to remove AA elements while iterating over it via .byKeyValue?

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

On 9/28/20 1:18 PM, ikod wrote:

On Monday, 28 September 2020 at 14:58:15 UTC, Steven Schveighoffer wrote:

On 9/27/20 4:43 PM, Per Nordlöw wrote:

On Sunday, 27 September 2020 at 14:23:11 UTC, H. S. Teoh wrote:
No.  Modifying a container while iterating over it is, in general, a 
bad idea (unless the container is designed to be


So the major problem of removing keys while iterating is that the AA 
can decide to rehash and shrink. If it does this, your iterator is 
invalidated -- you might skip elements that are




How do you "detect" this at compile time?


I think idea was to have some attributes that collection programmer may 
attach to implementation, like enums: SafeToRemoveOnIteration, 
SafeToAddOnIteration and so on, which may be checked at compile time 
when foreach is handled by compiler. Then in the foreach body compiler 
can refuse to call some unsafe methods. I do not know if it is worth of 
implementation, just this this was an idea.


auto sneaky = aa;
foreach(k, v; aa)
{
   sneaky.remove(k); // oops
}

It doesn't work. You can't restrict this at compile time. Possibly 
runtime, but not compile time.






One could write a specific function to iterate and remove. I


This looks like dead end to me, as you may not only remove items from 
arbitrary positions while iterating over collection, but also insert 
items. Also this can happens not only inside foreach body, but in other 
kinds of iteration. And also there can be nested iterations over same 
collection.


What do you mean dead end? You provide what is supported through a 
controlled interface. It works well, I wrote and used it in 
dcollections. Using the standard insertion and removal functions is not 
allowed (at least without invalidating the range).


If you want insertion, then potentially you could expose those methods 
via the specific iteration construct as well. But you must be prepared 
to do some really funky things.


If we are talking about AAs, insertion may end up expanding the bucket 
list, which means rehashing. That leads to iterating over the same keys 
again. Unless you do some kind of copy-on-write, or combination of 
iterated container + true container? I don't know.


However, deletion is possible (either delay the rehash until after, or 
don't do a rehash during that iteration) via the iteration construct 
(range). You still need to disallow removal via the original type, or 
you might get a rehash.


-Steve


Re: Any way to tell if an object is inside another class?

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

On 9/28/20 7:11 AM, Ruby The Roobster wrote:

For example:

class test {}
class T {
auto c = new test();
}

Any way to tell if an object of type test is a member of object T? I 
don't want to use the name of the member variable. I just want to know 
if this works in general.
Why am I asking this? Because I need it to develop this Multiple Alias 
This project I am working on(basically just mashing all the functions 
into a class and then using the class with alias this)


No. The type of e.g. T.c is the same as the type of some other instance 
of `test`.


Armed only with a class reference to a `test` object, you cannot tell 
where it is referenced from.


I think you need to be more specific about what you want to do. I have a 
feeling you are not understanding how classes work in D (they are not 
stored inside an object or struct, but rather on the heap, and the 
member variable is simply a reference to that item).


-Steve


Re: App hangs, GC.collect() fixet it. Why?

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

On 9/28/20 8:57 AM, Bastiaan Veelo wrote:

I am glad to have found the cause of the breakage finally, but it won't 
be easy to find a generic solution...


Obviously, this isn't a real piece of code, but there is no way around 
this. You have to align your pointers. The other option is to not use 
the GC and use manual memory management.


If this is a compatibility thing between D and Pascal, and you 
absolutely have to have the same layout, is there a way to adjust the 
structure in Pascal? Like put the elements that misalign the pointers at 
the end of the structure?


Another totally drastic approach would be to supply your own 
even-more-conservative GC which will scan misaligned pointers. Probably 
going to hurt performance quite a bit. You might be able to get away 
with marking only certain blocks as having misaligned pointers, but you 
will have to scan all the stacks with this assumption.


Some more information about the setup you are using might help (I'm 
assuming D and Pascal are using the same memory in the same process, 
otherwise this wouldn't be a problem). In particular, where does the 
data come from, and how malleable is it in your system? Are there times 
where references to the D data only exist in Pascal?


-Steve


Re: Safe to remove AA elements while iterating over it via .byKeyValue?

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

On 9/27/20 4:43 PM, Per Nordlöw wrote:

On Sunday, 27 September 2020 at 14:23:11 UTC, H. S. Teoh wrote:
No.  Modifying a container while iterating over it is, in general, a 
bad idea (unless the container is designed to be used that way, but 
even then, such removal is generally restricted), because it often 
leads to highly counterintuitive results.  In the case of AA's, 
removing an element may lead to a rehashing, which reorders elements, 
and your iteration may miss some elements or repeat some elements or 
terminate prematurely. Even without a rehashing, you may encounter 
inconsistent behaviours, like some elements going "missing".


I believe it's high time we start thinking about detecting these 
violations at compile-time. I recall it's in the spec somewhere so we 
should start a deprecation process at least for AAs.


So the major problem of removing keys while iterating is that the AA can 
decide to rehash and shrink. If it does this, your iterator is 
invalidated -- you might skip elements that are actually in the AA, and 
you might encounter elements that have already been iterated. 
Essentially, the ordering has completely been shuffled. Aside from that, 
there's the performance aspect that you have to re-run the hash lookup 
for no reason (you literally have a pointer to the element you are 
iterating).


How do you "detect" this at compile time?

One could write a specific function to iterate and remove. I did it for 
dcollections (this was actually a very important functionality that I 
missed from C++ std::map, which is why I created dcollections in the 
first place).


I don't think it's worth worrying about this at compile time, or even at 
runtime. Just identify that if you do it, you are subject to peculiarities.


Then, we can introduce a specific mechanism to do this (total strawman, 
have no idea what the best thing looks like):


auto r = aa.byKeyValuePurging;
while(!r.empty)
{
   if(shouldPurge(r.front.key, r.front.value)) r.popFrontAndDelete;
   else r.popFront;
}

where popFrontAndDelete will move to the next element, remove the prior 
element, and ensure that a rehash does not occur.


Again, this is not a formal proposal. Just something like this could be 
possible.


In dcollections, I used a trick of opApply to provide the boolean of 
whether to remove as a parameter to foreach:


foreach(k, v, ref doPurge; )
   doPurge = shouldPurge(k, v);

-Steve


Re: conflicting alias in package module

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

On 9/26/20 9:45 AM, Steven Schveighoffer wrote:

On 9/26/20 3:33 AM, 60rntogo wrote:
and this is an error: "struct pack.foo.Foo at source/pack/foo.d(3,1) 
conflicts with alias pack.bar.Foo at source/pack/bar.d(3,8)". I seems 
like the import in package.d sees Foo both in pack.foo and pack.bar, 
but I don't understand why this happens since the import in bar.d is 
private, isn't it?


A selective import is equivalent to aliasing (to the public) the symbol 
as if it were defined in that scope.


Just in case someone comes along and reads this, I was wrong about this. 
It's not a public import.


-Steve


Re: conflicting alias in package module

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

On 9/27/20 1:17 AM, 60rntogo wrote:

On Sunday, 27 September 2020 at 03:33:20 UTC, Mike Parker wrote:

package.d is for your external interface.


Fair enough, thanks.


This isn't an issue with package, it's an issue with a circular dependency.

You are importing yourself and trying alias something to itself before 
that is defined, which has a conflict.


-Steve


Re: conflicting alias in package module

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

On 9/26/20 10:59 AM, 60rntogo wrote:

On Saturday, 26 September 2020 at 13:45:21 UTC, Steven Schveighoffer wrote:
A selective import is equivalent to aliasing (to the public) the 
symbol as if it were defined in that scope.


You have to label it as private if you want it to be private.


Are you saying that I should write this in bar.d?

private import pack : Foo;

This still gives the same error.



Oh wait, I missed the problem. It's here:


pack/bar.d:
module pack.bar;

import pack : Foo;

Here you are importing the PACKAGE, which is importing bar, which is 
trying to define Foo. It's a recursive loop.


Instead:

import pack.foo : Foo;

Works.

-Steve


Re: conflicting alias in package module

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

On 9/26/20 3:33 AM, 60rntogo wrote:

I have a package with the following structure:

pack
|- foo.d
|- bar.d
|- package.d

and the modules look like this:

---
module pack.foo;

struct Foo {}
---
module pack.bar;

import pack : Foo;
---
module pack;

public import pack.foo, pack.bar;
---

and this is an error: "struct pack.foo.Foo at source/pack/foo.d(3,1) 
conflicts with alias pack.bar.Foo at source/pack/bar.d(3,8)". I seems 
like the import in package.d sees Foo both in pack.foo and pack.bar, but 
I don't understand why this happens since the import in bar.d is 
private, isn't it?


A selective import is equivalent to aliasing (to the public) the symbol 
as if it were defined in that scope.


You have to label it as private if you want it to be private.

-Steve


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

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

On 9/25/20 11:21 AM, Steven Schveighoffer wrote:

I wouldn't depend on that mechanism yes.


*yet*.

-Steve


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

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

On 9/25/20 11:13 AM, 60rntogo wrote:

On Friday, 25 September 2020 at 14:21:59 UTC, Steven Schveighoffer wrote:

in does not mean "take by reference", it means "scope const"


I'm not sure that I really understand scope, but I read 
https://dlang.org/spec/function.html#param-storage as saying "in means 
take by value or reference depending on what is better optimized". Is 
that not what we want here?


That's new, unreleased (available in 2.094.0), and requires the 
-preview=in switch. I wouldn't depend on that mechanism yes.


Right, again I'm wondering if there is a way of saying "just figure out 
if it's more optimal to return by value or const reference".


If the input is not ref, you should not return by ref, because then you 
would be returning a reference to local stack data that is about to be 
destroyed.


The only way to say "make this const ONLY if it's ref" is to overload 
the function with the proper attributes for the proper situations.


Otherwise, you can just return const auto ref.

-Steve


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

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

On 9/25/20 10:12 AM, 60rntogo wrote:

On Friday, 25 September 2020 at 13:15:27 UTC, Steven Schveighoffer wrote:

ou can use auto ref to alleviate that:


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


That's a good point, thanks. Since we are on that topic, how would that 
differ from the following?


int x(in Foo f)


in does not mean "take by reference", it means "scope const"

And going further, if instead of int I wanted to return something that 
might also be expensive to copy, what would be the best way to declare 
the function?


It depends on if you want to return a copy. If you want to return a 
reference if the source is a reference, use auto ref on the return as 
well. But if you still want to protect the internal data, it would have 
to be const.


-Steve


Re: A scheduled control signal with fibers?

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

On 9/25/20 9:16 AM, Ferhat Kurtulmuş wrote:

On Friday, 25 September 2020 at 13:08:16 UTC, Sebastiaan Koppe wrote:

On Friday, 25 September 2020 at 11:58:53 UTC, Ferhat Kurtulmuş wrote:

[...]


No need for fibers per se.

You can run 2 threads. One that produces {time: now + 1500.msecs, 
value: getFlameIntensityViaImageProcessing} objects and one that 
consumes those and basically waits until each's msg.time < now and 
then sendPWMSignalToValfe(msg.value). You would basically rely on 
std.concurrency's MessageBox to do the queuing. Although you could do 
that manually as well.


Could also run it on 1 thread if you don't mind there being a jitter 
of however long getFlameIntensityViaImageProcessing takes, but you 
will need a queue.


That was the first thing I thought. A FIFO queue. I just wanted to not 
reinvent the wheel. So, you guys say go for regular threads not fibers. 
Thank you.


Whether a fiber is a valid solution or not depends on that 
getFlameItensityViaImageProcessing function.


If that is actually code running in your process, a fiber is going to 
block any other fibers during that operation. So threads are the way to 
go here.


fibers work great if you can yield the fiber when waiting on something 
*external* to complete (like for instance, i/o). But if the fiber *is* 
the thing you are waiting on, it's not going to be able to execute 
anything else until that is done.


Given the rate and the number of concurrent tasks, I'd say threads.

-Steve


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


  1   2   3   4   5   6   7   8   9   10   >