Re: Descent 0.5.5 released

2009-05-20 Thread Saaa

 For this release Robert Fraser made an excelent addition: when compiling
 programs using an external tool such as dsss, rebuild, dmd, gdc, ldc, gdmd 
 or bud, there are now links to the files in the console output for 
 warnings and errors. I think this one was pretty requested. So say thanks 
 to him! :-)

 (here's a screenshot in case no one understood my poor English: 
 http://downloads.dsource.org/projects/descent/problems.jpg :-P)

3 




Re: Serialization for D. Comments, please!

2009-05-20 Thread BCS

Hello Brad,


(moved from .announce to dm.D)

BCS wrote:


I'm planning on taking a crack at a Serialization template library
and I'm looking for feed back. My thinking so far is up on my blog
here:

http://arrayboundserror.blogspot.com/2009/05/serialization-for-d-part
-1-of-n.html

Please comment! (here or there, doesn't matter, I think I'll see
both)


I strongly suggest figuring out early how you want to support multiple
serialization formats.  From experience, it's deceptively difficult to
splice that into the design later.



I'm already puzzling over that one g


As for invocation, consider making the deserialization a constructor.


The problem with making it a constructor is that it dosn't match with structs.


I assume that in the example that the Deserialize method was static
and acts as a factory?


yes. 


Another point for you to ponder... do you want to support builtin
types as a top level serialization point.  ie, can you serialize a
single int or must it be a struct or class or aggregate?  If you _do_
want to support it, consider what will happen for formats that don't
support it, such as xml and json.


I was thinking it would end up as a string wrapped in a tag (for XML):

int42/int




Re: OT: on IDEs and code writing on steroids

2009-05-20 Thread Yigal Chripun

Lutger wrote:

Yigal Chripun wrote:

...
IMO, designing the language to support this better work-flow is a good 
decision made by MS, and D should follow it instead of trying to get 
away without an IDE.


I'm not sure about this. D is designed to be easier to parse than C++ 
(but that's saying nothing) to allow better tools made for it. I think this 
should be enough. 

C#  friends not only better supports working inside an IDE, but makes it a pain to 
do without. Autocomplete dictates that related functions should be named with
the exact same prefix - even when this isn't logical. It also encourages names to be 
as descriptive as possible, in practice leading to a part of the api docs encoded in 
the function name. Extremely bloated names are the consequence of this. It doesn't 
always make code more readable imho. 

this I completely disagree with. those are the same faulty reasons I 
already answered.
an IDE does _not_ create bad programmers, and does _not_ encourage bad 
code. it does encourage descriptive names which is a _good_ thing.


writing strcpy ala C style is cryptic and *wrong*. code is read 
hundred times more than it's written and a better name would be for 
instance - stringCopy.
it's common nowadays to have tera-byte sized HDD so why people try to 
save a few bytes from their source while sacrificing readability?


the only issue I have with too long names is when dealing with C/C++ 
code that prefixes all symbols with their file-names/namespaces. At 
least in C++ this is solved by using namespaces. but this is a problem 
with the languages themselves and has nothing to do with the IDE.


The documentation comments are in xml: pure insanity. I tried to generate documentation 
for my stuff at work once, expecting to be done in max 5 min. like ddoc. Turns out nobody at 
work uses documentation generation for a reason: it isn't really fleshed out and one-click

from the IDE, in fact it is a pain in the arse compared to using ddoc.

I should stop now before this turns into a rant.



I agree fully with this. XML documents are a mistake made by MS. javadoc 
is a much better format and even that can be improved.


This however has nothing to do with the IDE. the important part is that 
the IDE parses whatever format is used and can show you the 
documentation via simple means. no need for you to spend time to find 
the documentation yourself.


Re: OT: on IDEs and code writing on steroids

2009-05-20 Thread Lutger
Andrei Alexandrescu wrote:

...
 What the heck do you need generics for when you have real templates?  To me,
 generics seem like just a lame excuse for templates.
 
 I agree. Then, templates aren't easy to implement and they were 
 understandably already busy implementing the using statement.
 
 Andrei

While I don't fully understand how generics work under the hood in .NET, there 
are some benefits to how it is done. For example, you can use runtime 
reflection on generic types. And the jit compiler 
instantiates them at runtime. They may serve a different purpose than templates:

Anders Hejlsberg: To me the best way to understand the distinction between C# 
generics and C++ templates is this: C# generics are really just like classes, 
except they have a type parameter. C++ templates 
are really just like macros, except they look like classes. 

It seems that lack of structural typing is seen as a feature:

When you think about it, constraints are a pattern matching mechanism. You 
want to be able to say, This type parameter must have a constructor that takes 
two arguments, implement operator+, have this 
static method, has these two instance methods, etc. The question is, how 
complicated do you want this pattern matching mechanism to be?
There's a whole continuum from nothing to grand pattern matching. We think it's 
too little to say nothing, and the grand pattern matching becomes very 
complicated, so we're in- between.  

From: http://www.artima.com/intv/genericsP.html




 










Re: OT: on IDEs and code writing on steroids

2009-05-20 Thread Lutger
Andrei Alexandrescu wrote:

...
 I've repeatedly failed to figure out the coolness of C#, and would 
 appreciate a few pointers. Or references. Or delegates :o).


It's not in the language. 

C# only has to do 'better' than C++ and Java to be cool and in that it 
succeeds: Besides many smaller improvements, it provides delegates / events, 
lambda's and true generics compared to java. Compared to 
C++ it provides, well, lots of the same stuff that make people prefer Java over 
C++. 
It does this while still being familiar. Take F# for example, probably a much 
cooler language: I suspect this is too alien for most people.

The real attraction of C# is the framework and the IDE. A lot of programmers 
don't program in a language, but in an ecosystem where the language is just a 
part of it alongside the framework, toolchain and 
documentation.







Re: Why is !() need with default template arguments

2009-05-20 Thread Lars T. Kyllingstad

Jeremie Pelletier wrote:

Jacob Carlborg Wrote:


If I have a class like this:

class Class (T = int) {}

Then why can't I use it like this:

auto c = new C;

I have to do this:

auto c = new C!();


I think it is so the parser knows how to make the difference between the 
template symbol and an instance symbol.



Can you do anything with a template except instantiate it?

-Lars


Re: Why is !() need with default template arguments

2009-05-20 Thread Daniel Keep


Lars T. Kyllingstad wrote:
 Can you do anything with a template except instantiate it?
 
 -Lars

Pass it to another template as an alias argument.

  -- Daniel


Re: OT: on IDEs and code writing on steroids

2009-05-20 Thread Tim Matthews
On Wed, 20 May 2009 17:31:14 +1200, Jarrett Billingsley  
jarrett.billings...@gmail.com wrote:




Just, uh, wow.  Please dude, read up on this stuff first.



This thread turned into a java vs .net argument. I'm sorry but I don't  
know the details of the JVM's just in time compiler. The virtual machine  
in the name plus the design goals led me to this misunderstanding It  
should be interpreted, threaded, and dynamic


http://en.wikipedia.org/wiki/Java_(programming_language)#Primary_goals

http://en.wikipedia.org/wiki/Comparison_of_the_Java_and_.NET_platforms


switch-case (bug, not a proposal)

2009-05-20 Thread Lionello Lunesu

Why can we do

string s;
switch(s)
{
case blah:
 break;
default:
}


but not

byte[] a;
switch(a)
{
case [cast(byte)1,2,3]:
 break;
default:
}

?


Re: switch-case (bug, not a proposal)

2009-05-20 Thread Lionello Lunesu

heh: http://d.puremagic.com/issues/show_bug.cgi?id=596


Re: with should be deprecated with extreme prejudice

2009-05-20 Thread Don

Nick Sabalausky wrote:
Nick Sabalausky a...@a.a wrote in message 
news:guscm2$2jf...@digitalmars.com...
Don nos...@nospam.com wrote in message 
news:gurkuo$17n...@digitalmars.com...

Nick Sabalausky wrote:
Don nos...@nospam.com wrote in message 
news:gur1ec$18...@digitalmars.com...
If warnings exist, libraries must not do anything that creates a 
warning. They are NOT optional.
That's only true if a compiler (such as DMD) is only capable of treating 
warnings as errors.
No. Users complain if library code generates warnings. Because a user 
cannot make their code warning-free if the libraries they use are 
generating warnings.

They can if they use a prebuilt version of the library, a lib/a/dll.


Warnings are optional built-in lint tools (kinda like how we already have a 
built-in doc tool, built-in code generation tool (ie, mixins), built-in 
profiling/code-coverage, etc). And it's pretty difficult to claim that lint 
tools are bad.


If they are standardised, they _are_ bad, because they become mandatory 
for libraries. If they're not standardised, no problem, it's just a 
third-party tool which you particular users find helpful in eliminating 
bugs; and demanding that a library support your third-party tool is 
unreasonable.


Warnings can be categorised based on probability that they indicate a 
bug, with a range from:
(1) it almost always indicates a bug -- in this case, it should be an 
error.
(2) it hardly ever indicates a bug -- in this case, it's useless at 
best, but in practice it's harmful.


If there's anything in between, it indicates a weakness in that part of 
the language design.
DMD's warnings are now extremely close to (1), I hope they can become 
errors soon. (Eg, leaving off a return statement in a function which 
doesn't contain asm statements is almost guaranteed to be a bug).


Re: with still sucks + removing features + adding features

2009-05-20 Thread bearophile
Christopher Wright:
 The more common suggestion is:
 alias bar = foo;

I can add this too:
typedef Bar = Foo;

This changes in typedef and alias can solve two of the small problems I have 
with D. Let's see if Walter accepts such ideas.

(In the last days two more ideas have floated in this newsgroup: disallowing 
floating point literals with nothing before the point like .57, and making 
with safer). Such small improvements pile up.

Bye,
bearophile


Re: OT: on IDEs and code writing on steroids

2009-05-20 Thread Kagamin
BCS Wrote:

 smaller object code? OTOH a good implementation will noice when I can fold 
 together several template expansions

That's the difference. You can't fold templates because they're binary 
incompatible as opposite to generics.


Re: OT: on IDEs and code writing on steroids

2009-05-20 Thread Frits van Bommel

Kagamin wrote:

BCS Wrote:

smaller object code? OTOH a good implementation will noice when I can fold 
together several template expansions


That's the difference. You can't fold templates because they're binary 
incompatible as opposite to generics.


They're not always binary-incompatible. For instance, if a template only works 
with pointers or references (this includes object references) to parameter types 
it might well contain the exact same machine code for some of the instantiations.
A compiler backend or linker could recognize these cases and use a single 
instantiation's machine code for them.
(Essentially, these are pretty much the same cases where generics would have 
been sufficient)


Re: OT: on IDEs and code writing on steroids

2009-05-20 Thread Denis Koroskin
On Wed, 20 May 2009 13:09:37 +0400, Kagamin s...@here.lot wrote:

 BCS Wrote:

 smaller object code? OTOH a good implementation will noice when I can  
 fold
 together several template expansions

 That's the difference. You can't fold templates because they're binary  
 incompatible as opposite to generics.

You can fold /some/ templates. I believe LLVM already does merging of identical 
functions (including templates, virtual functions etc) as a part of 
optimization process. Not sure about LDC, though.


Re: Some memory safety

2009-05-20 Thread bearophile
Walter Bright:

Sorry for raising this thread.
While C# has purposes somewhat different from D, I think C# designers are right 
in their emphasys on safety. Modern programmers appreciate some safeties, and 
modern languages give them. The ideas I am talking about are already 
implemented in C#.
D can disable such safeties in release mode.

For example this C# code, compiled in release + unsafe mode shows that the 
dotnet stops the execution almost as soon you write out of the allowed memory 
zone. This uses stackalloc (similar to alloca) so they may be using a stack 
canary to detect the out of bound condition at runtime:
http://en.wikipedia.org/wiki/Stack_buffer_overflow#Stack_canaries

using System;
public sealed unsafe class Test {
  static void Main(string[] args) {
int n = args.Length  0 ? Int32.Parse(args[0]) : 10;
int* a = stackalloc int[n];
for (int i = 0; i  n * 2; i++) {
  a[i] = i;
  Console.WriteLine({0}, a[i]);
}
  }
}


D is not going to catch memory safety problems that result from using C 
library functions, like malloc. D can only guarantee memory safety when using 
D code and D library functions. The programmer is on his own using the unsafe 
C functions.

When I port C code to D I'd like the D compiler help me catch some of the 
memory bugs that may be present in the translated C code.
In C you have www.splint.org and valgrind, but the Java compiler shows how much 
good is to have a stricter compiler in the first place.

And in D code you have array.ptr and std.gc.malloc too (and 
std.c.stdlib.alloca, that is a C function but has no equivalent to D, so I can 
think of it as part of D), such things may lead to bugs. Such things may be 
totally disallowed in safe D modules, but some safety may be added to unsafe 
D modules too.

For example the memory std.gc.capacity() of Phobos1 can be used to detect out 
of bound situations with pointers given by std.gc.malloc.

Bye,
bearophile


Re: OT: on IDEs and code writing on steroids

2009-05-20 Thread Nick Sabalausky
Lutger lutger.blijdest...@gmail.com wrote in message 
news:gv090o$22...@digitalmars.com...
 Andrei Alexandrescu wrote:

 ...
 What the heck do you need generics for when you have real templates?  To 
 me,
 generics seem like just a lame excuse for templates.

 I agree. Then, templates aren't easy to implement and they were
 understandably already busy implementing the using statement.

 Andrei

 While I don't fully understand how generics work under the hood in .NET, 
 there are some benefits to how it is done. For example, you can use 
 runtime reflection on generic types. And the jit compiler
 instantiates them at runtime. They may serve a different purpose than 
 templates:

 Anders Hejlsberg: To me the best way to understand the distinction 
 between C# generics and C++ templates is this: C# generics are really just 
 like classes, except they have a type parameter. C++ templates
 are really just like macros, except they look like classes.

 It seems that lack of structural typing is seen as a feature:

 When you think about it, constraints are a pattern matching mechanism. 
 You want to be able to say, This type parameter must have a constructor 
 that takes two arguments, implement operator+, have this
 static method, has these two instance methods, etc. The question is, how 
 complicated do you want this pattern matching mechanism to be?
 There's a whole continuum from nothing to grand pattern matching. We think 
 it's too little to say nothing, and the grand pattern matching becomes 
 very complicated, so we're in- between.

 From: http://www.artima.com/intv/genericsP.html


I can see certain potential benefits to the general way C# does generics, 
but until the old (and I do mean old) issue of There's an IComparable, so 
why the hell won't MS give us an IArithmetic so we can actually use 
arithmetic operators on generic code? gets fixed (and at this point I'm 
convinced they've never had any intent of ever fixing that), I don't care 
how valid the reasoning behind C#'s general approach to generics is, the 
actual state of C#'s generics still falls squarely into the categories of 
crap and almost useless. 




Re: OT: on IDEs and code writing on steroids

2009-05-20 Thread Frits van Bommel

Denis Koroskin wrote:

On Wed, 20 May 2009 13:09:37 +0400, Kagamin s...@here.lot wrote:


BCS Wrote:

smaller object code? OTOH a good implementation will noice when I can  
fold

together several template expansions
That's the difference. You can't fold templates because they're binary  
incompatible as opposite to generics.


You can fold /some/ templates. I believe LLVM already does merging of identical 
functions (including templates, virtual functions etc) as a part of 
optimization process. Not sure about LDC, though.


LLVM has a function merging pass, but LDC doesn't run it by default at any 
optimization level. (You can pass -mergefunc to run it explicitly, as with any 
LLVM pass)
It has some limitations though. Since it runs on IR, it matters what LLVM type 
values have. That means it might merge Templ!(int) and Templ!(uint) since int 
and uint are both an i32 to LLVM, but it normally wouldn't merge Templ!(int*) 
and Templ(short*) even if the template compiles down to return cast(T) 
somefunc(cast(void*) arg); because the types are still different (i32* vs i16*).
To do the latter transformation, the pass would need to be reimplemented to run 
when the code is closer to machine code.


Re: Why is !() need with default template arguments

2009-05-20 Thread Tim Matthews
On Wed, 20 May 2009 15:01:44 +1200, Jeremie Pelletier jerem...@gmail.com  
wrote:



I think it is so the parser knows how to make the difference between the  
template symbol and an instance symbol.





Can you explain a bit more on this? function templates dont require this  
by the way and I didn't think a template could ever be 'newed'


Re: OT: on IDEs and code writing on steroids

2009-05-20 Thread Ary Borenszweig

dsimcha escribió:

== Quote from Christopher Wright (dhase...@gmail.com)'s article

Nick Sabalausky wrote:

Andrei Alexandrescu seewebsiteforem...@erdani.org wrote in message
news:gus0lu$1sm...@digitalmars.com...


I've repeatedly failed to figure out the coolness of C#, and would
appreciate a few pointers. Or references. Or delegates :o).

Outside of this group, I think most of the people considering C# really cool
are people who are unaware of D and are coming to C# from Java. What's
cool about C# is that it's like a less-shitty version of Java (and *had*
good tools, although the newer versions of VS are almost as much of a
bloated unresponsive mess as Eclipse - Which come to think of it, makes me
wonder - If Java has gotten so fast as many people claim, why is Eclipse
still such a sluggish POS?).

Compare C# to D though and most of the coolness fades, even though there are
still a handful of things I think D could still learn from C# (but there's
probably more than a handful that C# could learn from D).

Generics and reflection. Generics just hide a lot of casts, usually, but
that's still quite useful. And autoboxing is convenient, though not
appropriate for D.


What the heck do you need generics for when you have real templates?  To me,
generics seem like just a lame excuse for templates.


Yesterday doob reported a bug in Descent saying when you compile your 
project and it references a user library that has errors, when you click 
on the console to jump to the error, it doesn't work. I said to him: I 
never thought a user library could have errors! How did this happen to 
you? He replied: I found a bug in a template in Tango.


That's why generics doesn't suck: if there's something wrong in them, 
the compiler tells you in compile-time. In D, you get the errors only 
when instantiating that template.


Generics might not be as powerful as templates, but once you write one 
that compiles, you know you will always be able to instantiate it.


Re: OT: on IDEs and code writing on steroids

2009-05-20 Thread bearophile
Ary Borenszweig:
 That's why generics doesn't suck: if there's something wrong in them, 
 the compiler tells you in compile-time. In D, you get the errors only 
 when instantiating that template.

It's just like in dynamic languages, you need to unittest them a lot :-)
So having a static throws() to assert that a template isn't working is very 
useful.

Bye,
bearophile


Re: OT: on IDEs and code writing on steroids

2009-05-20 Thread Christopher Wright

Nick Sabalausky wrote:
I can see certain potential benefits to the general way C# does generics, 
but until the old (and I do mean old) issue of There's an IComparable, so 
why the hell won't MS give us an IArithmetic so we can actually use 
arithmetic operators on generic code? gets fixed (and at this point I'm 
convinced they've never had any intent of ever fixing that), I don't care 
how valid the reasoning behind C#'s general approach to generics is, the 
actual state of C#'s generics still falls squarely into the categories of 
crap and almost useless. 


IArithmetic is impossible in C# because operator overloads are static 
methods, and interfaces cannot specify static methods.


Re: OT: on IDEs and code writing on steroids

2009-05-20 Thread bearophile
Frits van Bommel:
 To do the latter transformation, the pass would need to be reimplemented to 
 run 
 when the code is closer to machine code.

Can't this feature be asked to the LLVM developers?

Bye,
bearophile


Re: OT: on IDEs and code writing on steroids

2009-05-20 Thread Christopher Wright

dsimcha wrote:

== Quote from Christopher Wright (dhase...@gmail.com)'s article

Nick Sabalausky wrote:

Andrei Alexandrescu seewebsiteforem...@erdani.org wrote in message
news:gus0lu$1sm...@digitalmars.com...


I've repeatedly failed to figure out the coolness of C#, and would
appreciate a few pointers. Or references. Or delegates :o).

Outside of this group, I think most of the people considering C# really cool
are people who are unaware of D and are coming to C# from Java. What's
cool about C# is that it's like a less-shitty version of Java (and *had*
good tools, although the newer versions of VS are almost as much of a
bloated unresponsive mess as Eclipse - Which come to think of it, makes me
wonder - If Java has gotten so fast as many people claim, why is Eclipse
still such a sluggish POS?).

Compare C# to D though and most of the coolness fades, even though there are
still a handful of things I think D could still learn from C# (but there's
probably more than a handful that C# could learn from D).

Generics and reflection. Generics just hide a lot of casts, usually, but
that's still quite useful. And autoboxing is convenient, though not
appropriate for D.


What the heck do you need generics for when you have real templates?  To me,
generics seem like just a lame excuse for templates.


Put a template in an interface.

Use reflection to instantiate a template.


Re: OT: on IDEs and code writing on steroids

2009-05-20 Thread Frits van Bommel

bearophile wrote:

Frits van Bommel:
To do the latter transformation, the pass would need to be reimplemented to run 
when the code is closer to machine code.


Can't this feature be asked to the LLVM developers?


Sure, feel free to file a feature request: 
http://llvm.org/bugs/enter_bug.cgi?product=new-bugs


Re: with still sucks + removing features + adding features

2009-05-20 Thread Alexander Pánek

Andrei Alexandrescu wrote:

Robert Fraser wrote:

Frank Benoit wrote:

Alexander Pánek schrieb:

Andrei Alexandrescu wrote:

bearophile wrote:

Andrei Alexandrescu:

Thank you for bringing a real example that gives something to 
work on.



Awful!

Well, one of your cases was wrong. Using the +1 at the end one of
those cases become:
case 'A' .. 'Z'+1, 'a' .. 'z'+1:
Instead of what you have written:
case 'A' .. 'Z'+1: case 'a' .. 'z'+1:

I agree that that syntax with +1 isn't very nice looking. But the
advantage of +1 is that it introduces (almost) no new syntax, it's
not easy to miss, its meaning is easy to understand. AND you don't
have to remember that in a case the .. is inclusive while in foreach
is exclusive on the right, keeping the standard way in D to denote
ranges.

You don't understand. My point is not that people will dislike 'Z'+1.
They will FORGET TO WRITE THE BLESSED +1. They'll write:

case 'A' .. 'Z':

You know, Ruby solves this by introducing a “seperate” range syntax for
exclusive ranges: “...”. An inclusive range is written the same as an
exclusive range in D: “..”.

a[1 .. 2].length #= 1 ([a[1]])
a[1 ... 2].length #= 2 ([a[1], a[2]])

I see no reason not to include such a seperate syntax in D. “..” being
exclusive and “...” being inclusive, not the other way round as in Ruby
— see “Programmer’s Paradox” @
http://www.programmersparadox.com/2009/01/11/ruby-range-mnemonic/ .

Kind regards, Alex


Yes, this is useful for all use cases of ranges.
I like '...'.


Indeed it's not a bad idea... But it might be easily mistyped, lead to 
strange off-by-one errors and be very difficult to find while 
debugging them. Hmmm...


It's an awful idea. It's a non-idea. If idea had an antonym, that 
would be it.


I can't fathom what's on the mind of a person (not you, at least you
foresee some potential problems) who, even after patiently explained the
issues with this mental misfire, several times, still can bring
themselves to think it's not that bad.


I don’t see a reason not to restrict other features to introduce a new 
one. I never used .foo to access the global scope or .1 for floating 
point literals. But what I do use very often is array[n..m + 1], which 
would ease things for quite a lot of things going on when working with 
arrays. Of course it’s just syntactic sugar, but so is the whole slicing 
feature. It could easily be done in the standard library.


So I’m not demanding anything, I’m just providing my very own thoughts 
on this topic. If there are too many obstacles then it’s probably not 
worth it. The thing is, I don’t know half as much as most of the guys 
here do, so I don’t see those obstacles at first glance. Please bear 
with me. :)



Let me add one more, although more than sure someone will find a remedy
for it, too.

a...b


inclusive range from a to b


vs.

a.. .b


exclusive range from a to .b

Personally, I see “...” as an atomic operator, like “!=” or “==”. I 
wouldn’t ever recognize “.. .” as “...” or “! =” as “!=”. Additionally, 
I add a space before and after every operator, so there’s no ambiguity 
in any way, plus it’s nicely recognizable what the hell is going on. If 
it was for me, I’d even go as far as to make this a requirement in the 
specification. But that would upset downs.


Actually, what about “…” as inclusive range operator? :P I’d love that.



and of course the beauty

ab


Inclusive range from “a” to “.b”? Pretty clear in this *particular* case. ;)



I don't plan to discuss minor features on this group anymore.


But.. bike shed discussions are fun! Seriously, though — I learn a lot 
thanks to people “nitpicking” other people’s ideas, showing corner 
cases, obstacles and so on. So please, don’t stop discussing minor 
features. :)


Re: with still sucks + removing features + adding features

2009-05-20 Thread KennyTM~

bearophile wrote:

Christopher Wright:

The more common suggestion is:
alias bar = foo;


I can add this too:
typedef Bar = Foo;

This changes in typedef and alias can solve two of the small problems I have 
with D. Let's see if Walter accepts such ideas.

(In the last days two more ideas have floated in this newsgroup: disallowing floating point 
literals with nothing before the point like .57, and making with safer). 
Such small improvements pile up.

Bye,
bearophile


typedef int MyInt = 1;


Re: with still sucks + removing features + adding features

2009-05-20 Thread Denis Koroskin
On Wed, 20 May 2009 00:43:56 +0400, Andrei Alexandrescu 
seewebsiteforem...@erdani.org wrote:

 It's an awful idea. It's a non-idea. If idea had an antonym, that  
 would be it.

 I can't fathom what's on the mind of a person (not you, at least you
 foresee some potential problems) who, even after patiently explained the
 issues with this mental misfire, several times, still can bring
 themselves to think it's not that bad.


Your post is emotional rather than rational.

 Let me add one more, although more than sure someone will find a remedy
 for it, too.

 a...b

 vs.

 a.. .b


a..b vs a.b - no one complains

It also gracefully solves an issue with uniform distribution

uniform(0..int.max)  - exclusive
uniform(0...int.max) - inclusive (can't be replaced with 0..int.max+1)

also in switch:

switch(a)
{
case 0..10: // exclusive
case 10...100: // inclusive
}


 I don't plan to discuss minor features on this group anymore.


It is as minor as case a: .. case b:, i.e. not minor at all.
I'd say that there is no such thing as minor feature, every feature is 
important.


 Andrei


Re: Why is !() need with default template arguments

2009-05-20 Thread Jeremie Pelletier
Tim Matthews Wrote:

 On Wed, 20 May 2009 15:01:44 +1200, Jeremie Pelletier jerem...@gmail.com  
 wrote:
 
 
  I think it is so the parser knows how to make the difference between the  
  template symbol and an instance symbol.
 
 
 
 Can you explain a bit more on this? function templates dont require this  
 by the way and I didn't think a template could ever be 'newed'

Oh yeah you are right, it has already been filed as a bug.


Re: OT: on IDEs and code writing on steroids

2009-05-20 Thread dsimcha
== Quote from Ary Borenszweig (a...@esperanto.org.ar)'s article
 dsimcha escribió:
  == Quote from Christopher Wright (dhase...@gmail.com)'s article
  Nick Sabalausky wrote:
  Andrei Alexandrescu seewebsiteforem...@erdani.org wrote in message
  news:gus0lu$1sm...@digitalmars.com...
 
  I've repeatedly failed to figure out the coolness of C#, and would
  appreciate a few pointers. Or references. Or delegates :o).
  Outside of this group, I think most of the people considering C# really 
  cool
  are people who are unaware of D and are coming to C# from Java. What's
  cool about C# is that it's like a less-shitty version of Java (and *had*
  good tools, although the newer versions of VS are almost as much of a
  bloated unresponsive mess as Eclipse - Which come to think of it, makes me
  wonder - If Java has gotten so fast as many people claim, why is Eclipse
  still such a sluggish POS?).
 
  Compare C# to D though and most of the coolness fades, even though there 
  are
  still a handful of things I think D could still learn from C# (but there's
  probably more than a handful that C# could learn from D).
  Generics and reflection. Generics just hide a lot of casts, usually, but
  that's still quite useful. And autoboxing is convenient, though not
  appropriate for D.
 
  What the heck do you need generics for when you have real templates?  To me,
  generics seem like just a lame excuse for templates.
 Yesterday doob reported a bug in Descent saying when you compile your
 project and it references a user library that has errors, when you click
 on the console to jump to the error, it doesn't work. I said to him: I
 never thought a user library could have errors! How did this happen to
 you? He replied: I found a bug in a template in Tango.
 That's why generics doesn't suck: if there's something wrong in them,
 the compiler tells you in compile-time. In D, you get the errors only
 when instantiating that template.
 Generics might not be as powerful as templates, but once you write one
 that compiles, you know you will always be able to instantiate it.

Yes, but there are two flaws in this argument:

1.  If you are only using templates like generics, you simply use a unit test to
see if it compiles.  If you're not doing anything fancy and it compiles for one 
or
two types, it will probably compile for everything that you would reasonably
expect it to.

2.  If you're doing something fancier, like metaprogramming, you have to just 
face
the fact that this is non-trivial, and couldn't be done with generics anyhow.

3.  As Bearophile alluded to, templates are really a clever hack to give you the
flexibility of a dynamic language with the performance and compile time checking
of a static language.  This is done by moving the dynamism to instantiation 
time.
 Therefore, whereas in a dynamic language you pay at runtime in terms of the 
here
be monsters, this code may not be being used as the author intended and tested
it, with templates you pay at instantiation time.  However, IMHO this is orders
of magnitude better than not having that flexibility at all.  I personally can't
figure out how people accomplish anything in static languages w/o templates.  
It's
just too inflexible.


Re: with still sucks + removing features + adding features

2009-05-20 Thread Jason House
bearophile Wrote:

Andrei Alexandrescu:
 I don't plan to discuss minor features on this group anymore.

That's a real pity.

I had a lot of respect for you and your perpetual inclusion of the D community 
(both announcing features and getting design feedback). 

Very early on in this thread, it became obvious to me that too much of it was 
getting under your skin. I've lost count of the insults posted in this thread. 
We're all trying to make D the best language we can, even if we come from 
vastly different perspectives.


Re: OT: on IDEs and code writing on steroids

2009-05-20 Thread Andrei Alexandrescu

Lutger wrote:

Andrei Alexandrescu wrote:

...

What the heck do you need generics for when you have real templates?  To me,
generics seem like just a lame excuse for templates.
I agree. Then, templates aren't easy to implement and they were 
understandably already busy implementing the using statement.


Andrei


While I don't fully understand how generics work under the hood in .NET, there are some benefits to how it is done. For example, you can use runtime reflection on generic types. And the jit compiler 
instantiates them at runtime. They may serve a different purpose than templates:


Anders Hejlsberg: To me the best way to understand the distinction between C# generics and C++ templates is this: C# generics are really just like classes, except they have a type parameter. C++ templates 
are really just like macros, except they look like classes. 


It seems that lack of structural typing is seen as a feature:

When you think about it, constraints are a pattern matching mechanism. You want to be able to say, This type parameter must have a constructor that takes two arguments, implement operator+, have this 
static method, has these two instance methods, etc. The question is, how complicated do you want this pattern matching mechanism to be?
There's a whole continuum from nothing to grand pattern matching. We think it's too little to say nothing, and the grand pattern matching becomes very complicated, so we're in- between.  


From: http://www.artima.com/intv/genericsP.html


Oh, so Wal^H^H^Ha friend of mine I was talking to was right: there's 
some missing of the point point going on. The code generation aspect of 
templates is a blind spot of the size of Canada.


Andrei


Re: with still sucks + removing features + adding features

2009-05-20 Thread Andrei Alexandrescu

Denis Koroskin wrote:

On Wed, 20 May 2009 00:43:56 +0400, Andrei Alexandrescu 
seewebsiteforem...@erdani.org wrote:

It's an awful idea. It's a non-idea. If idea had an antonym, that  
would be it.


I can't fathom what's on the mind of a person (not you, at least you
foresee some potential problems) who, even after patiently explained the
issues with this mental misfire, several times, still can bring
themselves to think it's not that bad.



Your post is emotional rather than rational.


Agreed. In my defense, let me mention that I've been rational in my 
previous 50 posts on the topic :o).



Let me add one more, although more than sure someone will find a remedy
for it, too.

a...b

vs.

a.. .b



a..b vs a.b - no one complains


You see, you didn't understand my point. My point was that the 
introduction of a space changes semantics. We should avoid that.



It also gracefully solves an issue with uniform distribution

uniform(0..int.max)  - exclusive
uniform(0...int.max) - inclusive (can't be replaced with 0..int.max+1)


Yeah, and this does something else:

uniform(0int.max)

and if you use an alias we also have:

uniform(0.A.max)

It's interesting how there is a continuum of number of . that still 
lead to compilable code that does different things every time. Perfect 
material for Why D is a horrible language articles.



Andrei


Re: with still sucks + removing features + adding features

2009-05-20 Thread Ary Borenszweig

Andrei Alexandrescu wrote:

Denis Koroskin wrote:
On Wed, 20 May 2009 00:43:56 +0400, Andrei Alexandrescu 
seewebsiteforem...@erdani.org wrote:


It's an awful idea. It's a non-idea. If idea had an antonym, that  
would be it.


I can't fathom what's on the mind of a person (not you, at least you
foresee some potential problems) who, even after patiently explained the
issues with this mental misfire, several times, still can bring
themselves to think it's not that bad.



Your post is emotional rather than rational.


Agreed. In my defense, let me mention that I've been rational in my 
previous 50 posts on the topic :o).



Let me add one more, although more than sure someone will find a remedy
for it, too.

a...b

vs.

a.. .b



a..b vs a.b - no one complains


You see, you didn't understand my point. My point was that the 
introduction of a space changes semantics. We should avoid that.



It also gracefully solves an issue with uniform distribution

uniform(0..int.max)  - exclusive
uniform(0...int.max) - inclusive (can't be replaced with 0..int.max+1)


Yeah, and this does something else:

uniform(0int.max)

and if you use an alias we also have:

uniform(0.A.max)

It's interesting how there is a continuum of number of . that still 
lead to compilable code that does different things every time. Perfect 
material for Why D is a horrible language articles.


This is easily solved by making the lexer not allow the  token, or 
  . token, etc. (maximum 3 dots.) This way you are forced to 
insert a space there to make your intention clear, and you can never 
have bugs like that.


Perfect material for Why D is a beautiful language articles.


Re: with still sucks + removing features + adding features

2009-05-20 Thread Andrei Alexandrescu

Ary Borenszweig wrote:
This is easily solved by making the lexer not allow the  token, or 
  . token, etc. (maximum 3 dots.) This way you are forced to 
insert a space there to make your intention clear, and you can never 
have bugs like that.


I agree that things could be fixed. This is, however, a hack because a 
lexer is not supposed to operate that way. Lexers are maximum munch.


So we're looking at a number of problems here. One is that we'd need to 
change the language in several places to accommodate an ill-conceived 
feature. Another is that I can't seem to get some very simple points 
across such as the difference between a token and a non-terminal, in 
spite of having tried repeatedly and in various forms. Another is that I 
am becoming suffocated with self-righteousness and therefore am losing 
goodwill in this thread at an exponentially-increasing rate. Finally, it 
looks like such discussions necessitate more than a full-time job.



Andrei


Re: with still sucks + removing features + adding features

2009-05-20 Thread bearophile
Denis Koroskin:
 It also gracefully solves an issue with uniform distribution
 uniform(0..int.max)  - exclusive
 uniform(0...int.max) - inclusive (can't be replaced with 0..int.max+1)

To avoid the possible confusion caused by ... Chapel uses ..#

uniform(0 .. int.max)  - exclusive
uniform(0 ..# int.max) - inclusive

Bye,
bearophile


Re: with still sucks + removing features + adding features

2009-05-20 Thread Bill Baxter
On Wed, May 20, 2009 at 7:28 AM, Andrei Alexandrescu
seewebsiteforem...@erdani.org wrote:
 Denis Koroskin wrote:

 On Wed, 20 May 2009 00:43:56 +0400, Andrei Alexandrescu
 seewebsiteforem...@erdani.org wrote:

 It's an awful idea. It's a non-idea. If idea had an antonym, that
  would be it.

 I can't fathom what's on the mind of a person (not you, at least you
 foresee some potential problems) who, even after patiently explained the
 issues with this mental misfire, several times, still can bring
 themselves to think it's not that bad.


 Your post is emotional rather than rational.

 Agreed. In my defense, let me mention that I've been rational in my previous
 50 posts on the topic :o).

 Let me add one more, although more than sure someone will find a remedy
 for it, too.

 a...b

 vs.

 a.. .b


 a..b vs a.b - no one complains

 You see, you didn't understand my point. My point was that the introduction
 of a space changes semantics. We should avoid that.

 It also gracefully solves an issue with uniform distribution

 uniform(0..int.max)  - exclusive
 uniform(0...int.max) - inclusive (can't be replaced with 0..int.max+1)

 Yeah, and this does something else:

 uniform(0int.max)

 and if you use an alias we also have:

 uniform(0.A.max)

 It's interesting how there is a continuum of number of . that still lead
 to compilable code that does different things every time. Perfect material
 for Why D is a horrible language articles.

Isn't 0...a already a horrendously awful non-idea and mental misfire
by these arguments?

--bb


Re: with still sucks + removing features + adding features

2009-05-20 Thread KennyTM~

Andrei Alexandrescu wrote:

Denis Koroskin wrote:
On Wed, 20 May 2009 00:43:56 +0400, Andrei Alexandrescu 
seewebsiteforem...@erdani.org wrote:


It's an awful idea. It's a non-idea. If idea had an antonym, that  
would be it.


I can't fathom what's on the mind of a person (not you, at least you
foresee some potential problems) who, even after patiently explained the
issues with this mental misfire, several times, still can bring
themselves to think it's not that bad.



Your post is emotional rather than rational.


Agreed. In my defense, let me mention that I've been rational in my 
previous 50 posts on the topic :o).



Let me add one more, although more than sure someone will find a remedy
for it, too.

a...b

vs.

a.. .b



a..b vs a.b - no one complains


You see, you didn't understand my point. My point was that the 
introduction of a space changes semantics. We should avoid that.




Like,

a- --b

vs.

a-- -b

?


It also gracefully solves an issue with uniform distribution

uniform(0..int.max)  - exclusive
uniform(0...int.max) - inclusive (can't be replaced with 0..int.max+1)


Yeah, and this does something else:

uniform(0int.max)

and if you use an alias we also have:

uniform(0.A.max)

It's interesting how there is a continuum of number of . that still 
lead to compilable code that does different things every time. Perfect 
material for Why D is a horrible language articles.



Andrei


Re: with still sucks + removing features + adding features

2009-05-20 Thread Andrei Alexandrescu

Bill Baxter wrote:

On Wed, May 20, 2009 at 7:28 AM, Andrei Alexandrescu
seewebsiteforem...@erdani.org wrote:

Denis Koroskin wrote:

On Wed, 20 May 2009 00:43:56 +0400, Andrei Alexandrescu
seewebsiteforem...@erdani.org wrote:


It's an awful idea. It's a non-idea. If idea had an antonym, that
 would be it.

I can't fathom what's on the mind of a person (not you, at least you
foresee some potential problems) who, even after patiently explained the
issues with this mental misfire, several times, still can bring
themselves to think it's not that bad.


Your post is emotional rather than rational.

Agreed. In my defense, let me mention that I've been rational in my previous
50 posts on the topic :o).


Let me add one more, although more than sure someone will find a remedy
for it, too.

a...b

vs.

a.. .b


a..b vs a.b - no one complains

You see, you didn't understand my point. My point was that the introduction
of a space changes semantics. We should avoid that.


It also gracefully solves an issue with uniform distribution

uniform(0..int.max)  - exclusive
uniform(0...int.max) - inclusive (can't be replaced with 0..int.max+1)

Yeah, and this does something else:

uniform(0int.max)

and if you use an alias we also have:

uniform(0.A.max)

It's interesting how there is a continuum of number of . that still lead
to compilable code that does different things every time. Perfect material
for Why D is a horrible language articles.


Isn't 0...a already a horrendously awful non-idea and mental misfire
by these arguments?

--bb


The problems increase exponentially with the number of dots.

Andrei


Re: with still sucks + removing features + adding features

2009-05-20 Thread Andrei Alexandrescu

Jason House wrote:

bearophile Wrote:

Andrei Alexandrescu:

I don't plan to discuss minor features on this group anymore.


That's a real pity.

I had a lot of respect for you and your perpetual inclusion of the D
community (both announcing features and getting design feedback).

Very early on in this thread, it became obvious to me that too much
of it was getting under your skin. I've lost count of the insults
posted in this thread. We're all trying to make D the best language
we can, even if we come from vastly different perspectives.


I am sorry I have gotten on the wrong side of civility in this thread.

Andrei


Re: the last change for ranges

2009-05-20 Thread Andrei Alexandrescu

Robert Jacques wrote:
Bicycle shed: Well, since output ranges use 'put', how about 'get' for 
input ranges?


Nice color :o). In fact, put is a poor choice because it doesn't 
reflect advancement. Probably putNext and getNext are better.


Andrei


Re: the last change for ranges

2009-05-20 Thread Andrei Alexandrescu

Bill Baxter wrote:

On Wed, May 20, 2009 at 9:19 AM, Andrei Alexandrescu
seewebsiteforem...@erdani.org wrote:


I'm thinking a better design is to require any range that's forward or
better to define a function save(). Ranges that don't implement it are input
ranges; those that do, will guarantee a brand new range is returned from
save(). So then adjacentFind would look like this:

R adjacentFind(R)(R r)
{
   if (r,empty) return r;
   R last = r.save;
   r.popFront;
   for (; !r.empty  last.front != r.front; last.popFront, r.popFront)
   {
   }
   return r;
}

Obviously, when you pass a range that doesn't support save, adjacentFind
will not compile, which is what we want.


The only other alternative that comes to mind would be forcing input
ranges to hide their copy constructor, or whatever the D equivalent
is, making R last = r; fail.  But that would make input ranges very
difficult to use.


Exactly. I thought of that design, and it was difficult to even pass a 
range to a function.



So, of those two options at least, requiring a .save sounds like the
better choice.

The down side is you will get no error if you write the code the first
way, without a .save.   I see this as turning into tip #5 in
Effective D -- Know when to use .save   It would be nice if that
potential mistake could be eliminated somehow.  You could perhaps
require input ranges to implement transfer semantics, and have them
implement a .clone for cases when you really do want to make an
aliasing copy.


Good point. I don't have a solution for that. Giving ranges move 
semantics would probably make for another Effective D tip (or perhaps 
more... move semantics are pretty brutal).


Another partial solution is to define a different interface for input 
ranges, one that combines front() and popFront(). Something like 
popNext. That way, people who use only the primitives empty() and 
popNext() know they are using a forward range and with hope they'll 
remember they can't really save copies of it and expect them to 
remember where they are in the input.



Andrei


Re: the last change for ranges

2009-05-20 Thread dsimcha
== Quote from Andrei Alexandrescu (seewebsiteforem...@erdani.org)'s article
 In wake of a few discussion I've witnessed, I'm thinking of a last
 change for ranges. (In fact there's one more, but that's minor.)
 The problem is that input ranges and forward ranges have the same
 syntactic interface, but different semantic interfaces. Consider the
 problem of finding the first two identical adjacent items in a range:
 R adjacentFind(R)(R r)
 {
  if (r,empty) return r;
  R last = r;
  r.popFront;
  for (; !r.empty  last.front != r.front; last.popFront, r.popFront)
  {
  }
  return r;
 }
 This will work properly on lists and vectors, but horrendously on files
 and sockets. This is because input ranges can't be saved for later use:
 incrementing r also increments popFront and essentially forces both to
 look at the same current value.
 I'm thinking a better design is to require any range that's forward or
 better to define a function save(). Ranges that don't implement it are
 input ranges; those that do, will guarantee a brand new range is
 returned from save(). So then adjacentFind would look like this:
 R adjacentFind(R)(R r)
 {
  if (r,empty) return r;
  R last = r.save;
  r.popFront;
  for (; !r.empty  last.front != r.front; last.popFront, r.popFront)
  {
  }
  return r;
 }
 Obviously, when you pass a range that doesn't support save, adjacentFind
 will not compile, which is what we want.
 Andrei
 P.S. There is a way to implement adjacentFind for forward ranges by
 saving data instead of ranges. I've used a limited version above for
 illustration purposes.

Sounds like at least a reasonable solution.  The thing I like about it is that, 
in
addition to safety, it allows for the range to do fancy and arbitrary stuff 
under
the hood if necessary to allow for saving.  Also, while we're fine tuning input
ranges vs. forward ranges, I think the concept of iterables as a catch-all for
ranges, opApply, builtins, etc. needs to be introduced and fine tuned, too.  
We've
shown on this NG previously that, while ranges are usually preferable for the
flexibility they offer, opApply does have its legitimate use cases.


Re: OT: on IDEs and code writing on steroids

2009-05-20 Thread Frits van Bommel

Kagamin wrote:

Frits van Bommel Wrote:


That's the difference. You can't fold templates because they're binary 
incompatible as opposite to generics.
They're not always binary-incompatible. For instance, if a template only works 
with pointers or references (this includes object references) to parameter types 
it might well contain the exact same machine code for some of the instantiations.


If you require that the class inherits some interface and call that interface's 
methods, they'll be incompatible. I'll dare to say this is the most useful 
variant of generic code.


Okay, so it doesn't (usually) work for interfaces, but it'll work if the 
requirement is for a common base class. Or perhaps even if they happen to have a 
common base class that implements the interface in question.


the last change for ranges

2009-05-20 Thread Andrei Alexandrescu
In wake of a few discussion I've witnessed, I'm thinking of a last 
change for ranges. (In fact there's one more, but that's minor.)


The problem is that input ranges and forward ranges have the same 
syntactic interface, but different semantic interfaces. Consider the 
problem of finding the first two identical adjacent items in a range:


R adjacentFind(R)(R r)
{
if (r,empty) return r;
R last = r;
r.popFront;
for (; !r.empty  last.front != r.front; last.popFront, r.popFront)
{
}
return r;
}

This will work properly on lists and vectors, but horrendously on files 
and sockets. This is because input ranges can't be saved for later use: 
incrementing r also increments popFront and essentially forces both to 
look at the same current value.


I'm thinking a better design is to require any range that's forward or 
better to define a function save(). Ranges that don't implement it are 
input ranges; those that do, will guarantee a brand new range is 
returned from save(). So then adjacentFind would look like this:


R adjacentFind(R)(R r)
{
if (r,empty) return r;
R last = r.save;
r.popFront;
for (; !r.empty  last.front != r.front; last.popFront, r.popFront)
{
}
return r;
}

Obviously, when you pass a range that doesn't support save, adjacentFind 
will not compile, which is what we want.


Andrei

P.S. There is a way to implement adjacentFind for forward ranges by 
saving data instead of ranges. I've used a limited version above for 
illustration purposes.


Re: OT: on IDEs and code writing on steroids

2009-05-20 Thread Kagamin
Frits van Bommel Wrote:

  That's the difference. You can't fold templates because they're binary 
  incompatible as opposite to generics.
 
 They're not always binary-incompatible. For instance, if a template only 
 works 
 with pointers or references (this includes object references) to parameter 
 types 
 it might well contain the exact same machine code for some of the 
 instantiations.

If you require that the class inherits some interface and call that interface's 
methods, they'll be incompatible. I'll dare to say this is the most useful 
variant of generic code.


Re: the last change for ranges

2009-05-20 Thread Jason House
I feel like there are too many differences between input and forward ranges for 
such a minor difference. Many range functions are written assuming no side 
effects on the caller. This can restrict the use of helper functions. It may be 
best to make their usage different... 

Andrei Alexandrescu Wrote:

 In wake of a few discussion I've witnessed, I'm thinking of a last 
 change for ranges. (In fact there's one more, but that's minor.)
 
 The problem is that input ranges and forward ranges have the same 
 syntactic interface, but different semantic interfaces. Consider the 
 problem of finding the first two identical adjacent items in a range:
 
 R adjacentFind(R)(R r)
 {
  if (r,empty) return r;
  R last = r;
  r.popFront;
  for (; !r.empty  last.front != r.front; last.popFront, r.popFront)
  {
  }
  return r;
 }
 
 This will work properly on lists and vectors, but horrendously on files 
 and sockets. This is because input ranges can't be saved for later use: 
 incrementing r also increments popFront and essentially forces both to 
 look at the same current value.
 
 I'm thinking a better design is to require any range that's forward or 
 better to define a function save(). Ranges that don't implement it are 
 input ranges; those that do, will guarantee a brand new range is 
 returned from save(). So then adjacentFind would look like this:
 
 R adjacentFind(R)(R r)
 {
  if (r,empty) return r;
  R last = r.save;
  r.popFront;
  for (; !r.empty  last.front != r.front; last.popFront, r.popFront)
  {
  }
  return r;
 }
 
 Obviously, when you pass a range that doesn't support save, adjacentFind 
 will not compile, which is what we want.
 
 Andrei
 
 P.S. There is a way to implement adjacentFind for forward ranges by 
 saving data instead of ranges. I've used a limited version above for 
 illustration purposes.



Re: the last change for ranges

2009-05-20 Thread Denis Koroskin
On Wed, 20 May 2009 20:23:27 +0400, Denis Koroskin 2kor...@gmail.com wrote:

 On Wed, 20 May 2009 20:19:30 +0400, Andrei Alexandrescu  
 seewebsiteforem...@erdani.org wrote:

 In wake of a few discussion I've witnessed, I'm thinking of a last
 change for ranges. (In fact there's one more, but that's minor.)

 The problem is that input ranges and forward ranges have the same
 syntactic interface, but different semantic interfaces. Consider the
 problem of finding the first two identical adjacent items in a range:

 R adjacentFind(R)(R r)
 {
  if (r,empty) return r;
  R last = r;
  r.popFront;
  for (; !r.empty  last.front != r.front; last.popFront,  
 r.popFront)
  {
  }
  return r;
 }

 This will work properly on lists and vectors, but horrendously on files
 and sockets. This is because input ranges can't be saved for later use:
 incrementing r also increments popFront and essentially forces both to
 look at the same current value.

 I'm thinking a better design is to require any range that's forward or
 better to define a function save(). Ranges that don't implement it are
 input ranges; those that do, will guarantee a brand new range is
 returned from save(). So then adjacentFind would look like this:

 R adjacentFind(R)(R r)
 {
  if (r,empty) return r;
  R last = r.save;
  r.popFront;
  for (; !r.empty  last.front != r.front; last.popFront,  
 r.popFront)
  {
  }
  return r;
 }

 Obviously, when you pass a range that doesn't support save, adjacentFind
 will not compile, which is what we want.

 Andrei

 P.S. There is a way to implement adjacentFind for forward ranges by
 saving data instead of ranges. I've used a limited version above for
 illustration purposes.

 Why not r.dup?

Nevermind, I don't want to turn it into a bycicle shed discussion, but .dup 
would be consistent with arrays.

Do you suggest that ranges now have a reference semantics? That's quite a big 
change, but I do believe that it's for good, because it make classes a rightful 
ranges citizen.


Re: with still sucks + removing features + adding features

2009-05-20 Thread Andrei Alexandrescu

KennyTM~ wrote:

Andrei Alexandrescu wrote:

Denis Koroskin wrote:
On Wed, 20 May 2009 00:43:56 +0400, Andrei Alexandrescu 
seewebsiteforem...@erdani.org wrote:


It's an awful idea. It's a non-idea. If idea had an antonym, that  
would be it.


I can't fathom what's on the mind of a person (not you, at least you
foresee some potential problems) who, even after patiently explained 
the

issues with this mental misfire, several times, still can bring
themselves to think it's not that bad.



Your post is emotional rather than rational.


Agreed. In my defense, let me mention that I've been rational in my 
previous 50 posts on the topic :o).



Let me add one more, although more than sure someone will find a remedy
for it, too.

a...b

vs.

a.. .b



a..b vs a.b - no one complains


You see, you didn't understand my point. My point was that the 
introduction of a space changes semantics. We should avoid that.




Like,

a- --b

vs.

a-- -b

?


Yes, like that. I didn't say there aren't any right now. I said we 
should avoid that.



Andrei



Re: the last change for ranges

2009-05-20 Thread Robert Fraser

dsimcha wrote:

Also, while we're fine tuning input
ranges vs. forward ranges, I think the concept of iterables as a catch-all for
ranges, opApply, builtins, etc. needs to be introduced and fine tuned, too.  
We've
shown on this NG previously that, while ranges are usually preferable for the
flexibility they offer, opApply does have its legitimate use cases.


An input/forward range is basically just another name/syntax for an 
iterable. Perhaps algorithms that work on input ranges should be written 
using foreach instead of front/popFront?


Re: the last change for ranges

2009-05-20 Thread Andrei Alexandrescu

Robert Fraser wrote:

dsimcha wrote:

Also, while we're fine tuning input
ranges vs. forward ranges, I think the concept of iterables as a 
catch-all for
ranges, opApply, builtins, etc. needs to be introduced and fine tuned, 
too.  We've
shown on this NG previously that, while ranges are usually preferable 
for the

flexibility they offer, opApply does have its legitimate use cases.


An input/forward range is basically just another name/syntax for an 
iterable. Perhaps algorithms that work on input ranges should be written 
using foreach instead of front/popFront?


For most, foreach is not sufficient.

Andrei


Re: the last change for ranges

2009-05-20 Thread dsimcha
== Quote from Denis Koroskin (2kor...@gmail.com)'s article
 Why not r.dup?

.dup is supposed to imply copying of the range's contents, not copying of the
range's iteration state.


Re: the last change for ranges

2009-05-20 Thread Andrei Alexandrescu

Jason House wrote:

Andrei Alexandrescu Wrote:


Jason House wrote:

I feel like there are too many differences between input and forward
ranges for such a minor difference. Many range functions are written
assuming no side effects on the caller. This can restrict the use of
helper functions. It may be best to make their usage different...
So how do you think we should go about it? Also don't forget that any 
ranges should be seamlessly and efficiently treated as input ranges.


Andrei


You won't like my answer!

Like you've already said, the semantics of forward ranges and input ranges are 
different. I would argue that forward ranges have value semantics but input 
ranges do not. Any function that implicitly assumes value semantics is wrong. 
Sadly, overlapping API's makes that all too easy for someone to write bad code 
that passes simplistic tests with forward ranges and then fail with input 
ranges.

My initial thoughts is that input ranges should have two changes:
1. A different API from forward ranges
2. Be a reference type (AKA class instead of struct)

In short, I disagree with your basic premise of treating the two ranges 
similarly.


I don't want to treat them similarly, but we should be able to treat 
forward ranges as input ranges. Otherwise, all algorithms that work for 
input ranges would have to be written twice.


Andrei


Re: the last change for ranges

2009-05-20 Thread Jason House
Andrei Alexandrescu Wrote:

 Jason House wrote:
  I feel like there are too many differences between input and forward
  ranges for such a minor difference. Many range functions are written
  assuming no side effects on the caller. This can restrict the use of
  helper functions. It may be best to make their usage different...
 
 So how do you think we should go about it? Also don't forget that any 
 ranges should be seamlessly and efficiently treated as input ranges.
 
 Andrei

You won't like my answer!

Like you've already said, the semantics of forward ranges and input ranges are 
different. I would argue that forward ranges have value semantics but input 
ranges do not. Any function that implicitly assumes value semantics is wrong. 
Sadly, overlapping API's makes that all too easy for someone to write bad code 
that passes simplistic tests with forward ranges and then fail with input 
ranges.

My initial thoughts is that input ranges should have two changes:
1. A different API from forward ranges
2. Be a reference type (AKA class instead of struct)

In short, I disagree with your basic premise of treating the two ranges 
similarly.


Re: the last change for ranges

2009-05-20 Thread dsimcha
== Quote from Jason House (jason.james.ho...@gmail.com)'s article
 Andrei Alexandrescu Wrote:
  Jason House wrote:
   I feel like there are too many differences between input and forward
   ranges for such a minor difference. Many range functions are written
   assuming no side effects on the caller. This can restrict the use of
   helper functions. It may be best to make their usage different...
 
  So how do you think we should go about it? Also don't forget that any
  ranges should be seamlessly and efficiently treated as input ranges.
 
  Andrei
 You won't like my answer!
 Like you've already said, the semantics of forward ranges and input ranges are
different. I would argue that forward ranges have value semantics but input 
ranges
do not. Any function that implicitly assumes value semantics is wrong. Sadly,
overlapping API's makes that all too easy for someone to write bad code that
passes simplistic tests with forward ranges and then fail with input ranges.
 My initial thoughts is that input ranges should have two changes:
 1. A different API from forward ranges
 2. Be a reference type (AKA class instead of struct)
 In short, I disagree with your basic premise of treating the two ranges 
 similarly.

Then how would you handle functions that only require lowest common denominator
functionality?  This is true for *a lot* of cases, including some important ones
like finding the mean and standard deviation some object.  (Incidentally, this 
is
also where iterable comes in, since such a function doesn't even need to care if
the iteration is with ranges, opApply, or the fairy #$()@* god mother, as long 
as
foreach somehow works.)  You mean to tell me you'd require explicit handling of
both the input range and forward range case separately in these cases?  The day
this happens, I switch to Java because D will have become just as much of an
insanely verbose bondage and discipline language, but with less libraries.


Re: the last change for ranges

2009-05-20 Thread Denis Koroskin
On Wed, 20 May 2009 20:19:30 +0400, Andrei Alexandrescu 
seewebsiteforem...@erdani.org wrote:

 In wake of a few discussion I've witnessed, I'm thinking of a last  
 change for ranges. (In fact there's one more, but that's minor.)

 The problem is that input ranges and forward ranges have the same  
 syntactic interface, but different semantic interfaces. Consider the  
 problem of finding the first two identical adjacent items in a range:

 R adjacentFind(R)(R r)
 {
  if (r,empty) return r;
  R last = r;
  r.popFront;
  for (; !r.empty  last.front != r.front; last.popFront, r.popFront)
  {
  }
  return r;
 }

 This will work properly on lists and vectors, but horrendously on files  
 and sockets. This is because input ranges can't be saved for later use:  
 incrementing r also increments popFront and essentially forces both to  
 look at the same current value.

 I'm thinking a better design is to require any range that's forward or  
 better to define a function save(). Ranges that don't implement it are  
 input ranges; those that do, will guarantee a brand new range is  
 returned from save(). So then adjacentFind would look like this:

 R adjacentFind(R)(R r)
 {
  if (r,empty) return r;
  R last = r.save;
  r.popFront;
  for (; !r.empty  last.front != r.front; last.popFront, r.popFront)
  {
  }
  return r;
 }

 Obviously, when you pass a range that doesn't support save, adjacentFind  
 will not compile, which is what we want.

 Andrei

 P.S. There is a way to implement adjacentFind for forward ranges by  
 saving data instead of ranges. I've used a limited version above for  
 illustration purposes.

Why not r.dup?


Re: the last change for ranges

2009-05-20 Thread Bill Baxter
On Wed, May 20, 2009 at 11:44 AM, Andrei Alexandrescu
seewebsiteforem...@erdani.org wrote:
 Jason House wrote:

 Andrei Alexandrescu Wrote:

 Jason House wrote:

 I feel like there are too many differences between input and forward
 ranges for such a minor difference. Many range functions are written
 assuming no side effects on the caller. This can restrict the use of
 helper functions. It may be best to make their usage different...

 So how do you think we should go about it? Also don't forget that any
 ranges should be seamlessly and efficiently treated as input ranges.

 Andrei

 You won't like my answer!

 Like you've already said, the semantics of forward ranges and input ranges
 are different. I would argue that forward ranges have value semantics but
 input ranges do not. Any function that implicitly assumes value semantics is
 wrong. Sadly, overlapping API's makes that all too easy for someone to write
 bad code that passes simplistic tests with forward ranges and then fail with
 input ranges.

 My initial thoughts is that input ranges should have two changes:
 1. A different API from forward ranges
 2. Be a reference type (AKA class instead of struct)

 In short, I disagree with your basic premise of treating the two ranges
 similarly.

 I don't want to treat them similarly, but we should be able to treat forward
 ranges as input ranges. Otherwise, all algorithms that work for input ranges
 would have to be written twice.

auto inp = std.typecons.inputRangeFromForwardRange(fwd);


No need to write the algos twice now, but you do have to add a line or
two of code to every input range algo.  Or force the the user to call
the converter function.

--bb


Re: the last change for ranges

2009-05-20 Thread Robert Jacques
On Wed, 20 May 2009 13:04:42 -0400, Andrei Alexandrescu  
seewebsiteforem...@erdani.org wrote:

Bill Baxter wrote:

On Wed, May 20, 2009 at 9:19 AM, Andrei Alexandrescu
seewebsiteforem...@erdani.org wrote:


I'm thinking a better design is to require any range that's forward or
better to define a function save(). Ranges that don't implement it are  
input
ranges; those that do, will guarantee a brand new range is returned  
from

save(). So then adjacentFind would look like this:

R adjacentFind(R)(R r)
{
   if (r,empty) return r;
   R last = r.save;
   r.popFront;
   for (; !r.empty  last.front != r.front; last.popFront, r.popFront)
   {
   }
   return r;
}

Obviously, when you pass a range that doesn't support save,  
adjacentFind

will not compile, which is what we want.

 The only other alternative that comes to mind would be forcing input
ranges to hide their copy constructor, or whatever the D equivalent
is, making R last = r; fail.  But that would make input ranges very
difficult to use.


Exactly. I thought of that design, and it was difficult to even pass a  
range to a function.



So, of those two options at least, requiring a .save sounds like the
better choice.
 The down side is you will get no error if you write the code the first
way, without a .save.   I see this as turning into tip #5 in
Effective D -- Know when to use .save   It would be nice if that
potential mistake could be eliminated somehow.  You could perhaps
require input ranges to implement transfer semantics, and have them
implement a .clone for cases when you really do want to make an
aliasing copy.


Good point. I don't have a solution for that. Giving ranges move  
semantics would probably make for another Effective D tip (or perhaps  
more... move semantics are pretty brutal).


Another partial solution is to define a different interface for input  
ranges, one that combines front() and popFront(). Something like  
popNext. That way, people who use only the primitives empty() and  
popNext() know they are using a forward range and with hope they'll  
remember they can't really save copies of it and expect them to  
remember where they are in the input.



Andrei


Bicycle shed: Well, since output ranges use 'put', how about 'get' for  
input ranges?


Re: the last change for ranges

2009-05-20 Thread Bill Baxter
On Wed, May 20, 2009 at 9:19 AM, Andrei Alexandrescu
seewebsiteforem...@erdani.org wrote:

 I'm thinking a better design is to require any range that's forward or
 better to define a function save(). Ranges that don't implement it are input
 ranges; those that do, will guarantee a brand new range is returned from
 save(). So then adjacentFind would look like this:

 R adjacentFind(R)(R r)
 {
    if (r,empty) return r;
    R last = r.save;
    r.popFront;
    for (; !r.empty  last.front != r.front; last.popFront, r.popFront)
    {
    }
    return r;
 }

 Obviously, when you pass a range that doesn't support save, adjacentFind
 will not compile, which is what we want.

The only other alternative that comes to mind would be forcing input
ranges to hide their copy constructor, or whatever the D equivalent
is, making R last = r; fail.  But that would make input ranges very
difficult to use.

So, of those two options at least, requiring a .save sounds like the
better choice.

The down side is you will get no error if you write the code the first
way, without a .save.   I see this as turning into tip #5 in
Effective D -- Know when to use .save   It would be nice if that
potential mistake could be eliminated somehow.  You could perhaps
require input ranges to implement transfer semantics, and have them
implement a .clone for cases when you really do want to make an
aliasing copy.

--bb


Re: the last change for ranges

2009-05-20 Thread dsimcha
== Quote from Bill Baxter (wbax...@gmail.com)'s article
 On Wed, May 20, 2009 at 11:44 AM, Andrei Alexandrescu
 seewebsiteforem...@erdani.org wrote:
  Jason House wrote:
 
  Andrei Alexandrescu Wrote:
 
  Jason House wrote:
 
  I feel like there are too many differences between input and forward
  ranges for such a minor difference. Many range functions are written
  assuming no side effects on the caller. This can restrict the use of
  helper functions. It may be best to make their usage different...
 
  So how do you think we should go about it? Also don't forget that any
  ranges should be seamlessly and efficiently treated as input ranges.
 
  Andrei
 
  You won't like my answer!
 
  Like you've already said, the semantics of forward ranges and input ranges
  are different. I would argue that forward ranges have value semantics but
  input ranges do not. Any function that implicitly assumes value semantics 
  is
  wrong. Sadly, overlapping API's makes that all too easy for someone to 
  write
  bad code that passes simplistic tests with forward ranges and then fail 
  with
  input ranges.
 
  My initial thoughts is that input ranges should have two changes:
  1. A different API from forward ranges
  2. Be a reference type (AKA class instead of struct)
 
  In short, I disagree with your basic premise of treating the two ranges
  similarly.
 
  I don't want to treat them similarly, but we should be able to treat forward
  ranges as input ranges. Otherwise, all algorithms that work for input ranges
  would have to be written twice.
 auto inp = std.typecons.inputRangeFromForwardRange(fwd);
 No need to write the algos twice now, but you do have to add a line or
 two of code to every input range algo.  Or force the the user to call
 the converter function.
 --bb

But if you make the input range a class as Jason proposed, then:

1.  Unless it's final, its methods will be virtual (slow).
2.  You trigger a heap allocation every time you want to make this conversion.  
(slow)


Re: the last change for ranges

2009-05-20 Thread dsimcha
== Quote from Bill Baxter (wbax...@gmail.com)'s article
 On Wed, May 20, 2009 at 11:44 AM, Andrei Alexandrescu
 seewebsiteforem...@erdani.org wrote:
  Jason House wrote:
 
  Andrei Alexandrescu Wrote:
 
  Jason House wrote:
 
  I feel like there are too many differences between input and forward
  ranges for such a minor difference. Many range functions are written
  assuming no side effects on the caller. This can restrict the use of
  helper functions. It may be best to make their usage different...
 
  So how do you think we should go about it? Also don't forget that any
  ranges should be seamlessly and efficiently treated as input ranges.
 
  Andrei
 
  You won't like my answer!
 
  Like you've already said, the semantics of forward ranges and input ranges
  are different. I would argue that forward ranges have value semantics but
  input ranges do not. Any function that implicitly assumes value semantics 
  is
  wrong. Sadly, overlapping API's makes that all too easy for someone to 
  write
  bad code that passes simplistic tests with forward ranges and then fail 
  with
  input ranges.
 
  My initial thoughts is that input ranges should have two changes:
  1. A different API from forward ranges
  2. Be a reference type (AKA class instead of struct)
 
  In short, I disagree with your basic premise of treating the two ranges
  similarly.
 
  I don't want to treat them similarly, but we should be able to treat forward
  ranges as input ranges. Otherwise, all algorithms that work for input ranges
  would have to be written twice.
 auto inp = std.typecons.inputRangeFromForwardRange(fwd);
 No need to write the algos twice now, but you do have to add a line or
 two of code to every input range algo.  Or force the the user to call
 the converter function.
 --bb

On a broader note, I think that people need to understand that, just as a free
society can never be a perfectly safe society, a language that allows 
programmers
the freedom to create concise, general and efficient constructs can never be a
perfectly safe language.  Yes, we could make D as safe as Java, but then
programming in D would be like programming in Java--an exercise in superfluous
verbosity and getting around the language's rigidity.


Re: the last change for ranges

2009-05-20 Thread Andrei Alexandrescu

Jason House wrote:

I feel like there are too many differences between input and forward
ranges for such a minor difference. Many range functions are written
assuming no side effects on the caller. This can restrict the use of
helper functions. It may be best to make their usage different...


So how do you think we should go about it? Also don't forget that any 
ranges should be seamlessly and efficiently treated as input ranges.


Andrei


Re: OT: on IDEs and code writing on steroids

2009-05-20 Thread Nick Sabalausky
Christopher Wright dhase...@gmail.com wrote in message 
news:gv0p4e$uv...@digitalmars.com...
 Nick Sabalausky wrote:
 I can see certain potential benefits to the general way C# does generics, 
 but until the old (and I do mean old) issue of There's an IComparable, 
 so why the hell won't MS give us an IArithmetic so we can actually use 
 arithmetic operators on generic code? gets fixed (and at this point I'm 
 convinced they've never had any intent of ever fixing that), I don't care 
 how valid the reasoning behind C#'s general approach to generics is, the 
 actual state of C#'s generics still falls squarely into the categories of 
 crap and almost useless.

 IArithmetic is impossible in C# because operator overloads are static 
 methods, and interfaces cannot specify static methods.

Then how does IComparable work? 




Re: the last change for ranges

2009-05-20 Thread Robert Jacques
On Wed, 20 May 2009 14:02:02 -0400, Andrei Alexandrescu  
seewebsiteforem...@erdani.org wrote:



Robert Jacques wrote:
Bicycle shed: Well, since output ranges use 'put', how about 'get' for  
input ranges?


Nice color :o). In fact, put is a poor choice because it doesn't  
reflect advancement. Probably putNext and getNext are better.


Andrei


Well, on that note, more shed colors and common use cases:
  stacks, queues, messge passing, file I/O, network I/O, confusion  
factor

send/recv  weak ,  okay ,  good ,  weak   ,good,low
sink/rise  bad  ,  bad  ,  bad  ,  bad,bad ,high
push/pop   good ,  okay ,  okay ,  okay   ,okay,high


Re: the last change for ranges

2009-05-20 Thread Andrei Alexandrescu

dsimcha wrote:

== Quote from Denis Koroskin (2kor...@gmail.com)'s article

Why not r.dup?


.dup is supposed to imply copying of the range's contents, not copying of the
range's iteration state.


Yes, for arrays save() is:

T[] save(T)(T[] r) { return r; }


Andrei


Re: OT: on IDEs and code writing on steroids

2009-05-20 Thread Yigal Chripun

BCS wrote:

  minor point; I said you have to give the compiler all the source files.
You might not actually nned to compile them all, but without some 
external meta data, it still needs to be handled the full because it 
can't find them on it's own. And at that point you might as well compile 
them anyway.


you are only considering small hobby projects. that's not true for big 
projects where you do not want to build all at once. Think of DWT for 
instance.
besides, you do NOT need to provide all sources, not even just for 
partially processing them to find the symbols.

there is no difference between C#'s /r someAssembly and GCC's -llib

I don't think you fully understand the C# compilation model -
in C# you almost never compile each source file separately, rather you 
compile a bunch of sources into an assembly all at once and you provide 
the list of other assemblies your code depends on. so the dependency is 
on the package level rather than on the file level. this make so much 
more sense since each assembly is a self contained unit of functionality.





sure, you don't get the full power of an IDE that can track all the
source files in the project for you. That just means that it's worth
the money you pay for it.

you can write makefiles or what ever (scons, rake, ant, ...) in the
same way you'd do for C and C++. In other words:
if you prefer commnad line tools you get the same experience and if
you do use an IDE you get a *much* better experience.
same goes for D - either write your own makefile or use rebuild which




uses the compiler front-end to parse the source files just like you
suggested above for C#.



where did I suggest that?


I replied to both you and Daniel. I think I was referring to what Daniel 
said here.





where in all of that, do you see any contradiction to what I said?
again, I said the D compilation model is ancient legacy and should be
replaced and that has nothing to do with the format you prefer for
your build scripts.



I think that you think I'm saying something other than what I'm trying 
to say. I'm struggling to make my argument clear but can't seem to put 
it in words. My thesis is that, in effect, C# is married to VS and that 
D is married only to the compiler.


I understand your thesis and disagree with it. what i'm saying is that 
not only C# is NOT married to VS but also that VS isn't even the best 
IDE for C#. VS is just a fancy text-editor with lots of bells and 
whistles. if you want a real IDE for C# you'd probably use Re-Sharper or 
a similar offering.


My argument is that a D project can be done as nothing but a collection 
of .d files with no extra project files of any kind. In c# this is 
theoretically possible, but from any practical standpoint it's not going 
to be done. There is going to be some extra files that list, in some 
form, extra information the compiler needs to resolve symbols and figure 
out where to look for stuff. In any practical environment this extra bit 
that c# more or less forces you to have (and the D doesn't) will be 
maintain by some sort of IDE.


this is wrong. you cannot have a big project based solely on .d files. 
look at DWT as an example. no matter what tool you use, let's say DSSS, 
it still has a config file of some sort which contains that additional 
meta-data. a DSSS config file might be shorter than what's required for 
a C# project file but don't forget that this comes from DSSS relying on 
rebuild which embeds the entire DMDFE.

in practice, both languages need more than just the compiler.



To put it quantitatively:

productivity on a scale of 0 to whatever
c# w/o IDE - ~1
D w/o IDE - 10
c# w/ IDE - 100+
D w/ IDE - 100+

Either C# or D will be lots more productive with an IDE but D without an 
IDE will be lots more productive than C# without an IDE. D is designed 
to be used however you want, IDE or not. C# is *designed* to be used 
from within VS. I rather suspect that the usability of C# without VS is 
very low on MS things we care about list.







Re: the last change for ranges

2009-05-20 Thread Bill Baxter
On Wed, May 20, 2009 at 12:05 PM, dsimcha dsim...@yahoo.com wrote:
 == Quote from Bill Baxter (wbax...@gmail.com)'s article
 On Wed, May 20, 2009 at 11:44 AM, Andrei Alexandrescu
 seewebsiteforem...@erdani.org wrote:
  Jason House wrote:
 
  Andrei Alexandrescu Wrote:
 
  Jason House wrote:
 
  I feel like there are too many differences between input and forward
  ranges for such a minor difference. Many range functions are written
  assuming no side effects on the caller. This can restrict the use of
  helper functions. It may be best to make their usage different...
 
  So how do you think we should go about it? Also don't forget that any
  ranges should be seamlessly and efficiently treated as input ranges.
 
  Andrei
 
  You won't like my answer!
 
  Like you've already said, the semantics of forward ranges and input ranges
  are different. I would argue that forward ranges have value semantics but
  input ranges do not. Any function that implicitly assumes value semantics 
  is
  wrong. Sadly, overlapping API's makes that all too easy for someone to 
  write
  bad code that passes simplistic tests with forward ranges and then fail 
  with
  input ranges.
 
  My initial thoughts is that input ranges should have two changes:
  1. A different API from forward ranges
  2. Be a reference type (AKA class instead of struct)
 
  In short, I disagree with your basic premise of treating the two ranges
  similarly.
 
  I don't want to treat them similarly, but we should be able to treat 
  forward
  ranges as input ranges. Otherwise, all algorithms that work for input 
  ranges
  would have to be written twice.
 auto inp = std.typecons.inputRangeFromForwardRange(fwd);
 No need to write the algos twice now, but you do have to add a line or
 two of code to every input range algo.  Or force the the user to call
 the converter function.
 --bb

 But if you make the input range a class as Jason proposed, then:

 1.  Unless it's final, its methods will be virtual (slow).
 2.  You trigger a heap allocation every time you want to make this 
 conversion.  (slow)

Maybe, but I don't really agree that input ranges should be forced to
be classes.  Seems like they should be allowed to be either as long as
they support the required methods.

Actually that's a good argument for not making  a = b part of the
Forward Range concept.   If you get rid of that one, then Forward
Ranges can be either classes or structs too.

--bb


Re: OT: on IDEs and code writing on steroids

2009-05-20 Thread Yigal Chripun

Andrei Alexandrescu wrote:

Lutger wrote:

Andrei Alexandrescu wrote:

...
What the heck do you need generics for when you have real 
templates?  To me,

generics seem like just a lame excuse for templates.
I agree. Then, templates aren't easy to implement and they were 
understandably already busy implementing the using statement.


Andrei


While I don't fully understand how generics work under the hood in 
.NET, there are some benefits to how it is done. For example, you can 
use runtime reflection on generic types. And the jit compiler 
instantiates them at runtime. They may serve a different purpose than 
templates:


Anders Hejlsberg: To me the best way to understand the distinction 
between C# generics and C++ templates is this: C# generics are really 
just like classes, except they have a type parameter. C++ templates 
are really just like macros, except they look like classes.

It seems that lack of structural typing is seen as a feature:

When you think about it, constraints are a pattern matching 
mechanism. You want to be able to say, This type parameter must have 
a constructor that takes two arguments, implement operator+, have this 
static method, has these two instance methods, etc. The question is, 
how complicated do you want this pattern matching mechanism to be?
There's a whole continuum from nothing to grand pattern matching. We 
think it's too little to say nothing, and the grand pattern matching 
becomes very complicated, so we're in- between. 
From: http://www.artima.com/intv/genericsP.html


Oh, so Wal^H^H^Ha friend of mine I was talking to was right: there's 
some missing of the point point going on. The code generation aspect of 
templates is a blind spot of the size of Canada.


Andrei


I think you miss the point here.
Generics and code generation are two separate and orthogonal features 
that where conflated together by C++.


while you can do powerful stuff with templates it smells of trying to 
write Haskel code with the C pre-proceesor.

if you want to see a clean solution to this issue look at Nemerle.
essentially, their AST Macro system provides multi-level compilation.

c++ templates are a horrible hack designed to ween off C programmers 
from using the pre-processor and the D templates provide mostly cosmetic 
 changes to this. they do not solve the bigger design issue.


Re: OT: on IDEs and code writing on steroids

2009-05-20 Thread Andrei Alexandrescu

Yigal Chripun wrote:

I think you miss the point here.
Generics and code generation are two separate and orthogonal features 
that where conflated together by C++.


It's kind of odd, then, that for example the Generative Programming book 
(http://www.generative-programming.org) chose to treat the two notions 
in conjunction.


while you can do powerful stuff with templates it smells of trying to 
write Haskel code with the C pre-proceesor.

if you want to see a clean solution to this issue look at Nemerle.
essentially, their AST Macro system provides multi-level compilation.

c++ templates are a horrible hack designed to ween off C programmers 
from using the pre-processor and the D templates provide mostly cosmetic 
 changes to this. they do not solve the bigger design issue.


What is the bigger design issue?


Andrei


Re: OT: on IDEs and code writing on steroids

2009-05-20 Thread dsimcha
== Quote from Yigal Chripun (yigal...@gmail.com)'s article
 Andrei Alexandrescu wrote:
  Lutger wrote:
  Andrei Alexandrescu wrote:
 
  ...
  What the heck do you need generics for when you have real
  templates?  To me,
  generics seem like just a lame excuse for templates.
  I agree. Then, templates aren't easy to implement and they were
  understandably already busy implementing the using statement.
 
  Andrei
 
  While I don't fully understand how generics work under the hood in
  .NET, there are some benefits to how it is done. For example, you can
  use runtime reflection on generic types. And the jit compiler
  instantiates them at runtime. They may serve a different purpose than
  templates:
 
  Anders Hejlsberg: To me the best way to understand the distinction
  between C# generics and C++ templates is this: C# generics are really
  just like classes, except they have a type parameter. C++ templates
  are really just like macros, except they look like classes.
  It seems that lack of structural typing is seen as a feature:
 
  When you think about it, constraints are a pattern matching
  mechanism. You want to be able to say, This type parameter must have
  a constructor that takes two arguments, implement operator+, have this
  static method, has these two instance methods, etc. The question is,
  how complicated do you want this pattern matching mechanism to be?
  There's a whole continuum from nothing to grand pattern matching. We
  think it's too little to say nothing, and the grand pattern matching
  becomes very complicated, so we're in- between.
  From: http://www.artima.com/intv/genericsP.html
 
  Oh, so Wal^H^H^Ha friend of mine I was talking to was right: there's
  some missing of the point point going on. The code generation aspect of
  templates is a blind spot of the size of Canada.
 
  Andrei
 I think you miss the point here.
 Generics and code generation are two separate and orthogonal features
 that where conflated together by C++.
 while you can do powerful stuff with templates it smells of trying to
 write Haskel code with the C pre-proceesor.
 if you want to see a clean solution to this issue look at Nemerle.
 essentially, their AST Macro system provides multi-level compilation.
 c++ templates are a horrible hack designed to ween off C programmers
 from using the pre-processor and the D templates provide mostly cosmetic
   changes to this. they do not solve the bigger design issue.

Not sure I agree.  C++ templates were probably intended to be something like
generics initially and became Turing-complete almost by accident.  To get Turing
completeness in C++ templates requires severe abuse of features and spaghetti 
code
writing.  D extends templates so that they're actually *designed* for
metaprogramming, not just an implementation of generics, thus solving C++'s 
design
problem.  Mixins (to really allow code generation), CTFE (to make it easier to
generate code), static if (to avoid kludges like using specialization just to 
get
branching) and tuples (to handle variadics) make D templates useful for
metaprogramming without massive kludges.


Re: the last change for ranges

2009-05-20 Thread Kristian Kilpi
On Wed, 20 May 2009 21:02:02 +0300, Andrei Alexandrescu  
seewebsiteforem...@erdani.org wrote:



Robert Jacques wrote:
Bicycle shed: Well, since output ranges use 'put', how about 'get' for  
input ranges?


Nice color :o). In fact, put is a poor choice because it doesn't  
reflect advancement. Probably putNext and getNext are better.


Andrei


(Just thinking aloud... :) ) I have been using get() + set() and read() +  
write().

read() and write() advance to the next item; get() + set() do not.

Actually I have implemented my iterator classes (in C++) as follows  
(simplified):


BasicIFlow:
read()
toNext()
isEnd()

IFlow:
get()
read()
toNext()
isEnd()

Iter:
get()
read()
toNext()
toPrev()
isBegin()
isFirst()
isLast()
isEnd()

As seen, Iter is a two-way iterator, and the other two are one-way  
iterators. (And there are correponding output iterators too, of course.)


There are also functions like toFirst(), toEnd(), etc (only Iter has  
toFirst()). And for convenience, Iter also has functions like getNext()  
and getPrev() that return the next/previous item without moving the  
iterator. So there are quite many functions, which is not necessary good  
;) (although many of them have default functionality that simply calls the  
other core functions; for example, read() *could* be written with get()  
+ toNext()).


I know very little about Ranges (when I have time, that will change), but  
if I'm not mistaken, they hold and modify the beginning and end of the  
iterated area? That's an interesting and unique approach. :) My classes  
move a cursor inside the iterated area. Of course, with the Flow classes,  
the beginning of the area is moved together with the cursor (as the cursor  
cannot move backwards).


Re: OT: on IDEs and code writing on steroids

2009-05-20 Thread Andrei Alexandrescu

dsimcha wrote:

Not sure I agree.  C++ templates were probably intended to be something like
generics initially and became Turing-complete almost by accident.


That is factually correct. It was quite a hubbub on the C++ 
standardization committee when Erwin Unruh wrote a C++ program that 
wrote prime numbers in error messages. See http://tinyurl.com/oqk6nl


Andrei


Re: OT: on IDEs and code writing on steroids

2009-05-20 Thread Jacob Carlborg

dsimcha wrote:

== Quote from Ary Borenszweig (a...@esperanto.org.ar)'s article

dsimcha escribió:

== Quote from Christopher Wright (dhase...@gmail.com)'s article

Nick Sabalausky wrote:

Andrei Alexandrescu seewebsiteforem...@erdani.org wrote in message
news:gus0lu$1sm...@digitalmars.com...


I've repeatedly failed to figure out the coolness of C#, and would
appreciate a few pointers. Or references. Or delegates :o).

Outside of this group, I think most of the people considering C# really cool
are people who are unaware of D and are coming to C# from Java. What's
cool about C# is that it's like a less-shitty version of Java (and *had*
good tools, although the newer versions of VS are almost as much of a
bloated unresponsive mess as Eclipse - Which come to think of it, makes me
wonder - If Java has gotten so fast as many people claim, why is Eclipse
still such a sluggish POS?).

Compare C# to D though and most of the coolness fades, even though there are
still a handful of things I think D could still learn from C# (but there's
probably more than a handful that C# could learn from D).

Generics and reflection. Generics just hide a lot of casts, usually, but
that's still quite useful. And autoboxing is convenient, though not
appropriate for D.

What the heck do you need generics for when you have real templates?  To me,
generics seem like just a lame excuse for templates.

Yesterday doob reported a bug in Descent saying when you compile your
project and it references a user library that has errors, when you click
on the console to jump to the error, it doesn't work. I said to him: I
never thought a user library could have errors! How did this happen to
you? He replied: I found a bug in a template in Tango.
That's why generics doesn't suck: if there's something wrong in them,
the compiler tells you in compile-time. In D, you get the errors only
when instantiating that template.
Generics might not be as powerful as templates, but once you write one
that compiles, you know you will always be able to instantiate it.


Yes, but there are two flaws in this argument:

1.  If you are only using templates like generics, you simply use a unit test to
see if it compiles.  If you're not doing anything fancy and it compiles for one 
or
two types, it will probably compile for everything that you would reasonably
expect it to.


I used tango.text.xml.Document with wchar and dchar as the template type 
and in tango.text.xml.PullParser there were some functions that took 
char[] instead of T[] as the argument. 
http://www.dsource.org/projects/tango/ticket/1663



2.  If you're doing something fancier, like metaprogramming, you have to just 
face
the fact that this is non-trivial, and couldn't be done with generics anyhow.

3.  As Bearophile alluded to, templates are really a clever hack to give you the
flexibility of a dynamic language with the performance and compile time checking
of a static language.  This is done by moving the dynamism to instantiation 
time.
 Therefore, whereas in a dynamic language you pay at runtime in terms of the 
here
be monsters, this code may not be being used as the author intended and tested
it, with templates you pay at instantiation time.  However, IMHO this is orders
of magnitude better than not having that flexibility at all.  I personally can't
figure out how people accomplish anything in static languages w/o templates.  
It's
just too inflexible.


Re: OT: on IDEs and code writing on steroids

2009-05-20 Thread BCS

Reply to Yigal,


D templates provide mostly cosmetic changes to this.



If you think D's templates are C++'s template with a few cosmetic changes 
than you aren't paying attention.


A few cosmetic changes aren't going to allow 1.4MB of c++ header files to 
be anywhere near duplicated in 2000 LOC (Boost sprit vs dparse)





Re: OT: on IDEs and code writing on steroids

2009-05-20 Thread BCS

Reply to Yigal,


BCS wrote:


minor point; I said you have to give the compiler all the source
files. You might not actually nned to compile them all, but without
some external meta data, it still needs to be handled the full
because it can't find them on it's own. And at that point you might
as well compile them anyway.



(BTW: that is only referring to c#)


you are only considering small hobby projects. that's not true for big
projects where you do not want to build all at once. Think of DWT for
instance. besides, you do NOT need to provide all sources, not even
just for partially processing them to find the symbols.
there is no difference between C#'s /r someAssembly and GCC's -llib
I don't think you fully understand the C# compilation model -

in C# you almost never compile each source file separately, rather you
compile a bunch of sources into an assembly all at once and you provide
the list of other assemblies your code depends on. so the dependency is
on the package level rather than on the file level. this make so much
more sense since each assembly is a self contained unit of
functionality.


That is more or less what I thought it was. Also, that indicates that the 
design of c# assumes a build model that I think is a bad idea; the big dumb 
all or nothing build where a sub part of a program is either up to date, 
or rebuilt by recompiling everything in it.



 where in all of that, do you see any contradiction to what I said?
again, I said the D compilation model is ancient legacy and should
be replaced and that has nothing to do with the format you prefer
for your build scripts.


I think that you think I'm saying something other than what I'm
trying to say. I'm struggling to make my argument clear but can't
seem to put it in words. My thesis is that, in effect, C# is married
to VS and that D is married only to the compiler.


I understand your thesis and disagree with it. what i'm saying is that
not only C# is NOT married to VS but also that VS isn't even the best
IDE for C#.


Maybe I should have said it's married to having *an IDE*, it's just VS by 
default and design.



VS is just a fancy text-editor with lots of bells and
whistles. if you want a real IDE for C# you'd probably use Re-Sharper
or a similar offering.


Last I heard Re-Sharper is a VS plugin, not an IDE in it's own right, and 
even if that has changed, it's still an IDE. Even so, my point is Any IDE 
vs. No IDE, so it dosn't address my point.



My argument is that a D project can be done as nothing but a
collection of .d files with no extra project files of any kind. In c#
this is theoretically possible, but from any practical standpoint
it's not going to be done. There is going to be some extra files that
list, in some form, extra information the compiler needs to resolve
symbols and figure out where to look for stuff. In any practical
environment this extra bit that c# more or less forces you to have
(and the D doesn't) will be maintain by some sort of IDE.


this is wrong. you cannot have a big project based solely on .d files.
look at DWT as an example. no matter what tool you use, let's say DSSS,
it still has a config file of some sort which contains that additional
meta-data.


So DWT depends on DSSS's meta data. That's a design choice of DWT not D. 
What I'm asserting that that C# projects depending on meta data is a design 
choice of C# not the project. D project can (even if some don't) be practically 
designed so that they don't need that meta data where as, I will assert, 
C# projects, for practical purposes, can't do away with it.


--

I'm fine with any build system you want to have implemented as long as a 
tool stack can still be built that works like the current one. That is that 
it can practically:


- support projects that need no external meta data
- produce monolithic OS native binary executables
- work with the only language aware tool being the compiler

I don't expect it to requiter that projects be done that way and I wouldn't 
take any issue if a tool stack were built that didn't fit that list. What 
I /would/ take issue with is the the language (okay, or DMD in particular) 
were altered to the point that one or more of those *couldn't* be done.





Re: the last change for ranges

2009-05-20 Thread Jason House
dsimcha Wrote:

 == Quote from Bill Baxter (wbax...@gmail.com)'s article
  On Wed, May 20, 2009 at 11:44 AM, Andrei Alexandrescu
  seewebsiteforem...@erdani.org wrote:
   Jason House wrote:
  
   Andrei Alexandrescu Wrote:
  
   Jason House wrote:
  
   I feel like there are too many differences between input and forward
   ranges for such a minor difference. Many range functions are written
   assuming no side effects on the caller. This can restrict the use of
   helper functions. It may be best to make their usage different...
  
   So how do you think we should go about it? Also don't forget that any
   ranges should be seamlessly and efficiently treated as input ranges.
  
   Andrei
  
   You won't like my answer!
  
   Like you've already said, the semantics of forward ranges and input 
   ranges
   are different. I would argue that forward ranges have value semantics but
   input ranges do not. Any function that implicitly assumes value 
   semantics is
   wrong. Sadly, overlapping API's makes that all too easy for someone to 
   write
   bad code that passes simplistic tests with forward ranges and then fail 
   with
   input ranges.
  
   My initial thoughts is that input ranges should have two changes:
   1. A different API from forward ranges
   2. Be a reference type (AKA class instead of struct)
  
   In short, I disagree with your basic premise of treating the two ranges
   similarly.
  
   I don't want to treat them similarly, but we should be able to treat 
   forward
   ranges as input ranges. Otherwise, all algorithms that work for input 
   ranges
   would have to be written twice.
  auto inp = std.typecons.inputRangeFromForwardRange(fwd);
  No need to write the algos twice now, but you do have to add a line or
  two of code to every input range algo.  Or force the the user to call
  the converter function.
  --bb
 
 But if you make the input range a class as Jason proposed, then:
 
 1.  Unless it's final, its methods will be virtual (slow).
 2.  You trigger a heap allocation every time you want to make this 
 conversion.  (slow)

Scope classes avoid the heap allocations. Classes are not required for 
referance semantics. Specially constructed structs can also satisfy the 
requirement. By declaring the typical input range to be a (scope final) class, 
I was hoping to emphasize the fundamental difference with forward ranges.

It should be trivial to write a (scope) wrapper that converts a forward range 
into an input range. The compiler should be able to optimize away the wrapper 
or at least inline the functions. 


Re: OT: on IDEs and code writing on steroids

2009-05-20 Thread Bill Baxter
On Wed, May 20, 2009 at 1:09 PM, Andrei Alexandrescu
seewebsiteforem...@erdani.org wrote:
 Yigal Chripun wrote:

 I think you miss the point here.
 Generics and code generation are two separate and orthogonal features that
 where conflated together by C++.

 It's kind of odd, then, that for example the Generative Programming book
 (http://www.generative-programming.org) chose to treat the two notions in
 conjunction.

Yeh, there's definitely a overlap.  Orthogonal isn't quite the right word there.

I'm reading a bit on C++/CLI right now, which is C++ extended to
inter-operate with CLR.
C++/CLI has *both* classic C++ templates and CLR generics:

  templatetypename T ...// all code specializations generated at
compile-time (if at all)
  generictypename T ... // code generated at compiletime
unconditionally, specialized at run-time.

I'm not clear on exactly what happens at runtime in the generic
case.  I had been thinking it was simply that the compiler does some
type checking at compile time and the VM code then just manipulates
pointers to Object from there.  That may be what happens in Java
generics, but in CLR generics at least you can specialize on
non-Object value types and that apparently does not result in
everything getting boxed.  So it seems like there's a little something
extra going on.

I think the main reason for having Generics is that they're the best
anyone currently knows how to do at the IL bytecode level.  Generics
give you a way to define generic parameterized types that work across
all the languages that target a given VM's bytecode.  But that doesn't
preclude any language that targets that VM from *also* implementing
compile-time templates, or code generators, or AST macros at the
source code level.

But the problem with source-level code generation is that you then
need the source code in order to use the library.  I think they were
trying to avoid that with C#.   If you have a compiled C# assembly,
then you have everything you need to use it.   Period.   (I think.)
At any rate, a tech that requires inclusion of source code is not very
interesting to Microsoft, because Microsoft doesn't generally like to
let people see their source code in the first place, and they know
that many of their biggest customers don't like to either.  They're
nervous enough about just putting de-compileable bytecode out there.

--bb


Re: the last change for ranges

2009-05-20 Thread MLT
Andrei Alexandrescu Wrote:

 In wake of a few discussion I've witnessed, I'm thinking of a last 
 change for ranges. (In fact there's one more, but that's minor.)
 
 The problem is that input ranges and forward ranges have the same 
 syntactic interface, but different semantic interfaces. Consider the 
 problem of finding the first two identical adjacent items in a range:
 
 R adjacentFind(R)(R r)
 {
  if (r.empty) return r;
  R last = r;
  r.popFront;
  for (; !r.empty  last.front != r.front; last.popFront, r.popFront)
  {
  }
  return r;
 }
 
 This will work properly on lists and vectors, but horrendously on files 
 and sockets. This is because input ranges can't be saved for later use: 
 incrementing r also increments popFront and essentially forces both to 
 look at the same current value.
 

I think that if
  R last = r;
then after
  r.popFront;
the order of elements in last should not change, no matter what type of range 
you are dealing with. (That means that input operations would be buffered to 
the leftmost range that still extsts.)

If I understood the logic of ranges, popFront() just changes the range, and not 
the elements it points to.


Re: the last change for ranges

2009-05-20 Thread Steven Schveighoffer
On Wed, 20 May 2009 13:35:14 -0400, Andrei Alexandrescu  
seewebsiteforem...@erdani.org wrote:



Jason House wrote:

I feel like there are too many differences between input and forward
ranges for such a minor difference. Many range functions are written
assuming no side effects on the caller. This can restrict the use of
helper functions. It may be best to make their usage different...


So how do you think we should go about it? Also don't forget that any  
ranges should be seamlessly and efficiently treated as input ranges.


Andrei


struct Input(R) // enforce that R is a forward range for type T, not  
versed well enough in D2 to know how to do this yet

{
  R _range; // make this R * if you want Input(R) to be a reference type
  alias _range this;
  auto popNext() { auto result = _range.front; _range.popFront(); return  
result; }
  // and so-on, can leave out truly duplicate functions like empty as the  
alias this will take care of that.

}

// convenience method
Input!(R) asInput(R)(R r)
{
  return Input!(R)(r); // or Input!(R)(new R(r)); if reference type is the  
right answer

}

No extra code required in any forward range, just wrap it.  Input still  
retains the forward range functions as an underlying base if you need BOTH  
input and forward range functionality (not sure why).


-Steve


Re: the last change for ranges

2009-05-20 Thread dsimcha
== Quote from Jason House (jason.james.ho...@gmail.com)'s article
 IMHO, D should have a type with low size and function call overhead  like a
struct as well as reference semantics like a class.

What's wrong with a pointer to a heap-allocated struct?  I sometimes need what 
you
describe, too, and I've never seen a case where this doesn't do the job.


Re: the last change for ranges

2009-05-20 Thread Bill Baxter
On Wed, May 20, 2009 at 4:03 PM, dsimcha dsim...@yahoo.com wrote:
 == Quote from Jason House (jason.james.ho...@gmail.com)'s article
 IMHO, D should have a type with low size and function call overhead  like a
 struct as well as reference semantics like a class.

 What's wrong with a pointer to a heap-allocated struct?  I sometimes need 
 what you
 describe, too, and I've never seen a case where this doesn't do the job.

And you can alias Foo_* Foo, so that it doesn't even look like you're
passing around a pointer.  :-)


--bb


Re: with still sucks + removing features + adding features

2009-05-20 Thread Lutger
Andrei Alexandrescu wrote:

...
 
 So we're looking at a number of problems here. One is that we'd need to 
 change the language in several places to accommodate an ill-conceived 
 feature. Another is that I can't seem to get some very simple points 
 across such as the difference between a token and a non-terminal, in 
 spite of having tried repeatedly and in various forms. Another is that I 
 am becoming suffocated with self-righteousness and therefore am losing 
 goodwill in this thread at an exponentially-increasing rate. Finally, it 
 looks like such discussions necessitate more than a full-time job.
 
 
 Andrei

You could ask Walter for advice on most of these matters ;)



Re: the last change for ranges

2009-05-20 Thread Andrei Alexandrescu

MLT wrote:

I think that if

R last = r;

then after

r.popFront;

the order of elements in last should not change, no matter what
type of range you are dealing with. (That means that input operations
would be buffered to the leftmost range that still extsts.)

If I understood the logic of ranges, popFront() just changes the
range, and not the elements it points to.


That's the case for all ranges except input ranges. Consider:

FileByCharacter
{
private FILE* _f;
private dchar _last;
bool empty() { return _last == 0x; }
void popFront() { _last = fgetc(_f); }
dchar front() { return _last; }
}

Consider what happens when you copy this range around.


Andrei


Re: the last change for ranges

2009-05-20 Thread Jason House
dsimcha Wrote:

 == Quote from Jason House (jason.james.ho...@gmail.com)'s article
  IMHO, D should have a type with low size and function call overhead  like a
 struct as well as reference semantics like a class.
 
 What's wrong with a pointer to a heap-allocated struct?  I sometimes need 
 what you
 describe, too, and I've never seen a case where this doesn't do the job.

That does the job, but it looks ugly ;) I think it's also not allowed in safe 
d. 


Re: the last change for ranges

2009-05-20 Thread Jason House
Bill Baxter Wrote:

 On Wed, May 20, 2009 at 4:03 PM, dsimcha dsim...@yahoo.com wrote:
  == Quote from Jason House (jason.james.ho...@gmail.com)'s article
  IMHO, D should have a type with low size and function call overhead  like 
  a
  struct as well as reference semantics like a class.
 
  What's wrong with a pointer to a heap-allocated struct?  I sometimes need 
  what you
  describe, too, and I've never seen a case where this doesn't do the job.
 
 And you can alias Foo_* Foo, so that it doesn't even look like you're
 passing around a pointer.  :-)
 
 
 --bb

Interesting thought. Wouldn't calls to new still require use of Foo__?


Re: the last change for ranges

2009-05-20 Thread Jason House
Andrei Alexandrescu Wrote:

 MLT wrote:
  I think that if
  R last = r;
  then after
  r.popFront;
  the order of elements in last should not change, no matter what
  type of range you are dealing with. (That means that input operations
  would be buffered to the leftmost range that still extsts.)
  
  If I understood the logic of ranges, popFront() just changes the
  range, and not the elements it points to.
 
 That's the case for all ranges except input ranges. Consider:
 
 FileByCharacter
 {
  private FILE* _f;
  private dchar _last;
  bool empty() { return _last == 0x; }
  void popFront() { _last = fgetc(_f); }
  dchar front() { return _last; }
 }
 
 Consider what happens when you copy this range around.
 
 
 Andrei

You didn't declare FileByCharacter as either a struct or a class? Did I plant a 
seed? :)


Re: the last change for ranges

2009-05-20 Thread dsimcha
== Quote from Jason House (jason.james.ho...@gmail.com)'s article
 dsimcha Wrote:
  == Quote from Jason House (jason.james.ho...@gmail.com)'s article
   IMHO, D should have a type with low size and function call overhead  
   like a
  struct as well as reference semantics like a class.
 
  What's wrong with a pointer to a heap-allocated struct?  I sometimes need 
  what you
  describe, too, and I've never seen a case where this doesn't do the job.
 That does the job, but it looks ugly ;) I think it's also not allowed in safe 
 d.

Well then that argues more for a generic reference type than for a whole new
aggregate type different from both classes and structs.  IIRC, Ref was supposed 
to
be coming to std.typecons soon.  Also, if you don't care about the few bytes of
overhead for vtbl and monitor, there's always final classes.  The bottom line is
that I can see where what you're asking for could be useful, but the cases where
neither a final class nor a pointer to a heap-allocated struct cut it are way 
too
few and far between to justify a whole new aggregate type.


Re: the last change for ranges

2009-05-20 Thread Bill Baxter
On Wed, May 20, 2009 at 5:11 PM, Jason House
jason.james.ho...@gmail.com wrote:
 Bill Baxter Wrote:

 On Wed, May 20, 2009 at 4:03 PM, dsimcha dsim...@yahoo.com wrote:
  == Quote from Jason House (jason.james.ho...@gmail.com)'s article
  IMHO, D should have a type with low size and function call overhead  
  like a
  struct as well as reference semantics like a class.
 
  What's wrong with a pointer to a heap-allocated struct?  I sometimes need 
  what you
  describe, too, and I've never seen a case where this doesn't do the job.

 And you can alias Foo_* Foo, so that it doesn't even look like you're
 passing around a pointer.  :-)


 --bb

 Interesting thought. Wouldn't calls to new still require use of Foo__?

Yes.  Also if you're creating 'em on the stack.

--bb


Re: OT: on IDEs and code writing on steroids

2009-05-20 Thread Christopher Wright

Nick Sabalausky wrote:
Christopher Wright dhase...@gmail.com wrote in message 
news:gv0p4e$uv...@digitalmars.com...

Nick Sabalausky wrote:
I can see certain potential benefits to the general way C# does generics, 
but until the old (and I do mean old) issue of There's an IComparable, 
so why the hell won't MS give us an IArithmetic so we can actually use 
arithmetic operators on generic code? gets fixed (and at this point I'm 
convinced they've never had any intent of ever fixing that), I don't care 
how valid the reasoning behind C#'s general approach to generics is, the 
actual state of C#'s generics still falls squarely into the categories of 
crap and almost useless.
IArithmetic is impossible in C# because operator overloads are static 
methods, and interfaces cannot specify static methods.


Then how does IComparable work? 


It uses a member function instead.


Re: the last change for ranges

2009-05-20 Thread MLT
Andrei Alexandrescu Wrote:

 MLT wrote:
  I think that if
  R last = r;
  then after
  r.popFront;
  the order of elements in last should not change, no matter what
  type of range you are dealing with. (That means that input operations
  would be buffered to the leftmost range that still extsts.)
  
  If I understood the logic of ranges, popFront() just changes the
  range, and not the elements it points to.
 
 That's the case for all ranges except input ranges. Consider:
 
 FileByCharacter
 {
  private FILE* _f;
  private dchar _last;
  bool empty() { return _last == 0x; }
  void popFront() { _last = fgetc(_f); }
  dchar front() { return _last; }
 }
 
 Consider what happens when you copy this range around.
 
 
 Andrei


I thought more of something like:

FileByCharacter
 {
  private FILE* _f;
  private dchar[] _buf;
  bool empty() { return _buf[0] == 0x; } 
  void popFront() { 
_buf = _buf[1..$] ; 
if( _buf.length  1 ) _buf ~= fgetc(_f); 
  }
  dchar front() { return _buf[0]; }
 }

The idea is that you continue to expand an array. Another copy of the range 
will continue to step over the same array. This doesn't really work, because 
the second copy doesn't really know how much the first copy already read. But 
that should be fixable
the problem is in the line
if( _buf.length  1 ) _buf ~= fgetc(_f); 
which should only trigger if _buf reached the end of the read part, not the end 
of the current copy of _buf.

I'm also not sure if D's GC will handle dropping the part of the array that no 
one looks at.

One needs something like a lazy semi-infinite range, that only calls a certain 
function when it reaches an unexplored part.


Re: the last change for ranges

2009-05-20 Thread Andrei Alexandrescu

MLT wrote:

One needs something like a lazy semi-infinite range, that only calls
a certain function when it reaches an unexplored part.


That's a great abstraction, but we can't afford to impose that to 
everybody. There must be an abstraction for a one-pass go through an 
arbitrarily long stream.


Anyhow, I decided to change ranges as follows:

a) Input:

bool empty();
ref T popNext();

b) Output:

void putNext(T);

c) Forward:

bool empty();
ref T front();
void popFront();

The function ref T popNext() is a nonmember that accepts any forward 
range and uses front() and popFront(). Of course, a forward range is 
welcome to implement popFront as a member if it so wishes. The function 
putNext() overwrites front() and then calls popFront.


d) Bidirectional:

bool empty();
ref T front();
void popFront();
ref T back();
void popBack();

popNext, putNext apply as for forward ranges.

e) Random

bool empty();
ref T front();
void popFront();
ref T back();
void popBack();
ref T opIndex(uint n);
void opIndexAssign(T, uint n);

popNext, putNext apply as for forward ranges. We need to fix the 
opIndexAssign mess.



Andrei


Re: the last change for ranges

2009-05-20 Thread dsimcha
== Quote from Andrei Alexandrescu (seewebsiteforem...@erdani.org)'s article
 MLT wrote:
  One needs something like a lazy semi-infinite range, that only calls
  a certain function when it reaches an unexplored part.
 That's a great abstraction, but we can't afford to impose that to
 everybody. There must be an abstraction for a one-pass go through an
 arbitrarily long stream.
 Anyhow, I decided to change ranges as follows:
 a) Input:
 bool empty();
 ref T popNext();
 b) Output:
 void putNext(T);
 c) Forward:
 bool empty();
 ref T front();
 void popFront();
 The function ref T popNext() is a nonmember that accepts any forward
 range and uses front() and popFront(). Of course, a forward range is
 welcome to implement popFront as a member if it so wishes. The function
 putNext() overwrites front() and then calls popFront.
 d) Bidirectional:
 bool empty();
 ref T front();
 void popFront();
 ref T back();
 void popBack();
 popNext, putNext apply as for forward ranges.
 e) Random
 bool empty();
 ref T front();
 void popFront();
 ref T back();
 void popBack();
 ref T opIndex(uint n);
 void opIndexAssign(T, uint n);
 popNext, putNext apply as for forward ranges. We need to fix the
 opIndexAssign mess.
 Andrei

Please, please, please PLEASE, PRETTY PLEASE FOR THE LOVE OF GOD ALMIGHTY tell 
me
you're not serious!!!  Isn't changing the interface such that forward ranges are
no longer effectively a subtype of input ranges a bit drastic?  Or do you have
some magic up your sleeve that, given any forward range, will automatically call
popFront, and then front, when popNext is called, using extension function hacks
or something?

The whole beauty of ranges is that they provide one standard interface to 
program
to if all you need is a lowest common denominator level of functionality.
Frankly, if you destroy this, I think that just enforcing forward vs. input 
ranges
purely by convention would be the lesser of two evils.


Re: the last change for ranges

2009-05-20 Thread dsimcha
== Quote from Andrei Alexandrescu (seewebsiteforem...@erdani.org)'s article
 MLT wrote:
  One needs something like a lazy semi-infinite range, that only calls
  a certain function when it reaches an unexplored part.
 That's a great abstraction, but we can't afford to impose that to
 everybody. There must be an abstraction for a one-pass go through an
 arbitrarily long stream.
 Anyhow, I decided to change ranges as follows:
 a) Input:
 bool empty();
 ref T popNext();
 b) Output:
 void putNext(T);
 c) Forward:
 bool empty();
 ref T front();
 void popFront();
 The function ref T popNext() is a nonmember that accepts any forward
 range and uses front() and popFront(). Of course, a forward range is
 welcome to implement popFront as a member if it so wishes. The function
 putNext() overwrites front() and then calls popFront.
 d) Bidirectional:
 bool empty();
 ref T front();
 void popFront();
 ref T back();
 void popBack();
 popNext, putNext apply as for forward ranges.
 e) Random
 bool empty();
 ref T front();
 void popFront();
 ref T back();
 void popBack();
 ref T opIndex(uint n);
 void opIndexAssign(T, uint n);
 popNext, putNext apply as for forward ranges. We need to fix the
 opIndexAssign mess.
 Andrei

(Bangs head against desk.)  Sorry.  Didn't see the part about the non-member
popNext(), though this would require Walter to make extension methods work for
structs, which should probably happen anyway.


Re: the last change for ranges

2009-05-20 Thread Andrei Alexandrescu

dsimcha wrote:

Please, please, please PLEASE, PRETTY PLEASE FOR THE LOVE OF GOD ALMIGHTY tell 
me
you're not serious!!!  Isn't changing the interface such that forward ranges are
no longer effectively a subtype of input ranges a bit drastic?  Or do you have
some magic up your sleeve that, given any forward range, will automatically call
popFront, and then front, when popNext is called, using extension function hacks
or something?


Consider:

struct R
{
bool empty();
ref int front();
void popFront();
}

ref int popNext(ref R fwdRange)
{
auto result =  fwdRange.front();
fwdRange.popFront;
return *result;
}

void main()
{
R r;
int x = r.popNext;
}

This should work, I just noticed with surprise it doesn't. It's a bug, 
specifically bug 3015:


http://d.puremagic.com/issues/show_bug.cgi?id=3015


The whole beauty of ranges is that they provide one standard interface to 
program
to if all you need is a lowest common denominator level of functionality.
Frankly, if you destroy this, I think that just enforcing forward vs. input 
ranges
purely by convention would be the lesser of two evils.


You and I see eye to eye.


Andrei


Re: the last change for ranges

2009-05-20 Thread Andrei Alexandrescu

dsimcha wrote:

== Quote from Andrei Alexandrescu (seewebsiteforem...@erdani.org)'s article

MLT wrote:

One needs something like a lazy semi-infinite range, that only calls
a certain function when it reaches an unexplored part.

That's a great abstraction, but we can't afford to impose that to
everybody. There must be an abstraction for a one-pass go through an
arbitrarily long stream.
Anyhow, I decided to change ranges as follows:
a) Input:
bool empty();
ref T popNext();
b) Output:
void putNext(T);
c) Forward:
bool empty();
ref T front();
void popFront();
The function ref T popNext() is a nonmember that accepts any forward
range and uses front() and popFront(). Of course, a forward range is
welcome to implement popFront as a member if it so wishes. The function
putNext() overwrites front() and then calls popFront.
d) Bidirectional:
bool empty();
ref T front();
void popFront();
ref T back();
void popBack();
popNext, putNext apply as for forward ranges.
e) Random
bool empty();
ref T front();
void popFront();
ref T back();
void popBack();
ref T opIndex(uint n);
void opIndexAssign(T, uint n);
popNext, putNext apply as for forward ranges. We need to fix the
opIndexAssign mess.
Andrei


(Bangs head against desk.)  Sorry.  Didn't see the part about the non-member
popNext(), though this would require Walter to make extension methods work for
structs, which should probably happen anyway.


I should learn to never post before reading all messages...

Andrei


Re: OT: on IDEs and code writing on steroids

2009-05-20 Thread Nick Sabalausky
Christopher Wright dhase...@gmail.com wrote in message 
news:gv29vn$7a...@digitalmars.com...
 Nick Sabalausky wrote:
 Christopher Wright dhase...@gmail.com wrote in message 
 news:gv0p4e$uv...@digitalmars.com...
 Nick Sabalausky wrote:
 I can see certain potential benefits to the general way C# does 
 generics, but until the old (and I do mean old) issue of There's an 
 IComparable, so why the hell won't MS give us an IArithmetic so we can 
 actually use arithmetic operators on generic code? gets fixed (and at 
 this point I'm convinced they've never had any intent of ever fixing 
 that), I don't care how valid the reasoning behind C#'s general 
 approach to generics is, the actual state of C#'s generics still falls 
 squarely into the categories of crap and almost useless.
 IArithmetic is impossible in C# because operator overloads are static 
 methods, and interfaces cannot specify static methods.

 Then how does IComparable work?

 It uses a member function instead.

And they can't do the same for arithmetic? 




Re: OT: on IDEs and code writing on steroids

2009-05-20 Thread Nick Sabalausky
Bill Baxter wbax...@gmail.com wrote in message 
news:mailman.151.1242855932.13405.digitalmar...@puremagic.com...
 On Wed, May 20, 2009 at 1:09 PM, Andrei Alexandrescu
 seewebsiteforem...@erdani.org wrote:
 Yigal Chripun wrote:

 I think you miss the point here.
 Generics and code generation are two separate and orthogonal features 
 that
 where conflated together by C++.

 It's kind of odd, then, that for example the Generative Programming book
 (http://www.generative-programming.org) chose to treat the two notions in
 conjunction.

 Yeh, there's definitely a overlap.  Orthogonal isn't quite the right word 
 there.

 I'm reading a bit on C++/CLI right now, which is C++ extended to
 inter-operate with CLR.
 C++/CLI has *both* classic C++ templates and CLR generics:

  templatetypename T ...// all code specializations generated at
 compile-time (if at all)
  generictypename T ... // code generated at compiletime
 unconditionally, specialized at run-time.

 I'm not clear on exactly what happens at runtime in the generic
 case.  I had been thinking it was simply that the compiler does some
 type checking at compile time and the VM code then just manipulates
 pointers to Object from there.  That may be what happens in Java
 generics, but in CLR generics at least you can specialize on
 non-Object value types and that apparently does not result in
 everything getting boxed.  So it seems like there's a little something
 extra going on.

 I think the main reason for having Generics is that they're the best
 anyone currently knows how to do at the IL bytecode level.  Generics
 give you a way to define generic parameterized types that work across
 all the languages that target a given VM's bytecode.  But that doesn't
 preclude any language that targets that VM from *also* implementing
 compile-time templates, or code generators, or AST macros at the
 source code level.

 But the problem with source-level code generation is that you then
 need the source code in order to use the library.  I think they were
 trying to avoid that with C#.   If you have a compiled C# assembly,
 then you have everything you need to use it.   Period.   (I think.)
 At any rate, a tech that requires inclusion of source code is not very
 interesting to Microsoft, because Microsoft doesn't generally like to
 let people see their source code in the first place, and they know
 that many of their biggest customers don't like to either.  They're
 nervous enough about just putting de-compileable bytecode out there.


Maybe this is naive, but what about an AST-level template/generic? Couldn't 
that provide for the best of both worlds?

For instance, suppose (purely hypothetically) that the .NET assembly system 
were changed to allow the source for a D/C++ style of source-level template 
to be embedded into the assembly. Then they'd be able to do D/C++ style 
source-level template/code-generation. Right? Now obviously the big problem 
with that is it would only be usable in the same language it was originally 
written in. So, instead of getting that cross-language support by going all 
the way down to the IL bytecode level to implement generics (which, as you 
said, would somehow prevent the flexibility that the D/C++ style enjoys) 
suppose it only went down as far as a language-agnostic AST?

I suppose that might make reverse-engineering easier which MS might not 
like, but I'm not suggesting this as something that MS should like or should 
even do, but rather suggesting it as (business issues completely aside) 
something that would possibly gain the benefits of both styles. 




Re: the last change for ranges

2009-05-20 Thread Nick Sabalausky
Andrei Alexandrescu seewebsiteforem...@erdani.org wrote in message 
news:gv2hj8$k1...@digitalmars.com...
 dsimcha wrote:

 Consider:

 struct R
 {
 bool empty();
 ref int front();
 void popFront();
 }

 ref int popNext(ref R fwdRange)
 {
 auto result =  fwdRange.front();
 fwdRange.popFront;
 return *result;
 }

 void main()
 {
 R r;
 int x = r.popNext;
 }

 This should work, I just noticed with surprise it doesn't. It's a bug, 
 specifically bug 3015:

 http://d.puremagic.com/issues/show_bug.cgi?id=3015


I thought that was only supposed to work for arrays. Has that changed? If 
so, what's the new rule?




Re: OT: on IDEs and code writing on steroids

2009-05-20 Thread Daniel Keep


Nick Sabalausky wrote:
 ...
 
 Maybe this is naive, but what about an AST-level template/generic? Couldn't 
 that provide for the best of both worlds?
 
 For instance, suppose (purely hypothetically) that the .NET assembly system 
 were changed to allow the source for a D/C++ style of source-level template 
 to be embedded into the assembly. Then they'd be able to do D/C++ style 
 source-level template/code-generation. Right? Now obviously the big problem 
 with that is it would only be usable in the same language it was originally 
 written in. So, instead of getting that cross-language support by going all 
 the way down to the IL bytecode level to implement generics (which, as you 
 said, would somehow prevent the flexibility that the D/C++ style enjoys) 
 suppose it only went down as far as a language-agnostic AST?
 
 ...

What I've always thought might be an interesting experiment would be to
change templates in LDC so that instead of generating an AST, they
generate code that generates code.

So when you use A!(T), what happens is that at runtime the template is
run with T as an argument.  This generates a chunk of LLVM bitcode
which LLVM then assembles to machine code and links into the program.

This alleviates the problem with using source in that if you embed the
template's actual source, then you suddenly ALSO have to embed the
standard library's source and the source of any other libraries you
happened to compile with.

Oh, and the same version of the compiler.

  -- Daniel


Re: the last change for ranges

2009-05-20 Thread Robert Fraser

Andrei Alexandrescu wrote:

struct R
{
bool empty();
ref int front();
void popFront();
}

ref int popNext(ref R fwdRange)
{
auto result =  fwdRange.front();
fwdRange.popFront;
return *result;
}

void main()
{
R r;
int x = r.popNext;
}

This should work, I just noticed with surprise it doesn't. It's a bug, 
specifically bug 3015:


http://d.puremagic.com/issues/show_bug.cgi?id=3015


Yes. Oh yes. YES!!!


  1   2   >