February 13, 2007
Jarrett Billingsley wrote:
> "BCS" <ao@pathlink.com> wrote in message news:ce0a334373a38c91d108e764264@news.digitalmars.com...
> 
>>>5. Function literals and first-class, non-broken closures
>>>
>>
>>that's broken usage, not a broken feature, they work if you do them right, just as pointers do.
> 
> 
> I'd consider the current incarnation of closures "broken."  Are they useful as they are now?  Hell yes.  But can you do everything with them that you can in languages that have true closures?  No.  Functions are *almost* first class types in D ;)  Being able to return closures without having to manually create the context would be.. amazing.
> 
> 

Yes that would be nice, but it is one hell of a can of worms. It has more corner cases than general cases. About the only things that would be safe and reasonably understandable would be to put the whole stack frame on the heap.

If someone can figure out how to fix all the problems in a reasonably understandable manner, I'd love to see it. Until then, I think Explicit scoping (using structs) is the way to go.

Again, just my opinion.

>>>9. List comprehensions
>>
>>Ok, I'll bite, What is it?
> 
> 
> Basically it's a way of really easily applying functions and such over a list.  They're kind of like array operations (a[] = b[] + c[]), which D doesn't have yet, but more flexible.  You can do stuff like (using very python-like syntax):
> 
> int[] numbers = [1, 2, 3, 4, 5, 6, 7, 8];
> 
> // This loops through numbers, seeing if the condition holds true,
> // and if it does, adds it to a new list, which is eventually assigned
> // to evens.
> int[] evens = [x for x in numbers if !(x & 1)];
> 
> // Square the list
> int[] squares = [x * x for x in numbers];
> 

Cool, LISPisums.

Again, it would be a lib but I think it is possible, it would look something like this:

int[] squares = mapOver(numbers, (int x){return x*x;});
int[] evens = Filter(numbers, (int x){return !(x & 1);});

A smart compiler would try real hard to inline these so you'd even get most of the performance.

> 
>>>13. Keyword and rest parameters
>>
>>I'm not sure what this is
> 
> 
> Keyword parameters are another thing found in python.  They allow you to call functions with named parameters:
> 
> foo(x = 5, y = 10);
> 
> In python, the keyword parameters are interpreted as a hashtable, but since D is statically typed, it could probably just map the parameters right to the parameters defined in the function.  I'd really like to see this.
> 

Would this count?

struct foo{int x=1; int y=1;}

void fn(foo f){...}

fn({x:0});
fn({y:0});

not as nice, but with a little tweaking we could have this:

void fn(struct {int x=1; int y=1;}){...}

use an anon struct as the arguments.

>>>17. Solid string and collection libraries
>>>
>>>_Libraries_?  Noooo.
>>>
>>
>>We don't need them, D's AA's and dynamic arrays cover most of it and IIRC there are about a dozen libs for playing with them when you need more, clean them up a little and you've got it.
> 
> 
> I'll agree with you mostly for collections (I haven't missed STL a bit), but std.string is kind of an embarassment.  It only really has support for char[] (major shortfall in a language that supposedly handles UTF-16 and UTF-32) and doesn't provide any in-place functions (which would be great when you're writing a program that doesn't want to make any heap allocations). 
> 
> 

Ah... UTF, Oh, yeah. Forgot about that.
February 13, 2007
Jarrett Billingsley wrote:
> "BCS" <ao@pathlink.com> wrote in message news:ce0a334373d08c91d138f82c904@news.digitalmars.com...
> 
>>To pick at a few:
>>Does any language do interators for user type as language features? You have to write them your self in every language I know of.
> 
> 
> ....well if you don't write the iterator for your user type, how is the language going to know how to iterate over it?  When Steve said "iterators and generators" as a 'thing to have', I think he meant that they are first-class primitives in the language.  Having to write a custom iterator for a class wouldn't change that fact.
> 

Strait up question: how does D fail in this regard? opApply and delegate based foreach cover a /lot/ of ground.
February 13, 2007
Jarrett Billingsley a écrit :
> "BCS" <ao@pathlink.com> wrote in message 
>>> 13. Keyword and rest parameters
>> I'm not sure what this is
> 
> Keyword parameters are another thing found in python.  They allow you to call functions with named parameters:
> 
> foo(x = 5, y = 10);
> 
> In python, the keyword parameters are interpreted as a hashtable, but since D is statically typed, it could probably just map the parameters right to the parameters defined in the function.  I'd really like to see this.

+1

When you think about it, the current function call where parameter passing is done by position is quite broken as shown nicely by memset: developers make so many mistake calling it, that some compilers integrated warnings when they see that the parameters are likely wrong..

IMHO when a function has two parameters with 'compatible' type, it should be called by 'keyword' to avoid hard to find errors.
Plus, this really improves readability, if a bit verbose.

renoX
February 13, 2007
"BCS" <BCS@pathlink.com> wrote in message news:eqst6m$29s$2@digitalmars.com...
>> ....well if you don't write the iterator for your user type, how is the language going to know how to iterate over it?  When Steve said "iterators and generators" as a 'thing to have', I think he meant that they are first-class primitives in the language.  Having to write a custom iterator for a class wouldn't change that fact.
>>
>
> Strait up question: how does D fail in this regard? opApply and delegate based foreach cover a /lot/ of ground.

I guess it doesn't really miss much functionality, though the way D handles iteration certainly makes it harder to do parallel iteration.  I have *no* idea how Walter/Andrei plan to implement the "foreach(i;a)(j;b){}" syntax that Andrei has been talking about.  On the other hand, many general case iterators are far easier to write using the D callback style than with iterator style.

Generators, on the other hand, are just plain cool.  I think they can be done using something like StackThreads.


February 13, 2007
"BCS" <BCS@pathlink.com> wrote in message news:eqst20$29s$1@digitalmars.com...
>
> Yes that would be nice, but it is one hell of a can of worms. It has more corner cases than general cases. About the only things that would be safe and reasonably understandable would be to put the whole stack frame on the heap.
>
> If someone can figure out how to fix all the problems in a reasonably understandable manner, I'd love to see it. Until then, I think Explicit scoping (using structs) is the way to go.
>
> Again, just my opinion.

That's why it's Walter's job ;)

> Would this count?
>
> struct foo{int x=1; int y=1;}
>
> void fn(foo f){...}
>
> fn({x:0});
> fn({y:0});
>
> not as nice, but with a little tweaking we could have this:
>
> void fn(struct {int x=1; int y=1;}){...}
>
> use an anon struct as the arguments.

Someone actually suggested this.  Basically the idea was that if your function took a struct as a parameter, you could replace the struct with a list of struct member initializers and D would implicitly create the struct.

struct foo { int x = 1; int y = 1; }
void fn(foo f) { ... }
fn(x:0, y:5);

basically the same as your suggestion but without the curly braces at the call site.

I'd like to see something, anything, for named parameters.  I still think the compiler should be able to map directly to the function's named arguments without any extra trickery like using a struct.


February 13, 2007
Reply to Jarrett,

> I guess it doesn't really miss much functionality, though the way D
> handles iteration certainly makes it harder to do parallel iteration.
> I have *no* idea how Walter/Andrei plan to implement the
> "foreach(i;a)(j;b){}" syntax that Andrei has been talking about.

It might take this approch (interate over the intersect of to AA's)

int delegate(int delegate (inout U, SetT!(T, T)) dg) Intersect(T, U)(T[U] first, T[U] sec)

returns this delegate

|{
|  foreach(k, v1; first)
|  {
|    if(v2 = (k in sec))
|      {
|        if(ret = dg (k, Set(v1, *v2))
|          return ret  |      }
|  }
|}

> 
> Generators, on the other hand, are just plain cool.  I think they can
> be done using something like StackThreads.
> 

I'm missing somthing here: what is a generator?


February 14, 2007
BCS wrote:
> Reply to Jarrett,
> 
>> Generators, on the other hand, are just plain cool.  I think they can
>> be done using something like StackThreads.
> 
> I'm missing somthing here: what is a generator?

A generator is like a function, but after it "returns" it can be "called" again and it will resume where it left off. Local variables are preserved, and execution resumes after the statement that caused the return.
They're basically an automated method for creating an iterator object out of an opApply-like function.


In Python, you create them by using 'yield' instead of return.
Python tutorial section on generators: http://docs.python.org/tut/node11.html#SECTION00111000000000000000000
February 14, 2007
Reply to Frits,

> BCS wrote:
> 
>> Reply to Jarrett,
>> 
>>> Generators, on the other hand, are just plain cool.  I think they
>>> can be done using something like StackThreads.
>>> 
>> I'm missing somthing here: what is a generator?
>> 
> A generator is like a function, but after it "returns" it can be
> "called" again and it will resume where it left off. Local variables
> are
> preserved, and execution resumes after the statement that caused the
> return.
> They're basically an automated method for creating an iterator object
> out of an opApply-like function.
> In Python, you create them by using 'yield' instead of return. Python
> tutorial section on generators:
> http://docs.python.org/tut/node11.html#SECTION00111000000000000000000
> 

I should be burned at the stake for this...

| struct
| {
|   // all needed variables
|   int at=0;
|   |   int go() // fn with no local variables
|   {
|     switch(at)
|     {
|       case -1:
|       assert(false);
| |       case 0:
| |       //stuff
| |      at=1; return value; case 1:
| |       // more stuff
| |       at=2; return value; case 2:
| |       // more stuff
| |     }
|     at = -1;
|     return value;
|   }
| }


February 14, 2007
BCS wrote:
> Reply to Frits,
> 
>> BCS wrote:
>>
>>> Reply to Jarrett,
>>>
>>>> Generators, on the other hand, are just plain cool.  I think they
>>>> can be done using something like StackThreads.
>>>>
>>> I'm missing somthing here: what is a generator?
>>>
>> A generator is like a function, but after it "returns" it can be
>> "called" again and it will resume where it left off. Local variables
>> are
>> preserved, and execution resumes after the statement that caused the
>> return.
>> They're basically an automated method for creating an iterator object
>> out of an opApply-like function.
>> In Python, you create them by using 'yield' instead of return. Python
>> tutorial section on generators:
>> http://docs.python.org/tut/node11.html#SECTION00111000000000000000000
>>
> 
> I should be burned at the stake for this...
> 
> | struct
> | {
> |   // all needed variables
> |   int at=0;
> |   |   int go() // fn with no local variables
> |   {
> |     switch(at)
> |     {
> |       case -1:
> |       assert(false);
> | |       case 0:
> | |       //stuff
> | |      at=1; return value; case 1:
> | |       // more stuff
> | |       at=2; return value; case 2:
> | |       // more stuff
> | |     }
> |     at = -1;
> |     return value;
> |   }
> | }
> 
> 

Which kind of proves what I've been seeing as the point, i.e., D is a complete language, and it's POSSIBLE to do anything computable in it.  That doesn't mean it's easy, or worth doing, if you have to do it within the D syntax.

The things that people have been saying are all things that are POSSIBLE to do in D...but frequently the techniques for doing them are so cumbersome or error prone that the only reasonable choice is to avoid them.

If one believes that a particular technique is desirable, then one wishes to have it reasonably easy to use.  Thus, because MANY people have thought that templates are a good idea (esp. Walter), lots of work and improvement has been done on them. Much less work has been done on advanced run-time features, which aren't typically used in, at a guess, embedded systems.  (Well, those don't even like garbage collectors, so it's some other purpose that's at the center of focus for D.  It doesn't seem to involve graphics or databases.  Those are "available", but only in rudimentary form, and largely as a side effect of having C routines be callable.

N.B.:  I'm not asserting that everyone is interested in some one particular thing, but merely that the "center of gravity" of interest is in an area with certain characteristics. Presumably as it becomes "well developed" more out-lying areas will experience more development.

But just contrast D's approach with that of Python.  Python has long boasted "Batteries Included!".  I don't know if it's still on the home web page, but it was for many years.  Or Perl's proclaiming of CPAN.  I've never used it, but I'm still well aware of claims that programs don't need to check that libraries are available locally.  As long as there's a net connection, they'll be downloaded automatically.  (That may be overselling...but that's the way I've heard it advertised.) D, OTOH, is more like Ruby.  Libraries aren't available by default, and lots of the ones that are in the repositories aren't maintained any more and have suffered from bit-rot.  As a result Ruby has Rails programmers, and Python has Python programmers, and Perl has Perl programmers.  (OK.  That statement's a bit too strong.  But that's the tendency.)

D is starting from the language model of C and C++.  In many ways this is good, but I'm not sure to what extent...

N.B.:  In the commentary about languages I left out Java, because that was driven by large corporations.  Still, it's worth noting that much of Java's success was due to the large libraries it has of routines that can be counted upon to work.  Phobos is more analogous to the libraries that came with the Fortran compilers around 1970.  (Well, less extensive, but more tuned to the basic tasks.)

P.S.:  Partially this note is due to my current frustration due to the release of Tango, which won't work with Phobos, and therefore means that I can't depend on any particular library being installed with a D compiler...with the libraries being so different that the same code can't be used with both.
February 14, 2007
Deewiant wrote:
> Mentions D, and is an interesting article overall.
> 
> http://steve-yegge.blogspot.com/2007/02/next-big-language.html
> 

Attached is what happens when I go to Kinematics class after reading this post :)