February 14, 2007
> And we should keep on frowning on attempts to use overloaded << for I/O purposes <g>.

Why? I think it's intuitive. The arrows point from the source of the message to the destination. Should the operator only be used for shifting because that happens to have been its first purpose?

I also like how you can send a message to an abstract object. And that can be a cout, a cerr, an error console in a GUI, or something else. Same thing the other way around.
February 14, 2007
Andrei Alexandrescu (See Website For Email) a écrit :
> Probably this might be helpful. I think I should give it a shot, too:
> 
> http://srfi.schemers.org/srfi-49/srfi-49.html
> 
> A big-time Scheme champion (wrote an entire Scheme system and two dozens of great papers) admitted to me that syntax is a big hurdle for acceptance and that he is looking into offering alternatives. The advantage is that they come from the "right" place. Unix started as a system for professionals with security, flexibility, etc. in place, and it's much harder to make Windows, which started as a consumer product, get to the same level.

I'm not sure srfi helps: I find it worse than the original syntax: sure there is no more parenthesis, but now functions are spread over too many lines.
I remember one article where the author used a very light grey (over a white background) for the parenthesis to make them less noticeable..

With a correct indentation, this presentation trick makes the program far more readable for non-Lispers..

renoX




> 
> 
> Andrei
February 14, 2007
Nicolai Waniek wrote:
> janderson wrote:
>> What about using it for files that you are going to load at runtime
>> otherwise? XML ect...?
>>
>> -Joel
> 
> Loading the file belongs to runtime. Well, if it would take 10 minutes
> to load the file instead of 1 second if it was "loaded during
> compilation", that would be an argument for something like that - but I
> guess this won't be the case in most projects.
> 
> With your example: If you define something like that for compile time,
> it won't make it possible to change this dynamically, e.g. with a
> configuration file. If you write a super-D-duper library that loads file
> xyz and converts it to zyx, you won't want to sell the code (if it's not
> open source) so this possibility won't even fit to your business...

I think it should be clarified that the loading-config-files example is a strawman that we could leave in peace. It's the least interesting example of the bunch, and also the hardest to make interesting.

What we're talking here is about things that would improve life of everyone: better database integration, better regular expressions, proper reflection, better integration with other languages (e.g. Python, Javascript), remote procedure calls, persistence, networking...

> So, if "a" stands for "easy to learn, easy to use, fixed language" and
> "b" for "hard to learn because of dynamic language extension" you might
> get something like this for "not using mixins and that kind of stuff":
> 
> a [---|-----------] b
> 
> and the following, if you use them:
> 
> a [----------|----] b
> 
> Well I have to admit that there are some real good and well thought-out
> examples on how to reasonably use the new language features, but there
> will be more examples on how to _not_ use them. and the latter ones will
> be the ones with which we will have to struggle - and I don't want to
> struggle when programming, it usually is a joy! (and that's why I don't
> want to code in C++).

Technology can be annoying and have bad side effects, it's known ever since Ned Ludd whacked those sewing machines or whatever they were.


Andrei
February 14, 2007
replied in new thread "overloading operators for I/O"
February 14, 2007
The longer I think about all this stuff, the more I come up with good examples for its usage - but i'm not fully converted to a "yeehaa, here comes the mixin" one =D
February 14, 2007
Bill Baxter wrote:
> Andrei Alexandrescu (See Website For Email) wrote:
>> Bill Baxter wrote:
>>> Andrei Alexandrescu (See Website For Email) wrote:
>>>> Bill Baxter wrote:
>>>>> Andrei Alexandrescu (See Website For Email) wrote:
>>>>>
>>>>>
>>>>>> I'm actually mildly surprised. Lately there was some talk around here about supporting the day-to-day programmers and so on. I find looping a very day-to-day thing, and looping over 2+ things at least a few-days-to-few-days thing. There is a need for parallel iteration, if nothing else shown by the existence of a library that addresses exactly that - to the extent possible in a library that's not in the position to control syntax, scoping, and visibility. I was sure people will be on this one like white on rice. But Bjarne Stroustrup was right: nobody knows what most programmers do :o).
>>>>>
>>>>> Python and Ruby are hardly considered to be obtuse languages, or unfriendly to Joe coder, but both get by just fine without special case syntax for iterating over multiple collections, or for iterating in reverse.
>>>>>    for x,y izip(foo,bar):
>>>>>        do stuff
>>>>>
>>>>>    for x reversed(foo):
>>>>>        do stuff
>>>>>
>>>>>    for x,y izip(reversed(foo),bar):
>>>>>        do that with your proposal!
>>>>
>>>> foreach (x ; reverse_view(foo)) (y ; bar)
>>>>   probably I could!
>>>
>>> foreach (x,y ; transpose_view(reverse_view(foo),bar)
>>>   then why not this too?!
>>
>> Because it doesn't keep bound variables together with the data. Perl has a way of initializing multiple variables that is unnerving:
>>
>> my ($a, $b, $c) = (e1, e2, e3);
>>
>> The long-distance relationships make it so irritating when ek are more than a couple of characters, I often give up and write:
>>
>> my $a = e1;
>> my $b = e2;
>> my $c = e3;
>>
>> even though I try to use vertical space sparingly.
> 
> You're of course welcome to your opinion, but multiple assignment exists in many languages.  So you're saying they're all wrong to have such a feature?

No. It's good to have multiple assignments; it's annoying that Perl prevents the option of grouping initializers with the data if I so wanted:

my $a = e1, $b = e2, $c = e3;

I was just opining that

foreach (a ; e1) (a2 ; e2) {}

is clearer than:

foreach (a ; b) (e1 ; e2) {}


Andrei

February 14, 2007
Bill Baxter wrote:
> Ok, I won't.  But I may end up in the pits carrying only my steering wheel a few times on the way to figuring out what "over-use" means.  ;-)

Yup <g>. And frankly, right now, we don't know what overuse is for this capability. We're just going to have to crash into the wall a few times before we figure it out.
February 14, 2007
Aarti_pl a écrit :
> Isn't it possible to extend proposed syntax for something like suggested on D wish list:
> http://all-technology.com/eigenpolls/dwishlist/index.php?it=42 

The wishlist itself doesn't strike me as very useful:
'on first' can be done with a boolean variable test (maybe a little less optimal for performance point of view)
and
'on last' can be done with scope(success){} (at least for the current foreach).


Aarti_pl a écrit :
> Maybe syntax like this would be more D-ish, flexible and compact, because in fact we need kind of switch..case syntax for 'foreach'... :
> 
> foreach (i ; coll1) (j ; coll2) {
>       ... use i and j ...
> 
>     case(continue)(i) {
>       ... coll2 finished; use i ...
>     }
> 
>     case(continue)(j) {
>       ... coll1 finished; use j ...
>     }
> 
>     case(last)(i) {
>       ... do something with last col1 element
>     }
> 
>     case(first)(j) {
>       ... do something with first col2 element
>     }
> }
> 
> It does not introduce new keywords and is easy to extend for other situations. I like also that everything is a part of foreach, and is not separated into different statements...

Yes! IMHO, this is better than the 'continue foreach': as it avoids the 'magical' state passing between foreach and continue foreach (ok it's not magically passed, i|j are used but as they "look" like simple variabl, this still looks weird).
Plus coll1 and coll2 cannot be modified anymore before the second iteration.

My only nitpick would be that the name continue in case(continue) is not very good: it could confuse a user to think that this is executed in case of usage of the 'normal' continue.
But I can't think of a better name: case(alone), case(only) case(iterate_alone),  case(continue_alone) are not very good..
Maybe case(end)(j) (when j do not iterate anymore) to be more consistent with case(first), case(last)..

Also what to do when the iteration is made on three collections say i,j,k: case(continue)(i,j) ? or maybe case(end)(j,k)?

This would make the code like this:
case(continue)(i,j) { .. foo1 .. }
case(continue)(j,k) { .. foo2 .. }
case(continue)(i,k) { .. foo3 .. }
case(continue)(i) { .. foo4 .. }
case(continue)(j) { .. foo5 .. }
case(continue)(k) { .. foo6 .. }

Hopefully one doesn't need to do this too often!

renoX

PS:
IMHO there are quite a few basic features missing in D such as proper associative/static array initialisation, good string format sugar (like in Ruby), etc that I have a hard time to find 'continue foreach / case(continue)' interesting.



> 
> BR
> Marcin Kuszczak
February 15, 2007
Walter Bright wrote:
> Nicolai Waniek wrote:
>> The main problem I have with mixins/templates and so on is that it
>> enables a programmer to change the "look and feel" of the language
>> completely. What is bad about it? That if you're working in a team
>> someone has a "great idea" and invents his own MyDSL. So what? Everyone
>> else has to "learn" this new DSL. So they spend time on something they
>> would've better spent on coding something else, or fixing bugs... I
>> worked in a team of about 8 persons bugfixing a project with
>> approximately 1.000.000 LoC. The former programmers just seemed to not
>> know how to code (and we programmed using Delphi!!! a language most
>> people like to tell you: "oh, that's a language that shows you how to
>> work structured" - that's totally bullshit!).
>> So on one hand, we had to improve the software as it was used by just
>> too many companies to completely rewrite it - on the other hand we had
>> to bugfix it with a syntax that even didn't look like Pascal. Now what?
>> If we had someone "just for the sake of it" implementing something with
>> his MyDSL, i would've probably killed him!
> 
> I hear you. I also find most uses C++ templates are put to to be incomprehensible - either from programmers showing off, or from working around the severe limitations of C++ templates.
> 
> Another big part of the problem is that templates are just hard to read and understand. If they were as easy to deal with as regular functions, then that difficulty would (I hope) melt away. This is what we're working towards.
> 
> I agree with you on another level - programmers showing off their understanding of the language by some need to use every feature of the language, MAKING SIMPLE THINGS COMPLICATED. To me, *real* programming skill is expressing complicated things in a simple manner.
> 
> One of my (unfavorite) examples of the making simple things complicated is the simple linked list concept:
>     struct Foo
>     {    Foo *next;
>         ...
>     }
> voila, a linked list. But nooo, for some reason (just for the sake of it? <g>), this has to be made complicated, with templates, macros, iterators, akk. There's a place for iterators, but they are overused.

Boy is that not a good example.

From http://mitpress.mit.edu/sicp/chapter1/node18.html, a quote that
has stayed with me since I first read it (in illegal copy) back in
Romania many years ago:

"We have seen that procedures are, in effect, abstractions that describe
compound operations on numbers independent of the particular numbers.
For example, when we

(define (cube x) (* x x x))

we are not talking about the cube of a particular number, but rather
about a method for obtaining the cube of any number. Of course we could
get along without ever defining this procedure, by always writing
expressions such as

(* 3 3 3)
(* x x x)
(* y y y)

and never mentioning cube explicitly. This would place us at a serious
disadvantage, forcing us to work always at the level of the particular
operations that happen to be primitives in the language (multiplication,
in this case) rather than in terms of higher-level operations. Our
programs would be able to compute cubes, but our language would lack the
ability to express the concept of cubing. One of the things we should
demand from a powerful programming language is the ability to build
abstractions by assigning names to common patterns and then to work in
terms of the abstractions directly."

Your example shows that you are able to make a list, but it gives zero
indication on whether you can express what a list _is_.


Andrei
February 15, 2007
Andrei Alexandrescu (See Website For Email) wrote:
> Your example shows that you are able to make a list, but it gives zero
> indication on whether you can express what a list _is_.

I just don't feel that everything that can be abstracted away, should be. Sometimes a trivial list is just a ->next, and doesn't need any more than that. Sometimes, I just want to do x*x*x rather than abstracting away a cube(T)(T x) function.

An abstraction becomes useful when it's repeated repeatedly, not when it's used once or twice.