www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Whence came UFCS?

reply Sameer Pradhan <pradhan cemantix.org> writes:
During our Boston D Meetup today, we went through and 
deconstructed Walter's wonderfully elegant blog post from 2012 
called "Component Programming in D"

http://www.drdobbs.com/article/print?articleId=240008321&siteSectionName=architecture-and-design

I stumbled upon this gem (and another score or so articles on the 
digital mars site) a few days back, while following various 
hyperlinks, within and around the blog on Walter's take on what 
was C's biggest mistake which has been getting a lot of comments 
over the past few days.

This post which I have been trying to digest bit-by-bit over the 
past few days, made me realize why I fell in love with D in the 
first place. To top it all, Steven played a lightening talk from 
2018, called "values as types" by Andreas 
(https://youtu.be/Odj_5_pDN-U?t=21m10s) which is a parody on C++ 
and is so utterly ludicrous, we could not stop laughing.  Anyway, 
back to the point.

During the same period, but independent of the thread on C's 
mistake, I found that Kotlin has something called "Extension 
Functions" and "Extension Properties" 
(https://kotlinlang.org/docs/reference/extensions.html) via. the 
following article on Medium

https://medium.com/ magnus.chatt/why-you-should-totally-switch-to-kotlin-c7bbde9e10d5



What I saw/read seemed eerily familiar. Almost like a "wolf in 
sheeps clothing". The example screamed of UFCS.  Then, later, 
while reading the above Kotlin documentation, I saw a reference 

programming language that I have never heard of before today) 
called Extensions.

Furthermore, I found that Project Lombok 
(https://projectlombok.org/features/experimental/ExtensionMethod) 
has tried to make this idiom/functionality available in Java 
through a  ExtensionMethod annotation. This also almost exactly 
represent UFCS functionality, though much more cludgy, I must say.

Therefore, after reading the word "Extension" in three different 
contexts, I started wondering and various questions came to mind, 
starting with---Whence came UFCS?


b. Was it called UFCS in some other language?
c. Were they not aware of Extensions when they coined UFCS?
d. Are UFCS and Extensions really one and the same thing?
e. If not, what is/are the difference(s)?  And is this why a 
different term/acronym was coined?

As far as I can tell a Google search on UFCS leads to only 
material on D and a Wikipedia entry mentioning Stroustrup and 
Sutter's proposal from 2016 to extend C++ to have this facility. 
It is likely that the Wikipedia article is severely incomplete in 

of Walter's 2012 Dr. Dobbs post which already lists it towards 
the end---in the list of features that D has which allows the 
creation of elegant components---among other dozen or so features.

In the end I thought I might as well dump my thoughts on the D 
forum and hear straight from the horse's (or horses') 
mouth(s)---so to speak.

--
Sameer
Jul 26 2018
next sibling parent Arun Chandrasekaran <aruncxy gmail.com> writes:
On Friday, 27 July 2018 at 03:41:29 UTC, Sameer Pradhan wrote:
 During our Boston D Meetup today, we went through and 
 deconstructed Walter's wonderfully elegant blog post from 2012 
 called "Component Programming in D"

 [...]
I remember reading somewhere that it's inspired from Nim. I might be wrong.
Jul 26 2018
prev sibling next sibling parent reply Joakim <dlang joakim.fea.st> writes:
On Friday, 27 July 2018 at 03:41:29 UTC, Sameer Pradhan wrote:
 During our Boston D Meetup today, we went through and 
 deconstructed Walter's wonderfully elegant blog post from 2012 
 called "Component Programming in D"

 [...]
discussed as a generalization of the concept to free functions at that year's DConf, fully implemented years later: https://forum.dlang.org/thread/htjuut$av2$1 digitalmars.com
Jul 26 2018
parent Joakim <dlang joakim.fea.st> writes:
On Friday, 27 July 2018 at 05:22:17 UTC, Joakim wrote:
 On Friday, 27 July 2018 at 03:41:29 UTC, Sameer Pradhan wrote:
 During our Boston D Meetup today, we went through and 
 deconstructed Walter's wonderfully elegant blog post from 2012 
 called "Component Programming in D"

 [...]
discussed as a generalization of the concept to free functions at that year's DConf, fully implemented years later: https://forum.dlang.org/thread/htjuut$av2$1 digitalmars.com
The DConf slides linked from that old thread list this 2000 Scott Meyers article as an inspiration for UFCS: http://www.drdobbs.com/cpp/how-non-member-functions-improve-encapsu/184401197
Jul 27 2018
prev sibling next sibling parent reply Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
On Friday, July 27, 2018 03:41:29 Sameer Pradhan via Digitalmars-d wrote:
 In the end I thought I might as well dump my thoughts on the D
 forum and hear straight from the horse's (or horses')
 mouth(s)---so to speak.
It evolved out of D's member function call syntax for arrays - basically, for years before we had UFCS in D, we had UFCS for arrays. However, when and how that was added to arrays, I don't know. I don't recall it ever not being in the language, but I never used D1, and I don't know if it had it. At minimum, it's been in D since early D2, if not much earlier. I'd have to do a lot of spelunking through old releases to figure out when it was added. Certainly, the origins of UFCS in D do not come from making it possible to extend user-defined types with member functions. It comes from wanting member function call syntax when using arrays (probably aimed primarily at strings, but I don't know). It's just that later it was proposed to extend it so that it would work with any type and thus make the member function call syntax universal. - Jonathan M Davis
Jul 27 2018
parent reply Simen =?UTF-8?B?S2rDpnLDpXM=?= <simen.kjaras gmail.com> writes:
On Friday, 27 July 2018 at 10:30:07 UTC, Jonathan M Davis wrote:
 It evolved out of D's member function call syntax for arrays - 
 basically, for years before we had UFCS in D, we had UFCS for 
 arrays. However, when and how that was added to arrays, I don't 
 know. I don't recall it ever not being in the language, but I 
 never used D1, and I don't know if it had it. At minimum, it's 
 been in D since early D2, if not much earlier. I'd have to do a 
 lot of spelunking through old releases to figure out when it 
 was added.

 Certainly, the origins of UFCS in D do not come from making it 
 possible to extend user-defined types with member functions. It 
 comes from wanting member function call syntax when using 
 arrays (probably aimed primarily at strings, but I don't know). 
 It's just that later it was proposed to extend it so that it 
 would work with any type and thus make the member function call 
 syntax universal.
This compiles in DMD 0.50 (oldest version on the download page, nov 20, 2002), so I think it's safe to say it's been around for a while: void fun(int[] arr) {} void main() { int[] a; a.fun(); } Arrays' .reverse, .sort and others were added in 0.24, but I can't find a download for anything before 0.50. -- Simen
Jul 27 2018
parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
On 7/27/18 7:24 AM, Simen Kjærås wrote:
 On Friday, 27 July 2018 at 10:30:07 UTC, Jonathan M Davis wrote:
 It evolved out of D's member function call syntax for arrays - 
 basically, for years before we had UFCS in D, we had UFCS for arrays. 
 However, when and how that was added to arrays, I don't know. I don't 
 recall it ever not being in the language, but I never used D1, and I 
 don't know if it had it. At minimum, it's been in D since early D2, if 
 not much earlier. I'd have to do a lot of spelunking through old 
 releases to figure out when it was added.

 Certainly, the origins of UFCS in D do not come from making it 
 possible to extend user-defined types with member functions. It comes 
 from wanting member function call syntax when using arrays (probably 
 aimed primarily at strings, but I don't know). It's just that later it 
 was proposed to extend it so that it would work with any type and thus 
 make the member function call syntax universal.
This compiles in DMD 0.50 (oldest version on the download page, nov 20, 2002), so I think it's safe to say it's been around for a while: void fun(int[] arr) {} void main() {     int[] a;     a.fun(); } Arrays' .reverse, .sort and others were added in 0.24, but I can't find a download for anything before 0.50.
Reverse and sort were properties (compiler built-ins), not extensions. If it existed in 2002, it's safe to say it was there pretty much from the beginning. -Steve
Jul 27 2018
next sibling parent reply Simen =?UTF-8?B?S2rDpnLDpXM=?= <simen.kjaras gmail.com> writes:
On Friday, 27 July 2018 at 13:38:26 UTC, Steven Schveighoffer 
wrote:
 On 7/27/18 7:24 AM, Simen Kjærås wrote:
 Arrays' .reverse, .sort and others were added in 0.24, but I 
 can't find a download for anything before 0.50.
Reverse and sort were properties (compiler built-ins), not extensions. If it existed in 2002, it's safe to say it was there pretty much from the beginning.
From what I recall, UFCS for arrays were essentially a bug - an unintended side effect of how the properties were implemented. But it's been 15 years, so I can't really trust my memory. :p -- Simen
Jul 27 2018
next sibling parent reply Mike Parker <aldacron gmail.com> writes:
On Friday, 27 July 2018 at 14:09:02 UTC, Simen Kjærås wrote:

 From what I recall, UFCS for arrays were essentially a bug - an 
 unintended side effect of how the properties were implemented. 
 But it's been 15 years, so I can't really trust my memory. :p
You're not alone! That's how I remember it as well.
Jul 27 2018
parent reply Mike Parker <aldacron gmail.com> writes:
On Friday, 27 July 2018 at 14:12:53 UTC, Mike Parker wrote:
 On Friday, 27 July 2018 at 14:09:02 UTC, Simen Kjærås wrote:

 From what I recall, UFCS for arrays were essentially a bug - 
 an unintended side effect of how the properties were 
 implemented. But it's been 15 years, so I can't really trust 
 my memory. :p
You're not alone! That's how I remember it as well.
This is the earliest thread I could find in the archives, based solely on searching for "array" in the title. I almost fell down the rabbit hole reading some of those old threads, as the ones I did look at tickled my memory. Fortunately, I caught myself in time. https://digitalmars.com/d/archives/digitalmars/D/16452.html
Jul 27 2018
parent Mike Parker <aldacron gmail.com> writes:
On Friday, 27 July 2018 at 14:31:24 UTC, Mike Parker wrote:

 This is the earliest thread I could find in the archives, based 
 solely on searching for "array" in the title. I almost fell 
 down the rabbit hole reading some of those old threads, as the 
 ones I did look at tickled my memory. Fortunately, I caught 
 myself in time.

 https://digitalmars.com/d/archives/digitalmars/D/16452.html
And even earlier: https://digitalmars.com/d/archives/digitalmars/D/9779.html
Jul 27 2018
prev sibling next sibling parent Steven Schveighoffer <schveiguy gmail.com> writes:
On 7/27/18 10:09 AM, Simen Kjærås wrote:
 On Friday, 27 July 2018 at 13:38:26 UTC, Steven Schveighoffer wrote:
 On 7/27/18 7:24 AM, Simen Kjærås wrote:
 Arrays' .reverse, .sort and others were added in 0.24, but I can't 
 find a download for anything before 0.50.
Reverse and sort were properties (compiler built-ins), not extensions. If it existed in 2002, it's safe to say it was there pretty much from the beginning.
From what I recall, UFCS for arrays were essentially a bug - an unintended side effect of how the properties were implemented. But it's been 15 years, so I can't really trust my memory. :p
Heh, that pre-dates my D lifetime. Interesting if it was a bug! -Steve
Jul 27 2018
prev sibling parent reply Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
On Friday, July 27, 2018 8:09:02 AM MDT Simen Kjrs via Digitalmars-d 
wrote:
 On Friday, 27 July 2018 at 13:38:26 UTC, Steven Schveighoffer

 wrote:
 On 7/27/18 7:24 AM, Simen Kjrs wrote:
 Arrays' .reverse, .sort and others were added in 0.24, but I
 can't find a download for anything before 0.50.
Reverse and sort were properties (compiler built-ins), not extensions. If it existed in 2002, it's safe to say it was there pretty much from the beginning.
From what I recall, UFCS for arrays were essentially a bug - an unintended side effect of how the properties were implemented. But it's been 15 years, so I can't really trust my memory. :p
I vaguely recall the whole property thing being a bug, but I don't trust my memory on that at this point. - Jonathan M Davis
Jul 27 2018
parent Sameer Pradhan <pradhan cemantix.org> writes:
Wow! I am glad to see so many responses!  Thanks for your 
indulgence.

So, to summarize, the concept (no pun intended) has been around 
for a while in D---originally in the context of arrays. It just 
might have been a bug, or an unintended side-effect. I intend to 
read the archival posts and might have something to say later.

--
Sameer

PS: I realize that I am a stickler for history, or rather 
historical contexts related to technology or research that I am 
involved in, and more recently regarding programming language 
concepts.  The culprit is probably the fact that I have been 
teaching programming languages course (or, taught one semester of 
it, and plan to teach it again in Spring) which has allowed me to 
learn of the origins of so many concepts which we sometimes take 
for granted today, but were part of some old languages.

PS1: I didn't want to respond to a particular thread, but there 
is no way in this forum to write a generic response to multiple 
posts so I am picking one as the anchor.
Jul 27 2018
prev sibling parent Mike Parker <aldacron gmail.com> writes:
On Friday, 27 July 2018 at 13:38:26 UTC, Steven Schveighoffer 
wrote:


 Reverse and sort were properties (compiler built-ins), not 
 extensions. If it existed in 2002, it's safe to say it was 
 there pretty much from the beginning.

 -Steve
I came to D in 2003. I recall this coming up in the forums now and again by people discovering it for the first time and wondering why it only worked with arrays. I remember thinking it was a pretty big deal when it was expanded to work in the general case. I'm sure I wrote about it on my old blog, but now I can't find my database backup to verify.
Jul 27 2018
prev sibling next sibling parent "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Fri, Jul 27, 2018 at 03:41:29AM +0000, Sameer Pradhan via Digitalmars-d
wrote:
[...]
 Whence came UFCS?
[...] As far as I know, UFCS came about from a particular interpretation of TDPL (Andrei's book). Andrei was talking about the range API, and inserted a little note about how native arrays can be made into ranges by adopting the convention that if: arr.func(...) cannot be resolved as a member function, then the compiler would rewrite it as: func(arr, ...) instead. This would then allow generic code to be written as: while (r.empty) { doSomething(r.front); r.popFront(); } without needing to special case the code for native arrays. Initially, this was only implemented for arrays as a special case, and some people read Andrei's description as applying only to arrays. However, others (including myself) read it as a general principle that ought to apply to all types, even though at the time the compiler had only implemented this for the array case. After quite a lot of debate, eventually somebody (I believe it was Kenji -- man I still miss that guy) implemented a PR for it, and after quite a bit more controversy, the PR was merged. That was when UFCS became a reality. The rest, as they say, was history. T -- People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird. -- D. Knuth
Jul 27 2018
prev sibling next sibling parent Jesse Phillips <Jesse.K.Phillips+D gmail.com> writes:
On Friday, 27 July 2018 at 03:41:29 UTC, Sameer Pradhan wrote:
 Therefore, after reading the word "Extension" in three 
 different contexts, I started wondering and various questions 
 came to mind, starting with---Whence came UFCS?
The answer I always say back in the day for the functionality was that it was a bug for arrays. The term UFCS though is much newer and just comes from discussion for applying the array bug to all types. Who started it, why it caught on I don't know. The use of the term Extension I believe is because of the implementation/syntax approach used to describe this behavior in new class with static methods. This makes the new class act as an "extension" of another object. D having free functions and the functionality working on more than objects means "Extension" wouldn't be a good term to describe it.
Jul 27 2018
prev sibling parent Meta <jared771 gmail.com> writes:
On Friday, 27 July 2018 at 03:41:29 UTC, Sameer Pradhan wrote:
 During our Boston D Meetup today, we went through and 
 deconstructed Walter's wonderfully elegant blog post from 2012 
 called "Component Programming in D"

 http://www.drdobbs.com/article/print?articleId=240008321&siteSectionName=architecture-and-design

 I stumbled upon this gem (and another score or so articles on 
 the digital mars site) a few days back, while following various 
 hyperlinks, within and around the blog on Walter's take on what 
 was C's biggest mistake which has been getting a lot of 
 comments over the past few days.

 This post which I have been trying to digest bit-by-bit over 
 the past few days, made me realize why I fell in love with D in 
 the first place. To top it all, Steven played a lightening talk 
 from 2018, called "values as types" by Andreas 
 (https://youtu.be/Odj_5_pDN-U?t=21m10s) which is a parody on 
 C++ and is so utterly ludicrous, we could not stop laughing.  
 Anyway, back to the point.

 During the same period, but independent of the thread on C's 
 mistake, I found that Kotlin has something called "Extension 
 Functions" and "Extension Properties" 
 (https://kotlinlang.org/docs/reference/extensions.html) via. 
 the following article on Medium

 https://medium.com/ magnus.chatt/why-you-should-totally-switch-to-kotlin-c7bbde9e10d5



 What I saw/read seemed eerily familiar. Almost like a "wolf in 
 sheeps clothing". The example screamed of UFCS.  Then, later, 
 while reading the above Kotlin documentation, I saw a reference 

 a programming language that I have never heard of before today) 
 called Extensions.

 Furthermore, I found that Project Lombok 
 (https://projectlombok.org/features/experimental/ExtensionMethod) has tried to
make this idiom/functionality available in Java through a  ExtensionMethod
annotation. This also almost exactly represent UFCS functionality, though much
more cludgy, I must say.

 Therefore, after reading the word "Extension" in three 
 different contexts, I started wondering and various questions 
 came to mind, starting with---Whence came UFCS?


 b. Was it called UFCS in some other language?
 c. Were they not aware of Extensions when they coined UFCS?
 d. Are UFCS and Extensions really one and the same thing?
 e. If not, what is/are the difference(s)?  And is this why a 
 different term/acronym was coined?

 As far as I can tell a Google search on UFCS leads to only 
 material on D and a Wikipedia entry mentioning Stroustrup and 
 Sutter's proposal from 2016 to extend C++ to have this 
 facility. It is likely that the Wikipedia article is severely 
 incomplete in its historical connections as there is no mention 

 lists it towards the end---in the list of features that D has 
 which allows the creation of elegant components---among other 
 dozen or so features.

 In the end I thought I might as well dump my thoughts on the D 
 forum and hear straight from the horse's (or horses') 
 mouth(s)---so to speak.

 --
 Sameer
I remember reading an article that Andrei wrote a long time ago that cited an older language as the inspiration for UFCS, but it was probably from around 2007 where UFCS for arrays was already well-established (I never knew that it was actually a bug at one point). I don't remember what that language was unfortunately.
Jul 27 2018