www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - What is the shortest way to define an immutable token of unique type?

reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Is there a simpler way that this?

struct Hex {}
immutable Hex hex;

I don't want to introduce two names in the scope, just `hex`. Another 
attempt:

immutable hex = function {};

That's a bit... arcane. Is there another simple way? Thanks!
Mar 14
next sibling parent Paul Backus <snarwin gmail.com> writes:
On Sunday, 14 March 2021 at 16:37:58 UTC, Andrei Alexandrescu 
wrote:
 Is there a simpler way that this?

 struct Hex {}
 immutable Hex hex;

 I don't want to introduce two names in the scope, just `hex`. 
 Another attempt:

 immutable hex = function {};

 That's a bit... arcane. Is there another simple way? Thanks!
You could use a Voldemort type: immutable hex = () { static struct Hex {} return Hex(); }();
Mar 14
prev sibling next sibling parent Bastiaan Veelo <Bastiaan Veelo.net> writes:
On Sunday, 14 March 2021 at 16:37:58 UTC, Andrei Alexandrescu 
wrote:
 Is there a simpler way that this?

 struct Hex {}
 immutable Hex hex;

 I don't want to introduce two names in the scope, just `hex`. 
 Another attempt:

 immutable hex = function {};

 That's a bit... arcane. Is there another simple way? Thanks!
Hardly simpler, but Hex can be kept out of scope by making it Voldemort: immutable hex = (){struct Hex{} return Hex();}(); -- Bastiaan.
Mar 14
prev sibling next sibling parent reply Petar Kirov [ZombineDev] <petar.p.kirov gmail.com> writes:
On Sunday, 14 March 2021 at 16:37:58 UTC, Andrei Alexandrescu 
wrote:
 Is there a simpler way that this?

 struct Hex {}
 immutable Hex hex;

 I don't want to introduce two names in the scope, just `hex`. 
 Another attempt:

 immutable hex = function {};
Could be slightly shorter: const u = (){};
 That's a bit... arcane. Is there another simple way? Thanks!
Indeed, though what is your use case? Usually the use case determines whether a solution is good or not. Is JavaScript's Symbol [1] primitive data type something like what you're after? Perhaps anonymous classes would be closest D can offer - `auto a = new class {};`. Unfortunately, unlike struct values, classes objects can't pass through from CTFE to RT, which makes them limited for certain use cases (e.g. you can't put the statement above at the module scope). [1]: https://developer.mozilla.org/en-US/docs/Glossary/Symbol
Mar 14
parent reply Adam D. Ruppe <destructionator gmail.com> writes:
On Sunday, 14 March 2021 at 19:10:19 UTC, Petar Kirov 
[ZombineDev] wrote:
 Unfortunately, unlike struct values, classes objects can't pass 
 through from CTFE to RT, which makes them limited for certain 
 use cases (e.g. you can't put the statement above at the module 
 scope).
Yes they can. The limitation is class objects cannot be enums and passing as template arguments is not allowed (I believe the error is caught at codegen though so avoid codegen, avoid error, but still). But you can assign them to static values post ctfe. I think you could make a little function to convert a class to a struct too immutable bar = new class { int a; }.toStruct; That is totally possible, but the implementation of toStruct is a slight pain, keeping the identifiers and such. I don't think it is worth the hassle.
Mar 14
parent Petar Kirov [ZombineDev] <petar.p.kirov gmail.com> writes:
On Sunday, 14 March 2021 at 19:23:33 UTC, Adam D. Ruppe wrote:
 On Sunday, 14 March 2021 at 19:10:19 UTC, Petar Kirov 
 [ZombineDev] wrote:
 Unfortunately, unlike struct values, classes objects can't 
 pass through from CTFE to RT, which makes them limited for 
 certain use cases (e.g. you can't put the statement above at 
 the module scope).
Yes they can. The limitation is class objects cannot be enums and passing as template arguments is not allowed (I believe the error is caught at codegen though so avoid codegen, avoid error, but still). [...]
I think my point still stands :P You can use class objects inside CTFE, but they can't exit unchanged - you can't really use them to initialize class variables and more importantly, if you convert a class object to a struct value, you loose the object identity, so you can't quite emulate [1]. [1]: https://developer.mozilla.org/en-US/docs/Glossary/Symbol
Mar 14
prev sibling next sibling parent Walter Bright <newshound2 digitalmars.com> writes:
On 3/14/2021 9:37 AM, Andrei Alexandrescu wrote:
 Another attempt:
 
 immutable hex = function {};
That won't have a unique type. It may not have a unique value, either. The compiler/linker may merge identical immutable objects.
Mar 15
prev sibling next sibling parent reply Per =?UTF-8?B?Tm9yZGzDtnc=?= <per.nordlow gmail.com> writes:
On Sunday, 14 March 2021 at 16:37:58 UTC, Andrei Alexandrescu 
wrote:
 struct Hex {}
 immutable Hex hex;
What about making the type name optional (via a language change) and allow immutable struct { int x; int y; } hex; and if possible have it be lowered to a builtin tuple immutable (int, int) hex; ? Does a struct and tuple with the same fields have the same memory layout?
Mar 15
next sibling parent Per =?UTF-8?B?Tm9yZGzDtnc=?= <per.nordlow gmail.com> writes:
On Monday, 15 March 2021 at 09:45:44 UTC, Per Nordlöw wrote:
 and if possible have it be lowered to a builtin tuple

     immutable (int, int) hex;
Forget about the tuple lowering. It doesn't have the fields accessible by name.
Mar 15
prev sibling parent Max Haughton <maxhaton gmail.com> writes:
On Monday, 15 March 2021 at 09:45:44 UTC, Per Nordlöw wrote:
 On Sunday, 14 March 2021 at 16:37:58 UTC, Andrei Alexandrescu 
 wrote:
 struct Hex {}
 immutable Hex hex;
What about making the type name optional (via a language change) and allow immutable struct { int x; int y; } hex; and if possible have it be lowered to a builtin tuple immutable (int, int) hex; ? Does a struct and tuple with the same fields have the same memory layout?
Some kind of lowering would hopefully be a way of getting tuples that work. Tuples-as-compiler-magic are embarrassing, tuples as a library are too complicated I find. i.e. The tuple should be either a sister or close-child of a struct
Mar 15
prev sibling parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 14.03.21 17:37, Andrei Alexandrescu wrote:
 Is there a simpler way that this?
 
 struct Hex {}
 immutable Hex hex;
 
 I don't want to introduce two names in the scope, just `hex`. Another 
 attempt:
 
 immutable hex = function {};
 
 That's a bit... arcane. Is there another simple way? Thanks!
 
Not sure about simple or non-arcane, but this works: immutable typeof(new class{}) hex;
Mar 15
next sibling parent Imperatorn <johan_forsberg_86 hotmail.com> writes:
On Monday, 15 March 2021 at 20:07:53 UTC, Timon Gehr wrote:
 On 14.03.21 17:37, Andrei Alexandrescu wrote:
 Is there a simpler way that this?
 
 struct Hex {}
 immutable Hex hex;
 
 I don't want to introduce two names in the scope, just `hex`. 
 Another attempt:
 
 immutable hex = function {};
 
 That's a bit... arcane. Is there another simple way? Thanks!
 
Not sure about simple or non-arcane, but this works: immutable typeof(new class{}) hex;
This is nice because it's actually kinda readable
Mar 15
prev sibling parent Per =?UTF-8?B?Tm9yZGzDtnc=?= <per.nordlow gmail.com> writes:
On Monday, 15 March 2021 at 20:07:53 UTC, Timon Gehr wrote:
 Not sure about simple or non-arcane, but this works:

 immutable typeof(new class{}) hex;
Nice. Would be interesting to list use cases for this in the docs. Moreover typeof(new class{}) is __anonclass1 so, for conformity, typeof(struct {}) should be allowed and be __anonstruct1
Mar 15