Re: D feature request

2024-08-05 Thread user1234 via Digitalmars-d-learn

On Monday, 5 August 2024 at 03:09:41 UTC, IchorDev wrote:
On Sunday, 4 August 2024 at 10:32:38 UTC, Richard (Rikki) 
Andrew Cattermole wrote:

Chuck it into the ideas forum.

If it interests somebody, somebody else can work on it.


Also sometimes if a feature is very minor you can submit a 
‘feature request’ issue.


"enhancement" is the bugzilla word for this. IIRC it's in the 
"severity" field.


Re: importC with struct name and function conflict

2024-08-05 Thread Dennis via Digitalmars-d-learn

On Monday, 5 August 2024 at 11:02:24 UTC, Dakota wrote:
This will not work for me.  (huge code base I can not change 
and maintain)


You don't have to change the code where the type is defined per 
se, you just need to put it in any C file that can access the C 
symbol.


clib_helpers.c:
```C
#include

typedef struct S S_t;
```

app.d:
```
import clib_helpers;

S_t s;
```


Re: importC with struct name and function conflict

2024-08-05 Thread Dakota via Digitalmars-d-learn

On Saturday, 3 August 2024 at 11:55:53 UTC, Dennis wrote:

On Saturday, 3 August 2024 at 05:10:37 UTC, Dakota wrote:
How can I get the function and type from importC?  is there a 
auto rename mechanism ?


The most pragmatic workaround is to add a typedef to the C code:

```C
int S;
struct S { int a, b; };
typedef struct S S_t;// add this typedef
```

https://dlang.org/spec/importc.html#tag-symbols


Thanks for tips.

This will not work for me.  (huge code base I can not change and 
maintain)


Re: D feature request

2024-08-04 Thread IchorDev via Digitalmars-d-learn
On Sunday, 4 August 2024 at 10:32:38 UTC, Richard (Rikki) Andrew 
Cattermole wrote:

Chuck it into the ideas forum.

If it interests somebody, somebody else can work on it.


Also sometimes if a feature is very minor you can submit a 
‘feature request’ issue.


Re: D feature request

2024-08-04 Thread Richard (Rikki) Andrew Cattermole via Digitalmars-d-learn

On 04/08/2024 10:06 PM, aberba wrote:
So if I have a feature request, but I don't have the necessary technical 
skills to draft a DIP with the implementation details, is there a 
process in D community to submit such a request?


Other communities using GitHub have a way to file an issue which then 
gets labelled as a feature request and others can vote (thumbs up) on it 
such that with enough interest and momentum, someone with the right 
skills or the language maintainers can start to collect feedback and 
draft a DIP. Is the there such a process in D?


Chuck it into the ideas forum.

If it interests somebody, somebody else can work on it.


Re: Get compile time string of dmd command line options "-os" & "-target"

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

On Saturday, 3 August 2024 at 12:15:46 UTC, Dennis wrote:

On Thursday, 1 August 2024 at 04:00:08 UTC, An Pham wrote:

pragma(msg, os.stringof...?);
pragma(msg, target.stringof...?);


There's no built-in way, but you can define it yourself in a 
helper module:


```D
version(Windows)
enum os = "windows";
else version(AArch64)
enum os = "aarch64";
else
static assert(0, "unsupported os");
```


First, I will note that "windows" and "aarch64" are not in the 
same category...


Second, there are some already-built parts in phobos:

https://dlang.org/phobos/std_compiler.html
https://dlang.org/phobos/std_system.html

I also went ahead and did some for arch and runtime flavor, in a 
project where I needed these, feel free to steal (Boost licensed):


https://github.com/schveiguy/raylib-d/blob/master/install/source/app.d#L135-L154

-Steve


Re: Get compile time string of dmd command line options "-os" & "-target"

2024-08-03 Thread Dennis via Digitalmars-d-learn

On Thursday, 1 August 2024 at 04:00:08 UTC, An Pham wrote:

pragma(msg, os.stringof...?);
pragma(msg, target.stringof...?);


There's no built-in way, but you can define it yourself in a 
helper module:


```D
version(Windows)
enum os = "windows";
else version(AArch64)
enum os = "aarch64";
else
static assert(0, "unsupported os");
```



Re: importC with struct name and function conflict

2024-08-03 Thread Dennis via Digitalmars-d-learn

On Saturday, 3 August 2024 at 05:10:37 UTC, Dakota wrote:
How can I get the function and type from importC?  is there a 
auto rename mechanism ?


The most pragmatic workaround is to add a typedef to the C code:

```C
int S;
struct S { int a, b; };
typedef struct S S_t;// add this typedef
```

https://dlang.org/spec/importc.html#tag-symbols


Re: importC error: can not find the #define ERR_INVALID -1

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

On Saturday, 3 August 2024 at 05:07:55 UTC, Dakota wrote:

```c
#define ERR_SUCCESS 0
#define ERR_INVALID -1   // invalid argument
```

If the number >=0, it work.  < 0 will not work.

DMD64 D Compiler v2.110.0-beta.1


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

-Steve


Re: How to work with long paths on Windows?

2024-08-02 Thread James Carter via Digitalmars-d-learn

On Monday, 14 November 2022 at 18:45:40 UTC, Imperatorn wrote:

On Monday, 14 November 2022 at 14:43:50 UTC, Preetpal wrote:

On Monday, 14 November 2022 at 10:44:11 UTC, Imperatorn wrote:

On Tuesday, 13 September 2022 at 19:54:15 UTC, Preetpal wrote:

[...]


Have you set longPathAware in the applications manifest?


Yeah that's how I dealt with the issue. I just replied to my 
own question with a working example that people who might find 
this post can refer to: 
[gist](https://gist.github.com/preetpalS/2fd6c6bf05a94734f89b70b679716bf3) (see my comment in the gist for how to make it work).





Don't get in the weeds,
it really did my my head this path thing, but I found a way,  I 
tried LongPath Tool Program and that sorted it.


Re: Any way to automatically convert structs on return?

2024-08-02 Thread Juraj via Digitalmars-d-learn

On Thursday, 1 August 2024 at 07:25:53 UTC, Emma wrote:

```d
Option!int something() {
  return None(); // Error: cannot implicitly convert expression 
`None()` of type `None` to `Option!int`

}
```



Not D per se, but you can check Adam D. Ruppe's current work.
If I am not mistaken, the thing you are asking for is already 
possible in the nightly release.


https://dpldocs.info/this-week-in-arsd/Blog.Posted_2024_02_20.html#implicit-construction


Juraj


Re: Segmentation fault while reading a file

2024-08-01 Thread IchorDev via Digitalmars-d-learn
On Thursday, 1 August 2024 at 14:42:36 UTC, Ruby The Roobster 
wrote:
Thank you.  I am not very well acquainted with the standard 
library, and this cleans up things significantly.


Question:  Is there a good guide to Phobos anywhere?  I would 
like to learn the more commonly used algorithms / convenience 
functions, so I don't have to look through the docs trying to 
find what I want, and so that I don't keep having to re-invent 
the wheel when trying to work with data.


I’m actually not sure. I think the best stuff is usually the 
examples in the documentation. If you’re searching for whether 
something might be in Phobos, try seeing if there’s a module that 
sounds right in the [index](https://dlang.org/phobos/index.html). 
In general I just peruse different modules until I see a function 
that fits what I need. It also depends on how functional you like 
your code, there’s a lot of map/filter/etc. stuff that I 
regularly write my own ad-hoc code for.


Re: Any way to automatically convert structs on return?

2024-08-01 Thread IchorDev via Digitalmars-d-learn

On Thursday, 1 August 2024 at 14:20:29 UTC, user1234 wrote:

That was a general criticism of implicit construction.


We are only talking about it in the context of returning from a 
function.



The classic example is

```d
struct S {int i;}
function f(S s);
function f(int i);

unittest { f(0); } // both match
```

unless the idea would rather be to allow implicit construction 
only in the context of initialization.


You are wasting my time. Show me how this applies to retuning 
from within a function.


Re: Any way to automatically convert structs on return?

2024-08-01 Thread Emma via Digitalmars-d-learn
Thanks everyone for the replies! I just thought it was weird that 
implicit construction is seemingly supported when directly 
initialising a struct but not in any other case. I guess it's 
because it's clearly less ambiguous.


On Thursday, 1 August 2024 at 13:07:09 UTC, Lance Bachmeier wrote:


For the program you've written, I'm happy it doesn't compile, 
because a lot of the time the compiler would be making buggy 
code compile - though I would love to have a way to do it 
explicitly. In this case you can change your definition of None 
to use alias this and it will compile:


The alias this doesn't work generically, though. Either way I 
agree that implicit construction, if it was present in D, should 
not be the default, instead being opt-in like say through an 
`implicit this(...)` or whatever instead of C++'s horrendous 
implicit by default behaviour.




Re: Any way to automatically convert structs on return?

2024-08-01 Thread Nick Treleaven via Digitalmars-d-learn

On Thursday, 1 August 2024 at 08:46:00 UTC, IchorDev wrote:
P.S. You might want to put `value = void`, otherwise it’ll 
always be default-constructed.


Doing `= void` can violate the assumptions of a destructor of T. 
Nullable uses a union to store T, so it can decide when to call 
the destructor.


Re: Segmentation fault while reading a file

2024-08-01 Thread Ruby The Roobster via Digitalmars-d-learn

On Thursday, 1 August 2024 at 07:03:04 UTC, IchorDev wrote:
Hey just a heads up, you might wanna use 
[`readText`](https://dlang.org/library/std/file/read_text.html) 
and 
[`lineSplitter`](https://dlang.org/library/std/string/line_splitter.html) just so you don’t have to deal with file handles.

...


Thank you.  I am not very well acquainted with the standard 
library, and this cleans up things significantly.


Question:  Is there a good guide to Phobos anywhere?  I would 
like to learn the more commonly used algorithms / convenience 
functions, so I don't have to look through the docs trying to 
find what I want, and so that I don't keep having to re-invent 
the wheel when trying to work with data.




Re: Any way to automatically convert structs on return?

2024-08-01 Thread user1234 via Digitalmars-d-learn

On Thursday, 1 August 2024 at 10:59:03 UTC, IchorDev wrote:

On Thursday, 1 August 2024 at 09:55:08 UTC, user1234 wrote:
The problem would be that sorting the candidates of an 
overload set would be more complicated. Also in certain cases 
it would be less obvious to get which one is selected.


Please elaborate about how this would interact with function 
overloads at all?


That was a general criticism of implicit construction. The 
classic example is


```d
struct S {int i;}
function f(S s);
function f(int i);

unittest { f(0); } // both match
```

unless the idea would rather be to allow implicit construction 
only in the context of initialization.


Re: Any way to automatically convert structs on return?

2024-08-01 Thread Lance Bachmeier via Digitalmars-d-learn

On Thursday, 1 August 2024 at 07:25:53 UTC, Emma wrote:


but this doesn't:

```d
Option!int something() {
  return None(); // Error: cannot implicitly convert expression 
`None()` of type `None` to `Option!int`

}
```


For the program you've written, I'm happy it doesn't compile, 
because a lot of the time the compiler would be making buggy code 
compile - though I would love to have a way to do it explicitly. 
In this case you can change your definition of None to use alias 
this and it will compile:


```
struct None {
alias convert this;

Option!int convert() {
return Option!int(None());
}
}
```


Re: Any way to automatically convert structs on return?

2024-08-01 Thread IchorDev via Digitalmars-d-learn

On Thursday, 1 August 2024 at 09:55:08 UTC, user1234 wrote:
The problem would be that sorting the candidates of an overload 
set would be more complicated. Also in certain cases it would 
be less obvious to get which one is selected.


Please elaborate about how this would interact with function 
overloads at all? The function has the same parameters, same 
return type, same attributes… what’s different exactly?


Re: Any way to automatically convert structs on return?

2024-08-01 Thread user1234 via Digitalmars-d-learn

On Thursday, 1 August 2024 at 08:46:00 UTC, IchorDev wrote:

[...]
I’m pretty sure this is intentional to prevent ambiguity, but I 
can’t quite remember what the point of that is.


The problem would be that sorting the candidates of an overload 
set would be more complicated. Also in certain cases it would be 
less obvious to get which one is selected.


Re: Any way to automatically convert structs on return?

2024-08-01 Thread Dukc via Digitalmars-d-learn

Emma kirjoitti 1.8.2024 klo 10.25:
This kind of prevents ergonomic code like the above. Instead you have to 
use a function like `Option!T None(T)() => Option!T()` and then you have 
to repeat yourself with `return None!int` and etc... it's quite annoying :(



While this isn't exactly less verbose, I mention it because at least you 
don't have to write the type twice:


```D
Option!int something() {
return typeof(return)(None());
}


Re: Any way to automatically convert structs on return?

2024-08-01 Thread IchorDev via Digitalmars-d-learn

On Thursday, 1 August 2024 at 07:25:53 UTC, Emma wrote:

This code works:

```d
struct None {}

struct Option(T) {
bool hasSome;
T value;

this(None) {}

this(T v) {
hasSome = true;
value = v;
}
}

Option!int a = 123;// automatically constructs an 
Option!int from a bare int

Option!int b = None(); // same as above but with None
```
but this doesn't:
```d
Option!int something() {
  return None(); // Error: cannot implicitly convert expression 
`None()` of type `None` to `Option!int`

}
```
This kind of prevents ergonomic code like the above. Instead 
you have to use a function like `Option!T None(T)() => 
Option!T()` and then you have to repeat yourself with `return 
None!int` and etc... it's quite annoying :(


In C++ you may do this fairly easily, but of course there are 
various pitfalls because it's C++. But at least you can opt out 
with `explicit` most of the time.


Thanks in advance!


I’m pretty sure this is intentional to prevent ambiguity, but I 
can’t quite remember what the point of that is. You can always 
just write the constructor manually, but yes it’s a hassle. I 
wonder how open people would be to changing this restriction?


P.S. You might want to put `value = void`, otherwise it’ll always 
be default-constructed. Phobos also has `Nullable` if you want 
another implementation for reference.


Re: Any way to automatically convert structs on return?

2024-08-01 Thread Richard (Rikki) Andrew Cattermole via Digitalmars-d-learn

No, D does not support implicit construction.

However in saying that, I will continue to argue in support of sum types 
when they get added to the language to support implicit construction!




Re: Segmentation fault while reading a file

2024-08-01 Thread IchorDev via Digitalmars-d-learn
Hey just a heads up, you might wanna use 
[`readText`](https://dlang.org/library/std/file/read_text.html) 
and 
[`lineSplitter`](https://dlang.org/library/std/string/line_splitter.html) just so you don’t have to deal with file handles. Also you can use something like [`formattedRead`](https://dlang.org/library/std/format/read/formatted_read.html) for parsing formatted floats more easily.
Also please only use `in` if you have `-preview=in` and you know 
what it’s for. You were probably looking for `const`, because 
`in` with `-preview=in` is not useful for strings.


Re: Segmentation fault while reading a file

2024-07-31 Thread Ruby The Roobster via Digitalmars-d-learn
Nevermind. The segfault happened because I accidentally used the 
Mesh class before loading OpenGL.  I don't know if it works as 
intended, but it no longer crashes.





Re: Segmentation fault while reading a file

2024-07-31 Thread matheus via Digitalmars-d-learn
On Wednesday, 31 July 2024 at 23:06:30 UTC, Ruby The Roobster 
wrote:
... or is `readln` bugging out because the file (backpack.obj 
contained in the linked .zip file) is too large?

...


I don't have I compiler in hand to try your code at moment, but 
about your concern over the size of the file, you could try a 
simple object[1]:


# cube.obj
#

g cube

v  0.0  0.0  0.0
v  0.0  0.0  1.0
v  0.0  1.0  0.0
v  0.0  1.0  1.0
v  1.0  0.0  0.0
v  1.0  0.0  1.0
v  1.0  1.0  0.0
v  1.0  1.0  1.0

vn  0.0  0.0  1.0
vn  0.0  0.0 -1.0
vn  0.0  1.0  0.0
vn  0.0 -1.0  0.0
vn  1.0  0.0  0.0
vn -1.0  0.0  0.0

f  1//2  7//2  5//2
f  1//2  3//2  7//2
f  1//6  4//6  3//6
f  1//6  2//6  4//6
f  3//3  8//3  7//3
f  3//3  4//3  8//3
f  5//5  7//5  8//5
f  5//5  8//5  6//5
f  1//4  5//4  6//4
f  1//4  6//4  2//4
f  2//1  6//1  8//1
f  2//1  8//1  4//1

Matheus.

[1] https://cs.wellesley.edu/~cs307/readings/obj-ojects.html


Re: copy must be const?!?

2024-07-30 Thread swigy food via Digitalmars-d-learn

Hello
A const copy ensures the copied value remains unchanged, 
providing safety and predictability. If the original is const, 
copying it as non-const could introduce unintended side effects. 
To modify a copied value, create a mutable copy explicitly.
For file systems, copying write-protected files maintains their 
attributes for security reasons. To modify them, change the file 
permissions after copying.
There isn't a direct way to tell the compiler to discard "const" 
or "immutable" attributes during a copy. You need to cast away 
constness explicitly where necessary.





Re: copy must be const?!?

2024-07-29 Thread Dom DiSc via Digitalmars-d-learn

On Friday, 26 July 2024 at 10:04:45 UTC, Jonathan M Davis wrote:
On Friday, July 26, 2024 2:17:21 AM MDT Dom DiSc via 
Digitalmars-d-learn wrote:
If you are not able to construct a mutable copy of a type, why 
on earth are you handing it over by value?!?


Why not?


Because you can't make a mutable copy?


Structs are [...] often pseudo-reference types. [...]
such types can often work just fine with const copies, because 
the data that's shared between objects is const or immutable.


Then declare the template to take a const parameter.


```d
immutable MyNonCopyableType x;
MyNonCopyableType y = x; // compile error?
```


If you can't get a mutable copy of MyNonCopyableType, then yes, 
you'll get a compiler error.


This is why you should get the same error, if the compiler cannot 
create a mutable parameter-by-value copy.


In D, const is pretty much cancer, honestly. You do _not_ want 
to use it for generic code if you can possible avoid it,


Why? In a template that guarantees not to modify a parameter by 
declaring it const, what bad can happen?



because many, many types do not work with it at all.


At least reading it should never be a problem. And nothing more 
one want to do with a const parameter.


But I don't see your problem. I'm taking about situations where a 
const instance of a type IS ALREADY THERE (which will never be 
the case with any of your problematic types), and I want to have 
a mutable copy of them.
So if the compiler would discard the const from parameters that 
are anyway never const, that's a NOP. All is fine.


On the other hand if there is a const object, that should be an 
object of a type that indeed CAN provide mutable copies. This is 
also fine.


So, where is the problem if the compiler drops "const" from the 
by-value copy of a parameter?


in situations where a type can be logically const (or which 
could be const in C++), it cannot be const in D, because D's 
const is simply too restrictive.


Sorry, but if a type is "logically const" (like a range) and you 
read it and thereby change it's internal state, then the template 
that guaranteed not to modify a parameter is very likely to 
destroy this internal state, and so you are much better of if 
this doesn't compile beforehand.


Some templates are simply not meant to work with all kinds of 
user defined types.


If you declare the parameter to be const, then there are a lot 
of types that won't work with the template.


Fine. If I can change the internal state via read-functions, I 
don't want to work with that bogous type. If my intention is not 
to modify an object, I'm perfectly ok that I can't use may of 
that fake-const types functions.


On top of that, in many cases, getting a mutable copy would 
give you completely incorrect behavior - e.g. if a range is a 
range over a container, you need that range to point to the 
elements in the container, and if the range refers to those 
elements as const, then getting a mutable copy of those 
elements would mean that they're no longer necessarily the same 
elements which are in the container (they might be at the point 
that the copy is made, but that won't necessarily stay true, 
whereas it would if the elements aren't copied).


Ranges are a bad example, because they really cannot be const. 
They are completely unusable in a function not modifying them, 
because reading them is using them up. So a function taking a 
range as parameter indeed cannot guarantee not to modify it (at 
least not if it reads that parameters data at all).


It's also the case that a lot of code simply avoids using const 
altogether with user-defined types


Fine. Then you won't run into the problem I have. And indeed, as 
you weren't aware of this problem is an indicator that you are 
not really using const.


Most anyone who tries to use D's const like you would in C++ 
eventually stops, because D's const is simply too different 
from C++'s const for that to work.


No, so far the C++ code I converted to D is working fine. And it 
is heavily using const - but it uses it correct, despite C++ 
doesn't enforce that. Maybe I never used C++ the way it was 
meant?!?


And that's especially true with templated code, since if it has 
to work with a large range of types, types which don't work 
with const are going to be on the list.


Nope. Constraints work very good in guaranteeing that such types 
are NOT on the list of types the template is working with.


On top of that, some common D idioms (e.g. ranges) can't work 
with const, because they require mutation (a range can have 
const elements, but the range itself cannot be const).


Jup. If a template takes a range, it should not take it const.
But I also won't take a range by value. As whatever I do will 
modify the range, why should I pretend to work on a copy of it? 
Take it by ref!




Re: Libraries for Model Loading

2024-07-26 Thread Chance Snow via Digitalmars-d-learn
On Thursday, 18 July 2024 at 14:02:09 UTC, Ruby The Roobster 
wrote:
Is there a good package available that can load models, 
Wavefront .obj files in particular?  I tried to use the 
existing bindings to old versions of Assimp, but I could not 
get Assimp itself to build on my machine.


Thanks in advance.


I would bind to Assimp using 
[ImportC](https://dlang.org/spec/importc.html).


Re: copy must be const?!?

2024-07-26 Thread Jonathan M Davis via Digitalmars-d-learn
On Friday, July 26, 2024 2:17:21 AM MDT Dom DiSc via Digitalmars-d-learn 
wrote:
> On Thursday, 25 July 2024 at 13:07:03 UTC, Jonathan M Davis wrote:
> > On Thursday, July 25, 2024 6:00:58 AM MDT Dom DiSc via
> >
> >> But a parameter given by value is ALWAYS a copy.
> >
> > It has to be a _full_, independent copy. If you're talking
> > about integer types, that's a non-issue, but if you're talking
> > about types with any indirections, it becomes a big issue. If
> > the type contains any pointers, dynamic arrays, class
> > references, etc. then the copy can't be mutable unless you're
> > dealing with a struct with a copy constructor that does a deep
> > copy of all of the member variables. So, in the general case,
> > you cannot copy a value and expect to get a mutable result.
>
> If you are not able to construct a mutable copy of a type, why on
> earth are you handing it over by value?!?

Why not? Structs are almost never reference types (since that would mean
only holding a single pointer or class reference), but they're often
pseudo-reference types. Something as simple as having a dynamic array or
string in your struct means that you can't get a mutable copy without
duplicating memory (and depending on the types involved, you can't even do
that), but such types can often work just fine with const copies, because
the data that's shared between objects is const or immutable.

> And what do you do with normal assignment with such a type?

You can't assign to variables which are const or immutable, so assignment
won't work. But plenty of generic code is written which never assigns to a
variable and works just fine with const objects being copied.

> ```d
> immutable MyNonCopyableType x;
> MyNonCopyableType y = x; // compile error?
> ```

If you can't get a mutable copy of MyNonCopyableType, then yes, you'll get a
compiler error.

> Also, if you need no writeable copy in your template, why don't
> you declare it with const parameter?
> Maybe you need this behaviour often and so don't want to type the
> 7 extra characters. But I think, it is a bad default to create
> const copies of const objects, and to make it worse the language
> does not allow you to change this default (would need a new
> keyword "mutable" to explicitly request to get a mutable copy).

In D, const is pretty much cancer, honestly. You do _not_ want to use it for
generic code if you can possible avoid it, because many, many types do not
work with it at all. Unlike C++'s const, it's transitive and has no
backdoors (at least not without violating the type system), making it very
easy to end up in situations where even when a type can be logically const
(or which could be const in C++), it cannot be const in D, because D's const
is simply too restrictive. When something is const in D, it means it. There
are types when those guarantees are useful, but often, the end result is
that you're better off avoding const with any user-defined types, because
const is simply too restrictive. And if a type has any indirections in it,
the odds are extremely low that it's going to be possible to get a mutable
copy from a const object.

As such, unless you're dealing with a specific subset of types where you
know that const will work (e.g. if you're only dealing with integer types),
then you usually don't want to use const at all with templates. Templates
will often work with const types just fine when those types are designed to
work with const, but if the template require const, then you're going to end
up with a lot of types that won't work with that template, because they
won't work with const (and in many cases, cannot be made to work with
const).

> > It's most definitely not a bug that IFTI (Implicit Function
> > Template Instantiation) instantiates the template with the
> > exact type that it's given. In the general case, that's what
> > you want - particularly since many, many types (probably the
> > vast majority of types) cannot be const or immutable and then
> > result in a mutable copy when they're copied.
>
> If you need this, declare the parameter const.
> The default should be a mutable copy (and a compile error if
> creating a mutable copy is not possible).

If you declare the parameter to be const, then there a lot of types that
won't work with the template. D's const is just too restrictive for it to
make any sense to use it unless you're specifically restricting your code to
a subset of types which are designed to work with it. With generic code,
it's usually the case that the decision on whether const should be used
needs to be left up to the caller if you want any chance of the code working
with a large range of types.

Using const parameters with function templates can work quite well with the
primitive types, but with user-defined types, it tends to become untenable
quite quickly - especially if you're writing library code that will be used
by a whole bunch of people writing types that you don't control.

> > That really only works 

Re: Libraries for Model Loading

2024-07-26 Thread IchorDev via Digitalmars-d-learn
On Thursday, 18 July 2024 at 14:02:09 UTC, Ruby The Roobster 
wrote:
Is there a good package available that can load models, 
Wavefront .obj files in particular?  I tried to use the 
existing bindings to old versions of Assimp, but I could not 
get Assimp itself to build on my machine.


Thanks in advance.


Not that I know of, but Wavefront .obj files are pretty simple. 
You could translate Assimp into D, or make your own simple 
library for loading them.


Re: copy must be const?!?

2024-07-26 Thread Dom DiSc via Digitalmars-d-learn

On Thursday, 25 July 2024 at 13:07:03 UTC, Jonathan M Davis wrote:

On Thursday, July 25, 2024 6:00:58 AM MDT Dom DiSc via

But a parameter given by value is ALWAYS a copy.


It has to be a _full_, independent copy. If you're talking 
about integer types, that's a non-issue, but if you're talking 
about types with any indirections, it becomes a big issue. If 
the type contains any pointers, dynamic arrays, class 
references, etc. then the copy can't be mutable unless you're 
dealing with a struct with a copy constructor that does a deep 
copy of all of the member variables. So, in the general case, 
you cannot copy a value and expect to get a mutable result.


If you are not able to construct a mutable copy of a type, why on 
earth are you handing it over by value?!?


And what do you do with normal assignment with such a type?

```d
immutable MyNonCopyableType x;
MyNonCopyableType y = x; // compile error?
```

Also, if you need no writeable copy in your template, why don't 
you declare it with const parameter?
Maybe you need this behaviour often and so don't want to type the 
7 extra characters. But I think, it is a bad default to create 
const copies of const objects, and to make it worse the language 
does not allow you to change this default (would need a new 
keyword "mutable" to explicitly request to get a mutable copy).



Therefore I consider the current behaviour a bug.


It's most definitely not a bug that IFTI (Implicit Function 
Template Instantiation) instantiates the template with the 
exact type that it's given. In the general case, that's what 
you want - particularly since many, many types (probably the 
vast majority of types) cannot be const or immutable and then 
result in a mutable copy when they're copied.


If you need this, declare the parameter const.
The default should be a mutable copy (and a compile error if 
creating a mutable copy is not possible).


That really only works with very simple types with no 
indirections.


Sorry, but no. It is possible to write copy constructors that 
create mutable copies for pretty much any type. It may for bad 
designed types be not very fast, but if you are able to create a 
mutable instance of a type, it should also be possible to create 
a mutable copy.




Now, the fact that code such as
```
void fun(T : const U, U)(U x)
if(is(immutable T == immutable U))
{
...
}
```
or code like
```
void fun(T)(Unqual!T x) {}
```
doesn't work with IFTI and requires explicit instantation is 
definitely a deficiency in IFTI's current capabilities.


So you basically agree that it is a missing feature (if not a 
bug).



we very much want
```
void fun(T)(T x) {}
```
to be instantiated as fun!(const Foo) if it's passed a const 
Foo.


No. this is a bad default. If you want this, write

```d
void fun(T)(const(T) x) {}
```

I know, it's seven characters more to type, but I think they are 
definitely worth it.




Re: copy must be const?!?

2024-07-26 Thread Dom DiSc via Digitalmars-d-learn

On Friday, 26 July 2024 at 02:34:12 UTC, Andy Valencia wrote:
On Thursday, 25 July 2024 at 13:07:03 UTC, Jonathan M Davis 
wrote:


It's most definitely not a bug that IFTI (Implicit Function 
Template Instantiation) instantiates the template with the 
exact type that it's given.


The "principle of least astonishment" certainly supports this 
behavior.  To check my understanding, I forced the type of 
instantiation:


  writeln(test2!int(v));

and that worked as I expected.

Andy


Yes, it's pretty much the same "solution" but on the caller side 
instead of the callee. But it works only for types like int or 
which provides a constructor that generates a mutable copy.


Re: Prevent self-comparison without taking the address

2024-07-26 Thread Dom DiSc via Digitalmars-d-learn

On Thursday, 25 July 2024 at 15:40:29 UTC, Nick Treleaven wrote:

On Thursday, 25 July 2024 at 15:06:35 UTC, IchorDev wrote:
I think your function most likely has a safe interface, so it 
can be marked as `@trusted` as-per [the 
spec](https://dlang.org/spec/function.html#safe-interfaces).


Just to mention that with -dip1000, taking the address of 
variables is allowed, so the function would be @safe.


Thanks for all the good answers.
So the solution for me is -dip1000.

Marking something @trusted that the compiler should be able to 
check to be @safe is not so good, as it increases the review 
effort significantly and unneccessarily.


Re: What is an rvalue constructor?

2024-07-25 Thread Jonathan M Davis via Digitalmars-d-learn
On Thursday, July 25, 2024 4:48:06 PM MDT Quirin Schroll via Digitalmars-d-
learn wrote:
> It seems one can’t have one in a struct together with a copy
> constructor, but what is it? When is it called? What is it for?

An rvalue constructor is a constructor that takes the same type as the
struct that it's in, but it takes it as an rvalue (whereas a copy
constructor takes it as an lvalue). So, if you have

struct MyType
{
this(MyType rhs)
{
...
}
}

then you can do stuff like MyType(getMyType()) where getMyType returns a
MyType, whereas if you don't have such a constructor, you can't. This is
particularly useful in generic code. For instance, if you have an algebraic
type that takes a whole bunch of types, you can do something like

this(T)(T rhs)
{
...
}

and then you can happily call MyType(getMyType()) where getMyType() returns
a MyType.

However, without that rvalue constructor, then MyType(getMyType()) can't be
done. So, if MyType has a copy constructor, you're forced to check for
MyType with such a templated constructor, e.g.

this(T)(T rhs)
if(!is(immutable T == immutable MyType))
{
...
}

and you need to create a wrapper function to be able to generically
construct a MyType, e.g.

MyType make(T)(T rhs)
{
static if(is(immutable T == immutable MyType))
return rhs;
else
return MyType(rhs);
}

Of course, for most code, you really don't need to be able to construct a
struct from its own type, so in many cases, you really don't need an rvalue
constructor, but when you do need it, the fact that copy constructors don't
allow them is pretty annoying.

With the current DIP proposal for move constructors, an rvalue constructor
would become a move constructor, though since it's not necessarily obvious
that that's what it is, and such constructors already exist as normal
constructors, there are some objections to making such a change. But of
course, we'll have to see what ultimately happens with that.

- Jonathan M Davis






Re: Prevent self-comparison without taking the address

2024-07-25 Thread Jonathan M Davis via Digitalmars-d-learn
On Thursday, July 25, 2024 4:50:04 AM MDT Dom DiSc via Digitalmars-d-learn 
wrote:
> I have copied some source from C++, where the following pattern
> is common (operator== already renamed):
>
> ```d
> @safe:
> struct S
> {
> bool opEquals(const ref S x) const
> {
>if(==) return true;
>...
> }
> }
> ```
>
> Can I replace this pattern with ```(x is this)``` or are there
> some special cases where this doen't work?

If you want to do that, that's basically what you would need to do. However,
I've never seen anyone do that with structs in D. They're usually put on the
stack and passed around by value. They are of course sometimes passed by
reference, but that's usually going to be to a variable on the stack, making
comparing addresses kind of pointless, since you'd usually need to be doing
something like x == x to end up comparing the same object against itself.

Pretty much the only time that something like this might make sense is when
you're dealing with pointers to structs, which of course is done sometimes,
but it's much less common than it would be in C++, since D separates classes
and structs. And classes already do that check with ==, since it's lowered
to a free function, opEquals, before calling the class' opEquals, and it
does stuff like compare the address of the class reference and compare
against null.

Either way, the fact that the this member for structs is a reference rather
than a pointer means that if you want to compare addresses, you'll need to
take the addresses - which won't be @safe without DIP 1000, because taking
the address of a local variable is not @safe without the tracking that DIP
1000 adds via scope (since without the extra checks, you could easily take
that address and pass it around, letting it escape the lifetime of the
reference).

- Jonathan M Davis





Re: copy must be const?!?

2024-07-25 Thread Quirin Schroll via Digitalmars-d-learn

On Thursday, 25 July 2024 at 13:07:03 UTC, Jonathan M Davis wrote:
On Thursday, July 25, 2024 6:00:58 AM MDT Dom DiSc via 
Digitalmars-d-learn wrote:
> And no, in general, you don't want to be casting away const 
> or immutable. There are cases where it can work (e.g. if the 
> cast does a copy, which it would with an integer type)


But a parameter given by value is ALWAYS a copy.
So if a copy is done, the copy should be mutable. I can't see 
why

that should ever be a problem. The compiler should never create
new values const or immutable unless explicitly advised to do 
so.


It has to be a _full_, independent copy. If you're talking 
about integer types, that's a non-issue, but if you're talking 
about types with any indirections, it becomes a big issue. If 
the type contains any pointers, dynamic arrays, class 
references, etc. then the copy can't be mutable unless you're 
dealing with a struct with a copy constructor that does a deep 
copy of all of the member variables. So, in the general case, 
you cannot copy a value and expect to get a mutable result.



E.g.
```d
void fun(myType x) { }
```

called with immutable object should create a mutable x, because

```d
   myType x = immutableObject;
```

will also create a mutable x. If I want an immutable x, i can 
do


```d
   immutable myType = immutableObject;
```

```d
void fun(T)(T x) if (is(Unqual!T==myType)) { }
```

should also create a mutable x, for the same reason, because 
if I want an immutable x, I can do



```d
void fun(T)(immutable(T) x) if (is(Unqual!T==myType)) { }
```

Therefore I consider the current behaviour a bug.


It's most definitely not a bug that IFTI (Implicit Function 
Template Instantiation) instantiates the template with the 
exact type that it's given. In the general case, that's what 
you want - particularly since many, many types (probably the 
vast majority of types) cannot be const or immutable and then 
result in a mutable copy when they're copied. That really only 
works with very simple types with no indirections. In the 
general case, there is no expectation whatsoever that it's 
going to be possible to get a mutable copy from a const or 
immutable variable, and generic code that expects that to work 
is very likely to run into problems very quickly.


Now, the fact that code such as
```d
void fun(T : const U, U)(U x)
if(is(immutable T == immutable U))
{
...
}
```
or code like
```d
void fun(T)(Unqual!T x)
{
}
```
doesn't work with IFTI and requires explicit instantation is 
definitely a deficiency in IFTI's current capabilities, but in 
the general case, we very much want

```d
void fun(T)(T x) {}
```
to be instantiated as `fun!(const Foo)` if it's passed a `const 
Foo`.


For some types, we _would_ like the ability to tell the 
compiler to implicitly instantiate function templates with a 
tail-const version similar to what we get with dynamic arrays, 
but that really only makes sense for certain types such as 
ranges.


But either way, it would cause quite a few problems if IFTI 
started instantiating templates in general with mutable instead 
of the actual type that it's given, because it's extremely 
common that const and immutable types cannot be converted to 
mutable.


It’s wild how C++ and D disagree on this one. In C++, a copy 
constructor must produce a mutable copy. Now, C++ and D disagree 
on what `const` means and therefore what counts as a mutable 
copy. But, and this is the key takeaway, C++ never infers `const` 
on a copy. Never. It does infer `const` on a reference, of course.


Nothing of this is out of reach for D. A type for which const 
objects can’t be copied to initialize a mutable one simply isn’t 
copyable and therefore can’t be passed by value. A type for which 
const rvalues can’t be used to initialize a mutable variable 
aren’t movable.


C++ solves this by binding values by universal reference:
```cpp
template
void f(T&&);
```
This `f` eats anything. For rvalues of type `X`, `T` is inferred 
`X`, the rvalue is materialized in the caller and passed by 
(rvalue) reference to `f`. For lvalues, `T` is inferred `X&` so 
that the parameter becomes of type `(T&)&&` which is the same as 
`T&`, thus `f` ends up binding the value by (lvalue) reference.


D doesn’t have that. In that regard, D is approximately where C++ 
was before C++11. D’s `ref` can’t bind lvalues, which is probably 
a good thing. In one of my recent DIP Ideas posts, I outlined 
`@universal ref` and `@rvalue ref`.


The best D can do today is this:
```d
void f(T)(auto ref T);
```
For lvalues, that’s great. Nothing to complain. Rvalues should be 
moved into the parameter. For that, the type must support moves, 
which most types do, but the compiler doesn’t check if the move 
could give you a mutable object. Even if it can, the compiler 
will give you a qualified parameter.


Because of D’s transitive qualifiers, a mutable copy may not be 
possible. In that case, we’d have two options: Say the type isn’t 
copyable, or 

Re: Prevent self-comparison without taking the address

2024-07-25 Thread Nick Treleaven via Digitalmars-d-learn

On Thursday, 25 July 2024 at 15:06:35 UTC, IchorDev wrote:
I think your function most likely has a safe interface, so it 
can be marked as `@trusted` as-per [the 
spec](https://dlang.org/spec/function.html#safe-interfaces).


Just to mention that with -dip1000, taking the address of 
variables is allowed, so the function would be @safe.


Re: Prevent self-comparison without taking the address

2024-07-25 Thread IchorDev via Digitalmars-d-learn

On Thursday, 25 July 2024 at 14:05:50 UTC, Dom DiSc wrote:

As he said: no. It's only true for @safe:


No they did not, they specifically said that my assertion holds 
true for all other [function 
attributes](https://dlang.org/spec/attribute.html#function-attributes). This does not tell me anything about other attributes like `align`, `deprecated`, `@__future`, linkage attributes, visibility attributes, mutability attributes, shared storage attributes, `@system` variables, or UDAs.



But that doesn't answer my question.


Your question was ‘Can I replace this pattern with `(x is 
this)`’. The answer is no.


You said it is not the same. But then: is there another way to 
translate the C++ pattern in a @safe way?


This is the first time you have mentioned this intention with 
words. I’m not a mind reader.
I think your function most likely has a safe interface, so it can 
be marked as `@trusted` as-per [the 
spec](https://dlang.org/spec/function.html#safe-interfaces). 
Let’s go through the checklist:
- undefined behaviour? Nothing undefined about comparing two 
numbers.
- creates unsafe values accessible by safe code? No it only 
returns a Boolean.

- unsafe aliasing accessible by safe code? No aliasing whatsoever.


Re: Prevent self-comparison without taking the address

2024-07-25 Thread Dom DiSc via Digitalmars-d-learn

On Thursday, 25 July 2024 at 13:20:59 UTC, IchorDev wrote:

On Thursday, 25 July 2024 at 13:01:53 UTC, Dennis wrote:
That's true for the other function attributes, but `@safe:` 
actually does penetrate scopes


The spec doesn’t mention this at all! Is this the case for any 
other `AttributeSpecifier` declarations?


As he said: no. It's only true for @safe:


But that doesn't answer my question.
You said it is not the same. But then: is there another way to 
translate the C++ pattern in a @safe way?


Re: Prevent self-comparison without taking the address

2024-07-25 Thread IchorDev via Digitalmars-d-learn

On Thursday, 25 July 2024 at 13:01:53 UTC, Dennis wrote:
That's true for the other function attributes, but `@safe:` 
actually does penetrate scopes


The spec doesn’t mention this at all! Is this the case for any 
other `AttributeSpecifier` declarations?


Re: copy must be const?!?

2024-07-25 Thread Jonathan M Davis via Digitalmars-d-learn
On Thursday, July 25, 2024 6:00:58 AM MDT Dom DiSc via Digitalmars-d-learn 
wrote:
> > And no, in general, you don't want to be casting away const or
> > immutable. There are cases where it can work (e.g. if the cast
> > does a copy, which it would with an integer type)
>
> But a parameter given by value is ALWAYS a copy.
> So if a copy is done, the copy should be mutable. I can't see why
> that should ever be a problem. The compiler should never create
> new values const or immutable unless explicitly advised to do so.

It has to be a _full_, independent copy. If you're talking about integer
types, that's a non-issue, but if you're talking about types with any
indirections, it becomes a big issue. If the type contains any pointers,
dynamic arrays, class references, etc. then the copy can't be mutable unless
you're dealing with a struct with a copy constructor that does a deep copy
of all of the member variables. So, in the general case, you cannot copy a
value and expect to get a mutable result.

> E.g.
> ```d
> void fun(myType x) { }
> ```
>
> called with immutable object should create a mutable x, because
>
> ```d
>myType x = immutableObject;
> ```
>
> will also create a mutable x. If I want an immutable x, i can do
>
> ```d
>immutable myType = immutableObject;
> ```
>
> ```d
> void fun(T)(T x) if (is(Unqual!T==myType)) { }
> ```
>
> should also create a mutable x, for the same reason, because if I
> want an immutable x, I can do
>
>
> ```d
> void fun(T)(immutable(T) x) if (is(Unqual!T==myType)) { }
> ```
>
> Therefore I consider the current behaviour a bug.

It's most definitely not a bug that IFTI (Implicit Function Template
Instantiation) instantiates the template with the exact type that it's
given. In the general case, that's what you want - particularly since many,
many types (probably the vast majority of types) cannot be const or
immutable and then result in a mutable copy when they're copied. That really
only works with very simple types with no indirections. In the general case,
there is no expectation whatsoever that it's going to be possible to get a
mutable copy from a const or immutable variable, and generic code that
expects that to work is very likely to run into problems very quickly.

Now, the fact that code such as

void fun(T : const U, U)(U x)
if(is(immutable T == immutable U))
{
...
}

or code like

void fun(T)(Unqual!T x)
{
}

doesn't work with IFTI and requires explicit instantation is definitely a
deficiency in IFTI's current capabilities, but in the general case, we very
much want

void fun(T)(T x) {}

to be instantiated as fun!(const Foo) if it's passed a const Foo.

For some types, we _would_ like the ability to tell the compiler to
implicitly instantiate function templates with a tail-const version similar
to what we get with dynamic arrays, but that really only makes sense for
certain types such as ranges.

But either way, it would cause quite a few problems if IFTI started
instantiating templates in general with mutable instead of the actual type
that it's given, because it's extremely common that const and immutable
types cannot be converted to mutable.

- Jonathan M Davis





Re: Prevent self-comparison without taking the address

2024-07-25 Thread Dennis via Digitalmars-d-learn

On Thursday, 25 July 2024 at 11:46:29 UTC, IchorDev wrote:
Also just so you know, placing `@safe:` there will not affect 
the contents of `S`. It has to be inside the struct declaration 
to affect its contents.


That's true for the other function attributes, but `@safe:` 
actually does penetrate scopes


Re: copy must be const?!?

2024-07-25 Thread Dom DiSc via Digitalmars-d-learn

On Thursday, 25 July 2024 at 08:42:29 UTC, Jonathan M Davis wrote:

It's not a cast. Casts in D use the keyword, cast - e.g.

return --(cast(T)x);

Rather, Dennis' solution is constructing a value of the given 
type. For it to work, T must be constructible from an immutable 
T - which works with integer types but won't actually work with 
most types.


Ah! Good, so at least here I can use it. Fine.
Should also wor if the type has an appropriate constructor, e.g. 
a copy constructor that takes a const parameter and returns a 
mutable copy (as I would expect every copy constructor to do), so 
at least in code I write, I will never have a problem.


It also won't work with pointer types or reference types, since 
those would need new when constructing them.


Of course. For those that also wouldn't work for functions 
instead of templates.


And no, in general, you don't want to be casting away const or 
immutable. There are cases where it can work (e.g. if the cast 
does a copy, which it would with an integer type)


But a parameter given by value is ALWAYS a copy.
So if a copy is done, the copy should be mutable. I can't see why 
that should ever be a problem. The compiler should never create 
new values const or immutable unless explicitly advised to do so.

E.g.
```d
void fun(myType x) { }
```

called with immutable object should create a mutable x, because

```d
  myType x = immutableObject;
```

will also create a mutable x. If I want an immutable x, i can do

```d
  immutable myType = immutableObject;
```

```d
void fun(T)(T x) if (is(Unqual!T==myType)) { }
```

should also create a mutable x, for the same reason, because if I 
want an immutable x, I can do



```d
void fun(T)(immutable(T) x) if (is(Unqual!T==myType)) { }
```

Therefore I consider the current behaviour a bug.


Re: Prevent self-comparison without taking the address

2024-07-25 Thread IchorDev via Digitalmars-d-learn

On Thursday, 25 July 2024 at 10:50:04 UTC, Dom DiSc wrote:

```d
@safe:
struct S{
```


Also just so you know, placing `@safe:` there will not affect the 
contents of `S`. It has to be inside the struct declaration to 
affect its contents.


Re: Prevent self-comparison without taking the address

2024-07-25 Thread IchorDev via Digitalmars-d-learn

On Thursday, 25 July 2024 at 10:50:04 UTC, Dom DiSc wrote:
Can I replace this pattern with ```(x is this)``` or are there 
some special cases where this doen't work?


When a parameter is `ref` it is treated as a value type (i.e. it 
has value semantics), even though it is a reference; therefore an 
identity expression of `x is this` will check whether the bits in 
`x` and `this` are identical: 
https://dlang.org/spec/expression.html#identity_expressions
Using the reference operator (`&`) on something that is `ref` 
returns its pointer form, which is what you want to compare.


TL;DR: No, `is` will compare the struct data not the pointers.


Re: copy must be const?!?

2024-07-25 Thread Jonathan M Davis via Digitalmars-d-learn
On Thursday, July 25, 2024 12:50:04 AM MDT Dom DiSc via Digitalmars-d-learn 
wrote:
> On Wednesday, 24 July 2024 at 15:40:28 UTC, Dennis wrote:
> >> Is there a way to tell the compiler that it should discard
> >> "const" and "immutable" if it needs to create a copy?
> >> Unqual!T doesn't work :-(
> >
> > When you add `const` or `immutable` before the template type
> > parameter, it will infer T as simply `int`:
> >
> > ```D
> > T test2(T)(immutable T x) { return --T(x); }
> > ```
>
> Woah. Is this @safe?
> Ok, I know this is a fresh copy, that hopefully doesn't go to
> non-volatile memory, but I'm always sceptical casting away const.

It's not a cast. Casts in D use the keyword, cast - e.g.

return --(cast(T)x);

Rather, Dennis' solution is constructing a value of the given type. For it
to work, T must be constructible from an immutable T - which works with
integer types but won't actually work with most types. It also won't work
with pointer types or reference types, since those would need new when
constructing them.

And no, in general, you don't want to be casting away const or immutable.
There are cases where it can work (e.g. if the cast does a copy, which it
would with an integer type), but if you ever cast away const or immutable
and mutate the result when the result isn't a fully independent copy, you're
violating the type system.

Usually, in cases like this one, you'd just require that the caller pass a
type that's mutable, forcing the caller to do whatever is appropriate to get
a mutable copy rather than trying to do such a copy internally, but Dennis'
solution will work with some types. That could be done by just letting the
caller get an error (like you were), or the more user-friendly solution is
to use a template constraint that checks that the operations that you need
to use actually work with the given type, e.g.

T test2(T)(T x)
if(is(typeof(--x)))
{
return --x;
}

So, then you get an error about the template constraint failing rather than
the template simply not being able to be instantiated. And aside from the
issue of const, that's arguably a better solution anyway, since then it will
catch any type which doesn't work with the decrement operator.

Then if you wanted to pass a const int, some of the options would be

test2(int(i));

test2(cast(int)(i));

test2!int(i); // works, because the compiler will copy i

In general though, you can't currently pass a const type to a templated
function and then have it instantiated without const. The only types that
that currently works with are dynamic arrays. Templated functions which take
dynamic arrays are instantiated with the same type you get when slicing
them, which means that const gets removed from the array itself but not from
the element type, e.g.

const int[] arr;
static assert(is(typeof(arr) == const(int[])));
static assert(is(typeof(arr[]) == const(int)[]));

So, if you have something like

immutable string foo = "hello";

and you pass it to a templated function, the type will be treated as string,
whereas with a user-defined type - or with any built-in types which aren't
dynamic arrays - the templated function is instantiated with exactly the
type that you pass it.

- Jonathan M Davis





Re: copy must be const?!?

2024-07-25 Thread Dom DiSc via Digitalmars-d-learn

On Wednesday, 24 July 2024 at 15:40:28 UTC, Dennis wrote:
Is there a way to tell the compiler that it should discard 
"const" and "immutable" if it needs to create a copy?

Unqual!T doesn't work :-(


When you add `const` or `immutable` before the template type 
parameter, it will infer T as simply `int`:


```D
T test2(T)(immutable T x) { return --T(x); }
```


Woah. Is this @safe?
Ok, I know this is a fresh copy, that hopefully doesn't go to 
non-volatile memory, but I'm always sceptical casting away const.


Re: Array concatenation & optimisation

2024-07-22 Thread IchorDev via Digitalmars-d-learn

On Monday, 22 July 2024 at 12:03:33 UTC, Quirin Schroll wrote:

this has no effect on whether the function is `@nogc`.


That is a highly amusing (but obviously understandable) logical 
contradiction that I’d never considered before.

‘Sometimes you can’t use non-GC code in `@nogc` code.’


Re: Array concatenation & optimisation

2024-07-22 Thread Nick Treleaven via Digitalmars-d-learn

On Sunday, 21 July 2024 at 10:33:38 UTC, Nick Treleaven wrote:

On Sunday, 21 July 2024 at 05:43:32 UTC, IchorDev wrote:
Does this mean that array literals are *always* separately 
allocated first, or is this usually optimised out?


My understanding is that they do not allocate if used to 
initialize or assign a static array. That includes passing an 
array literal as an argument to a static array function 
parameter.


A scope slice can also be initialized from an array literal in 
@nogc code:

https://dlang.org/changelog/2.102.0.html#dmd.scope-array-on-stack


Another (related) case that doesn't heap allocate is when passing 
a literal as a scope parameter:


```d
void main() @nogc {
f([1,2]);
}

void f(scope int[]) @nogc;
```

I will look at adding these cases to the spec.


Re: Array concatenation & optimisation

2024-07-22 Thread Quirin Schroll via Digitalmars-d-learn

On Sunday, 21 July 2024 at 05:43:32 UTC, IchorDev wrote:
Obviously when writing optimised code it is desirable to reduce 
heap allocation frequency. With that in mind, I'm used to being 
told by the compiler that I can't do this in `@nogc` code:

```d
void assign(ref int[4] a) @nogc{
	a[] = [1,3,6,9]; //Error: array literal in `@nogc` function 
`assign` may cause a GC allocation

}
```

'may cause' a GC allocation


Does this mean that array literals are *always* separately 
allocated first, or is this usually optimised out?
For instance, will this example *always* allocate a new dynamic 
array for the array literal, and then append it to the existing 
one, even in optimised builds?


Optimization is unrelated to language semantics, except for what 
optimizations the language semantics allow for. Even if an 
allocation is optimized away, if the language semantics don’t 
require this optimization (which means it’s no optimization 
actually), it must pretend it’s not happening as far as 
diagnostics etc. are concerned.


My mental model of array literals is that array literals have 
their own, internal type. Think of `__arrayLiteral!(T, n)`. If 
you ask an array literal its type (e.g. using `typeof`), it’ll 
say `T[]`. But when you use it to initialize a static array, it 
simply behaves differently than a `T[]` because it just isn’t 
one. The madness about this is that even casts don’t affect the 
typing.


```d
void main() @nogc
{
int x;
enum int[] xs = [1,2,3];
int[4] ys = cast(int[])(xs ~ x); // good
int[4] zs = (b ? xs : xs) ~ x; // error
}
```
Here, neither the explicit type `int[]` for `xs` or the cast (you 
can remove any subset of them) make it so that the assignment 
isn’t `@nogc`. The whole `__arrayLiteral!(T, n)` is after some 
semi-constant folding that only applies to the length. In no way 
is `xs ~ x` a compile-time constant as `x` is a run-time value.


However, if you use `(b ? xs : xs)` instead of plain `xs` with a 
run-time boolean `b`, the language doesn’t see it as an array 
with compile-time-known length, and thus requires allocation.


In your example, you’re not assigning an array literal to a 
static array as far as the type system is concerned. The 
left-hand side is `a[]`, which has type `int[]`. So, as far as 
the type system is concerned, you assign an array literal to an 
`int[]`, and that requires allocating the literal on the GC heap, 
rendering the function non-`@nogc`. If the optimizer figures out 
that all of this ends up just putting some values in some static 
array and it removes the allocation, this has no effect on 
whether the function is `@nogc`.


Re: Using FFI to write a std::string to a buffer passed in from D

2024-07-21 Thread Troy via Digitalmars-d-learn

On Sunday, 21 July 2024 at 15:31:47 UTC, Johan wrote:

On Sunday, 21 July 2024 at 13:35:46 UTC, Troy wrote:


void create(void* b) {
std::string s = "engineer again";
*(std::string*)(b) = s;// Segfault here
}


You have to construct an empty string object first in location 
`b` (emplacement new). Then you can assign to it as you do.
The `=` calls `operator=` which assumes that both operands (`b` 
and `s`) are both fully constructed and valid `std::string` 
objects. Without emplacement new, `b` is not a valid 
`std::string` object (random byte buffer returned by `malloc`).


Hope that works,
  Johan


Using placement new like you suggested seems to have solved my 
issue perfectly.  I would never have never thought of that on my 
own.  Thanks for the suggestion!


Re: Array concatenation & optimisation

2024-07-21 Thread IchorDev via Digitalmars-d-learn

On Sunday, 21 July 2024 at 15:41:50 UTC, Johan wrote:

https://d.godbolt.org/z/sG5Kancs4

The short array is not dynamically allocated (it's allocated on 
the stack, or for larger arrays it will be a hidden symbol in 
the binary image), even at `-O0` (i.e. `-O` was not passed).


Wow thanks, that's an impressive find! I didn't know LDC was 
quite so clever either.


Re: Array concatenation & optimisation

2024-07-21 Thread IchorDev via Digitalmars-d-learn

On Sunday, 21 July 2024 at 10:33:38 UTC, Nick Treleaven wrote:
Just to mention that if you assign to the static array it 
works: `a = [1,3,6,9];`.


Bonkers. `array[]` is meant to be 'all of `array` as a slice', so 
you'd think that's how you copy a slice to a static array, but no!


My understanding is that they do not allocate if used to 
initialize or assign a static array. That includes passing an 
array literal as an argument to a static array function 
parameter.


D is pretty eager to make array literals into slices; thus have I 
developed a general distrust for using array literals in the 
vicinity of static arrays.


Case and point:

A scope slice can also be initialized from an array literal in 
@nogc code:

https://dlang.org/changelog/2.102.0.html#dmd.scope-array-on-stack
But assigning a literal to a scope slice is not allowed in 
@nogc code.



If there is enough spare capacity in a's allocation, no 
allocation will occur.


Obviously for a long array literal, the benefit of knowing its 
length upfront (and the readability) would probably outweigh 
the allocation; but for small array literals, is splitting 
them into separate concatenations going to yield faster code, 
or will I waste my time and screen space?


Note that concatenation always allocates:

Concatenation always creates a copy of its operands, even if 
one of the operands is a 0 length array


https://dlang.org/spec/arrays.html#array-concatenation


Thank you for all this info!

P.S. I am mostly addressing LDC2 & GDC's output, since I am 
aware that DMD's optimisations are usually minimal.


While people may say that on the forum, dmd's optimizer does 
actually do data flow analysis:

https://forum.dlang.org/post/uqhgoi$31a7$1...@digitalmars.com


People frequently come here to complain that 'D is slow' when 
they're using DMD, and often not even using `-O`. The responses 
will then usually contain some version of 'don't use DMD to 
generate optimised code'.


Re: Array concatenation & optimisation

2024-07-21 Thread Johan via Digitalmars-d-learn

On Sunday, 21 July 2024 at 05:43:32 UTC, IchorDev wrote:


Does this mean that array literals are *always* separately 
allocated first, or is this usually optimised out?


Not always allocated, see your example below.
I don't quite know what the heuristic is for allocation or not...

For instance, will this example *always* allocate a new dynamic 
array for the array literal, and then append it to the existing 
one, even in optimised builds?

```d
void append(ref int[] a){
a ~= [5, 4, 9];
}
```


https://d.godbolt.org/z/sG5Kancs4

The short array is not dynamically allocated (it's allocated on 
the stack, or for larger arrays it will be a hidden symbol in the 
binary image), even at `-O0` (i.e. `-O` was not passed).


-Johan



Re: Using FFI to write a std::string to a buffer passed in from D

2024-07-21 Thread Johan via Digitalmars-d-learn

On Sunday, 21 July 2024 at 13:35:46 UTC, Troy wrote:


void create(void* b) {
std::string s = "engineer again";
*(std::string*)(b) = s;// Segfault here
}


You have to construct an empty string object first in location 
`b` (emplacement new). Then you can assign to it as you do.
The `=` calls `operator=` which assumes that both operands (`b` 
and `s`) are both fully constructed and valid `std::string` 
objects. Without emplacement new, `b` is not a valid 
`std::string` object (random byte buffer returned by `malloc`).


Hope that works,
  Johan



Re: Array concatenation & optimisation

2024-07-21 Thread Nick Treleaven via Digitalmars-d-learn

On Sunday, 21 July 2024 at 10:33:38 UTC, Nick Treleaven wrote:
For instance, will this example *always* allocate a new 
dynamic array for the array literal, and then append it to the 
existing one, even in optimised builds?

```d
void append(ref int[] a){
a ~= [5, 4, 9];
}
```


If there is enough spare capacity in a's allocation, no 
allocation will occur.


Sorry, I see what you mean. I've compared the -vasm output 
(without -O) for that function and this one:


```d
void append(ref int[] a){
enum e = [5, 4, 9];
a ~= e;
}
```
The ASM output is the same. If you use runtime value elements I'm 
not sure but I think there's still no heap allocation.


I'm not good at reading ASM though.


Re: Tuple deconstruction in Phobos

2024-07-21 Thread Nick Treleaven via Digitalmars-d-learn

On Sunday, 21 July 2024 at 04:05:52 UTC, IchorDev wrote:

On Saturday, 20 July 2024 at 20:48:29 UTC, Nick Treleaven wrote:

Instead of the `tie` assignment, you can just do:
```d
import std.meta;
AliasSeq!(y, x) = tupRetFn().expand;
```


And here I was trying to use comma expressions for this like a 
buffoon! Of course they didn't work, but I'm pleasantly 
surprised that using a sequence does.


I think The lvalue sequence docs in template.dd were only updated 
in the last year to mention sequence assignment.


I should really PR `std.typecons` to add a couple of examples 
of this, because I think a lot of people will have overlooked 
it.


Good idea.



Re: Array concatenation & optimisation

2024-07-21 Thread Nick Treleaven via Digitalmars-d-learn

On Sunday, 21 July 2024 at 05:43:32 UTC, IchorDev wrote:
Obviously when writing optimised code it is desirable to reduce 
heap allocation frequency. With that in mind, I'm used to being 
told by the compiler that I can't do this in `@nogc` code:

```d
void assign(ref int[4] a) @nogc{
	a[] = [1,3,6,9]; //Error: array literal in `@nogc` function 
`assign` may cause a GC allocation

}
```


Just to mention that if you assign to the static array it works: 
`a = [1,3,6,9];`.



'may cause' a GC allocation


Does this mean that array literals are *always* separately 
allocated first, or is this usually optimised out?


My understanding is that they do not allocate if used to 
initialize or assign a static array. That includes passing an 
array literal as an argument to a static array function parameter.


A scope slice can also be initialized from an array literal in 
@nogc code:

https://dlang.org/changelog/2.102.0.html#dmd.scope-array-on-stack

But assigning a literal to a scope slice is not allowed in @nogc 
code.


For instance, will this example *always* allocate a new dynamic 
array for the array literal, and then append it to the existing 
one, even in optimised builds?

```d
void append(ref int[] a){
a ~= [5, 4, 9];
}
```


If there is enough spare capacity in a's allocation, no 
allocation will occur.


Obviously for a long array literal, the benefit of knowing its 
length upfront (and the readability) would probably outweigh 
the allocation; but for small array literals, is splitting them 
into separate concatenations going to yield faster code, or 
will I waste my time and screen space?


Note that concatenation always allocates:

Concatenation always creates a copy of its operands, even if 
one of the operands is a 0 length array


https://dlang.org/spec/arrays.html#array-concatenation

P.S. I am mostly addressing LDC2 & GDC's output, since I am 
aware that DMD's optimisations are usually minimal.


While people may say that on the forum, dmd's optimizer does 
actually do data flow analysis:

https://forum.dlang.org/post/uqhgoi$31a7$1...@digitalmars.com


Re: Tuple deconstruction in Phobos

2024-07-20 Thread IchorDev via Digitalmars-d-learn

On Saturday, 20 July 2024 at 20:48:29 UTC, Nick Treleaven wrote:

Instead of the `tie` assignment, you can just do:
```d
import std.meta;
AliasSeq!(y, x) = tupRetFn().expand;
```


And here I was trying to use comma expressions for this like a 
buffoon! Of course they didn't work, but I'm pleasantly surprised 
that using a sequence does. I should really PR `std.typecons` to 
add a couple of examples of this, because I think a lot of people 
will have overlooked it.
I honestly thought there was no way to do this in D for the 
longest time until I saw some C++ code using `std::tie` and I 
realised that obviously the same thing is doable in D using 
`opAssign`, and then refined it to use UFCS because the syntax 
`Tie!(y,x)()` was a bit clunky.


Re: Tuple deconstruction in Phobos

2024-07-20 Thread Nick Treleaven via Digitalmars-d-learn

On Saturday, 20 July 2024 at 14:02:21 UTC, IchorDev wrote:
Why does Phobos not provide a method to easily deconstruct 
tuples? Here's a trivial implementation:

...

tie!(y, x) = tupRetFn().expand;
writeln(x,", ",y);
}
```
Not having this is like if Phobos didn't have `AliasSeq`. Yes 
you can make your own, but it's wasteful boilerplate.


Instead of the `tie` assignment, you can just do:
```d
import std.meta;
AliasSeq!(y, x) = tupRetFn().expand;
```


Re: Unexpected range assignment behaviour

2024-07-19 Thread Jonathan M Davis via Digitalmars-d-learn
On Friday, July 19, 2024 12:02:55 PM MDT H. S. Teoh via Digitalmars-d-learn 
wrote:
> On Fri, Jul 19, 2024 at 05:48:37PM +, Dennis via Digitalmars-d-learn 
wrote:
> > On Friday, 19 July 2024 at 17:20:22 UTC, matheus wrote:
> > > couldn't this case for example be caught during the compiling time?
> >
> > The RangeError is only thrown when at runtime, the key doesn't exist,
> > so that can't be caught. The real problem is implicit slicing of
> > static arrays, which I'm not a fan of, but removing it is a breaking
> > change. So perhaps Associative Arrays should be enhanced to create
> > keys on slice assignment.
>
> IMO, implicit slicing of static arrays ought to be killed with fire.
> This is not the first time it has caused problems.  In the past it used
> to cause issues with the implicit slice escaping the scope of the
> original static array, leading to dangling pointers and subsequent
> memory corruption / UB.  With -dip1000 the situation has somewhat
> improved, but not entirely. It still causes nasty surprises when a slice
> was implicitly taken where it was unexpected.  This case here is another
> example of the problems that it causes.

Very, very hot fire. :)

IIRC, Atila has indicated that he would like to kill implicit slicing of
static arrays (though that's going to require that we have actually started
doing Editions first), so we may end up finally getting rid of it. I don't
know how much convincing it will take for Walter though.

I actually brought this up with Walter years ago at one of the dconfs in
Berlin, suggesting that it was a big @safety mistake, but he preferred the
idea of improving the language to catch escaping over removing the implicit
slicing (which is probably part of why DIP 1000 and the related changes have
unfortunately become a thing).

Regardless of DIP 1000 though, IMHO, the implicit slicing just causes
confusion and invisible behavior simply so that you can avoid using an
explicit [] - and some of that isn't even related to bugs per se. For
instance, plenty of folks end up trying to pass a static array to a
range-based function and get confused when that doesn't work, since if the
function took a dynamic array, it would work (and that also makes it more
problematic to change a function so that it takes a range instead of a
dynamic array). It's one of those features that seems like it's a nice
usability improvement at first glance but which ultimately is a footgun.

And when you get a more complex example like the one in this thread, it's
that much worse, since even if you know enough to suspect that something
along those lines might be the problem, I bet that most of us would not
immediately come to that conclusion. It's just too subtle. And all to avoid
typing a couple of characters.

- Jonathan M Davis





Re: Unexpected range assignment behaviour

2024-07-19 Thread H. S. Teoh via Digitalmars-d-learn
On Fri, Jul 19, 2024 at 05:48:37PM +, Dennis via Digitalmars-d-learn wrote:
> On Friday, 19 July 2024 at 17:20:22 UTC, matheus wrote:
> > couldn't this case for example be caught during the compiling time?
> 
> The RangeError is only thrown when at runtime, the key doesn't exist,
> so that can't be caught. The real problem is implicit slicing of
> static arrays, which I'm not a fan of, but removing it is a breaking
> change. So perhaps Associative Arrays should be enhanced to create
> keys on slice assignment.

IMO, implicit slicing of static arrays ought to be killed with fire.
This is not the first time it has caused problems.  In the past it used
to cause issues with the implicit slice escaping the scope of the
original static array, leading to dangling pointers and subsequent
memory corruption / UB.  With -dip1000 the situation has somewhat
improved, but not entirely. It still causes nasty surprises when a slice
was implicitly taken where it was unexpected.  This case here is another
example of the problems that it causes.


T

-- 
I don't trust computers, I've spent too long programming to think that
they can get anything right. -- James Miller


Re: Unexpected range assignment behaviour

2024-07-19 Thread Dennis via Digitalmars-d-learn

On Friday, 19 July 2024 at 17:20:22 UTC, matheus wrote:
couldn't this case for example be caught during the compiling 
time?


The RangeError is only thrown when at runtime, the key doesn't 
exist, so that can't be caught. The real problem is implicit 
slicing of static arrays, which I'm not a fan of, but removing it 
is a breaking change. So perhaps Associative Arrays should be 
enhanced to create keys on slice assignment.


Re: Unexpected range assignment behaviour

2024-07-19 Thread matheus via Digitalmars-d-learn

On Friday, 19 July 2024 at 15:33:34 UTC, Dennis wrote:

On Friday, 19 July 2024 at 09:34:13 UTC, Lewis wrote:
But the value of $ here is 3. Why do I get a RangeError at 
runtime even though the slice is the correct size (and the 
same size as the hardcoded one that works)?


The range `0 .. 3` has compile time known length, so it gets 
converted to string[3]:


```D
lookup["test"] = dynArray[0 .. 3];
// becomes
lookup["test"] = cast(string[3]) dynArray[0 .. 3];
```

The key "test" doesn't exist yet, but because it's an 
assignment, it gets created.
However, `0 .. $` depends on a run-time variable here, so it 
doesn't convert to a static array and does slice assignment:


```D
lookup["test"] = dynArray[0 .. $];
// becomes
lookup["test"][0 .. $] = dynArray[0 .. $];
```

Now, you get a range error because "test" doesn't exist in 
`lookup`, and slice assignment doesn't create a new entry.


Hi Dennis, I undestood your explanation, and based on that  
couldn't this case for example be caught during the compiling 
time?


Thanks,

Matheus.


Re: Unexpected range assignment behaviour

2024-07-19 Thread Lance Bachmeier via Digitalmars-d-learn

On Friday, 19 July 2024 at 09:34:13 UTC, Lewis wrote:

```
string[3][string] lookup;
string[] dynArray = ["d", "e", "f"];
lookup["test"] = dynArray[0..$];
```

This fails at runtime with RangeError. But if I change that 
last line to:


```
lookup["test"] = dynArray[0..3];
```

then it works. But the value of $ here is 3. Why do I get a 
RangeError at runtime even though the slice is the correct size 
(and the same size as the hardcoded one that works)? I would 
have expected to only get a RangeError if at runtime the value 
turned out to be wrong.


The simplest solution is to keep them consistent:

```
string[3][string] lookup;
string[3] dynArray = ["d", "e", "f"];
```

or

```
string[][string] lookup;
string[] dynArray = ["d", "e", "f"];
```

Avoid the temptation to mix static and dynamic arrays and your 
life will be easier. If you run into a situation where it's tough 
to avoid, use an explicit conversion:


```
lookup["test"] = dynArray.to!(string[3])[0..$];
```

(I don't know all the complicated under the hood stuff as others 
do, but I know what works and why.)


Re: Unexpected range assignment behaviour

2024-07-19 Thread Dennis via Digitalmars-d-learn

On Friday, 19 July 2024 at 09:34:13 UTC, Lewis wrote:
But the value of $ here is 3. Why do I get a RangeError at 
runtime even though the slice is the correct size (and the same 
size as the hardcoded one that works)?


The range `0 .. 3` has compile time known length, so it gets 
converted to string[3]:


```D
lookup["test"] = dynArray[0 .. 3];
// becomes
lookup["test"] = cast(string[3]) dynArray[0 .. 3];
```

The key "test" doesn't exist yet, but because it's an assignment, 
it gets created.
However, `0 .. $` depends on a run-time variable here, so it 
doesn't convert to a static array and does slice assignment:


```D
lookup["test"] = dynArray[0 .. $];
// becomes
lookup["test"][0 .. $] = dynArray[0 .. $];
```

Now, you get a range error because "test" doesn't exist in 
`lookup`, and slice assignment doesn't create a new entry.




Re: Unexpected range assignment behaviour

2024-07-19 Thread H. S. Teoh via Digitalmars-d-learn
On Fri, Jul 19, 2024 at 09:34:13AM +, Lewis via Digitalmars-d-learn wrote:
> ```
> string[3][string] lookup;
> string[] dynArray = ["d", "e", "f"];
> lookup["test"] = dynArray[0..$];
> ```
> 
> This fails at runtime with RangeError. But if I change that last line to:
> 
> ```
> lookup["test"] = dynArray[0..3];
> ```
> 
> then it works. But the value of $ here is 3. Why do I get a RangeError
> at runtime even though the slice is the correct size (and the same
> size as the hardcoded one that works)? I would have expected to only
> get a RangeError if at runtime the value turned out to be wrong.

Sounds like a bug.  First, there's an incompatibility between AA value
type and the type being assigned: the value type of `lookup` is a static
array, whereas a slice is a dynamic array.  But since the compiler
allows this assignment, it should work.  I suspect there's a frontend
bug somewhere in how assignments of slices to static arrays are
implemented.


T

-- 
MAS = Mana Ada Sistem?


Re: Error: circular reference to variable cause by order (bugs?)

2024-07-18 Thread monkyyy via Digitalmars-d-learn

On Thursday, 18 July 2024 at 12:25:37 UTC, Dakota wrote:

I am trying to translate some c code into d, get this error:

```d
struct A {
void* sub;
}

struct B {
void* subs;
}

__gshared {
const A[1] a0 = [
{ _ptr },
];
const A[2] a1 = [
{ _ptr },
];
const B b1 = {a1.ptr};
const b1_ptr = 

const A[1] a2 = [
{ _ptr },
];
const B b2 = {a2.ptr};
const b2_ptr = 
}

```

```sh
 Error: circular reference to variable `tests.b1_ptr`
```

If I move `a0` after `b2_ptr`, no error any more.

The c code has circular reference type, and compile ok. and 
there is a lot type I am not able to adjust order by hand to 
guess right order.


the translate code still need to work with C interface, so I 
can not change the struct layout.  is this a bug of d?


if it was a compiler bug it probably be a crash; and the c code 
may have had a header file of some sort to make the linker happy 
that the traslator skipped


that is just confusing cyclic code


Re: Recommendations on porting Python to D

2024-07-17 Thread rkompass via Digitalmars-d-learn

On Monday, 15 July 2024 at 19:40:01 UTC, mw wrote:

On Friday, 12 July 2024 at 18:07:50 UTC, mw wrote:

[...]


FYI, now merged into the main branch:

https://github.com/py2many/py2many/tree/main/pyd


This is great and certainly deserves an own discussion 
contribution in General.


Did you try to convert any of the pystone programs?
This would allow for benchmarking comparisons with e.g. nuitka or 
other approaches of compiled Python.




Re: Recommendations on porting Python to D

2024-07-15 Thread mw via Digitalmars-d-learn

On Friday, 12 July 2024 at 18:07:50 UTC, mw wrote:

On Friday, 3 May 2024 at 17:38:10 UTC, Chris Piker wrote:

On Thursday, 25 April 2024 at 16:57:53 UTC, mw wrote:
On Wednesday, 24 April 2024 at 22:07:41 UTC, Chris Piker 
wrote:



Python-AST to D source converter may already exist?


https://github.com/joortcom/eiffel_rename/tree/main/yi

A rudimentary converter from (extended) Python to D. Maybe 
you can use it as a starting point.


Thanks for the suggestions.  I put the question aside for a 
bit, but yesterday ran across a python transpiler here:


  https://github.com/py2many/py2many

It already has support for C++, Go and others.  Since I have 
mountains of python code created over many years, maybe it 
would be worth contributing to this project out of self 
interest.


Can you take a look at py2many and see what you think about 
it?  Getting D on the support list might be good.


Hi,

I have made basic py2many.pyd work at language/syntax level in 
my dlang fork:


https://github.com/mw66/py2many/tree/dlang

The following examples works now:

https://github.com/mw66/py2many/tree/dlang/tests/expected

py2many/ 13:56:23$ ls ./tests/expected/*.d
./tests/expected/bubble_sort.d
./tests/expected/cls.d
./tests/expected/fib.d
./tests/expected/import_tests.d
./tests/expected/classes.d
./tests/expected/dict.d
./tests/expected/hello_world.d
./tests/expected/nested_dict.d


I haven't created PR to be merged into the main branch, since 
it's better to pass all the tests.


All the remaining work is to make Python's specific feature 
(e.g. async), library (e.g. complex number, NamedTemporaryFile) 
work in D. There are many things need to be done, if you have 
time, you can pick up from my fork, and work from there. (E.g. 
you can create PR to my branch, and when everything is ready, 
we submit to the main py2many all together).



HTH.


FYI, now merged into the main branch:

https://github.com/py2many/py2many/tree/main/pyd




Re: need help to check symbol is static variable or not

2024-07-15 Thread Dakota via Digitalmars-d-learn

On Monday, 15 July 2024 at 11:16:23 UTC, Nick Treleaven wrote:

I put `type_s` in a file anonstruct.c, then:
```d
import anonstruct;

pragma(msg, isStatic!(type_s.c));
```
That outputs `false`, because the symbol is not a compile-time 
value. Is that what you meant?



No, I am here deal with a lot type and structs, no symbol problem 
yet.


I guess the problem cause by the subtype has a hidden pointer to 
parent.









Re: need help to check symbol is static variable or not

2024-07-15 Thread Nick Treleaven via Digitalmars-d-learn

On Monday, 15 July 2024 at 06:44:12 UTC, Dakota wrote:

```d
struct type_s
{

union {
struct
{
int a;
int b;
} c;
};
};
```

`type c` will return false with `enum isStatic(alias V) = 
__traits(compiles, { enum v = V; });`


I put `type_s` in a file anonstruct.c, then:
```d
import anonstruct;

pragma(msg, isStatic!(type_s.c));
```
That outputs `false`, because the symbol is not a compile-time 
value. Is that what you meant?


Re: need help to check symbol is static variable or not

2024-07-15 Thread Dakota via Digitalmars-d-learn

On Monday, 1 July 2024 at 11:15:46 UTC, Nick Treleaven wrote:

```



There is a case check will give wrong resutls:


```d
struct type_s
{

union {
struct
{
int a;
int b;
} c;
};
};
```

`type c` will return false with `enum isStatic(alias V) = 
__traits(compiles, { enum v = V; });`


type_s is from importC with DMD v2.110.0-beta.1.



Re: std.container.rbtree has no search method?! e.g. `contains`, `canFind`

2024-07-14 Thread mw via Digitalmars-d-learn
On Sunday, 14 July 2024 at 02:01:44 UTC, Steven Schveighoffer 
wrote:

On Saturday, 13 July 2024 at 17:41:42 UTC, mw wrote:

Hi,

on doc:

https://dlang.org/phobos/std_container_rbtree.html#.RedBlackTree

I cannot find any search method?! e.g. `contains`, `canFind`.

Is this a over look? Or there are such functions else where?


The functions are called `equalRange` (which gives you a range 
of all the elements that compare equal to the parameter), 
`lowerBound` (all elements less than the parameter), and 
`upperBound` (all elements greater than the parameter).


This was not my choice, my original dcollections implementation 
used a `find` function. It was a condition for having the type 
added to phobos.


-Steve


I think for containers, it's better to have uniform naming 
convention, either `contains`, `canFind` or `in`, so writing 
generic code (e.g. via D template) is easier.




Re: How to build a statically linked executable, before i loose my mind

2024-07-14 Thread ryuukk_ via Digitalmars-d-learn
On Sunday, 14 July 2024 at 06:34:54 UTC, Richard (Rikki) Andrew 
Cattermole wrote:

On 14/07/2024 5:06 AM, ryuukk_ wrote:
On Saturday, 13 July 2024 at 16:44:22 UTC, Richard (Rikki) 
Andrew Cattermole wrote:

On 14/07/2024 4:37 AM, ryuukk_ wrote:
On Saturday, 13 July 2024 at 16:16:20 UTC, Richard (Rikki) 
Andrew Cattermole wrote:
Seeing ``_d_arraybounds_slice`` missing sounds like 
druntime isn't being linked against.


It is possible that your distribution of ldc doesn't 
include a static build of druntime/phobos. You need to 
verify that ld is trying to link against a static build and 
that static build exists.


`curl -fsS https://dlang.org/install.sh | bash -s ldc`


Okay yup, looks like its all there in latest release.

Have to dump out what ld is getting passed to it, and what it 
thinks it is doing next.



```
/usr/bin/ld -plugin 
/usr/lib/gcc/x86_64-linux-gnu/11/liblto_plugin.so 
-plugin-opt=/usr/lib/gcc/x86_64-linux-gnu/11/lto-wrapper 
-plugin-opt=-fresolution=/tmp/ccBV7TjM.res 
-plugin-opt=-pass-through=-lgcc 
-plugin-opt=-pass-through=-lgcc_s 
-plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc 
-plugin-opt=-pass-through=-lgcc_s --build-id --eh-frame-hdr -m 
elf_x86_64 --hash-style=gnu --as-needed -dynamic-linker 
/lib64/ld-linux-x86-64.so.2 -pie -z now -z relro -o bin/dls 
/usr/lib/gcc/x86_64-linux-gnu/11/../../../x86_64-linux-gnu/Scrt1.o /usr/lib/gcc/x86_64-linux-gnu/11/../../../x86_64-linux-gnu/crti.o /usr/lib/gcc/x86_64-linux-gnu/11/crtbeginS.o -L/home/runner/dlang/ldc-1.39.0/bin/../lib -L/home/runner/dlang/ldc-1.39.0/lib/../lib -L/usr/lib/gcc/x86_64-linux-gnu/11 -L/usr/lib/gcc/x86_64-linux-gnu/11/../../../x86_64-linux-gnu -L/usr/lib/gcc/x86_64-linux-gnu/11/../../../../lib -L/lib/x86_64-linux-gnu -L/lib/../lib -L/usr/lib/x86_64-linux-gnu -L/usr/lib/../lib -L/home/runner/dlang/ldc-1.39.0/lib -L/usr/lib/gcc/x

```


https://github.com/ryuukk/dls/actions/runs/9921536908/job/27409615370


It works locally, but not their machine, ubuntu apparently


Boom, got it working!

https://github.com/rikkimax/dls/blob/master/makefile#L39

It's a link order issue.

```
ldc2 -of=bin/dlsobj.o -c --output-o $(OPTIMIZE) $(PREVIEWS) 
-Iserver/ -i server/cjson/cJSON.c server/dls/main.d


ldc2 -of=bin/dls$(exe) bin/dlsobj.o server/dls/libdcd.a
```


It works!! thanks a lot!!


Re: Wrapper around a recursive data type

2024-07-14 Thread drug007 via Digitalmars-d-learn

On 09.07.2024 06:54, Steven Schveighoffer wrote:

On Monday, 8 July 2024 at 08:56:51 UTC, drug007 wrote:

How can I "break" this recursion or some other work around to fix it?


A few ideas:

1. If it's immediately recursive (that is, contains a pointer to 
itself), just use the type itself somehow. You may not be able to do 
this with recursive templates.
2. If the data itself is static, and not actually containing different 
things, defer the construction of the Meta members until needed. In 
other words, make them structs with a member which accesses the meta 
when requested.
3. In a project I have which constructs a parallel type on existing 
types, I use `opDispatch` to defer instantiation of the members until 
later. This may or may not work for you depending on the use case (you 
can't introspect `opDispatch`).


-Steve


Decided to use untyped array (like void[]) and then a decorator to make 
it typed one. It seems to be working, testing in progress.




Re: How to build a statically linked executable, before i loose my mind

2024-07-14 Thread Richard (Rikki) Andrew Cattermole via Digitalmars-d-learn

On 14/07/2024 5:06 AM, ryuukk_ wrote:
On Saturday, 13 July 2024 at 16:44:22 UTC, Richard (Rikki) Andrew 
Cattermole wrote:

On 14/07/2024 4:37 AM, ryuukk_ wrote:
On Saturday, 13 July 2024 at 16:16:20 UTC, Richard (Rikki) Andrew 
Cattermole wrote:
Seeing ``_d_arraybounds_slice`` missing sounds like druntime isn't 
being linked against.


It is possible that your distribution of ldc doesn't include a 
static build of druntime/phobos. You need to verify that ld is 
trying to link against a static build and that static build exists.


`curl -fsS https://dlang.org/install.sh | bash -s ldc`


Okay yup, looks like its all there in latest release.

Have to dump out what ld is getting passed to it, and what it thinks 
it is doing next.



```
/usr/bin/ld -plugin /usr/lib/gcc/x86_64-linux-gnu/11/liblto_plugin.so 
-plugin-opt=/usr/lib/gcc/x86_64-linux-gnu/11/lto-wrapper 
-plugin-opt=-fresolution=/tmp/ccBV7TjM.res 
-plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s 
-plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc 
-plugin-opt=-pass-through=-lgcc_s --build-id --eh-frame-hdr -m 
elf_x86_64 --hash-style=gnu --as-needed -dynamic-linker 
/lib64/ld-linux-x86-64.so.2 -pie -z now -z relro -o bin/dls 
/usr/lib/gcc/x86_64-linux-gnu/11/../../../x86_64-linux-gnu/Scrt1.o 
/usr/lib/gcc/x86_64-linux-gnu/11/../../../x86_64-linux-gnu/crti.o 
/usr/lib/gcc/x86_64-linux-gnu/11/crtbeginS.o 
-L/home/runner/dlang/ldc-1.39.0/bin/../lib 
-L/home/runner/dlang/ldc-1.39.0/lib/../lib 
-L/usr/lib/gcc/x86_64-linux-gnu/11 
-L/usr/lib/gcc/x86_64-linux-gnu/11/../../../x86_64-linux-gnu 
-L/usr/lib/gcc/x86_64-linux-gnu/11/../../../../lib 
-L/lib/x86_64-linux-gnu -L/lib/../lib -L/usr/lib/x86_64-linux-gnu 
-L/usr/lib/../lib -L/home/runner/dlang/ldc-1.39.0/lib -L/usr/lib/gcc/x

```


https://github.com/ryuukk/dls/actions/runs/9921536908/job/27409615370


It works locally, but not their machine, ubuntu apparently


Boom, got it working!

https://github.com/rikkimax/dls/blob/master/makefile#L39

It's a link order issue.

```
ldc2 -of=bin/dlsobj.o -c --output-o $(OPTIMIZE) $(PREVIEWS) -Iserver/ -i 
server/cjson/cJSON.c server/dls/main.d


ldc2 -of=bin/dls$(exe) bin/dlsobj.o server/dls/libdcd.a
```




Re: std.container.rbtree has no search method?! e.g. `contains`, `canFind`

2024-07-13 Thread Steven Schveighoffer via Digitalmars-d-learn

On Saturday, 13 July 2024 at 17:41:42 UTC, mw wrote:

Hi,

on doc:

https://dlang.org/phobos/std_container_rbtree.html#.RedBlackTree

I cannot find any search method?! e.g. `contains`, `canFind`.

Is this a over look? Or there are such functions else where?


The functions are called `equalRange` (which gives you a range of 
all the elements that compare equal to the parameter), 
`lowerBound` (all elements less than the parameter), and 
`upperBound` (all elements greater than the parameter).


This was not my choice, my original dcollections implementation 
used a `find` function. It was a condition for having the type 
added to phobos.


-Steve


Re: std.container.rbtree has no search method?! e.g. `contains`, `canFind`

2024-07-13 Thread Dennis via Digitalmars-d-learn

On Saturday, 13 July 2024 at 17:41:42 UTC, mw wrote:

I cannot find any search method?! e.g. `contains`, `canFind`.

Is this a over look? Or there are such functions else where?


It's the `in` operator:

https://dlang.org/phobos/std_container_rbtree.html#.RedBlackTree.opBinaryRight

But indeed, the documentation can be clearer about that.


Re: How to build a statically linked executable, before i loose my mind

2024-07-13 Thread ryuukk_ via Digitalmars-d-learn
On Saturday, 13 July 2024 at 16:44:22 UTC, Richard (Rikki) Andrew 
Cattermole wrote:

On 14/07/2024 4:37 AM, ryuukk_ wrote:
On Saturday, 13 July 2024 at 16:16:20 UTC, Richard (Rikki) 
Andrew Cattermole wrote:
Seeing ``_d_arraybounds_slice`` missing sounds like druntime 
isn't being linked against.


It is possible that your distribution of ldc doesn't include 
a static build of druntime/phobos. You need to verify that ld 
is trying to link against a static build and that static 
build exists.


`curl -fsS https://dlang.org/install.sh | bash -s ldc`


Okay yup, looks like its all there in latest release.

Have to dump out what ld is getting passed to it, and what it 
thinks it is doing next.



```
/usr/bin/ld -plugin 
/usr/lib/gcc/x86_64-linux-gnu/11/liblto_plugin.so 
-plugin-opt=/usr/lib/gcc/x86_64-linux-gnu/11/lto-wrapper 
-plugin-opt=-fresolution=/tmp/ccBV7TjM.res 
-plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s 
-plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc 
-plugin-opt=-pass-through=-lgcc_s --build-id --eh-frame-hdr -m 
elf_x86_64 --hash-style=gnu --as-needed -dynamic-linker 
/lib64/ld-linux-x86-64.so.2 -pie -z now -z relro -o bin/dls 
/usr/lib/gcc/x86_64-linux-gnu/11/../../../x86_64-linux-gnu/Scrt1.o /usr/lib/gcc/x86_64-linux-gnu/11/../../../x86_64-linux-gnu/crti.o /usr/lib/gcc/x86_64-linux-gnu/11/crtbeginS.o -L/home/runner/dlang/ldc-1.39.0/bin/../lib -L/home/runner/dlang/ldc-1.39.0/lib/../lib -L/usr/lib/gcc/x86_64-linux-gnu/11 -L/usr/lib/gcc/x86_64-linux-gnu/11/../../../x86_64-linux-gnu -L/usr/lib/gcc/x86_64-linux-gnu/11/../../../../lib -L/lib/x86_64-linux-gnu -L/lib/../lib -L/usr/lib/x86_64-linux-gnu -L/usr/lib/../lib -L/home/runner/dlang/ldc-1.39.0/lib -L/usr/lib/gcc/x

```


https://github.com/ryuukk/dls/actions/runs/9921536908/job/27409615370


It works locally, but not their machine, ubuntu apparently


Re: How to build a statically linked executable, before i loose my mind

2024-07-13 Thread Richard (Rikki) Andrew Cattermole via Digitalmars-d-learn

On 14/07/2024 4:37 AM, ryuukk_ wrote:
On Saturday, 13 July 2024 at 16:16:20 UTC, Richard (Rikki) Andrew 
Cattermole wrote:
Seeing ``_d_arraybounds_slice`` missing sounds like druntime isn't 
being linked against.


It is possible that your distribution of ldc doesn't include a static 
build of druntime/phobos. You need to verify that ld is trying to link 
against a static build and that static build exists.


`curl -fsS https://dlang.org/install.sh | bash -s ldc`


Okay yup, looks like its all there in latest release.

Have to dump out what ld is getting passed to it, and what it thinks it 
is doing next.


Re: How to build a statically linked executable, before i loose my mind

2024-07-13 Thread ryuukk_ via Digitalmars-d-learn
On Saturday, 13 July 2024 at 16:16:20 UTC, Richard (Rikki) Andrew 
Cattermole wrote:
Seeing ``_d_arraybounds_slice`` missing sounds like druntime 
isn't being linked against.


It is possible that your distribution of ldc doesn't include a 
static build of druntime/phobos. You need to verify that ld is 
trying to link against a static build and that static build 
exists.


`curl -fsS https://dlang.org/install.sh | bash -s ldc`




Re: How to build a statically linked executable, before i loose my mind

2024-07-13 Thread Richard (Rikki) Andrew Cattermole via Digitalmars-d-learn
Seeing ``_d_arraybounds_slice`` missing sounds like druntime isn't being 
linked against.


It is possible that your distribution of ldc doesn't include a static 
build of druntime/phobos. You need to verify that ld is trying to link 
against a static build and that static build exists.


Re: How to build a statically linked executable, before i loose my mind

2024-07-13 Thread ryuukk_ via Digitalmars-d-learn

For anyone curious:

https://github.com/ryuukk/dls/tree/master

``make build-dcd-release && make build-dls-release``

i'm giving up for now, i'll never touch druntime/phobos/dub never 
again


Re: How to build a statically linked executable, before i loose my mind

2024-07-13 Thread ryuukk_ via Digitalmars-d-learn

I'm loosing it

Even with dub it doesn't work

`"lflags": [ "-static", "--link-defaultlib-shared=false" ],`



```
(cut due to forum's limit)
trivia.d:(.text._D6dparse6trivia__T22MultiLineCommentHelperHTyaZQBd6__ctorMFNaNbNcNfAyaZSQCtQCp__TQClHTyaZQCt+0x1a9):
 undefined reference to `_d_arraybounds_slice'
/usr/bin/ld: 
trivia.d:(.text._D6dparse6trivia__T22MultiLineCommentHelperHTyaZQBd6__ctorMFNaNbNcNfAyaZSQCtQCp__TQClHTyaZQCt+0x1c5): undefined reference to `_d_arraybounds_slice'
/usr/bin/ld: 
trivia.d:(.text._D6dparse6trivia__T22MultiLineCommentHelperHTyaZQBd6__ctorMFNaNbNcNfAyaZSQCtQCp__TQClHTyaZQCt+0x1e3): undefined reference to `_d_arraybounds_index'
/usr/bin/ld: 
trivia.d:(.text._D6dparse6trivia__T22MultiLineCommentHelperHTyaZQBd6__ctorMFNaNbNcNfAyaZSQCtQCp__TQClHTyaZQCt+0x1fc): undefined reference to `_d_arraybounds_slice'
/usr/bin/ld: server/dls/libdcd.a(dparse.trivia.o): in function 
`_D6dparse6trivia__T22MultiLineCommentHelperHTyaZQBd__T7processTS3std5array__T8AppenderTAyaZQoZQBoMFNaNbNfKQBrZv':

trivia.d:(.text._D6dparse6trivia__T22MultiLineCommentHelperHTyaZQBd__T7processTS3std5array__T8AppenderTAyaZQoZQBoMFNaNbNfKQBrZv+0xfe):
 undefined reference to `_d_arraybounds_slice'
/usr/bin/ld: server/dls/libdcd.a(dparse.trivia.o): in function 
`_D6dparse6trivia__T22MultiLineCommentHelperHTyaZQBd11stripIndentMFNaNbNiNfZv':

trivia.d:(.text._D6dparse6trivia__T22MultiLineCommentHelperHTyaZQBd11stripIndentMFNaNbNiNfZv+0x6c):
 undefined reference to `_D3std5ascii7isWhiteFNaNbNiNfwZb'
/usr/bin/ld: 
trivia.d:(.text._D6dparse6trivia__T22MultiLineCommentHelperHTyaZQBd11stripIndentMFNaNbNiNfZv+0x142): undefined reference to `_D3std5ascii7isWhiteFNaNbNiNfwZb'
/usr/bin/ld: 
trivia.d:(.text._D6dparse6trivia__T22MultiLineCommentHelperHTyaZQBd11stripIndentMFNaNbNiNfZv+0x17d): undefined reference to `_d_arraybounds_index'
/usr/bin/ld: 
trivia.d:(.text._D6dparse6trivia__T22MultiLineCommentHelperHTyaZQBd11stripIndentMFNaNbNiNfZv+0x196): undefined reference to `_d_arraybounds_index'
/usr/bin/ld: 
trivia.d:(.text._D6dparse6trivia__T22MultiLineCommentHelperHTyaZQBd11stripIndentMFNaNbNiNfZv+0x1b1): undefined reference to `_d_arraybounds_index'
/usr/bin/ld: 
trivia.d:(.text._D6dparse6trivia__T22MultiLineCommentHelperHTyaZQBd11stripIndentMFNaNbNiNfZv+0x1cd): undefined reference to `_d_arraybounds_slice'
/usr/bin/ld: 
trivia.d:(.text._D6dparse6trivia__T22MultiLineCommentHelperHTyaZQBd11stripIndentMFNaNbNiNfZv+0x1ee): undefined reference to `_d_arraybounds_slice'
/usr/bin/ld: server/dls/libdcd.a(dparse.trivia.o): in function 
`_D6dparse6trivia__T22MultiLineCommentHelperHTyaZQBd16processFirstLineMFNaNbNiNfZv':

trivia.d:(.text._D6dparse6trivia__T22MultiLineCommentHelperHTyaZQBd16processFirstLineMFNaNbNiNfZv+0xff):
 undefined reference to `_d_array_slice_copy'
/usr/bin/ld: 
trivia.d:(.text._D6dparse6trivia__T22MultiLineCommentHelperHTyaZQBd16processFirstLineMFNaNbNiNfZv+0x13c): undefined reference to `_D3std5ascii7isWhiteFNaNbNiNfwZb'
/usr/bin/ld: 
trivia.d:(.text._D6dparse6trivia__T22MultiLineCommentHelperHTyaZQBd16processFirstLineMFNaNbNiNfZv+0x16d): undefined reference to `_d_arraybounds_index'
/usr/bin/ld: 
trivia.d:(.text._D6dparse6trivia__T22MultiLineCommentHelperHTyaZQBd16processFirstLineMFNaNbNiNfZv+0x186): undefined reference to `_d_arraybounds_index'
/usr/bin/ld: 
trivia.d:(.text._D6dparse6trivia__T22MultiLineCommentHelperHTyaZQBd16processFirstLineMFNaNbNiNfZv+0x1a1): undefined reference to `_d_arraybounds_index'
/usr/bin/ld: 
trivia.d:(.text._D6dparse6trivia__T22MultiLineCommentHelperHTyaZQBd16processFirstLineMFNaNbNiNfZv+0x1bc): undefined reference to `_d_arraybounds_index'
/usr/bin/ld: 
trivia.d:(.text._D6dparse6trivia__T22MultiLineCommentHelperHTyaZQBd16processFirstLineMFNaNbNiNfZv+0x1da): undefined reference to `_d_arraybounds_slice'
/usr/bin/ld: 
trivia.d:(.text._D6dparse6trivia__T22MultiLineCommentHelperHTyaZQBd16processFirstLineMFNaNbNiNfZv+0x1f5): undefined reference to `_d_arraybounds_index'
/usr/bin/ld: 
trivia.d:(.text._D6dparse6trivia__T22MultiLineCommentHelperHTyaZQBd16processFirstLineMFNaNbNiNfZv+0x20b): undefined reference to `_d_arraybounds_index'
/usr/bin/ld: server/dls/libdcd.a(dparse.trivia.o): in function 
`_D6dparse6trivia__T22MultiLineCommentHelperHTyaZQBd15processLastLineMFNaNbNiNfZv':

trivia.d:(.text._D6dparse6trivia__T22MultiLineCommentHelperHTyaZQBd15processLastLineMFNaNbNiNfZv+0xc7):
 undefined reference to `_d_arraybounds_index'
/usr/bin/ld: 
trivia.d:(.text._D6dparse6trivia__T22MultiLineCommentHelperHTyaZQBd15processLastLineMFNaNbNiNfZv+0xe0): undefined reference to `_d_arraybounds_index'
/usr/bin/ld: 
trivia.d:(.text._D6dparse6trivia__T22MultiLineCommentHelperHTyaZQBd15processLastLineMFNaNbNiNfZv+0xfc): undefined reference to `_d_arraybounds_slice'
/usr/bin/ld: server/dls/libdcd.a(dparse.trivia.o): in function 
`_D6dparse6trivia__T22MultiLineCommentHelperHTyaZQBd10unDecorateMFNaNbNiNfZv':

trivia.d:(.text._D6dparse6trivia__T22MultiLineCommentHelperHTyaZQBd10unDecorateMFNaNbNiNfZv+0x1d4):

Re: How to build a statically linked executable, before i loose my mind

2024-07-13 Thread Richard (Rikki) Andrew Cattermole via Digitalmars-d-learn

On 14/07/2024 2:53 AM, ryuukk_ wrote:

First of all, i build with `ldmd2`

Second of all, i do not use DUB

Lastly, it fails with:


```
ldmd2 -L-static  ...
```

```
/usr/bin/ld: cannot find -lphobos2-ldc-shared: No such file or directory
/usr/bin/ld: cannot find -ldruntime-ldc-shared: No such file or directory
```


Why does it complain about SHARED when passing STATIC?


Doesn't look like the switch does what you are thinking it does.

```
-static
On systems that support dynamic linking, this overrides -pie and 
prevents linking with the shared libraries. On other systems, this 
option has no effect.

```

https://gcc.gnu.org/onlinedocs/gcc/Link-Options.html

Preventing linking against, and swapping two different binaries to link 
against are different things.


Specifying to link against the shared libraries for druntime + phobos is 
done by the compiler, not the linker.


You might want to try ``--link-defaultlib-shared=false`` instead.


Re: How to build a statically linked executable, before i loose my mind

2024-07-13 Thread Sergey via Digitalmars-d-learn

On Saturday, 13 July 2024 at 14:53:41 UTC, ryuukk_ wrote:

Why does it complain about SHARED when passing STATIC?


It depends on the OS and if Linux - distribution.


Re: Recommendations on porting Python to D

2024-07-12 Thread Imperatorn via Digitalmars-d-learn

On Wednesday, 24 April 2024 at 19:50:45 UTC, Chris Piker wrote:
I can just call my old C code from D, but the old Python is 
another story.


Thanks for any advice you may have,


You could also try some AI solution


Re: Recommendations on porting Python to D

2024-07-12 Thread mw via Digitalmars-d-learn

On Friday, 12 July 2024 at 18:07:50 UTC, mw wrote:

On Friday, 3 May 2024 at 17:38:10 UTC, Chris Piker wrote:

...


Hi,

I have made basic py2many.pyd work at language/syntax level in 
my dlang fork:


https://github.com/mw66/py2many/tree/dlang

The following examples works now:

https://github.com/mw66/py2many/tree/dlang/tests/expected

py2many/ 13:56:23$ ls ./tests/expected/*.d
./tests/expected/bubble_sort.d
./tests/expected/cls.d
./tests/expected/fib.d
./tests/expected/import_tests.d
./tests/expected/classes.d
./tests/expected/dict.d
./tests/expected/hello_world.d
./tests/expected/nested_dict.d


I haven't created PR to be merged into the main branch, since 
it's better to pass all the tests.


All the remaining work is to make Python's specific feature 
(e.g. async), library (e.g. complex number, NamedTemporaryFile) 
work in D. There are many things need to be done, if you have 
time, you can pick up from my fork, and work from there. (E.g. 
you can create PR to my branch, and when everything is ready, 
we submit to the main py2many all together).



HTH.



Please use this Makefile for local setup and run tests:

https://github.com/mw66/py2many/blob/dlang/Makefile




Re: Recommendations on porting Python to D

2024-07-12 Thread mw via Digitalmars-d-learn

On Friday, 3 May 2024 at 17:38:10 UTC, Chris Piker wrote:

On Thursday, 25 April 2024 at 16:57:53 UTC, mw wrote:

On Wednesday, 24 April 2024 at 22:07:41 UTC, Chris Piker wrote:


Python-AST to D source converter may already exist?


https://github.com/joortcom/eiffel_rename/tree/main/yi

A rudimentary converter from (extended) Python to D. Maybe you 
can use it as a starting point.


Thanks for the suggestions.  I put the question aside for a 
bit, but yesterday ran across a python transpiler here:


  https://github.com/py2many/py2many

It already has support for C++, Go and others.  Since I have 
mountains of python code created over many years, maybe it 
would be worth contributing to this project out of self 
interest.


Can you take a look at py2many and see what you think about it? 
 Getting D on the support list might be good.


Hi,

I have made basic py2many.pyd work at language/syntax level in my 
dlang fork:


https://github.com/mw66/py2many/tree/dlang

The following examples works now:

https://github.com/mw66/py2many/tree/dlang/tests/expected

py2many/ 13:56:23$ ls ./tests/expected/*.d
./tests/expected/bubble_sort.d
./tests/expected/cls.d
./tests/expected/fib.d
./tests/expected/import_tests.d
./tests/expected/classes.d
./tests/expected/dict.d
./tests/expected/hello_world.d
./tests/expected/nested_dict.d


I haven't created PR to be merged into the main branch, since 
it's better to pass all the tests.


All the remaining work is to make Python's specific feature (e.g. 
async), library (e.g. complex number, NamedTemporaryFile) work in 
D. There are many things need to be done, if you have time, you 
can pick up from my fork, and work from there. (E.g. you can 
create PR to my branch, and when everything is ready, we submit 
to the main py2many all together).



HTH.



Re: Being reading a lot about betterC, but still have some questions

2024-07-10 Thread kiboshimo via Digitalmars-d-learn

On Wednesday, 10 July 2024 at 08:26:56 UTC, kiboshimo wrote:
It would take sometime for me to figure how to print to 
javascript console from a generated .html file from emscripten, 
this is a small update so nobody gets too caught up that quote.


Got it printing quicker than I thought (node and browser with 
localhost). So stdio works. Any reason why other libraries 
wouldn't?


Just archiving this progress here for anyone reading, but won't 
pollute the forum further if this thread dies out. I'm very 
grateful for the help, would have lost a lot of time without the 
reference frame you guys gave me :)


Re: Being reading a lot about betterC, but still have some questions

2024-07-10 Thread kiboshimo via Digitalmars-d-learn

On Wednesday, 10 July 2024 at 01:48:54 UTC, kiboshimo wrote:
- I though one could write an application with -betterC for 
WASM, because LDC can target it, then could build it linking to 
C libraries that already work on WASM and run the resulting 
build on the browser. That would avoid the JS-WASM bondary 
since everything would be WASM and I would not need to write my 
own abstractions.
// I'm guessing one can't simply do that, and the toolchain 
that compiles to WASM is not so flexible/similar to compiling a 
normal binary. Maybe WASM does not have support for dynamic 
linking, for example.


I was able to generate a .wasm file from hello_world.d (main) and 
hello_lib.c using LDC for compilation to bytecode, then to 
webassembly with emscripten. So, in theory it works, just 
couldn't test it yet since I'm learning Web APIs and nodejs.


It would take sometime for me to figure how to print to 
javascript console from a generated .html file from emscripten, 
this is a small update so nobody gets too caught up that quote.





Re: Being reading a lot about betterC, but still have some questions

2024-07-09 Thread kiboshimo via Digitalmars-d-learn

On Tuesday, 9 July 2024 at 20:24:14 UTC, H. S. Teoh wrote:
What are you planning to run your wasm on?  If in the browser, 
you could just use the browser's JS math functions.  The 
performance won't be stellar (the wasm-JS boundary is SLOW), 
but it'd work and you wouldn't have to write your own math 
functions.  This is what I use in my own D/wasm project.  (It'd 
probably still beat any hand-written WASM reimplementation of 
math functions that you write.  Remember, wasm is interpreted, 
so it won't beat the browser's built-in native math functions, 
which in all likelihood use the CPU's hardware math 
instructions.)


This cleared up some fundamental misunderstandings I had, thank 
you. I want to use raylib and betterC to build a small game that 
runs on the browser. For motivation I though Wasm had many 
advantages over Js, but now I don't know if that is necessarily 
the case.


If you're planning to run your wasm in a native environment, 
you could probably just use the C API to interface with the 
host system's C library functions.


That covers native use-case. In the browser I can compile my 
programs to .js using emscripten/dscripten or I can just use JS 
API from WASM (but that is slow).


I though emscripten could target WASM directly, without 
conversion to .js first. And, since it supports C, I'm assuming 
they re-implemented C API to the OS on WASM, without the need for 
calling JS API or WASI. (that might not serve me still, see 
bellow)


I feel some fundamental misunderstanding remain, but now I have 
more material to research on my own, so feel free to ignore this 
if it is "too wrong".


- I though one could write an application with -betterC for WASM, 
because LDC can target it, then could build it linking to C 
libraries that already work on WASM and run the resulting build 
on the browser. That would avoid the JS-WASM bondary since 
everything would be WASM and I would not need to write my own 
abstractions.
// I'm guessing one can't simply do that, and the toolchain that 
compiles to WASM is not so flexible/similar to compiling a normal 
binary. Maybe WASM does not have support for dynamic linking, for 
example.


- Is WASI relevant to the browser context? Or just to native 
apps? I though WASI API could be used on the browser, but 
comments and blogs about it often bring up the native context 
only.


I tried to reply everyone here, since I think most answers 
converge. Thank you all for your help :)


Re: Being reading a lot about betterC, but still have some questions

2024-07-09 Thread Richard (Rikki) Andrew Cattermole via Digitalmars-d-learn

On 09/07/2024 9:58 PM, kiboshimo wrote:
On Tuesday, 9 July 2024 at 09:30:18 UTC, Richard (Rikki) Andrew 
Cattermole wrote:

Threads are indeed gone.


Oh no.

If you want them, you'll have to call out to the system API and do 
your own thing.


I hope "doing my own thing here" could be linking to a C library that 
interacts with the OS on my behalf.


If you don't need to interact with an existing thread abstraction such 
as druntime, working with pthreads or Windows threading abstraction 
isn't an issue.


These API's are pretty easy to interact with, I've got my own -betterC 
threading abstraction (I have good reasons not to recommend it here).



I cannot comment about web assembly since I haven't done
anything there, but some people have so hopefully they'll
comment about where to go from here.


Some of them might know. And if they know, them I will know. And if I 
know, then, you know...


Oh I've seen them do stuff with it, its just not something I've wanted 
to learn, I have a lot of other stuff before it.


Re: Being reading a lot about betterC, but still have some questions

2024-07-09 Thread monkyyy via Digitalmars-d-learn

On Tuesday, 9 July 2024 at 20:03:15 UTC, kiboshimo wrote:

On Tuesday, 9 July 2024 at 14:42:01 UTC, monkyyy wrote:

On Tuesday, 9 July 2024 at 07:54:12 UTC, kiboshimo wrote:
- betterC can be compiled to WASM, but some of phobos can't, 
so basically same worries as above. I'm afraid to lose some 
essential systems stuff that I could not replace.


yes, and your not afraid enough

Really liked the idea of doing it with betterC to start my 
systems programming journey


Theres nothing even slightly pleasant or easy about d's wasm 
"support"; I wrote my own cos, sqrt functions, you get 
*nothing* from phoboes


Writing my own math functions is outside of my range, I still 
have hopes of this not being so hard. So you get another 
opportunity to crush it.


Honestly porting isqrt is easier then trying to get a half baked 
file io to work


but it is *everything* is gone and thats probaly overwhelming 
unless your prepared for it.




You could have used a C library for those things you 
implemented yourself, right? I suppose you didn't because doing 
things is cool, or because C is "not ergonomic" to use as 
foreign code. Because of the quirks. Which would make for a not 
so pleasant experience when writing a small game.


What do you think about using C libraries like that?


wasm *in general* breaks libc's fileio "for safety" (arguably the 
most important part of libc, morons), d's wasm libc in even more 
broken due to it coming out of no where and there being like 3 
guys doing 20 ours of work on the "runtime" or something(ignore 
ppl who say d supports 7 platforms, it supports 2).


While it can be a trivial port, I think you better off sticking 
to the raylib api as your ground layer as whatever work there 
seems to carry over.


Re: Being reading a lot about betterC, but still have some questions

2024-07-09 Thread H. S. Teoh via Digitalmars-d-learn
On Tue, Jul 09, 2024 at 08:03:15PM +, kiboshimo via Digitalmars-d-learn 
wrote:
> On Tuesday, 9 July 2024 at 14:42:01 UTC, monkyyy wrote:
> > On Tuesday, 9 July 2024 at 07:54:12 UTC, kiboshimo wrote:
[...]
> > > Really liked the idea of doing it with betterC to start my systems
> > > programming journey
> > 
> > Theres nothing even slightly pleasant or easy about d's wasm
> > "support"; I wrote my own cos, sqrt functions, you get *nothing*
> > from phoboes
> 
> Writing my own math functions is outside of my range, I still have
> hopes of this not being so hard. So you get another opportunity to
> crush it.
[...]

What are you planning to run your wasm on?  If in the browser, you could
just use the browser's JS math functions.  The performance won't be
stellar (the wasm-JS boundary is SLOW), but it'd work and you wouldn't
have to write your own math functions.  This is what I use in my own
D/wasm project.  (It'd probably still beat any hand-written WASM
reimplementation of math functions that you write.  Remember, wasm is
interpreted, so it won't beat the browser's built-in native math
functions, which in all likelihood use the CPU's hardware math
instructions.)

If you're planning to run your wasm in a native environment, you could
probably just use the C API to interface with the host system's C
library functions.

Don't reinvent the square wheel unless you're planning to ride it on an
inverted catenary road. :-P

//

On a larger note, if you're planning to write something small that runs
in a browser, you might be interested to check out:

https://github.com/Ace17/dscripten

This is the D equivalent of emscripten. While it's nowhere near the
maturity of emscripten itself, it may be Good Enough(tm) for your use.
Rather than wrangling with the WASM/JS API (it's still early stage,
there are a LOT of bumps currently still in the road), just let LLVM
convert your D code straight into JS and run it as JS in the browser.
Then you can leverage all the existing JS APIs your browser already
supports, instead of having to reinvent yet another square wheel.


T

-- 
Some days you win; most days you lose.


Re: Being reading a lot about betterC, but still have some questions

2024-07-09 Thread kiboshimo via Digitalmars-d-learn

On Tuesday, 9 July 2024 at 14:42:01 UTC, monkyyy wrote:

On Tuesday, 9 July 2024 at 07:54:12 UTC, kiboshimo wrote:
- betterC can be compiled to WASM, but some of phobos can't, 
so basically same worries as above. I'm afraid to lose some 
essential systems stuff that I could not replace.


yes, and your not afraid enough

Really liked the idea of doing it with betterC to start my 
systems programming journey


Theres nothing even slightly pleasant or easy about d's wasm 
"support"; I wrote my own cos, sqrt functions, you get 
*nothing* from phoboes


Writing my own math functions is outside of my range, I still 
have hopes of this not being so hard. So you get another 
opportunity to crush it.


You could have used a C library for those things you implemented 
yourself, right? I suppose you didn't because doing things is 
cool, or because C is "not ergonomic" to use as foreign code. 
Because of the quirks. Which would make for a not so pleasant 
experience when writing a small game.


What do you think about using C libraries like that?



Re: Being reading a lot about betterC, but still have some questions

2024-07-09 Thread kiboshimo via Digitalmars-d-learn

On Tuesday, 9 July 2024 at 14:38:34 UTC, Lance Bachmeier wrote:
If you haven't done so, I'd recommend reading the blog posts 
from Walter to get an understanding of why BetterC was 
introduced and how to use it: 
https://dlang.org/blog/category/betterc/


- betterC does not need glue code to interop with C. Does it 
achieve this by "gluing" behind the scenes? I've read in a 
comment somewhere that the ABI is the same, but idk people say 
lots of things.


You're declaring your D code extern(C), as you can see in 
Walter's blog posts, so yes, you're using the C ABI.


The blog post contextualizes evilrat's comment too. It facilities 
code migration because conversion is also easier (given adequate 
attention to C's quirks). After that you can start using D 
features on top of converted code. That won't help much on my 
Wasm use case, but it might, now that I know more about the ABI 
thing.


Thank you.



Re: Being reading a lot about betterC, but still have some questions

2024-07-09 Thread monkyyy via Digitalmars-d-learn

On Tuesday, 9 July 2024 at 07:54:12 UTC, kiboshimo wrote:

I'm going to try a project with raylib and WASM.


use mine

https://github.com/crazymonkyyy/raylib-2024/blob/master/docs/examplecode.md

- betterC can be compiled to WASM, but some of phobos can't, so 
basically same worries as above. I'm afraid to lose some 
essential systems stuff that I could not replace.


yes, and your not afraid enough

Really liked the idea of doing it with betterC to start my 
systems programming journey


Theres nothing even slightly pleasant or easy about d's wasm 
"support"; I wrote my own cos, sqrt functions, you get *nothing* 
from phoboes


  1   2   3   4   5   6   7   8   9   10   >