digitalmars.D - Showing TypeFunction style
- Stefan Koch (117/117) Oct 02 2020 Hi there,
- Jacob Carlborg (5/10) Oct 03 2020 Not sure if other cares, but your examples will look more appealing if
- Stefan Koch (4/12) Oct 03 2020 Yeah ... I know. It's one of these things I keep putting off.
- Basile B. (13/28) Oct 03 2020 a DIP for TypeFunction requires the parser change. There are two
- Stefan Koch (8/38) Oct 03 2020 Actually, no.
- Basile B. (4/48) Oct 03 2020 calls to type functions have to accept basic types, i.e keywords.
- Basile B. (4/55) Oct 03 2020 not to have a special syntax will make the compiler slower. The
- Stefan Koch (3/13) Oct 03 2020 type functions are supposed to support UFCS.
- Basile B. (8/22) Oct 03 2020 UFCS style still works:
- Timon Gehr (3/27) Oct 03 2020 IMO this is ugly and unnecessary. The distinction between types and
- Stefan Koch (2/22) Oct 04 2020 Yes that's what I meant to say.
- Stefan Koch (27/35) Oct 04 2020 Done now:
Hi there, This evening I played with a partial translation of implicitConversionTargets help in phobos. Here is what I have so far. Note that this is not true transliteration because I wanted to show some of the more unknown type function features. --- alias Bool = bool; alias Ubyte = ubyte; alias Byte = byte; alias Ushort = ushort; alias Short = short; alias Uint = uint; alias Int = int; alias Ulong = ulong; alias Long = long; // for those ty.isFloating is true, which takes a diffrent path than all other types ;) // therefore we can't use it as of now //alias Double = double; //alias Float = float; enum basic_types = makeAliasArray(Bool, Ubyte, Byte, Short, Ushort, Uint, Int, Long, Ulong, /*Double, Float*/); // temporarly needed because parser issues .... auto makeAliasArray(alias[] types ...) { return types; } auto convTargets(alias T) { if (isBasicType(T)) return basicTypeConvTargets(T); return S.init; } bool isBasicType(alias T) { foreach(t;basic_types) { if (is(T == t)) return true; } return false; } // just showing off that you can store type arrays in structs struct S { typeof(makeAliasArray()) result; size_t n; alias type; } auto basicTypeConvTargets(alias T) { typeof(makeAliasArray()) targets; targets.length = basic_types.length; assert(isBasicType(T), "You may not call this function when you don't have a basic type ... (given: " ~ T.stringof ~ ")"); size_t n = 0; foreach(t;basic_types) { if (is(T : t)) { targets[n++] = t; } } return S(targets[0 .. n], n, T); } pragma(msg, convTargets(Long)); // S([(long), (ulong)], 2LU, (long)) pragma(msg, convTargets(Short)); // S([(short), (ushort), (uint), (int), (long), (ulong)], 6LU, (short)) --- I hope that this code will be nice and readable. As a comparison, here is a piece from the template I translated which should be equivalent. --- static if (is(T == bool)) alias ImplicitConversionTargets = AliasSeq!(byte, ubyte, short, ushort, int, uint, long, ulong, CentTypeList, float, double, real, char, wchar, dchar); else static if (is(T == byte)) alias ImplicitConversionTargets = AliasSeq!(short, ushort, int, uint, long, ulong, CentTypeList, float, double, real, char, wchar, dchar); else static if (is(T == ubyte)) alias ImplicitConversionTargets = AliasSeq!(short, ushort, int, uint, long, ulong, CentTypeList, float, double, real, char, wchar, dchar); else static if (is(T == short)) alias ImplicitConversionTargets = AliasSeq!(int, uint, long, ulong, CentTypeList, float, double, real); else static if (is(T == ushort)) alias ImplicitConversionTargets = AliasSeq!(int, uint, long, ulong, CentTypeList, float, double, real); else static if (is(T == int)) alias ImplicitConversionTargets = AliasSeq!(long, ulong, CentTypeList, float, double, real); else static if (is(T == uint)) alias ImplicitConversionTargets = AliasSeq!(long, ulong, CentTypeList, float, double, real); else static if (is(T == long)) alias ImplicitConversionTargets = AliasSeq!(float, double, real); else static if (is(T == ulong)) alias ImplicitConversionTargets = AliasSeq!(float, double, real); --- The behavior is not 100% equivalent as the hand-written target list does not include signed conversions in the same size class. (I assume this is an omission). Please leave comments and suggestions.
Oct 02 2020
On 2020-10-03 00:24, Stefan Koch wrote:// temporarly needed because parser issues .... auto makeAliasArray(alias[] types ...) { return types; }Not sure if other cares, but your examples will look more appealing if you fix the parser. -- /Jacob Carlborg
Oct 03 2020
On Saturday, 3 October 2020 at 07:36:17 UTC, Jacob Carlborg wrote:On 2020-10-03 00:24, Stefan Koch wrote:Yeah ... I know. It's one of these things I keep putting off. You could remove all the aliases from my example if I did fix the parser.// temporarly needed because parser issues .... auto makeAliasArray(alias[] types ...) { return types; }Not sure if other cares, but your examples will look more appealing if you fix the parser.
Oct 03 2020
On Saturday, 3 October 2020 at 08:44:53 UTC, Stefan Koch wrote:On Saturday, 3 October 2020 at 07:36:17 UTC, Jacob Carlborg wrote:a DIP for TypeFunction requires the parser change. There are two possibilities 1. a new keyword 2. use a symbol, e.g like template instanciation with a bang The first soltion is absolutly aweful. It leads to deprecate an identifier, which will delay the feature. The second is more likely what should be adopted. At first glance I'd propose a double bang. string templateStuff = instance!stuff(); string typefuncstuff = callAtCompileTime!!stuff() so after the double bang, the parser can parse a TypeFuntionCallExpr call instead of a CallExpr.On 2020-10-03 00:24, Stefan Koch wrote:Yeah ... I know. It's one of these things I keep putting off. You could remove all the aliases from my example if I did fix the parser.// temporarly needed because parser issues .... auto makeAliasArray(alias[] types ...) { return types; }Not sure if other cares, but your examples will look more appealing if you fix the parser.
Oct 03 2020
On Saturday, 3 October 2020 at 10:05:23 UTC, Basile B. wrote:On Saturday, 3 October 2020 at 08:44:53 UTC, Stefan Koch wrote:Actually, no. You can just have a rule which goes like this. Function calls may accept types. It doesn't change much, since just builtin types are rejected by the parser. Anything else is an unresolved Identifier as far as the parser is concerned.On Saturday, 3 October 2020 at 07:36:17 UTC, Jacob Carlborg wrote:a DIP for TypeFunction requires the parser change. There are two possibilities 1. a new keyword 2. use a symbol, e.g like template instanciation with a bang The first soltion is absolutly aweful. It leads to deprecate an identifier, which will delay the feature. The second is more likely what should be adopted. At first glance I'd propose a double bang. string templateStuff = instance!stuff(); string typefuncstuff = callAtCompileTime!!stuff() so after the double bang, the parser can parse a TypeFuntionCallExpr call instead of a CallExpr.On 2020-10-03 00:24, Stefan Koch wrote:Yeah ... I know. It's one of these things I keep putting off. You could remove all the aliases from my example if I did fix the parser.// temporarly needed because parser issues .... auto makeAliasArray(alias[] types ...) { return types; }Not sure if other cares, but your examples will look more appealing if you fix the parser.
Oct 03 2020
On Saturday, 3 October 2020 at 10:47:47 UTC, Stefan Koch wrote:On Saturday, 3 October 2020 at 10:05:23 UTC, Basile B. wrote:calls to type functions have to accept basic types, i.e keywords. Even if you've made the biggest part of semantic, you still need to specify this.On Saturday, 3 October 2020 at 08:44:53 UTC, Stefan Koch wrote:Actually, no. You can just have a rule which goes like this. Function calls may accept types. It doesn't change much, since just builtin types are rejected by the parser. Anything else is an unresolved Identifier as far as the parser is concerned.On Saturday, 3 October 2020 at 07:36:17 UTC, Jacob Carlborg wrote:a DIP for TypeFunction requires the parser change. There are two possibilities 1. a new keyword 2. use a symbol, e.g like template instanciation with a bang The first soltion is absolutly aweful. It leads to deprecate an identifier, which will delay the feature. The second is more likely what should be adopted. At first glance I'd propose a double bang. string templateStuff = instance!stuff(); string typefuncstuff = callAtCompileTime!!stuff() so after the double bang, the parser can parse a TypeFuntionCallExpr call instead of a CallExpr.On 2020-10-03 00:24, Stefan Koch wrote:Yeah ... I know. It's one of these things I keep putting off. You could remove all the aliases from my example if I did fix the parser.// temporarly needed because parser issues .... auto makeAliasArray(alias[] types ...) { return types; }Not sure if other cares, but your examples will look more appealing if you fix the parser.
Oct 03 2020
On Saturday, 3 October 2020 at 12:28:47 UTC, Basile B. wrote:On Saturday, 3 October 2020 at 10:47:47 UTC, Stefan Koch wrote:not to have a special syntax will make the compiler slower. The expression semantic for a call is already complex, it's better to have a dedicated call with a dedicated syntax for type functions.On Saturday, 3 October 2020 at 10:05:23 UTC, Basile B. wrote:calls to type functions have to accept basic types, i.e keywords. Even if you've made the biggest part of semantic, you still need to specify this.On Saturday, 3 October 2020 at 08:44:53 UTC, Stefan Koch wrote:Actually, no. You can just have a rule which goes like this. Function calls may accept types. It doesn't change much, since just builtin types are rejected by the parser. Anything else is an unresolved Identifier as far as the parser is concerned.On Saturday, 3 October 2020 at 07:36:17 UTC, Jacob Carlborg wrote:a DIP for TypeFunction requires the parser change. There are two possibilities 1. a new keyword 2. use a symbol, e.g like template instanciation with a bang The first soltion is absolutly aweful. It leads to deprecate an identifier, which will delay the feature. The second is more likely what should be adopted. At first glance I'd propose a double bang. string templateStuff = instance!stuff(); string typefuncstuff = callAtCompileTime!!stuff() so after the double bang, the parser can parse a TypeFuntionCallExpr call instead of a CallExpr.On 2020-10-03 00:24, Stefan Koch wrote:Yeah ... I know. It's one of these things I keep putting off. You could remove all the aliases from my example if I did fix the parser.// temporarly needed because parser issues .... auto makeAliasArray(alias[] types ...) { return types; }Not sure if other cares, but your examples will look more appealing if you fix the parser.
Oct 03 2020
On Saturday, 3 October 2020 at 14:16:09 UTC, Basile B. wrote:On Saturday, 3 October 2020 at 12:28:47 UTC, Basile B. wrote:type functions are supposed to support UFCS. How would I do that with the calling syntax you propose?calls to type functions have to accept basic types, i.e keywords. Even if you've made the biggest part of semantic, you still need to specify this.not to have a special syntax will make the compiler slower. The expression semantic for a call is already complex, it's better to have a dedicated call with a dedicated syntax for type functions.
Oct 03 2020
On Saturday, 3 October 2020 at 21:36:20 UTC, Stefan Koch wrote:On Saturday, 3 October 2020 at 14:16:09 UTC, Basile B. wrote:UFCS style still works: size_t SizeOf(alias T){ return T.sizeof; } static assert (SizeOf!!(ubyte) == 1); static assert (ubyte!!SizeOf() == 1); static assert (ubyte!!SizeOf == 1); although you clearly loose the feel that it's like a builtin property.On Saturday, 3 October 2020 at 12:28:47 UTC, Basile B. wrote:type functions are supposed to support UFCS. How would I do that with the calling syntax you propose?calls to type functions have to accept basic types, i.e keywords. Even if you've made the biggest part of semantic, you still need to specify this.not to have a special syntax will make the compiler slower. The expression semantic for a call is already complex, it's better to have a dedicated call with a dedicated syntax for type functions.
Oct 03 2020
On 04.10.20 07:04, Basile B. wrote:On Saturday, 3 October 2020 at 21:36:20 UTC, Stefan Koch wrote:IMO this is ugly and unnecessary. The distinction between types and expressions in the parser is pointless anyway.On Saturday, 3 October 2020 at 14:16:09 UTC, Basile B. wrote:UFCS style still works: size_t SizeOf(alias T){ return T.sizeof; } static assert (SizeOf!!(ubyte) == 1); static assert (ubyte!!SizeOf() == 1); static assert (ubyte!!SizeOf == 1); although you clearly loose the feel that it's like a builtin property.On Saturday, 3 October 2020 at 12:28:47 UTC, Basile B. wrote:type functions are supposed to support UFCS. How would I do that with the calling syntax you propose?calls to type functions have to accept basic types, i.e keywords. Even if you've made the biggest part of semantic, you still need to specify this.not to have a special syntax will make the compiler slower. The expression semantic for a call is already complex, it's better to have a dedicated call with a dedicated syntax for type functions.
Oct 03 2020
On Sunday, 4 October 2020 at 05:14:02 UTC, Timon Gehr wrote:On 04.10.20 07:04, Basile B. wrote:Yes that's what I meant to say.On Saturday, 3 October 2020 at 21:36:20 UTC, Stefan Koch wrote:IMO this is ugly and unnecessary. The distinction between types and expressions in the parser is pointless anyway.On Saturday, 3 October 2020 at 14:16:09 UTC, Basile B. wrote:UFCS style still works: size_t SizeOf(alias T){ return T.sizeof; } static assert (SizeOf!!(ubyte) == 1); static assert (ubyte!!SizeOf() == 1); static assert (ubyte!!SizeOf == 1); although you clearly loose the feel that it's like a builtin property.[...]type functions are supposed to support UFCS. How would I do that with the calling syntax you propose?
Oct 04 2020
On Saturday, 3 October 2020 at 07:36:17 UTC, Jacob Carlborg wrote:On 2020-10-03 00:24, Stefan Koch wrote:Done now: --- alias alias_t = alias; // this is needed because if a declaration starts with alias it is thought to be the old style of alias declaration. //Which is ambiguous ... sigh. alias_t[] makeAliasArray(alias[] array ...) { return array; } pragma(msg, makeAliasArray(int, ulong, void)); // outputs [(int), (ulong), (void)] --- For anyone interested the parser change was actually much more trivial than I would have thought. --- } + // if the type is not followed by a dot then the type is a type expression + if (token.value != TOK.dot) + { + e = new AST.TypeExp(loc, t); + break; + } check(TOK.dot, t.toChars()); ---// temporarly needed because parser issues .... auto makeAliasArray(alias[] types ...) { return types; }Not sure if other cares, but your examples will look more appealing if you fix the parser.
Oct 04 2020