March 30, 2012
On Fri, 30 Mar 2012 02:42:03 -0400, Walter Bright <newshound2@digitalmars.com> wrote:

> On 3/29/2012 6:57 PM, Nick Sabalausky wrote:
>> How the heck does that improve encapsualtion? With D's implicit friends, it
>> *doesn't*, it's just shifting things around. There is NO encapsualtion
>> benefit there. Like Steven said, to *get* the encapsualtion, you have to
>> create a whole new module to stick "extraFunctionality" into.
>
> It doesn't improve intra-module encapsulation, you're right. The point of UFCS, however, is so that *other* modules can extend a class's methods without breaking encapsulation.

This is misleading, the class being extended or the code that uses the extensions must import the extension methods or it doesn't work.

The OP to this sub-thread brought up your example in the article -- adding range functions to a class.  Yes, you can do it, but it won't work with std.algorithm.  There's no need to test this, because it fundamentally cannot work that way (see my counter-case).

-Steve
March 30, 2012
On Friday, 30 March 2012 at 10:22:18 UTC, Walter Bright wrote:
> On 3/30/2012 2:15 AM, Nick Sabalausky wrote:
>>> Andrei and I have  talked about it, and we think it is because of
>>> difficulties in breaking a module up into submodules of a package.
>>> We think it's something we need to address.
>>
>> Eh? Other people have voiced concerns over that since waaay back in even
>> pre-D1 times. In particular, many people have argued for allowing modules
>> with the same name as a package. Ie: you could have both module "foo" and
>> module "foo.bar". The reasons they gave for wanting this are right along the
>> lines of what you're talking about here. Eventually they got the message
>> that it wasn't gonna happen and they gave up asking for it.
>>
>> Or is there a separate problem you're refering to?
>
> No, that's it. What brings it to the fore is, as I said, the kitchen-sink module that is becoming prevalent.

I'm confused. I thought that The kitchen-sink approach was a deliberate design decision. I also don't see how the language is at fault here - some libraries opted for a all.d module that public imports the other modules which cleanly solves the problem.

This can be trivially solved by a convention of adding a _.d or all.d or whatever agreed upon module at the package level. Sure, the above mentioned enhancement will remove the need for this extra tiny step. But this is merely eliminating a minor inconvenience, not some huge flaw of the language that prevents good design and proper organization.
March 30, 2012
On Fri, 30 Mar 2012 04:21:12 -0400, Nick Sabalausky <a@a.a> wrote:

> "Nick Sabalausky" <a@a.a> wrote in message
> news:jl3n59$qf7$1@digitalmars.com...

>>
>> Yea, I've seen that. It's a very good article, though. Although I've been
>> saying this since before that article, and even before multi-cores.
>> Contrary to the title, I wasn't at all surprised which won ;)
>>
>> Of course, I don't expect software to be as super-fine-tuned as it was on,
>> say, the Apple 2 or Atari 2600. There *is* definitely some value in
>> loosing a certain amount of performance to abstractions, up to a point.
>> But we've blown way, way, WAAAY beyond that point.
>>
>> It's sickening how much gratuitous waste there is in a lot of "modern"
>> software, and really for not much benefit, as D proves.

100% agree.  There has been a huge trend in software to disregard performance because "the hardware will take care of it."  Interestingly enough though, performance still turns heads :)  That is, when faced with two applications that do the same thing, but one is twice as fast, most people will choose (and probably pay more for) the faster one.

> Actually, one thing that really gets me is shutdown times: RAM is
> *volitile*. How much processing can really be needed when the RAM's just
> gonna get wiped anyway? You ask the user if they want to save, you flush the
> output queues for anything non-volitile, and you cut the power. Sheesh!

One of the things I was extremely impressed with on my new macbook is that it usually shuts down in under 2 seconds.

> Desktops are the worst offenders, and paricularly WinXP.

Windows 7 is vastly better at both startup and shutdown than WinXP.  I think part of the problem is that shutdown on these systems defers to the user applications.  Sometimes I shutdown, and come back the next day to find it was still asking me some questions.  Grrrr.  Now I have to answer the questions, let it power off, then power back on again.  The apps should save enough state so they can resume the next day without issue (this is how the mac seems to work, and I love it).

> But then even on my
> brother's PS3, you can literally count the seconds before it actually turns
> off. It's just a set-top gaming console, is that really necessary? (They can
> spare me their "It does everything!" - like I give a crap about any of those
> gimmicks.) On my old (super-low-power) NES, you could hit the power button,
> and within one second you were at the title screen.

You must have had a different version of NES.  The process to start mine up was not nearly as fast.  It went something like this:

1. Insert cartridge, push down cartridge, power on.  (I cite this as one step because it became automatic to do this in 2 seconds)
2. Screen with horribly large pixellated game appears.
3. Power off, pull out cartridge.
4. Blow in bottom of cartridge, even though the pins are clean and free of dust (did this actually ever do anything?)
5. Re-insert cartridge, this time more firmly, push down deliberately to make sure game locks into place
6. Power on, normal screen comes up, push start button.
7. Play for about 2 minutes, game hangs with single audio tone.
8. Bang hand on top of NES to show it you mean business.  Sometimes it will whimper back to playing mode.
9. After second hang, attempt to press reset button about 15 times.  Peanut-sized pixels return.
10. Power off, remove catridge, repeat blowing procedure from step 4, but with slower more deliberate breath.  Try a blowing pattern, like quick bursty blows in various locations.  Insert cartidge even MORE firmly.  Jiggle cartridge a bit to make sure the NES is aware there is a valid game for it to consume.
11. Lower cartridge, power on.  Play game for another 5 minutes.
12. After next hang, turn power off, and watch cartoons.

I exaggerate a bit :)  But sometimes I swear it was like this.  I don't miss those days, though I don't get to play many video games these days.  I'm waiting for my kids to get old enough to play them so I can mooch off of their video game time :)

> Some of that stuff isn't even a technical matter at all, but deliberate
> design: Who the hell decided we need twenty company logos (fully animated,
> one at a time), then 10+ minutes of exposition and building "atmosphere",
> followed by half an hour of (typically patronizing) tutorials before
> actually getting to the real gameplay? Zelda Skyward Sword is the worst
> offender, it literally takes *hours* to get past all the initial exposition,
> tutorials and shit into the real core of the game (I honestly started
> wondering if there even *was* a game - "Did I pick up a Harry Potter movie
> by mistake?"). The original Zelda, you could get from power off to the meat
> of the gameplay in literally seconds. Game devs won't let you do that now:
> They've gotta show off their cinematography so they can get hired by Pixar,
> where they *really* wanted to be all along. (Meh, Dreamworks was always
> better anyway ;) )

When I bought the new Wii motion plus (that gives better sensitivity) with Wii Sports Resort, the first time you play, it makes you watch 8 minutes of instructional video on how to use your Wii motion plus.  I thought at the time "Wow, that was a bit long, but I guess I only have to do it once."  Then I went to my sister-in-law's house, and wanted to show her the game.  This was *her* Wii's first time playing the game, so again, I had to watch the damn video (no way to skip).  It happened a third time on my parents' Wii, and I was thinking "Man, this was a *bad* design decision".

-Steve
March 30, 2012
Walter Bright wrote:
> On 3/29/2012 5:09 PM, Steven Schveighoffer wrote:
>> The reason being, if you change anything in class A, you do not have
>> to worry
>> about the implementation of getXSquared, because it simply has no
>> access to the
>> private implementation. You only have to worry about internal methods,
>> and
>> friend functions.
>
> Ok, I see what you're talking about. It has nothing to do with UFCS, it
> is D's design decision to not have explicit friends, but to make
> everything in a module implicitly a friend.
>
> I think it's far superior to the explicit friend thing in C++.

Just curious. Did you take it from Delphi? :-)
March 30, 2012
On 2012-03-30 10:20, Walter Bright wrote:

> There has been a trend in Phobos of having some truly gigantic modules.
> I believe this is indicative of a problem in the language. Andrei and I
> have talked about it, and we think it is because of difficulties in
> breaking a module up into submodules of a package.
>
> We think it's something we need to address.

I don't know for HOW LONG I've been saying this. The modules in Phobos are way too large. I always thought this was a design decision, that you wanted a flat hierarchy of modules in Phobos.

But I don't think it's a problem with the language. I've been splitting up my code in several sub packages and modules for as long as I've been using D. Just move the code to new modules. It can take some time to figure out how to best organize the modules but when that's finished there should be any problems.

-- 
/Jacob Carlborg
March 30, 2012
Le 30/03/2012 11:40, bls a écrit :
> On 03/30/2012 02:15 AM, Nick Sabalausky wrote:
>> Eh? Other people have voiced concerns over that since waaay back in even
>> pre-D1 times. In particular, many people have argued for allowing modules
>> with the same name as a package. Ie: you could have both module "foo" and
>> module "foo.bar".
>
> This is afaik similar to ADA child packages.
> Quote :
> Ada allows one to extend the functionality of a unit (package) with
> so-called children (child packages). With certain exceptions, all the
> functionality of the parent is available to a child. This means that all
> public and private declarations of the parent package are visible to all
> child packages.

This sound interesting. And why not use public import for that ? It wouldn't break any existing code, because it enlarge the field of possibles.
March 30, 2012
Le 30/03/2012 12:57, foobar a écrit :
> On Friday, 30 March 2012 at 10:22:18 UTC, Walter Bright wrote:
>> On 3/30/2012 2:15 AM, Nick Sabalausky wrote:
>>>> Andrei and I have talked about it, and we think it is because of
>>>> difficulties in breaking a module up into submodules of a package.
>>>> We think it's something we need to address.
>>>
>>> Eh? Other people have voiced concerns over that since waaay back in even
>>> pre-D1 times. In particular, many people have argued for allowing
>>> modules
>>> with the same name as a package. Ie: you could have both module "foo"
>>> and
>>> module "foo.bar". The reasons they gave for wanting this are right
>>> along the
>>> lines of what you're talking about here. Eventually they got the message
>>> that it wasn't gonna happen and they gave up asking for it.
>>>
>>> Or is there a separate problem you're refering to?
>>
>> No, that's it. What brings it to the fore is, as I said, the
>> kitchen-sink module that is becoming prevalent.
>
> I'm confused. I thought that The kitchen-sink approach was a deliberate
> design decision. I also don't see how the language is at fault here -
> some libraries opted for a all.d module that public imports the other
> modules which cleanly solves the problem.
>
> This can be trivially solved by a convention of adding a _.d or all.d or
> whatever agreed upon module at the package level. Sure, the above
> mentioned enhancement will remove the need for this extra tiny step. But
> this is merely eliminating a minor inconvenience, not some huge flaw of
> the language that prevents good design and proper organization.

all.d this the de facto standard here. I think it should become an official guideline.
March 30, 2012
Le 30/03/2012 01:34, Steven Schveighoffer a écrit :
> On Wed, 28 Mar 2012 21:53:57 -0400, Jesse Phillips
> <jessekphillips+D@gmail.com> wrote:
>
>> I won't be going out of my way to check this, but there is a mention
>> of adding the range primatives. This works, but it doesn't make the
>> class a range for any other module, so std.algorithms won't recogonise
>> it as a range.
>
> At first thought, I believed this should be fixable -- if not working
> already. Consider that std.algorithm doesn't include *your* module, yet
> you can pass types defined in your module into std.algorithm and it
> works just fine.
>
> But I realized after typing about 2 messages in response to this (and
> deleting them), you are right, there is a fundamental problem here.
> Because the template instantiation is based solely on the type. It does
> *not* include the type and whatever other modules you may have included
> that could define extension methods. I don't think it's an
> implementation issue, I think it's a design issue -- there simply is no
> way to do this.
>
> A counter case:
>
> module1.d:
>
> int foo(T)(T t)
> {
> return t.bar();
> }
>
> module2.d:
>
> struct S { int x;}
>
> module3.d:
>
> import module1, module2;
>
> int bar(S s) { return s.x * 2;}
>
> void baz1()
> {
> S s(2);
> assert(foo(s) == 4);
> }
>
> module4.d:
>
> import module1, module 2;
>
> int bar(S s) { return s.x * 3;}
>
> void baz2()
> {
> S s(2);
> assert(foo(s) == 6);
> }
>
> // and to drive the point further:
> module5.d:
> import module3, module4;
>
> void main()
> {
> baz1();
> baz2();
> }
>
> In order for the asserts to *both* pass, there has to be two different
> instantiations of foo!S, one for module3, and one for module4.
>
> So two possible sane rules:
> 1. A template instantiation can *only* use UFCS from functions defined
> in or imported from the module in which the template is defined. (i.e.
> the way it works now I think)
> or
> 2. A template instantiation can *only* use UFCS from functions defined
> in or imported from the module in which the template is defined, *and*
> from functions as defined or imported by the module that defines the
> type on which UFCS is being used. In other words, from my example above,
> only functions defined in or imported from module1.d and module2.d.
> Therefore, the bar extension defined in module3 and module4 cannot be
> called from module1.
>
> For builtin types (such as arrays or numbers), there wouldn't be a
> module that the type was defined. However, object.di is imported by
> everything, so extensions could be put in there.
>
> This kind of puts a damper on certain expectations for how UFCS could be
> used. But I don't see any other way (other than adding the current
> module into the instantiation somehow -- imagine the template bloat...).
>
> Even with this limitation, UFCS still allows a lot of cool things. One
> misleading suggestion from the article however, it's not very easy to
> create non-friend non-member functions using UFCS, considering that
> every function in a given module is a friend. In order to do this, you
> would need a helper module for each module that wants to define such
> non-friend functions. Given the above proof, the helper module would
> also have to be imported by the main module.
>
> -Steve

I would expect this not to work, because bar isn't defined in module1 and template are supposed to use declaration scope, not instantiation scope (unless it is mixin template).
March 30, 2012
On 2012-03-30 10:36, Andrej Mitrovic wrote:
> On 3/30/12, Walter Bright<newshound2@digitalmars.com>  wrote:
>> There has been a trend in Phobos of having some truly gigantic modules. I
>> believe this is indicative of a problem in the language.
>
> Ignoring that there are still a few import bugs, you can split
> functionality into multiple modules and use one module per package
> that publicly imports all modules in that package:
>
> module std.datetime;
> public import std.date.time, std.date.clock, std.date.watch;

I agree.

> That's what people are already doing with various D libraries.
> Then, unittests could be moved into a central place.

Yeah, that's working just fine.

> I think that
> could cut down the linecount quite a bit. If linecount is still a
> problem after that, then either the modules have to be further split
> or it might be an indication that Phobos is getting too large.

If any abstraction (or what to call it) becomes too large then you just create another one.

If method becomes too large - split it up in several methods
If a class gets too many methods - split the class in several classes
If a module gets too many classes - split the module in several modules
If package gets too many modules - split it up in in several (sub) packages
If a library gets too many packages - split it up in several libraries

-- 
/Jacob Carlborg
March 30, 2012
Le 30/03/2012 04:13, Adam D. Ruppe a écrit :
> On Friday, 30 March 2012 at 01:55:23 UTC, Nick Sabalausky wrote:
>> <wishful musing>I've been starting to think
>> more and more that the "everything in a module is a friend" was a
>> mistake,and that we should have instead just had a "module"
>> access specifier like we have "package".</wishful musing>
>
> Or, for moar compatibility, have enemy functions.
>
> class Klingon { private Starship commanding; }
> void nonFriend(enemy Klingon kor) {
> kor.commanding = lol; // error, commanding is private and kor is an enemy
> }
>
>
> Or, to avoid having a new keyword, call it interface
> instead of enemy.
>
> Though, then you could just pass an interface instead of
> a class too. Take most general possible type.
>
>
>
> But, separate modules are kinda cool anyway. I often put
> stuff together in one module just for ease of distribution,
> but eh modules are cool.
>

For the ease of distribution, you can use a module with public import in it.