January 24, 2022

On 1/24/22 11:41 AM, rempas wrote:

>

On Monday, 24 January 2022 at 15:40:56 UTC, Walter Bright wrote:

>

Not sure what you mean. This compiles:

  int foo(const int);

  int bar(int i)
  {
    return foo(i);
  }

Actually this compiles but what I thought that didn't was something like this:

void mul_num(int num) {
   num *= 2;
}

void main() {
   const int number = 10;
   mul_num(number);
}

But it turns out that it compiles but I would swear that I tried something similar to this and it wouldn't compile on both D and C.

I know exactly what you were doing:

void mul_num(T)(T num) {
   num *= 2;
}

That will fail if you just do mul_num(number) because templates infer the type from the argument (e.g. T becomes const int)

Unfortunately, D doesn't have a "tail-const" modifier, which would work really well here.

-Steve

January 24, 2022
On 1/24/2022 7:44 AM, Walter Bright wrote:
> On 1/24/2022 6:40 AM, Steven Schveighoffer wrote:
>> immutable/const is purely a compile-time concept. It's not reflected in the final binary, so it's not necessary to forward the attributes to a language that doesn't support it.
> 
> Immutable global data gets placed in read-only memory sections. Read-only memory sections are nice in a demand-paged virtual system, as the pages they are in never have to be copied because they are never marked as "dirty".

Also, immutable data can be merged together, reducing the memory footprint. The dmd compiler does this with strings, for example. Identical string literals are set up to get merged at link time, this can only happen if they are immutable.

Immutable zero initialized data also gets merged. A zero is a zero, no matter what type it is!
January 24, 2022
On 1/24/2022 8:43 AM, rempas wrote:
> Read only memory? So in the same place where string literals are placed? This sounds cool and it's really something considerable! Does this offer things like security as date will be able to be created once and not get modified again? I hope I'm not asking for too much...

You can see this if you run an object file disassembler over the compiler output, the immutable data goes in read-only sections.
January 24, 2022
On Mon, Jan 24, 2022 at 11:59:37AM -0800, Walter Bright via Digitalmars-d wrote:
> On 1/24/2022 7:44 AM, Walter Bright wrote:
[...]
> Also, immutable data can be merged together, reducing the memory footprint.  The dmd compiler does this with strings, for example. Identical string literals are set up to get merged at link time, this can only happen if they are immutable.
> 
> Immutable zero initialized data also gets merged. A zero is a zero, no matter what type it is!

Makes me curious: how feasible is it to have functions with identical bodies merge together as well? This would help reduce template bloat when you have e.g. a templated type where a bunch of functions are identical because they either don't depend on the type (e.g. a container method that doesn't care about what type the payload is), or else depend on type traits that are common across many types (e.g., int.sizeof which is shared with uint.sizeof, float.sizeof, etc.).


T

-- 
Why is it that all of the instruments seeking intelligent life in the universe are pointed away from Earth? -- Michael Beibl
January 24, 2022
On Mon, Jan 24, 2022 at 12:02:11PM -0800, Walter Bright via Digitalmars-d wrote:
> On 1/24/2022 8:43 AM, rempas wrote:
> > Read only memory? So in the same place where string literals are placed?  This sounds cool and it's really something considerable! Does this offer things like security as date will be able to be created once and not get modified again? I hope I'm not asking for too much...
> 
> You can see this if you run an object file disassembler over the compiler output, the immutable data goes in read-only sections.

It depends on OS support, obviously. But most commonly-used OSes ought to support this.

Placing static string data in the read-only segment could be one line of defense against exploits that, e.g., modify an embedded shell script to do something pernicious instead.


T

-- 
Elegant or ugly code as well as fine or rude sentences have something in common: they don't depend on the language. -- Luca De Vitis
January 24, 2022

On Monday, 24 January 2022 at 16:23:25 UTC, rempas wrote:

>

On Monday, 24 January 2022 at 14:22:55 UTC, Guillaume Piolat wrote:

>

const has utility at interface boundaries. You don't want an API to be used incorrectly.
If it's internal code though, it only helps the maintainers, and is often line noise.

I mean, I can understand and agree the cases where people will just make mistakes because they are humans or because they are coding at a time they should be sleeping but like I said, I think that why should start writing good documentation and people should start reading it. Thanks for your thoughts!

No, at API level it is also a documentation help. When a parameter is marked as const, the code reader can be sure that there are no side effects in that function on that parameter. This reduces the mental burden when one tries to read code.

January 24, 2022
On Monday, 24 January 2022 at 17:30:26 UTC, Ali Çehreli wrote:
> On 1/24/22 04:31, Dennis wrote:
>
> > I never understood the idea of people always including {}
> braces in
> > if-statements and for-loops.
> [...]
> > What idiot would write something like that,
>
> Yeah, that thought disappears once one realizes that humans are mistake-making machines. :)
>
> > One day I had a single-line for-loop
> > body, and to fix an error I quickly added an `import`
> statement above
> > it, pushing the for-loop body outside the for-loop scope.
> Oops.
>
> I've done its counterpart just two days ago by commenting out one line (in somebody else's code):
>
>   foreach(i; 0..2)
>     // foo();
>
>   bar();
>
> Oops! Now bar() is executed multiple times.
>
> I am saddened with this skipped-braces "optimization" because all that risk for just to skip writing two characters! Wow! Now... that's... interesting... :) Humans are really interesting...
>
Not really a problem in my experience (25 years of C + 5 years of D) it happened only a couple of times and it is quickly found when it happens. I'm an extremly minimalistic programmer, I avoid unecessary parenthesis and brackets whenever I can.


January 24, 2022
On 1/24/2022 11:09 AM, Steven Schveighoffer wrote:
> Sure, but const isn't necessary for that. Const is a compiler construct to prevent you from doing stupid things. But a programming language can run perfectly fine with ROM without having a const concept.
> 
> D1 put string literals in ROM without const.

Yeah, but it's undefined behavior if you write to them.

January 24, 2022
On Monday, 24 January 2022 at 20:09:46 UTC, H. S. Teoh wrote:
> [snip]
>
> Makes me curious: how feasible is it to have functions with identical bodies merge together as well? This would help reduce template bloat when you have e.g. a templated type where a bunch of functions are identical because they either don't depend on the type (e.g. a container method that doesn't care about what type the payload is), or else depend on type traits that are common across many types (e.g., int.sizeof which is shared with uint.sizeof, float.sizeof, etc.).
>
>
> T

This reminds me of generics. In languages with generics, you can get one copy of a function over many different types. My (possibly incorrect) recollection is that it works like having the compiler cast the generic MyClass!T to MyClass. Ideally from D's perspective there would be a way to do this to minimize any overhead that you would get in Java from being forced to use classes.

Merging functions with identical bodies is basically the problem that inout is trying to solve. A way to express inout via the language would probably be good, though inout is rather complicated.  For instance, you have an Inout(T) with the property that if you have a function that takes an Inout(T), then calling it with Inout!int, Inout!(const(int)), and Inout!(immutable(int)) would all have only one version of a function at runtime. You would still need to be able to enforce that Inout(T) has the same unique behaviors as inout, such as that you can't modify the variable in the body of the function.

This would also be useful for reducing template bloat with allocators. For instance, if you have a templated function that takes an allocator as a parameter, then for every different allocator you use with it, you get an extra copy of the function, even if the body of the function may be the same across the different allocators used (since it may be jumping to the allocator to call that code).
January 24, 2022
On 1/24/2022 12:09 PM, H. S. Teoh wrote:
> Makes me curious: how feasible is it to have functions with identical
> bodies merge together as well? This would help reduce template bloat
> when you have e.g. a templated type where a bunch of functions are
> identical because they either don't depend on the type (e.g. a container
> method that doesn't care about what type the payload is), or else depend
> on type traits that are common across many types (e.g., int.sizeof which
> is shared with uint.sizeof, float.sizeof, etc.).

It's quite feasible. I've considered adding that optimization many times.