Re: The magic behind foreach (was: Re: Descent 0.5.3 released)

2009-01-22 Thread Jarrett Billingsley
On Fri, Jan 23, 2009 at 12:30 AM, Bill Baxter  wrote:
>
> I see what you're saying now.  So the user has to manipulate a bool
> return value instead of an int?
>
> Then you could have
>
> void opApply(bool delegate(ref int) dg) {
>  foreach(i; internal_) {
>if (dg(i)) return;
>  }
> }
>
> Yep, that looks like an improvement to me.

Right.  Granted, it's not perfect - it's still possible to write an
opApply that doesn't respect breaks/returns/gotos out of the loop -
but it's much more straightforward.

A "perfect" opApply would probably look like:

void opApply(void delegate(ref int) dg)
{
foreach(i; mData)
dg(i);
}

but it would probably have to abuse exceptions to accomplish this,
which doesn't sound like a great idea to me.


Re: The magic behind foreach (was: Re: Descent 0.5.3 released)

2009-01-22 Thread Bill Baxter
On Fri, Jan 23, 2009 at 11:59 AM, Jarrett Billingsley
 wrote:
> On Thu, Jan 22, 2009 at 9:38 PM, Bill Baxter  wrote:
>>
>> Yep, that was the gist of it.  Put the return value on the stack of
>> the calling frame.
>> Nothing all that fancy really, just you want to be able to hide that
>> __result = blah ugliness from the user.
>
> Oh, I'm suggesting that the compiler do this instead of us having to
> do it with macros.

I see what you're saying now.  So the user has to manipulate a bool
return value instead of an int?

Then you could have

void opApply(bool delegate(ref int) dg) {
  foreach(i; internal_) {
if (dg(i)) return;
  }
}

Yep, that looks like an improvement to me.


Re: The magic behind foreach (was: Re: Descent 0.5.3 released)

2009-01-22 Thread Jarrett Billingsley
On Thu, Jan 22, 2009 at 9:38 PM, Bill Baxter  wrote:
>
> Yep, that was the gist of it.  Put the return value on the stack of
> the calling frame.
> Nothing all that fancy really, just you want to be able to hide that
> __result = blah ugliness from the user.

Oh, I'm suggesting that the compiler do this instead of us having to
do it with macros.


Re: Any chance to call Tango as Extended Standard Library

2009-01-22 Thread Michel Fortin

On 2009-01-19 18:11:15 -0500, Sergey Gromov  said:


I think "can't" is a bit strong a statement.  Let's see:

With opApply:

class progressUpdater(Collection)
{
  this(Collection c)
  {
collection_ = c;
  }

  int opApply(int delegate(ref ElementType!(Collection)) dg)
  {
composed_ = dg;
return collection_.opApply(&fancifier);
  }

  private:

  int fancifier(ref ElementType!(Collection) el)
  {
globalOnProgress();
return composed_(el);
  }

  Collection collection_;
  int delegate(ref ElementType!(Collection)) composed_;
}


I think it's the same as this:


class progressUpdater(Collection)
{
 this(Collection c)
 {
   collection_ = c;
 }

 int opApply(int delegate(ref ElementType!(Collection)) dg)
 {
   int fancifier(ref ElementType!(Collection) el)
   {
 globalOnProgress();
 return composed_(el);
   }

   composed_ = dg;
   return collection_.opApply(&fancifier);
 }

 private:

 Collection collection_;
}


Or this:


class progressUpdater(Collection)
{
 this(Collection c)
 {
   collection_ = c;
 }

 int opApply(int delegate(ref ElementType!(Collection)) dg)
 {
foreach(ref ElementType!(Collection) el; collection_)
   {
 globalOnProgress();
 if (dg(el))
   return 1;
   }
   return 0;
 }

 private:

 Collection collection_;
}


--
Michel Fortin
michel.for...@michelf.com
http://michelf.com/



Re: The magic behind foreach (was: Re: Descent 0.5.3 released)

2009-01-22 Thread Bill Baxter
On Fri, Jan 23, 2009 at 11:15 AM, Jarrett Billingsley
 wrote:
> On Thu, Jan 22, 2009 at 7:00 PM, Bill Baxter  wrote:
>>
>> I posted a proposal for how to hide the magic int from the user a
>> while back, but my conclusion was that my approach would require AST
>> macros in order to give it a reasonable syntax.  With the ast macros
>> you'd be able to do something like  yield(i) in the body of your
>> foreach, where yield is an appropriately defined macro.
>>
>
> Consider the case where you return a value inside a foreach loop:
>
> int find(char[] value)
> {
>foreach(k, v; someAA)
>if(v == value)
>return k;
> }
>
> How is this implemented?  It puts a local variable in the stack frame
> of find(), called __result.  Then the foreach delegate just writes
> into that local when it returns (__result = k; return
> IM_RETURNING_NOW;), and the compiler-generated cruft returns the value
> of that local from find() (switch(...) { case IM_RETURNING_NOW: return
> __result; }).
>
> The delegate return status code doesn't have to be any different.
> Just have the delegate return a bool (should iteration stop?) and put
> its actual return status in the stack frame of the enclosing function.

Yep, that was the gist of it.  Put the return value on the stack of
the calling frame.
Nothing all that fancy really, just you want to be able to hide that
__result = blah ugliness from the user.

--bb


Re: Any chance to call Tango as Extended Standard Library

2009-01-22 Thread Jarrett Billingsley
On Thu, Jan 22, 2009 at 8:13 PM, Stewart Gordon  wrote:
> Don wrote:
> 
>>
>> The other option (which I would prefer) is for druntime to get bigger, and
>> encompass more of the common code from both. So that both Phobos and Tango
>> became (crucial) extension libraries over a small core. And the bigger that
>> common core becomes, the smaller the library problem becomes.
>
> Up until the point at which somebody decides it's time to develop a library
> to rival druntime.

And we prevent that from happening by making as many people as
possible happy with the development and features of druntime/core.
This is exactly what caused the split in libraries in the first place
- a sizable contingent of users who _weren't_ happy with the existing
library or its development.

In the end though, of course there's nothing we can do from stopping
people from developing yet another library.  But we can at least try
to reduce the likelihood of it.


Re: The magic behind foreach (was: Re: Descent 0.5.3 released)

2009-01-22 Thread Jarrett Billingsley
On Thu, Jan 22, 2009 at 7:00 PM, Bill Baxter  wrote:
>
> I posted a proposal for how to hide the magic int from the user a
> while back, but my conclusion was that my approach would require AST
> macros in order to give it a reasonable syntax.  With the ast macros
> you'd be able to do something like  yield(i) in the body of your
> foreach, where yield is an appropriately defined macro.
>

Consider the case where you return a value inside a foreach loop:

int find(char[] value)
{
foreach(k, v; someAA)
if(v == value)
return k;
}

How is this implemented?  It puts a local variable in the stack frame
of find(), called __result.  Then the foreach delegate just writes
into that local when it returns (__result = k; return
IM_RETURNING_NOW;), and the compiler-generated cruft returns the value
of that local from find() (switch(...) { case IM_RETURNING_NOW: return
__result; }).

The delegate return status code doesn't have to be any different.
Just have the delegate return a bool (should iteration stop?) and put
its actual return status in the stack frame of the enclosing function.


Re: Any chance to call Tango as Extended Standard Library

2009-01-22 Thread Stewart Gordon

Don wrote:

The other option (which I would prefer) is for druntime to get bigger, 
and encompass more of the common code from both. So that both Phobos and 
Tango became (crucial) extension libraries over a small core. And the 
bigger that common core becomes, the smaller the library problem becomes.


Up until the point at which somebody decides it's time to develop a 
library to rival druntime.


Stewart.


Re: Pluggable type sytems

2009-01-22 Thread Nick Sabalausky
"bearophile"  wrote in message 
news:gl0ohe$1gd...@digitalmars.com...
>I think pluggable type systems will become more common in the following 
>years (see also the optional annotations of Python3 that are designed for 
>that too). This is more or less related:
>
> http://bartoszmilewski.wordpress.com/2009/01/18/java-pluggable-types/
>
> (but nonnullability is so basic that it's better inside the language, and 
> not left out to a plug-in type system).
>
> Bye,
> bearophile

Interesting article. Sounds a lot like D2 but with that flow-analysis 
nice-ity, and @PolyNull (which has been proposed here...often). Although I 
wonder...maybe @PolyNull should be the default (wherever applicable) instead 
of @Nullable or @NonNull? (Or maybe I'm overlooking some obvious problem 
with that.)

I see pluggable type sytems as potentially being a specific form of a more 
general thing I've been observing an increasing need for/trend towards: 
customizable languages.

Ex: A language that doesn't say "Semicolons mark end-of-statement" or 
"Newline marks end-of-statement and lines can be split with a backslash", 
but provides both as mutually-exclusive programmer-selectable options. Or a 
choice of C-style curly-braces vs Python-style indentation. Etc. (Side note: 
This stuff could really cut down on religious language debates. Not 
eliminate, of course, but reduce.)

Also, a tool could then be used to translate code between the various 
options, maybe even integrated into the IDE, so that people working on 
multi-person projects could each set up their own environments and use their 
own "customized language" even while working on the same line of code. The 
only project-wide standard would be what settings are used for checked-in 
code, just like tab/space settings and EOL markers (but ideally performed 
automatically (and reliably) by the check-in/check-out process). Eventually 
this might even be generalizable to the point where most languages can be 
reduced to nothing more than a collection of language settings. Which I 
think is the direction we appear to be headed anyway, since it seems like 
everyone and their grandmother is designing their own language (or two) 
these days, and many of these languages are more-or-less "just like language 
X, but with A, B and C changed to be more like language Y."

Obviously this is all much easier said than done, but it's something I've 
been thinking a lot about lately, and I think may be worth exploring. 




Re: The magic behind foreach (was: Re: Descent 0.5.3 released)

2009-01-22 Thread Bill Baxter
On Fri, Jan 23, 2009 at 8:52 AM, Ary Borenszweig  wrote:
> Bill Baxter wrote:
>>
>> On Fri, Jan 23, 2009 at 8:10 AM, Christopher Wright 
>> wrote:
>>>
>>> Ary Borenszweig wrote:

 If the compiler can transform a "foreach" into an opApply call, passing
 the foreach body and converting breaks to "return 1" statements... can't
 opApply be specified as:

 int opApply(void delegate(ref uint) dg) { // note: delegate returns void
 }

 and the compiler transforms the opApply signature to the one that's used
 now, plus converting each dg call to a call and a check of return value
  !=
 0 and return 1 in that case?
>>>
>>> This only fails if you wish to take a particular action when the calling
>>> code breaks out of iteration. This is not such a large use case that I
>>> think
>>> it worth preserving.
>
> Why do you mean by "fails"? The compiler transforms the foreach's body, it
> can transform the opApply's body.
>
>>
>> It's not?
>>
>> foreach(i;  things) {
>>  if (i==a) continue;
>>  if (i==b) break;
>>  if (i==d) return;
>>  if (i==c) goto somewhere;
>> }
>>
>> Those are all fairly common things to do from inside the 'dg' call.
>> The int is how the compiler distinguishes which case got you out of
>> the dg.
>>
>> --bb
>
> Aaaah... Now I see what's the return value of opApply for. So I tried your
> code:
>
> (just the relevant piece)
> ---
> int main(char[][] args) {
>int a = 1, b = 2, c = 3, d = 4;
>
>Foo foo = new Foo();
>foreach(i; foo) {
>if (i==a) continue;
>if (i==b) break;
>if (i==d) return;
>if (i==c) goto somewhere;
>}
>
>somewhere:
>
>return 0;
> }
> ---
>
> and DMD spits out this:
>
> ---
> int main(char[][] args) {
>int a = 1, b = 2, c = 3, d = 4;
>
>Foo foo = new Foo;
>switch(foo.opApply(delegate (uint __applyArg0) {
>{
>uint i = __applyArg0;
>if(i == cast(uint) a)
>return 0;
>if(i == cast(uint) b)
>return 1;
>if(i == cast(uint) d)
>return 2;
>if(i == cast(uint) c)
>return 3;
>}
>return 0;
>} )) {
>default:
>break;
>case 2:
>return;
>case 3:
>goto somewhere;
>}
>
>somewhere:
>
>return 0;
> }
> ---
>
> Intersting. The compiler (Walter?) is being smart here. :-)

I posted a proposal for how to hide the magic int from the user a
while back, but my conclusion was that my approach would require AST
macros in order to give it a reasonable syntax.  With the ast macros
you'd be able to do something like  yield(i) in the body of your
foreach, where yield is an appropriately defined macro.

If anyone is interested I'll try to dig it up from the archives.

--bb


Re: The magic behind foreach (was: Re: Descent 0.5.3 released)

2009-01-22 Thread Ary Borenszweig

Bill Baxter wrote:

On Fri, Jan 23, 2009 at 8:10 AM, Christopher Wright  wrote:

Ary Borenszweig wrote:

If the compiler can transform a "foreach" into an opApply call, passing
the foreach body and converting breaks to "return 1" statements... can't
opApply be specified as:

int opApply(void delegate(ref uint) dg) { // note: delegate returns void
}

and the compiler transforms the opApply signature to the one that's used
now, plus converting each dg call to a call and a check of return value  !=
0 and return 1 in that case?

This only fails if you wish to take a particular action when the calling
code breaks out of iteration. This is not such a large use case that I think
it worth preserving.


Why do you mean by "fails"? The compiler transforms the foreach's body, 
it can transform the opApply's body.




It's not?

foreach(i;  things) {
  if (i==a) continue;
  if (i==b) break;
  if (i==d) return;
  if (i==c) goto somewhere;
}

Those are all fairly common things to do from inside the 'dg' call.
The int is how the compiler distinguishes which case got you out of
the dg.

--bb


Aaaah... Now I see what's the return value of opApply for. So I tried 
your code:


(just the relevant piece)
---
int main(char[][] args) {
int a = 1, b = 2, c = 3, d = 4;

Foo foo = new Foo();
foreach(i; foo) {
if (i==a) continue;
if (i==b) break;
if (i==d) return;
if (i==c) goto somewhere;
}

somewhere:

return 0;
}
---

and DMD spits out this:

---
int main(char[][] args) {
int a = 1, b = 2, c = 3, d = 4;

Foo foo = new Foo;
switch(foo.opApply(delegate (uint __applyArg0) {
{
uint i = __applyArg0;
if(i == cast(uint) a)
return 0;
if(i == cast(uint) b)
return 1;
if(i == cast(uint) d)
return 2;
if(i == cast(uint) c)
return 3;
}
return 0;
} )) {
default:
break;
case 2:
return;
case 3:
goto somewhere;
}

somewhere:

return 0;
}
---

Intersting. The compiler (Walter?) is being smart here. :-)


Re: The magic behind foreach (was: Re: Descent 0.5.3 released)

2009-01-22 Thread Bill Baxter
On Fri, Jan 23, 2009 at 8:10 AM, Christopher Wright  wrote:
> Ary Borenszweig wrote:
>>
>> If the compiler can transform a "foreach" into an opApply call, passing
>> the foreach body and converting breaks to "return 1" statements... can't
>> opApply be specified as:
>>
>> int opApply(void delegate(ref uint) dg) { // note: delegate returns void
>> }
>>
>> and the compiler transforms the opApply signature to the one that's used
>> now, plus converting each dg call to a call and a check of return value  !=
>> 0 and return 1 in that case?
>
> This only fails if you wish to take a particular action when the calling
> code breaks out of iteration. This is not such a large use case that I think
> it worth preserving.

It's not?

foreach(i;  things) {
  if (i==a) continue;
  if (i==b) break;
  if (i==d) return;
  if (i==c) goto somewhere;
}

Those are all fairly common things to do from inside the 'dg' call.
The int is how the compiler distinguishes which case got you out of
the dg.

--bb


Re: The magic behind foreach (was: Re: Descent 0.5.3 released)

2009-01-22 Thread Christopher Wright

Ary Borenszweig wrote:
If the compiler can transform a "foreach" into an opApply call, passing 
the foreach body and converting breaks to "return 1" statements... can't 
opApply be specified as:


int opApply(void delegate(ref uint) dg) { // note: delegate returns void
}

and the compiler transforms the opApply signature to the one that's used 
now, plus converting each dg call to a call and a check of return value 
 != 0 and return 1 in that case?


This only fails if you wish to take a particular action when the calling 
code breaks out of iteration. This is not such a large use case that I 
think it worth preserving.


Re: Any chance to call Tango as Extended Standard Library

2009-01-22 Thread Jason House
Denis Koroskin Wrote:

> I think believe we could take advantage of current state of both libraries in 
> D2 - they are both incomplete and being redesigned to fit D2 better.
> We could revisit both Tango and Phobos, and clean them up by removing 
> outdated modules and modules with same functionality. This will make Phobos 
> really small and much easier to learn.
> 
> On the other hand, Tango will continue providing all the extended 
> functionality.
> 
> Here is a list of Phobos modules that I believe could be safely removed:
> 
> - crc32 and std.md5 - these should be deprecated in favor of 
> tango.io.digest.Crc32 and tango.io.digest.Md5
> Tango is better designed and has support for other algoriths (MD2, MD4, 
> SHA256, SHA512, Tiger and more).
> See http://www.dsource.org/projects/tango/wiki/ChapterEncodingAndCrypto for 
> details.
> 
> - std.atomics - tango.core.Atomic is superior to it (std.atomics has nothing 
> but CAS anyway).
> - std.base64 - deprecate in favor of tango.io.encode.Base64
> - std.cover - is it supposed to be visible to user? Should it be in Phobos?
> - std.loader - deprecate in favor of tango.sys.SharedLib
> - std.bitarray
> - std.openrj
> - std.process - merge with tango.sys.Process
> - std.regexp - buggy, deprecate in favor of tango.text.Regex
> - std.socket, std.socketstream - deprecate in favor of tango.net.*
> - std.uni - deprecate in favor of tango.text.Unicode
> - std.uri - deprecate in favor of tango.net.Uri
> - std.xml - deprecate in favor of tango.text.xml.*
> - std.zip and std.zlib - deprecate in favor of tango.io.compress.*
> 
> In almost *all* cases Tango has cleaner, faster and less buggy implementation 
> of the same functionality.

That's an interesting list.  Without the ability to distribute Phobos and Tango 
together from the digitalmars.com site, I doubt anything will get dropped from 
Phobos in favor of what is in Tango.  For a combined distribution to ever occur 
requires a whole lot more coordination between Phobos and Tango that I doubt 
we'll see for a very long time.



> Other modules - does anyone use any of these:
> std.bitmanip
> std.bind
> std.boxer
> std.outbuffer
> std.stdint
> std.syserror
> std.system
> ?

std.bind is useful for binding data that will change before the delegate is 
called.  I've used bind a lot when doing inter-thread communication with queues 
of pending commands.

I'd also like to use a variant of bit array with fixed sizes, easier 
initialiation, and uses the SSE instruction set.  Right now, neither Phobos nor 
Tango contains what I want.


Re: Any chance to call Tango as Extended Standard Library

2009-01-22 Thread Simen Kjaeraas
On Thu, 22 Jan 2009 18:11:02 +0100, Jarrett Billingsley  
 wrote:



On Thu, Jan 22, 2009 at 1:53 AM, Alexander Pánek
 wrote:

John Reimer wrote:


Don wrote:


The other option (which I would prefer) is for druntime to get bigger,
and encompass more of the common code from both. So that both Phobos
and Tango became (crucial) extension libraries over a small core. And
the bigger that common core becomes, the smaller the library problem
becomes.


Actually, I very much like that idea.  And it seems to make sense too.


Seconded! That's a nice idea.



Thirded.


Fourthed!

--
Simen


Re: Protection in BaseClassList: semantics undefined?

2009-01-22 Thread Frank Benoit
Jarrett Billingsley schrieb:
> As far as most people can tell, it's an artifact from very early on in
> D's development.  It was probably originally supposed to have MI but
> that was dropped.  The compiler accepts public/private/protected on
> the base class but it's useless as it breaks things.

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



Re: Any chance to call Tango as Extended Standard Library

2009-01-22 Thread Andrei Alexandrescu

Sergey Gromov wrote:

Mon, 19 Jan 2009 06:15:06 -0800, Andrei Alexandrescu wrote:


Michel Fortin wrote:
Other possible things involves a rudimentary profiler (checking for the 
elapsed time at each loop iteration), or a progress monitoring template 
(notifying another thread of the progress of a particular task).


foreach (task; progessUpdater(timeProfiler(listOfTasks)))
{ ... }
You can't compose iteration based on opApply. How would progessUpdater 
and timeProfiler look like? This example pretty much transforms your 
argument into mine :o).


I think "can't" is a bit strong a statement.  Let's see:

With opApply:

class progressUpdater(Collection)
{
  this(Collection c)
  {
collection_ = c;
  }
  
  int opApply(int delegate(ref ElementType!(Collection)) dg)

  {
composed_ = dg;
return collection_.opApply(&fancifier);
  }
  
  private:
  
  int fancifier(ref ElementType!(Collection) el)

  {
globalOnProgress();
return composed_(el);
  }
  
  Collection collection_;

  int delegate(ref ElementType!(Collection)) composed_;
}


I see. Very ingenious! Reversed flow of control all the way. Thanks.

Andrei


Re: Any chance to call Tango as Extended Standard Library

2009-01-22 Thread Jarrett Billingsley
On Thu, Jan 22, 2009 at 1:53 AM, Alexander Pánek
 wrote:
> John Reimer wrote:
>>
>> Don wrote:
>>>
>>> The other option (which I would prefer) is for druntime to get bigger,
>>> and encompass more of the common code from both. So that both Phobos
>>> and Tango became (crucial) extension libraries over a small core. And
>>> the bigger that common core becomes, the smaller the library problem
>>> becomes.
>>
>> Actually, I very much like that idea.  And it seems to make sense too.
>
> Seconded! That's a nice idea.
>

Thirded.


Re: Any chance to call Tango as Extended Standard Library

2009-01-22 Thread Andrei Alexandrescu

Don wrote:

Daniel Keep wrote:


Andrei Alexandrescu wrote:

Don wrote:

[snip]

It means that any code which uses a library based on both Tango and a
library based on Phobos will end up with two copies of all of the
functions, and they'll have different name mangling etc. You end up
with two incompatible Bigints, for example, even though they have
identical code inside.

Oh, I see. You want your library to be usable whether the end user
prefers Phobos or Tango. But then why not stick it into a namespace of
your choosing? Let's say your libraries are general enough to warrant
putting them in a common core, but then anyone who defines some library
don't have to go to the "core ombudsman" to add it to the common
namespace. They'd just create unique namespaces of their own. No?


Andrei


I think he means this: let's say you're writing app A.  A depends on
libraries B and C.  B depends on Phobos, and C depends on Tango.  Both B
and C happen to use BigInts or IO or anything else that isn't shared.

All of a sudden, you've now got to link in TWO standard libraries
instead of just one, each with potentially duplicated code.


And you can't obtain a BigInt from library B and pass it into library C, 
since they are different types; even though they have 100% identical 
source code except for the name.


This will partially be solved by structural casts. I have an 
implementation but haven't put it in phobos yet. Structural casts will 
allow types that have the same layout to be cast to one another. Of 
course, that's still not ideal but it's one step forward.



Andrei


Re: Any chance to call Tango as Extended Standard Library

2009-01-22 Thread Don

Daniel Keep wrote:


Andrei Alexandrescu wrote:

Don wrote:

[snip]

It means that any code which uses a library based on both Tango and a
library based on Phobos will end up with two copies of all of the
functions, and they'll have different name mangling etc. You end up
with two incompatible Bigints, for example, even though they have
identical code inside.

Oh, I see. You want your library to be usable whether the end user
prefers Phobos or Tango. But then why not stick it into a namespace of
your choosing? Let's say your libraries are general enough to warrant
putting them in a common core, but then anyone who defines some library
don't have to go to the "core ombudsman" to add it to the common
namespace. They'd just create unique namespaces of their own. No?


Andrei


I think he means this: let's say you're writing app A.  A depends on
libraries B and C.  B depends on Phobos, and C depends on Tango.  Both B
and C happen to use BigInts or IO or anything else that isn't shared.

All of a sudden, you've now got to link in TWO standard libraries
instead of just one, each with potentially duplicated code.


And you can't obtain a BigInt from library B and pass it into library C, 
since they are different types; even though they have 100% identical 
source code except for the name.




From personal experience, the alternative isn't much better: writing
code that switches between the two.

I have an XML library that can use either Phobos or Tango.  It does this
by implementing all the calls it needs in a shim library, essentially
using it's own standard library.

It gets really fun when you need to implement some call that's trivial
in one library, but really hard in the other.  I remember having to
build an IO layer so that both Phobos and Tango had the same semantics
regarding EOF or something...

Urgh.

  -- Daniel


Re: Any chance to call Tango as Extended Standard Library

2009-01-22 Thread Don

Andrei Alexandrescu wrote:

Don wrote:

Andrei Alexandrescu wrote:

Don wrote:

Andrei Alexandrescu wrote:

IUnknown wrote:

Regarding Phobos + Tango, the minimum I expect is things like
containers, algorithm and common math stuff to be in one core module.


This is already bound to be an issue because there is disagreement 
on how e.g. containers should look like (Java-style vs. STL-style). 
Which should be chosen? This naturally influences how algorithms 
are defined.



Andrei



The analogy with KDE vs Gnome doesn't seem valid to me -- most 
libraries will work regardless of which GUI library is chosen. 
Programmers can still rely on the Posix and C standard libraries.


I agree.

Can we work out the math stuff at least? There's no difference 
between Phobos and Tango there. All we need is an agreement on 
common module naming (eg, create core.math).


That would be great. I don't think that's a major issue anyway. If I 
were you, to be compatible with today's state of affairs, I'd simply 
put in the makefile the code necessary for switching the module 
prefixes.


It means that any code which uses a library based on both Tango and a 
library based on Phobos will end up with two copies of all of the 
functions, and they'll have different name mangling etc. You end up 
with two incompatible Bigints, for example, even though they have 
identical code inside.


Oh, I see. You want your library to be usable whether the end user 
prefers Phobos or Tango. But then why not stick it into a namespace of 
your choosing? Let's say your libraries are general enough to warrant 
putting them in a common core, but then anyone who defines some library 
don't have to go to the "core ombudsman" to add it to the common 
namespace. They'd just create unique namespaces of their own. No?


That's possible too. Originally, my code was in the 'mathextra' 
namespace, and I'm somewhat regretting moving it it out.


You still need an ombudsman, though, to determine which libraries are 
standard, and which are not, in order to prevent namespace collisions. 
Personally, I like the boost model -- all you need is a root level (like 
'boost') to act as a namespace protection mechanism, and then a library 
standardisation policy.


But then you have the question as to the organisation of the 'std' 
namespace -- for example, it contains such obscure stuff as std.openrj 
which is actually a stand-alone library.


(I notice Dennis has just posted some similar sentiments, so I'll stop 
for now).


It could be that all that we need is to create a standard naming policy.


Re: Protection in BaseClassList: semantics undefined?

2009-01-22 Thread Jarrett Billingsley
On Thu, Jan 22, 2009 at 9:43 AM, Harry Vennik  wrote:
> Hi,
>
>
> http://www.digitalmars.com/d/2.0/class.html
>
> In the grammar specification I read that a base class or interface name can 
> be prepended a protection attribute. But I don't find a word about the 
> semantics thereof... Can anyone tell (and update the docs)?

As far as most people can tell, it's an artifact from very early on in
D's development.  It was probably originally supposed to have MI but
that was dropped.  The compiler accepts public/private/protected on
the base class but it's useless as it breaks things.


Re: dsource considered harmful

2009-01-22 Thread Tomas Lindquist Olsen
On Sun, Jan 18, 2009 at 11:11 PM, Stewart Gordon wrote:

> ...
> Speaking of which, has anybody tried asking Brad for commit permission on
> an abandoned project in order to revive it?
>
> Stewart.
>

I took over the MinWin project a long time ago, since its author, Ben
Hinkle, had disappeared from the community, I tried reviving it for about
half a year, with some success, but eventually I got tired of doing it
alone, with little to no testers/users.
So it's pretty dead now again...

-Tomas


Re: Any chance to call Tango as Extended Standard Library

2009-01-22 Thread Daniel Keep


Andrei Alexandrescu wrote:
> Don wrote:
>> [snip]
>>
>> It means that any code which uses a library based on both Tango and a
>> library based on Phobos will end up with two copies of all of the
>> functions, and they'll have different name mangling etc. You end up
>> with two incompatible Bigints, for example, even though they have
>> identical code inside.
> 
> Oh, I see. You want your library to be usable whether the end user
> prefers Phobos or Tango. But then why not stick it into a namespace of
> your choosing? Let's say your libraries are general enough to warrant
> putting them in a common core, but then anyone who defines some library
> don't have to go to the "core ombudsman" to add it to the common
> namespace. They'd just create unique namespaces of their own. No?
> 
> 
> Andrei

I think he means this: let's say you're writing app A.  A depends on
libraries B and C.  B depends on Phobos, and C depends on Tango.  Both B
and C happen to use BigInts or IO or anything else that isn't shared.

All of a sudden, you've now got to link in TWO standard libraries
instead of just one, each with potentially duplicated code.

>From personal experience, the alternative isn't much better: writing
code that switches between the two.

I have an XML library that can use either Phobos or Tango.  It does this
by implementing all the calls it needs in a shim library, essentially
using it's own standard library.

It gets really fun when you need to implement some call that's trivial
in one library, but really hard in the other.  I remember having to
build an IO layer so that both Phobos and Tango had the same semantics
regarding EOF or something...

Urgh.

  -- Daniel


Protection in BaseClassList: semantics undefined?

2009-01-22 Thread Harry Vennik
Hi,


http://www.digitalmars.com/d/2.0/class.html

In the grammar specification I read that a base class or interface name can be 
prepended a protection attribute. But I don't find a word about the semantics 
thereof... Can anyone tell (and update the docs)?


Regards,

Harry




Re: Any chance to call Tango as Extended Standard Library

2009-01-22 Thread Andrei Alexandrescu

Don wrote:

Andrei Alexandrescu wrote:

Don wrote:

Andrei Alexandrescu wrote:

IUnknown wrote:

Regarding Phobos + Tango, the minimum I expect is things like
containers, algorithm and common math stuff to be in one core module.


This is already bound to be an issue because there is disagreement 
on how e.g. containers should look like (Java-style vs. STL-style). 
Which should be chosen? This naturally influences how algorithms are 
defined.



Andrei



The analogy with KDE vs Gnome doesn't seem valid to me -- most 
libraries will work regardless of which GUI library is chosen. 
Programmers can still rely on the Posix and C standard libraries.


I agree.

Can we work out the math stuff at least? There's no difference 
between Phobos and Tango there. All we need is an agreement on common 
module naming (eg, create core.math).


That would be great. I don't think that's a major issue anyway. If I 
were you, to be compatible with today's state of affairs, I'd simply 
put in the makefile the code necessary for switching the module prefixes.


It means that any code which uses a library based on both Tango and a 
library based on Phobos will end up with two copies of all of the 
functions, and they'll have different name mangling etc. You end up with 
two incompatible Bigints, for example, even though they have identical 
code inside.


Oh, I see. You want your library to be usable whether the end user 
prefers Phobos or Tango. But then why not stick it into a namespace of 
your choosing? Let's say your libraries are general enough to warrant 
putting them in a common core, but then anyone who defines some library 
don't have to go to the "core ombudsman" to add it to the common 
namespace. They'd just create unique namespaces of their own. No?



Andrei


Re: Any chance to call Tango as Extended Standard Library

2009-01-22 Thread Frits van Bommel

Don wrote:

Andrei Alexandrescu wrote:

Don wrote:
Can we work out the math stuff at least? There's no difference 
between Phobos and Tango there. All we need is an agreement on common 
module naming (eg, create core.math).


That would be great. I don't think that's a major issue anyway. If I 
were you, to be compatible with today's state of affairs, I'd simply 
put in the makefile the code necessary for switching the module prefixes.


It means that any code which uses a library based on both Tango and a 
library based on Phobos will end up with two copies of all of the 
functions, and they'll have different name mangling etc. You end up with 
two incompatible Bigints, for example, even though they have identical 
code inside.


Interestingly, this might be less of a problem when using LDC. LLVM has 
an IPO pass to merge identical functions (opt -mergefunc).


Re: Overload by return type

2009-01-22 Thread Kagamin
BCS Wrote:

> Hello dsimcha,
> 
> > Just curious, why doesn't D, and why don't more statically typed
> > languages in general, support overload by return type?  I haven't
> > exactly thought through all the pros and cons, but at first glance it
> > seems like an incredibly useful thing.  What's the catch that I'm
> > missing?
> > 
> 
> Off hand it's one more degree of freedom (and confusion) in trying to figure 
> out what type something is.
> 
> int bar(char[] c)
> int[] bar(char[] c)
> 
> float baz(int i)
> object baz(int[] i)
> 
> auto z = baz(bar("what type is z"));
> 
> float foo();
> object foo();
> 
> z = foo();  // what foo?
> 
> Also for all other cases in D (and C, and C++, and C#, and ...) the semantics 
> of an expression is not dependent on what expression it is nested under. 
> Changing this could have far reaching consequences. 

Fortunately, D already has this bug
http://d.puremagic.com/issues/show_bug.cgi?id=52


Re: Any chance to call Tango as Extended Standard Library

2009-01-22 Thread Aarti_pl

Denis Koroskin pisze:
On Thu, 22 Jan 2009 09:18:52 +0300, Benji Smith 
 wrote:



IUnknown wrote:
Agree. Which is why I said the problems you are facing seem to be 
non-technical. I'm suggesting that the D library developers should 
pick one and axe the other. *I* think what more important is to have 
one single set of containers in a single style rather than have two 
separate ones. There is going to be complaining for sure from the 
current developers, but in my opinion, the target of having a single 
standard library (with core and advanced modules to suit system/ app 
programming) is more important than having to make a difficult choice.


Totally agree. While I personally prefer the Java-style containers, 
I'd gladly accept the STL-style containers if it meant unification of 
Phobos and Tango.


Having druntime is nice, sure, but application-level code and 
high-level libraries will bake the container API into their public 
interfaces, and any code that uses both the Phobos and Tango libraries 
would have to perform a zillion tedious conversions.


In my mind, the things that need a unified API are (in order of 
importance):


1. GC and TypeInfo
2. Data structures
3. Algorithms
4. String processing
5. Date & Time
6. IO

Everything else (encryption, compression, sockets, regular 
expressions, could have a totally different API in Tango & Phobos and 
I wouldn't care much.


Having a common runtime (GC and TypeInfo) is a neat trick, but pretty 
useless if the data structures and algorithms are entirely different.


And, while I'm perfectly willing to accept either Java-style or 
STL-style containers, I'd also really appreciate it if the design 
anticipates and supports custom implementations (because I almost 
always end up implementing my own multimaps, multisets, circular 
queues etc)


--benji


I think believe we could take advantage of current state of both 
libraries in D2 - they are both incomplete and being redesigned to fit 
D2 better.
We could revisit both Tango and Phobos, and clean them up by removing 
outdated modules and modules with same functionality. This will make 
Phobos really small and much easier to learn.


On the other hand, Tango will continue providing all the extended 
functionality.


Here is a list of Phobos modules that I believe could be safely removed:

- crc32 and std.md5 - these should be deprecated in favor of 
tango.io.digest.Crc32 and tango.io.digest.Md5
Tango is better designed and has support for other algoriths (MD2, MD4, 
SHA256, SHA512, Tiger and more).
See http://www.dsource.org/projects/tango/wiki/ChapterEncodingAndCrypto 
for details.


- std.atomics - tango.core.Atomic is superior to it (std.atomics has 
nothing but CAS anyway).

- std.base64 - deprecate in favor of tango.io.encode.Base64
- std.cover - is it supposed to be visible to user? Should it be in Phobos?
- std.loader - deprecate in favor of tango.sys.SharedLib
- std.bitarray
- std.openrj
- std.process - merge with tango.sys.Process
- std.regexp - buggy, deprecate in favor of tango.text.Regex
- std.socket, std.socketstream - deprecate in favor of tango.net.*
- std.uni - deprecate in favor of tango.text.Unicode
- std.uri - deprecate in favor of tango.net.Uri
- std.xml - deprecate in favor of tango.text.xml.*
- std.zip and std.zlib - deprecate in favor of tango.io.compress.*

In almost *all* cases Tango has cleaner, faster and less buggy 
implementation of the same functionality.


Other modules - does anyone use any of these:
std.bitmanip
std.bind
std.boxer
std.outbuffer
std.stdint
std.syserror
std.system
?

There are a lot of modules that only exist in Phobos because of some 
historical reasons or because Walter wrote it. Is it a sufficient reason 
for them to stay?
They are no doubt useful sometimes, but are we going to put everything 
that is useful sometimes into Phobos?


I believe it would be better for everyone to keep Phobos simple and 
prevent the two libraries from competing by separating the functionality.
Once they don't compete anymore, users won't have to worry about what 
library to use how to stay compatible.


Also my thoughts. Several months ago I send similar proposition to 
divide libraries responsibilities:

- for Phobos - low level API
- for Tango - higher level API

Stuff which is in both libraries should be designed together by both 
teams. Andrei is talking about new design for IO in Phobos. Why not to 
prepare this new design together with Tango people?


Some differences between philosophies of libraries should not stop 
merging. E.g. Phobos uses IO synchronized with C, but Tango is not. Why 
to divide libraries based on this? I think that there are cases where 
users would want one approach and also cases where they would want the 
other. IMHO standard library should have API allowing one or other 
approach depending on what user wants... So this difference is purely 
rhetorical...


BR
Marcin Kuszczak
(aarti_pl)
www.zapytajmnie.com - my christian site


Re: Any chance to call Tango as Extended Standard Library

2009-01-22 Thread Denis Koroskin

On Thu, 22 Jan 2009 09:18:52 +0300, Benji Smith  
wrote:


IUnknown wrote:
Agree. Which is why I said the problems you are facing seem to be  
non-technical. I'm suggesting that the D library developers should pick  
one and axe the other. *I* think what more important is to have one  
single set of containers in a single style rather than have two  
separate ones. There is going to be complaining for sure from the  
current developers, but in my opinion, the target of having a single  
standard library (with core and advanced modules to suit system/ app  
programming) is more important than having to make a difficult choice.


Totally agree. While I personally prefer the Java-style containers, I'd  
gladly accept the STL-style containers if it meant unification of Phobos  
and Tango.


Having druntime is nice, sure, but application-level code and high-level  
libraries will bake the container API into their public interfaces, and  
any code that uses both the Phobos and Tango libraries would have to  
perform a zillion tedious conversions.


In my mind, the things that need a unified API are (in order of  
importance):


1. GC and TypeInfo
2. Data structures
3. Algorithms
4. String processing
5. Date & Time
6. IO

Everything else (encryption, compression, sockets, regular expressions,  
could have a totally different API in Tango & Phobos and I wouldn't care  
much.


Having a common runtime (GC and TypeInfo) is a neat trick, but pretty  
useless if the data structures and algorithms are entirely different.


And, while I'm perfectly willing to accept either Java-style or  
STL-style containers, I'd also really appreciate it if the design  
anticipates and supports custom implementations (because I almost always  
end up implementing my own multimaps, multisets, circular queues etc)


--benji


I think believe we could take advantage of current state of both libraries in 
D2 - they are both incomplete and being redesigned to fit D2 better.
We could revisit both Tango and Phobos, and clean them up by removing outdated 
modules and modules with same functionality. This will make Phobos really small 
and much easier to learn.

On the other hand, Tango will continue providing all the extended functionality.

Here is a list of Phobos modules that I believe could be safely removed:

- crc32 and std.md5 - these should be deprecated in favor of 
tango.io.digest.Crc32 and tango.io.digest.Md5
Tango is better designed and has support for other algoriths (MD2, MD4, SHA256, 
SHA512, Tiger and more).
See http://www.dsource.org/projects/tango/wiki/ChapterEncodingAndCrypto for 
details.

- std.atomics - tango.core.Atomic is superior to it (std.atomics has nothing 
but CAS anyway).
- std.base64 - deprecate in favor of tango.io.encode.Base64
- std.cover - is it supposed to be visible to user? Should it be in Phobos?
- std.loader - deprecate in favor of tango.sys.SharedLib
- std.bitarray
- std.openrj
- std.process - merge with tango.sys.Process
- std.regexp - buggy, deprecate in favor of tango.text.Regex
- std.socket, std.socketstream - deprecate in favor of tango.net.*
- std.uni - deprecate in favor of tango.text.Unicode
- std.uri - deprecate in favor of tango.net.Uri
- std.xml - deprecate in favor of tango.text.xml.*
- std.zip and std.zlib - deprecate in favor of tango.io.compress.*

In almost *all* cases Tango has cleaner, faster and less buggy implementation 
of the same functionality.

Other modules - does anyone use any of these:
std.bitmanip
std.bind
std.boxer
std.outbuffer
std.stdint
std.syserror
std.system
?

There are a lot of modules that only exist in Phobos because of some historical 
reasons or because Walter wrote it. Is it a sufficient reason for them to stay?
They are no doubt useful sometimes, but are we going to put everything that is 
useful sometimes into Phobos?

I believe it would be better for everyone to keep Phobos simple and prevent the 
two libraries from competing by separating the functionality.
Once they don't compete anymore, users won't have to worry about what library 
to use how to stay compatible.



Re: Templates and virtual functions

2009-01-22 Thread Aarti_pl

Walter Bright pisze:
Setting aside the technical issues for the moment, I'd like to go back 
to the notion that structs are for compile time polymorphism and classes 
are for runtime polymorphism. Template functions are clearly in the 
compile time camp, and if you need compile time polymorphism in a class, 
perhaps the design should be seriously looked at to see if that's 
justifiable.


That's not always true. I have similar case in my serialization library 
(Doost project) where template function is called in class to get 
information about class properties/values. Then, to support 
serialization from base classes I need to make virtual call to get most 
derived class. My point here is that there are cases where virtual 
template functions would be needed in classes.



As to resolving the technical issue, put the instantiation of the 
template inside another virtual function:


class foo {
T nothing(T)(T arg) {  // Non-virtual.
return arg;
}

int virtual_nothing(int arg)
{
return nothing!(arg);
}

float virtual_nothing(float arg)
{
return nothing!(arg);
}
}

The advantage of this is there is nothing new to learn.


I was thinking about above design in my serialization library. As I 
already said it is needed for serialization of classes from base class 
reference (It's necessary to know most derived class to do proper 
serialization).


Unfortunately such a design cause quite a big problem for users of such 
a library. Please let me explain below.


I have following template in my libs:

template Serializable() {
  void describeUdt(T)(T arch) {
foreach(i, v; this.tupleof)
  arch.describe(this.tupleof[i], this.tupleof[i].stringof);
  }
}

Argument passed to function describeUdt is Archive, which is class, 
representing what type of output/input is used for serialization (JSon, 
Text, Binary etc)


To make user class serializable is is just enough to put it as a mixin 
into user class.


class UserClassA {
  mixin Serializable;
}

And now, to support serialization from base class pointer I played with 
following design:



class UserClassA {
  mixin Serializable;

  void transportUdt(Archive arch) {
describeUdt!(Archive)(arch);
  }
}

class UserClassB : UserClassA {
  mixin Serializable;

  void transportUdt(Archive arch) {
describeUdt!(Archive)(arch);
  }
}

The problem here is that:
1. User of library will have to know all types of Archive template class 
(which is privately created by Serializer class). There are a lot of 
different possible classes which can be produced from Archive template 
class based on input/output stream type and based on type of archive. 
They should be unknown for user.


2. It is necessary to put functions transportUdt for every different 
Archive type into serialized class. It must be done by hand by user, as 
I don't see a way to make it automatically...


Do you see any nice solution for above problem? I was thinking about 
registering somehow different Archive types during their instantiations 
and then automatically generating necessary functions transportUdt, but 
it doesn't seem to be possible currently...


I would be happy to know about a good solution for this...

REF: 
http://www.dsource.org/projects/doost/browser/trunk/doost/util/serializer


Best Regards
Marcin Kuszczak
(aarti_pl)
www.zapytajmnie.com - my christian site