Re: Why doesn't this piece of code work?

2022-05-16 Thread SvGaming via Digitalmars-d-learn

On Monday, 16 May 2022 at 22:25:23 UTC, kdevel wrote:

On Monday, 16 May 2022 at 16:53:15 UTC, SvGaming wrote:
[...]

[...]


In main your program reads an integer:

```
   int n;
   writef("Pick an option: ");
   readf(" %s", );
```

[...]

Thanks for the help!


Re: Question on shapes

2022-05-16 Thread matheus via Digitalmars-d-learn

On Tuesday, 17 May 2022 at 04:37:58 UTC, Ali Çehreli wrote:

...
2) If you want to have a shape hierarchy, then you can start by 
defining its interface and implement that interface by concrete 
shape types. Drawing is ordinarily handled by member functions:

...


Hi Ali, I'm not the author but I have a question, in your second 
example, let's say that sometimes it would be required to "draw" 
with some scale factor, so (As a newbie) I would do something 
like this:


interface Shape {
  void draw();
  void draw(float scale);
}

Then in Circle class:

  void draw(float scale) {
writeln("This circle's radius is ", radius*scale);
  }
  void draw(){ draw(1); }

Then in Rectangular class:

  void draw(float scale) {
writefln!"This rectangle's dimensions are 
%sx%s."(width*scale,height*scale);

  }
  void draw(){ draw(1); }


So calling shape.draw() would draw with the original scale, 
otherwise you could call as shape.draw(some_scale);


The problem is these are just 2 shapes and it could be much more, 
so it would required to repeat all this.


In D there would be a better way to do such thing?

Thanks,

Matheus.


Re: Question on shapes

2022-05-16 Thread Ali Çehreli via Digitalmars-d-learn

On 5/16/22 17:10, Alain De Vos wrote:
Let's say a shape is ,a circle with a radius ,or a square with a 
rectangular size.

I want to pass shapes to functions, eg to draw them on the screen,
draw(myshape) or myshape.draw();
But how do i implement best shapes ?


There are many ways of achieving this but I think you are looking for 
the classic object-oriented (OOP) shape hierarchy. (Option 2 below.)


1) This option does not use OOP. It uses function overloading:

import std.stdio;

struct Circle {
  float radius;
}

void draw(Circle circle) {
  writeln("This circle's radius is ", circle.radius);
}

struct Rectangle {
  float width;
  float height;
}

void draw(Rectangle rectangle) {
  writefln!"This rectangle's dimensions are %sx%s."(rectangle.width, 
rectangle.height);

}

void main() {
  draw(Circle(1.5));
  draw(Rectangle(2.5, 3.5));
}

That's very simple but it does not allow putting different types of 
shapes e.g. in the same array.



2) If you want to have a shape hierarchy, then you can start by defining 
its interface and implement that interface by concrete shape types. 
Drawing is ordinarily handled by member functions:


import std.stdio;

// This defines what we can do with a Shape:
interface Shape {
  void draw();
}

// This type is now a 'class' that implements Shape.
class Circle : Shape {
  float radius;

  // Classes require constructors; so here is one:
  this (float radius) {
this.radius = radius;
  }

  // No parameter needed. This function always executes on
  // 'this' object.
  void draw() {
writeln("This circle's radius is ", radius);
  }
}

// Similarly, a class
class Rectangle : Shape {
  float width;
  float height;

  this(float width, float height) {
this.width = width;
this.height = height;
  }

  void draw() {
writefln!"This rectangle's dimensions are %sx%s."(width, height);
  }
}

// Here is the promise of polymorphism: This function takes
// a Shape but the special drawing of each shape type is
// handled automatically.
void use(Shape shape) {
  shape.draw();
}

void main() {
  // Class hierarchies allow putting different types into
  // the same array:
  Shape[] shapes;

  // Let's populate with alternating circles and rectangles
  foreach (i; 1 .. 10) {
if  (i % 2) {
  shapes ~= new Circle(i);

} else {
  shapes ~= new Rectangle(i, i * 2);
}
  }

  // And finally let's use them
  foreach (shape; shapes) {
use(shape);
  }
}

Ali


Re: freebsd dub linker error

2022-05-16 Thread Alain De Vos via Digitalmars-d-learn

Bugs in the clang/llvm toolchain but not in the gcc toolchain ?


Re: freebsd dub linker error

2022-05-16 Thread Alain De Vos via Digitalmars-d-learn

The following worked , and i don't know what is going on:
```
ldc2 --gcc=gcc11
```



Question on shapes

2022-05-16 Thread Alain De Vos via Digitalmars-d-learn
Let's say a shape is ,a circle with a radius ,or a square with a 
rectangular size.

I want to pass shapes to functions, eg to draw them on the screen,
draw(myshape) or myshape.draw();
But how do i implement best shapes ?


Re: freebsd dub linker error

2022-05-16 Thread Alain De Vos via Digitalmars-d-learn

The problem re-appeared and i have totally no idea what caused it.
ldc2 test.d
ld: error: undefined hidden symbol: __start___minfo

referenced by test.d
  test.o:(ldc.register_dso)


ld: error: undefined hidden symbol: __stop___minfo

referenced by test.d
  test.o:(ldc.register_dso)
cc: error: linker command failed with exit code 1 (use -v to see 
invocation)

Error: /usr/bin/cc failed with status: 1

The only thing i did was disabling 32-bit code in kernel and 
userland.


Re: Why doesn't this piece of code work?

2022-05-16 Thread Ali Çehreli via Digitalmars-d-learn

On 5/16/22 15:25, kdevel wrote:

> string a;
> a = readln();
> writeln(a);

> consumes that newline from your first input resulting in variable a
> containing the empty string ending with a newline.

Great catch! I should put this combination in my chapter.

> I am not sure, why %s fits here. I would have expected a %d format for
> parsing the integer.

I learned to read %s as "whatever the type of the argument is" (not 
"string").


Ali



Re: Why doesn't this piece of code work?

2022-05-16 Thread kdevel via Digitalmars-d-learn

On Monday, 16 May 2022 at 16:53:15 UTC, SvGaming wrote:
[...]

https://github.com/svgaming234/ezusb
forgot to post it in the previous reply, I am kind of stupid


In main your program reads an integer:

```
   int n;
   writef("Pick an option: ");
   readf(" %s", );
```

but your console/Terminal is line buffered, i.e. you type 1 plus 
a newline ("\n"). Only after the newline the OS transfers control 
back to your program. Unfortunately your program does not consume 
the newline, as ltrace reveals the newline is put back to the 
input buffer with ungetch. Therefore the next read command


```
   string a;
   a = readln();
   writeln(a);
```

consumes that newline from your first input resulting in variable 
a containing the empty string ending with a newline. Following 
change fixes the issue:


```
   int n;
   writef("Pick an option: ");
   readf(" %s\n", ); // explicitly read the newline
```

I am not sure, why %s fits here. I would have expected a %d 
format for parsing the integer.




Re: Why are structs and classes so different?

2022-05-16 Thread Ali Çehreli via Digitalmars-d-learn

On 5/15/22 21:20, Tejas wrote:

> Never say never :
>
> https://github.com/dlang/DIPs/blob/master/DIPs/DIP1040.md

Thanks! I am reading it now.

> Also, there's `opPostMove` already within the language

I see: It indeed appears on some pages on dlang.org but the language 
spec has no mention of it. :) It looks like a DbI (design by 
introspection) thing in Phobos or core.


It looks like structs with self references are allowed now as long as 
they do the right thing in their opPostMove. Cool...


Ali



Re: Why are structs and classes so different?

2022-05-16 Thread Ali Çehreli via Digitalmars-d-learn

On 5/16/22 08:18, Kevin Bailey wrote:

> I was asking, "Why is it this way? Why was it
> designed this way?

I for one misunderstood you. I really thought you were arguing that 
struct and class should be the same.


> What bad thing happens the other way?"

C++ is proof that it can indeed work the other way. However, for it to 
work correctly, programmers must follow guidelines. Here are four:



http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#c67-a-polymorphic-class-should-suppress-public-copymove


http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#c145-access-polymorphic-objects-through-pointers-and-references

  http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Res-slice


http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#e15-throw-by-value-catch-exceptions-from-a-hierarchy-by-reference

C++ does not use terms "value type" and "reference type" to make any 
distinction but the rules above are proof enough for me that C++ 
implicitly divides user-defined types into such categories.


D is this way because someone realized that there are different kinds of 
user-defined types.


> When I think
> about most things in D, I can at least think of a reason, even if I
> don't agree with it. But not putting class objects on the stack makes no
> sense to me (assuming we still pass by reference.)

Ok, I think I see better now. You would like members of a class 
recursively placed next to each other in memory. What if a polymorphic 
type had a polymorphic member?


class Student : Human {
  double a;
  Pet pet;
  double b;
}

Could Pet (which could be a Cat or a Dog, etc.) fit between a and b? 
Yes, emplacing the top-level object in our memory would have some value 
but not all members would be there. For example, D's dynamic arrays are 
like C++'s vector. What if the type had a vector? It's element would not 
be on the stack.


Granted, the type could have a specific Pet:

  Dog pet;

but I would argue that not all Students would have a Dog.

> Reasons below.
>
> Ola, your response is very interesting. I would say that assignment
> isn't any more or less of an issue, as long as you pass by reference:
>
> // Using C syntax to make intent clear.
> class Foo { int x; }
> class Bar: Foo { int y; }
>
> void func1(Bar* bar) {
>bar.y = 4; // boom
> }
>
> void func2(Bar* bar) {
>Foo* foo = bar;
>foo.x = 3; // this is fine
>
>foo = new Foo;
>func1(cast(Bar*)(foo)); // uh oh
> }
>
> Illuminating comment about the ABI.

I don't understand that example. I see a programmer error of casting a 
Foo to a Bar.


> re: pass-by-reference and performance, agreed, this is why we pass
> integers in registers. But a struct on the stack is just as fast to
> access locally through a pointer register - "[bp+6]" - as remotely, yes?

I thought more of this and conferred with a colleague who degisned parts 
of Intel CPUs. He agrees with you: Even if passed by reference, the 
objects are in CPU cache anyway and the pointer arithmetic is made in 
the core that all is good.


He went further to suggest yes, by-reference will be faster for large 
structs but there is no clear answer because it all depends on the 
speeds of the core, cache (including the size), memory.


> D went the Java path: You can have any color you
> like, as long as it's grey.

Did you mean C#? C# is like D: structs are value types and classes are 
reference types.


> I agree that C++'s organic growth allows programmers to do things they
> shouldn't, and requires that they be more careful. But I would not have
> gone from there to Java.

Not at all!

> I've learned from all the projects that I've been on
> that we need all these types.

With all due respect, based on other conversation here, may I assume you 
those projects were based on C++? If you also had any language with 
reference types like Python, did you have the similar issues with those 
languages?


I accepted D's struct/class separation since the beginning and never had 
any issue with it. It just worked for me.


Ali



Re: Why are structs and classes so different?

2022-05-16 Thread Ali Çehreli via Digitalmars-d-learn

On 5/16/22 13:48, Kevin Bailey wrote:

> a large code-base written
> by thousands of other people. I do every day. I can't make them name
> things in any special way.

I think we need a comparable D project to know whether this is really an 
issue.


> But when I see the above code, I need to know
> exactly what it does with just a scan.

Most IDEs and editors show whether a type is a class or a struct.

Ali



Re: Why are structs and classes so different?

2022-05-16 Thread Ali Çehreli via Digitalmars-d-learn

On 5/16/22 10:35, Johan wrote:

> What is very problematic is that you cannot see the difference in
> syntax. In my opinion it would have been much better if the language
> required using a `*` for class types: for example `Foo* a`, and `Foo a`
> would simply give a compile error.

I see. Is it really a high mental load without the syntax? I seems to 
just work in my programs but perhaps because I am the main programmer 
and classes are very rare anyway.


Also, same syntax is said to help with template code but perhaps the 
argument there is a template must be written either for value types or 
reference types? I am not sure.


> A few years ago when I taught C++, this was 50% of the reason for me not
> to teach D.

That's unfortunate. :(

> I see a big confirmation of that decision in this thread.

Luckily, in my experience such threads are not frequent. Still, we may 
see a related topic at DConf. ;)


Ali



Re: Why are structs and classes so different?

2022-05-16 Thread Kevin Bailey via Digitalmars-d-learn

On Monday, 16 May 2022 at 19:06:01 UTC, Alain De Vos wrote:

A new syntax like "*" should introduce something new.
If it's not needed for classes why introduce it.


Hi Alain!

I have to sympathize with Johan. If you see:

Foo foo = get_foo();
call_function(foo);

can 'foo' change in 'call_function()' ? Is it by-reference or is 
it by value?


Foo* foo = get_foo();

How about now? Pretty obvious.

call_function();

Also obvious.

To re-phrase your claim, a new syntax doesn't need to introduce 
something new. Syntax is there to convey information.



If you don't know if something is a class name it class_blabla.
Just remember the effect of "="


ah, I see the problem. You've never worked in a large code-base 
written by thousands of other people. I do every day. I can't 
make them name things in any special way. But when I see the 
above code, I need to know exactly what it does with just a scan.




Re: Why are structs and classes so different?

2022-05-16 Thread Alain De Vos via Digitalmars-d-learn

A new syntax like "*" should introduce something new.
If it's not needed for classes why introduce it.
If you don't know if something is a class name it class_blabla.
Just remember the effect of "="


Re: D WebAssembly working differently than C++, Zig

2022-05-16 Thread Allen Garvey via Digitalmars-d-learn

On Monday, 16 May 2022 at 18:14:13 UTC, kinke wrote:
The problem is the memset signature. You assume the length is 
the number of floats, while it's the number of *bytes* to be 
set to the specified value. 
https://en.cppreference.com/w/c/string/byte/memset


Thanks so much, that fixed the problem! You have no idea have 
long I have spent trying to debug this!


Re: D WebAssembly working differently than C++, Zig

2022-05-16 Thread Allen Garvey via Digitalmars-d-learn

On Monday, 16 May 2022 at 18:05:00 UTC, Adam D Ruppe wrote:
I would suspect it is something to do with your memset... even 
if it needs to take the int (wtf but ldc is weird) you might 
want to reinterpret cast it to float to avoid any extra 
conversions.


I was thinking memset might be the case, but I tried changing it 
to ignore the int value and just hard-coding 0 and the result was 
the same.


Re: D WebAssembly working differently than C++, Zig

2022-05-16 Thread kinke via Digitalmars-d-learn
The problem is the memset signature. You assume the length is the 
number of floats, while it's the number of *bytes* to be set to 
the specified value. 
https://en.cppreference.com/w/c/string/byte/memset


Re: D WebAssembly working differently than C++, Zig

2022-05-16 Thread Adam D Ruppe via Digitalmars-d-learn
I would suspect it is something to do with your memset... even if 
it needs to take the int (wtf but ldc is weird) you might want to 
reinterpret cast it to float to avoid any extra conversions.


Re: Why are structs and classes so different?

2022-05-16 Thread Johan via Digitalmars-d-learn

On Sunday, 15 May 2022 at 16:36:05 UTC, Ali Çehreli wrote:

On 5/15/22 08:26, Kevin Bailey wrote:

> structs and classes are so different.

I think a more fundamental question is why structs and classes 
both exist at all. If they could be the same, one kind would be 
sufficient. And the answer is there are value types and there 
are reference types in programming.


What is very problematic is that you cannot see the difference in 
syntax. In my opinion it would have been much better if the 
language required using a `*` for class types: for example `Foo* 
a`, and `Foo a` would simply give a compile error.
A few years ago when I taught C++, this was 50% of the reason for 
me not to teach D. I see a big confirmation of that decision in 
this thread.


-Johan



D WebAssembly working differently than C++, Zig

2022-05-16 Thread Allen Garvey via Digitalmars-d-learn
I'm working on a comparison of WebAssembly performance for error 
propagation dithering using D, C++ and Zig. So far C++ and Zig 
work as expected, but for D, despite using the same algorithm and 
similar code the output is different.


You can see the differences here 
https://wasm-error-propagation-dither-comparison.netlify.app/ by 
opening an image.


Code
* D 
https://github.com/allen-garvey/wasm-error-propagation-dither-comparison/blob/master/wasm/d/main.d
* C++ 
https://github.com/allen-garvey/wasm-error-propagation-dither-comparison/blob/master/wasm/cpp/main.cpp
* Zig 
https://github.com/allen-garvey/wasm-error-propagation-dither-comparison/blob/master/wasm/zig/main.zig


Any help would be appreciated. From my extensive debugging it 
seems that calculating the pixel lightness is working correctly, 
it has something to do with either saving or retrieving the 
stored error in the float arrays.


Re: Why are structs and classes so different?

2022-05-16 Thread H. S. Teoh via Digitalmars-d-learn
On Mon, May 16, 2022 at 05:02:57PM +, IGotD- via Digitalmars-d-learn wrote:
> On Sunday, 15 May 2022 at 16:08:01 UTC, Mike Parker wrote:
> > 
> > `scope` in a class variable declaration will cause it to the class
> > to be allocated on the stack.
> > 
> 
> Common practice is that a class has class members itself. So where are
> they allocated? Most likely is only the top class that is on the
> stack, the class members are allocated on the heap because the
> constructor is already compiled.
> 
> That scope isn't that useful unless you have it like C++, that expands
> class members in the parent class.
[...]

C++ embedded class members suffer from the same problems as by-value
class objects. I.e., object truncation when you assign a derived class
member to it.  The only way to avoid this problem in C++ is to turn them
into pointers, at which point it becomes equivalent to D class members
that by default are reference types.

In D, if you have members that you want to have by-value semantics, just
use structs instead.  In general, in my own D code I rarely use classes.
Structs are my go-to constructs; only when there is good reason I use
classes -- usually when I need inheritance, which is also when by-value
types would encounter truncation issues.  Since it *is* possible to pass
around pointers to structs, I don't really see much reason for using
classes if you don't need inheritance, i.e., when you'll never run into
truncation issues.

So IMO D's design of structs and classes makes much more sense than in
C++, where `struct` and `class` means essentially the same thing (just
with some different default protections -- just lip gloss, really), and
where the unclear intention of whether you want a by-value or
by-reference type means that truncation issues keep cropping up. D's
choice to settle this decision and bake it into the language IMO was the
right choice. (Now obviously, this implies that the usage of structs /
classes will differ between D and C++... but then again, that's why this
is D, not C++. I want to speak idiomatic D, not D with a C++ lisp. :-P)


T

-- 
The richest man is not he who has the most, but he who needs the least.


Re: Why are structs and classes so different?

2022-05-16 Thread IGotD- via Digitalmars-d-learn

On Sunday, 15 May 2022 at 16:08:01 UTC, Mike Parker wrote:


`scope` in a class variable declaration will cause it to the 
class to be allocated on the stack.




Common practice is that a class has class members itself. So 
where are they allocated? Most likely is only the top class that 
is on the stack, the class members are allocated on the heap 
because the constructor is already compiled.


That scope isn't that useful unless you have it like C++, that 
expands class members in the parent class.






Re: Why doesn't this piece of code work?

2022-05-16 Thread SvGaming via Digitalmars-d-learn

On Monday, 16 May 2022 at 16:44:13 UTC, SvGaming wrote:

On Monday, 16 May 2022 at 16:40:59 UTC, SvGaming wrote:

On Sunday, 15 May 2022 at 20:06:20 UTC, kdevel wrote:

On Sunday, 15 May 2022 at 15:27:32 UTC, SvGaming wrote:
[...]

[...]


Until you post your full programm ideally in a reduced form 
[1] everybody who is willing to help must guess wildly what 
the unposted parts of your program does and how it may cause 
the read to be seemingly skipped.


[...]


I use dmd but I tried befor with another compiler and got the 
same result. Not sure if it was GDC or LDC.
Here is the repository on GitHub i just made for the code(i 
know it is quite messy, I am a begginer in D):


https://github.com/svgaming234/ezusb
forgot to post it in the previous reply, I am kind of stupid


Re: Why are structs and classes so different?

2022-05-16 Thread Ola Fosheim Grøstad via Digitalmars-d-learn

On Monday, 16 May 2022 at 15:18:11 UTC, Kevin Bailey wrote:
I would say that assignment isn't any more or less of an issue, 
as long as you pass by reference:


What I mean is if you write your code for the superclass, and 
later add a subclass with some invariants that depends on the 
superclass fields… then upcast an instance of the subclass to the 
superclass and pass it on… your risk the same issue. The subclass 
invariant can be broken because of sloppy modelling.


The premise for "slicing" being an issue is that people who write 
functions have no clue about how the type system works or how to 
properly model. So it is a lot of fuzz over nothing, because with 
that assumption you can make the exact same argument for 
references. (I've never had any practical issues related to 
"slicing", ever…)


Besides, slicing can very well be exactly what you want, e.g. if 
you have a super-class "EntityID" and want to build an array of 
all the EntityIDs… nothing wrong about slicing out the EntityID 
for all subclass instances when building that array.


Now, there are many other issues with C++, mostly related to the 
fact that they give very high priority to avoid overhead. E.g. 
take a new feature like std::span, if you create a subspan 
("slice" in D terminology) and the original span does not contain 
enough elements then C++ regards that as undefined behaviour and 
will happily return a span into arbitrary memory past the end of 
the original span. C++ is very unforgiving in comparison to 
"higher level" languages like D.


If we extend this reasoning to D classes, one can say that D 
classes are convenience constructs that does not pay as much 
attention to overhead. One example of this is how interfaces are 
implemented, each interface will take a full pointer in every 
instance of the class. The monitor mutex is another example. And 
how pointers to classes are different (simpler syntax) than 
pointers to struct also suggests that classes are designed more 
for convenience than principles.


Whether this is good or bad probably depends on the user group:

1. Those that are primarily interested in low level with a bit of 
high level might think it is "too much" and favour structs.


2. Those that are primarily interested in high level with a bit 
of low level might think otherwise.


In C++ everyone belong to group 1. In other system languages such 
as D and Rust you probably have a large silent majority in group 
2. (All those programmers that find C++ to be too brittle or hard 
to get into, but want comparable performance.)











Re: decimal type in d

2022-05-16 Thread Steven Schveighoffer via Digitalmars-d-learn

On 5/15/22 9:26 AM, vit wrote:
Hello, I want read decimal type from sql db, do some arithmetic 
operations inside D program and write it back to DB. Result need to be 
close to result as if this operations was performed in sql DB. Something 
like C# decimal.

Exists this kind of library ind D? (ideally `pure @safe @nogc nothrow`).


https://code.dlang.org/search?q=decimal

-Steve


Re: Why doesn't this piece of code work?

2022-05-16 Thread SvGaming via Digitalmars-d-learn

On Monday, 16 May 2022 at 16:40:59 UTC, SvGaming wrote:

On Sunday, 15 May 2022 at 20:06:20 UTC, kdevel wrote:

On Sunday, 15 May 2022 at 15:27:32 UTC, SvGaming wrote:
[...]

[...]


Until you post your full programm ideally in a reduced form 
[1] everybody who is willing to help must guess wildly what 
the unposted parts of your program does and how it may cause 
the read to be seemingly skipped.


[...]


I use dmd but I tried befor with another compiler and got the 
same result. Not sure if it was GDC or LDC.
Here is the repository on GitHub i just made for the code(i know 
it is quite messy, I am a begginer in D):


Re: Why doesn't this piece of code work?

2022-05-16 Thread SvGaming via Digitalmars-d-learn

On Sunday, 15 May 2022 at 20:06:20 UTC, kdevel wrote:

On Sunday, 15 May 2022 at 15:27:32 UTC, SvGaming wrote:
[...]

[...]


Until you post your full programm ideally in a reduced form [1] 
everybody who is willing to help must guess wildly what the 
unposted parts of your program does and how it may cause the 
read to be seemingly skipped.


[...]


I use dmd but I tried befor with another compiler and got the 
same result. Not sure if it was GDC or LDC.


Re: Why are structs and classes so different?

2022-05-16 Thread Kevin Bailey via Digitalmars-d-learn

Great responses, everyone. I'll try to address all of them.

Mike, I know the rules. I was asking, "Why is it this way? Why 
was it designed this way? What bad thing happens the other way?" 
When I think about most things in D, I can at least think of a 
reason, even if I don't agree with it. But not putting class 
objects on the stack makes no sense to me (assuming we still pass 
by reference.) Reasons below.


Ola, your response is very interesting. I would say that 
assignment isn't any more or less of an issue, as long as you 
pass by reference:


// Using C syntax to make intent clear.
class Foo { int x; }
class Bar: Foo { int y; }

void func1(Bar* bar) {
  bar.y = 4; // boom
}

void func2(Bar* bar) {
  Foo* foo = bar;
  foo.x = 3; // this is fine

  foo = new Foo;
  func1(cast(Bar*)(foo)); // uh oh
}

Illuminating comment about the ABI.

Ali, I've never liked the distinction between 'struct' and 
'class' in C++ either, but that's no reason to actually make them 
different. It's a reason to remove 'class' and save the keyword.


re: pass-by-reference and performance, agreed, this is why we 
pass integers in registers. But a struct on the stack is just as 
fast to access locally through a pointer register - "[bp+6]" - as 
remotely, yes?


Finally, 'scope' is nice but it doesn't solve the segfault issue.

HS Teoh: See above for my responses about assignment and 'scope'.

bauss: "But that's not entirely true as you can allocate a struct 
on the heap as well."


forkit: "where they live in memory should be less of the 
programmers concern, and more an implementation issue (although 
some programmers will of course consider this as well)."


Precisely. You can allocate structs, and you can put class 
objects in 'scope' variables. (I'm not sure if this was your 
intent, forkit, but) a class object can live on the stack just as 
easily as on the heap, as long as you pass by reference. The only 
danger is if a called function tries to own a stack allocated 
object, but this is a concern for heap allocated objects too. 
This is why C++ has moveable types and unique_ptr.


Walter, Thanks for the insightful reply! I'm getting the sense 
that the decision was made in order to make the language simpler. 
That is, ignoring struct's, D went the Java path: You can have 
any color you like, as long as it's grey.


I agree that C++'s organic growth allows programmers to do things 
they shouldn't, and requires that they be more careful. But I 
would not have gone from there to Java.


I think an interesting middle-ground would be a language that had 
"template" types - Copyable, MoveOnly, Interface, Singleton, 
FactoryBuilt, etc. I've learned from all the projects that I've 
been on that we need all these types. We can either ask 
programmers to hand-craft them, or we can provide them. Note that 
in C++, we can get pretty close:


class Foo: Moveable { ...

And then there's the segfault issue. I think that, if we're going 
to ignore a huge problem like that, there has to be very strong 
reasons. From this discussion, it doesn't sound like they were 
very strong.


Of course, it's done and there's little changing it. A seemingly 
harmless fix would be to not require 'new':


Foo foo; // this allocates an object
Foo foo = null; // this does not
Foo foo = function(); // this doesn't either

In fact, I suspect we could make that change today and few would 
notice. Nevertheless, I'm still a little shocked that this isn't 
existing behavior.


cheers all



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

2022-05-16 Thread H. S. Teoh via Digitalmars-d-learn
On Mon, May 16, 2022 at 04:00:12AM +, cc via Digitalmars-d-learn wrote:
> On Wednesday, 11 May 2022 at 05:41:35 UTC, Ali Çehreli wrote:
> > What are you stuck at? What was the most difficult features to
> > understand? etc.
> > 
> > To make it more meaningful, what is your experience with other
> > languages?
[...]
> Immutability.  Ended up having to do so many hundreds of casts to and
> from immutable(whatever) the amount of mental strain greatly exceeded
> whatever benefits the entire concept is supposed to offer.

If you find yourself having to cast to/from immutable, you're using it
wrong.  Most of my code doesn't have a single mention of immutable in
it, and I don't care. It's there for when it's relevant, if it's not
useful, don't use it.


> Safety?  Performance, in a future compiler version?  I don't know
> where it's at right now.

What about performance?

For anything performance-related, I don't even look at dmd, I use LDC
all the way. DMD is only useful for fast compile-run-debug cycle, I
don't even look at performance numbers for DMD-produced executables, it
doesn't mean anything to me.


> But you'd think I could do something like load some data from disk,
> craft a few objects, mark them as immutable, and shove them in an
> array or associative array without it being a nightmare, but it isn't.

An explicit example would be nice.

I write D programs that process input files all the time, including
stuffing data into AAs and what-not, and it Just Works(tm).  But not
once did I bother with immutable (why should I?).  The most I'd do is to
mark something const (you might want to read up on the difference
between immutable and const -- maybe that's why you had so much
trouble), but even that I don't bother with most of the time. Const in D
has limited utility beyond leaf-node data structures and modules, just
let it be mutable and call it a day.


> Or, having an otherwise mutable class with a member that references an
> immutable class, but can change which immutable instance it's
> referencing, without having to cast away the immutability of the thing
> I'm trying to protect in the first place.  So I just stopped doing it,
> and simply rely on the "just don't make mistakes" practice to avoid
> writing to things that shouldn't be written to now.

Just make things private and use getters/setters to control access. Like
I said, if you find yourself writing lots of casts when using
immutable/const, you're probably doing it wrong.


[...]
> On another topic, the lack of a good "delete" keyword doing what one
> would expect, when there's a perfectly good "new" without its matching
> existential companion.  This, and the ways around it, have already
> been discussed to death though, but banging my head over trying to
> force deterministic memory management into the GC-controlled D
> universe did take its toll on a good year or two of productivity.

Why would you want to force deterministic memory management onto
GC-allocated objects?  Just use malloc/free (or whatever else you
fancy).  Slap @nogc on main() and go from there, if that helps.

IME, most programs don't actually need to care whether their memory is
manually-managed or GC'd.  Many of my programs use GC freely, except in
inner loops where tigher control is needed, then I either preallocate or
use malloc/free.  But only where it actually makes a difference to
performance.  Outside of performance bottlenecks I don't bother with
memory management, just let the GC do its job.


T

-- 
Latin's a dead language, as dead as can be; it killed off all the Romans, and 
now it's killing me! -- Schoolboy


Re: decimal type in d

2022-05-16 Thread bauss via Digitalmars-d-learn

On Monday, 16 May 2022 at 09:46:57 UTC, IGotD- wrote:

On Sunday, 15 May 2022 at 13:26:30 UTC, vit wrote:
Hello, I want read decimal type from sql db, do some 
arithmetic operations inside D program and write it back to 
DB. Result need to be close to result as if this operations 
was performed in sql DB. Something like C# decimal.
Exists this kind of library ind D? (ideally `pure @safe @nogc 
nothrow`).


This also something I wondered, it should be standard in the D 
library. Implementing it can be done straight forward with 
existing D language primitives, essentially a struct.


For those who don't know, decimal in C# is like a floating 
point value but the exponent is a power of 10 (internally total 
16 bytes). This means that for "simple" mathematics rational 
decimal values remains rational decimals values and not some 
rounded value that would happen if you would use normal 
floating point values. The decimal type is essential for 
financial calculations.


I think D can more or less copy the C# solution.


Here's the implementation if anyone needs it:

https://referencesource.microsoft.com/#mscorlib/system/decimal.cs,1b2858baf311cbf9

Should be fairly straightforward to implement.


Re: decimal type in d

2022-05-16 Thread IGotD- via Digitalmars-d-learn

On Sunday, 15 May 2022 at 13:26:30 UTC, vit wrote:
Hello, I want read decimal type from sql db, do some arithmetic 
operations inside D program and write it back to DB. Result 
need to be close to result as if this operations was performed 
in sql DB. Something like C# decimal.
Exists this kind of library ind D? (ideally `pure @safe @nogc 
nothrow`).


This also something I wondered, it should be standard in the D 
library. Implementing it can be done straight forward with 
existing D language primitives, essentially a struct.


For those who don't know, decimal in C# is like a floating point 
value but the exponent is a power of 10 (internally total 16 
bytes). This means that for "simple" mathematics rational decimal 
values remains rational decimals values and not some rounded 
value that would happen if you would use normal floating point 
values. The decimal type is essential for financial calculations.


I think D can more or less copy the C# solution.




Re: Why are structs and classes so different?

2022-05-16 Thread bauss via Digitalmars-d-learn

On Sunday, 15 May 2022 at 15:59:17 UTC, Alain De Vos wrote:

Can i summarize ,
structs are value-objects which live on the stack.
class instances are reference objects which live on the heap.


But that's not entirely true as you can allocate a struct on the 
heap as well.


The real difference is inheritance and polymorphism, not 
allocation and where the memory lives.