March 09, 2012
On Friday, March 09, 2012 18:39:25 Steven Schveighoffer wrote:
> I want to stress again the difference between C++'s namespaces, and D's module import mechanism. In C++, you *deliberately* pull a namespace into your scope (and usually only in the implementation file, which doesn't affect any other implementation files), whereas in D, a standard "import std.datetime" *automatically* pulls its namespace into your scope, and any public imports it has made.

Yeah. D has great tools for getting around conflicts, but things tend to conflict by default, which means that it's very easy to break code by introducing conflicts when adding functions.

- Jonathan M Davis
March 09, 2012
On Fri, Mar 9, 2012 at 4:45 PM, Jonathan M Davis <jmdavisProg@gmx.com>wrote:

> On Friday, March 09, 2012 18:39:25 Steven Schveighoffer wrote:
> > I want to stress again the difference between C++'s namespaces, and D's module import mechanism. In C++, you *deliberately* pull a namespace into your scope (and usually only in the implementation file, which doesn't affect any other implementation files), whereas in D, a standard "import std.datetime" *automatically* pulls its namespace into your scope, and
> any
> > public imports it has made.
>
> Yeah. D has great tools for getting around conflicts, but things tend to conflict by default, which means that it's very easy to break code by introducing conflicts when adding functions.
>
>
Hmm, fair enough.  In our case they were essentially pulled into the global namespace due to some questionable decisions with regard to namespaces made in our project.  The difference between D and C++ is important to point out though so thanks for clarifying.

Regards,
Brad Anderson


> - Jonathan M Davis
>


March 09, 2012
Jonathan M Davis:

> I don't know what the current state of UFCS is.

I have found a possible problem in it, and probably there are some missing parts, but it's working well.

At first I didn't like it a lot because it's cheap syntax sugar that adds no new power and gives programmers more freedom to write different-looking versions of the the same code (and this is often bad). But I have soon found that it's able to make functional-style code more readable, because you write:
x.foo().bar().baz().spam()

Instead of this, where my eye sometimes loses count of the nesting level:
spam(baz(bar(foo(x))))

Bye,
bearophile
March 09, 2012
On Fri, Mar 09, 2012 at 04:30:11PM -0700, Brad Anderson wrote:
> On Fri, Mar 9, 2012 at 4:24 PM, Jonathan M Davis <jmdavisProg@gmx.com>wrote:
[...]
> > I don't know what the current state of UFCS is. I know that Kenji has been working on it and that at least some portion of it has been checked in, but what exactly it enables at this point, I don't know.
[...]
> Here are the unittests he added if you are curious about what
> currently works in dmd HEAD:
> https://github.com/D-Programming-Language/dmd/blob/master/test/runnable/ufcs.d

Wow, 2.5.twice==5.0 works now? So does 2.5.sqrt()! And pseudo-members for structs!  And classes!  Amazing!  Kudos to Kenji!


T

-- 
Question authority. Don't ask why, just do it.
March 10, 2012
On Fri, Mar 09, 2012 at 06:50:50PM -0500, bearophile wrote:
> Jonathan M Davis:
> 
> > I don't know what the current state of UFCS is.
> 
> I have found a possible problem in it, and probably there are some missing parts, but it's working well.

I found that x.foo doesn't work, it needs to be x.foo(). But we're deprecating omission of parentheses of non-@property functions anyway, and an external function can hardly be a @property of anything, so I don't think this needs to be fixed.


> At first I didn't like it a lot because it's cheap syntax sugar that adds no new power and gives programmers more freedom to write different-looking versions of the the same code (and this is often bad).

But it also allows you to write pseudo-members for generic templates that want to access built-in types via some abstract interface. This makes template code much much cleaner.


> But I have soon found that it's able to make functional-style code
> more readable, because you write:
> x.foo().bar().baz().spam()
> 
> Instead of this, where my eye sometimes loses count of the nesting level:
> spam(baz(bar(foo(x))))
[...]

Personally, I find the chained syntax rather jarring if the object of each . is different. I'm OK with things like jQuery where the base object is always the same, but if it changes across the .'s, it can get confusing to read.

OTOH, this is a refreshing change from centuries of silly backwards function notation that we inherited from math, so maybe this is a good thing after all. :-)


T

-- 
Always remember that you are unique. Just like everybody else. -- despair.com
March 10, 2012
On Friday, March 09, 2012 18:50:50 bearophile wrote:
> Jonathan M Davis:
> > I don't know what the current state of UFCS is.
> 
> I have found a possible problem in it, and probably there are some missing parts, but it's working well.
> 
> At first I didn't like it a lot because it's cheap syntax sugar that adds no new power and gives programmers more freedom to write different-looking versions of the the same code (and this is often bad).

Which is one of the reasons that I really don't like the idea. Sometimes it's nice with strings, but it creates inconsistencies, and stuff like 5.max(7) just seems insane. UFCS will give people more freedom and may help templates in some cases, but I think that it's a major step back for readibility in general.

> But I have soon
> found that it's able to make functional-style code more readable, because
> you write: x.foo().bar().baz().spam()
> 
> Instead of this, where my eye sometimes loses count of the nesting level:
> spam(baz(bar(foo(x))))

I must be in the minority in that I find chaining with UFCS to be _harder_ to read than the more traditional way. It just feels insanely backwards to me. But some people definitely seem to prefer the UFCS chaining. YMMV.

- Jonathan M Davis
March 10, 2012
On Saturday, 10 March 2012 at 00:16:14 UTC, Jonathan M Davis wrote:
> UFCS will give people more freedom and may help templates in
> some cases, […]

Note aside: I think people tend to overestimate the amount of generic code that becomes easier to write/extend with UFCS, as D, in contrast to C++, doesn't have ADL.

David
March 10, 2012
On Friday, 9 March 2012 at 23:39:25 UTC, Steven Schveighoffer wrote:
> I want to stress again the difference between C++'s namespaces, and D's module import mechanism.  In C++, you *deliberately* pull a namespace into your scope (and usually only in the implementation file, which doesn't affect any other implementation files), whereas in D, a standard "import std.datetime" *automatically* pulls its namespace into your scope, and any public imports it has made.

To be honest, I don't quite see the big difference here. Just as you can only #include a »namespaced« file without using a using directive, you can »static import« a module in D. You seem to be arguing that we shouldn't encourage use of these features (cf. the std.log discussion), but I can't quite follow you there.

Why would _not_ using static and selective imports be desirable? Don't we generally discourage people from write »using namespace std« in C++ or »import *« in Python as well? (I'm aware that the D module system is different, but the general idea is the same)

David
March 10, 2012
On Saturday, March 10, 2012 01:22:49 David Nadlinger wrote:
> On Saturday, 10 March 2012 at 00:16:14 UTC, Jonathan M Davis
> 
> wrote:
> > UFCS will give people more freedom and may help templates in some cases, […]
> 
> Note aside: I think people tend to overestimate the amount of generic code that becomes easier to write/extend with UFCS, as D, in contrast to C++, doesn't have ADL.

That wouldn't surprise me at all. But then again, aside from using
arrays as ranges, I don't recall _ever_ running into a function in D where
a user-defined type had a member function with that name, and a free
function had that name, and I wanted to call that function in a template and
therefore had to use static ifs to separate the two. So, personally, I don't
think that it will help me _at all_. I can see there being a few cases where
it would though. If C++ had it, then could have implemented begin and end
differently and not have to try and get everyone to switch over to using the
free function versions for C++11. And in the case of arrays, having that sort
of syntax has been _very_ useful for ranges.

But I don't buy that that's really the case for other primitive types (certainly not frequently), and unless you don't control the user-defined type that you're trying to operate on, you'd just put the function on the type itself when dealing with a user-defined type.

So, it'll probably help _some_, but I think that there's a good chance that you're right and that it won't be as useful as some people are expecting. But for better or worse, it looks like we're getting it.

- Jonathan M Davis
March 10, 2012
On 03/10/2012 01:10 AM, H. S. Teoh wrote:
> On Fri, Mar 09, 2012 at 06:50:50PM -0500, bearophile wrote:
>> Jonathan M Davis:
>>
>>> I don't know what the current state of UFCS is.
>>
>> I have found a possible problem in it, and probably there are some
>> missing parts, but it's working well.
>
> I found that x.foo doesn't work, it needs to be x.foo(). But we're
> deprecating omission of parentheses of non-@property functions anyway,
> and an external function can hardly be a @property of anything, so I
> don't think this needs to be fixed.
>

UFCS for @properties seems to work according to the unit tests.
However, this makes @property ambiguous. foo = 2 will be the same as 2.foo.