www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Shall I use immutable or const while passing parameters to functions

reply "tcak" <tcak gmail.com> writes:
I have data in memory, and I want a function to take a part of 
data for processing only. It will only read and won't change.

char[] importantData;


With Immutable,

void dataProcessor( string giveMeAllYourData ){}

dataProcessor( cast( immutable )( importantData[5 .. 14] ) );



With Const,

void dataProcessor( in char[] giveMeAllYourData ){}

dataProcessor( cast( const )( importantData[5 .. 14] ) );


(Code with const wasn't tested)

Which one is better? I didn't understand it very well in 
http://dlang.org/const3.html this page.
Apr 07 2015
next sibling parent "John Colvin" <john.loughran.colvin gmail.com> writes:
On Tuesday, 7 April 2015 at 15:11:39 UTC, tcak wrote:
 I have data in memory, and I want a function to take a part of 
 data for processing only. It will only read and won't change.

 char[] importantData;


 With Immutable,

 void dataProcessor( string giveMeAllYourData ){}

 dataProcessor( cast( immutable )( importantData[5 .. 14] ) );



 With Const,

 void dataProcessor( in char[] giveMeAllYourData ){}

 dataProcessor( cast( const )( importantData[5 .. 14] ) );


 (Code with const wasn't tested)

 Which one is better? I didn't understand it very well in 
 http://dlang.org/const3.html this page.
const means "I will not modify this via this variable" and immutable means "no one will modify this from anywhere" Don't cast to immutable unless you are sure what you are doing. Immutable is a strong guarantee, it's easy to break it by accident if you're casting things. The safest way of getting an immutable array is with the .idup property. You don't have to cast to const most of the time. mutable is implicitly convertible to const: void foo(const int[] a){} void main() { int[] a = [1,2,3,4]; foo(a); foo(a[0..2]); } Also, see https://archive.org/details/dconf2013-day01-talk02 In general, immutable in an API allows greater freedom for the implementation, const allows for greater freedom/convenience for the API user. Which is more important depends on your exact problem.
Apr 07 2015
prev sibling next sibling parent "Adam D. Ruppe" <destructionator gmail.com> writes:
If you're just looking at the data, use const. immutable becomes 
more important if it is shared across threads or stored for later.

Functions that accept const will work with almost anything you 
pass to it.
Apr 07 2015
prev sibling next sibling parent reply "bearophile" <bearophileHUGS lycos.com> writes:
tcak:

 void dataProcessor( string giveMeAllYourData ){}

 dataProcessor( cast( immutable )( importantData[5 .. 14] ) );



 With Const,

 void dataProcessor( in char[] giveMeAllYourData ){}

 dataProcessor( cast( const )( importantData[5 .. 14] ) );
Don't cast to const/immutable unless you have a good reason to do it, and you know what you are doing (and most times you don't know it). More generally, minimize the number of cast() in your D programs. You can use a search to count how many "cast(" there are in your whole D codebase, and you can try to reduce that number. Bye, bearophile
Apr 07 2015
parent reply "tcak" <tcak gmail.com> writes:
On Tuesday, 7 April 2015 at 15:51:59 UTC, bearophile wrote:
 tcak:

 void dataProcessor( string giveMeAllYourData ){}

 dataProcessor( cast( immutable )( importantData[5 .. 14] ) );



 With Const,

 void dataProcessor( in char[] giveMeAllYourData ){}

 dataProcessor( cast( const )( importantData[5 .. 14] ) );
Don't cast to const/immutable unless you have a good reason to do it, and you know what you are doing (and most times you don't know it). More generally, minimize the number of cast() in your D programs. You can use a search to count how many "cast(" there are in your whole D codebase, and you can try to reduce that number. Bye, bearophile
I am trying to avoid it as much as I can, though this "shared" keyword is not leaving me alone. Most of the projects I am working on use multiple threads, and I am mostly obliged to use casting many times. I am getting worried some times about what the compiler is doing when I do casting other than just changing a simple understanding like taking the first byte of ulong when I do casting, etc. Please do not suggesting to use __gshared. It is ugly looking.
Apr 07 2015
parent Marco Leise <Marco.Leise gmx.de> writes:
Am Tue, 07 Apr 2015 17:26:23 +0000
schrieb "tcak" <tcak gmail.com>:

 On Tuesday, 7 April 2015 at 15:51:59 UTC, bearophile wrote:
 tcak:

 void dataProcessor( string giveMeAllYourData ){}

 dataProcessor( cast( immutable )( importantData[5 .. 14] ) );



 With Const,

 void dataProcessor( in char[] giveMeAllYourData ){}

 dataProcessor( cast( const )( importantData[5 .. 14] ) );
Don't cast to const/immutable unless you have a good reason to do it, and you know what you are doing (and most times you don't know it). More generally, minimize the number of cast() in your D programs. You can use a search to count how many "cast(" there are in your whole D codebase, and you can try to reduce that number. Bye, bearophile
I am trying to avoid it as much as I can, though this "shared" keyword is not leaving me alone. Most of the projects I am working on use multiple threads, and I am mostly obliged to use casting many times. I am getting worried some times about what the compiler is doing when I do casting other than just changing a simple understanding like taking the first byte of ulong when I do casting, etc. Please do not suggesting to use __gshared. It is ugly looking.
I'd advise you not to use shared, at least not for anything more than core.atomic. It's not in a good state for general use and not even mutexes or conditions in D are 'shared'. It becomes really messy as soon as you have structs that contain shared fields. I suggest you use __gshared. :) -- Marco
Apr 09 2015
prev sibling parent reply "jkpl" <jkpl somewhere.fr> writes:
On Tuesday, 7 April 2015 at 15:11:39 UTC, tcak wrote:
 I have data in memory, and I want a function to take a part of 
 data for processing only. It will only read and won't change.

 char[] importantData;


 With Immutable,

 void dataProcessor( string giveMeAllYourData ){}

 dataProcessor( cast( immutable )( importantData[5 .. 14] ) );



 With Const,

 void dataProcessor( in char[] giveMeAllYourData ){}

 dataProcessor( cast( const )( importantData[5 .. 14] ) );


 (Code with const wasn't tested)

 Which one is better? I didn't understand it very well in 
 http://dlang.org/const3.html this page.
With `Object` or `struct` parameters, the `const` storage class is often a cripple because of its transitiveness. At least for me this is in the top five reasons why sometimes a program doesn't compile (with the error...`cannot modify const this`...)
Apr 09 2015
parent "H. S. Teoh via Digitalmars-d-learn" <digitalmars-d-learn puremagic.com> writes:
On Fri, Apr 10, 2015 at 05:15:52AM +0000, jkpl via Digitalmars-d-learn wrote:
 On Tuesday, 7 April 2015 at 15:11:39 UTC, tcak wrote:
I have data in memory, and I want a function to take a part of data for
processing only. It will only read and won't change.

char[] importantData;


With Immutable,

void dataProcessor( string giveMeAllYourData ){}

dataProcessor( cast( immutable )( importantData[5 .. 14] ) );



With Const,

void dataProcessor( in char[] giveMeAllYourData ){}

dataProcessor( cast( const )( importantData[5 .. 14] ) );
[...] It's a very bad idea to cast away immutable or const without understanding what it does. This breaks the type system and may introduce subtle bugs into your program, because the compiler may optimize based on const/immutable, and breaking the type system could make the optimization break your program. This diagram may help you understand when to use const: const / \ (mutable) immutable Basically, what this means is that both mutable and immutable implicitly converts to const, so you don't need to cast anything to const, you can just pass it as-is. However, immutable and mutable cannot implicitly convert to each other, unless the type is a by-value type with no indirections (in which case it's making a copy, so there is no breakage of const/immutable). Unless C++, const in D means *physical* const, that is, you cannot modify the *entire* data (including everything it points to), even if semantically modifying, say, a caching member doesn't logically modify the data. That's why const is transitive. Immutable means the data does not change, *ever*, after it has been initialized. The compiler is free to assume that immutable data can be stored in registers even if there is an intervening function call that takes that data by reference, because nothing is ever supposed to modify it, not even another thread. If you randomly cast away immutable, or if you cast something into immutable but later on somebody modifies it through a mutable reference, you will break the type system and may cause the compiler to emit wrong code. The compiler is also free to put immutable data in ROM, which means you might get a segfault if later on you attempt to modify it through a casted mutable reference. So basically, it's a very bad idea to cast away const/immutable or cast into immutable, unless you know what you're doing. You don't ever need to cast to const, because you can just assign the data to const directly. Const means *you*, the holder of the const reference, cannot modify the data, but somebody else, somewhere else, who has a mutable reference to it may modify it. Immutable means *nobody* can modify the data, ever. In your case, it's enough to use const or in, you don't need a cast. You should not use immutable if you ever need to pass in mutable data to the function; that's what const is for. Const means the function cannot modify the data, but the caller may. Immutable means nobody can modify the data, which is wrong if the caller holds a mutable reference to it. Usually, the only time a function needs to take immutable parameters is when it wants to make sure the *caller* won't modify the data either, say if the function is caching a hash of the data for later use, and the hash will get invalidated if the caller can freely modify the data. T -- Amateurs built the Ark; professionals built the Titanic.
Apr 09 2015