digitalmars.D.learn - A look inside "filter" function defintion
- pascal111 (26/26) Aug 01 2022 This is the definition of "filter" function, and I think it
- frame (8/10) Aug 01 2022 It's a template that defines the function called "Eponymous
- pascal111 (7/18) Aug 02 2022 Instantiation seems some complicated to me. I read "If a template
- frame (15/21) Aug 02 2022 There are obvious examples direct below.
- pascal111 (6/20) Aug 02 2022 I guess you mean if we will understand the templates concept as a
- =?UTF-8?Q?Ali_=c3=87ehreli?= (7/9) Aug 09 2022 I will refer to my explanation because down-to-earth has always been my
- pascal111 (2/12) Aug 09 2022 I'll read this when I'll study template with more details. Thanks!
- Patrick Schluter (11/33) Aug 09 2022 A template is conceptually like a macro with parameters in C. An
- Kyle Ingraham (4/6) Aug 14 2022 I often go back to this post when writing templates:
- Andrey Zherikov (3/7) Aug 02 2022 Create an object of type `FilterResult!(unaryFun!predicate,
- Meta (32/58) Aug 09 2022 To give a vastly simplified answer, the term "eponymous template"
This is the definition of "filter" function, and I think it called itself within its definition. I'm guessing how it works? '''D template filter(alias predicate) if (is(typeof(unaryFun!predicate))) { /** Params: range = An $(REF_ALTTEXT input range, isInputRange, std,range,primitives) of elements Returns: A range containing only elements `x` in `range` for which `predicate(x)` returns `true`. */ auto filter(Range)(Range range) if (isInputRange!(Unqual!Range)) { return FilterResult!(unaryFun!predicate, Range)(range); } } ''' I think this line needs explanation: '''D return FilterResult!(unaryFun!predicate, Range)(range); '''
Aug 01 2022
On Monday, 1 August 2022 at 23:35:13 UTC, pascal111 wrote:This is the definition of "filter" function, and I think it called itself within its definition. I'm guessing how it works?It's a template that defines the function called "Eponymous Templates": https://dlang.org/spec/template.html#implicit_template_properties A template generates code, it cannot be called, only instantiated. The common syntax is just a shortcut for using it. Otherwise you would need to write `filter!(a => a > 0).filter([1, -1, 2, 0, -3])`. Like UFCS, some magic the compiler does for you.
Aug 01 2022
On Tuesday, 2 August 2022 at 04:06:30 UTC, frame wrote:On Monday, 1 August 2022 at 23:35:13 UTC, pascal111 wrote:Instantiation seems some complicated to me. I read "If a template contains members whose name is the same as the template identifier then these members are assumed to be referred to in a template instantiation:" in the provided link, but I'm still stuck. Do you have a down-to-earth example for beginners to understand this concept?This is the definition of "filter" function, and I think it called itself within its definition. I'm guessing how it works?It's a template that defines the function called "Eponymous Templates": https://dlang.org/spec/template.html#implicit_template_properties A template generates code, it cannot be called, only instantiated. The common syntax is just a shortcut for using it. Otherwise you would need to write `filter!(a => a > 0).filter([1, -1, 2, 0, -3])`. Like UFCS, some magic the compiler does for you.
Aug 02 2022
On Tuesday, 2 August 2022 at 12:39:41 UTC, pascal111 wrote:Instantiation seems some complicated to me. I read "If a template contains members whose name is the same as the template identifier then these members are assumed to be referred to in a template instantiation:" in the provided link, but I'm still stuck. Do you have a down-to-earth example for beginners to understand this concept?There are obvious examples direct below. Where do you get stuck? Maybe this helps: A template can be seen as a static struct too, so you can access its members with the scope operator "." and if there is only one member of the same name as the template ifself, the compiler auto completes it to this member. You could always write out `name!(someTemplateArg).name(someRuntimeArg)`, we just prefer the short syntax `name!(someTemplateArg)(someRuntimeArg)` or `name(someRuntimeArg)` (if there are no template arguments or it could be auto deducted by the compiler). The last syntax shows that it can be called as a normal function while in fact it's a template.
Aug 02 2022
On Tuesday, 2 August 2022 at 14:24:50 UTC, frame wrote:On Tuesday, 2 August 2022 at 12:39:41 UTC, pascal111 wrote:I guess you mean if we will understand the templates concept as a static struct that the template is like the struct or - "records" in Pascal - that preserve its members values each time of calling through the runtime because they are "static". Isn't like that or what do you mean?Instantiation seems some complicated to me. I read "If a template contains members whose name is the same as the template identifier then these members are assumed to be referred to in a template instantiation:" in the provided link, but I'm still stuck. Do you have a down-to-earth example for beginners to understand this concept?There are obvious examples direct below. Where do you get stuck? Maybe this helps: A template can be seen as a static struct too, so you can access its members with the scope operator "." and if there is only one member of the same name as the template ifself, the compiler auto completes it to this member.
Aug 02 2022
On Tuesday, 2 August 2022 at 14:58:52 UTC, pascal111 wrote:I don't know anything about Pascal - I can only say that the template scope can be seen like that from a logical point of view. A function defined in a template is a static member of that template but not necessarily static context in runtime. It depends on the usage and scope. But most library functions in Phobos are very simple like that and you have just to know that most functions are templates. They just may not require template arguments to be supplied and others do.Maybe this helps: A template can be seen as a static struct too, so you can access its members with the scope operator "." and if there is only one member of the same name as the template ifself, the compiler auto completes it to this member.I guess you mean if we will understand the templates concept as a static struct that the template is like the struct or - "records" in Pascal - that preserve its members values each time of calling through the runtime because they are "static". Isn't like that or what do you mean?
Aug 02 2022
leyts try very rough simlified concept: template itself - is compile-time program (parameterizable), it can generate some code for you. template instantiation (like "calling") with "!" - instruct compiler to "start this compile-time program here with this parameters".
Aug 03 2022
On 8/2/22 05:39, pascal111 wrote:I'm still stuck. Do you have a down-to-earth example for beginners to understand this concept?I will refer to my explanation because down-to-earth has always been my goal. I hope i succeeded: http://ddili.org/ders/d.en/templates_more.html#ix_templates_more.eponymous%20template However, my chapters assume that previous chapters have already been read. Ali
Aug 09 2022
On Tuesday, 9 August 2022 at 18:23:04 UTC, Ali Çehreli wrote:On 8/2/22 05:39, pascal111 wrote:I'll read this when I'll study template with more details. Thanks!I'm still stuck. Do you have a down-to-earth example for beginners to understand thisconcept? I will refer to my explanation because down-to-earth has always been my goal. I hope i succeeded: http://ddili.org/ders/d.en/templates_more.html#ix_templates_more.eponymous%20template However, my chapters assume that previous chapters have already been read. Ali
Aug 09 2022
On Tuesday, 2 August 2022 at 12:39:41 UTC, pascal111 wrote:On Tuesday, 2 August 2022 at 04:06:30 UTC, frame wrote:A template is conceptually like a macro with parameters in C. An instantiation is like the using of the macro in your C program. The fundamental difference is, that the template is syntactically and semantically linked to the language. In C, the preprocessor was just a textual replacement done before the proper compilation. This meant that there are things that you couldn't do in the pre-processor (like `#if sizeof(int)==4`) and (horrible) things that never should have been possible (I used to use the C pre-processor with other languages like AutoLISP and dBase III).On Monday, 1 August 2022 at 23:35:13 UTC, pascal111 wrote:Instantiation seems some complicated to me. I read "If a template contains members whose name is the same as the template identifier then these members are assumed to be referred to in a template instantiation:" in the provided link, but I'm still stuck. Do you have a down-to-earth example for beginners to understand this concept?This is the definition of "filter" function, and I think it called itself within its definition. I'm guessing how it works?It's a template that defines the function called "Eponymous Templates": https://dlang.org/spec/template.html#implicit_template_properties A template generates code, it cannot be called, only instantiated. The common syntax is just a shortcut for using it. Otherwise you would need to write `filter!(a => a > 0).filter([1, -1, 2, 0, -3])`. Like UFCS, some magic the compiler does for you.
Aug 09 2022
On Tuesday, 2 August 2022 at 12:39:41 UTC, pascal111 wrote:but I'm still stuck. Do you have a down-to-earth example for beginners to understand this concept?I often go back to this post when writing templates: https://dlang.org/blog/2020/07/31/the-abcs-of-templates-in-d/ It helped me when I was first trying to understand them.
Aug 14 2022
On Monday, 1 August 2022 at 23:35:13 UTC, pascal111 wrote:I think this line needs explanation: '''D return FilterResult!(unaryFun!predicate, Range)(range); '''Create an object of type `FilterResult!(unaryFun!predicate, Range)` by passing `range` to its ctor, then return that object.
Aug 02 2022
On Monday, 1 August 2022 at 23:35:13 UTC, pascal111 wrote:This is the definition of "filter" function, and I think it called itself within its definition. I'm guessing how it works? '''D template filter(alias predicate) if (is(typeof(unaryFun!predicate))) { /** Params: range = An $(REF_ALTTEXT input range, isInputRange, std,range,primitives) of elements Returns: A range containing only elements `x` in `range` for which `predicate(x)` returns `true`. */ auto filter(Range)(Range range) if (isInputRange!(Unqual!Range)) { return FilterResult!(unaryFun!predicate, Range)(range); } } ''' I think this line needs explanation: '''D return FilterResult!(unaryFun!predicate, Range)(range); '''To give a vastly simplified answer, the term "eponymous template" essentially means that if you have an item declared inside a template that has a same name as the template: ```D template SomeTemplate(T) { alias SomeTemplate = T; } ``` It is not a compile error. Instead, when you use the template: ```D SomeTemplate!int n; ``` The compiler rewrites your code like to: ```D SomeTemplate!int.SomeTemplate n; ``` Because normally when you instantiate a template, you have to refer to the declarations inside it by name: ```D template SomeOtherTemplate(T) { alias SomeAlias = T; } //SomeOtherTemplate!int n; Error: `SomeOtherTemplate!int` is used as a type SomeOtherTemplate!int.SomeAlias n; //Ok ``` Except in the special case I outlined above. It's essentially a hack that was brought over from C++. It makes using templates more ergonomic.
Aug 09 2022