Re: What exact debugging information is added to the binary and how to parse it all?

2022-05-13 Thread Basile B. via Digitalmars-d-learn

On Friday, 13 May 2022 at 16:11:14 UTC, BoQsc wrote:
Haven't used debuggers or debugged a lot just yet, but I've had 
this question in my mind and I'd like to inspect some debugging 
information manually. Are there some kind of documentation or 
specification and are there a lot of information that is hidden 
in a an average "debuggable" binary?


if you're on linux then the debug information are generated in a 
format that's well specified called DWARF.


DWARF essentially contain information about

- translation unit filename
- call stack
- each instruction of the runtime code is associated to a 
location (allowing to put breakpoints)

- the layout of user defined types (allowing to inspect instances)
- the inheritance chain of user defined types
- the variable types (alowing to inspect variables)

That's a lot of information, they non-trivially increase the size 
of the binary, but this is required to debug a program.


[learn more](https://dwarfstd.org/)...


Re: What are (were) the most difficult parts of D?

2022-05-12 Thread Basile B. via Digitalmars-d-learn
On Thursday, 12 May 2022 at 15:31:03 UTC, Steven Schveighoffer 
wrote:

On 5/12/22 11:18 AM, jmh530 wrote:

On Thursday, 12 May 2022 at 12:13:32 UTC, Basile B. wrote:

[snip]
```
is ( Type : TypeSpecialization , TemplateParameterList )
is ( Type == TypeSpecialization , TemplateParameterList )
is ( Type Identifier : TypeSpecialization , 
TemplateParameterList )
is ( Type Identifier == TypeSpecialization , 
TemplateParameterList )

```

I never remember those variants, because basically you never 
need them...

They were required for std.traits and that's it.


What's the difference between a Type and Type Identifier?


Type is a type, Identifier is an identifier.

In general, after such expressions, Identifier is now declared 
as an alias to the type, if the is expression was true. But in 
special forms, it might be a portion of the type.


So e.g.:

```d
static if(is(Foo Bar == struct))
{
  // inside here, it was determined that `Foo` was a type, and 
it is a

  // struct, and now, `Bar` is aliased to `Foo`
}
```

It's very confusing syntax though.

-Steve


yess that kind of stuff


Re: What are (were) the most difficult parts of D?

2022-05-12 Thread Basile B. via Digitalmars-d-learn

On Thursday, 12 May 2022 at 14:06:13 UTC, Arjan wrote:

On Thursday, 12 May 2022 at 11:05:08 UTC, Basile B. wrote:

On Wednesday, 11 May 2022 at 05:41:35 UTC, Ali Çehreli wrote:

- Operator overloading in certain cases was confusing, I 
remember that for one particular form once I had to use your 
book instead of the official specs (when opSlice and opIndex 
are combined)




I still have the thing :

```d
/**
 * CharMap is an helper struct that allows to test
 * if a char is within a set of characters.
 */
struct CharMap
{
private bool[] _map;
private dchar _min, _max;

private void setMinMax(dchar value) pure nothrow @safe
{
if (value <= _min) _min = value;
else if (value >= _max) _max = value;
_map.length = _max + 1 - _min;
}

/**
 * Used in the construction process.
 *
 * Params:
 *  lo = The dchar that defines the range lower bound.
 *  hi = The dchar that defines the range upper bound 
(inclusive).

 *
 * Examples:
 * ---
 * CharMap cm = CharMap['0'..'9'];
 * ---
 */
static CharRange opSlice(int index)(dchar lo, dchar hi) pure 
nothrow @safe @nogc

{
return CharRange(lo, hi);
}

/**
 * Used in the construction process.
 *
 * Params:
 *  a = A list made of character slices, of single 
characters or

 *
 * any other values whose type is implicitly convertible to 
dchar.

 *
 * Examples:
 * ---
 * CharMap cm = CharMap['0'..'9', '.', 'f', 'd', 38, 39];
 * ---
 */
static CharMap opIndex(A...)(A a) pure nothrow @safe
{
CharMap result;

// bounds
foreach(elem; a)
{
alias T = typeof(elem);
static if (isSomeChar!T || 
isImplicitlyConvertible!(T, dchar))

{
result.setMinMax(elem);
}
else static if (is(T == CharRange))
{
result.setMinMax(elem._min);
result.setMinMax(elem._max);
}
else static assert(0, "unsupported opIndex argument 
type: " ~ T.stringof);

}

result._map[] = false;
foreach(elem; a)
{
alias T = typeof(elem);
static if (isSomeChar!T || 
isImplicitlyConvertible!(T, dchar))

result._map[elem - result._min] = true;
else static if (is(T == CharRange))
{
foreach(size_t i; elem._min - result._min .. 
elem._max - result._min + 1)

result._map[i] = true;
}
}
return result;
}

/**
 * Returns true if a character is within the map.
 *
 * Params:
 *  c = A character or any value convertible to a dchar.
 */
bool opBinaryRight(string op = "in", C)(C c) const pure 
nothrow @safe @nogc

if (op == "in")
{
static if (isSomeChar!C || isImplicitlyConvertible!(C, 
dchar))

{
if (_min > c || c > _max) return false;
else return _map[c - _min];
}
else static assert(0, `invalid argument type for 
CharMap.opBinaryRight!"in"(): ` ~ C.stringof);

}
}
///
pure @safe unittest
{
CharMap cm = CharMap['a'..'f', '0'..'9' , 'A'..'F', '_', 9];
assert('a' in cm);
assert('b' in cm);
assert('c' in cm);
assert('d' in cm);
assert('e' in cm);
assert('f' in cm);
assert('g' !in cm);
assert('A' in cm);
assert('B' in cm);
assert('C' in cm);
assert('D' in cm);
assert('E' in cm);
assert('F' in cm);
assert('G' !in cm);
assert('0' in cm);
assert('4' in cm);
assert('9' in cm);
assert('_' in cm);
assert('%' !in cm);
assert('\t' in cm);
}
```





Re: What are (were) the most difficult parts of D?

2022-05-12 Thread Basile B. via Digitalmars-d-learn

On Thursday, 12 May 2022 at 12:13:32 UTC, Basile B. wrote:

On Thursday, 12 May 2022 at 11:50:59 UTC, Alain De Vos wrote:
Some keywords are overloaded and have different meaning when 
used in a different place.
Also some syntactic-sugar is way to much meaning too many 
different ways to do the same thing. I would prefer one way 
which is advised.


`ptr1 is ptr2` VS `is(T==U)` is ok even if the keyword is 
reused for two different things.


Problem is more (from 
https://dlang.org/spec/expression.html#is_expression)


```
is ( Type : TypeSpecialization , TemplateParameterList )
is ( Type == TypeSpecialization , TemplateParameterList )
is ( Type Identifier : TypeSpecialization , 
TemplateParameterList )
is ( Type Identifier == TypeSpecialization , 
TemplateParameterList )

```

I never remember those variants, because basically you never 
need them...

They were required for std.traits and that's it.


Perfect example of reuse that is never a problem : `final`.

what statically does `is` should have been several `__traits` I 
think.


Re: What are (were) the most difficult parts of D?

2022-05-12 Thread Basile B. via Digitalmars-d-learn

On Thursday, 12 May 2022 at 11:50:59 UTC, Alain De Vos wrote:
Some keywords are overloaded and have different meaning when 
used in a different place.
Also some syntactic-sugar is way to much meaning too many 
different ways to do the same thing. I would prefer one way 
which is advised.


`ptr1 is ptr2` VS `is(T==U)` is ok even if the keyword is reused 
for two different things.


Problem is more (from 
https://dlang.org/spec/expression.html#is_expression)


```
is ( Type : TypeSpecialization , TemplateParameterList )
is ( Type == TypeSpecialization , TemplateParameterList )
is ( Type Identifier : TypeSpecialization , TemplateParameterList 
)
is ( Type Identifier == TypeSpecialization , 
TemplateParameterList )

```

I never remember those variants, because basically you never need 
them...

They were required for std.traits and that's it.


Re: What are (were) the most difficult parts of D?

2022-05-12 Thread Basile B. via Digitalmars-d-learn

On Wednesday, 11 May 2022 at 05:41:35 UTC, Ali Çehreli wrote:
What are you stuck at? What was the most difficult features to 
understand? etc.


To make it more meaningful, what is your experience with other 
languages?


Ali


Overhall I think that D was not hard to learn because well 
designed (i.e intuitive).


A few specific points however that I remember

- Certain variant forms of the `is` Expression are not obvious 
(not intuitive), I'm pretty sure I still cant use them without a 
quick look to the specs.


- Operator overloading in certain cases was confusing, I remember 
that for one particular form once I had to use your book instead 
of the official specs (when opSlice and opIndex are combined)


The main difficulty I had is actually not specific to D. It was 
to accept that a GC is OK.


Re: Trait for "can be instantiated"?

2022-05-11 Thread Basile B. via Digitalmars-d-learn

On Tuesday, 10 May 2022 at 16:10:26 UTC, Ben Jones wrote:

On Tuesday, 10 May 2022 at 16:05:15 UTC, H. S. Teoh wrote:
Using wrapper structs, etc., for this is IMO total overkill. 
Just use an enum for your token types.  Something like this 
would suffice:


That's basically what sumtype is going to do for me, but 
(hopefully) more safely. Also, the token types are "user 
defined,"  my lexer just grabs everything annotated with @Token 
and passes those types/wrapped enums to sumtype.


How about being more explicit in the UDA ?
The idea would be to associate the enum value to a type or not:

```d
import std.traits;
import std.stdio;

struct Token(T);

struct Token(T...)
if (T.length == 0) { }

@Token!(string) enum str_tok;
@Token!(float)  enum float_tok;
@Token!()   enum lparen_tok;

void main()
{
alias toks = getSymbolsByUDA!(mixin(__MODULE__), Token);

static foreach (t; toks)
{{
alias U = getUDAs!(t, Token);
alias A = TemplateArgsOf!(U);
static if (A.length)
pragma(msg, "add a `" ~ A[0].stringof ~ "`for `" ~ 
t.stringof ~ "`");

else
pragma(msg, "no SumType data needed for `" ~ 
t.stringof ~ "`");

}}
}
```


Re: Make shared static this() encoding table compilable

2022-03-14 Thread Basile B. via Digitalmars-d-learn

On Monday, 14 March 2022 at 09:40:00 UTC, zhad3 wrote:
Hey everyone, I am in need of some help. I have written this 
Windows CP949 encoding table 
https://github.com/zhad3/zencoding/blob/main/windows949/source/zencoding/windows949/table.d which is used to convert CP949 to UTF-16.


After some research about how to initialize immutable 
associative arrays people suggested using `shared static 
this()`. So far this worked for me, but I recently discovered 
that DMD cannot compile this in release mode with optimizations.


`dub build --build=release`  or `dmd` with `-release -O` fails:

```
code  windows949
function  
zencoding.windows949.fromWindows949!(immutable(ubyte)[]).fromWindows949

code  table
function  zencoding.windows949.table._sharedStaticCtor_L29_C1
dmd failed with exit code -11.
```


That's a compiler bug of type "ICE", the compiler crashes.
Try reducing to a simple module that does not use phobos and 
report to bugzilla.




Re: Detecting manifest contants

2022-03-13 Thread Basile B. via Digitalmars-d-learn

On Saturday, 12 March 2022 at 18:49:32 UTC, Anonymouse wrote:
I'm introspecting structs, and I ran into an issue where  
`__traits(derivedMembers)` includes manifest constant enums in 
the returned tuple.


What is the correct way to statically detect these? The 
immediate thing that springs to mind is `is(symbol == enum)`, 
but it's not it.


Currently I'm testing if a function that takes the address of 
the member compiles, and I think it works, but like with 
everything `__traits(compiles)` it strikes me as it might not 
be the right way to go about things.


```d
struct Foo
{
int i;
enum k = 42;
}

void main()
{
foreach (memberstring; __traits(derivedMembers, Foo))
{
static if (__traits(compiles, { Foo f; auto ptr = 
&__traits(getMember, f, memberstring); }))

{
// ...
}
}
}
```

What else can I try?


A way is to try declaring an enum with the value returned by the 
`getMember` trait.


```d
/**
 * Indicates wether something is a value known at compile time.
 *
 * Params:
 *  V = The value to test.
 *  T = Optional, the expected value type.
 */
template isCompileTimeValue(alias V, T...)
if (T.length == 0 || (T.length == 1 && is(T[0])))
{
enum isKnown = is(typeof((){enum v = V;}));
static if (!T.length)
enum isCompileTimeValue = isKnown;
else
enum isCompileTimeValue = isKnown && is(typeof(V) == 
T[0]);

}
///
unittest
{
string a;
enum b = "0";
enum c = 0;
static assert(!isCompileTimeValue!a);
static assert(isCompileTimeValue!b);
static assert(isCompileTimeValue!c);
static assert(isCompileTimeValue!(b,string));
static assert(isCompileTimeValue!(c,int));
static assert(!isCompileTimeValue!(c,char));
static assert(!isCompileTimeValue!(char));
}

/// ditto
template isCompileTimeValue(V, T...)
if (T.length == 0 || (T.length == 1 && is(T[0])))
{
enum isCompileTimeValue = false;
}
```



Re: https://run.dlang.io/ vs All dmd compilers (2.060 - latest)

2022-02-28 Thread Basile B. via Digitalmars-d-learn

On Sunday, 27 February 2022 at 16:14:31 UTC, Matheus wrote:

Hi,

[...]

After one minute I think I get:

rdmd playground.d

Server error:

Thanks,

Matheus.


This was [reported before]. Apparently this would be caused by a 
timeout.


[reported before]: 
https://forum.dlang.org/post/skc2dd$1o52$1...@digitalmars.com


Re: Set output location for dub --single

2022-02-28 Thread Basile B. via Digitalmars-d-learn

On Sunday, 27 February 2022 at 16:58:34 UTC, Chris Piker wrote:

Hi D

Coming from a python background it's worked well to organize my 
D projects as a dub `sourceLibrary` and then to put top level 
programs in a directory named `scripts` that are just dub 
single file projects.  So the layout looks like this:


[...]

After reading over the dub documentation I don't see a general 
way to override project options via the command line, but maybe 
it's there and I couldn't understand what the dub docs were 
trying to say.


That 's not exactly what you ask for but you can define the path 
in the embedded recipe (targetPath)


```d
#!/usr/bin/env dub
/+ dub.sdl:
   dependency "mypackage" version="*" path=".."
   targetPath "./bin"
+/
```



Re: Why writeln can't be converted to nothrow with just catching of StdioException

2022-02-21 Thread Basile B. via Digitalmars-d-learn

On Monday, 21 February 2022 at 11:12:38 UTC, partypooper wrote:

On Monday, 21 February 2022 at 11:07:55 UTC, Basile B. wrote:
Yeah there must be another one then. Something actionnable is 
the documentation.


What about Mike Parker answer?


if nothrow fails that's because things are checked. We could 
imagine a second flow analysis leading to better error messages. 
You see, instead of the generic error message you get now.


"If it fails, let's see why"


Re: Why writeln can't be converted to nothrow with just catching of StdioException

2022-02-21 Thread Basile B. via Digitalmars-d-learn

On Monday, 21 February 2022 at 11:05:42 UTC, partypooper wrote:

On Monday, 21 February 2022 at 10:58:26 UTC, Basile B. wrote:

more likely UTFException actually


Additionaly catching UTF and Conv exceptions doesn't help.


Yeah there must be another one then. Something actionnable is the 
documentation.


Re: Why writeln can't be converted to nothrow with just catching of StdioException

2022-02-21 Thread Basile B. via Digitalmars-d-learn

On Monday, 21 February 2022 at 10:49:13 UTC, partypooper wrote:
Do I completely not understand what is `nothrow` or why I can't 
make function nothrow with just catching StdioException?


This doesn't work
```d
nothrow void hello() {
  try {
writeln("Hello, World!")
  } catch (StdioException) {}
}
```
This doest work
```d
nothrow void hello() {
  try {
writeln("Hello, World!")
  } catch (Exception) {}
}
```


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


Re: Why writeln can't be converted to nothrow with just catching of StdioException

2022-02-21 Thread Basile B. via Digitalmars-d-learn

On Monday, 21 February 2022 at 10:53:56 UTC, Basile B. wrote:

On Monday, 21 February 2022 at 10:49:13 UTC, partypooper wrote:
Do I completely not understand what is `nothrow` or why I 
can't make function nothrow with just catching StdioException?


This doesn't work
```d
nothrow void hello() {
  try {
writeln("Hello, World!")
  } catch (StdioException) {}
}
```
This doest work
```d
nothrow void hello() {
  try {
writeln("Hello, World!")
  } catch (Exception) {}
}
```


I believe it's because it can throw ConvException as well ;)


more likely UTFException actually


Re: Why writeln can't be converted to nothrow with just catching of StdioException

2022-02-21 Thread Basile B. via Digitalmars-d-learn

On Monday, 21 February 2022 at 10:53:56 UTC, Basile B. wrote:

On Monday, 21 February 2022 at 10:49:13 UTC, partypooper wrote:
Do I completely not understand what is `nothrow` or why I 
can't make function nothrow with just catching StdioException?


This doesn't work
```d
nothrow void hello() {
  try {
writeln("Hello, World!")
  } catch (StdioException) {}
}
```
This doest work
```d
nothrow void hello() {
  try {
writeln("Hello, World!")
  } catch (Exception) {}
}
```


I believe it's because it can throw ConvException as well ;)


However you're totally right to open a discussion, the 
documentation is innacurate:


in https://dlang.org/phobos/std_stdio.html#.writeln

just StdioException is mentioned ;)


Re: Why writeln can't be converted to nothrow with just catching of StdioException

2022-02-21 Thread Basile B. via Digitalmars-d-learn

On Monday, 21 February 2022 at 10:49:13 UTC, partypooper wrote:
Do I completely not understand what is `nothrow` or why I can't 
make function nothrow with just catching StdioException?


This doesn't work
```d
nothrow void hello() {
  try {
writeln("Hello, World!")
  } catch (StdioException) {}
}
```
This doest work
```d
nothrow void hello() {
  try {
writeln("Hello, World!")
  } catch (Exception) {}
}
```


I believe it's because it can throw ConvException as well ;)


Re: keyword as struct field

2022-02-20 Thread Basile B. via Digitalmars-d-learn

On Sunday, 20 February 2022 at 11:08:55 UTC, partypooper wrote:

Hello, I'm new to D.

Title is self described, is it possible to use keyword as 
struct field?


Maybe it is XYproblem, so here I will describe a little what I 
need.
I'm parsing some json currently with 
[mir-ion](https://code.dlang.org/packages/mir-ion) 
(better/simpler suggestions for only json de/serialization?), 
that has "version" as one of it's keys, so I can't use that as 
field in my struct. Maybe some annotation in mir library to 
parse "version" into other struct field name, can't find though 
(its docs pretty concise).


I have a library solution based on opDispatch + 
__traits(getMember):


```d
/**
 * Mixin template allowing to use a field as if its identifier is 
a D keyword.

 * Note that this only works with `__traits(getMember)`.
 * Params:
 *  keywordFieldPairs = An array of keyword and field pairs.
 */
template FieldOfKeyword(string[2][] keywordFieldPairs)
{
template opDispatch(string member)
{
static foreach (pair; keywordFieldPairs)
static if (member == pair[0])
mixin("alias opDispatch = ", pair[1], ";" );
}
}
///
unittest
{
struct Foo
{
mixin FieldOfKeyword!([["scope", "scope_"],["class", 
"class_"]]);

string scope_;
string class_;
}

Foo foo;
__traits(getMember, foo, "scope") = "The Universe";
assert(__traits(getMember, foo, "scope") == "The Universe");
__traits(getMember, foo, "class") = "Atom";
assert(__traits(getMember, foo, "class") == "Atom");
}
```

never used it TBH.


Re: Declaring a reusable formula and using it in other scopes.

2022-02-12 Thread Basile B. via Digitalmars-d-learn

On Saturday, 12 February 2022 at 12:36:06 UTC, BoQsc wrote:

`bool nextArgumentDoesNotReachEndOfArray = i + 1 < args.length;`

How can I declare it out of scope and reuse it in any scope 
that has `i` and `args.length` declared?


Here is an ugly solution, just to encourage someone else to post 
better:


```d
enum n = "i+1The problem of the initial problem is to have automatic capture 
of `i` and `args` in any scope...


Lost cause ?


Re: Is there an equivavlent to C# boxing in D?

2022-02-12 Thread Basile B. via Digitalmars-d-learn

On Saturday, 12 February 2022 at 16:50:16 UTC, H. S. Teoh wrote:

Without alias this it would be harder to pull off, yes.


I don't see any other way that allows to unbox *implictly*.
That would require a new operator. Something like opCast but more 
permissive, that works without `cast`.





Re: ldc executable crashes with this code

2022-02-02 Thread Basile B. via Digitalmars-d-learn

On Thursday, 3 February 2022 at 01:51:34 UTC, Basile B. wrote:

On Thursday, 3 February 2022 at 01:39:33 UTC, forkit wrote:
On Wednesday, 2 February 2022 at 23:30:50 UTC, H. S. Teoh 
wrote:

[...]


that explains ldc perhaps (although i don't really get it. 
It's cast to mutable and being assigned to mutable.


in any case... ldc doesn't like it, but dmd is fine with this 
??


your cast from immutable to mutable is an undefined behavior, 
this may work or not.


Note that casting away a const qualifier and then mutating is 
undefined behavior, too, even when the referenced data is 
mutable. This is so that compilers and programmers can make 
assumptions based on const alone. For example, here it may be 
assumed that f does not alter x:


(from https://dlang.org/spec/const3.html#removing_with_cast)


the D safe way :

```
void main() @safe
{
char[] palindrome = "able was I ere I saw elba".dup;
writeln(palindrome);
writeln(palindrome.reverse);
}
```


Re: ldc executable crashes with this code

2022-02-02 Thread Basile B. via Digitalmars-d-learn

On Thursday, 3 February 2022 at 01:39:33 UTC, forkit wrote:

On Wednesday, 2 February 2022 at 23:30:50 UTC, H. S. Teoh wrote:

[...]


that explains ldc perhaps (although i don't really get it. It's 
cast to mutable and being assigned to mutable.


in any case... ldc doesn't like it, but dmd is fine with this ??


your cast from immutable to mutable is an undefined behavior, 
this may work or not.


Note that casting away a const qualifier and then mutating is 
undefined behavior, too, even when the referenced data is 
mutable. This is so that compilers and programmers can make 
assumptions based on const alone. For example, here it may be 
assumed that f does not alter x:


(from https://dlang.org/spec/const3.html#removing_with_cast)


Re: Is DMD still not inlining "inline asm"?

2021-11-13 Thread Basile B. via Digitalmars-d-learn

On Friday, 12 November 2021 at 00:46:05 UTC, Elronnd wrote:

On Thursday, 11 November 2021 at 13:22:15 UTC, Basile B. wrote:

As for now, I know no compiler that can do that.


GCC can do it.  Somewhat notoriously,


you meant "infamously" ?

LTO can lead to bugs from underspecified asm constraints 
following cross-TU inlining.


I have missed the LTO train TBH, gotta try that once...


Re: Is DMD still not inlining "inline asm"?

2021-11-11 Thread Basile B. via Digitalmars-d-learn

On Thursday, 11 November 2021 at 08:58:43 UTC, rempas wrote:
I've seen from 
[this](https://forum.dlang.org/post/op.vrzngqeavxi10f@biotronic-laptop) reply in a thread from 2011 that DMD will not inline functions that contain inline assembly. Is this still the case?


Yes, this is still the case. A particularity of DMD inliner is 
that it does its job in the front-end, so inlining asm is totally 
impossible. Then, even if inlining was done in the backend 
inlining of asm would not be guaranteed because the byte code is 
generated at a very late stag, which causes problem with the 
registry allocator, the preservation of the stack, etc.


For example ldc2 does not inline a trival asm func 
https://godbolt.org/z/1W6r693Tq.


As for now, I know no compiler that can do that.


Re: Possible runtime bug in preprocessing of command line arguments passed to the D main

2021-10-24 Thread Basile B. via Digitalmars-d-learn

On Sunday, 24 October 2021 at 14:38:44 UTC, jfondren wrote:

[...]

With nothing to the contrary, I'd take "must be terminated by a 
null pointer" as "can't itself be a null pointer".




ah yeah, and thanks, of course ... how would the count of arg be 
known without the sentinel...


Re: Possible runtime bug in preprocessing of command line arguments passed to the D main

2021-10-24 Thread Basile B. via Digitalmars-d-learn

On Sunday, 24 October 2021 at 14:21:52 UTC, Basile B. wrote:

The following code, on linux
[...]
What do you think ?


Forgot to say that this change

```diff
- execv("a", null);
+ execv("a", ["whatever".ptr].ptr);
```

makes the problem goes away, so it would be caused by how `null` 
args are handled, presumably.


Possible runtime bug in preprocessing of command line arguments passed to the D main

2021-10-24 Thread Basile B. via Digitalmars-d-learn

The following code, on linux

```d
module runnable;
​
extern(C) int execv(const char* p, const char** args);
​
immutable src = `
import std.getopt;
void main(string[] args)
{
bool c;
getopt(args, "c", );
}
`;
​
void prepareProgram()
{
import std.process  : execute;
import std.file : write;
write("a.d", src);
execute(["dmd", "a.d"]);
}
​
void main(string[] args)
{
prepareProgram();
execv("a", null);
}
```

results in a std.getopt exception:

object.Exception@/usr/include/dmd/phobos/std/getopt.d(423): 
Invalid arguments string passed: program name missing


Context is a program not written in D that uses execv to call a D 
program that uses getopt.


What do you think ?


Re: How to make a function that accepts optional struct but can accept struct literal too

2021-10-16 Thread Basile B. via Digitalmars-d-learn

On Friday, 15 October 2021 at 20:33:33 UTC, JN wrote:
Is there some nice way of achieving something like this C99 
code in D?


[...]


The 
[literal](https://www.ibm.com/docs/sr/xl-c-and-cpp-aix/13.1.0?topic=operators-compound-literal-expressions) in the C version creates an alloca too but it's hidden.


Re: Better debugging?

2021-10-03 Thread Basile B. via Digitalmars-d-learn

On Sunday, 3 October 2021 at 22:21:45 UTC, Tim wrote:

Hi all,

I am currently using GDB within VScode with the -gc DMD2 
compiler switch and my debugging is not amazing. Whenever I 
inspect a struct/object it just shows me the pointer rather 
than the object information and strings come up as a gross 
array of the characters. Does anybody happen to know whether 
LDB is better or how I can have a nicer debug environment?


Thanks in advance


1. LDC2 generate better debug infos, especially for classes, 
although this might change from the next DMD version (it will 
include the inherited fields, just like LDC2).


2. to inspect objects you must evluate the dereference of an 
instance.


for example for a project, if  i eval `d`, a class instance VS 
`*d`, the pointed chunk of memory.


| name| value
| ---| ---
d | 0x77b4b480
s | 0x77b506c0
locParentAggr | 0x0
symParentAggr | 0x0
thisParentAggr | 0x0
needInheritance | false
this | 0x77b506c0
loc | 0x77b43ea0
evaluation of `d` | 0x77b4b480
evaluation of `*d` | { = { 
= {}, startPos = {line = 18, column = 1}, ir = 
0x0}, name = 0x77b4e5e0, symbol = 0x77b506c0, attributes 
= 0x0, asTypeDeclared = 0x77b50720, kind = 34 '\"', 
protection = 0 '\\000', progress = 0 '\\000'}


I don't know how the debugger gui you use works, here this is 
just a paste of dexed-ide table for locals and custom 
expressions. More often I use a debug popup:


![](https://i.imgur.com/cGdQfOr.png)

[A similar feature seems possible in 
vscode](https://github.com/microsoft/vscode-java-debug/issues/444), maybe post a feature request to the extension developpers, as the debug popup is often very handy (no need to type expressions, as they are already there in the code !)


Re: Mutually recursive template expansion

2021-10-02 Thread Basile B. via Digitalmars-d-learn

On Saturday, 2 October 2021 at 08:48:24 UTC, Stephen wrote:

Is this by design?


No but it's easily explainable.

## without mixins

```d
struct Ar { Br b; ubyte a; }
struct Br { ubyte b; }
```

`Ar` semantic starts, members are analyzed, that begins with the 
variable declaration `Br b`. `Br` type needs to be resolved. `Br` 
can be found in the AST as it is declared manually. Now `Br` is 
run and finally `Ar` sema continues.


## with mixins

```d
mixin(q{struct Ar { Br b; ubyte a; }});
mixin(q{struct Br { ubyte b; }});
```

The first mixin is compiled (`compileIt()` in dmd code base).

The AST is now the same as obtained by parsing

```d
struct Ar { Br b; ubyte a; }
mixin(q{struct Br { ubyte b; }});
```

`Ar` semantic starts, members are analyzed, that begins with the 
variable declaration`Br b`. But `Br` cannot be resolved because 
**it is not yet in the AST** and the symbol tables.


Re: 0 cost template instantiation

2021-09-29 Thread Basile B. via Digitalmars-d-learn

On Thursday, 30 September 2021 at 02:02:19 UTC, Hipreme wrote:

On Thursday, 30 September 2021 at 01:56:42 UTC, Basile B. wrote:

On Thursday, 30 September 2021 at 01:09:47 UTC, Hipreme wrote:
I have a template function that all it does is given a 
symbol, it loads a dll for its type + its name:


```
void loadSymbol(alias s, string symName = "")()
{
static if(symName == "")
s = cast(typeof(s))_loadSymbol(_dll, (s.stringof~"\0").ptr);
else
s = cast(typeof(s))_loadSymbol(_dll, (symName~"\0").ptr);
}
```


The main problem is that this function is costing 2KB per 
instantiation, which is something pretty high. Specially if I 
inline, there is almost no cost when compared to its inline 
version. Trying to use pragma(inline, true) didn't do 
anything too.


cant you just use a regular functions ? loading happens at 
runtime right ?



The entire reason to having that function is having that syntax 
which would pretty much do the monkey's job for me:


Instead of writing

myFunction = cast(typeof(myFunction))_loadSymbol(_dll, 
"myFunction");


I could write

loadSymbol!myFunction;

But if no other way is found of doing that, I will do the 
massive rewriting.


Anyway, I don't think the problem is not in the way I'm doing, 
but the output, as that template could easily be inlined


well ok. Maybe try to see if overloads

  void loadSymbol(alias s)()
  void loadSymbol(alias s, string symName)()

helps. That save the static if. In addition there's the null 
sentinel that can save a bit of memory, as you've been suggested.


Re: 0 cost template instantiation

2021-09-29 Thread Basile B. via Digitalmars-d-learn

On Thursday, 30 September 2021 at 01:09:47 UTC, Hipreme wrote:
I have a template function that all it does is given a symbol, 
it loads a dll for its type + its name:


```
void loadSymbol(alias s, string symName = "")()
{
static if(symName == "")
s = cast(typeof(s))_loadSymbol(_dll, (s.stringof~"\0").ptr);
else
s = cast(typeof(s))_loadSymbol(_dll, (symName~"\0").ptr);
}
```


The main problem is that this function is costing 2KB per 
instantiation, which is something pretty high. Specially if I 
inline, there is almost no cost when compared to its inline 
version. Trying to use pragma(inline, true) didn't do anything 
too.


cant you just use a regular functions ? loading happens at 
runtime right ?


Re: Which operators cannot be overloaded and why not?

2021-09-13 Thread Basile B. via Digitalmars-d-learn

On Monday, 13 September 2021 at 14:42:42 UTC, jfondren wrote:

On Monday, 13 September 2021 at 14:33:03 UTC, user1234 wrote:

- condition al expression ` cond ? exp : exp `


And many other boolean operators, unary !, binary && and ||

https://dlang.org/spec/operatoroverloading.html lists all the 
overloadable operators, and 
https://dlang.org/spec/expression.html has all the operators, 
so "which operators" is a matter of close comparison. "why not" 
is much harder to answer.


Oh! I have never noticed that `&&` and `||`, despite of being 
quite "ordinary" binary ops are not overloadable.


In 
[styx](https://styx-lang.gitlab.io/styx/attribute.html#operatorattribute) that works because, although inspired by the D way, in the sense that overloads are implemented in custom types, the selection is done using an expression template


```d
struct S {
@operator(a && b) function andAnd(T other): auto {return 
false}

}
```

So as long as the expression in the attribute argument looks like 
a valid expression the stuff is found (and the supprot code in 
the compiler is super simple), e.g with code in a body:


```d
e1 && e2; // look if e1 is an aggregate and if it contains 
@operator(a && b)
e1 + e2;  // look if e1 is an aggregate and if it contains 
@operator(a && b)

```

While D uses specific identifier + templates value param for 
strings.

(note that only the equivalent of D opBinary**Right** works...)

anyway. zorry for this off-topic.


Re: GDC - program runs in one thread, DMD - in 4 threads, why?

2021-09-10 Thread Basile B. via Digitalmars-d-learn

On Friday, 10 September 2021 at 09:27:49 UTC, eugene wrote:

Here is test program (which is using DList aggressively)
[...]
Can this (really unwanted) behavior be disabled in DMD?
I do not want to have multiple threads,
a program (real program, not the test above) has to be 
single-threaded.


system used:
@dexp ~ $ cat /etc/debian_version
8.11


most recent dmd has a GC that collect in threads. it can be tuned 
but I dont find the documentation for this right now.


Re: Absence of isAllocator trait

2021-09-06 Thread Basile B. via Digitalmars-d-learn

On Saturday, 4 September 2021 at 19:43:27 UTC, Per Nordlöw wrote:
Is there a reason for the absence of an `isAllocator` trait 
under `std.experimental.allocator`?


I had ask a similar Q once and I've been told that (more or less):

It's because the clients of an allocator should rather statically 
check for specific traits of an allocator, there are too many 
possible permutations of capabilities possible, not all can 
allocate and deallocate, not all can reallocate, and so on.


actually I'm 100% sure that what you want is `isMallocator` and 
not `isAllocator` ;)


Re: issue with static foreach

2021-07-22 Thread Basile B. via Digitalmars-d-learn

On Thursday, 22 July 2021 at 05:57:02 UTC, jfondren wrote:

On Thursday, 22 July 2021 at 03:43:44 UTC, someone wrote:
... it compiles no-more: Error: found `End of File` when 
expecting `}` following compound statement


... what I am doing wrong ?


You'll get the same error from this code:

```d
unittest {
mixin("{");
mixin("}");
}
```

https://dlang.org/spec/statement.html#mixin-statement

The text contents of the string must be compilable as a valid 
StatementList, and is compiled as such.


Each individual string has to compile on its own. You'll have 
to concatenate strings and then mixin them.


There was a similar issue on bugzilla, and the consensus for 
closing is that mixins are not supposed to introduce scopes (or 
unmatched scopes, let's say).


See https://issues.dlang.org/show_bug.cgi?id=3858#c4

However the specs are indeed not up to date with that.


Re: LLVM asm with constraints, and 2 operands

2021-07-19 Thread Basile B. via Digitalmars-d-learn

On Monday, 19 July 2021 at 10:21:58 UTC, kinke wrote:

On Sunday, 18 July 2021 at 16:32:46 UTC, Basile B. wrote:

- **=x** says "returns in whatever is has to"
- **x** (1) is the constraint for input `a`, which is passed 
as operand **$0**
- **x** (2) is the constraint for input `b`, which is passed 
as operand **$1**


$0 is actually the output operand, $1 is `a`, and $2 is `b`.
[...]
Note: inline asm syntax and resulting asm in AT syntax, *not* 
Intel syntax.


yeah thnaks for the precision, I totally forgot about that.

And what about the `extern(C)` issue ? Does it make sense to be 
used when the parameters are int4 ?


Re: LLVM asm with constraints, and 2 operands

2021-07-18 Thread Basile B. via Digitalmars-d-learn

On Sunday, 18 July 2021 at 17:45:05 UTC, Guillaume Piolat wrote:

On Sunday, 18 July 2021 at 16:32:46 UTC, Basile B. wrote:

[...]


Thanks.

Indeed that seems to work even when inline and optimized. 
Registers are spilled to stack.
A minor concern is what happens when the enclosing function is 
extern(C) => https://d.godbolt.org/z/s6dM3a3de

I need to check that more...


I think this should be rejected just like when you use D arrays 
in the interface of an `extern(C)` func, as C has no equivalent 
of __vector (afaik).


Re: LLVM asm with constraints, and 2 operands

2021-07-18 Thread Basile B. via Digitalmars-d-learn

On Sunday, 18 July 2021 at 18:47:50 UTC, Basile B. wrote:

On Sunday, 18 July 2021 at 17:45:05 UTC, Guillaume Piolat wrote:

On Sunday, 18 July 2021 at 16:32:46 UTC, Basile B. wrote:

[...]


Thanks.

Indeed that seems to work even when inline and optimized. 
Registers are spilled to stack.
A minor concern is what happens when the enclosing function is 
extern(C) => https://d.godbolt.org/z/s6dM3a3de

I need to check that more...


I think this should be rejected just like when you use D arrays 
in the interface of an `extern(C)` func, as C has no equivalent 
of __vector (afaik).


but in any case there's a bug.


Re: LLVM asm with constraints, and 2 operands

2021-07-18 Thread Basile B. via Digitalmars-d-learn

On Sunday, 18 July 2021 at 11:42:24 UTC, Guillaume Piolat wrote:

Is anyone versed in LLVM inline asm?

I know how to generate SIMD unary op with:

return __asm!int4("pmovsxwd $1,$0","=x,x",a);

but I struggle to generate 2-operands SIMD ops like:

return __asm!int4("paddd $1,$0","=x,x",a, b);

If you know how to do it => https://d.godbolt.org/z/ccM38bfMT  
it would probably help build speed of SIMD heavy code, also -O0 
performance
Also generating the right instruction is good but it must 
resist optimization too, so proper LLVM constraints is needed. 
It would be really helpful if someone has understood the 
cryptic rules of LLVM assembly constraints.


Yeah I can confirm it's aweful. Took me hours to understand how 
to use it a bit (my PL has [an 
interface](https://styx-lang.gitlab.io/styx/primary_expressions.html#asmexpression) for LLVM asm)


You need to add a "x" to the constraint string

return __asm!int4("paddd $1,$0","=x,x,x",a, b);

- **=x** says "returns in whatever is has to"
- **x** (1) is the constraint for input `a`, which is passed as 
operand **$0**
- **x** (2) is the constraint for input `b`, which is passed as 
operand **$1**


So the thing to get is that the output constraint does not 
consume anything else, it is standalone.




Re: Faster Dlang Execution

2021-06-08 Thread Basile B. via Digitalmars-d-learn

On Tuesday, 8 June 2021 at 17:10:47 UTC, seany wrote:

Hello

How can I increase the speed of executable files created via :

`dub build -b release`



try `dub build -b release --compiler=ldc2`

Then you can set some specific DFlags for ldc, like -O3 or --mcpu

I am unable to parallellise all of it, as it depends on part of 
the result being calculated before something else can be 
calculated.


I have many `nonsafe, nonpure` functions.


`nothrow` presumably opens optimisation opportunities with the 
stack management, although it's not verified



Classes are virtual  by defalut.


set them final when possible. When not possible set the virtual 
methods that

are not overridden `final`.

Profiling doesn't help, because different input is causing 
different parts of the program to become slow.


if you're on linux, you can try callgrind + kcachegrind instead 
of builtin intrumentation.



Thank you.





Re: Compiler Explorer Assembly Output for C, C++ and D (dlang)

2021-05-27 Thread Basile B. via Digitalmars-d-learn

On Thursday, 27 May 2021 at 08:47:50 UTC, Tariq Siddiqui wrote:
When using Compiler Explorer (https://godbolt.org/) to compare 
assembly output of simple programs, why D language assembly 
output is so long compared to C or C++ output. The simple 
square function output is the same for C, C++, and D, but the D 
output has additional lines that are not highlighted when 
hovering over the square function in the source code.


 - What are these additional lines?
 - How can I remove these lines from being generated?


In addition to other answers, see 
https://forum.dlang.org/post/myrjutqyzpzlyltrd...@forum.dlang.org


Re: cannot I override and mark it as private?

2021-05-12 Thread Basile B. via Digitalmars-d-learn

On Wednesday, 12 May 2021 at 19:35:31 UTC, Jack wrote:
I'd to change the visibility of a method overrided from public 
to private but it doesn't work tho to protected it does. Why is 
that?

...
Why is that? why must I leave it accessible somehow (even if 
it's protected) to all derived class of my derived class?


See specs : 
https://dlang.org/spec/attribute.html#visibility_attributes


Symbols with private visibility can only be accessed from 
within the same module. Private member functions are implicitly 
final and cannot be overridden.





Re: alias & local function

2021-05-09 Thread Basile B. via Digitalmars-d-learn

On Monday, 10 May 2021 at 01:25:10 UTC, Alain De Vos wrote:

This does not:
```
import std.stdio;
void main()
{
int afunction(int x){return x;};


it's not static so -> context -> delegate


alias myint = int;
myint i=5;
alias tfunction = int function(int);
tfunction f = & afunction;
writeln(f(1));
}
```
It gives compile error :
Error: cannot implicitly convert expression  of type 
int delegate(int x) pure nothrow @nogc @safe to int 
function(int)


add static in the second case.




Re: class grammar

2021-05-07 Thread Basile B. via Digitalmars-d-learn

On Friday, 7 May 2021 at 18:07:45 UTC, Nick wrote:
The class grammar, as defined in the D language specification 
...
is not clear to me how a user-defined type (such as a class or 
interface) is also a 'BasicType' (as defined by the grammar). 
However, the compiler only accepts classes or interfaces as a 
base type.




Just like a natural language what is grammatically correct is not 
necessarily semantically correct.


In the case of the inherithence list it's easier to choose 
'BasicType' because 'TypeOf' and 'QualifiedIdentifier' can both 
be solved to a class or an interface.


With this example:

```
alias B = int;
class A : B {}
```

you can see that the semantic check to reject `int` is necessary 
anyway.





Re: Since dmd 2.096.0: import `x.t` is used as a type

2021-05-02 Thread Basile B. via Digitalmars-d-learn

On Sunday, 2 May 2021 at 15:41:13 UTC, kdevel wrote:

On Saturday, 1 May 2021 at 16:32:32 UTC, Basile B. wrote:
Hard breakage is not acceptable, even if the goal is to 
introduce a more correct behavior.


I still wonder why module names are taken as a candidates for 
types and functions in the first place. Isn't there a symbol 
table for module names separate from that for type and function 
names?


I dont think so. That would lead to special cases in fully 
qualified lookups.
Lookups must follow the reverse lexical order of declarations so 
an import adds a symbols in the current scope.


BTW during the PR review the problem you encounter [was 
anticipated](https://github.com/dlang/dmd/pull/12178#issuecomment-773886263) si I guess you're stuck with [the author answer](https://github.com/dlang/dmd/pull/12178#issuecomment-773902749), i.e "this worked because of a special case".


Again you can still try to get the change turn into a deprecation 
first, that'd be legit.


Just checked how things are done in another language where 
modules are called “packages”:


I have checked in styx too. This does not work either but for 
another reason that D, that is that overloads are explicit, 
meaning all names unique in a given scope, so


```styx
§s.sx
unit s;

§u.sx
unit v;

struct s {}

import s;

var s s1;
```

gives


u.sx:8:8: error, symbol `s` already declared line 6


same when the import and the var decls positions are exchanged.


Re: Fake IFTI-compatible struct constructors

2021-05-01 Thread Basile B. via Digitalmars-d-learn

On Saturday, 1 May 2021 at 21:57:54 UTC, Chad Joan wrote:
I came up with a couple techniques for making it seem like 
templated structs deduce their template parameters from 
constructor invocations. These are given further down in the 
post.

...

However, this was not to be. Rather, this setup doesn't work at 
all, because IFTI doesn't seem to work on function-templates 
with alias parameters.


Yes your observation is correct. That should work but this is 
currently not implemented and referenceced as [issue 
20877](https://issues.dlang.org/show_bug.cgi?id=20877)


Re: Since dmd 2.096.0: import `x.t` is used as a type

2021-05-01 Thread Basile B. via Digitalmars-d-learn

On Friday, 30 April 2021 at 21:41:43 UTC, kdevel wrote:

On Friday, 30 April 2021 at 19:17:14 UTC, user1234 wrote:
[...]
Likely a side effect of 
https://github.com/dlang/dmd/pull/12178 but

according to me the new behavior is correct.


It breaks my code. I have files named $C containing struct or 
class $C plus some other stuff. Using the workaround means to 
switch to selective imports for all used types/functions within 
this module.


Found another workaround: I created a symlink here -> . and 
replaced all imports $C with here.$C. In some places I had to 
remove an artificial  "prefix" ($C.$C -> $C).


I understand the situation but I can opnly suggest to fill a 
report.
Hard breakage is not acceptable, even if the goal is to introduce 
a more correct behavior.


Re: Derived type

2021-03-31 Thread Basile B. via Digitalmars-d-learn

On Wednesday, 31 March 2021 at 04:49:50 UTC, novice3 wrote:

On Tuesday, 30 March 2021 at 21:53:34 UTC, Basile B. wrote:

struct Typedef(TBase)
{
   TBase payload;
   alias payload this;
}

alias Xobj = Typedef!(void*);


This is how std.typecons.Typedef made, IMHO.

The problem is this code generate struct with name 
"Typedef!(void*)",

then compiler show this name (not "Xobj") in messages:

https://run.dlang.io/is/eEI2yC

  void* bad;
  foo(bad);

Error: function foo(Typedef!(void*) obj) is not callable using 
argument types (void*)
   cannot pass argument bad of type void* to parameter 
Typedef!(void*) obj


yeah template instances are identified using the parameters 
identifiers, then the alias is just a syntactic shortcut to that, 
not producing a new symbol with a unique mangle... but the 
message is correct assuming you want void* to be rejected.


That being said you can still use a string mixin if the messages 
have to be correct


---
string genTypeDef(TBase)(string name)
{
return "struct " ~ name ~ "{" ~ TBase.stringof ~ " payload; 
alias payload this;}";

}

mixin(genTypeDef!(void*)("Xobj"));

void foo (Xobj obj) {}
---


Re: Derived type

2021-03-30 Thread Basile B. via Digitalmars-d-learn

On Tuesday, 30 March 2021 at 19:47:41 UTC, novice2 wrote:

My tries to make template for struct and alias this:

// variant 1
template Typedef(alias Tnew, Tbase)
{
  struct Tnew
  {
Tbase payload;
alias payload this;
  }
}



you must give a name to the template specialization, using alias 
[1], also the TypeDef declaration can be highly simplified:


---
struct Typedef(TBase)
{
   TBase payload;
   alias payload this;
}

alias Xobj = Typedef!(void*);

void foo (Xobj obj) {}
---


[1]: https://dlang.org/spec/declaration.html#alias



Re: Using onOutOfMemoryError in C wrappers

2021-03-24 Thread Basile B. via Digitalmars-d-learn

On Wednesday, 24 March 2021 at 08:51:34 UTC, Per Nordlöw wrote:

On Wednesday, 24 March 2021 at 08:31:19 UTC, Basile B. wrote:
There are several ways to do that. In addition to 
onOutOfMemoryError, you can use a static instance


  void v() @nogc nothrow
  {
__gshared oom = new OutOfMemoryError();
auto X* = X_create();
if (X is null)
throw oom;
  }


How is that better than

void v() @nogc nothrow
{
auto X* = X_create();
if (X is null)
onOutOfMemoryError();
}

considering the fact that accessing `__gshared` state is 
neither `@safe` nor `pure`? Which, in turn, makes `v()` 
unconditionally unsafe and unpure regardless of safety and 
purity of `X_create()`.


In now way. But in your question you mentioned @nogc nothrow and 
not @safe and pure.


Re: Using onOutOfMemoryError in C wrappers

2021-03-24 Thread Basile B. via Digitalmars-d-learn

On Wednesday, 24 March 2021 at 07:58:22 UTC, Per Nordlöw wrote:
When wrapping C code that tries to allocate memory resources 
via functions such as


X* X_create();

should one call `onOutOfMemoryError();` upon null return?

Making more D wrappers `nothrow @nogc`.



There are several ways to do that. In addition to 
onOutOfMemoryError, you can use a static instance or `if (somePtr 
is null) assert(0);`


  void v() @nogc nothrow
  {
__gshared oom = new OutOfMemoryError();
auto X* = X_create();
if (X is null)
throw oom;
  }


Re: Checking for manifest constants

2021-03-05 Thread Basile B. via Digitalmars-d-learn

On Friday, 5 March 2021 at 08:23:09 UTC, Bogdan wrote:
I was using a trick with dmd to check for manifest constants 
which worked until dmd v2.094. Yesterday I tried it on the 
latest compiler and it failed with:



source/introspection/manifestConstant.d(37,28): Error: need 
this for name of type string
source/introspection/type.d(156,13): Error: value of this is 
not known at compile time


any ideas how to fix it? or, is it a bug with dmd?

```

/// Check if a member is manifest constant
bool isManifestConstant(T, string name)() {
  mixin(`return is(typeof(T.init.` ~ name ~ `)) && 
!is(typeof(` ~ name ~ `));`);

}

/// ditto
bool isManifestConstant(alias T)() {
  return is(typeof(T)) && !is(typeof());
}

enum globalConfig = 32;
int globalValue = 22;

unittest {
  struct Test {
enum config = 3;
int value = 2;
  }

  static assert(isManifestConstant!(Test.config));
  static assert(isManifestConstant!(Test, "config"));
  static assert(isManifestConstant!(globalConfig));

  static assert(!isManifestConstant!(Test.value));
  static assert(!isManifestConstant!(Test, "value"));
  static assert(!isManifestConstant!(globalValue));
}

void main() {}


```


Hello, you can use this template instead:

  template isManifestConstant(alias V, T...)
  if (T.length == 0 || (T.length == 1 && is(T[0])))
  {
enum isKnown = is(typeof((){enum v = V;}));
static if (!T.length)
enum isManifestConstant = isKnown;
else
enum isManifestConstant = isKnown && is(typeof(V) == 
T[0]);

  }

The optional T is to verify if it is a compile time constant of a 
certain type.

the tests you wrote and that are not based on a string pass.



Re: Dimensions in compile time

2021-02-08 Thread Basile B. via Digitalmars-d-learn

On Monday, 8 February 2021 at 13:27:14 UTC, Vindex wrote:

Thanks everyone!

The solution that works for me now looks like this:


template ndim(T) {
static if (std.traits.isArray!T) {
static if (is(typeof(T.init[0]))) {
alias SubArrayType = typeof(T.init[0]);
enum ndim = ndim!SubArrayType + 1;
}
else enum ndim = 1;
}
else enum ndim = 0;
}
unittest {
assert(ndim!(int[]) == 1);
assert(ndim!(int[][]) == 2);
assert(ndim!(int[4][3]) == 2);
assert(ndim!(int[][2][]) == 3);
assert(ndim!(string) == 1);
}


Nice. You should look at Rumbu solution too. It possibly has a 
better behavior toward the recursive expansion. Also interesting 
to learn the more advanced use of "is".


Re: Dimensions in compile time

2021-02-08 Thread Basile B. via Digitalmars-d-learn

On Monday, 8 February 2021 at 13:13:33 UTC, Basile B. wrote:

On Monday, 8 February 2021 at 13:09:53 UTC, Rumbu wrote:

On Monday, 8 February 2021 at 12:19:26 UTC, Basile B. wrote:

[...]


dimensionCount!string should be 2.

My take without std.traits:

template rank(T: U[], U)
{
   enum rank = 1 + rank!U;
}

template rank(T: U[n], size_t n)
{
enum rank = 1 + rank!U;
}

template rank(T)
{
enum rank = 0;
}


yeah you're right, strings were a special case (I remember now) 
so that stuff could be stored as literals.


well to OP just dont use my dimensionCount template ^^. it should 
have been declared with the "package" protection in first place; 
not public.


Re: Dimensions in compile time

2021-02-08 Thread Basile B. via Digitalmars-d-learn

On Monday, 8 February 2021 at 13:09:53 UTC, Rumbu wrote:

On Monday, 8 February 2021 at 12:19:26 UTC, Basile B. wrote:

[...]


dimensionCount!string should be 2.

My take without std.traits:

template rank(T: U[], U)
{
   enum rank = 1 + rank!U;
}

template rank(T: U[n], size_t n)
{
enum rank = 1 + rank!U;
}

template rank(T)
{
enum rank = 0;
}


yeah you're right, strings were a special case (I remember now) 
so that stuff could be stored as literals.


Re: Dimensions in compile time

2021-02-08 Thread Basile B. via Digitalmars-d-learn

On Monday, 8 February 2021 at 12:19:26 UTC, Basile B. wrote:

On Monday, 8 February 2021 at 11:42:45 UTC, Vindex wrote:

[...]


yeah.

---
template dimensionCount(T)
{
static if (isArray!T)
{
static if (isMultiDimensionalArray!T)
{
alias DT = typeof(T.init[0]);
enum dimensionCount = dimensionCount!DT + 1;
}
else enum dimensionCount = 1;
}
else enum dimensionCount = 0;
}
///
unittest
{
static assert(dimensionCount!char == 0);
static assert(dimensionCount!(string[]) == 1);
static assert(dimensionCount!(int[]) == 1);
static assert(dimensionCount!(int[][]) == 2);
static assert(dimensionCount!(int[][][]) == 3);
}
---

that can be rewritten using some phobos traits too I think, but 
this piece of code is very old now, more like learner template.


well I didn't realize but static array are not handled. I think 
this is because in first place this was made for a specific usage 
that was a serializer.


Re: Dimensions in compile time

2021-02-08 Thread Basile B. via Digitalmars-d-learn

On Monday, 8 February 2021 at 11:42:45 UTC, Vindex wrote:

size_t ndim(A)(A arr) {
return std.algorithm.count(typeid(A).to!string, '[');
}

Is there a way to find out the number of dimensions in an array 
at compile time?


yeah.

---
template dimensionCount(T)
{
static if (isArray!T)
{
static if (isMultiDimensionalArray!T)
{
alias DT = typeof(T.init[0]);
enum dimensionCount = dimensionCount!DT + 1;
}
else enum dimensionCount = 1;
}
else enum dimensionCount = 0;
}
///
unittest
{
static assert(dimensionCount!char == 0);
static assert(dimensionCount!(string[]) == 1);
static assert(dimensionCount!(int[]) == 1);
static assert(dimensionCount!(int[][]) == 2);
static assert(dimensionCount!(int[][][]) == 3);
}
---

that can be rewritten using some phobos traits too I think, but 
this piece of code is very old now, more like learner template.


Re: core.atomic for ldc.

2021-01-31 Thread Basile B. via Digitalmars-d-learn

On Monday, 1 February 2021 at 06:12:59 UTC, vitamin wrote:
On Monday, 1 February 2021 at 05:23:52 UTC, rikki cattermole 
wrote:
The only difference between dmd, ldc and gdc (in effect) is 
the backend.
While druntime and Phobos will be patched for other platform 
targets, over all its the same library.


The same goes for core.atomic. You should not need to know 
that it has been patched. If you can call it and it gives you 
the right results, you can assume it worked.


Oh and $ dub build --compiler=ldc2


problem is when I build with ldc then id doesn't work and with 
dmd it does:


try compile this with ldc:
https://run.dlang.io/is/gngLFu

error on webite run.dlang.io is same as I have.


LDC has all LLVM intrinsics so try

---
import ldc.intrinsics;
ldc.intrinsics.llvm_atomic_rmw_add(...);
---


Re: How define accepted types in a template parameter?

2021-01-16 Thread Basile B. via Digitalmars-d-learn

On Saturday, 16 January 2021 at 18:39:03 UTC, Marcone wrote:
For example, I want my function template to only accept integer 
or string;


You can do that with either

- `static if` inside the body [1]

  import std.traits;
  void foo(T)(T t)
  {
static if (isIntegral!T) {}
else static assert false;
  }


- template constraint [2]

  import std.traits;
  void foo(T)(T t)
  if (isIntegral!T)
  {
  }

- template parameter specialization [3]

  void foo(T : ulong)(T t) // : meaning implictly convert to
  {
  }


2 and 3 being the more commonly used.
1 is more to use the same body instead of using N overloads

[1] : https://dlang.org/spec/version.html#staticif
[2] : https://dlang.org/spec/template.html#template_constraints
[3] : 
https://dlang.org/spec/template.html#parameters_specialization


Re: Template alias as template specialisation not recognized.

2021-01-15 Thread Basile B. via Digitalmars-d-learn

On Saturday, 16 January 2021 at 01:21:24 UTC, Paul wrote:
I'm having issues when trying to use a template alias as a 
template specialisation.

When using the following:

alias Vec(uint size, Type) = Mat!(size, 1, Type);


void setUniform(V : Vec!(L, bool), int L)(string name, V 
value) {...}



Vec!(4, bool) a;
setUniform("test", a);


I get the following error:
template `shader.Shader.setUniform` cannot deduce function 
from argument types `!()(string, Mat!(4u, 1u, bool))`, 
candidates are:DUB
shader.d(43, 7): `setUniform(V : Vec!(L, bool), uint L)(string 
name, V value)`


Meanwhile, when using the following, I have no issues:
void setUniform(V : Mat!(L, 1, bool), int L)(string name, V 
value) {}


In this case you can use a const template parameter:

  alias Vec(uint size, Type, const uint length = 1) = Mat!(size, 
length, Type);


Although this is not a generic workaround for the issue mentioned.


Re: Open question: what code pattern you use usually for null safety problem

2021-01-15 Thread Basile B. via Digitalmars-d-learn

On Thursday, 14 January 2021 at 18:24:44 UTC, ddcovery wrote:
I know there is other threads about null safety and the 
"possible" ways to support this in D and so on.

[...]
If it's not a bother, I'd like to know how you usually approach 
it


[...]

Thanks!!!


I have a opDispatch solution here [1], probably very similar to 
the other opDispatch solution mentioned. It is used in d-scanner 
since several years, e.g here [2]. I'd like to have this as a 
first class operator because as usual in D,  you can do great 
things with templates but then completion is totally unable to 
deal with them. Also There's a great difference between using the 
template to do refacts and using it to write new code. Very 
frustrating to write `safeAcess(stuff). ` and no completion popup 
appears.


[1]: 
https://gitlab.com/basile.b/iz/-/blob/master/import/iz/sugar.d#L1655
[2]: 
https://github.com/dlang-community/D-Scanner/blob/2963358eb4a24064b0893493684d4075361297eb/src/dscanner/analysis/assert_without_msg.d#L42





Re: Why many programmers don't like GC?

2021-01-14 Thread Basile B. via Digitalmars-d-learn

On Wednesday, 13 January 2021 at 18:58:56 UTC, Marcone wrote:
I've always heard programmers complain about Garbage Collector 
GC. But I never understood why they complain. What's bad about 
GC?


Semi serious answer:

In the domain of hoby-ism and small companies programmers that 
work with statically typed languages all believe that they are 
super hero in the domain of memory managment. When they see "GC" 
they think that they are considered as 2nd grade student ^^


It's basically snobbism.


Re: Hardcoded filepaths in compiled exe

2020-12-29 Thread Basile B. via Digitalmars-d-learn
On Wednesday, 30 December 2020 at 01:21:37 UTC, Steven 
Schveighoffer wrote:

On 12/29/20 7:46 PM, Basile B. wrote:
On Tuesday, 29 December 2020 at 23:11:25 UTC, Steven 
Schveighoffer wrote:
But I would think a feature should exist that masks the base 
directory of exception file names.


Probably worth an enhancement request.



Also aren't dmd output binaries supposed to be "reproducible" ?


If you had an option to change __FILE__ to be canonical, then 
it could be.


i.e. instead of:

C:\D\dmd2\windows\bin\..\..\src\phobos\std\file.d

you stored:

(imports)\std\file.d

where (imports) (or maybe some other token) was substituted in 
for the base of every import. Files passed on the command line 
would just store the __FILE__ as it was passed.


-Steve


actually the string 
"C:\D\dmd2\windows\bin\..\..\src\phobos\std\file.d"

looks like it comes from how the ini file variables are expanded.

__FILE__ is not supposed to represent an absolute file name 
unless the compiler get passed absolute file names. That why 
__FILE_FULL_PATH__ was added at some point.


Re: Hardcoded filepaths in compiled exe

2020-12-29 Thread Basile B. via Digitalmars-d-learn
On Tuesday, 29 December 2020 at 23:11:25 UTC, Steven 
Schveighoffer wrote:
But I would think a feature should exist that masks the base 
directory of exception file names.


Probably worth an enhancement request.

-Steve


Also aren't dmd output binaries supposed to be "reproducible" ?


Re: Hardcoded filepaths in compiled exe

2020-12-29 Thread Basile B. via Digitalmars-d-learn

On Tuesday, 29 December 2020 at 21:27:07 UTC, Raikia wrote:

Interesting.  I was able to clobber it with bbe with no issues.
 I'm surprised the compiler doesn't strip out this potentially 
sensitive metadata, but I guess I'll just patch it out as part 
of my build process.  Thanks!


Other super safe options are to use either a VM or a CI service 
to build the releases.


Re: dmd: enum to!string slows down compilation

2020-12-29 Thread Basile B. via Digitalmars-d-learn

On Tuesday, 29 December 2020 at 22:42:16 UTC, kdevel wrote:

Why is the enum to!string conversion so slow?

~~~slowenumtostringconversion.d
private enum S { A, B, C, D, };

[...]


one factor is all the template constraints that are evaluated 
until the right std.conv.to overload gets selected.


Re: Hardcoded filepaths in compiled exe

2020-12-29 Thread Basile B. via Digitalmars-d-learn

On Tuesday, 29 December 2020 at 16:13:53 UTC, Raikia wrote:

Hey all,

[...]
$ strings -a program.exe | grep 'dmd2'
C:\D\dmd2\windows\bin\..\..\src\phobos\std\file.d
C:\D\dmd2\windows\bin\..\..\src\phobos\std\utf.d
C:\D\dmd2\windows\bin\..\..\src\phobos\std\base64.d


This problem is more egregious when I am using a home folder, 
like "C:\Users\\" instead of "C:\D\".  Am I missing 
something?  Is there a way to compile D without leaking 
metadata like this in a production release binary?


I believe those are because of Exception constructors that use 
the __FILE__ special keyword. You might patch the final 
executable and replace the string content with spaces or 'x's.


Re: Get the code of any D-entity as string?

2020-12-27 Thread Basile B. via Digitalmars-d-learn

On Sunday, 27 December 2020 at 12:20:01 UTC, sighoya wrote:

On Sunday, 27 December 2020 at 04:13:53 UTC, Max Haughton wrote:
Not possible although implementing as a __trait would be about 
15 lines I think.




I think that too, and it would nicely reuse the work of the 
compiler to parse the whole project.


I think read only AST access in some form would actually be 
quite nice, if not for dmd's AST being fuckugly (the hierarchy 
is fine but it's more gcc than clang)


The point is, once we have that we can decide ourselves which 
framework is the best for meta modelling.


Is it pure string manipulation or token stream manipulation à 
la Rust or an AST manipulation à la Nim/Scala. It can be all 
defined on top.


A more concrete example of what you are trying to achieve would 
allow to show the D way.


Re: Get the code of any D-entity as string?

2020-12-26 Thread Basile B. via Digitalmars-d-learn

On Saturday, 26 December 2020 at 12:38:21 UTC, sighoya wrote:

On Friday, 25 December 2020 at 23:04:15 UTC, Ali Çehreli wrote:

I am probably misunderstanding it but there is the .stringof 
property for all types: T.stringof.


But does stringof really print the declaration as string and 
not the type name itself?


I found: https://dlang.org/spec/property.html#stringof

I am probably stating the obvious but you normally import the 
interesting modules of that library anyway and the type 
information is available that way.


Ali


Well, certainly, yes. But only if `stringof` would do the job. 
The best thing would be to retrieve whole modules (abstract 
files) as string. On top of that we can retrieve any value/type 
declaration.


with __traits(allMembers) you can rebuild the declaration. For a 
struct that works well.


---
struct E {int a;}
struct S
{
ulong[] a;
@E(0) const int b;
void v() const {}
void v(int) const {}
}

string getDeclaration(T)()
if (is(T == struct))
{
import std.traits, std.meta;
string result = "struct " ~ T.stringof ~ " {\n";
static foreach (m; __traits(allMembers, T))
{{
static if (isCallable!(__traits(getMember, T, m)))
alias sym = __traits(getOverloads, T, m);
else
alias sym = AliasSeq!(__traits(getMember, T, m));
static foreach (s; sym)
{
result ~= "";
static foreach (a; __traits(getAttributes, s))
result ~= "@" ~ a.stringof ~ " ";
static if (is(typeof(s)))
result ~= typeof(s).stringof ~ " " ~ m ~ ";\n";
}
}}
result ~= "}";
return result;
}

pragma(msg, getDeclaration!S);
---


Re: gdb + Windows 64: No debugging symbols found

2020-12-26 Thread Basile B. via Digitalmars-d-learn
On Saturday, 26 December 2020 at 11:55:58 UTC, Виталий Фадеев 
wrote:

We have:
[...]
Problem is:
$ gdb ./app.exe
GNU gdb (GDB) 9.2
...
(No debugging symbols found in ./app.exe)

What is a right way to build .exe and debug with gdb ?


Try to build with latest version of LDC and use the -gdwarf 
option.

This will generate debug info that GDB can understand.


Re: Slice allocation after appending

2020-12-22 Thread Basile B. via Digitalmars-d-learn

On Tuesday, 22 December 2020 at 22:12:29 UTC, Rekel wrote:
According to the D slice article 
(https://dlang.org/articles/d-array-article.html), slices do 
not care where they start, only where they end, when checking 
whether expanding in place is permitable, or at least that is 
what I understood regarding it.


Now I'm unsure how to check this, I tried to a bit using the 
online editor and a bit of pointer usage which seemed to 
confirm my suspicion, but does this mean that taking a (small) 
slice at the end of a (possibly) very large dynamic array can 
lead to problematic behavior?


No there's some runtime and GC magic under the hood. Appending on 
the slice is more like a smart "copy on append" operation so "a" 
will always ends with -1 and "b" with 2. It's described here : 
https://dlang.org/articles/d-array-article.html#how-it-works


Re: Can I use dub to generate docs?

2020-12-14 Thread Basile B. via Digitalmars-d-learn

On Monday, 14 December 2020 at 02:54:12 UTC, Jack wrote:

like dmd's -D flag?


you can try

   $ dub run harbored-mod -- $(find -iname *.d)

That will generate doc for all d source in the current working 
directory.




Re: How to check that function gets ref parameter?

2020-12-13 Thread Basile B. via Digitalmars-d-learn
On Sunday, 13 December 2020 at 16:41:06 UTC, Andrey Zherikov 
wrote:
I'm trying to check that function has 'ref' parameter. The only 
way I found so far is to use std.traits.Parameters.


Here is the code I have:
void f(int) {}
void g(ref int) {}
void main()
{
writeln(Parameters!f[0].stringof);
writeln(__traits(isRef, Parameters!f[0]));
writeln(Parameters!g.stringof);
writeln(Parameters!g[0].stringof);
writeln(__traits(isRef, Parameters!g[0]));
}

The output is:
int
false
(ref int)
int
false

"Parameters!g[0]" strips off 'ref' qualifier as you can see. 
How can I make it work?


You use the wrong traits, try ParameterStorageClassTuple instead:

  void f(int) {}
  void g(ref int) {}
  import std.traits : ParameterStorageClass, 
ParameterStorageClassTuple;
  static assert(ParameterStorageClassTuple!g[0] == 
ParameterStorageClass.ref_);
  static assert(ParameterStorageClassTuple!f[0] != 
ParameterStorageClass.ref_);





Re: Is this a compiler error? "recursive template expansion"

2020-12-08 Thread Basile B. via Digitalmars-d-learn

On Tuesday, 8 December 2020 at 20:11:40 UTC, Nathan S. wrote:
The following code fails to compile. Is this a compiler error 
or if not what is wrong with the code?


What is wrong is that partial specialization is not correct.
The correct partial specialization is:

---
struct Template2(T)
{
enum tString = T.stringof;
static if (is(T == class))
enum tLinkage = __traits(getLinkage, T);
}

struct Template1(Param1, Param2 = Template2!Param1) {}

alias AliasTemplate1S(SecondParam) = Template1!(S,SecondParam);
//^here

class S
{
Template1!int x;
}
---

Now that being said, the compiler could complain about the 
incorrect partial spec instead of falling in the nonsensical 
error message.


There is a gap because the second template param looks optional 
so you dont put it the partial specialization but it is still 
required.


Anyway. This case is either a "bad diagnostic" or an 
"enhancement" request.

Or should be specified.


Re: betterC question

2020-11-19 Thread Basile B. via Digitalmars-d-learn
On Thursday, 19 November 2020 at 00:07:12 UTC, Dibyendu Majumdar 
wrote:

I have simple test program:

import core.stdc.stdio : printf;

void test() {
int* a;
printf("a == null %d\n", a == null);
}

int function() fp = test;

extern (C) void main() {
fp();
}

Why do I get:

\d\dmd-2.092.1\windows\bin64\dmd.exe -betterC tests.d
tests.d(5): Error: printf cannot be interpreted at compile 
time, because it has no available source code


This is on Windows


IMO another problem here is that `function` and `delegate` are 
special cases of the `*` postfix. With a syntax like


int()* fp = test

it would be more obvious to new comers that `&` is missing.
This is a syntax I experiment in STYX for example [1].


Note that then there's also the problem with functions pointers 
requiring a context. This context is not necessarily a `this` 
(for closures it's a frame obviously).


[1] 
https://gitlab.com/basile.b/styx/-/blob/master/tests/backend/function_pointers.sx#L10


Re: Best way to confine project to 64 bit builds only?

2020-10-17 Thread Basile B. via Digitalmars-d-learn

On Saturday, 17 October 2020 at 14:50:47 UTC, NonNull wrote:
I have inherited an open source C project that assumes that the 
size of a long and the size of a pointer are the same, and I 
have translated it into very similar D just like 
https://dlang.org/blog/2018/06/11/dasbetterc-converting-make-c-to-d/


D has the size of long fixed at 64 bits, so a pointer now has 
to be 64 bits.


No it's wrong. A pointer always has the size of a general purpose 
register.


So I want to put something into the source to ensure an attempt 
to make a 32 bit build fails. What is the best way to do this?


anyway you have several options:

---
version(X86)
static assert (false, "not for i386");
---

or

---
static assert (size_t.sizeof != 4, "blablalala");
---


Re: Count template parameters of method

2020-10-11 Thread Basile B. via Digitalmars-d-learn

On Sunday, 11 October 2020 at 06:53:59 UTC, Andrey wrote:

Hello,

How to count a number of parameters in uninitialized template 
method?


For example:

struct Test
{
void abc(int a, bool status, string text)() {}
{


The method "Test.abc" has three template paramenters.

I know that "TemplateArgsOf" exists but it is used only for 
INITIALIZED templates...


You can count the commas in the text representation  but this is 
not a good solution. The default value of a 
TemplateValueParameter can lead to wrong results, for example if 
it's an array literal or a string literal.


---
size_t countTP(alias T)()
{
import std.algorithm : count;
return T.stringof.count(',') + 1;
}

template T1(A){}
template T2(A,B){}
template T3(A,B,C){}

void main()
{
pragma(msg, countTP!T1);
pragma(msg, countTP!T2);
pragma(msg, countTP!T3);
}
---

probably the countTP function can be enhanced to handle corner 
cases I mentioned.


Re: Deprecation in traits

2020-09-30 Thread Basile B. via Digitalmars-d-learn

On Tuesday, 29 September 2020 at 17:08:40 UTC, 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?


The problem has been observed already and it is an official 
enhancement request [1].
I think it is legit because deprecation are sometimes used to 
help into refactoring, so to have the use site is a essential.


[1] https://issues.dlang.org/show_bug.cgi?id=21176


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

2020-08-24 Thread Basile B. via Digitalmars-d-learn

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 ) ?


Re: Introspecting a package for submodules

2020-08-24 Thread Basile B. via Digitalmars-d-learn

On Tuesday, 25 August 2020 at 00:09:38 UTC, Adam D. Ruppe wrote:

On Monday, 24 August 2020 at 22:32:52 UTC, Anonymouse wrote:

How do I do this? (Is there some other way?)


Not really a way. A package doesn't quite exist in D; there is 
no formal construct that is a package and has a defined list if 
stuff.


Wrong. Packages and modules exist in D as derived of 
ScopeDsymbol. OP just encounters a small bug.


https://github.com/dlang/dmd/pull/11619


Re: alias restriction??!

2020-07-19 Thread Basile B. via Digitalmars-d-learn

On Sunday, 19 July 2020 at 15:00:59 UTC, Paul Backus wrote:

On Sunday, 19 July 2020 at 12:42:47 UTC, Carl Sturtivant wrote:

On Sunday, 19 July 2020 at 12:08:07 UTC, Paul Backus wrote:


Easiest workaround:

ref inout(long) Second() inout { return second.one; }


Was trying to avoid this for performance reasons. In fact what 
are the performance implications of this sort of thing with 
current implementations? --- relative to using a simple offset.


Almost certainly no difference at all. Even DMD can inline this 
function:


https://d.godbolt.org/z/7ve6M8


The alias proposal matches to the "code fast" moto. When you do 
object composition with several level of nesting this would be a 
time saver.


Re: alias restriction??!

2020-07-18 Thread Basile B. via Digitalmars-d-learn

On Saturday, 18 July 2020 at 22:49:18 UTC, Dennis wrote:
On Saturday, 18 July 2020 at 18:46:16 UTC, Carl Sturtivant 
wrote:
Is there any way to avoid the duplication of the entries in 
the anonymous union, aside from using a mixin template?


I think this would be fixed if 
https://github.com/dlang/dmd/pull/11273 gets merged.


The feature still needs some work. With this PR aliases of 
members only works when they are declared in a function scope and 
not in the aggregate scope.


Example:

---
struct Inner
{
int a;
}

struct TopLevel
{
Inner inner;
alias ia = inner.a;
}

void main()
{
TopLevel tl;
alias ia = tl.inner.a;
ia = 42;// OK with PR 11273
tl.ia = 42; // NG Error: need `this` for `a` of type `int`
}
---

I think it's not good to merge until the second case works.
Also it requires approval. For now it is specified that 
expressions cant be aliased.


Re: Uploading coverage to Codecov doesn't work

2020-07-14 Thread Basile B. via Digitalmars-d-learn

On Tuesday, 14 July 2020 at 17:52:25 UTC, Basile B. wrote:

On Tuesday, 14 July 2020 at 11:05:17 UTC, Mitacha wrote:

On Saturday, 11 July 2020 at 09:43:39 UTC, Basile B. wrote:

On Wednesday, 8 July 2020 at 15:55:58 UTC, Mitacha wrote:
I filed an issue on codecov community forum 
https://community.codecov.io/t/uploading-d-lang-coverage-doesnt-work/1740

So hopefully, someone will look at this.


Bookmarked. Thanks much for taking the time to register on 
their forums, I didn't want to.


Forgot to say. In my case I suspect that this is caused by a 
force push, like here 
https://community.codecov.io/t/force-push-intermittently-leads-to-codecov-not-updating-pr/68/2. But a problem can hide another I might be afected by this one plus the same as you, who knows.


Re: Uploading coverage to Codecov doesn't work

2020-07-14 Thread Basile B. via Digitalmars-d-learn

On Tuesday, 14 July 2020 at 11:05:17 UTC, Mitacha wrote:

On Saturday, 11 July 2020 at 09:43:39 UTC, Basile B. wrote:

On Wednesday, 8 July 2020 at 15:55:58 UTC, Mitacha wrote:
I filed an issue on codecov community forum 
https://community.codecov.io/t/uploading-d-lang-coverage-doesnt-work/1740

So hopefully, someone will look at this.


Bookmarked. Thanks much for taking the time to register on their 
forums, I didn't want to.


Re: Uploading coverage to Codecov doesn't work

2020-07-11 Thread Basile B. via Digitalmars-d-learn

On Wednesday, 8 July 2020 at 15:55:58 UTC, Mitacha wrote:

Hello there,

I've been trying to setup bitbucket pipelines to submit 
coverage to codecov, but with no luck.
I use `dub run -b unittest-cov` and it generates .lst files 
correctly, then `bash <(curl -s https://codecov.io/bash) -t 
$CODECOV_TOKEN` is called, but all I get is:


```
==> Bitbucket detected.
project root: .
Yaml not found, that's ok! Learn more at 
http://docs.codecov.io/docs/codecov-yaml

==> Running gcov in . (disable via -X gcov)
==> Python coveragepy not found
==> Searching for coverage reports in:
+ .
--> No coverage report found.
Please visit http://docs.codecov.io/docs/supported-languages
```
No reports were uploaded.

The thing I'm concerned about is "--> No coverage report 
found.". I checked and token is supplied. I ran same commands 
locally and get same result.


Is there some magic configuration in yaml file necessary, to 
make that work?


It's broken for me too, on gitlab,...

---
GitLab CI detected.
project root: .
--> token set from env
Yaml found at: ./.codecov.yml
==> Running gcov in . (disable via -X gcov)
==> Python coveragepy not found
==> Searching for coverage reports in:
+ .
--> No coverage report found.
Please visit http://docs.codecov.io/docs/supported-languages
---

That used to work perfectly. Note that it's broken for DMD test 
suite too.


Re: Generating struct .init at run time?

2020-07-02 Thread Basile B. via Digitalmars-d-learn

On Thursday, 2 July 2020 at 10:37:27 UTC, kinke wrote:
I don't think a struct should ever be that large, as it can 
probably only live on the heap anyway and only passed around by 
refs. I'd probably use a thin struct instead, containing and 
managing a `double[]` member (or `double[elementCount]*`).


so right but the compiler should definitively not crash.



Re: filter custom version id from __traits code

2020-06-09 Thread Basile B. via Digitalmars-d-learn

On Tuesday, 9 June 2020 at 18:08:01 UTC, Stanislav Blinov wrote:

On Tuesday, 9 June 2020 at 17:40:10 UTC, Basile B. wrote:


Any idea ?


As I replied in the issue report:


Instead of

static if (!is(mixin(member) == module) && 
!(is(mixin(member


use

static if (is(typeof(mixin(member


Yes thanks again for the help.


filter custom version id from __traits code

2020-06-09 Thread Basile B. via Digitalmars-d-learn
I don't see how to filter a custom version identifier from this 
traits code:


---
module test;

import std.traits   : isCallable;
version(all) version = my_version;

private bool onlyFuncs()
{
bool result = true;
foreach (member; __traits(allMembers, mixin(__MODULE__)))
{
static if (!is(mixin(member) == module) && 
!(is(mixin(member
static if (__traits(getOverloads, mixin(__MODULE__), 
member, true).length == 0)

{
pragma(msg, "`", member, "` ", "is not a type or a 
function");

result = false;
break;
}
}
return result;
}
static assert(onlyFuncs(), "this script must hide globals as 
local static variable in a getter");


void main(){}
---


: Error: undefined identifier my_version in module test
onlineapp.d(12): Error: module test.my_version cannot be 
resolved

onlineapp.d(21):called from here: onlyFuncs()
onlineapp.d(21):while evaluating: static


Any idea ?


Re: non-constant expression while initializing two dim array

2020-06-08 Thread Basile B. via Digitalmars-d-learn

On Monday, 8 June 2020 at 06:37:18 UTC, tirithen wrote:

How can I initialize my two dimensional array?

When I try to run the code below I get the error:

Error: non-constant expression ["user":[cast(Capability)0], 
"administrator":[cast(Capability)1]]


Code:

enum Capability {
  self,
  administer
}

alias Capabilities = immutable Capability[];

private Capabilities[string] roleCapabilities = [
  "user" : [Capability.self], "administrator" : 
[Capability.administer]

];

I have tried adding more const and immutable prefixes but it 
still gives me the same error. The goal is that 
roleCapabilities should be an immutable/const two dimensional 
array.


What you declare here is not a two dim array it's an associative 
array.
Associative array implementation have limitations. To initialize 
one that doesn't have const expr as key you can use a static 
module constructor:


---
enum Capability {
  self,
  administer
}

alias Capabilities = immutable Capability[];

private Capabilities[string] roleCapabilities;

static this()
{
roleCapabilities = [
  "user" : [Capability.self], "administrator" : 
[Capability.administer]

];
}
---

which is done at runtime, just before the D main() get executed.

Notes:

1. You can also use a function containing a switch statement 
instead of an assoc array.
2. the other way would work because it would be a static array, 
the enum member giving an integer index:


---
enum Capability {
  self,
  administer
}

alias Capabilities = immutable Capability[];

private string[Capability.max + 1] roleCapabilities = [
Capability.self : "user",
Capability.administer : "administrator",
];
---

but I suppose that is different.


Re: Dub Error Message "Invalid variable: DUB"

2020-06-07 Thread Basile B. via Digitalmars-d-learn

On Sunday, 7 June 2020 at 12:24:13 UTC, Russel Winder wrote:
On Sun, 2020-06-07 at 10:30 +, Basile B. via 
Digitalmars-d-learn wrote: […]
What is the docker image that you use ?  If it is an older 
version maybe that the $DUB env variable is not yet supported 
by the dub version that's installed (it exists since 2.084.0 
according to [1]).


I am using ubuntu:focal. ubuntu:bionic has ldc 1.8 which is far 
too old. Focal has ldc 1.20.


I think the dub version is 1.19.

I am having to manually symbolically link /usr/bin/gcc and 
/usr/bin/cc so I suspect the installation of focal is not going 
quite right. Especially as I have to manually set a TZ variable 
to avoid a lock up.


In my .gitalab-ci.yml I use 'dlang2/ldc-ubuntu' [2] or 
'dlang2/dmd-ubuntu' [3] which give always recent versions of D.


[1] https://dlang.org/changelog/2.084.0.html
[2] https://hub.docker.com/r/dlang2/ldc-ubuntu
[3] https://hub.docker.com/r/dlang2/dmd-ubuntu


I shall have to investigate these docker images in favour of 
working with a bare Ubuntu.


Yes because that works reasonably well on gitlab.
The only problem is that you might have to setup other things as 
their ubuntu image is very light. Software like zip or even git 
are not there by default.


A simple example of `.gitlab-ci.yml` file to support D is

---
job:
  image: dlang2/dmd-ubuntu
  before_script:
  # tools that are not in their base ubuntu image
  - apt-get update -y
  - apt-get install -y supplemental_package_x
  - apt-get install -y supplemental_package_y
  # similarly to what's done on most of the other CI services
  script:
  - bash some_script.sh
  - dub build
  - dub test
  # - etc.
---


Re: Dub Error Message "Invalid variable: DUB"

2020-06-07 Thread Basile B. via Digitalmars-d-learn

On Sunday, 7 June 2020 at 10:06:14 UTC, Russel Winder wrote:

On Sun, 2020-06-07 at 10:24 +0100, Russel Winder wrote:

Hi,

Why on earth is Dub sending out this error message (Invalid 
variable: DUB)

on
GitLab but not on Travis-CI or locally?

OK, that was slightly rhetorical, more reasonably, why is dub 
sending out

this
message at all?


I am assuming that the error comes from the line:

preBuildCommands "$DUB run --compiler=$$DC unit-threaded -c 
gen_ut_main -- -f generated/ut_dub_main.d -d $DUB"


in the unittest configuration as suggested for using 
unit-threaded. The question is why does the symbol DUB not need 
to be defined locally or on Travis-CI, but only on GitLab?


|> printenv | grep -i dub
|>

On Travis-CI and locally Dub find where it is, why does it not 
do this on GitLab? It is at /usr/bin/dub in all cases.


What is the docker image that you use ?  If it is an older 
version maybe that the $DUB env variable is not yet supported by 
the dub version that's installed (it exists since 2.084.0 
according to [1]).


In my .gitalab-ci.yml I use 'dlang2/ldc-ubuntu' [2] or 
'dlang2/dmd-ubuntu' [3] which give always recent versions of D.


[1] https://dlang.org/changelog/2.084.0.html
[2] https://hub.docker.com/r/dlang2/ldc-ubuntu
[3] https://hub.docker.com/r/dlang2/dmd-ubuntu


Re: Should it compile?

2020-06-06 Thread Basile B. via Digitalmars-d-learn

On Saturday, 6 June 2020 at 08:55:20 UTC, Jack Applegame wrote:

Should it compile?

```d
import std.algorithm.mutation;

void main() {
const char a = void;
const char b ='b';
moveEmplace(b, a); // mutation.d: Error: cannot modify 
const expression target

assert(a == 'b');
}
```
I think, it should.


maybe it shouldn't but then with another message, for example

Error, cannot `void` initialize a `const` declaration.

since that makes very little sense, at least as a local variable. 
(as a member, this can be initialized in a constructor)




Re: Fastest way to check using if identifier has already been defined, using static if or similar?

2020-06-03 Thread Basile B. via Digitalmars-d-learn

On Wednesday, 3 June 2020 at 10:24:44 UTC, Simen Kjærås wrote:

On Wednesday, 3 June 2020 at 09:39:34 UTC, Basile B. wrote:

You can use this template:

  enum Exists(alias T) = is(typeof(T));

I don't know if there's a faster way bu this technic is used, 
notatbly in phobos, to workaroud issues of double declaration 
in `static foreach`


enum Exists(alias T) = is(typeof(T));
static assert(!Exists!bar); // undefined identifier bar

--
  Simen


This is because the template parameter must be resolved to a 
valid symbol or type.

This version other version bypass the problem:

---
enum Exists(string s) = is(typeof(mixin(s)));

void main()
{
static if (!Exists!"foo")
int foo;
foo = 42;
}
---


Re: Fastest way to check using if identifier has already been defined, using static if or similar?

2020-06-03 Thread Basile B. via Digitalmars-d-learn

On Wednesday, 3 June 2020 at 09:03:22 UTC, drathier wrote:
I'm generating some code. Some of the generated types need to 
be overridden, so I define them manually at the top of the 
generated file. Then I need to guard against redefining the 
identifier (type/value/function) later on, in the generated 
code.


I'm currently using `static if (!__traits(compiles, thingy)) {` 
to avoid redefining things twice.


Of course the proper fix is to not generate code for the 
identifiers which are already manually defined, and not 
generate any `static if`s at all, but until then, is there a 
faster way than `static if (__traits(compiles, ...` to check if 
a type/value/function has already been defined?


You can use this template:

  enum Exists(alias T) = is(typeof(T));

I don't know if there's a faster way bu this technic is used, 
notatbly in phobos, to workaroud issues of double declaration in 
`static foreach`


Re: Making alias of a struct field needs "this".

2020-06-02 Thread Basile B. via Digitalmars-d-learn

On Tuesday, 2 June 2020 at 09:07:08 UTC, Basile B. wrote:

On Tuesday, 2 June 2020 at 08:56:13 UTC, realhet wrote:

[...]


There's a language rule, expressions cant be aliased, however D 
has a bug, some expressions
that look like type can be aliased, then when you use them you 
have an error about 'this' but in first place here you should 
really have an error saying 'cant alias expression'.


Note that most of the time attempts to alias expressions is 
detected. This is a particular bug, a "corner case".


Re: Making alias of a struct field needs "this".

2020-06-02 Thread Basile B. via Digitalmars-d-learn

On Tuesday, 2 June 2020 at 08:56:13 UTC, realhet wrote:

Hello,

I have a 2 level nested struct structure with nice descriptive 
field names.
And I thought it will be easy to alias those identifierLists 
with a few letter names and do some calculations on them.

But I'm having an error.

struct A{
  struct B{ int c; }
  B b;

  auto f(){
alias d = b.c;
return d;  //Compiler Error: need 'this' for c of type int.
  }
}

There's the this and it's called "b."

Why is this? If I copy paste the aliased expression "b.c", it 
compiled fine.


Thanks in advance!


There's a language rule, expressions cant be aliased, however D 
has a bug, some expressions
that look like type can be aliased, then when you use them you 
have an error about 'this' but in first place here you should 
really have an error saying 'cant alias expression'.


Re: Postblit segfault.

2020-06-02 Thread Basile B. via Digitalmars-d-learn

On Tuesday, 2 June 2020 at 06:34:14 UTC, MaoKo wrote:

On Monday, 1 June 2020 at 19:52:39 UTC, Basile B. wrote:

On Monday, 1 June 2020 at 15:55:45 UTC, H. S. Teoh wrote:
On Mon, Jun 01, 2020 at 03:27:11PM +, Basile B. via 
Digitalmars-d-learn wrote: [...]
Possibly a backend bug (keyword "wrong code"), caused by 
either of [1] or

[2]

[1] https://github.com/dlang/dmd/pull/9357
[2] https://github.com/dlang/dmd/pull/9623/files


Yeah, it looks like a backend bug.  The struct address was 
somehow either not loaded correctly, or not passed correctly 
(didn't look into more detail which case).


A regression should be filed for this, if not already.


T


yeah done. culprit commit confirmed and reduced w/o phobos:

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


Ok cool. I hesitate to report an issue because the bug was too 
"simple".

This is a proof that dmd user use the GC a lot :).


Mmmmh I don't follow you, this has nothing to do with the GC. 
It's rather a problem with the backend (i.e the translation to an 
IR andthe generation of byte code)


Anyway someone already pushed a fix so next point release (~1 or 
2 weeks) will not produce invalid code for the case you've found.


Re: Postblit segfault.

2020-06-01 Thread Basile B. via Digitalmars-d-learn

On Monday, 1 June 2020 at 15:55:45 UTC, H. S. Teoh wrote:
On Mon, Jun 01, 2020 at 03:27:11PM +, Basile B. via 
Digitalmars-d-learn wrote: [...]
Possibly a backend bug (keyword "wrong code"), caused by 
either of [1] or

[2]

[1] https://github.com/dlang/dmd/pull/9357
[2] https://github.com/dlang/dmd/pull/9623/files


Yeah, it looks like a backend bug.  The struct address was 
somehow either not loaded correctly, or not passed correctly 
(didn't look into more detail which case).


A regression should be filed for this, if not already.


T


yeah done. culprit commit confirmed and reduced w/o phobos:

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


Re: Postblit segfault.

2020-06-01 Thread Basile B. via Digitalmars-d-learn

On Monday, 1 June 2020 at 14:53:43 UTC, H. S. Teoh wrote:
On Mon, Jun 01, 2020 at 01:53:09PM +, Bastiaan Veelo via 
Digitalmars-d-learn wrote:

On Monday, 1 June 2020 at 09:42:44 UTC, Boris Carvajal wrote:
> On Monday, 1 June 2020 at 06:35:36 UTC, MaoKo wrote:
> > Hello, I don't understand why this code segfault on
> 
> Reduced to:
> 
> import std.stdio;
> 
> struct S {}
> 
> void main() {

>   S[1] s;
>   writeln(s);
> }

This used to work up to dmd 2.084.1. It fails since 2.085.1. 
Please file a regression report at 
https://issues.dlang.org/enter_bug.cgi?product=D

[...]

Tracked the segfault to Phobos, writeUpToNextSpec():

1216if (trailing[i] != '%') continue;

Apparently `trailing` has an invalid pointer.


T


Possibly a backend bug (keyword "wrong code"), caused by either 
of [1] or [2]


[1] https://github.com/dlang/dmd/pull/9357
[2] https://github.com/dlang/dmd/pull/9623/files


  1   2   3   4   5   6   7   >