Re: Program crash: GC destroys an object unexpectedly

2021-09-13 Thread Tejas via Digitalmars-d-learn
On Monday, 13 September 2021 at 18:42:47 UTC, Steven 
Schveighoffer wrote:

On 9/13/21 1:54 PM, eugene wrote:

[...]


The GC only scans things that it knows about.

Inside your EventQueue you have this code:

[...]


Umm is it okay that he declared variables `init` and `idle` of 
type `Stage` inside the constructor? Maybe that has something to 
do with this? Also, calling a variable `init` could be 
problematic since the compiler assigns a property of the same 
name to every single type?


Re: Development of the foundation of a programming language

2021-09-13 Thread Elronnd via Digitalmars-d-learn

On Tuesday, 14 September 2021 at 03:24:45 UTC, max haughton wrote:

On Tuesday, 14 September 2021 at 03:19:46 UTC, Elronnd wrote:
On Monday, 13 September 2021 at 11:40:10 UTC, max haughton 
wrote:

The dragon book barely mentions SSA for example


In fairness, dmd doesn't use SSA either


That's not a good thing.


No, but if the OP's goal is to contribute to dmd, learning SSA 
wouldn't be very helpful beyond a general acclimation to compiler 
arcana.


(Unless they wish to add SSA to dmd--a worthy goal, but perhaps 
not the best thing to start out with.)


Re: object.d: Error: module object is in file 'object.d' which cannot be read

2021-09-13 Thread max haughton via Digitalmars-d-learn
On Tuesday, 14 September 2021 at 03:31:17 UTC, Kenneth Dallmann 
wrote:

On Sunday, 27 March 2011 at 10:28:00 UTC, Ishan Thilina wrote:

[...]





I had the exact same problem, very frustrating.  I believe I 
solved the issue,

it was a simple error.

  When you are installing D, on Windows, it asks you to 
download MSVC, if it isn't

already present.

 Basically you are missing some form of dependency, which could 
be different based

on which compiler you are using.

  On my Windows machine I fixed the issue by downloading the 
Microsoft Visual IDE and then
from there I hit a button within that application to download 
the C compiler, MSVC.


After I did that I reinstalled D and it works now.

Thank you


Please try to avoid resurrecting very old threads if you can.


Re: object.d: Error: module object is in file 'object.d' which cannot be read

2021-09-13 Thread Kenneth Dallmann via Digitalmars-d-learn

On Sunday, 27 March 2011 at 10:28:00 UTC, Ishan Thilina wrote:
When I give "dmd untitled.d" command in my ubuntu maverick 64 
bit laptop I get the following error.


"
object.d: Error: module object is in file 'object.d' which 
cannot be read

import path[0] = /etc/../../src/phobos
import path[1] = /etc/../../src/druntime/import
"






I had the exact same problem, very frustrating.  I believe I 
solved the issue,

it was a simple error.

  When you are installing D, on Windows, it asks you to download 
MSVC, if it isn't

already present.

 Basically you are missing some form of dependency, which could 
be different based

on which compiler you are using.

  On my Windows machine I fixed the issue by downloading the 
Microsoft Visual IDE and then
from there I hit a button within that application to download the 
C compiler, MSVC.


After I did that I reinstalled D and it works now.

Thank you


Re: Development of the foundation of a programming language

2021-09-13 Thread max haughton via Digitalmars-d-learn

On Tuesday, 14 September 2021 at 03:19:46 UTC, Elronnd wrote:
On Monday, 13 September 2021 at 11:40:10 UTC, max haughton 
wrote:

The dragon book barely mentions SSA for example


In fairness, dmd doesn't use SSA either


That's not a good thing.


Re: Development of the foundation of a programming language

2021-09-13 Thread Elronnd via Digitalmars-d-learn

On Monday, 13 September 2021 at 11:40:10 UTC, max haughton wrote:

The dragon book barely mentions SSA for example


In fairness, dmd doesn't use SSA either


Recommendations on parsing XML via an InputRange

2021-09-13 Thread Chris Piker via Digitalmars-d-learn

Hi D

I just finished a ~1K line project using `dxml` as the XML reader 
for my data streams.  It works well in my test examples using 
memory mapped files, but like an impulse shopper I didn't notice 
that dxml requires `ForwardRange` objects.  That's unfortunate, 
because my next enhancement was to start parsing streams as they 
come in from stdin. (doh!)


So I've learned my lesson and will RTFM closer next time, but now 
I'm casting about for a solution.  Two ideas, either:


1. Find a different StAX-ish parser that works with `InputRange` 
(and buffers internally a bit if needed), or


2. Find a way to represent standard input as a ForwardRange 
without saving the whole stream in memory. (iopipe?)


Dxml is very nice, as I have small sections of the stream that I 
parse into a DOM, but the majority of the items are handled and 
discarded element by element.


Any recommendations?




Re: Development of the foundation of a programming language

2021-09-13 Thread leikang via Digitalmars-d-learn

On Monday, 13 September 2021 at 10:23:14 UTC, Dennis wrote:

On Monday, 13 September 2021 at 03:21:37 UTC, leikang wrote:
Are there any recommended books or videos to learn about the 
principles of compilation? What else should I learn besides 
the principles of compilation?


Check out this video: [DConf 2016 Day 2 Keynote: Spelunking D 
Compiler Internals -- Walter 
Bright](https://www.youtube.com/watch?v=bNJhtKPugSQ)
Just browsing [dmd's source 
code](https://github.com/dlang/dmd/tree/master/src/dmd#readme) 
and watching [dmd's Pull Request 
queue](https://github.com/dlang/dmd/pulls) is a good way to get 
familiar with the code and see what a bug fix looks like. Try 
to start with something small, like error message improvements 
or [refactorings listed in the contributing 
guide](https://github.com/dlang/dmd/blob/master/CONTRIBUTING.md#dmd-best-practices). If you have any questions along the way, just ask them.


Thanks!


Re: Program crash: GC destroys an object unexpectedly

2021-09-13 Thread eugene via Digitalmars-d-learn

On Monday, 13 September 2021 at 18:45:22 UTC, jfondren wrote:
Instead of using a temporary EpollEvent array in 
EventQueue.wait, you could make the array an instance variable 
and have registerEventSource populate it directly


Actually, initial version of all that was using array,
allocated in constructor, but then (when struggling with GC)
I thought that array in stack will press GC less...

... It seems I said something stupid just now )




Re: Program crash: GC destroys an object unexpectedly

2021-09-13 Thread eugene via Digitalmars-d-learn
On Monday, 13 September 2021 at 18:42:47 UTC, Steven 
Schveighoffer wrote:

And you are registering your signals using the `+=` operator.


That was a sort of exercise with operator overloading.

Now, with your stopper code that you showed, it looks like you 
are storing the reference to stopper right on the main stack 
frame. This *should* prevent those from being destroyed, since 
Stopper has a reference to both signals.


Exactly - this is the main point of my confusion.
On my expectation, GC should not mark those as unreferenced.

Also, notice those dynamic arrays

void main(string[] args) {
RxSm[] rxMachines;
auto rxPool = new RestRoom();
foreach (k; 0 .. nConnections) {
auto sm = new RxSm(rxPool);
rxMachines ~= sm;
sm.run();
}

rxMachines (and alike) are not needed by the prog itself,
they are just to keep references for GC.




Re: Program crash: GC destroys an object unexpectedly

2021-09-13 Thread jfondren via Digitalmars-d-learn

On Monday, 13 September 2021 at 17:18:30 UTC, eugene wrote:
Then after pressing ^C (SIGINT) the program gets SIGSEGV, since 
references to sg0 and sg1 are no longer valid (they are 
"sitting" in epoll_event structure).


engine/ecap.d(54): Error: field `EpollEvent.es` cannot assign to 
misaligned pointers in `@safe` code
engine/ecap.d(56): Error: cannot take address of local `e` in 
`@safe` function `registerEventSource`


from adding @safe to ecap.EventQueue.registerEventSource, and 
then from using a @trusted block to silence the first complaint.


Instead of using a temporary EpollEvent array in EventQueue.wait, 
you could make the array an instance variable and have 
registerEventSource populate it directly, so that the GC can 
always trace from this array to an EnventSource.


... however, I don't think this fixes your problem, or is your 
only problem, since the segfault's still observed when this 
memory is leaked:


```d
void registerEventSource(EventSource es) {
import core.memory : pureMalloc, GC;

auto p = cast(EpollEvent*) pureMalloc(EpollEvent.sizeof);
p.event_mask = 0;
p.es = es;
GC.addRoot(p);
int r = epoll_ctl(id, EPOLL_CTL_ADD, es.id, p);
assert(r == 0, "epoll_ctl(ADD) failed");
}
```


Re: Program crash: GC destroys an object unexpectedly

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

On 9/13/21 1:54 PM, eugene wrote:

On Monday, 13 September 2021 at 17:40:41 UTC, user1234 wrote:
The problems seems to lies in `newSignal()` which "would" not allocate 
using the GC.


     final Signal newSignal(int signum) {
     Signal sg = new Signal(signum);
     sg.owner = this;
     sg.number = sg_number++;
     sg.register();
     return sg;
     }

full src is here
http://zed.karelia.ru/0/e/edsm-in-d-2021-09-10.tar.gz



The GC only scans things that it knows about.

Inside your EventQueue you have this code:

```d
void registerEventSource(EventSource es) {
auto e = EpollEvent(0, es);
int r = epoll_ctl(id, EPOLL_CTL_ADD, es.id, );
assert(r == 0, "epoll_ctl(ADD) failed");
}

EventQueue opOpAssign(string op)(EventSource es)
if (("+" == op) || ("~" == op)) {
registerEventSource(es);
return this;
}

void deregisterEventSource(EventSource es) {
auto e = EpollEvent(0, es);
int r = epoll_ctl(id, EPOLL_CTL_DEL, es.id, );
assert(r == 0, "epoll_ctl(DEL) failed");
}

EventQueue opOpAssign(string op)(EventSource es)
if ("-" == op) {
deregisterEventSource(es);
return this;
}
```

And you are registering your signals using the `+=` operator.

What is happening here, is, `epoll_ctl` is adding your event source to a 
*C allocated* structure (namely the epoll struct, allocated by 
`epoll_create1`, and possibly even managed by the OS). The GC does not 
have access to this struct, so if that's the only reference to them, 
they will get cleaned up by the GC.


Now, with your stopper code that you showed, it looks like you are 
storing the reference to stopper right on the main stack frame. This 
*should* prevent those from being destroyed, since Stopper has a 
reference to both signals.


But I would recommend using `core.memory.GC.addRoot` on your EventSource 
when registering it with epoll, and using `core.memory.GC.removeRoot` 
when unregistering. That will ensure they do not get cleaned up before 
being unregistered. If this doesn't fix the problem, perhaps there is 
some other issue happening.


-Steve


Re: Which operators cannot be overloaded and why not?

2021-09-13 Thread NonNull via Digitalmars-d-learn

On Monday, 13 September 2021 at 16:12:34 UTC, H. S. Teoh wrote:
On Mon, Sep 13, 2021 at 02:12:36PM +, NonNull via 
Digitalmars-d-learn wrote:

Which operators cannot be overloaded and why not?


Others have already given the list, so I won't repeat that.


I didn't see unary &. Maybe others are missing.


As to the "why":

In general, D tries to avoid the wild wild west, every operator 
for himself situation in C++ that leads to unreadable, 
unmaintainable code.


Thanks for this explanation. The consolidation you mention is 
great!





Re: Which operators cannot be overloaded and why not?

2021-09-13 Thread user1234 via Digitalmars-d-learn

On Monday, 13 September 2021 at 18:06:42 UTC, NonNull wrote:

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

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

- condition al expression ` cond ? exp : exp `


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

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


Is there no list of such in an article online? It would be good 
if that work was done for once and for all, with a short 
explanation in each case, possibly with discussion in some 
cases of how to achieve results by other means.


well this whole thread is certainly the raw material for an 
article (or D blog post) on D operator overloads. Just, someone 
has to compile the informations and write the said article.


Re: Program crash: GC destroys an object unexpectedly

2021-09-13 Thread eugene via Digitalmars-d-learn

On Monday, 13 September 2021 at 17:56:34 UTC, user1234 wrote:
thx, so the problem is not what I suspected to be (mixed 
gc-managed and manually managed memory). sorrry...


I am actually C coder and do not have much experience
with GC languages, so I did not even attempt to
try use D without GC yet, just want to understand
how all that GC magic works.

The programs does not contain manual malloc()/free(),
I am just not ready for such mix.




Re: Which operators cannot be overloaded and why not?

2021-09-13 Thread NonNull via Digitalmars-d-learn

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

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

- condition al expression ` cond ? exp : exp `


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

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


Is there no list of such in an article online? It would be good 
if that work was done for once and for all, with a short 
explanation in each case, possibly with discussion in some cases 
of how to achieve results by other means.




Re: Program crash: GC destroys an object unexpectedly

2021-09-13 Thread eugene via Digitalmars-d-learn

On Monday, 13 September 2021 at 17:18:30 UTC, eugene wrote:

And the most strange thing is this


It is echo-server/echo-client pair.
And it is echo-client that crashes upon SIGINT.

echo-server contains very similar code

class Listener : StageMachine {

enum ulong M0_WORK = 0;
enum ulong M1_WORK = 1;
enum ulong M0_GONE = 0;

RestRoom workerPool;
ushort port;
TCPListener reception;
Signal sg0, sg1;

this(RestRoom wPool, ushort port = ) {
super("LISTENER");
workerPool = wPool;
this.port = port;

Stage init, work;
init = addStage("INIT", );
work = addStage("WORK", );

init.addReflex("M0", work);

work.addReflex("L0", );
work.addReflex("M0", );
work.addReflex("S0", );
work.addReflex("S1", );
}

void listenerInitEnter() {
reception = newTCPListener(port);
sg0 = newSignal(Signal.sigInt);
sg1 = newSignal(Signal.sigTerm);
msgTo(this, M0_WORK);
}

but it does not crashes (destruc).

The only significant difference - it has TCPListener instance, 
besides absolutely the same sg0 and sg1 'channels'.




Re: Program crash: GC destroys an object unexpectedly

2021-09-13 Thread user1234 via Digitalmars-d-learn

On Monday, 13 September 2021 at 17:54:43 UTC, eugene wrote:

On Monday, 13 September 2021 at 17:40:41 UTC, user1234 wrote:
The problems seems to lies in `newSignal()` which "would" not 
allocate using the GC.


final Signal newSignal(int signum) {
Signal sg = new Signal(signum);
sg.owner = this;
sg.number = sg_number++;
sg.register();
return sg;
}

full src is here
http://zed.karelia.ru/0/e/edsm-in-d-2021-09-10.tar.gz


thx, so the problem is not what I suspected to be (mixed 
gc-managed and manually managed memory). sorrry...


Re: Program crash: GC destroys an object unexpectedly

2021-09-13 Thread eugene via Digitalmars-d-learn

On Monday, 13 September 2021 at 17:40:41 UTC, user1234 wrote:
The problems seems to lies in `newSignal()` which "would" not 
allocate using the GC.


final Signal newSignal(int signum) {
Signal sg = new Signal(signum);
sg.owner = this;
sg.number = sg_number++;
sg.register();
return sg;
}

full src is here
http://zed.karelia.ru/0/e/edsm-in-d-2021-09-10.tar.gz



Re: Program crash: GC destroys an object unexpectedly

2021-09-13 Thread user1234 via Digitalmars-d-learn

On Monday, 13 September 2021 at 17:18:30 UTC, eugene wrote:

[...]


At first glance and given the fact that some code necessary to 
diagnose the problem accurately is missing:


`new Stopper` allocates using the GC. it's then a "GC range", 
it's content will be scanned and handled by the GC, including 
`sg0` and `sg1`.


So far everything is simple.

The problems seems to lies in `newSignal()` which "would" not 
allocate using the GC. So when the GC reaches `sg0` and `sg1` 
values, indirectly when scanning a `Stopper` instance, it thinks 
that these they are unused and, consequently, free them.


If you dont want them to be managed by the GC remove them from 
the GC, using `removeRange()`.


Re: Program crash: GC destroys an object unexpectedly

2021-09-13 Thread user1234 via Digitalmars-d-learn

On Monday, 13 September 2021 at 17:40:41 UTC, user1234 wrote:

On Monday, 13 September 2021 at 17:18:30 UTC, eugene wrote:

[...]


At first glance and given the fact that some code necessary to 
diagnose the problem accurately is missing:


`new Stopper` allocates using the GC. it's then a "GC range", 
it's content will be scanned and handled by the GC, including 
`sg0` and `sg1`.


So far everything is simple.

The problems seems to lies in `newSignal()` which "would" not 
allocate using the GC. So when the GC reaches `sg0` and `sg1` 
values, indirectly when scanning a `Stopper` instance, it 
thinks that these they are unused and, consequently, free them.


If you dont want them to be managed by the GC remove them from 
the GC, using `removeRange()`.


of sorry, or maybe the opposite, so addRange...


Program crash: GC destroys an object unexpectedly

2021-09-13 Thread eugene via Digitalmars-d-learn

Code snippets

```d
class Stopper : StageMachine {

enum ulong M0_IDLE = 0;
Signal sg0, sg1;

this() {
super("STOPPER");

Stage init, idle;
init = addStage("INIT", );
idle = addStage("IDLE", );

init.addReflex("M0", idle);

idle.addReflex("S0", );
idle.addReflex("S1", );
}

void stopperInitEnter() {
sg0 = newSignal(Signal.sigInt);
sg1 = newSignal(Signal.sigTerm);
msgTo(this, M0_IDLE);
}
```

The instance of Stopper is created in the scope of main():

```d
void main(string[] args) {

auto stopper = new Stopper();
stopper.run();
```

stopperInitEnter(), where sg0 and sg1 are created, is invoked 
inside run() method.


After ~6 seconds from the start (dummy) destructors of sg0 and 
sg1 are called:


   !!! esrc.EventSource.~this() : esrc.Signal (owner STOPPER, fd 
= 24) this @ 0x7fa5410d4f60
   !!! esrc.EventSource.~this() : esrc.Signal (owner STOPPER, fd 
= 25) this @ 0x7fa5410d4f90


Then after pressing ^C (SIGINT) the program gets SIGSEGV, since 
references to sg0 and sg1 are no longer valid (they are "sitting" 
in epoll_event structure).


First I thought I am stupid and I do not see some obvious 
mistake, but...
That crash happens if the program was compiled with dmd 
(v2.097.2).
When using gdc (as well as ldc, both from Debian 8 official 
repo), I do not observe no crashes - program may run for hours 
and after interrupting by ^C it terminates as expected.


And the most strange thing is this - if using gdc with -Os flag, 
the program behaves
exactly as when compiled with fresh dmd - destructors for sg0 and 
sg1 are called soon

after program start.

I do not understand at all why GC considers those sg0 and sg1 as 
unreferenced.

And why old gdc (without -Os) and old ldc do not.



Re: Which operators cannot be overloaded and why not?

2021-09-13 Thread H. S. Teoh via Digitalmars-d-learn
On Mon, Sep 13, 2021 at 02:12:36PM +, NonNull via Digitalmars-d-learn wrote:
> Which operators cannot be overloaded and why not?

Others have already given the list, so I won't repeat that. As to the
"why":

In general, D tries to avoid the wild wild west, every operator for
himself situation in C++ that leads to unreadable, unmaintainable code.

For example, C++ allows you to separately overload <, <=, ==, >, >=, !=.
That means the programmer is free to define == and != in a way
completely inconsistent with each other, for example.  D solves this by
combining == and != into a single operator overload, opEquals, where !=
is the negation of ==. This ensures == and != are always consistent with
each other.  Same with <, <=, >, >=: C++ lets you overload each one
separately, potentially in a completely inconsistent way with each
other, so that somebody reading your code has no idea whether x < y
implies y >= x, or whether x < y implies y > x. Again, unreadable code.
D solves this by combining all these operators into a single overload:
opCmp.  This ensures consistency between all of these relative
comparison operators.

Similarly, prefix ++/-- and postfix ++/-- cannot be separately
overloaded; they are combined into a single overload, where postfix
++/--, as in `x++`, is simply rewritten by the compiler to the
equivalent of:

(){ auto tmp = x; x++; return tmp; }()

(Of course, this is just to illustrate the semantics. The compiler
doesn't actually create a lambda here.)

This ensures that prefix and postfix operators behave in the expected
way, so that ++x and x++ don't behave in two wildly different, unrelated
ways, like it sometimes happens in C++ code because C++ lets you define
separate overloads for them.

Combining these operator overloads have the additional benefit that less
overloads are needed to implement a numerical type: instead of needing
to separately implement ==, !=, <, <=, >, >=, you only have to implement
two overloads, opEquals and opCmp, and the compiler takes care of the
rest. Similarly, ++ and -- only need to be implement once each, and
you'll get the postfix varieties for free.

Furthermore, the boolean operators !, &&, || are not directly
overloadable. Again, C++ lets you separately overload them, which
guarantees that when you see (what looks like) a boolean expression in
C++, you have no idea what its true semantics are, because && could mean
something completely different from the usual meaning.  D doesn't let
you overload these operators, thereby ensuring that a boolean expression
remains a boolean expression: !, &&, || always have the standard
semantics.  What D *does* let you do is to define opCast!bool yourself,
so that you can define how a user-defined type converts to a bool, which
can then participate in the !, &&, || operators in the usual way.


In general, the philosophy in D is that operator overloading really
should be reserved for number-like (or math-like) objects, and
overloaded operators are expected to behave more-or-less like their
standard, non-overloaded meanings. Operator overloading of the variety
that C++ likes to do, like iostream's <<, >> overloads, are frowned
upon, because they obscure the surface meaning of the code and make it
hard to understand and maintain. (Incidentally, D *does* allow you to
overload '<<' and '>>'. It's just frowned upon to overload them in a way
that doesn't in someway represent bit-shifting.)  Furthermore,
overloaded operators are expected to behave analogously w.r.t. each
other, e.g., == and != should behave like opposites of each other; <
should not have completely unrelated semantics to >, and so on.


T

-- 
The right half of the brain controls the left half of the body. This means that 
only left-handed people are in their right mind. -- Manoj Srivastava


Re: Which operators cannot be overloaded and why not?

2021-09-13 Thread user1234 via Digitalmars-d-learn

On Monday, 13 September 2021 at 14:59:38 UTC, Paul Backus wrote:

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

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

- condition al expression ` cond ? exp : exp `


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

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


I think the intent is for the boolean operators to be handled 
via `opCast!bool`.


I didn't see it was already suggested and answered the same... 
but yet that's exactly the case.


Re: Which operators cannot be overloaded and why not?

2021-09-13 Thread user1234 via Digitalmars-d-learn

On Monday, 13 September 2021 at 15:29:05 UTC, user1234 wrote:

[...]
so this is a bit like the postincr case.


i.e "prevent the semantics to be hijacked".


Re: Which operators cannot be overloaded and why not?

2021-09-13 Thread user1234 via Digitalmars-d-learn

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

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

- condition al expression ` cond ? exp : exp `


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


They are all indirectly supported if `opCast` is overloaded:

```d
unittest
{
struct S
{
bool opCast(T = bool)(){return true;}
}
S s;
assert(s && s);
}
```

so this is a bit like the postincr case.




Re: Which operators cannot be overloaded and why not?

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

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

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

- condition al expression ` cond ? exp : exp `


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

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


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


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


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

}
```

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


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

```

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

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

anyway. zorry for this off-topic.


Re: Which operators cannot be overloaded and why not?

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

On 9/13/21 10:47 AM, user1234 wrote:

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

what else ?


when you have

```d
alias AA1 = int[int];
alias AA2 = AA1[int];
```

then you can write

```d
AA2 aa;
aa[0] = [0 : 0];
aa[0][0] = 0;
```

The `[0][0]` cannot be expressed using operator overloads (and a custom 
map type that implements opIndexAssign).But this case is rather due to 
the fact that druntime seems to do something a bit unusal here 
(according to an old discussion that happend once on irc).




This is because the compiler calls a different hook depending on the 
usage of the expression `aa[0]`. Which one it calls is not consistent.


There isn't an analog for indexing overloads.

A further example:

```d
int[int] aa;
aa[0]++; // ok
void foo(ref int x) {x++;}
foo(aa[1]); // range violation
```

-Steve


Re: Which operators cannot be overloaded and why not?

2021-09-13 Thread Paul Backus via Digitalmars-d-learn

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

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

- condition al expression ` cond ? exp : exp `


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

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


I think the intent is for the boolean operators to be handled via 
`opCast!bool`.


Re: Which operators cannot be overloaded and why not?

2021-09-13 Thread user1234 via Digitalmars-d-learn

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

what else ?


when you have

```d
alias AA1 = int[int];
alias AA2 = AA1[int];
```

then you can write

```d
AA2 aa;
aa[0] = [0 : 0];
aa[0][0] = 0;
```

The `[0][0]` cannot be expressed using operator overloads (and a 
custom map type that implements opIndexAssign).But this case is 
rather due to the fact that druntime seems to do something a bit 
unusal here (according to an old discussion that happend once on 
irc).




Re: Which operators cannot be overloaded and why not?

2021-09-13 Thread jfondren via Digitalmars-d-learn

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

- condition al expression ` cond ? exp : exp `


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

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


Re: Which operators cannot be overloaded and why not?

2021-09-13 Thread user1234 via Digitalmars-d-learn

On Monday, 13 September 2021 at 14:12:36 UTC, NonNull wrote:

Which operators cannot be overloaded and why not?


Let's start the list.

- `new` and `delete`

Because operators are overloaded in aggregates
new was supported but not anymore, the idea is
that a an aggregate should not be tied a specific allocator.

- post incr/decr

See 
[https://dlang.org/spec/operatoroverloading.html#postincrement_postdecrement_operators](explantations). This is an arbitrary limitation imho but the current way enfore that the side effect is not apllied to the expression result.


- condition al expression ` cond ? exp : exp `

No idea why it is not supported... nobody has never complained 
tho ;)


- `typeid`

Same... the result of typeid has to be a TypeInfoClass, so 
there's not much to do... exactness is expected


- `is` (identity)

could be but I suppose that this stuff needs to be correct to 
keep code consistent


what else ?


Which operators cannot be overloaded and why not?

2021-09-13 Thread NonNull via Digitalmars-d-learn

Which operators cannot be overloaded and why not?



Re: Development of the foundation of a programming language

2021-09-13 Thread Paul Backus via Digitalmars-d-learn

On Monday, 13 September 2021 at 00:53:06 UTC, leikang wrote:
I want to contribute to the development of the dlang language, 
but I feel that I am insufficient, so I want to ask the big 
guys, can I participate in the development of the Dlang 
language after learning the principles of compilation?


In addition to what others have said: there are many ways you can 
contribute to D without needing to know anything about compiler 
internals. For example, you could fix one of the many [known bugs 
in the standard library][1], or improve the documentation.


In general, there are more things that need to be done in D than 
there are people with the time to do them, so any contribution is 
valuable.


[1]: 
https://issues.dlang.org/buglist.cgi?bug_status=NEW_status=REOPENED=phobos_id=237469=---=D2


Re: Development of the foundation of a programming language

2021-09-13 Thread max haughton via Digitalmars-d-learn
On Monday, 13 September 2021 at 04:08:53 UTC, rikki cattermole 
wrote:


On 13/09/2021 3:21 PM, leikang wrote:
Are there any recommended books or videos to learn about the 
principles of compilation? What else should I learn besides 
the principles of compilation?


The classic book on compilers that Walter recommends is the 
dragon book.


https://smile.amazon.com/Compilers-Principles-Techniques-Tools-2nd-dp-0321486811/dp/0321486811

(D Language Foundation is a charity Amazon Smile recognizes).


The dragon book is really really showing it's age these days so I 
would highly recommend getting a copy but not reading it fully. 
"Engineering a compiler" is much better pedagogically. The dragon 
book barely mentions SSA for example, although the sections they 
did properly bother to update towards the end are quite 
interesting.


"Crafting interpreters" is quite good, I recommend it for 
learning how to actually write a parser without getting bogged 
down in totally useless theory.


Stephen Muchnick's "Advanced Compiler Design and Implementation" 
is *the* bible for optimizations, but uses a very weird 
unimplemented language so be careful for bugs.


"Optimizing Compilers for Modern Architectures: A 
Dependence-based Approach" is the only book I'm aware of that 
actually covers even the beginnings of modern loop optimizations 
thoroughly. Even this however is still somewhat set back by it 
being written 20 years ago, the principles are the same but the 
instinct is not i.e. memory latency is worse, ILP is much better.


What all of these books have in common, by the way, is that they 
were all written at a time when it was assumed that x86 would go 
the way of the dodo. So there is a somewhat significant deviation 
from "theory" and practice in some parts as (say) x86 SIMD is 
quite different from how the authors of the aforementioned book 
expected the world to go.


Re: Development of the foundation of a programming language

2021-09-13 Thread Dennis via Digitalmars-d-learn

On Monday, 13 September 2021 at 03:21:37 UTC, leikang wrote:
Are there any recommended books or videos to learn about the 
principles of compilation? What else should I learn besides the 
principles of compilation?


Check out this video: [DConf 2016 Day 2 Keynote: Spelunking D 
Compiler Internals -- Walter 
Bright](https://www.youtube.com/watch?v=bNJhtKPugSQ)
Just browsing [dmd's source 
code](https://github.com/dlang/dmd/tree/master/src/dmd#readme) 
and watching [dmd's Pull Request 
queue](https://github.com/dlang/dmd/pulls) is a good way to get 
familiar with the code and see what a bug fix looks like. Try to 
start with something small, like error message improvements or 
[refactorings listed in the contributing 
guide](https://github.com/dlang/dmd/blob/master/CONTRIBUTING.md#dmd-best-practices). If you have any questions along the way, just ask them.