digitalmars.D.learn - Shall I use immutable or const while passing parameters to functions
- tcak (12/12) Apr 07 2015 I have data in memory, and I want a function to take a part of
- John Colvin (21/33) Apr 07 2015 const means "I will not modify this via this variable" and
- Adam D. Ruppe (4/4) Apr 07 2015 If you're just looking at the data, use const. immutable becomes
- bearophile (9/14) Apr 07 2015 Don't cast to const/immutable unless you have a good reason to do
- tcak (9/30) Apr 07 2015 I am trying to avoid it as much as I can, though this "shared"
- Marco Leise (9/43) Apr 09 2015 I'd advise you not to use shared, at least not for anything
- jkpl (5/17) Apr 09 2015 With `Object` or `struct` parameters, the `const` storage class
- H. S. Teoh via Digitalmars-d-learn (50/70) Apr 09 2015 [...]
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
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
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
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
On Tuesday, 7 April 2015 at 15:51:59 UTC, bearophile wrote:tcak: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.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
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: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. :) -- Marcotcak: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.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 09 2015
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
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:[...] 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.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] ) );
Apr 09 2015