Re: Concatenating compile time sequences

2019-03-01 Thread H. S. Teoh via Digitalmars-d-learn
On Sat, Mar 02, 2019 at 02:16:22AM +, Victor Porton via Digitalmars-d-learn 
wrote:
> I try to split a compile time sequence of types and names into a
> sequence consisting of two-element subsequences (each of type and
> name).
> 
> That is, I want to transform:
> 
> (int, "x", float, "y", double, "z")
> 
> into
> 
> (AliasSeq!(int, "x"), AliasSeq!(float, "y"), AliasSeq!(double, "z"))

Keep in mind that sequences produced by AliasSeq are auto-expanding,
meaning the above construct will automatically flatten into a flat
AliasSeq!(int, "x", float, "y", double, "z").  If that's not what you
want, you need to wrap your subsequences in a separate, non-eponymous
template.


> I am trying like this:
> 
> private alias enum processFields() = AliasSeq!();

I'm not sure what "alias enum" is supposed to mean; is that a typo?
Surely you mean just "alias"?


> private alias enum processFields(T, name, Fields...) =
> AliasSeq!(AliasSeq!(T, name), processFields!(Fields));

This line doesn't do what you think it does, because of auto-expansion.
It's essentially exactly the same thing as:

private alias processFields(T, name, Fields...) =
AliasSeq!(T, name, processFields!(Fields));

i.e., the nested AliasSeq has no effect.


> But the above would (as I understand) make AliasSeq! returned by the
> recursively called processFields an element of the parent sequence
> rather than its tail subsequence as it should.

If you want anything that retains a nested structure, you cannot use
AliasSeq because of auto-expansion.  You need to define your own,
non-eponymous template container, e.g.:

template MySeq(T...) {
alias data = T;
}

alias processFields(T, name, Fields...) =
AliasSeq!(MySeq!(T, name), MySeq!(processFields!(Fields)));

The MySeq!(...) "protect" their contents from flattening into the outer
list, while the outer AliasSeq causes individual MySeq!(...)'s to be
promoted to the top level sequence rather than producing a tree-like
structure.

Note that to access the data inside a MySeq, you'll have to use .data,
for example:

alias fields = processFields!(int, "x", float, "y");

alias type0 = fields[0].data[0]; // int
string name0 = fields[0].data[1]; // "x"
alias type1 = fields[1].data[0]; // float
string name1 = fields[1].data[1]; // "y"

Hope this helps.


T

-- 
Windows: the ultimate triumph of marketing over technology. -- Adrian von Bidder


Re: How to cast arrays?

2019-03-01 Thread Matheus via Digitalmars-d-learn

On Saturday, 2 March 2019 at 02:14:01 UTC, Murilo wrote:
How do I cast a ubyte[] into uint[]? It keeps raising an error, 
I have read the documentation saying there are restrictions for 
that concerning the length of the arrays.


By the way here is how:

void foo(){
   ubyte[] x = [1,2];
   auto y = (cast(int*) )[0..2];
   writeln(y);
}

Matheus.


Re: How to cast arrays?

2019-03-01 Thread Matheus via Digitalmars-d-learn

On Saturday, 2 March 2019 at 02:14:01 UTC, Murilo wrote:
How do I cast a ubyte[] into uint[]? It keeps raising an error, 
I have read the documentation saying there are restrictions for 
that concerning the length of the arrays.


https://dlang.org/spec/expression.html#cast_expressions

"Casting a dynamic array to another dynamic array is done only if 
the array lengths multiplied by the element sizes match. The cast 
is done as a type paint, with the array length adjusted to match 
any change in element size. If there's not a match, a runtime 
error is generated."


Matheus.


Re: How to cast arrays?

2019-03-01 Thread H. S. Teoh via Digitalmars-d-learn
On Sat, Mar 02, 2019 at 02:14:01AM +, Murilo via Digitalmars-d-learn wrote:
> How do I cast a ubyte[] into uint[]? It keeps raising an error, I have
> read the documentation saying there are restrictions for that
> concerning the length of the arrays.

That depends on what you're trying to accomplish.  Are you trying to
*reinterpret* the ubytes as uints? I.e., every 4 ubytes will be
interpreted as 1 uint?  If so, cast(uint[]) is your ticket.  And
obviously it will require that the .length of the ubyte[] must be a
multiple of uint.sizeof, since otherwise the last element would be
malformed.  And there will probably be alignment issues as well.

However, if you're trying to *transcribe* ubyte values into uint, i.e.,
promote each ubyte value to uint, then what you want is NOT a cast, but
a transcription, i.e., copy ubytes into uint with integer promotion.
There are various ways of doing this; an obvious one is:

ubyte[] bytes = ...;
uint[] ints = bytes.map!(b => cast(uint) b).array;


T

-- 
Beware of bugs in the above code; I have only proved it correct, not tried it. 
-- Donald Knuth


Concatenating compile time sequences

2019-03-01 Thread Victor Porton via Digitalmars-d-learn
I try to split a compile time sequence of types and names into a 
sequence consisting of two-element subsequences (each of type and 
name).


That is, I want to transform:

(int, "x", float, "y", double, "z")

into

(AliasSeq!(int, "x"), AliasSeq!(float, "y"), AliasSeq!(double, 
"z"))


I am trying like this:

private alias enum processFields() = AliasSeq!();

private alias enum processFields(T, name, Fields...) =
AliasSeq!(AliasSeq!(T, name), processFields!(Fields));

But the above would (as I understand) make AliasSeq! returned by 
the recursively called processFields an element of the parent 
sequence rather than its tail subsequence as it should.


Please help to fix the above code. I want namely a recursive 
implementation like the above, because I am going to generalize 
it for some more complex cases.


How to cast arrays?

2019-03-01 Thread Murilo via Digitalmars-d-learn
How do I cast a ubyte[] into uint[]? It keeps raising an error, I 
have read the documentation saying there are restrictions for 
that concerning the length of the arrays.


Re: Executing a D script without an [extension in the filename] leads to an error

2019-03-01 Thread Cym13 via Digitalmars-d-learn

On Friday, 1 March 2019 at 11:38:51 UTC, BoQsc wrote:

On Friday, 1 March 2019 at 09:27:33 UTC, Cym13 wrote:

On Friday, 1 March 2019 at 09:00:43 UTC, BoQsc wrote:
I've installed D compiler, and when i try to run a D script 
with filename without an extension/file type named: program


via: ./program

I'm getting and error:

vaidas@SATELLITE-L855:~/Desktop$ ./program
Error: module `program` is in file './program.d' which cannot 
be read

import path[0] = .
import path[1] = /snap/dmd/49/bin/../import/druntime
import path[2] = /snap/dmd/49/bin/../import/phobos
Failed: ["/snap/dmd/49/bin/dmd", "-v", "-o-", "./program.d", 
"-I."]



Now, when I rename my scirpt file : program
To: program.d

and execute it by: ./program.d

I no longer have an error.

Is this an intended behaviour?


In such questions it's important to show your shebang since 
that's what runs your script.


Given your symptoms I guess you're using the following:

#!/bin/env rdmd

And indeed rdmd won't call your script if it doesn't have the 
proper extension.


Try using this instead:

#!/bin/dmd -run


The shebang I used: #!/usr/bin/env rdmd

I was visiting Dlang Tour and that's where I've got an example 
of shebang usage, directly from there:

https://tour.dlang.org/tour/en/welcome/run-d-program-locally#/on-the-fly-compilation-with-rdmd

The shebang you suggested actually works perfectly:
#!/bin/dmd -run


"And indeed rdmd won't call your script if it doesn't have the 
proper extension."


Then why does Dlang Tour includes shebang: #!/usr/bin/env rdmd

Instead of the one you mentioned, that is fool proof. 
(#!/bin/dmd -run)


Is that an error/mistake in Dlang Tour guide?


Frankly using rdmd is closer to being fool-proof, you just 
haven't hit the corner cases yet :)


I'd either get used to having scripts with a .d extension or make 
an alias or a quick wrapper in shell and call it "program":


#!/bin/sh
exec rdmd /path/to/program.d "$@"

It's not exactly a mistake, it's just not that important to most 
people I guess. And as your program grows you're likely to take 
the habit to compile it and work with the binary directly anyway.


Re: Executing a D script without an [extension in the filename] leads to an error

2019-03-01 Thread Cym13 via Digitalmars-d-learn

On Friday, 1 March 2019 at 14:50:45 UTC, Jesse Phillips wrote:

On Friday, 1 March 2019 at 11:38:51 UTC, BoQsc wrote:
"And indeed rdmd won't call your script if it doesn't have the 
proper extension."


Then why does Dlang Tour includes shebang: #!/usr/bin/env rdmd

Instead of the one you mentioned, that is fool proof. 
(#!/bin/dmd -run)


Is that an error/mistake in Dlang Tour guide?


You may want to change that too:

#!/bin/dmd -i -run

DMD doesn't automatically compile imported files (at least not 
until -i came along), rdmd existed to solve that problem... I 
don't know what value it brings with the -i switch existing.


All systems I know only accept one argument in shebang so sadly 
it's not that simple :)


Re: Executing a D script without an [extension in the filename] leads to an error

2019-03-01 Thread Seb via Digitalmars-d-learn

On Friday, 1 March 2019 at 11:38:51 UTC, BoQsc wrote:

On Friday, 1 March 2019 at 09:27:33 UTC, Cym13 wrote:

On Friday, 1 March 2019 at 09:00:43 UTC, BoQsc wrote:

[...]


In such questions it's important to show your shebang since 
that's what runs your script.


Given your symptoms I guess you're using the following:

#!/bin/env rdmd

And indeed rdmd won't call your script if it doesn't have the 
proper extension.


Try using this instead:

#!/bin/dmd -run


The shebang I used: #!/usr/bin/env rdmd

I was visiting Dlang Tour and that's where I've got an example 
of shebang usage, directly from there:

https://tour.dlang.org/tour/en/welcome/run-d-program-locally#/on-the-fly-compilation-with-rdmd

The shebang you suggested actually works perfectly:
#!/bin/dmd -run


"And indeed rdmd won't call your script if it doesn't have the 
proper extension."


Then why does Dlang Tour includes shebang: #!/usr/bin/env rdmd

Instead of the one you mentioned, that is fool proof. 
(#!/bin/dmd -run)


Is that an error/mistake in Dlang Tour guide?


Well, because it isn't fool proof either ;-)

It won't work once you start using more files as you would then 
need the -i flag , but unfortunately most systems don't support 
more than one shebang argument.


I think it's simply a missing feature of rdmd to accept files 
without an extension as D programs (though of course the tour 
could be improved to be more explanatory here too).


Re: Executing a D script without an [extension in the filename] leads to an error

2019-03-01 Thread Seb via Digitalmars-d-learn

On Friday, 1 March 2019 at 16:45:38 UTC, Seb wrote:

On Friday, 1 March 2019 at 14:50:45 UTC, Jesse Phillips wrote:

I don't know what value it brings with the -i switch existing.


Almost none, except that it's twice as slow as DMD because it 
needs to run DMD twice to learn about all the dependencies.


It's only useful for a few small things now:

- '-e': evaluate d code with all modules automatically imported 
(though now that there's std.experimental.all this value is 
gone too)

- makefile deps generation
- shebang line (as arguments can't be part of the shebang line)

(The list is not complete)


I forgot one big reason why rdmd is still nice: caching. It does 
save the generated dependency file list and checks all 
modification time stamps, s.t. if nothing has changed, it'll run 
a cached build


Re: Executing a D script without an [extension in the filename] leads to an error

2019-03-01 Thread Seb via Digitalmars-d-learn

On Friday, 1 March 2019 at 14:50:45 UTC, Jesse Phillips wrote:

I don't know what value it brings with the -i switch existing.


Almost none, except that it's twice as slow as DMD because it 
needs to run DMD twice to learn about all the dependencies.


It's only useful for a few small things now:

- '-e': evaluate d code with all modules automatically imported 
(though now that there's std.experimental.all this value is gone 
too)

- makefile deps generation
- shebang line (as arguments can't be part of the shebang line)

(The list is not complete)


Re: Executing a D script without an [extension in the filename] leads to an error

2019-03-01 Thread Jesse Phillips via Digitalmars-d-learn

On Friday, 1 March 2019 at 11:38:51 UTC, BoQsc wrote:
"And indeed rdmd won't call your script if it doesn't have the 
proper extension."


Then why does Dlang Tour includes shebang: #!/usr/bin/env rdmd

Instead of the one you mentioned, that is fool proof. 
(#!/bin/dmd -run)


Is that an error/mistake in Dlang Tour guide?


You may want to change that too:

#!/bin/dmd -i -run

DMD doesn't automatically compile imported files (at least not 
until -i came along), rdmd existed to solve that problem... I 
don't know what value it brings with the -i switch existing.


Re: Executing a D script without an [extension in the filename] leads to an error

2019-03-01 Thread BoQsc via Digitalmars-d-learn

On Friday, 1 March 2019 at 09:27:33 UTC, Cym13 wrote:

On Friday, 1 March 2019 at 09:00:43 UTC, BoQsc wrote:
I've installed D compiler, and when i try to run a D script 
with filename without an extension/file type named: program


via: ./program

I'm getting and error:

vaidas@SATELLITE-L855:~/Desktop$ ./program
Error: module `program` is in file './program.d' which cannot 
be read

import path[0] = .
import path[1] = /snap/dmd/49/bin/../import/druntime
import path[2] = /snap/dmd/49/bin/../import/phobos
Failed: ["/snap/dmd/49/bin/dmd", "-v", "-o-", "./program.d", 
"-I."]



Now, when I rename my scirpt file : program
To: program.d

and execute it by: ./program.d

I no longer have an error.

Is this an intended behaviour?


In such questions it's important to show your shebang since 
that's what runs your script.


Given your symptoms I guess you're using the following:

#!/bin/env rdmd

And indeed rdmd won't call your script if it doesn't have the 
proper extension.


Try using this instead:

#!/bin/dmd -run


The shebang I used: #!/usr/bin/env rdmd

I was visiting Dlang Tour and that's where I've got an example of 
shebang usage, directly from there:

https://tour.dlang.org/tour/en/welcome/run-d-program-locally#/on-the-fly-compilation-with-rdmd

The shebang you suggested actually works perfectly:
#!/bin/dmd -run


"And indeed rdmd won't call your script if it doesn't have the 
proper extension."


Then why does Dlang Tour includes shebang: #!/usr/bin/env rdmd

Instead of the one you mentioned, that is fool proof. (#!/bin/dmd 
-run)


Is that an error/mistake in Dlang Tour guide?





Re: How to attach function attributes to delegate type?

2019-03-01 Thread Vijay Nayar via Digitalmars-d-learn

On Wednesday, 27 February 2019 at 20:45:33 UTC, Alex wrote:
On Wednesday, 27 February 2019 at 20:03:15 UTC, Q. Schroll 
wrote:
For any type constructors like const, I can use ConstOf!T to 
get `T` with const attached. For a delegate/function type DG, 
e.g. int delegate(int), how can I get the @safe version of 
that type, i.e. int delegate(int) @safe?


I tried

alias SafeOf(DG) = DG @safe;

but it didn't compile.

The case is not @safe-specific; it's the same for all function 
attributes.


At https://p0nce.github.io/d-idioms/

there is a demonstration for @nogc:

´´´
import std.traits;

// Casts @nogc out of a function or delegate type.
auto assumeNoGC(T) (T t) if (isFunctionPointer!T || 
isDelegate!T)

{
enum attrs = functionAttributes!T | FunctionAttribute.nogc;
return cast(SetFunctionAttributes!(T, functionLinkage!T, 
attrs)) t;

}
´´´

Didn't try this for other cases, however...


When I need particular attributes, such as for a comparator, but 
also need to pass in a function as a template argument, one 
approach I've started to adopt is to only call this function from 
within a wrapper that has all the properties I want.


For example:

import std.stdio;

class MyThing(T, alias LessF) {
  // This wrapper defines the conditions for a valid LessF.
  @safe @nogc
  private static bool less(in T t1, in T t2) {
return LessF(t1, t2);
  }
}

void main()
{
  MyThing!(int, (a, b) => a < b) a;  // Compiles fine!
  MyThing!(int, (a, b) {
writeln("Not @nogc!");  // Compiler error!
return a < b;
  }) b;
}

The error looks like this, which is fairly readable too.

onlineapp.d(6): Error: `@nogc` function 
`onlineapp.main.MyThing!(int, (a, b)

{
writeln("Not @nogc!");
return a < b;
}
).MyThing.less` cannot call non-@nogc function


Re: My template tuple code does not compile

2019-03-01 Thread Simen Kjærås via Digitalmars-d-learn
On Wednesday, 27 February 2019 at 22:45:03 UTC, Victor Porton 
wrote:

I rewrote it again:

https://github.com/vporton/struct-params-dlang/blob/f50f7e5919f90b1d06bf0cc08e3055548aad1797/source/struct_params.d

But it does not work :-( What is my error?

source/struct_params.d(43,60): Error: function expected before 
`()`, not `()` of type `()`
source/struct_params.d(44,43): Error: undefined identifier 
`fieldsWithDefaults`
source/struct_params.d(56,11): Error: template instance 
`struct_params.ProviderParamsCode!("S", int, "x", float, "y")` 
error instantiating
source/struct_params.d(82,5): Error: mixin 
`struct_params.__unittest_L81_C1.ProviderParams!("S", int, "x", 
float, "y")` error instantiating


You seem to have misunderstood how staticMap works. It operates 
on a compile-time list of values, and only takes a single set of 
parameters: staticMap!(fn, item0, item1, item...), not 
staticMap!fn(item0, item1, item...).


In addition, Types.length.iota will create a run-time range of 
values, not a compile-time AliasSeq of values. For this, you can 
use std.meta.aliasSeqOf: staticMap!(regularField, 
aliasSeqOf!(Types.length.iota)).


Next, join expects a range, not an AliasSeq. In other words, 
staticMap!(...).join('\n') will fail to compile - staticMap!(...) 
will need to be turned into a range of some sort. We can do this 
the same way we'd turn any list of values into a range - by 
putting brackets around it. Just like [1,2,3] is a valid array, 
so is [staticMap!(...)], supposing the elements have some common 
type.


But wait - there's more! You're using __traits(identifier, 
Types[i]). As pointed out in 
https://forum.dlang.org/post/smgsgycpgvtagfsdx...@forum.dlang.org, this will fail for built-in types, as they don't have an identifier. You can get their names, as well as the name of any other type with Types[i].stringof.


Lastly, you have not imported std.typecons, so your use of 
Nullable will fail.


So, that's the issues that cause it to not compile. There are 
issues also in the code that isn't instantiated, i.e. 
callFunctionWithParamsStruct and 
callMemberFunctionWithParamsStruct. Since these aren't used, they 
don't cause compile failure yet. The main issue here is exactly 
the same as above: a conflation of run-time and compile-time 
responsibilities, this time when using map.


Since map is a run-time function, it can't do compile-time things 
like __traits(getMember) - you'll need to use staticMap for that. 
However, there's a much easier solution:


auto callFunctionWithParamsStruct(alias f, S)(S s) {
return f(s.tupleof);
}

The same thing can be done for callMemberFunctionWithParamsStruct.

Now, I will note that no checking is done that parameter names 
and field names match, so void fun(int numberOfBeans, string 
nameOfCat) can easily be called with struct S { int 
temperatureOfPudding; string declarationOfIndependence; }, but I 
will assume that's because you haven't gotten around to it yet.


--
  Simen


Re: Executing a D script without an [extension in the filename] leads to an error

2019-03-01 Thread Cym13 via Digitalmars-d-learn

On Friday, 1 March 2019 at 09:00:43 UTC, BoQsc wrote:
I've installed D compiler, and when i try to run a D script 
with filename without an extension/file type named: program


via: ./program

I'm getting and error:

vaidas@SATELLITE-L855:~/Desktop$ ./program
Error: module `program` is in file './program.d' which cannot 
be read

import path[0] = .
import path[1] = /snap/dmd/49/bin/../import/druntime
import path[2] = /snap/dmd/49/bin/../import/phobos
Failed: ["/snap/dmd/49/bin/dmd", "-v", "-o-", "./program.d", 
"-I."]



Now, when I rename my scirpt file : program
To: program.d

and execute it by: ./program.d

I no longer have an error.

Is this an intended behaviour?


In such questions it's important to show your shebang since 
that's what runs your script.


Given your symptoms I guess you're using the following:

#!/bin/env rdmd

And indeed rdmd won't call your script if it doesn't have the 
proper extension.


Try using this instead:

#!/bin/dmd -run




Executing a D script without an [extension in the filename] leads to an error

2019-03-01 Thread BoQsc via Digitalmars-d-learn
I've installed D compiler, and when i try to run a D script with 
filename without an extension/file type named: program


via: ./program

I'm getting and error:

vaidas@SATELLITE-L855:~/Desktop$ ./program
Error: module `program` is in file './program.d' which cannot be 
read

import path[0] = .
import path[1] = /snap/dmd/49/bin/../import/druntime
import path[2] = /snap/dmd/49/bin/../import/phobos
Failed: ["/snap/dmd/49/bin/dmd", "-v", "-o-", "./program.d", 
"-I."]



Now, when I rename my scirpt file : program
To: program.d

and execute it by: ./program.d

I no longer have an error.

Is this an intended behaviour?