Re: this is almost a workaround for the lack of named parameters

2013-03-25 Thread foobar

On Saturday, 23 March 2013 at 15:00:13 UTC, bearophile wrote:

foobar:

Code that needs named parameters to be more readable is poorly 
designed code in the first place.


Have you used a language where the usage of named arguments is 
idiomatic, like Python, Scala or Ada? They are sometimes useful 
even for well designed code, like functions with two arguments.


Bye,
bearophile


idiomatic is a relative term, tightly coupled to a specific 
language. Idiomatic D code for example is very different from 
idiomatic Haskell code.
Idiomatic Python style in D would be very unidiomatic D code and 
vise versa. Each language has its own conventions, styles, set of 
distinct features, etc, etc and trying to use language A style 
while coding in language B is like trying to fit a square peg 
in a round hole.
For instance, I would NOT use smalltalk naming conventions while 
writing say Java code. Both have very good and very consistent 
styles that are tightly coupled with their respective syntaxes 
and are very unsuitable to use in the other language.


In short, if you want to discuss python features, style or 
specific math plotting libraries, please post to the python 
mailing list, not D's NG.


Re: this is almost a workaround for the lack of named parameters

2013-03-25 Thread foobar

On Saturday, 23 March 2013 at 15:59:12 UTC, Jacob Carlborg wrote:

On 2013-03-23 16:55, John Colvin wrote:


A simple example is matplotlib.pyplot.plot

There are so many possible flags and parameters that can be 
passed in
order to get the exact behaviour you want, but commonly you'll 
only want
a few set for each call. You don't want to have to set all the 
other
preceding parameters, you just want to go e.g. plot(data, 
linewidth=5)


I've heard it was a big boost for C# when it got support for 
default arguments and named parameters. It made it a lot easier 
to integrate with COM.


AFAIK, this is only relevant or useful for COM (i.e. to support 
legacy, not really OO code) and is not supported (compile error?) 
for regular C# code as it is *not idiomatic C#* style (and is not 
OO).


Re: this is almost a workaround for the lack of named parameters

2013-03-25 Thread foobar

On Monday, 25 March 2013 at 13:02:49 UTC, bearophile wrote:

foobar:

idiomatic is a relative term, tightly coupled to a specific 
language. Idiomatic D code for example is very different from 
idiomatic Haskell code.
Idiomatic Python style in D would be very unidiomatic D code 
and vise versa. Each language has its own conventions, styles, 
set of distinct features, etc, etc and trying to use language 
A style while coding in language B is like trying to fit a 
square peg in a round hole.
For instance, I would NOT use smalltalk naming conventions 
while writing say Java code. Both have very good and very 
consistent styles that are tightly coupled with their 
respective syntaxes and are very unsuitable to use in the 
other language.


In short, if you want to discuss python features, style or 
specific math plotting libraries, please post to the python 
mailing list, not D's NG.


Imperative/OOP languages are not totally different from each 
other, both Python and D derive strongly from C that comes 
partially from Algol, and D copies several things from Python 
(string functions, part of the module system, part of the range 
design comes from itertools, and so on). So comparing languages 
and their features is very useful.


If you have not used named arguments in languages that 
idiomatically use them, then it's not easy for you to see how 
and why they are sometimes useful and good.


In Python function arguments don't have a type, so named 
arguments are more useful than in D. But from my experience in 
Python, I believe D could enjoy named arguments.


Bye,
bearophile


C is a HORRIBLE language regarding naming conventions and is a 
*very poor choice* to learn from in this regard. Python sets very 
high expectations regarding beautiful code and IMHO fails 
miserably (more so because of the starting higher expectations).
I admit to being spoiled by actually beautifully designed 
languages that are far superior in that respect. I suggest to 
learn Smalltalk for a language that emphasizes code readability 
decades before Python became cool.
I find Ruby which is based on Smalltalk's semantics and spirit to 
be more elegant and less pretentious compared to Python.


Re: this is almost a workaround for the lack of named parameters

2013-03-23 Thread foobar

On Friday, 22 March 2013 at 21:41:46 UTC, John Colvin wrote:

On Friday, 22 March 2013 at 21:29:46 UTC, foobar wrote:

On Friday, 22 March 2013 at 21:10:27 UTC, John Colvin wrote:

On Friday, 22 March 2013 at 20:04:14 UTC, foobar wrote:


WTF? What do kwargs have to do with programming? Sounds more 
like a half-Klingon  half-Ferengi species to me.


kwargs = keyword arguments

It's a common naming convention in python, as exemplified in 
matplotlib.


That was meant more as a rhetorical question rather than a 
real one.
Yes, I guessed the meaning by the surrounding context but 
nevertheless it was a major WAT while skimming the post. Also, 
Who the fuck cares whats common in Python? I was reading and 
replying on the *D* NG, was I not?


Kwarg seems a reasonable name, consistent with a pre-existing 
convention. Please suggest a better alternative if you have 
one. I must admit I'm bemused by your level of aggression over 
what appears to be a trivial matter.


Your read it wrong. Not aggression but rather annoyment.
Also, code readability is NOT a trivial matter and people who 
think that it is should have their keyboard chopped off.


IMHO, I think the entire feature is a code smell and glad D does 
not support it. Code that needs named parameters to be more 
readable is poorly designed code in the first place.


Re: this is almost a workaround for the lack of named parameters

2013-03-22 Thread foobar

On Friday, 22 March 2013 at 10:17:02 UTC, J wrote:
With credit for inspiration to David Medlock in this post-- 
http://forum.dlang.org/thread/d9lnrr$26q3$1...@digitaldaemon.com 
...


// Tongue firmly in cheek, I'd like to introduce
// the NAPAPISS principle: (with apologies to SFINAE and RAII)

// NAPAPISS = NAmed Parameters Are simply Passed in a Struct, 
Silly.


// Yes, indeed, maybe this is what happens after drinking too 
much of
// the fine wine products from the Napa valley... you start 
having

// wild flights of fancy of how D might surprisingly soon have
// named parameters


import std.stdio;
import std.c.stdlib;

void main(string[] arg) {

// this works today: but with the drawback that the
// named params must be known at compile time...

// Here is a named param call,
// as compact as I could get it (see struct below for 
actual definition).


auto a = myfunc!q{ z= 2; x = -123; y = 200 }(0)(); // calls 
opCall

writeln(a=, a); // prints a=yo, as returned from opCall



// And here's the runtime version, unfortunately you have to
// pre-declare g because otherwise it won't survive the 
scope, and
// the return value from myfunc.opCall would become 
inaccessible.

string g;
with(myfunc!()(0)) {
  x=rand() % 40;
  y=x/2;
  z=y/2;
  g = call(); // as a side effect, prints 'X 7, Y 3, Z 
1'

 }
 writeln(g=, g); // prints g=yo, as returned from opCall


/*
// The bright future: this demonstrates that
// it would be fairly trivial to make some kind of 
annotation

// like @kwarg or whaterver, to indicate that a function
// was using this calling convention:
@kwarg string f(int a, string b) { body; }

// so that @kwarg function definitions are lowered to:
struct f_kw {
  int a;
  string b;
  string f() { body; }
}

// and calls to @kwarg functions are transformed
// from this:
auto r = f(a=5, b=good);

// into this:
f_kw tmp34;
tmp34.a = 5;
tmp34.b = good;
auto r = tmp34.f();

// the benefit: named parameters can be used in a natural 
way,

// and they need be known only at runtime.
*/
}

// how the 'works today' above examples were implemented:
struct myfunc(string init_string=)
{
   // named keyword or named parameters
   // --the call arguments and their defaults
   int x=0;
   int y=0;
   int z=0;

   this(int) {}
   string opCall() {
 mixin(init_string ~ ;);
 writefln(X %s, Y %s, Z %s, x, y, z );
 return yo;
   }
   alias opCall call;
}


On Friday, 22 March 2013 at 09:18:33 UTC, J wrote:


The bigger point here is more profound: it is trivial to 
implement named parameters using structs + trivial lowerings, 
and this is no way conflicts with function overloading.


D deserves to have named parameters to functions -- it makes 
for much more legible code, and obviates the need for slow 
builder patterns.  Readable and speedable. It's win-win.


WTF? What do kwargs have to do with programming? Sounds more like 
a half-Klingon  half-Ferengi species to me.


Re: this is almost a workaround for the lack of named parameters

2013-03-22 Thread foobar

On Friday, 22 March 2013 at 21:10:27 UTC, John Colvin wrote:

On Friday, 22 March 2013 at 20:04:14 UTC, foobar wrote:


WTF? What do kwargs have to do with programming? Sounds more 
like a half-Klingon  half-Ferengi species to me.


kwargs = keyword arguments

It's a common naming convention in python, as exemplified in 
matplotlib.


That was meant more as a rhetorical question rather than a real 
one.
Yes, I guessed the meaning by the surrounding context but 
nevertheless it was a major WAT while skimming the post. Also, 
Who the fuck cares whats common in Python? I was reading and 
replying on the *D* NG, was I not?


Re: Are there any default dmd optimizations

2013-02-28 Thread foobar
On Wednesday, 27 February 2013 at 21:57:06 UTC, Andrei 
Alexandrescu wrote:

On 2/27/13 3:16 PM, Jacob Carlborg wrote:

On 2013-02-27 14:29, Andrei Alexandrescu wrote:

Four years ago I would've entirely agreed. But right now it's 
an odd
comment to make seeing as we're discussing all major 
decisions in this

group and we're switching full-bore to DIPs.


The alias this syntax the foobar mentioned was removed under 
the radar

and only discussed in a pull request.


I agree we were sloppy on that. Kenji was feeling strong about 
and Walter and I didn't have particular objections, so we gave 
him green light. In the process we neglected backward 
compatibility.


Andrei


At a bare minimum, there should be a well defined place to notify 
*users* (NOT DMD contributers) about language changes *ahead of 
time*. If such place is not defined, than people do not know 
where to look for that info if that is even available at all. 
This at least will remove the element of surprise.


For D to be really open as it claims to be, there should be 
additional guidelines about the decision making process itself. 
This should be made accessible for *users* (D programmers). I 
need not be a core DMD contributer, nor should I need to know C++ 
or DMD's internals, Nor should I need to browse among hundreds of 
bugs on bugzilla or pull requests on github (both can be labeled 
very poorly) to discern out of that sea of information what are 
the *few* visible changes to the language and core library APIs.


Re: Are there any default dmd optimizations

2013-02-27 Thread foobar
On Tuesday, 26 February 2013 at 23:37:57 UTC, Andrei Alexandrescu 
wrote:

snip


Agreed, but it does happen often that a language feature is 
later superseded by a generalization thereof.


Andrei


I agree that this does happen. The question is how the language 
evolve with that in mind. Do we choose to preserve *all* previous 
semantics? Do we have a proper deprecation process? etc, etc..
I think that unfortunately, the D design process is not adequate 
as of yet - there is no proper deprecation process which causes 
things like a sudden death for previously valid syntax (alias 
syntax) instead of gradually deprecate it with proper 
announcements *everywhere* (website, NG, ..) on the one hand and 
keeping redundant special cases in the language and refusing to 
change semantics (AAs) to allow for an easier path forward, on 
the other hand.


So I think we agree on the spirit of things but the problems I'm 
voicing are about the details or lack thereof. Where are the 
guidelines describing all these issues? How to address required 
semantic changes in the language? how to address syntax changes? 
how to remove previously failed features or no longer needed 
ones? What constitutes a feature that should be completely 
removed and what should only be put on permanent deprecation 
status? How all those things interact?
If we still (after a decade!) decide these based on c++ common 
wisdom only than I think something is really broken here. 
Previously valid D syntax is easily broken without much regard 
yet we are still stuck on the comma backwards compatibility to C. 
We ignore all other languages that programmers migrate from to D 
and ignore their common wisdom and experience. Isn't it time for 
D to become its own language instead of a leech on C++ idioms?


Re: Are there any default dmd optimizations

2013-02-27 Thread foobar
On Wednesday, 27 February 2013 at 00:01:31 UTC, Andrei 
Alexandrescu wrote:


I understand how you see it, and honestly could see it from a 
mile. When a post (a) cherry-picks all negatives and (b) has a 
final tone that mentions no possible solution - it's a foregone 
conclusion that no amount of explaining, amending, arguing, 
etc. will improve the poster's outlook.


I could say e.g. Well I think things have changed, and look 
we've turned the bug trend curve (http://goo.gl/kf4ZC) which is 
unprecedented, fixed some incomplete features, break new 
records on bug fixes with each release, and have a big 
conference coming. - to which I have no doubt it's possible to 
concoct a negative answer.


So I understand you have a negative outlook on D. That's 
entirely fine, as is mentioning it on the forum. The only thing 
I'd like you to understand and appreciate is that we who work 
on D are doing our best to find solutions to the various 
problems in front of us, and in quite a literal sense we don't 
know how to do any better. The constructive thing I'm getting 
out of this is that we could use some more radicalization - try 
things that push stronger against our comfort zone. I have a 
few in mind but it's too early to discuss them publicly.



Andrei


Let me emphasize again, I did *not* intend to discuss the 
specific features, Walter brought that topic up. I intended to 
point out the lack of good general guidelines for the D design 
process. And i did actually mention one (partial) solution. I 
mean no disrespect to the hard work of the contributers and did 
not wish to discourage them, just to prevent wasted effort due to 
lack of proper guidelines.
The other criticism I have is exactly the last paragraph above. 
Rust is designed in the open and so I can read the weekly minutes 
and get the bigger picture of the design process, what are the 
different proposed alternatives, what are the considerations and 
trade-offs, etc. In D on the other hand, it's all closed. D 
claims that it is an open source project but all the major design 
decisions happen personally between you and Walter and this is 
worse than big company languages that at least publish some 
articles online.


Re: Are there any default dmd optimizations

2013-02-26 Thread foobar

On Monday, 25 February 2013 at 22:26:33 UTC, Walter Bright wrote:

On 2/25/2013 2:00 PM, foobar wrote:
On Sunday, 24 February 2013 at 22:28:46 UTC, Walter Bright 
wrote:
By baking one scheme into the language, people will rarely 
feel a need to
reinvent the wheel, and will go on to more productive uses of 
their time.
This is a fallacy caused by the culture of c++ programmers - 
there is exactly

*zero* benefit in baking this into the language.


On the contrary, I think it has turned out rather well. Another 
success story of baking certain things into the language is 
Ddoc. Unittest is a third. They've been big wins for D.


None of those strictly has to be in the language - they can be 
done by convention and 3rd party tools. Nevertheless, 
convenience, standardization and mechanical enforcement of a 
convention seem to work better than applying religious zeal to 
enforce a convention.




DDoc isn't part of the language but rather part of the compiler, 
nevertheless it has its downsides. Being part of the compiler 
means that the compiler needs to be changed to address those and 
it isn't even written in D! The end result is all sort of 
additional auxiliary D utilities to post-process this in order to 
address some of those issues. Hence, A prime example of the 
failure that I'm talking about.


unittest is worse, it is indeed part of the language so now the 
_language grammar_ needs to be changed to fix the problems with 
it, such as not having test names. A far better solution 
practiced in all other major languages is to use annotations and 
in fact, there probably already are similar D frameworks, thus 
exhibiting the same problem of multiple conflicting 
implementations you wished to avoid.


Additional such problems - the AA issue which has been going own 
for years now. The endless discussions regarding tuples.
It seems that D strives to bloat the language with needless 
features that really should have been standardized in the library 
and on the other hand tries to put in the library things that 
really ought to be built into the language to benefit from proper 
integration and syntax.


The latest case was the huge properties debate and its offshoots 
regarding ref semantics which I didn't even bother participate 
in. Bartosz developed an ownership system for D to address all 
the safety issues raised by ref *years ago* and it was rejected 
due to complexity. Now, Andrei tries to achieve similar safety 
guaranties by giving ref the semantics of borrowed pointers. It 
all seems to me like trying to build an airplane without wings 
cause they are too complex. Rust on the other hand already 
integrated an ownership system and is already far ahead of D's 
design. D had talked about macros *years ago* and rust already 
implemented them.




All of this is to say, that instead of trying to fix the c++ 
culture in D, we

should try to create a *better* D culture.


We do have a significantly better D culture than the C++ one. 
For example, C++ relies heavily and unapologetically on 
convention for writing correct, robust code. D eschews that, 
and instead is very biased towards mechanical verification.




I call bullshit. This is an half hearted intention at best.
@safe has holes in it, integers has no overflow checks, ref also 
has holes, Not only D has null pointer bugs but they also cause 
segfaults.





In fact there are many such not c++
features in D and which is why I find other languages such as 
rust a *much*
better design and it evolves much faster because it is 
designed in terms of -

what we want to achieve, how best to implement that.


How does rust handle this particular issue?




Re: Are there any default dmd optimizations

2013-02-26 Thread foobar

On Tuesday, 26 February 2013 at 10:59:41 UTC, Dicebot wrote:
I agree with all but small comment on unit tests : current 
approach makes it really easy to start adding tests for 
projects that do not have them and this is huge. So having 
unittest blocks themselves is really a success feature. 
Tightly coupling handling of this blocks to compiler is an 
issue though.


Again, this is a completely superfluous feature. D already has 
annotations (took only several years to convince Walter to add 
them) which are more flexible and much better suited for this.


@unittest // - this is a unit-test function
void mySuperDuperTestFunction(...);

There is no benefit in having all those special case features in 
the language which have all sorts of integration issues yet deny 
the usefulness of a more general solution generally accepted in 
the programming world, successfully used in many languages and 
thus also familiar to programmers coming from those languages.


Re: Are there any default dmd optimizations

2013-02-26 Thread foobar
On Tuesday, 26 February 2013 at 18:41:24 UTC, Andrej Mitrovic 
wrote:

On 2/26/13, foobar f...@bar.com wrote:

Rust on the other hand already
integrated an ownership system and is already far ahead of D's
design.


Far ahead? It allows things like local variables shadowing 
earlier declarations:


let monster_size = monster_factor * 10.0;
...
let monster_size: int = 50;

That's straight from the tutorial. When has anyone thought to
themselves I need a new variable to store some result to, but 
damn, I
wish I could use an existing name but use it to store a 
completely

different type. That is an incentive to write unreadable code.

And then there are things like this:

Note that, if applied to an integer value, ! flips all the 
bits (like ~ in C).


So (!2 == true)?

There are plenty of complaints for both languages (it's only 
natural),
but saying that Rust is somehow far ahead, I don't buy that one 
bit.
It's all too easy to cherrypick features which are in one 
language and

not in the other.


I don't get what fault you find in the binary NOT operation.
Regardless, my post wasn't really about specific features, 
(Walter actually mentioned those) but rather about the general 
design philosophy of D which I find lacking. Yes, it is obviously 
true that Rust has it own share of faults, The difference is what 
*principals* they use to address those faults and evolve the 
language.
Rust is written in Rust, thus the developers themselves feel all 
the shortcomings, they also listen to their users and they strive 
to find the best way to express the semantics they want in the 
possibly simplest yet readable syntax possible. They think 
positive and build on their vision, whereas D thinks negatively 
based on C++'s vision.
D exists for more than a decade and all it provides is slightly 
less hackish C++.
At first, I dismissed Rust for having poor syntax (ret really? 
Are we back to assembly?) but lo and behold, in a very short time 
they considerably improved the syntax. D still argues about the 
exact same issues from several years ago, as if it's stuck in a 
time loop. This to me shows a lack of direction. I expected thing 
to improve lately with all those newly minted release process 
discussions and such, but alas the attitude hasn't shifted at all.


Re: Are there any default dmd optimizations

2013-02-26 Thread foobar

On Tuesday, 26 February 2013 at 19:53:11 UTC, Walter Bright wrote:

On 2/25/2013 11:56 PM, foobar wrote:
DDoc isn't part of the language but rather part of the 
compiler, nevertheless it

has its downsides.  [...]
unittest is worse,


I think you're missing something gigantic. Before D had ddoc, 
the documentation for Phobos was TERRIBLE - it was mostly 
missing, and the rest would describe something that had no 
resemblance to what the code did. Adding Ddoc completely 
revolutionized this. It's like night and day. Sure, you can 
pick at Ddoc's flaws all day, but without Ddoc, the Phobos 
documentation would have remained utter s**t.


Yes, one could use Doxygen. One could hope an up-to-date 
version exists on all the platforms D is on. One could nag 
people to use it. One could argue with people who wanted to use 
a different doc generator. And one could look at typical C and 
C++ projects, which use no documentation generator at all, and 
pretty much have no documentation or have documentation as bad 
as the pre-Ddoc Phobos docs.


Having Ddoc always there, always installed, always up to date, 
with literally zero effort, tips the balance. It gets used. It 
raised the bar on what is acceptable D code - it looks wrong 
without Ddoc documentation. By tipping the balance I mean it 
*revolutionized* D code.




All of the above describes the benefits of having standardized 
documentation and I agree with that. That has nothing to do with 
DDoc's specific design compared to other similar efforts. A quick 
survey of languages shows that Ruby, Python, Java, C#, and many 
others all have the same benefits but non has the doc generator 
built into the compiler/vm with all the problems this entails.


The same goes for unittest. How many C/C++ projects have you 
run across that have unit tests? Again, yes, you can use 3rd 
party tools (of which there are a plethora). You can try to use 
multiple libraries that use different unit test frameworks. You 
can look at Phobos before unittest and see that it was pretty 
much completely untested.


Unittest in the language, always there, always installed, zero 
effort, completely changed the game. I'm very pleased at the 
depth and breadth of unittests in Phobos. I have no doubt that 
would not have happened without unittest.


Sure, you can pick all day at the flaws of unittest, but you'd 
be missing the point - without builtin unittest, there'd be 
nothing to pick at, because people would not have unit tests.




Same as above. You compare again to C++ and ignore the provably 
successful models of _many_ other languages. Ruby for instance 
really shines in this regard as its community is very much 
oriented towards TDD. Java has such a successful model with its 
JUnit that it inspired a whole bunch of clones for  other 
languges and you completely ignore this. Instead you discuss the 
design of a new car based on experiences of horseback riders.




Additional such problems - the AA issue which has been going 
own for years now.

The endless discussions regarding tuples.
It seems that D strives to bloat the language with needless 
features that really
should have been standardized in the library and on the other 
hand tries to put
in the library things that really ought to be built into the 
language to benefit

from proper integration and syntax.


A little history is in order here. AA's were built in to the 
language from the beginning, a result of my experience with how 
incredibly useful they were in javascript. This was many years 
before D had templates. There was no other way at the time to 
implement them in a nice manner (try doing it in C, for 
example).


D's improving generics has enabled them to be redone as library 
features.




I'm familiar with the history of AAs in D and how they came to be 
this horrible mess. Yet, templates in D are ancient news by now 
and the problem hadn't been fixed and not due to lack of effort. 
The problem is again - applying common c++ wisdom and trying to 
maintain inconsistent semantics.





The latest case was the huge properties debate and its 
offshoots regarding ref
semantics which I didn't even bother participate in. Bartosz 
developed an
ownership system for D to address all the safety issues raised 
by ref *years
ago* and it was rejected due to complexity. Now, Andrei tries 
to achieve similar
safety guaranties by giving ref the semantics of borrowed 
pointers. It all seems
to me like trying to build an airplane without wings cause 
they are too complex.
Rust on the other hand already integrated an ownership system 
and is already far
ahead of D's design. D had talked about macros *years ago* and 
rust already

implemented them.


Bartosz' ownership system was intended to support multithreaded 
programming. It was and still is too complicated. I've been 
working on another design which should serve the purpose and 
will need nearly zero effort from the programmer and it won't 
break anything. There was some

Re: Are there any default dmd optimizations

2013-02-25 Thread foobar

On Sunday, 24 February 2013 at 22:28:46 UTC, Walter Bright wrote:

On 2/24/2013 12:57 PM, Andrej Mitrovic wrote:

On 2/24/13, Jonathan M Davis jmdavisp...@gmx.com wrote:
Yeah, which just adds the confusion, because all it does is 
enable debug

bocks.


The feature almost doesn't pay its weight. I mean technically 
you can
use -version=Debug and then use version(Debug) blocks. All 
`debug`

does is saves a little bit of typing.


I should explain the reasoning for this.

I've talked to many C/C++ programming managers. They lament 
that every C/C++ coding group feels compelled to reinvent their 
own debug macro scheme. This makes it pointlessly difficult to 
share code between groups.


It's not that unlike how pre-C++98 code bases all had their own 
string class.


By baking one scheme into the language, people will rarely feel 
a need to reinvent the wheel, and will go on to more productive 
uses of their time.


This is a fallacy caused by the culture of c++ programmers - 
there is exactly *zero* benefit in baking this into the language.
Yes, I agree with the sentiment that there should be a standard 
way to save programmers the hassle and all that. The correct 
solution to that is a culture of cultivating standard conventions 
and convention over configuration. E.g. Java has many such 
convections followed to a level of religious zeal, such as using 
camelCase everywhere and using PascalCase for types, etc, etc. 
None of which is _enforced by the language_.
On the other hand, many major c++ libraries re-invent string 
even though there exists already std::string and there are even 
libraries that advocate _avoiding_ the use of stl entirely, all 
for the perceived benefit of efficiency which is a prime example 
of premature optimization. Even if there is efficiency gain in a 
specific implementation, ideally it should have been used to 
improve the standard stl::string but trying to change anything in 
the c++ standard is futile - you can't just send a pull request, 
you need to pass boat loads of red tape and wait a decade or two 
for the next version, thus causeing this major NIH attitude.
All of this is to say, that instead of trying to fix the c++ 
culture in D, we should try to create a *better* D culture. When 
you're buying an airplane ticket, what do you say to the travel 
agent? The human reflex of I don't want to go to ___ doesn't 
get you a ticket anywhere. This feature is analogous - it's 
designed to not allow c++ misbehavior, instead of actually 
thinking what we do want and how best to achieve that. In fact 
there are many such not c++ features in D and which is why I 
find other languages such as rust a *much* better design and it 
evolves much faster because it is designed in terms of - what we 
want to achieve, how best to implement that.


Re: Transitioning to the new Release Process

2013-01-15 Thread foobar

On Saturday, 12 January 2013 at 12:20:21 UTC, Johannes Pfau wrote:

Am Sat, 12 Jan 2013 09:22:27 +0100
schrieb foobar f...@bar.com:


[...]

Regarding pull requests targeting master, the current model 
*is* geared around that. Most contributions _should_ go to 
master (aka devel) and go through the full process. 
pull-requests for staging are meant for fixing regressions and 
critical bugs only, where there is _higher urgency_ for the 
fix that justifies the short-cut. Regular bug fixes should 
simply go through the regular process and will be released in 
the _next_ release.


I also think targeting staging for some pull requests is not 
that bad.
In the end it's not that bad if a pull request was accidentally 
merged
into master instead of staging. It just means that it'll take 
more time
for the fix to appear in a release (It'll be delayed by one 
release),

but it won't mess anything up.

Regarding where most requests go: This also depends on the 
project. I
guess for phobos most requests are enhancements/new features 
and would
go to master. For druntime it's mostly bugfixes, so probably 
more
requests target staging. And for the dmd almost everything is a 
bug fix

and could target staging.

The wiki currently says all bug fixes should go to staging. 
This is a
concession to D's rapid development. But again, it's not that 
important
where the pull requests go. We should try to make breaking 
changes in
master and have only harmless changes in staging, but the 
exact

decision is always up to the contributor  maintainers.

But those 'minor' tweaks such as defining what exactly is 
merged to

master and what to staging can always be made later on.


Yea, I agree with the above. I'll just add two additional points:
1. Perhaps it makes sense to have more strict rules for new 
contributors. So Walter, Don, etc could merge straight to 
/staging/ but someone new will need to have a few pull requests 
accepted to master before they are allowed the same privilege.
2. Regarding DMD - it depends on the definition of what a bug 
fix is. There are many bugs regarding conflicts with the spec 
or unimplemented features. Even though these are listed as bugs 
on bugzilla they are really enhancements or new features and 
probably should go through an extra cycle via merging to /master/.
For example, An implementation of auto ref for regular 
functions should really be treated as a new feature (and have a 
full design cycle) even though it's formally listed as a bug.


Re: Transitioning to the new Release Process

2013-01-15 Thread foobar

On Monday, 14 January 2013 at 10:33:56 UTC, mist wrote:
On Saturday, 12 January 2013 at 12:30:05 UTC, Johannes Pfau 
wrote:

Am Fri, 11 Jan 2013 18:54:12 +0100
schrieb mist n...@none.none:

Short comment about cherry pick - it is only bad in sense 
that it
creates separate untrackable commit with same content, which 
may

easily result in merging issues. If there is only one-way
direction for commit transitioning ( stuff goes from master to
staging and LTS and never goes back ) there is nothing 
inherently

bad about cherry pick.


Having multiple commit ids for the same commit is also 
annoying. For
example if someone bisected a regression and you want to 
revert a commit
you have to figure out the commit id of the cherry picked 
commits.




AFAIK reverts are content-based, so knowing any one commit id 
is enough. It is annoying mostly when comparison happens 
between two branches with those commits.



Much more important point is that
it complicates development process for newcomers without any
reasonable benefit. And if we still gonna push for success as 
an
open-source project, being easy understandable by an outsider 
is

as important as a clear release process.

The rule is quite simple and easy to understand though:
regression fix - version branch
bug fix - staging
enhancement - master


Ye, it is easy.. except you need to actually check out wiki 
page to be aware about it. At the very least we need relevant 
excerpts for outer devs separated to one small wiki page and 
set links to this page in github marked with big NB:.


I don't have a reason to argue about the rest.


The default is /master/ so any new dev unfamiliar with the 
process will just get his stuff delayed by one release which 
provides extra safety if you think about it. There is no _need_ 
to read the wiki as the process will work just fine without it. 
it'll just default too the longer, safer option.
I really see no point in arguing this it complicates the 
process point any further.


Re: Transitioning to the new Release Process

2013-01-12 Thread foobar

On Friday, 11 January 2013 at 18:03:33 UTC, mist wrote:
My understanding is that your understanding is somewhat 
different from initial proposal but that is where discussion 
has flow to since then and that makes me sad :)


They very reason to have staging is to have better replacement 
to beta process which simply does not work good enough 
currently. Is good to have a single branch all the time, which 
some obscure project maintainer can check from time to time to 
make sure his stuff still compiles and fire regression bug 
reports if needed. He may even have add this test to own 
continuous integration suite (I'd do this if I had a serious D 
project) to be notified when stuff goes wrong without paying 
any constant attention.


Attention is a key here. How many D projects are out there? How 
many of their maintainers pay close attention to newsgroup and 
read beta mail list? Compare this to being able to check your 
stuff on very next release at any moment you have time and want 
to.


I stand at the point that for open source projects release and 
development processes should care most about end users and 
developers and least - about maintainers. Maintainers should 
have perfect git and process knowledge anyway, or at some 
scales thing are doomed to be crewed (2.061 anyone?).


Thus I vote for a persistent staging branch.



My understanding was that staging is worked on only during the 
(short) time span from initiating a new release and finalizing 
that release.


Andrei


I don't understand the problem you seem to see in the process.

I've been away from the PC so couldn't respond earlier but I did 
manage to read most of the wiki page and I think Johnathan did a 
very good job explaining the various concepts. The only thing 
missing IMO is CI:
It's already agreed that master is the development channel in the 
proposed process. The next logical step would be to generate 
nightly builds off of that branch. The staging branch is the 
beta channel - and also makes sense to have a periodical beta 
build. This depends on the release time span but something like 
fortnight or monthly beta builds makes sense to me.
the additional manual builds described on the wiki on staging or 
even before an official release on the version branch will be 
something like RCs.


Regarding pull requests targeting master, the current model *is* 
geared around that. Most contributions _should_ go to master (aka 
devel) and go through the full process. pull-requests for staging 
are meant for fixing regressions and critical bugs only, where 
there is _higher urgency_ for the fix that justifies the 
short-cut. Regular bug fixes should simply go through the 
regular process and will be released in the _next_ release.


Re: github release procedure

2013-01-03 Thread foobar

On Thursday, 3 January 2013 at 20:42:39 UTC, Johannes Pfau wrote:

Am Thu, 03 Jan 2013 21:17:08 +0100
schrieb Rob T r...@ucora.com:

On Thursday, 3 January 2013 at 19:19:49 UTC, Andrei 
Alexandrescu wrote:

 On 1/3/13 1:58 PM, Walter Bright wrote:
 As I suggested to Jacob, if the wiki lists git command 
 sequences, it
 should be complete (like a script), and not full of 
 assumptions about

 other commands that need to be inserted.

 I think this is a pertinent point - the process proposed at 
 github is incomplete and scantily motivated. Can the experts 
 make one more pass through it?


 Thanks,

 Andrei

I'm rather concerned when I see comments that suggest that the 
purpose of the staging branch was not understood in the 
slightest. There's a lot of discussion on the issue here 
http://forum.dlang.org/thread/ka5rv5$2k60$1...@digitalmars.com


Sorry, but I'm not sure if we have a consensus on some things 
discussed

there:
This is probably the best summary:
http://forum.dlang.org/thread/ka5rv5$2k60$1...@digitalmars.com?page=16#post-woyboqigqbkqjxmshppn:40forum.dlang.org


4. Feature can than be further refined and _integration bugs_ 
can

be fixed by the general dev team.

What's the overhead for many small feature branches? DMD work is
probably 90% small bug fixes and 10% bigger features. So most 
of the

time there are no integration bugs and we just waste man power
reviewing commits again and copying those into staging?


When the dev branch is considered stable enough by the team
(exact criteria to be defined later), the changes are merged to
the _2nd level of integration_ - the staging branch. This
allows for a wider audience to test and provide real-world
feedback.

The exact criteria would be kinda important. But as we have 
many small
bugfixes which are merged every day I don't see how the master 
branch

would suddenly get more stable.


What I am most concerned about are the timespans discussed:
I propose to go for a yearly release of the
stable branches with one year support (In the beginning).

The wiki discussion page even mentions I don't think 4 months 
are a
ridiculously long time for staging if the release is made every 
3

years.


Let's clarify a bunch of things here:
1. There is no overhead with maintaining many feature brunches.
2. Feature branches can be safely removed after their contents 
have been merged. This is useful for avoiding clutter.
3. There is no need to re-review the _same_ code on each branch 
it is merged to. That's just plain stupid.
4. Chery picking is a HORRIBLE idea for managing releases and 
should only be used on development. Chery-picking COPIES commits 
and thus loses the connections in the history graph.
5. There is no problem developing bug_fixes on separate topic 
branches.

6. There is no problem merging back to master.
7. Let me say this again. Merges are cheap and easy in git. So 
are re-merges. Avoiding merges is an artifact of client-server 
designs such as SVN and is NOT compatible with Git's conceptual 
model.


I suggest to read about how git works and how best to utilize its 
features, and NOT apply common wisdom from CVS/SVN/RCS which are 
based on a _completely different_ conceptual model.


Re: github release procedure

2013-01-03 Thread foobar
On Thursday, 3 January 2013 at 22:04:28 UTC, Jonathan M Davis 
wrote:

On Thursday, January 03, 2013 21:42:37 Johannes Pfau wrote:

What I am most concerned about are the timespans discussed:
I propose to go for a yearly release of the
stable branches with one year support (In the beginning).

The wiki discussion page even mentions I don't think 4 months 
are a
ridiculously long time for staging if the release is made 
every 3

years.


That makes it sound like they want the current stuff to be 
marked as staging
and then have some other release that sits around for a very 
long time being
treated as somehow more stable than the staging branch. In 
general, there's
nothing about bug fixing which is stable, and separating out 
bug fixes between a
more stable branch and a less stable one doesn't make all that 
much sense.
Separating out new features and not putting them in the 
stable branch makes

sense, but that really doesn't make sense for bugs.

Also, the name staging implies that it's purely for preparing 
a release, in
which case keeping it around makes _no_ sense. Not to mention, 
as already
mentioned, it would make more sense to simply create a new 
branch for each
release to begin with than have a staging branch if that's what 
it's for. And

if that's not what it's for, then it's a horrible name.

- Jonathan M Davis


As I explained several times before, this is a HORRIBLE idea. If 
each release has its own branch than a bug fix needs to be 
applied to _all_ such branches _manually_ and it is easy to get a 
situation where a fix on say version 3.1 was accidentally not 
merged to version 4.0 (forgotten) and suddenly the bug was 
unfixed.
Whatever the name of this branch is, the semantics/purpose of it 
is to provide integration.


Re: moving away from changelog.dd?

2012-12-26 Thread foobar

On Tuesday, 25 December 2012 at 19:44:41 UTC, Walter Bright wrote:

On 12/25/2012 11:19 AM, Jonathan M Davis wrote:

On Tuesday, December 25, 2012 04:18:10 Walter Bright wrote:

On 12/25/2012 3:41 AM, Jonathan M Davis wrote:
I think that that's what most of us are agreed upon at this 
point. What is
currently the WHATSNEW section will continue to be done by 
hand, but the

LIBBUGSFIXED section will be autogenerated.


WHATSNEW is a list of new features, which are (or should be) 
in bugzilla as

enhancement requests.


So, if we put a new module through the review process, we're 
going to go and
create an ehancement request for it after the fact just so 
that it's in

bugzilla and shows up in the automatically generated changelog?


Yes. Recall that there are a pretty small number of these, so 
it's fair to compromise on this.



That seems off
to me. Bugzilla is for reporting bugs or requesting that 
things be added to
the language or library, not for reporting everything that we 
do.

The SCM log is for that.


That log is pretty useless for anyone who wants a list of bug 
fixes and new features, as it is full of commits that are 
irrelevant to users.



Also, some of those sorts of changes should probably get more 
prominence than
they're likely to get in the middle of a list of bugzilla 
issues, or they may

require further explanation.


Full explanations were never what the changelog was for, that's 
why it is a list of clickable links.


And it's not like it takes much time or effort to maintain the 
the WHATSNEW

section, as it's much smaller than the bug fix section.


Nor does it take much time or effort to add 3 enhancement 
requests to Bugzilla for new modules.



Various musings, rationales, future changes, etc., should go 
in a separate

document called releasenotes.

I don't think it's viable to have a document half-generated 
automatically

and half-editted by humans.


I really don't see why not. The section with new stuff gets 
written by hand and
the bug fix section gets created with a bugzilla query. What's 
so hard about

that?


Sure it's possible, but I prefer to keep the complexity down of 
generating the site. Also, releasenotes and changelog serve 
different purposes, it makes sense to have them be separate 
documents. (A future change is NOT a change to the current 
release.)



I don't think that we've been having any problems whatsoever 
dealing

with the WHATSNEW section.


Yes, we have. Things have frequently been omitted.


It seems everyone agrees there need to be an automated changelog 
and a hand written release-notes. I don't see a point to continue 
bikeshading whether they belong in a single document or two 
separate ones. Just pick the one that is easiest to implement! We 
can always add a link to the changelog from the release-notes to 
satisfy those that want a single document.


The more important issue is whether to add bugzilla entries after 
the fact and whether the changelog should be geberated from Git 
or bugzilla.
In the _current_ state of affairs yor (walter) are correct that 
relying on git log messages will be useless. BUT, this is only 
another symptom of the current broken process.
The CORRECT way to implement this would be to take the actual 
changes from the SCM (git) on the RELEASE branch (as opposed to 
the development branch) and filter it to only use MERGE commits. 
What that does is, it ignores all the intermediate development 
commits that are irrelevant.


Filling up bugzilla with entries that do not belong there 
shouldn't be the long term solution.


Re: dlang.org Library Reference

2012-12-23 Thread foobar
On Saturday, 22 December 2012 at 23:04:47 UTC, Andrei 
Alexandrescu wrote:

On 12/22/12 5:10 PM, foobar wrote:
On Friday, 21 December 2012 at 21:58:34 UTC, Jacob Carlborg 
wrote:

On 2012-12-21 18:05, Andrei Alexandrescu wrote:


s/remove/integrate/
s/ugly/awesome/


It's ugly that they are manually created. Over 300 lines of 
comments
that the doc generator should be doing automatically. I would 
say that

is far from awesome.


I would add to that that duplicating both the FS and the D 
module system
by yet another method of grouping symbols is a *horrible* 
notion reeks

of poor design.


What is FS? File system?

Andrei


Yes, FS is the file system. sorry if it wasn't clear.

Any categorization IMO must be made *within* the language and not 
in comments/documentation just as other attributes such as purity 
and constancy are also better served being *within* the language. 
D has plenty of means to accomplish this: code can be organized 
into packages and modules and within a module, free functions can 
be organized within stateless structs for additional namespace 
categorization.


Using an all encompassing algorithms module is also unhelpful 
as all code is essentially an algorithm to accomplish some task. 
This is akin to opening a store called - A store or perhaps A 
place to sell you stuff.
As a client of said shop, I want a better description if I to buy 
at the shop. Even a general Clothes shop is already much 
better. For 3rd party it also often makes sense to have a brand 
name - e.g we all know what vibe.d is all about.


Re: dlang.org Library Reference

2012-12-23 Thread foobar
On Sunday, 23 December 2012 at 13:21:16 UTC, Andrei Alexandrescu 
wrote:

On 12/23/12 6:44 AM, foobar wrote:
Using an all encompassing algorithms module is also 
unhelpful as all
code is essentially an algorithm to accomplish some task. This 
is akin
to opening a store called - A store or perhaps A place to 
sell you

stuff.


That I disagree with a bit. I think it's rather clear that 
std.algorithm includes classic, consecrated algorithms the kind 
you'll find in a book entitled Algorithms. By your argument a 
book called Algorithms would not make sense because it would 
need to describe the entire computing world.


So if I'm looking for sort, I'd open algorithm. If I'm 
looking for parsing program options, I wouldn't expect it to be 
in the same place.


As a client of said shop, I want a better description if I to 
buy at the
shop. Even a general Clothes shop is already much better. 
For 3rd
party it also often makes sense to have a brand name - e.g we 
all know

what vibe.d is all about.


Such differentiation is also useful.


Andrei


Does it mean you agree with the rest? :)

Regarding std.algorithm, the module isn't called - 'classic, 
consecrated algorithms the kind you'll find in a book entitled 
Algorithms'. It is simply called 'std.algorithm' and there are 
many, *many* books on algorithms. Should this module include 
concurrent algorithms? Should it include distributed algorithms? 
Should it include statistic algorithms? Should it include natural 
language processing algorithms? Should it include genetic 
algorithms? I think it's clear by now that the name does not 
convey what you intend it to convey.


A much better and more user friendly scheme would be to classify 
the algorithms by their *functionality* and not by some undefined 
belongs to classical algorithms books relation.

e.g. Sorting algorithms, Set operations, etc.
Now, if I want to sort something I know to shop at the sorting 
algorithms outlet and don't need to spend time going over a 
potentially infinite list of algorithms.


Re: dlang.org Library Reference

2012-12-22 Thread foobar

On Friday, 21 December 2012 at 18:31:48 UTC, Sönke Ludwig wrote:

Am 21.12.2012 18:05, schrieb Andrei Alexandrescu:

(...)

The cheat sheet in std.algorithm is unnecessary (though I 
liked the brief examples), but there's a
lot of value in the symbols grouped by category (searching, 
comparison, ...) at the top. So we need

to have a means to group things in the new interface.


Ideally, we would invent some standard DDOC syntax to specify 
groups then. But generally an
ungrouped list also has its advantages when you try to look 
something up _by name_. I've found
myself in the past, skimming over the category table multiple 
times, looking for a certain function,
until deciding that I had to guess the category first, which 
may not always be obvious.


So maybe keeping the manual category quick index table (and 
maybe putting it in a separate
Categories: section) is a viable option for the time being? 
Most modules probably wouldn't need

one anyway.

What also would be nice is to have the methods inline, 
expandable.


Would that mean the Classes/Structs/... tables as f.ex. in 
std.datetime?
So there would be a small clickable thing and all members would 
fly out below it as direct links?

and possibly with the short description?
What about different kinds of members? Only methods, all 
grouped by type or all in one list?


I'm just asking because I don't have any preferences for how 
such a thing should look like.


Other docs systems provide a sorted index of symbols and also the 
module tree can be further expanded to see the contained symbols. 
Both very handy features.


Re: dlang.org Library Reference

2012-12-22 Thread foobar

On Friday, 21 December 2012 at 21:58:34 UTC, Jacob Carlborg wrote:

On 2012-12-21 18:05, Andrei Alexandrescu wrote:


s/remove/integrate/
s/ugly/awesome/


It's ugly that they are manually created. Over 300 lines of 
comments that the doc generator should be doing automatically. 
I would say that is far from awesome.


I would add to that that duplicating both the FS and the D module 
system by yet another method of grouping symbols is a *horrible* 
notion reeks of poor design.


Re: Next focus: PROCESS

2012-12-21 Thread foobar

On Friday, 21 December 2012 at 18:34:12 UTC, Rob T wrote:
On Thursday, 20 December 2012 at 23:43:12 UTC, Joseph Cassman 
wrote:

Just some food for thought.

In the section about the Branching model, the wiki currently 
has a staging branch in addition to the master branch. From 
what I understand, the idea seems to be to vet a release on 
staging until it is considered production level and then 
marked as the release.


Another idea could be to keep the quality of the master branch 
at a high level so as to be able to branch into a release at 
any time, directly from master. Before feature branches are 
merged back into master, their quality is vetted so the 
quality of master is maintained.


This idea seems similar to what is used for the vibe.d project 
(http://vibed.org/temp/branch-model-small.png). My apologies 
if I misunderstood their process.


It looks like Xamarin has been using this process for a while 
and it seems to be working for them. 
http://tirania.org/blog/archive/2011/Oct-14.html


Joseph


Doesn't that just turn master into staging, and turn the 
feature branches into a diluted and distributed version of 
master?


If there's no common development branch to work with that 
integrates the most current features together, then how will 
such a thing ever be properly tested before going into a high 
quality common branch?


We also need the ability to stop brand new poorly tested 
features from making their way into a release, so at some point 
a common pre-release branch needs to be frozen from receiving 
any new features so that it can be honed into a high quality 
product. If you use the master branch for such a thing, then no 
new features can go into it, so with master frozen, what common 
branch is available for the devs to merge their new work into?


--rt


Precisely.
I think people just don't understand the purpose of these 
additional branches. The point being - integration.


The general flow of events should be:
1. Developer has cool idea/feature which he explores on a 
separate private feature branch
2. During development of the feature the developer can optionally 
collaborate with other developers. This can be done either by 
pulling from other developers' repositories directly or by 
pushing to a branch on github. Either way, this is an ad hoc my 
new feature branch.
3. First level of integration - feature is complete and is merged 
into official first level of integration - the dev branch 
(consensus was to use master for that)
4. Feature can than be further refined and _integration bugs_ can 
be fixed by the general dev team.
5. When the dev branch is considered stable enough by the team 
(exact criteria to be defined later), the changes are merged to 
the _2nd level of integration_ - the staging branch. This 
allows for a wider audience to test and provide real-world 
feedback.
6. when the 2nd level of integration is complete, the changes are 
stable enough to be released and the included features finalized.


Since git provides each developer with their own private copy of 
the entire repository there is *no need* to define any official 
processes prior to initial integration. The developers are free 
to collaborate by using ad hoc branches. The only common sense 
recommendation I'd give (again, NOT part of the _official 
process_) is to use meaningful branch names if they are meant to 
be shared with other people.


Re: Next focus: PROCESS

2012-12-20 Thread foobar

On Thursday, 20 December 2012 at 05:33:27 UTC, Rob T wrote:

On Wednesday, 19 December 2012 at 21:58:12 UTC, foobar wrote:


Personally, I think the whole pre-development stage needs to 
get looks at -
Specifically having some sort of at least high-level *binding* 
planning - road map, mile stones, todo lists. This should give 
more weight to DIPs.
DIPs at the moment have no weight whatsoever. The attributes 
showed all the major flows in the decision making process:


1. Feature idea comes up in discussion.
2. Feature was discussed heavily by the community reaching 
some design consensus.
3. Plan is abandoned/forgotten due to Walter's objections - 
not to the design but the idea itself.
4. Feature comes up again in discussion, thus returning to 
point 1 above in infinite loop.




A big fix is in order there too, it's actually what should be 
fixed first but from what I've seen going on in here if we can 
get something even basic implemented for the development and 
releases that will be a *huge* step forward. Once we have some 
kind of formalized process in place and prove to everyone how 
much better things are because of it, it'll be a first by the 
looks of things, and from that experience the other big holes 
will become easier to pick out and deal with.


I think we have to keep it simple for now, focus on a dev, 
staging, release process, implement something, work out the 
bugs, get people used to having it, and prove the value, then 
we can get on with tackling the other major issues in a similar 
way.


There's lots of room for improvement ahead, but we need to make 
at least one significant step forward in a successful way 
before we can hope to move on to the next one.


--rt


I see both as going hand-in-hand, otherwise we have chicken-egg 
problem.
We need a better process to allow more developers to contribute 
code more easily *and* we need better planning to provide 
incentive for new developer to contribute code.
Implementing only the the planning provides incentive but no 
means. Implementing only the process provides the means but not 
the incentive.


While improving git mastery levels is beneficial of itself, it 
brings no benefit to the _users_ if only Walter is still the main 
developer. We end up wasting Walter's time on adjusting to a new 
system for a hypothetical non existent system of many developers, 
when he already has a working system for the actual existing 
situation of being the sole main developer.


We need an *initial high-level* design for both parts. We can 
define and refine the details later and we probably should defer 
it to later and adjust it as we go along based on experience.
Arguing now on the exact time span of a release just wastes mind 
cycles and detracts from the important bits - reaching a 
consensus regarding the goals of the project and defining a 
general workflow that achieves those goals with minimal amount of 
overhead.


Re: The impoliteness of overriding methods

2012-12-20 Thread foobar

On Thursday, 20 December 2012 at 08:12:54 UTC, Paulo Pinto wrote:

On Thursday, 20 December 2012 at 07:48:12 UTC, foobar wrote:
On Thursday, 20 December 2012 at 00:07:49 UTC, H. S. Teoh 
wrote:
On Thu, Dec 20, 2012 at 12:11:34AM +0100, Andrej Mitrovic 
wrote:

Some interesting blog post:
http://journal.stuffwithstuff.com/2012/12/19/the-impoliteness-of-overriding-methods/

It's a post about a common problem in class design, I've ran 
into it a

few times in D too.

[...]

Interesting concept. So polite overriding is simply a kind 
of override
where the derived class method has a vtable entry separate 
from the base
class method's entry (and thus needs explicit invocation from 
the base
class), whereas the usual impolite overriding is a kind of 
override
where the derived class method replaces the vtable entry of 
the base

class method.

I can see use cases for both kinds of overriding.

Interestingly enough, in the polite overriding case, the 
call to inner
is undefined until it's defined in the derived class. Which 
means that a
method that calls inner is a kind of pseudo-abstract method 
(since
abstract methods are those that *must* be implemented by the 
derived
class). So if we were to implement this in D, we could extend 
the

meaning of 'abstract':

class Base {
// The current, usual overridable method
void replaceMe() {
writeln(A);
}

// Abstract, because chain(chainMe) is undefined until
// the derived class implements it.
abstract void chainMe() {
writeln(B);
inner.chainMe(); // call derived class method
// 'inner' is a tentative
// keyword
writeln(C);
}
}

class Derived : Base {
override replaceMe() {
writeln(D);
Base.replaceMe();
writeln(E);
}

// Base.chainMe is abstract, so we have to implement
// this method.
override void chainMe() {
writeln(F);
}
}

void main() {
auto d = new Derived();
d.replaceMe();  // prints D A E
d.chainMe();// prints B F C
}


T


This is trivially implemented with a simple OO design pattern 
in any usual OO language:


class Base {
 public override precious() {...}
 private void myPrecious() {
   before();
   precious();
   after();
 }
}

class Derived {
 override precious() {...}
}

Having syntax sugar is redundant given how simple this pattern 
is.


No because in your example you have to write Base already for 
that specific use case, whereas in BETA is up to the derived 
class to do as it please.


Have you read the article?
The Beta design (btw, it's the same in smalltalk - the article is 
wrong on that point) is to give control to the base class. The 
base class in beta is written specifically for that use case and 
the derived has no-control. That's the entire point of this 
design. It is basically a restriction to allow only overriding 
abstract methods (with a slightly more convenient syntax)


Re: The impoliteness of overriding methods

2012-12-20 Thread foobar
On Thursday, 20 December 2012 at 10:22:56 UTC, Benjamin Thaut 
wrote:

Am 20.12.2012 10:44, schrieb sclytrack:


I guess in the polite version you would make the call to the 
derived
version here. The derived version wouldn't have to call super 
or anything.




The problem I have with the inner method is performance. With 
the super method you know which method to call at compile time. 
The call can even be inlined. With the inner method you have to 
do another vtable lookup for each inner call. If implemented it 
should be possible to choose on a per method basis which kind 
of overriding policy is used, in my opinion.


This argument is false.

With the current usual design:
Base instance = new Derived();
instance.method(); // #1

With Beta design:
Base instance = new Derived();
instance.method(); // #2

In case #1, the call to method itself is virtual while the call 
to super is not, whereas in case #2 the call to method is _not_ 
virtual, but the call to inner is virtual. Either way you get one 
virtual call. The difference is the direction of the calls.


Re: The impoliteness of overriding methods

2012-12-20 Thread foobar
On Thursday, 20 December 2012 at 10:15:47 UTC, Benjamin Thaut 
wrote:

Am 20.12.2012 10:44, schrieb sclytrack:


@mustcallbefore @mustcallafter

Would these be automatically called in all derived versions?

@autocallbefore  @autocallafter




I think @mustcall would suffice, because it won't compile. If 
it does not compile the customer will investigate what broke 
and fix it (hopefully) appropriately. But of course the other 
options would be nice too.


So basically you suggest adding a language feature to cover up 
library developer's poorly designed API? IMO, if you want to 
provide a frozen API under the current inheritance design, you 
should use pimpl design pattern in the first place and not ask 
for features to solve the problem after the fact.


Re: The impoliteness of overriding methods

2012-12-20 Thread foobar

On Thursday, 20 December 2012 at 14:51:31 UTC, Dan wrote:

On Thursday, 20 December 2012 at 07:48:12 UTC, foobar wrote:



This is trivially implemented with a simple OO design pattern 
in any usual OO language:


class Base {
 public override precious() {...}
 private void myPrecious() {
   before();
   precious();
   after();
 }
}

class Derived {
 override precious() {...}
}

Having syntax sugar is redundant given how simple this pattern 
is.


I think it is more than syntactic sugar and in this case it is 
trivial because you as a designer of Base anticipate only one 
level of Derived. But, assume there are to be 2, 3, 4, or more 
levels of derivation. In fact, maybe you don't know how many 
levels there will be. For a chain of B-D1-D2-D3 I don't see 
how you can up front get the same effect this way. At the level 
of D2, base will skip the implementation of precious() in D1. 
At the level of D3, base will skip the implementation of 
precious() in D1 and D2, etc. Chaining is lost beyond the first 
level. It is as if something is done in one direction, you want 
it done the other and you provide an example that does the 
reversion as long as there are only two entries. It is not 
truly a general solution.




You misunderstand. It is precisely what the quote bellow says - 
it saves you from coming up with new names. The same pattern can 
be applied multiple times for the multi-derivation case you bring 
up, it's just needs more method names.


To extend my previous example:

class Derived {
  override precious() {
beforeDerived();
furtherPrecious();
afterDerived();
  }
}

class FurtherDerived : Derived {
  void furtherPrecious() {...}
}

Now, we get this call chain:
base.myPrecious() - Derived.precious() - 
FurtherDerived.furtherPrecious()

This can be extended ad infinitum.

From the article: If you chain more than two levels of 
subclasses, BETA scales better because you don’t need to keep 
coming up with new names.


Thanks
Dan


Re: The impoliteness of overriding methods

2012-12-20 Thread foobar

On Thursday, 20 December 2012 at 19:46:25 UTC, H. S. Teoh wrote:

On Thu, Dec 20, 2012 at 08:30:36PM +0100, foobar wrote:

On Thursday, 20 December 2012 at 14:51:31 UTC, Dan wrote:

[...]

I think it is more than syntactic sugar and in this case it is
trivial because you as a designer of Base anticipate only one
level of Derived. But, assume there are to be 2, 3, 4, or more
levels of derivation. In fact, maybe you don't know how many
levels there will be. For a chain of B-D1-D2-D3 I don't 
see how
you can up front get the same effect this way. At the level 
of D2,

base will skip the implementation of precious() in D1. At the
level of D3, base will skip the implementation of precious() 
in D1
and D2, etc. Chaining is lost beyond the first level. It is 
as if
something is done in one direction, you want it done the 
other and
you provide an example that does the reversion as long as 
there

are only two entries. It is not truly a general solution.


You misunderstand. It is precisely what the quote bellow says 
- it
saves you from coming up with new names. The same pattern can 
be
applied multiple times for the multi-derivation case you bring 
up,

it's just needs more method names.

To extend my previous example:

class Derived {
  override precious() {
beforeDerived();
furtherPrecious();
afterDerived();
  }
}

class FurtherDerived : Derived {
  void furtherPrecious() {...}
}

Now, we get this call chain:
base.myPrecious() - Derived.precious() -
FurtherDerived.furtherPrecious()
This can be extended ad infinitum.

[...]

But the fact that you keep having to invent new names is itself 
the
problem. It inevitably leads to horrible APIs that consist of 
names
suffixed by numbers: precious(), precious1(), precious2(), 
precious3(),
ad nauseaum. Method names that are suffixed by numbers are, as 
a rule,
an indication of bad API design. They also make your derived 
classes
immovable around the hierarchy, because to override their 
parent's
method, they have to use the exact name that's introduced by 
the parent
class, otherwise they risk accidentally short-circuiting part 
of the

chain.

Whereas BETA's unification of the entire chain of calls under a 
single
name means that it's trivial to shuffle derived classes around 
the
hierarchy -- you're guaranteed they only overload their 
immediate
parent's method, and it stems the inevitable tide towards the 
horrible

number-suffixed method names.

I'm not saying that the BETA approach cannot be represented by 
the
traditional approach -- they are functionally equivalent, as 
you point
out. It's just that for some use cases, the BETA approach is 
superior.
(All high-level languages compile to ASM, but that doesn't mean 
they add

no value to programming directly in ASM.)


T


Yeah, I agree with all of the above points and in a completely 
new language designed from scratch I may very well prefer the 
more principled Beta approach over the regular D approach.


But, In our current circumstances and given that D indeed already 
implements a functionally equivalent feature which we are not 
going to remove or replace, I just don't see adding this, in 
essence a duplicate feature, worth the complexity cost. As Anderi 
phrases that - it just doesn't pull its weight.


It's all a matter of trade-offs and we cannot and should not 
strive to put all possible feature combinations and 
implementation variants into D.


Re: The impoliteness of overriding methods

2012-12-20 Thread foobar
On Thursday, 20 December 2012 at 20:58:40 UTC, Benjamin Thaut 
wrote:

Am 20.12.2012 20:12, schrieb foobar:
 This argument is false.

 With the current usual design:
 Base instance = new Derived();
 instance.method(); // #1

 With Beta design:
 Base instance = new Derived();
 instance.method(); // #2

 In case #1, the call to method itself is virtual while the
call to super
 is not, whereas in case #2 the call to method is _not_
virtual, but the
 call to inner is virtual. Either way you get one virtual
call. The
 difference is the direction of the calls.

No its not, if you have a chain that is longer than just 1 you 
will have more virtual calls in the inner case.


Kind Regards
Benjamin Thaut


well, if the library developer wants to gain full control of that 
long call chain than yes, it will come with a certain price. The 
same price if you design the same way in C++. In practice however 
how common are those chains and how long are they? As far as I'm 
aware, inheritance of concrete classes has mostly fallen out of 
favor nowadays so practically speaking this is still 
insignificant.


Btw, This reminds me the OO class in university which makes it 
very clear that the C++/Java/C#/etc variant of inheritance is 
inherently flawed. It conflates two orthogonal concerns - 
sub-typing and sub-classing.
Small-talk for example is dynamically typed so inheritance only 
serves the sub-classing concern. Interfaces in Java where 
designed to serve only the sub-typing concern.


I find Rust's trait system fascinating precisely because they 
realized this and did not repeat the same old mistake. They 
haven't addressed fully the sub-classing relation yet but I'm 
eagerly awaiting any developments in that area.


Re: Javascript bytecode

2012-12-19 Thread foobar
On Wednesday, 19 December 2012 at 08:45:20 UTC, Walter Bright 
wrote:

On 12/19/2012 12:19 AM, Max Samukha wrote:
Evidently you've dismissed all of my posts in this thread on 
that topic :-)

As you dismissed all points in favor of bytecode.


And I gave detailed reasons why.


Such as it being a
standardized AST representation for multiple languages. CLI is 
all about that,
which is reflected in its name. LLVM is used almost 
exclusively for that purpose

(clang is great).


My arguments were all based on the idea of distributing 
compiled source code in bytecode format.


The idea of using some common intermediate format to tie 
together multiple front ends and multiple back ends is 
something completely different.


And, surprise (!), I've done that, too. The original C compiler 
I wrote for many years was a multipass affair, that 
communicated the data from one pass to the next via an 
intermediate file. I was forced into such a system because DOS 
just didn't have enough memory to combine the passes.


I dumped it when more memory became available, as it was the 
source of major slowdowns in the compilation process.


Note that such a system need not be *bytecode* at all, it can 
just hand the data structure off from one pass to the next. In 
fact, an actual bytecode requires a serialization of the data 
structures and then a reconstruction of them - rather pointless.



Not advocating bytecode here but you claiming it is completely 
useless is so

D-ish :).


I'm not without experience doing everything bytecode is 
allegedly good at.


As for CLI, it is great for implementing C#. For other 
languages, not so much. There turned out to be no way to 
efficiently represent D slices in it, for example.


There other part of an intermediate representation which you 
ignored is attaching *multiple backends* which is important for 
portability and the web.
Applications could be written in safeD (a subset that is supposed 
to have no implementation defined or undefined behaviors) and 
compiled to such an intermediate representation (let's call it 
common-IR since you don't like bytecode). Now, each client 
platform has its own backend for our common-IR. We can have 
install-time compilation like in .NET or JIT as in Java or both, 
or maybe some other such method.
Having such format allows to add distribution to the system. The 
serialization and de-serialization is only pointless when done on 
the same machine.


Another usecase could be a compilation server - we can put only 
the front-end on client machines and do the optimizations and 
native code generation on the server. This can be used for 
example in a browser to allow D scripting. Think for instant 
about smart-phone browsers.


the dreaded bytecode helps to solve all those use cases.


Re: Compilation strategy

2012-12-19 Thread foobar
On Wednesday, 19 December 2012 at 17:17:34 UTC, Dmitry Olshansky 
wrote:

12/19/2012 1:33 AM, Walter Bright пишет:

On 12/18/2012 11:58 AM, Dmitry Olshansky wrote:
The same bytecode then could be be used for external 
representation.


Sigh, there is (again) no point to an external bytecode.


BTW In the end I think I was convinced that bytecode won't buy 
D much. Esp considering the cost of maintaining a separate spec 
for it and making sure both are in sync.


This argument is bogus. One of the goals of bytecode formats is 
to provide a common representation for many languages. That is 
one of the state goals for MS' CIL and LLVM. So while it's 
definitely true that maintaining and *additional* format and spec 
adds considerable costs, but more importantly this is incorrect 
when *reusing already existing* such formats, not to mention the 
benefits of interoperability with other supported languages and 
platforms.
Consider, calling Java libraries from JRuby, using C# code in F# 
projects, etc.


Say I want to use both Haskel and D in the same project, How 
would I do it? Using LLVM I should be able to - both GHC and LDC 
are based on LLVM.


Re: Next focus: PROCESS

2012-12-19 Thread foobar

On Wednesday, 19 December 2012 at 20:51:57 UTC, deadalnix wrote:

On Wednesday, 19 December 2012 at 19:56:47 UTC, Rob T wrote:


Do we all agree that we need a stable branch?



No. Stable isn't a boolean criteria. You'll find different 
degree of stability going from not so stable (dev version) to 
very stable (dead project).


The wiki already mention a process with a branch per version of 
the software.


Let's generalize this point for the sake of reaching consensus - 
we need _at least one_ stable branch which is separate from 
staging. We are still conflicted as to what should be the 
maximum amount. For the record, I'm with the camp advocating at 
most a fixed amount countable on one hand. That's an O(1) with a 
very small constant as opposed to the O(n) suggestion by Andrei. 
I hope Andrei appreciates the order of efficiency here.


Re: Next focus: PROCESS

2012-12-19 Thread foobar
On Wednesday, 19 December 2012 at 21:30:44 UTC, Andrei 
Alexandrescu wrote:

On 12/19/12 4:23 PM, foobar wrote:
On Wednesday, 19 December 2012 at 20:51:57 UTC, deadalnix 
wrote:

On Wednesday, 19 December 2012 at 19:56:47 UTC, Rob T wrote:


Do we all agree that we need a stable branch?



No. Stable isn't a boolean criteria. You'll find different 
degree of
stability going from not so stable (dev version) to very 
stable (dead

project).

The wiki already mention a process with a branch per version 
of the

software.


Let's generalize this point for the sake of reaching consensus 
- we need
_at least one_ stable branch which is separate from 
staging. We are
still conflicted as to what should be the maximum amount. For 
the
record, I'm with the camp advocating at most a fixed amount 
countable on
one hand. That's an O(1) with a very small constant as opposed 
to the
O(n) suggestion by Andrei. I hope Andrei appreciates the order 
of

efficiency here.


I agree with one stable branch.

Andrei


That's great!
What about the other high level points summarized eloquently by 
H. S. Teoh?
Any other high level points or goals the process should 
incorporate?


Personally, I think the whole pre-development stage needs to get 
looks at -
Specifically having some sort of at least high-level *binding* 
planning - road map, mile stones, todo lists. This should give 
more weight to DIPs.
DIPs at the moment have no weight whatsoever. The attributes 
showed all the major flows in the decision making process:


1. Feature idea comes up in discussion.
2. Feature was discussed heavily by the community reaching some 
design consensus.
3. Plan is abandoned/forgotten due to Walter's objections - not 
to the design but the idea itself.
4. Feature comes up again in discussion, thus returning to point 
1 above in infinite loop.


** 5. After many cycles spanning years, the community accepts 
that the feature will never be added despite a consensus and 
constant demand.
5.1 Feature is added by surprise with deviations from consensus 
design, optionally integrates purely with other parts of the 
language.

5.1.1 Feature is final!

Another prime example is the auto-ref feature which we are stuck 
with because Walter apparently understood differently from what 
you intended.


This is highly coupled with Walter, making it very hard to agree 
on a high level design and delegate its implementation to other 
developers. As far as I see, No major feature was ever 
implemented by someone other than Walter and he has final say on 
all design decisions.


I agree with Walter's motives, he wants to stabilize the language 
and by resisting to feature suggestions he sets a very high bar 
for any major change. That is a good thing. The problem is that 
it all happens in his head and not in plain sight. The community 
has no idea what his plans are, I'm not convinced that even you 
get all the details. That means no planning ahead and no 
delegation. Had we known that Walter sign off featureX but just 
doesn't have the time to implement it, than it still would be on 
the official *binding* todo list and someone else would be able 
to implement this feature. As the situation now stands, no one 
will bother doing any significant work if it has a high chance of 
being entirely dismissed by Walter.


Re: Next focus: PROCESS

2012-12-19 Thread foobar

On Wednesday, 19 December 2012 at 21:58:12 UTC, foobar wrote:
On Wednesday, 19 December 2012 at 21:30:44 UTC, Andrei 
Alexandrescu wrote:

On 12/19/12 4:23 PM, foobar wrote:
On Wednesday, 19 December 2012 at 20:51:57 UTC, deadalnix 
wrote:

On Wednesday, 19 December 2012 at 19:56:47 UTC, Rob T wrote:


Do we all agree that we need a stable branch?



No. Stable isn't a boolean criteria. You'll find different 
degree of
stability going from not so stable (dev version) to very 
stable (dead

project).

The wiki already mention a process with a branch per version 
of the

software.


Let's generalize this point for the sake of reaching 
consensus - we need
_at least one_ stable branch which is separate from 
staging. We are
still conflicted as to what should be the maximum amount. For 
the
record, I'm with the camp advocating at most a fixed amount 
countable on
one hand. That's an O(1) with a very small constant as 
opposed to the
O(n) suggestion by Andrei. I hope Andrei appreciates the 
order of

efficiency here.


I agree with one stable branch.

Andrei


That's great!
What about the other high level points summarized eloquently by 
H. S. Teoh?
Any other high level points or goals the process should 
incorporate?


Personally, I think the whole pre-development stage needs to 
get looks at -
Specifically having some sort of at least high-level *binding* 
planning - road map, mile stones, todo lists. This should give 
more weight to DIPs.
DIPs at the moment have no weight whatsoever. The attributes 
showed all the major flows in the decision making process:


1. Feature idea comes up in discussion.
2. Feature was discussed heavily by the community reaching some 
design consensus.
3. Plan is abandoned/forgotten due to Walter's objections - not 
to the design but the idea itself.
4. Feature comes up again in discussion, thus returning to 
point 1 above in infinite loop.


** 5. After many cycles spanning years, the community accepts 
that the feature will never be added despite a consensus and 
constant demand.
5.1 Feature is added by surprise with deviations from consensus 
design, optionally integrates purely with other parts of the 
language.

5.1.1 Feature is final!

Another prime example is the auto-ref feature which we are 
stuck with because Walter apparently understood differently 
from what you intended.


This is highly coupled with Walter, making it very hard to 
agree on a high level design and delegate its implementation to 
other developers. As far as I see, No major feature was ever 
implemented by someone other than Walter and he has final say 
on all design decisions.


I agree with Walter's motives, he wants to stabilize the 
language and by resisting to feature suggestions he sets a very 
high bar for any major change. That is a good thing. The 
problem is that it all happens in his head and not in plain 
sight. The community has no idea what his plans are, I'm not 
convinced that even you get all the details. That means no 
planning ahead and no delegation. Had we known that Walter sign 
off featureX but just doesn't have the time to implement it, 
than it still would be on the official *binding* todo list and 
someone else would be able to implement this feature. As the 
situation now stands, no one will bother doing any significant 
work if it has a high chance of being entirely dismissed by 
Walter.


The high-level steps as I see them:
1. The community discusses the merits and costs of the suggested 
feature and a consensus must be reached regarding adding such a 
feature.
2. An initial design must be provided - also with consensus. 
including this parts:
2.a. Suggested semantics of the feature - describe as precisely 
as possible
2.b. All interactions with other language features must be 
carefully examined and listed.

2.c An initial syntax agreed upon by the community.
3. Feature is implemented and after reaching some agreed upon 
level of stability is than field tested by the public.
3.1 Based on public feedback, feature design can be refined and 
bugs are fixed until consensus is reached that feature is ready 
to be finalized and merged to the next stable release.


It's vague on purpose - the exact details of how each point above 
is approved is to be decided later. The main principle is that 
approved planned features should be listed on the road map and 
point to their DIP with description of their design. Rejected 
features are also listed as DIPs with the rationale for the 
rejection, this is to avoid wasting time on repeat discussing 
them and requesting them.
Ultimate goal for all this is making the planning process as 
transparent as possible for the community.


Re: Next focus: PROCESS

2012-12-19 Thread foobar

On Wednesday, 19 December 2012 at 21:53:04 UTC, H. S. Teoh wrote:
On Wed, Dec 19, 2012 at 04:48:22PM -0500, Andrei Alexandrescu 
wrote:

On 12/19/12 4:40 PM, deadalnix wrote:
On Wednesday, 19 December 2012 at 21:30:44 UTC, Andrei 
Alexandrescu wrote:

On 12/19/12 4:23 PM, foobar wrote:

[...]
Let's generalize this point for the sake of reaching 
consensus - we

need _at least one_ stable branch which is separate from
staging. We are still conflicted as to what should be the 
maximum
amount. For the record, I'm with the camp advocating at 
most a
fixed amount countable on one hand. That's an O(1) with a 
very
small constant as opposed to the O(n) suggestion by Andrei. 
I hope

Andrei appreciates the order of efficiency here.

I agree with one stable branch.


This does conflict with the requirement you gave before about 
being

able to support anything, as previous stable version cannot be
revised.

Or does stable here mean supported ? (which means we still 
have

branch per version, but only one version is supported)

Walter needs to chime in about that. One possibility is to 
continue

using tags for marking releases, and then branch for the few
important releases that we want to patch.

[...]

This is a good idea, to avoid cluttering the git repo with 
branches.
(But then again, branches in git are cheap so I don't think 
this is

really that big of a deal.)


T


This has nothing to do with repository size, git optimizes that 
anyway.


This is a very good decision which I endorse (well, I suggested 
it in the first place..). Having a single stable branch helps 
integration and minimizes human error in the process.


Re: The impoliteness of overriding methods

2012-12-19 Thread foobar

On Thursday, 20 December 2012 at 00:07:49 UTC, H. S. Teoh wrote:

On Thu, Dec 20, 2012 at 12:11:34AM +0100, Andrej Mitrovic wrote:

Some interesting blog post:
http://journal.stuffwithstuff.com/2012/12/19/the-impoliteness-of-overriding-methods/

It's a post about a common problem in class design, I've ran 
into it a

few times in D too.

[...]

Interesting concept. So polite overriding is simply a kind of 
override
where the derived class method has a vtable entry separate from 
the base
class method's entry (and thus needs explicit invocation from 
the base
class), whereas the usual impolite overriding is a kind of 
override
where the derived class method replaces the vtable entry of the 
base

class method.

I can see use cases for both kinds of overriding.

Interestingly enough, in the polite overriding case, the call 
to inner
is undefined until it's defined in the derived class. Which 
means that a
method that calls inner is a kind of pseudo-abstract method 
(since
abstract methods are those that *must* be implemented by the 
derived
class). So if we were to implement this in D, we could extend 
the

meaning of 'abstract':

class Base {
// The current, usual overridable method
void replaceMe() {
writeln(A);
}

// Abstract, because chain(chainMe) is undefined until
// the derived class implements it.
abstract void chainMe() {
writeln(B);
inner.chainMe(); // call derived class method
// 'inner' is a tentative
// keyword
writeln(C);
}
}

class Derived : Base {
override replaceMe() {
writeln(D);
Base.replaceMe();
writeln(E);
}

// Base.chainMe is abstract, so we have to implement
// this method.
override void chainMe() {
writeln(F);
}
}

void main() {
auto d = new Derived();
d.replaceMe();  // prints D A E
d.chainMe();// prints B F C
}


T


This is trivially implemented with a simple OO design pattern in 
any usual OO language:


class Base {
  public override precious() {...}
  private void myPrecious() {
before();
precious();
after();
  }
}

class Derived {
  override precious() {...}
}

Having syntax sugar is redundant given how simple this pattern is.


Re: Rust updates

2012-12-18 Thread foobar

On Tuesday, 18 December 2012 at 07:36:26 UTC, Marcel wrote:
Rust designers seems to love really short keywords, this is in 
my opinion a bit silly. On the other hand in D you have 
keywords like immutable that are rather long to type. So I 
prefer a mid way between those two.


They aren't silly, they're consistent. We have int, char, auto,
they have fn, var, and val which are common these days, why not
mut, pub, and priv? What is silly are the objections, such as
someone saying that it's like limiting the length of 
identifiers.

It's obviously NOTHING like that.

Rust supports several types of pointers. The simplest is the 
unsafe pointer, written *T, which is a completely unchecked 
pointer type only used in unsafe code (and thus, in typical 
Rust code, very rarely).


It's T, and it has nothing to do with unsafety.


Those are silly as well. Why be consistent with the wrong choice?
I really don't want to see pubs scattered around my code as my 
manager used to say - don't drink and code.


I really like Rust's semantics and the way it progresses but 
there is really no valid nor sane argument for an APL inspired 
syntax. Syntax is meant for human consumption and should be 
designed accordingly. That's one of the main goals of a 
programming language, otherwise we all would just program 
straight in assembly. After all, assembly op codes and numeric 
addresses are much shorter than the equivalent human readable 
identifiers and function names.


Re: Compilation strategy

2012-12-18 Thread foobar

On Tuesday, 18 December 2012 at 00:15:04 UTC, H. S. Teoh wrote:
On Tue, Dec 18, 2012 at 02:08:55AM +0400, Dmitry Olshansky 
wrote:

[...]

I suspect it's one of prime examples where UNIX philosophy of
combining a bunch of simple (~ dumb) programs together in 
place of
one more complex program was taken *far* beyond reasonable 
lengths.


Having a pipe-line:
preprocessor - compiler - (still?) assembler - linker

where every program tries hard to know nothing about the 
previous

ones (and be as simple as possibly can be) is bound to get
inadequate results on many fronts:
- efficiency  scalability
- cross-border error reporting and detection (linker errors? 
errors

for expanded macro magic?)
- cross-file manipulations (e.g. optimization, see _how_ LTO 
is done in GCC)

- multiple problems from a loss of information across pipeline*


The problem is not so much the structure preprocessor - 
compiler -
assembler - linker; the problem is that these logical stages 
have been
arbitrarily assigned to individual processes residing in their 
own
address space, communicating via files (or pipes, whatever it 
may be).


The fact that they are separate processes is in itself not that 
big of a
problem, but the fact that they reside in their own address 
space is a
big problem, because you cannot pass any information down the 
chain
except through rudimentary OS interfaces like files and pipes. 
Even that

wouldn't have been so bad, if it weren't for the fact that user
interface (in the form of text input / object file format) has 
also been
conflated with program interface (the compiler has to produce 
the input
to the assembler, in *text*, and the assembler has to produce 
object
files that do not encode any direct dependency information 
because

that's the standard file format the linker expects).

Now consider if we keep the same stages, but each stage is not a
separate program but a *library*. The code then might look, in 
greatly

simplified form, something like this:

import libdmd.compiler;
import libdmd.assembler;
import libdmd.linker;

void main(string[] args) {
// typeof(asmCode) is some arbitrarily complex data
// structure encoding assembly code, inter-module
// dependencies, etc.
auto asmCode = compiler.lex(args)
.parse()
.optimize()
.codegen();

// Note: no stupid redundant convert to string, parse,
// convert back to internal representation.
auto objectCode = assembler.assemble(asmCode);

// Note: linker has direct access to dependency info,
// etc., carried over from asmCode - objectCode.
auto executable = linker.link(objectCode);
File output(outfile, w);
executable.generate(output);
}

Note that the types asmCode, objectCode, executable, are 
arbitrarily
complex, and may contain lazy-evaluated data structure, 
references to
on-disk temporary storage (for large projects you can't hold 
everything
in RAM), etc.. Dependency information in asmCode is propagated 
to
objectCode, as necessary. The linker has full access to all 
info the
compiler has access to, and can perform inter-module 
optimization, etc.,
by accessing information available to the *compiler* front-end, 
not just

some crippled object file format.

The root of the current nonsense is that perfectly-fine data 
structures
are arbitrarily required to be flattened into some kind of 
intermediate
form, written to some file (or sent down some pipe), often with 
loss of

information, then read from the other end, interpreted, and
reconstituted into other data structures (with incomplete 
info), then
processed. In many cases, information that didn't make it 
through the
channel has to be reconstructed (often imperfectly), and then 
used. Most
of these steps are redundant. If the compiler data structures 
were
already directly available in the first place, none of this 
baroque

dance is necessary.


*Semantic info on interdependency of symbols in a source file 
is

destroyed right before the linker and thus each .obj file is
included as a whole or not at all. Thus all C run-times I've 
seen
_sidestep_ this by writing each function in its own file(!). 
Even

this alone should have been a clear indication.

While simplicity (and correspondingly size in memory) of 
programs
was the king in 70's it's well past due. Nowadays I think is 
all

about getting highest throughput and more powerful features.

[...]

Simplicity is good. Simplicity lets you modularize a very 
complex piece
of software (a compiler that converts D source code into 
executables)
into manageable chunks. Simplicity does not require 
shoe-horning modules
into separate programs with separate address spaces with 
separate (and

deficient) input/output formats.

The problem isn't with 

Re: Compilation strategy

2012-12-18 Thread foobar

On Monday, 17 December 2012 at 22:24:00 UTC, Walter Bright wrote:

On 12/17/2012 2:08 PM, Dmitry Olshansky wrote:
I really loved the way Turbo Pascal units were made. I wish D 
go the same
route.  Object files would then be looked at as minimal and 
stupid variation of
module where symbols are identified by mangling (not plain 
meta data as (would

be) in module) and no source for templates is emitted.
+1


I'll bite. How is this superior to D's system? I have never 
used TP.



*Semantic info on interdependency of symbols in a source file 
is destroyed right
before the linker and thus each .obj file is included as a 
whole or not at all.
Thus all C run-times I've seen _sidestep_ this by writing each 
function in its
own file(!). Even this alone should have been a clear 
indication.


This is done using COMDATs in C++ and D today.


Honest question - If D already has all the semantic info in 
COMDAT sections, why do we still require additional auxiliary 
files? Surely, a single binary library (lib/so) should be enough 
to encapsulate a library without the need to re-parse the source 
files or additional header files?


You yourself seem to agree that a single zip file is superior to 
what we currently have and as an aside the entire Java community 
agrees with use - Java Jar/War/etc formats are all renamed zip 
archives.


Regarding the obfuscation and portability issues - the zip file 
can contain whatever we want. This means it should be possible to 
tailor the contents to support different use-cases:
 * provide fat-libraries as in OSX - internally store multiple 
binaries for different architectures, those binary objects are 
very hard to decompile back to source code thus answering the 
obfuscation need.
 * provide a byte-code solution to support the portability case. 
e.g Java byte-code or Google's pNaCL solution that relies on LLVM 
bit-code.


Also, there are different work-flows that can be implemented - 
Java uses JIT to gain efficiency vs. .NET that supports 
install-time AOT compilation. It basically stores the native 
executable in a special cache.


Re: Compilation strategy

2012-12-18 Thread foobar

On Tuesday, 18 December 2012 at 00:48:40 UTC, Walter Bright wrote:

Wow, I think that's exactly what we could use! It serves 
multiple optional use

cases all at once!

Was there a technical reason for you not getting around 
towards implementing, or

just a lack of time?


There always seemed something more important to be doing, and 
Andrei thought it would be better to put such a capability in 
rdmd rather than dmd.


This is inconsistent with D's design - providing useful features 
built-in (docs generator, testing, profiling, etc).
More over, it breaks encapsulation. This means the compiler 
exposes an inferior format that will later be wrapped around by a 
more capable packaging format, thus exposing the implementation 
details and adding an external dependency on that inferior 
format. Besides, the other compilers merge in the same front-end 
code so they'll gain the same feature anyway. There's no gain in 
separating it out to rdmd.


The main question is if you approve the concept and willing to 
put it on the to-do list? I'm sure that if you endorse this 
feature someone else will come in and implement it.


Re: Next focus: PROCESS

2012-12-17 Thread foobar
On Sunday, 16 December 2012 at 22:43:13 UTC, David Nadlinger 
wrote:

On Sunday, 16 December 2012 at 22:18:14 UTC, SomeDude wrote:
This sounds to me like a bad idea. And indeed, I haven't heard 
of any other project doing this.


Having release branches is a common practice for many open 
source projects. For example, KDE creates a branch per minor 
release, with patch releases being made off that branch. LLVM 
also has a branch for each release.


David


Huh?
Both LLVM and KDE are developed on *subversion* and as such their 
work-flows are not applicable. Not to mention that KDE is vastly 
different in concept and goals than a programming language.


Subversion is conceptually very different from git and its model 
imposes practical restrictions that are not relevant for git, 
mostly with regards to branches, merging, etc. Actions which are 
first class and trivial to accomplish in git. This is analogous 
to designing highways based on the speed properties of bicycles.


Re: Next focus: PROCESS

2012-12-17 Thread foobar
On Sunday, 16 December 2012 at 23:18:20 UTC, Jonathan M Davis 
wrote:

On Sunday, December 16, 2012 11:23:57 Andrei Alexandrescu wrote:
Right now we're using a tagging system for releases, implying 
releases
are just snapshots of a continuum. But what we need is e.g. to 
be able
to patch 2.065 to fix a bug for a client who can't upgrade 
right now.

That means one branch per release.


Well, you can still do that. You just create a branch from the 
tag when you
need a branch. You don't have to branch from the latest. You 
can branch from
any point on the tree, and tags provide a good marker for 
points to branch if

you need to.

Then the official release is still clearly tagged, but you can 
have branches
based off it when you need it. It also avoids some minor 
overhead when patching
releases is rare. My main concern though would be that the 
actual release
needs to be clearly marked separately from any patches, so it 
pretty much

requires a tag regardless of what you do with branches.

What I would have expected that we do (though I haven't read 
through most of
this thread or the wiki yet, so I don't know what's being 
proposed) would be
to branch when we do beta, and that branch would be what would 
ultimately end
up where we release from, with a tag on the commit which was 
the actual
release. If further commits were made for specific clients 
after the release,
then either you'd make a branch from that which was specific to 
that client, or
you'd put them on the same branch, where'd they'd be after the 
tag for the

release and wouldn't affect it.

- Jonathan M Davis


Precisely. Thank you.


Re: Next focus: PROCESS

2012-12-17 Thread foobar
On Monday, 17 December 2012 at 17:45:12 UTC, David Nadlinger 
wrote:

On Monday, 17 December 2012 at 17:31:45 UTC, foobar wrote:

Huh?
Both LLVM and KDE are developed on *subversion* and as such 
their work-flows are not applicable. Not to mention that KDE 
is vastly different in concept and goals than a programming 
language.


Subversion is conceptually very different from git and its 
model imposes practical restrictions that are not relevant for 
git, mostly with regards to branches, merging, etc. Actions 
which are first class and trivial to accomplish in git. This 
is analogous to designing highways based on the speed 
properties of bicycles.


Guess what, I know that. The post by SomeDude just claimed that 
release branches in general are impractical and not used by 
open source projects, which is wrong.


David


At least the first part in that sentence is correct - there are 
more practical work flows that are just more difficult to achieve 
in svn. The branch per release in those projects is just a 
consequence of SVN limitations. hence open source projects _that 
use git_ don't need to follow this route.


Either way, this is completely irrelevant for our purpose.
The process should be designed with DVCS in mind since we already 
settled on this [very successful] model for D. We should avoid 
designing a work-flow based on other models and limited 
experience with git.
Suggestions such as implementing specific [shell?] scripts and 
having branch-per-release brings no improvement over what we 
already have.


I personally transitioned my [previous] team from ancient systems 
(rcs, cvs, proprietary in-house crap) to git. It requires not 
only memorizing a few new command line commands but also grokking 
a different model. Those that do, use git to great effect and 
greatly increase their efficiency, others simply have a ci 
script that calls git commit and gain nothing.
At the moment we may use git commands but really we are still 
developing on mostly a subversion model. Walter used to accept 
patches and those were simply replaced by pull requests. There 
isn't any change in the mental model required to really benefit 
from a decentralized system such as git. This is what the process 
discussion is ultimately meant to fix.


Re: Compilation strategy

2012-12-17 Thread foobar

On Monday, 17 December 2012 at 04:49:46 UTC, Michel Fortin wrote:
On 2012-12-17 03:18:45 +, Walter Bright 
newshou...@digitalmars.com said:


Whether the file format is text or binary does not make any 
fundamental difference.


I too expect the difference in performance to be negligible in 
binary form if you maintain the same structure. But if you're 
translating it to another format you can improve the structure 
to make it faster.


If the file had a table of contents (TOC) of publicly visible 
symbols right at the start, you could read that table of 
content alone to fill symbol tables while lazy-loading symbol 
definitions from the file only when needed.


Often, most of the file beyond the TOC wouldn't be needed at 
all. Having to parse and construct the syntax tree for the 
whole file incurs many memory allocations in the compiler, 
which you could avoid if the file was structured for 
lazy-loading. With a TOC you have very little to read from disk 
and very little to allocate in memory and that'll make 
compilation faster.


More importantly, if you use only fully-qualified symbol names 
in the translated form, then you'll be able to load lazily 
privately imported modules because they'll only be needed when 
you need the actual definition of a symbol. (Template 
instantiation might require loading privately imported modules 
too.)


And then you could structure it so a whole library could fit in 
one file, putting all the TOCs at the start of the same file so 
it loads from disk in a single read operation (or a couple of 
*sequential* reads).


I'm not sure of the speedup all this would provide, but I'd 
hazard a guess that it wouldn't be so negligible when compiling 
a large project incrementally.


Implementing any of this in the current front end would be a 
*lot* of work however.


Precisely. That is the correct solution and is also how [turbo?] 
pascal units (==libs) where implemented *decades ago*.


I'd like to also emphasize the importance of using a *single* 
encapsulated file. This prevents synchronization hazards that D 
inherited from the broken c/c++ model.


Re: Next focus: PROCESS

2012-12-17 Thread foobar

On Monday, 17 December 2012 at 21:03:04 UTC, Rob T wrote:

On Monday, 17 December 2012 at 18:14:54 UTC, foobar wrote:
At the moment we may use git commands but really we are still 
developing on mostly a subversion model. Walter used to accept 
patches and those were simply replaced by pull requests. There 
isn't any change in the mental model required to really 
benefit from a decentralized system such as git. This is what 
the process discussion is ultimately meant to fix.


I think you've made a very good point. In order to make the 
most out of the way decentralized systems work vs a centralized 
one, will require an adjustment in the way people think. If we 
choose to follow the centralized model nothing will be gained 
when using a decentralized service, however centralization has 
its place and there's an obvious need to merge decentralized 
branches into a common centralize branch so that there's a 
common branch to use for testing and performing releases (etc).


I find it's great to debate ideas in here first, not the talk 
page, but any conclusions or interesting points of view should 
be posted into the wiki talk page so that it is not lost. IMO 
this one should go in the wiki if only to remind people that we 
have the flexibility of decentralized model to take advantage 
of.


--rt


DVCS is not about centralized vs. non centralized. This is a 
common misunderstanding which I too had when I started using git.
The actual difference is a client-server topology (CVS, SVN, etc) 
vs. P2P or perhaps free-form topology. By making all users 
equal with their own full copies of the repository, git and 
similar systems made the topology an aspect of the human 
work-flow instead of part of the technical design  
implementation.


This gives you the freedom to have whatever topology you want - a 
star, a circle, whatever. For instance, Linux is developed with a 
web of trust. the topology represents trust relationships. 
Thus, all the people Linus is pulling from directly are core 
developers he personally trust. They in turn trust other 
developers, and so on and so forth. Linus's version is the 
semi-official release of the Linux kernel but it is not the only 
release. For instance, Linux distributions can have their own 
repositories, and Google maintains their own repository for the 
android fork. So in fact, there are *multiple* repositories that 
represent graph roots in this web of trust topology.


What about D?
The current git-hub repository owned by Walter and the core devs 
(the github organization) is the official repository. *But*, we 
could also treat other compilers as roots. more over, there's no 
requirement for developers to go through the main github 
repository to share and sync. E.g Walter can pull directly from 
Don's repository *without* going through a formal branch on 
github. This in fact should be *the default workflow* for 
internal collaboration to reduce clutter and facilitate better 
organization.


This is why I'm arguing fiercely against having any sort of 
official alpha stage. There is no need standardizing this and it 
only mixes private developer only code and builds with builds 
aimed at end-users (those would be us, people writing D code and 
compiling with DMD). If you look on SVN servers, you often find 
an endless list of developer folders, test branches, 
experimental branches, etc, etc.


As a user, this is highly annoying to figure out what branches 
are meant for user consumption (releases, betas, preview for a 
new feature) and what isn't, dev X's private place to conduct 
experiments. This is only a result of the client-server topology 
imposed by svn architecture.


The official process should only standardize and focus on the 
points where integration is required. Everything else is much 
better served as being left alone. On the other hand, I think 
that we need to add more focus on pre/post stages of the actual 
coding. This means, the planning, setting priorities (aka 
roadmap, mile-stones, etc) as well as reducing regressions. I saw 
a post suggesting an automated build-bot that will run the test 
suit and build nightlies. What about DIPs, how do they integrate 
in the work-flow?
I think Andrei talked about the DIPs before but I don't thik it 
was discussed as part of this thread.


Re: Next focus: PROCESS

2012-12-17 Thread foobar

On Monday, 17 December 2012 at 22:02:45 UTC, foobar wrote:

On Monday, 17 December 2012 at 21:03:04 UTC, Rob T wrote:

On Monday, 17 December 2012 at 18:14:54 UTC, foobar wrote:
At the moment we may use git commands but really we are still 
developing on mostly a subversion model. Walter used to 
accept patches and those were simply replaced by pull 
requests. There isn't any change in the mental model required 
to really benefit from a decentralized system such as git. 
This is what the process discussion is ultimately meant to 
fix.


I think you've made a very good point. In order to make the 
most out of the way decentralized systems work vs a 
centralized one, will require an adjustment in the way people 
think. If we choose to follow the centralized model nothing 
will be gained when using a decentralized service, however 
centralization has its place and there's an obvious need to 
merge decentralized branches into a common centralize branch 
so that there's a common branch to use for testing and 
performing releases (etc).


I find it's great to debate ideas in here first, not the talk 
page, but any conclusions or interesting points of view should 
be posted into the wiki talk page so that it is not lost. IMO 
this one should go in the wiki if only to remind people that 
we have the flexibility of decentralized model to take 
advantage of.


--rt


DVCS is not about centralized vs. non centralized. This is a 
common misunderstanding which I too had when I started using 
git.
The actual difference is a client-server topology (CVS, SVN, 
etc) vs. P2P or perhaps free-form topology. By making all 
users equal with their own full copies of the repository, git 
and similar systems made the topology an aspect of the human 
work-flow instead of part of the technical design  
implementation.


This gives you the freedom to have whatever topology you want - 
a star, a circle, whatever. For instance, Linux is developed 
with a web of trust. the topology represents trust 
relationships. Thus, all the people Linus is pulling from 
directly are core developers he personally trust. They in 
turn trust other developers, and so on and so forth. Linus's 
version is the semi-official release of the Linux kernel but it 
is not the only release. For instance, Linux distributions can 
have their own repositories, and Google maintains their own 
repository for the android fork. So in fact, there are 
*multiple* repositories that represent graph roots in this web 
of trust topology.


What about D?
The current git-hub repository owned by Walter and the core 
devs (the github organization) is the official repository. 
*But*, we could also treat other compilers as roots. more over, 
there's no requirement for developers to go through the main 
github repository to share and sync. E.g Walter can pull 
directly from Don's repository *without* going through a formal 
branch on github. This in fact should be *the default workflow* 
for internal collaboration to reduce clutter and facilitate 
better organization.


This is why I'm arguing fiercely against having any sort of 
official alpha stage. There is no need standardizing this and 
it only mixes private developer only code and builds with 
builds aimed at end-users (those would be us, people writing D 
code and compiling with DMD). If you look on SVN servers, you 
often find an endless list of developer folders, test 
branches, experimental branches, etc, etc.


As a user, this is highly annoying to figure out what branches 
are meant for user consumption (releases, betas, preview for a 
new feature) and what isn't, dev X's private place to conduct 
experiments. This is only a result of the client-server 
topology imposed by svn architecture.


The official process should only standardize and focus on the 
points where integration is required. Everything else is much 
better served as being left alone. On the other hand, I think 
that we need to add more focus on pre/post stages of the actual 
coding. This means, the planning, setting priorities (aka 
roadmap, mile-stones, etc) as well as reducing regressions. I 
saw a post suggesting an automated build-bot that will run the 
test suit and build nightlies. What about DIPs, how do they 
integrate in the work-flow?
I think Andrei talked about the DIPs before but I don't thik it 
was discussed as part of this thread.


I forgot to explain that the multiple roots is applicable to D as 
well in that we have there fully working compilers - LDC, GDC and 
DMD. They currently share the same front-end - GDC and LDC merge 
DMD's code. This situation is also sub optimal and requires 
manual work and has redundancies in the process. E.g. what if the 
LDC guys fix a bug in the shared front-end? Should this be 
integrated back to DMD? What if Walter comes up with a different 
fix?


Re: Compilation strategy

2012-12-17 Thread foobar

On Monday, 17 December 2012 at 22:12:01 UTC, Walter Bright wrote:

On 12/17/2012 1:53 PM, Rob T wrote:
I mentioned in a previous post that we should perhaps focus on 
making the .di

concept more efficient rather than focus on obfuscation.


We're not going to do obfuscation, because as I explained such 
cannot work, and we shouldn't do a disservice to users by 
pretending it does. There are many ways that *do* work, such as 
PIMPL, which work today and should be used by any organization 
wishing to obfuscate their implementation.



Shorter file sizes is a potential use case, and you could even 
allow a
distributor of byte code to optionally supply in compressed 
form that is
automatically uncompressed when compiling, although as a trade 
off that would

add on a small compilation performance hit.


I suspect most file transport protocols already compress the 
data, so compressing it ourselves probably accomplishes 
nothing. There are also compressed filesystems, so storing 
files in a compressed manner likely accomplishes little.


I have toyed with the idea many times, however, of having dmd 
support zip files. Zip files can contain an arbitrary file 
hierarchy, with individual files in compressed, encrypted, or 
plaintext at the selection of the zip builder. An entire 
project, or library, or collection of source modules can be 
distributed as a zip file, and could be compiled with nothing 
more than:


   dmd foo.zip

or:

   dmd myfile ThirdPartyLib.zip

and have it work. The advantage here is simply that everything 
can be contained in one simple file.


The concept is simple. The files in the zip file simply replace 
the zip file in the command line. So, if foo.zip contains a.d, 
b/c.d, and d.obj, then:


   dmd xx foo.zip

is equivalent to:

   unzip foo
   dmd xx a.d b/c.d d.obj

P.S. I've also wanted to use .zip files as the .lib file format 
(!), as the various .lib formats have nothing over .zip files.


Yes please.
This is successfully used in Java, their Jar files are actually 
zip files that can contain: source code, binary files, resources, 
documentation, package meta-data, etc. This can store multiple 
binaries inside to support multi-arch (as in OSX).
.NET assemblies accomplish similar goals (although I don't know 
if they are zip archives internally as well). D can support both 
legacy C/C++ compatible formats (lib/obj/headers) and this new 
dlib format.


Re: Next focus: PROCESS

2012-12-16 Thread foobar
On Sunday, 16 December 2012 at 15:05:58 UTC, Andrei Alexandrescu 
wrote:

On 12/16/12 6:15 AM, Joseph Rushton Wakeling wrote:

On 12/15/2012 09:39 PM, deadalnix wrote:
Can we drop the LTS name ? It reminds me of ubuntu, and I 
clearly hope

that
people promoting that idea don't plan to reproduce ubuntu's 
scheme :
- it is not suitable for a programming language (as stated 3 
time now,

so just
read before why I won't repeat it).
- ubuntu is notoriously unstable.


Call them stable release cycles if you like, which is what 
they are

intended to be.


Just one tidbit of information: I talked to Walter and we want 
to build into the process the ability to modify any particular 
release. (One possibility is to do so as part of paid support 
for large corporate users.) That means there needs to be one 
branch per release.


Andrei


I don't see why that is a requirement (having a branch per 
release).
We can still have a single stable branch with tags for releases 
and when Walter needs to provide special customizations he can 
always just branch off of the tagged release. This should be 
Walter's business and not part of the official community 
process.


in git terms, assuming we have a tagged release of 2.61
$ git checkout -b 2.61-partner 2.61
This branches off a new branch 2.61-partner for the specific 
partner modification based off the contents of the 2.61 release.


Also, this kinda messes with the notion of integration. A single 
stable branch helps prevent forgotten bug-fixes. I.e a critical 
bug was fixed on release N, what will ensure it will be included 
in release N+1? If Release N+1 is on the same branch than the 
bug-fix is included by default and prevented the need to perform 
a manual operation (a merge) that could be forgotten.


Re: OT (partially): about promotion of integers

2012-12-13 Thread foobar
On Wednesday, 12 December 2012 at 21:05:05 UTC, Walter Bright 
wrote:

On 12/12/2012 2:53 AM, foobar wrote:

One example that comes to mind is the
future version of JavaScript is implemented in ML.


Um, there are many implementations of Javascript. In fact, I 
have implemented it in both C++ and D.


Completely besides the point.
The discussion was about using ML in real life, not what you 
specifically chose to use. The fact that you use D has no baring 
on your own assertion that ML is effectively dead. Fact is _other 
people and organizations_ do use it to great effect.
Also, I said _future version_ of JS, meaning the next version of 
the ECMAscript standard. ML was specifically chosen as it allows 
to both be efficient and verify the correctness of the 
implementation.


Re: Next focus: PROCESS

2012-12-12 Thread foobar

On Wednesday, 12 December 2012 at 01:03:59 UTC, Rob T wrote:

On Tuesday, 11 December 2012 at 23:15:27 UTC, foobar wrote:
By support I meant specifically _bug fixes_. You can already 
download all previous released versions from the website and 
in no way am I arguing to change that policy.
Even if we ever get to a point where we don't want to keep 
older releases which I doubt very much (each zip is only a few 
MBs and therefore insignificant on today's storage) - we could 
still easily just checkout the specific release tagged in git 
and just build that.


That's what I meant too, I agree with you on this point.

This is precisely what I addressed bellow. we have monthly 
build of our staging branch - call them monthly betas that 
include new upcoming features that are already stable enough 
to be released to the public for field testing and are 
tentative for the next actual release but until these feature 
actually get to a release they hold no guaranties and can be 
further modified based on the wider public testing - including 
changes in API. Once released, they do hold such guaranties of 
API stability. So these monthly betas will provide preview of 
language changes and allow people to prepare for future 
changes and also provide feedback.


Having a pre-release build that can be downloaded and installed 
would be very nice to have if that's what you mean. Currently, 
to get DMD 2.061 alpha I have to jump through hoops to get it 
to a point where it is operational, and that is not so good as 
it limits severely how many users will be able to test it out.


See comment above. the pre-release will contain new features 
already stable enough to be consumes by the general public 
_before_ we the developers are ready to a commit finally to 
their API. E.g. Walter's release of DMD with attributes that 
was already tested and working but after release people argued 
about changing its syntax from [attributes] to @(attributes).


developers can have their own experimental branches for their 
own tests and new ideas, but once a feature reaches 
pre-release it should already be tested and working and ready 
for public consumption without commiting to a final API.


OK, but who has already tested it and how many people have been 
able to test it and comment on it? I was thinking more along 
the lines of how Debian does it, with a 4 staged release 
process: experimental = unstable = testing (pre-release) = 
stable.


We could probably do away with a  common experimental branch, 
leaving 3 common branches.


A common unstable branch will allow more people to test out 
newly introduced ideas well before they become merged into 
pre-release, and that may help avoid problems as we're seeing 
with the sudden introduction of UDA's.


I am hoping that we can have a pre-release version that will be 
stable enough to be used on real-world applications, knowing 
that some things can change but not in a major way. If I don't 
mind dealing with major changes, then I would instead make use 
of what's in the unstable branch, but I expect mostly 
compiler devs will be using unstable, and no one will be using 
it on anything important.




I really don't care about the numbering scheme and this is 
irrelevant to the topic of this discussion. We are discussing 
the PROCESS of development. How the releases are tagged is 
completely beside the point and could be named after sweet 
delights, cat names, Parks or even digits of PI. I really 
don't care and it really is _not important_.
This is one of those fundamental things that are required to 
truly understand git - versions are the _content_ (code) they 
contain and are identified by a hash of that content.
This is pure bikesheding but why not: Why not extend the 
astronomical theme to releases as well? What would you say 
about the latest Pluto release of DMD? ;)

(Yeah, I know this is already used by the eclipse project..)


I'm very surprised by your comment on version numbers and I 
hope you are a significant minority holder of that view.


How version numbers are assigned and what the number represents 
has to be made a defined part of the release process otherwise 
you'll end up with a meaningless random number or symbol (or 
nothing) for each new release, and the only information it will 
supply to you is here's a new release. I don't see that as an 
improvement to the current situation, it just perpetuates the 
existing problem where users of the D compiler have no easy way 
to know if a new release is a major ground breaking one, or a 
minor one, or just a simple bug fix. In order to find out what 
a new release means in terms of the magnitude of changes, one 
has to read through a technical change log, and read through 
endless forum posts, and possibly even take a look at the 
commit log. Why not do something better than that when it's so 
easy to do?


For example, if I see that the stable version has been updated, 
I want to quickly know if it's a bug fix

Re: OT (partially): about promotion of integers

2012-12-12 Thread foobar

On Wednesday, 12 December 2012 at 00:43:39 UTC, H. S. Teoh wrote:

On Wed, Dec 12, 2012 at 01:26:08AM +0100, foobar wrote:
On Wednesday, 12 December 2012 at 00:06:53 UTC, bearophile 
wrote:

foobar:

I would enforce overflow and underflow checking semantics.

Plus one or two switches to disable such checking, if/when 
someone
wants it, to regain the C performance. (Plus some syntax way 
to

disable/enable such checking in a small piece of code).

Maybe someday Walter will change his mind about this topic :-)


I don't agree that compiler switches should change language 
semantics.

Just because you specify a certain compiler switch, it can cause
unrelated breakage in some obscure library somewhere, that 
assumes
modular arithmetic with C/C++ semantics. And this breakage will 
in all

likelihood go *unnoticed* until your software is running on the
customer's site and then it crashes horribly. And good luck 
debugging
that, because the breakage can be very subtle, plus it's *not* 
in your
own code, but in some obscure library code that you're not 
familiar

with.

I think a much better approach is to introduce a new type (or 
new types)
that *does* have the requisite bounds checking and static 
analysis.

That's what a type system is for.


[...]

Yeah, of course, that's why I said the C# semantics are _way_
better. (That's a self quote)

btw, here's the link for SML which does not use tagged ints -
http://www.standardml.org/Basis/word.html#Word8:STR:SPEC

Instances of the signature WORD provide a type of unsigned 
integer

with modular arithmetic and logical operations and conversion
operations. They are also meant to give efficient access to the
primitive machine word types of the underlying hardware, and 
support

bit-level operations on integers. They are not meant to be a
``larger'' int. 


It's kinda too late for D to rename int to word, say, but it's 
not too
late to introduce a new checked int type, say 'number' or 
something like

that (you can probably think of a better name).

In fact, Andrei describes a CheckedInt type that uses operator
overloading, etc., to implement an in-library solution to 
bounds checks.

You can probably expand that into a workable lightweight int
replacement. By wrapping an int in a struct with custom 
operators, you
can pretty much have an int-sized type (with value semantics, 
just like
native ints, no less!) that does what you want, instead of 
the usual

C/C++ int semantics.


T


I didn't say D should change the implementation of integers, in 
fact I said the exact opposite - that it's probably to late to 
change the semantics for D. Had D was designed from scratch than 
yes, I would have advocated for a different design, either the C# 
one or as you suggest go even further and have two distinct types 
(as in SML) which is even better. But by no means am I to suggest 
to change D semantics _now_. Sadly, it's likely to late and we 
can only try to paper it on top with additional library types. 
This isn't a perfect solutions since the compiler has builtin 
knowledge about int and does optimizations that will be lost with 
a library type.


Re: OT (partially): about promotion of integers

2012-12-12 Thread foobar
On Wednesday, 12 December 2012 at 00:51:19 UTC, Walter Bright 
wrote:

On 12/11/2012 3:44 PM, foobar wrote:
Thanks for proving my point. after all , you are a C++ 
developer, aren't you? :)


No, I'm an assembler programmer. I know how the machine works, 
and C, C++, and D map onto that, quite deliberately. It's one 
reason why D supports the vector types directly.




Seriously though, it _is_ a trick and a code smell.


Not to me. There is no trick or smell to anyone familiar with 
how computers work.



I'm fully aware that computers used 2's complement. I'm also 
am aware of the
fact that the type has an unsigned label all over it. You 
see it right there
in that 'u' prefix of 'int'. An unsigned type should 
semantically entail _no
sign_ in its operations. You are calling a cat a dog and 
arguing that dogs barf?
Yeah, I completely agree with that notion, except, we are 
still talking about _a

cat_.


Andrei and I have endlessly talked about this (he argued your 
side). The inevitable result is that signed and unsigned types 
*are* conflated in D, and have to be, otherwise many things 
stop working.


For example, p[x]. What type is x?

Integer signedness in D is not really a property of the data, 
it is only how one happens to interpret the data in a specific 
context.



To answer you question, yes, I would enforce overflow and 
underflow checking
semantics. Any negative result assigned to an unsigned type 
_is_ a logic error.

you can claim that:
uint a = -1;
is perfectly safe and has a well defined meaning (well, for C 
programmers that

is), but what about:
uint a = b - c;
what if that calculation results in a negative number? What 
should the compiler

do? well, there are _two_ equally possible solutions:
a. The overflow was intended as in the mask = -1 case; or
b. The overflow is a _bug_.

The user should be made aware of this and should make the 
decision how to handle
this. This should _not_ be implicitly handled by the compiler 
and allow bugs go

unnoticed.

I think C# solved this _way_ better than C/D.


C# has overflow checking off by default. It is enabled by 
either using a checked { } block, or with a compiler switch. I 
don't see that as solving the issue in any elegant or natural 
way, it's more of a clumsy hack.


But also consider that C# does not allow pointer arithmetic, or 
array slicing. Both of these rely on wraparound 2's complement 
arithmetic.




Another data point would be (S)ML
which is a compiled language which requires _explicit 
conversions_ and has a
very strong typing system. Its programs are compiled to 
efficient native
executables and the strong typing allows both the compiler and 
the programmer
better reasoning of the code. Thus programs are more correct 
and can be
optimized by the compiler. In fact, several languages are 
implemented in ML

because of its higher guaranties.


ML has been around for 30-40 years, and has failed to catch on.


This is precisely the point that signed and unsigned types are 
conflated *in D*.

Other languages, namely ML chose a different design.
ML chose to have two distinct types: word and int, word is for 
binary data and int for integer numbers. Words provide efficient 
access to the machine representation and have no overflow checks, 
ints represent numbers and do carry overflow checks. you can 
convert between the two and the compiler/run-time can carry 
special knowledge about such conversions in order to provide 
better optimization.
in ML, array indexing is done with an int since it _is_ 
conceptually a number.


Btw, SML was standardized in '97. I'll also dispute the claim 
that it hasn't caught on - there are many derived languages from 
it and it is just as large if not larger than the C family of 
languages. It has influenced many languages and it and its 
derivations are being used. One example that comes to mind is the 
future version of JavaScript is implemented in ML. So no, not 
forgotten but rather alive and kicking.




Re: OT (partially): about promotion of integers

2012-12-12 Thread foobar
On Wednesday, 12 December 2012 at 10:35:26 UTC, Walter Bright 
wrote:

On 12/12/2012 2:33 AM, foobar wrote:

This isn't a perfect solutions
since the compiler has builtin knowledge about int and does 
optimizations that

will be lost with a library type.


See my reply to bearophile about that.


Yeah, just saw that :)
So basically you're suggesting to implement Integer and Word 
library types using compiler intrinsics as a way to migrate to 
better ML compatible semantics. This is a possible solution if it 
can be proven to work.


Regarding performance and overflow checking, the example you give 
is x86 specific. What about other platforms? For example ARM is 
very popular nowadays in the mobile world and there are many more 
smart-phones out there than there are PCs. Is the same issue 
exists and if not (I suspect not, but really have no idea) should 
D be geared towards current platforms or future ones?


Re: Next focus: PROCESS

2012-12-12 Thread foobar

On Wednesday, 12 December 2012 at 18:25:10 UTC, Rob T wrote:

On Wednesday, 12 December 2012 at 10:22:32 UTC, foobar wrote:

To summarize:
2. The version scheme is meaningless. Please check out 
http://www.mozilla.org/en-US/firefox/channel/#firefox as an 
example. It's perfectly clear, you can choose what Mozilla 
calls a channel - i.e release or beta.


I agree Firefox has a meaningless version numbering system 
because Firefox adopted a meaningless version numbering system. 
I don't understand the rational behind the decision to switch 
from the previous one that was meaningful.


What advantage do you gain by dropping a major, minor, and 
revision from your version numbering system?


We can put both in a two column table with high-level 
description of changes and links to more-detailed change logs.


There's no harm in doing that, but what would be most useful is 
knowing if the change is a major one or a minor one or just for 
bug fixes.



3. Debian is a HUGE project with lots of manpower. D is not.


We all know this, but that does not mean we cannot do a lot 
better than we're doing now, and if we can get rid of the 
waste, like those endless debates that cannot be resolved with 
one branch, then there'll effectively be more manpower 
available.


I think it is enough to have two _publicly visible download 
channels_ - release and beta (testing). Those are the only two 
that should be formally defined. There is no need to define 
prior stages of development as people can just informally 
create their own local branches for their own experiments and 
they could also push them upstream to share with other 
developers without any requirement to list an executable on 
the official download page. The source code is available on 
github - if you wanted to you could pull whatever branch and 
build it yourself at your own risk.


But that's almost what we have now, and it does not work and it 
never will work.


The problem with only two official branches, is that one has to 
be for a stable version, and the other has to be for the new 
stuff, but there's two kinds of new stuff. One kind is for 
breaking changes, or for introducing new concepts that have not 
been well tested. and the other kind is for field testing new 
concepts that are reasonably well understood and cause no 
breaking changes.


What real-world programmers want to have, is a reasonably 
stable beta version that they can use for real work - this is 
NOT for playing around with, but for making things work for 
real. They want the beta because it has something that the 
stable does not yet have.


What these guys don't want, and cannot put up with for real 
world programming, is an unstable alpha, but that's what you 
are proposing we continue on with, which is exactly what we 
have now and it does not work.


In addition, once the beta/alpha is close to ready to be 
released into stable, it has to be frozen for a few months, 
where no new features are added and only bug fixes continue on, 
but then you've just lost your unstable branch!


Have a look at the thread on the introduction of UDA's to see 
what's going on, and ask yourself if a two branch system will 
solve that kind of never ending problem.


4. The only official executables on the download page are for 
two channels - release and beta. You can grab the latest 
stable release that only gets critical bug-fixes or the 
monthly beta that also contains preview features such as the 
upcoming user-defined attributes. You can also grab previous 
versions of both release channels by clicking the previous 
versions link. Anything else has zero guaranties and you are 
required to build yourself from source.


That all works fine. What I think is glaringly missing is the 
unstable branch, so we need at a minimum 3 branches.


--rt


I really didn't want to get dragged into the versioning scheme 
debate as it is just bikesheding in disguise but oh well.. I'll 
ask in return, what's the added benefit of your scheme? I 
honestly see no added benefit whatsoever.
There's no intrinsic benefit compared to a changelog that lists 
Jelly bean after Ice cream sandwich. How do you know what was 
added to a version? Simple, you have a what's new page that 
lists new major features denoted by New feature: tag and 
bug-fixes denoted by Bug-Fix: tag.
Here's an example - 
http://www.mozilla.org/en-US/firefox/17.0.1/releasenotes/


Regarding the important (IMO) part of the discussion - 2 vs. 3 
levels - I feel I haven't explained myself properly so let me 
clarify:
I was taking into account what I thought was a reasonable 
assumption that D2 is in the process of stabilization and no 
major redesigns are planed. This means the Major version is 2 
as in D2.
My stable releases are meant to be the Minor releases on the D2 
branch. These releases can introduce new backwards-compatible 
features and restricted breaking changes when absolutely required 
_over several releases_ with _a well defined migration

Re: Next focus: PROCESS

2012-12-12 Thread foobar
On Wednesday, 12 December 2012 at 18:33:17 UTC, Jesse Phillips 
wrote:

On Wednesday, 12 December 2012 at 10:22:32 UTC, foobar wrote:

To summarize:


2. The version scheme is meaningless. Please check out 
http://www.mozilla.org/en-US/firefox/channel/#firefox as an 
example. It's perfectly clear, you can choose what Mozilla 
calls a channel - i.e release or beta.


This is a poor example as it doesn't show how the development 
team develops these versions.


If we are going to have a branch supported separate from the 
beta/dev builds then we need a way to say that this stable 
version is newer but is not as new as the beta/dev.


If we release 2.61 as a stable, we would then develop new 
features in which version? 2.62 beta 1? If so, when we release 
2.61 with a bug fix which version do we release? 2.62? 2.61 
stable 2?


You are right that version numbers have absolutely no meaning, 
I don't remember if it was you, but they are also not as 
important as the process improvements. However if we assign 
meaning to numbers there can be benefit. Mozilla basically just 
did away with the Major version. (I say we do a Linux and leave 
the 2 then realize it has no meaning and up it to 3 when we 
reach the age of the 2.0 kernel)


We should combine your beta with an added version number.

2.61.0 = bugfixes = 2.61.1
2.61.0 = newfeatures = 2.62.0 beta 1
2.62 = preparing for stabilizing = 2.62 rc1

just some thoughts.


Per my answer to Rob:
D2 *is* the major version.
releases should be minor versions and largely backwards 
compatible - some evolution is allowed given some reasonable 
restrictions like a proper migration path over several releases.
Critical bug-fixes can go directly on stable releases but nothing 
else.


Other enhancements, new features, etc, go first on monthly beta 
versions and need to pass acceptance tests  community approval 
before graduating to stable. So a big feature such as User 
defined attributes can spend several cycles of beta testing and 
can go redesigns until everyone agrees that the final design is 
worthy of inclusion in the next stable release.


Re: Next focus: PROCESS

2012-12-12 Thread foobar

On Wednesday, 12 December 2012 at 19:28:54 UTC, Rob T wrote:

The beta foobar speaks of is actually a combined alpha+beta, 
--rt


No. I have already addressed this point before.
Alpha is not part of the _official_ release process.

As a developer I can create my own local branch DMD-new_feature 
to experiment with some new idea I had. I can later on push this 
upstream and share my new cool feature with other developers to 
play with. besides other developers, users can also fetch these 
new branches and build themselves. This is done _before_ it 
matures enough to be included in beta testing.




Re: Next focus: PROCESS

2012-12-11 Thread foobar

On Tuesday, 11 December 2012 at 02:02:54 UTC, Andrei Alexandrescu
wrote:

On 12/10/12 7:19 PM, H. S. Teoh wrote:

Sounds OK to me, though it seems unnecessarily complicated.


FWIW there's also this:

http://drewfradette.ca/a-simpler-successful-git-branching-model/


Andrei


First of all - Yay!

There are still a few open questions that need to be decided
before a suitable process can be defined.

a. Should we have more than one stable release and provide
support branches?
That means we have version X which is latest stable with all the
latest (stable) features included and we have an older Y version
that only receives bug-fixes and is intended for support (think
of Ubuntu's LTE versions). If we have such additional versions,
how many do we have, for how long?
My opinion - (based on Walter's) you can always download a
previous version of the compiler. I'd say we should _at most_
support _one_ previous stable version with critical bug fixes
only. we could always decide to support ad-hoc additional
specific versions, for example before we introduce major paradigm
shifting changes and this also depends on available manpower.

B. should we have public pre-release versions?
I think we should release additional releases - call them beta,
pre-release, release candidates, whatever. These are for staging
changes, allowing to field test new features and language changes
before they are made final. Also allowing users to adjust their
code-bases.

Given the above, I think the simpler flow model above looks
very promising and we should adopt it with minor changes:
1. Both staging and release should be public - the website
lists both the stable versions and the staging versions.
2. the development branch should be the master branch for easier
integration with pull requests.

The staging releases (let's call them beta) will provide previews
of upcoming and experimental features to try out without the
promise of a stable API and would be released _monthly_.

The stable releases will be every 3-4 months and will guaranty a
stable API. A user could download DMD-201212 (i.e. this month)
and play around with UDA and of course report bugs, but knowing
that this feature could change syntax or even be completely
removed thus allowing the developers to test stuff out in the
open without committing to anything.


Re: OT (partially): about promotion of integers

2012-12-11 Thread foobar
On Tuesday, 11 December 2012 at 16:35:39 UTC, Andrei Alexandrescu 
wrote:

On 12/11/12 11:29 AM, eles wrote:
There's a lot to be discussed on the issue. A few quick 
thoughts:


* 32-bit integers are a sweet spot for CPU architectures. 
There's
rarely a provision for 16- or 8-bit operations; the action is 
at 32-

or 64-bit.


Speed can be still optimized by the compiler, behind the 
scenes. The

approach does not asks the compiler to promote everything to
widest-integral, but to do the job as if. Currently, the 
choice of
int-C as the fastest-integral instead of widest-integral move 
the burden

from the compiler to the user.


Agreed. But then that's one of them sufficiently smart 
compiler arguments. 
http://c2.com/cgi/wiki?SufficientlySmartCompiler


* Then, although most 64-bit operations are as fast as 32-bit 
ones,
transporting operands takes twice as much internal bus real 
estate and
sometimes twice as much core real estate (i.e. there are 
units that do

either two 32-bit ops or one 64-bit op).

* The whole reserving a bit and halving the range means extra 
costs of

operating with a basic type.


Yes, there is a cost. But, as always, there is a balance 
between
advantages and drawbacks. What is favourable? Simplicity of 
promotion or

a supplimentary bit?


A direct and natural mapping between language constructs and 
machine execution is very highly appreciated in the market D is 
in. I don't see that changing in the foreseeable future.


Besides, at the end of the day, a half-approach would be to 
have a
widest-signed-integral and a widest-unsigned-integral type and 
only play

with those two.


D has terrific abstraction capabilities. Lave primitive types 
alone and define a UDT that implements your desired behavior. 
You can always implement safe on top of fast but not the other 
way around.



Andrei


All of the above relies on the assumption that the safety problem 
is due to the memory layout. There are many other programming 
languages that solve this by using a different point of view - 
the problem lies in the implicit casts and not the memory layout. 
In other words, the culprit is code such as:

uint a = -1;
which compiles under C's implicit coercion rules but _really 
shouldn't_.

The semantically correct way would be something like:
uint a = 0x_;
but C/C++ programmers tend to think the -1 trick is less 
verbose and better.

Another way is to explicitly state the programmer's intention:
uint a = reinterpret!uint(-1); // no run-time penalty should occur

D decided to follow C's coercion rules which I think is a design 
mistake but one that cannot be easily changed.


Perhaps as Andrei suggested, a solution would be to use a higher 
level Integer type defined in a library that enforces better 
semantics.


Re: Is there any reason why arithmetic operation on shorts and bytes return int?

2012-12-11 Thread foobar
On Tuesday, 11 December 2012 at 16:09:14 UTC, Andrei Alexandrescu 
wrote:

On 12/11/12 8:24 AM, d coder wrote:


   No, it's a fix of a gotcha from C. The C code would just 
allow the

   assignment.


Yes Andrei.

But it does not look clean if you have to write:

byte a, b, c;
a = cast(byte) (b + c);

Well I know the advantages (safety). But imagine having to 
write all
that when working with bytes and shorts. Makes it really 
difficult to

work with shorts and bytes in D.


Value range propagation automatically avoids the need for a lot 
of those casts. 
http://www.drdobbs.com/tools/value-range-propagation/229300211



Would I be asking for too much if I ask
DMD to provide a compiler flag that makes it return bytes and 
shorts for

operations on them?


That won't happen.


Andrei


But than we have a bug in the value range propagation algorithm.
E.g in the original program:
void main()
{
 import std.stdio;
 ushort a = 0x55AA;
 ushort b = 0xAA55;
 writefln(%X, ~(a | b));
}

(a | b) will be in the range of ushort values and ~ of that also 
remains in the same value range. In other words, it makes no 
sense that boolean ops (and, or, xor, 1's compliment, 2's 
compliment) will require type promotion as they cannot exceed the 
original width of the values. This is unlike arithmetic which can 
require promotion.


Re: Next focus: PROCESS

2012-12-11 Thread foobar

On Tuesday, 11 December 2012 at 19:57:55 UTC, Rob T wrote:

On Tuesday, 11 December 2012 at 13:19:56 UTC, foobar wrote:

First of all - Yay!

There are still a few open questions that need to be decided
before a suitable process can be defined.

I'd say we should _at most_
support _one_ previous stable version with critical bug fixes
only.


I agree with that as well, although I think that after a new 
major stable release, the previously stable should be 
supported (at a minimum kept available for download) for some 
time until the new stable is fully stabilized and most people 
have been able to adopt it. It may be good enough to just and 
pick and choose if the previous stable should get certain bug 
fixes or not until the support period runs out.




By support I meant specifically _bug fixes_. You can already 
download all previous released versions from the website and in 
no way am I arguing to change that policy.
Even if we ever get to a point where we don't want to keep older 
releases which I doubt very much (each zip is only a few MBs and 
therefore insignificant on today's storage) - we could still 
easily just checkout the specific release tagged in git and just 
build that.



B. should we have public pre-release versions?


A lot of people will want to use the latest available changes 
for actual development, so the testing or pre-release 
branch should be public and kept reasonably stable, although 
anything can happen, so it's not considered stable, just 
stable enough given that it may be supporting new features 
and improvements that have been selected for the next major 
stable release.


This is precisely what I addressed bellow. we have monthly build 
of our staging branch - call them monthly betas that include new 
upcoming features that are already stable enough to be released 
to the public for field testing and are tentative for the next 
actual release but until these feature actually get to a release 
they hold no guaranties and can be further modified based on the 
wider public testing - including changes in API. Once released, 
they do hold such guaranties of API stability. So these monthly 
betas will provide preview of language changes and allow people 
to prepare for future changes and also provide feedback.




I think we should release additional releases - call them 
beta,
pre-release, release candidates, whatever. These are for 
staging
changes, allowing to field test new features and language 
changes

before they are made final. Also allowing users to adjust their
code-bases.


I think you'll need at a minimum experimental branches for 
testing out new ideas, the main development branch witch is 
considered unstable (the master branch is probably best for 
this one as was suggested), a pre-release or testing branch 
that is used for preparing for the next major stable release, 
and of course the current stable branch which only receives bug 
fixes up until the next pre-release branch is merged into 
stable.


See comment above. the pre-release will contain new features 
already stable enough to be consumes by the general public 
_before_ we the developers are ready to a commit finally to their 
API. E.g. Walter's release of DMD with attributes that was 
already tested and working but after release people argued about 
changing its syntax from [attributes] to @(attributes).


developers can have their own experimental branches for their own 
tests and new ideas, but once a feature reaches pre-release it 
should already be tested and working and ready for public 
consumption without commiting to a final API.




One more thing, is that we should adopt a version numbering 
system that is appropriate to indicate major, minor, and bug 
fix releases. The method of major.minor.revision can work well 
for us, but there may be alternatives that will work even 
better depending on what the process ends up being.


I really don't care about the numbering scheme and this is 
irrelevant to the topic of this discussion. We are discussing the 
PROCESS of development. How the releases are tagged is completely 
beside the point and could be named after sweet delights, cat 
names, Parks or even digits of PI. I really don't care and it 
really is _not important_.
This is one of those fundamental things that are required to 
truly understand git - versions are the _content_ (code) they 
contain and are identified by a hash of that content.
This is pure bikesheding but why not: Why not extend the 
astronomical theme to releases as well? What would you say about 
the latest Pluto release of DMD? ;)

(Yeah, I know this is already used by the eclipse project..)



What I'd hate to see continuing, is a major new release going 
out with no indication in the version number that it is a major 
new release as opposed to a minor revision change. For example, 
the current DMD stable is 2.060, and the next release will be 
2.061, but it includes brand new poorly tested features, and 
one of them

Re: OT (partially): about promotion of integers

2012-12-11 Thread foobar

On Tuesday, 11 December 2012 at 22:08:15 UTC, Walter Bright wrote:

On 12/11/2012 10:44 AM, foobar wrote:
All of the above relies on the assumption that the safety 
problem is due to the
memory layout. There are many other programming languages that 
solve this by
using a different point of view - the problem lies in the 
implicit casts and not

the memory layout. In other words, the culprit is code such as:
uint a = -1;
which compiles under C's implicit coercion rules but _really 
shouldn't_.

The semantically correct way would be something like:
uint a = 0x_;
but C/C++ programmers tend to think the -1 trick is less 
verbose and better.


Trick? Not at all.

1. -1 is the size of an int, which varies in C.

2. -i means complement and then increment.

3. Would you allow 2-1? How about 1-1? (1-1)-1?

Arithmetic in computers is different from the math you learned 
in school. It's 2's complement, and it's best to always keep 
that in mind when writing programs.


Thanks for proving my point. after all , you are a C++ developer, 
aren't you? :)

Seriously though, it _is_ a trick and a code smell.
I'm fully aware that computers used 2's complement. I'm also am 
aware of the fact that the type has an unsigned label all over 
it. You see it right there in that 'u' prefix of 'int'. An 
unsigned type should semantically entail _no sign_ in its 
operations. You are calling a cat a dog and arguing that dogs 
barf? Yeah, I completely agree with that notion, except, we are 
still talking about _a cat_.


To answer you question, yes, I would enforce overflow and 
underflow checking semantics. Any negative result assigned to an 
unsigned type _is_ a logic error.

you can claim that:
uint a = -1;
is perfectly safe and has a well defined meaning (well, for C 
programmers that is), but what about:

uint a = b - c;
what if that calculation results in a negative number? What 
should the compiler do? well, there are _two_ equally possible 
solutions:

a. The overflow was intended as in the mask = -1 case; or
b. The overflow is a _bug_.

The user should be made aware of this and should make the 
decision how to handle this. This should _not_ be implicitly 
handled by the compiler and allow bugs go unnoticed.


I think C# solved this _way_ better than C/D. Another data point 
would be (S)ML which is a compiled language which requires 
_explicit conversions_ and has a very strong typing system. Its 
programs are compiled to efficient native executables and the 
strong typing allows both the compiler and the programmer better 
reasoning of the code. Thus programs are more correct and can be 
optimized by the compiler. In fact, several languages are 
implemented in ML because of its higher guaranties.


Re: OT (partially): about promotion of integers

2012-12-11 Thread foobar

On Wednesday, 12 December 2012 at 00:06:53 UTC, bearophile wrote:

foobar:


I would enforce overflow and underflow checking semantics.


Plus one or two switches to disable such checking, if/when 
someone wants it, to regain the C performance. (Plus some 
syntax way to disable/enable such checking in a small piece of 
code).


Maybe someday Walter will change his mind about this topic :-)

Bye,
bearophile


Yeah, of course, that's why I said the C# semantics are _way_ 
better. (That's a self quote)


btw, here's the link for SML which does not use tagged ints -
http://www.standardml.org/Basis/word.html#Word8:STR:SPEC

Instances of the signature WORD provide a type of unsigned 
integer with modular arithmetic and logical operations and 
conversion operations. They are also meant to give efficient 
access to the primitive machine word types of the underlying 
hardware, and support bit-level operations on integers. They are 
not meant to be a ``larger'' int. 


Re: typeid() broken for interfaces?

2012-12-06 Thread foobar
On Wednesday, 5 December 2012 at 16:21:55 UTC, Jonathan M Davis 
wrote:

On Wednesday, December 05, 2012 15:11:55 foobar wrote:

On Tuesday, 4 December 2012 at 18:41:14 UTC, Jonathan M Davis

wrote:
 On Tuesday, December 04, 2012 17:35:23 foobar wrote:
 That's a lot of duplication considering D already provides 
 this

 in Object.
 
 Though per the last major discussion on const-correctness and

 Object, it's
 likely that toString, toHash, opCmp, and opEquals will be
 removed from Object,
 in which case you'd need a derived class which implemented 
 them

 to use any of
 them.
 
 - Jonathan m Davis


In other words, the plan is to pretty much deprecate Object? I
hope there would be appropriate replacement before this 
happens.

Users should be able to have a standardized API and a default
implementation for these methods.
Is phobos going to introduce interface such as Printable,
Comparable, etc.. ? (names tentative, I'm more worried about 
the

semantics).


No. The plan is not to deprecate Object. The reality is that 
those functions
don't need to be on Object in D, because all of the runtime 
stuff that relies
on them can (and really should) be templatized, whereas in Java 
or C#, they
have to put them on Object and operate through Object. What we 
have currently
have with Object in D is a case of having copied too much from 
Java and C#
(and templates weren't as good in D1, possibly making those 
functions
necessary there). And having those functions on Object has 
created a lot of
problems with regards to stuff like const. If they're there, 
they have to be
const so that you can compare const objects, but given how D's 
const works,
that then make certain idioms impossible in classes (e.g. lazy 
loading member
variables and caching). const needs to work, but we can't force 
it on people,
and putting it on Object forces it on people. Rather, it's 
perfectly possible
for only derived classes to have those functions. They can then 
use the
function attributes that match what they need, and stuff like 
druntime's
opEquals or AAs will just be appropriately tempatized and work 
with the
derived classes without needing to have any of that on Object. 
There's really

no need to have any of that on Object.

I'd have to go digging through the archives to find the last 
discussion on
const-correctness where this was discussed in some detail, but 
that's the gist
of it. Putting those functions on Object causes a lot of 
problems with regards
to function attributes, and templates make actually putting 
those functions on

Object unnecessary.

- Jonathan M Davis


But these are the methods of Object. So even if Object itself 
remains it looses its meaning. So are we going to keep Object 
just for backwards compatibility? Is there any point left keeping 
the single root design?


Re: typeid() broken for interfaces?

2012-12-05 Thread foobar
On Tuesday, 4 December 2012 at 18:41:14 UTC, Jonathan M Davis 
wrote:

On Tuesday, December 04, 2012 17:35:23 foobar wrote:

That's a lot of duplication considering D already provides this
in Object.


Though per the last major discussion on const-correctness and 
Object, it's
likely that toString, toHash, opCmp, and opEquals will be 
removed from Object,
in which case you'd need a derived class which implemented them 
to use any of

them.

- Jonathan m Davis


In other words, the plan is to pretty much deprecate Object? I 
hope there would be appropriate replacement before this happens. 
Users should be able to have a standardized API and a default 
implementation for these methods.
Is phobos going to introduce interface such as Printable, 
Comparable, etc.. ? (names tentative, I'm more worried about the 
semantics).


Re: typeid() broken for interfaces?

2012-12-05 Thread foobar
On Tuesday, 4 December 2012 at 18:41:14 UTC, Jonathan M Davis 
wrote:

On Tuesday, December 04, 2012 17:35:23 foobar wrote:

That's a lot of duplication considering D already provides this
in Object.


Though per the last major discussion on const-correctness and 
Object, it's
likely that toString, toHash, opCmp, and opEquals will be 
removed from Object,
in which case you'd need a derived class which implemented them 
to use any of

them.

- Jonathan m Davis


In other words, the plan is to pretty much deprecate Object? I 
hope there would be appropriate replacement before this happens. 
Users should be able to have a standardized API and a default 
implementation for these methods.
Is phobos going to introduce interface such as Printable, 
Comparable, etc.. ? (names tentative, I'm more worried about the 
semantics).


Re: typeid() broken for interfaces?

2012-12-05 Thread foobar
On Tuesday, 4 December 2012 at 18:41:14 UTC, Jonathan M Davis 
wrote:

On Tuesday, December 04, 2012 17:35:23 foobar wrote:

That's a lot of duplication considering D already provides this
in Object.


Though per the last major discussion on const-correctness and 
Object, it's
likely that toString, toHash, opCmp, and opEquals will be 
removed from Object,
in which case you'd need a derived class which implemented them 
to use any of

them.

- Jonathan m Davis



In other words, the plan is to pretty much deprecate Object? I 
hope there would be appropriate replacement before this happens. 
Users should be able to have a standardized API and a default 
implementation for these methods.
Is phobos going to introduce interfaces such as Printable, 
Comparable, etc.. ? (names tentative, I'm more worried about the 
semantics).


Re: typeid() broken for interfaces?

2012-12-04 Thread foobar

On Monday, 3 December 2012 at 20:59:24 UTC, Walter Bright wrote:

On 12/4/2012 2:52 AM, Jacob Carlborg wrote:
Note, I'm not saying that an interface should be implicitly 
converted to

any class, only to Object.



But not all interfaces come from Objects.


IMO this is a design mistake - the special case is preferred over 
the common case which goes against the D philosophy of making the 
common case easy and the special case possible.


All COM instances are known at _compile_time_ as they're all 
required to inherit from a special IUnknown interface so the 
compiler _knows_ if indeed an interface represents a COM instance 
or not. This can be used to handle this special case differently.


Interface i = new Class();
Object o = i; // should work for regular interfaces

The compiler can issue a compile-time error if i is COM since 
this is known at compile type.


Re: typeid() broken for interfaces?

2012-12-04 Thread foobar

On Tuesday, 4 December 2012 at 07:38:31 UTC, Maxim Fomin wrote:

On Monday, 3 December 2012 at 23:53:26 UTC, deadalnix wrote:
On Monday, 3 December 2012 at 21:53:47 UTC, Walter Bright 
wrote:
I really don't know what issue you're trying to solve here. 
The typeid's work fine - and interfaces are not objects. 
Having the typeid for an interface be an object means you 
cannot compare typeids of one interface to another interface.




You can't instantiate interface. So an underlying type MUST 
exist. The whole point of typeid on expression is to discover 
what is the dynamic type of things, otherwize you'd be using 
typeid(type) not typeid(expression).


You cannot create interface instance with new operator because 
interface object is not valid until it is actually some class 
instance. But this does not mean neither that typeid operator 
for interfaces should return dynamic type nor that interface 
can be implicitly converted to Object - because interface 
instance may be invalid:


import std.stdio;

interface I { }

void main()
{
I i;
// should be implicitly converted
Object o = cast(Object)i;
writeln(typeid(o));
}

and because presence of interface does not necessarily mean 
that some class has implemented it.


This makes casting interfaces to object unsafe operation that 
better should require explicit cast.


The above is a perfectly safe conversion.
The variable i is _a reference_ to instance of I. since it was 
not assigned any class instance that implements I, it is 
initialized as _null_.

In the example above: (o is null  typeid(o) == typeid(Object))



Re: typeid() broken for interfaces?

2012-12-04 Thread foobar

On Tuesday, 4 December 2012 at 12:30:29 UTC, Paulo Pinto wrote:
On Tuesday, 4 December 2012 at 12:26:53 UTC, Jacob Carlborg 
wrote:

On 2012-12-04 09:22, Maxim Fomin wrote:


And what happens if nobody implements an interface?

import std.stdio;

interface I { }

class A { }

void main()
{
   I i;
   // assume this is implicit
   Object o = cast(Object)i;
   writeln(typeid(o));
}


You get a segmentation fault since both i and o are null.


Safe conversion class to interface requires two conditions:
1a) that class implements interface
1b) if you try to use interface variable, it must be an 
allocated class

instance

Safe conversion to Object requires:
2a) somebody in class hierarchy implements interface
2b) interface instance is actually allocated class instance


You cannot really get an instance of an interface without 
having a class implementing it. That is, without inserting any 
explicit casts, which works:


interface I { }

class A { }

void main()
{
   A a = new A;
   I i = cast(I) a;
   Object o = cast(Object)i;
   writeln(typeid(a)); // A
}

It is possible to check 1a) but impossible in general case to 
check 2a).
Also the first is design feature while the second is design 
abuse.


I don't understand why it wouldn't be safe to allow implicit 
casts of interfaces to Object.


If I want to call toString, why should I need to insert an 
explicit cast to Object just because I have an interface?


If you want to call toSring, it should be part of the interface 
specification, as simple as that.


Interfaces are like contracts which state what is to be 
expected of a certain type.


--
Paulo


Generally speaking you are right. But specifically regarding 
toString, what would you suggest?

Should each and every Interface have a toString method?
Should we have an IObject Interface that all classes are required 
to explicitly inherit?
The purpose of having a root Object class is to define the 
_common interface of all objects_. Why else have such a class in 
the first place?
Requiring an explicit cast to Object makes sense only in a 
no-single-root design such as the one in c++ which D sensibly 
chose not to copy.


We can have a separate debate what should the root Object define, 
but there should not be a requirement to explicitly cast any 
object to it.


Re: typeid() broken for interfaces?

2012-12-04 Thread foobar

On Tuesday, 4 December 2012 at 13:47:39 UTC, Paulo Pinto wrote:

Generally speaking you are right. But specifically regarding 
toString, what would you suggest?

Should each and every Interface have a toString method?


Yes for each interface where you intend to call toString().


That's a lot of duplication considering D already provides this 
in Object.




Should we have an IObject Interface that all classes are 
required to explicitly inherit?
The purpose of having a root Object class is to define the 
_common interface of all objects_. Why else have such a class 
in the first place?


For languages without generics where you need a common base 
class to place in containers.


That's only one reason. Other reasons are to provide a common 
interface for all objects. Anyway, we are discussing the current 
D design and not other possible designs such as the one in C++.




Requiring an explicit cast to Object makes sense only in a 
no-single-root design such as the one in c++ which D sensibly 
chose not to copy.


We can have a separate debate what should the root Object 
define, but there should not be a requirement to explicitly 
cast any object to it.


The whole point of interfaces is to have explicit dependencies 
of

methods, properties, variables across the inheritance tree.

Actually there was a discussion some months ago about what 
methods still

made sense to expose via object, given D's templates.

--
Paulo


Given D's _current_ design, all objects should implicitly cast to 
Object.
It's plain common sense - If we have a root class that all other 
classes inherit from than it logically follows that all class 
instances can be implicitly  safely converted back to that root 
class (Object).


What you are arguing is whether the current design of D of 
defining Object makes sense in the first place. I'm arguing that 
_given the current design_ the language is inconsistent and has a 
design flaw.


Re: Fixing cyclic import static construction problems

2012-11-30 Thread foobar
On Thursday, 29 November 2012 at 23:02:17 UTC, Walter Bright 
wrote:

On 11/30/2012 9:43 AM, Walter Bright wrote:
It is possible for each static constructor to specify 
independently of
the other static constructors which imports must be 
constructed first.

But do we really want to go that far?


One way to do that might be to borrow syntax from classes:

   static this() : std.stdio, a, c
   {
   ...
   }

and the  this static constructor only requires that modules 
std.stdio, a, and c be constructed first.


   static this() : void
   {
   ...
   }

means it has no dependencies on other imports.

   static this()
   {
  ...
   }

has the current behavior (all imported modules must be 
constructed first).


Why not simplify?

static this()
{
import std.stdio, a, c; // existing syntax
   ...
}

static this()
{ // no imports - no dependencies
   ...
}

The current behavior should just be dropped.


Re: Breaking D2 language/spec changes with D1 being discontinued in a month

2012-11-29 Thread foobar

On Thursday, 29 November 2012 at 09:37:57 UTC, Manu wrote:
On 29 November 2012 03:48, deadalnix deadal...@gmail.com 
wrote:


On Thursday, 29 November 2012 at 01:29:12 UTC, Jonathan M 
Davis wrote:


Since master will almost certainly be the development branch, 
I don't see

how

that's a problem. The stable branch will be a separate 
branch, and

whoever is
managing the stable branch will merge stuff from the master 
branch into

it.


In this case, all bug fixes are mixed with new feature and 
then have to be
separated afterward and remerged into the stable branch. This 
is useless
work and it is likely to cause merge conflict in the stable 
branch.


Additionnaly, this become to really suck when several new 
features are dev

at the same time.

Finally, yhis is completely inconsistent with how github work 
in the first

place.

master make sense as an unstable branch, a release candidate, 
a beta or

whatever, but certainly not a dev branch.



Why don't you document precisely what branches you think should 
exist, and

the working merge/rebase policies.
I'm actually very curious to know.


 Granted, major stuff like 64-bit Windows support and UDAs 
should probably

be
introduced on branches separate from master, and it's still a 
problem if
they're not, but it won't affect the stable branch if they're 
not.



It will become all bigfixes will be based on code that 
contains the new

feature.


Manu:
This was mentioned in the group numerous times before, here's one 
more time to increase awareness even more:

git flow - http://nvie.com/posts/a-successful-git-branching-model/
should be easily adapted for the D development process.

Walter:
a champion cannot solve this issue as this requires participation 
of all (core) developers. Otherwise we get a _lot_ of redundant 
after the fact maintenance work. The only way to succeed long 
term is to remove all single points of failures - the single 
master branch on the technical side, and a single decision making 
person (you) on the management side. It can only be possible if 
you agree to relinquish some control and allow other core 
developers to _fully_ participate. that includes - review/pull 
powers, managing their own branches, taking part in the decision 
making process as to what feature is mature enough to be 
released on the stable branch. No champion can do any of that 
as it requires your agreement and participation.
Until such changes happen and D becomes _a community process_ (as 
I see Andrei is rightfully pushing for) there is little chance of 
a bigger D success.


Also, just to touch the multiple compiler versions overhead you 
mentioned - The point of maintaining multiple branches is to 
_minimize_ such overhead, not increase it. This allows for easier 
management of features, a more gradual release process to prevent 
regressions and breakage on the release branch, it gives _more 
control_ and allows for scaling of management to more developers. 
more branches = less work for you.


Re: The future of UDAs.

2012-11-29 Thread foobar
On Thursday, 29 November 2012 at 10:25:40 UTC, Walter Bright 
wrote:

On 11/29/2012 6:40 PM, Jacob Carlborg wrote:

On 2012-11-29 03:00, Walter Bright wrote:

An attribute would bring along with it the notion of having 
some static
constructors care about dependencies and others not. A pragma 
would be

global to the module.


Why can't the attribute be global to the module?



Because attributes attach to the declarations they enclose. A 
global attribute would be something else.


What's wrong with attaching the annotation to the module 
declaration?

i.e.
@no_circular_ctors module foobar;

Ideally, I'd like to have the reverse default - require an 
explicit import _inside_ the static ctor when a dependency 
actually exists. Seems to me that in the vast majority of cases 
this is the actual preferred choice by users and for the tiny (if 
any) percent that depend on the current behavior - they'll just 
get an easy to fix compile-error - e.g. symbol foo.bar is 
missing, solvable by adding the relevant import.
Of course, such a change should be properly announced and 
documented per the other thread about the development process of 
D.


Re: The future of UDAs.

2012-11-29 Thread foobar
On Thursday, 29 November 2012 at 14:17:40 UTC, Andrei 
Alexandrescu wrote:

On 11/29/12 6:44 AM, foobar wrote:
On Thursday, 29 November 2012 at 10:25:40 UTC, Walter Bright 
wrote:

On 11/29/2012 6:40 PM, Jacob Carlborg wrote:

On 2012-11-29 03:00, Walter Bright wrote:

An attribute would bring along with it the notion of having 
some static
constructors care about dependencies and others not. A 
pragma would be

global to the module.


Why can't the attribute be global to the module?



Because attributes attach to the declarations they enclose. A 
global

attribute would be something else.


What's wrong with attaching the annotation to the module 
declaration?

i.e.
@no_circular_ctors module foobar;


I think this entire approach is unprincipled (aside from 
solving a problem that's not urgent and not important). We 
shouldn't focus on the _syntax_ of the completely unprincipled 
approach, but instead on improving it.


A possibly better approach would be e.g. to do a simple 
analysis of the static constructor's use of symbols, and use 
that set to decide whether two static constructors must be 
ordered or not.



Andrei


Huh?
I made the exact same observation you did that module 
declarations can also carry attributes. You completely ignored 
the main part of my post regarding what I feel would indeed be a 
better approach (IMO).


I don't understand why you bother to answer a post you haven't 
bothered to read.


Re: Something needs to happen with shared, and soon.

2012-11-19 Thread foobar
On Saturday, 17 November 2012 at 13:22:23 UTC, Michel Fortin 
wrote:
On 2012-11-16 18:56:28 +, Dmitry Olshansky 
dmitry.o...@gmail.com said:



11/16/2012 5:17 PM, Michel Fortin пишет:
In case you want to protect two variables (or more) with the 
same mutex.

For instance:

Mutex m;
synchronized(m) int next_id;
synchronized(m) Object[int] objects_by_id;



Wrap in a struct and it would be even much clearer and safer.
struct ObjectRepository {
int next_id;
Object[int] objects_by_id;
}
//or whatever that combination indicates anyway
synchronized ObjectRepository objeRepo;


I guess that'd be fine too.


snip

That solution does not work in the general case. More 
specifically any graph-like data structure. E.g a linked-lists, 
trees, etc..

Think for example an insert to a shared AVL tree.


Re: function overload on full signature?

2012-11-15 Thread foobar

On Wednesday, 14 November 2012 at 19:12:59 UTC, Timon Gehr wrote:

On 11/14/2012 06:43 PM, foobar wrote:

On Tuesday, 13 November 2012 at 21:34:28 UTC, Rob T wrote:
I'm wondering why overloading has been implemented to only 
match on
the argument list rather than the full signature which 
includes the

return type? I know I would use it if it was available.

I'm not requesting this to be a feature of D, I'm only asking 
why it

is not being done.

--rt


This is hardly a new idea. It was implemented in a few 
languages of the
70's and it proved to be adding complexity and generally not 
worth the

trouble.


I guess they just were not doing it right then.

No language nowadays bothers with this based on those past 
lessons.


Haskell.

 fromInteger 2 :: Float
2.0


I thought that Haskell doesn't have function overloading (which 
simplifies this greatly)... Anyway, I mostly meant standard 
imperative/OO languages. Sorry for the confusion.


Re: function overload on full signature?

2012-11-14 Thread foobar

On Tuesday, 13 November 2012 at 21:34:28 UTC, Rob T wrote:
I'm wondering why overloading has been implemented to only 
match on the argument list rather than the full signature which 
includes the return type? I know I would use it if it was 
available.


I'm not requesting this to be a feature of D, I'm only asking 
why it is not being done.


--rt


This is hardly a new idea. It was implemented in a few languages 
of the 70's and it proved to be adding complexity and generally 
not worth the trouble. No language nowadays bothers with this 
based on those past lessons.


Re: [ ArgumentList ] vs. @( ArgumentList )

2012-11-07 Thread foobar
On Wednesday, 7 November 2012 at 08:36:49 UTC, Jacob Carlborg 
wrote:

On 2012-11-06 22:53, Walter Bright wrote:

C++11 has had problems adding new keywords, as about every 
identifier
somewhere has been used by someone's C++ source code, and they 
don't
want to break existing code. So C++11 winds up with awful 
things like

decltype.


Just create a new attribute, call it builtin or something 
similar, which takes attributes as arguments, i.e.


@builtin(shared) int a;
@builtin(property) int b;

I'm not suggesting that we should change the existing @shared 
and @property, I just used them as an example.


I honestly don't get why we keep reinventing the concept of 
namespaces.

I agree with Jonathan regarding the identifier look-up rules in D.
std.algorithm.find really should be *the default* unless the 
user specifically aliases that to find whereas now we have the 
exact opposite. But even without this we still should use D's 
already existing namespace solution - *the module system*. We 
should take a lesson from other platforms such as Java and .NET 
where everything is neatly organized. Let's stop this global 
identifiers nightmare!


On that note, here's some things we *should not do*:
- put unrelated random stuff in object.d
- add more redundant ways to define namespaces such as 
__identifier, builtin(identifier), @attribute(identifier), 
@identifier, etc, etc..
- add more @keywords because they conflict with global 
identifiers.
- have _huge_ single modules in Phobos that contain everything 
and ythe kitchen sink. I still hate with passion the 
std.algorithm module. It's like opening a shop called A 
Shop or naming a newspaper Newspaper.


Proper organization is not inherently evil and we should not 
complicate the language design to compensate our current 
sloppiness.


Re: [ ArgumentList ] vs. @( ArgumentList )

2012-11-06 Thread foobar

On Tuesday, 6 November 2012 at 20:01:27 UTC, Jacob Carlborg wrote:

On 2012-11-06 20:52, Manu wrote:
I'd like to re-enforce the consideration that @attribute() 
makes it
looks like they affect the code generation somehow... they're 
really

just annotations.


I still like the syntax.


I'd also like to add that the OP argument is false.
Sure, the attributes themselves are just meta-data and you can 
use them for purely informative purposes (to annotate with 
documentation, author names, versions, license, etc..) but more 
commonly attributes are intended to be introspected on at CT or 
RT and used to *indirectly cause some processing*.


The end result is the same and user defined attributes should be 
consistent with built-in ones.
Syntax wise, I agree the C# version is /slightly/ more pleasant 
to the eye than the Java one but given the possible grammar 
ambiguities and the consistency with buit-ins, @(attributes) win 
by a landslide.


Re: Regarding hex strings

2012-10-20 Thread foobar
On Saturday, 20 October 2012 at 10:51:25 UTC, Denis Shelomovskij 
wrote:

18.10.2012 12:58, foobar пишет:
IMO, this is a redundant feature that complicates the language 
for no

benefit and should be deprecated.
strings already have an escape sequence for specifying 
code-points \u

and for ubyte arrays you can simply use:
immutable(ubyte)[] data2 = [0xA1 0xB2 0xC3 0xD4];

So basically this feature gains us nothing.



Maybe. Just an example of a real world code:

Arrays:
https://github.com/D-Programming-Language/druntime/blob/fc45de1d089a1025df60ee2eea66ba27ee0bd99c/src/core/sys/windows/dll.d#L110

vs

Hex strings:
https://github.com/denis-sh/hooking/blob/69105a24d77fcb6eca701282a16dd5ec7311c077/tlsfixer/ntdll.d#L130

By the way, current code isn't affected by the topic issue.


I personally find the former more readable but I guess there 
would always be someone to disagree. As the say, YMMV.


Re: Regarding hex strings

2012-10-20 Thread foobar

On Saturday, 20 October 2012 at 21:03:20 UTC, H. S. Teoh wrote:

On Sat, Oct 20, 2012 at 04:39:28PM -0400, Nick Sabalausky wrote:

On Sat, 20 Oct 2012 14:59:27 +0200
foobar f...@bar.com wrote:
 On Saturday, 20 October 2012 at 10:51:25 UTC, Denis 
 Shelomovskij

 wrote:
 
  Maybe. Just an example of a real world code:
 
  Arrays:
  
https://github.com/D-Programming-Language/druntime/blob/fc45de1d089a1025df60ee2eea66ba27ee0bd99c/src/core/sys/windows/dll.d#L110
 
  vs
 
  Hex strings:
  
https://github.com/denis-sh/hooking/blob/69105a24d77fcb6eca701282a16dd5ec7311c077/tlsfixer/ntdll.d#L130
 
  By the way, current code isn't affected by the topic issue.
 
 I personally find the former more readable but I guess there 
 would always be someone to disagree. As the say, YMMV.


Honestly, I can't imagine how anyone wouldn't find the latter 
vastly

more readable.


If you want vastly human readable, you want heredoc hex syntax,
something like this:

ubyte[] = xEND
32 2b 32 3d 34 2e 20 32 2a 32 3d 34 2e 20 32 5e
32 3d 34 2e 20 54 68 65 72 65 66 6f 72 65 2c 20
2b 2c 20 2a 2c 20 61 6e 64 20 5e 20 61 72 65 20
74 68 65 20 73 61 6d 65 20 6f 70 65 72 61 74 69
6f 6e 2e 0a 22 36 34 30 4b 20 6f 75 67 68 74 20
74 6f 20 62 65 20 65 6e 6f 75 67 68 22 20 2d 2d
20 42 69 6c 6c 20 47 2e 2c 20 31 39 38 34 2e 20
22 54 68 65 20 49 6e 74 65 72 6e 65 74 20 69 73
20 6e 6f 74 20 61 20 70 72 69 6d 61 72 79 20 67
6f 61 6c 20 66 6f 72 20 50 43 20 75 73 61 67 65
END;

(I just made that syntax up, so the details are not final, but 
you get
the idea.) I would propose supporting this in D, but then D 
already has
way too many different ways of writing strings, some of 
questionable

utility, so I will refrain.

Of course, the above syntax might actually be implementable 
with a
suitable mixin template that takes a compile-time string. Maybe 
we

should lobby for such a template to go into Phobos -- that might
motivate people to fix CTFE in dmd so that it doesn't consume
unreasonable amounts of memory when the size of CTFE input gets
moderately large (see other recent thread on this topic).


T


Yeah, I like this. I'd prefer brackets over quotes but it not a 
big dig as the qoutes in the above are not very noticeable. It 
should look distinct from textual strings.

As you said, this could/should be implemented as a template.

Vote++


Re: Regarding hex strings

2012-10-20 Thread foobar

On Saturday, 20 October 2012 at 21:16:44 UTC, foobar wrote:

On Saturday, 20 October 2012 at 21:03:20 UTC, H. S. Teoh wrote:
On Sat, Oct 20, 2012 at 04:39:28PM -0400, Nick Sabalausky 
wrote:

On Sat, 20 Oct 2012 14:59:27 +0200
foobar f...@bar.com wrote:
 On Saturday, 20 October 2012 at 10:51:25 UTC, Denis 
 Shelomovskij

 wrote:
 
  Maybe. Just an example of a real world code:
 
  Arrays:
  
https://github.com/D-Programming-Language/druntime/blob/fc45de1d089a1025df60ee2eea66ba27ee0bd99c/src/core/sys/windows/dll.d#L110
 
  vs
 
  Hex strings:
  
https://github.com/denis-sh/hooking/blob/69105a24d77fcb6eca701282a16dd5ec7311c077/tlsfixer/ntdll.d#L130
 
  By the way, current code isn't affected by the topic 
  issue.
 
 I personally find the former more readable but I guess 
 there would always be someone to disagree. As the say, YMMV.


Honestly, I can't imagine how anyone wouldn't find the latter 
vastly

more readable.


If you want vastly human readable, you want heredoc hex syntax,
something like this:

ubyte[] = xEND
32 2b 32 3d 34 2e 20 32 2a 32 3d 34 2e 20 32 5e
32 3d 34 2e 20 54 68 65 72 65 66 6f 72 65 2c 20
2b 2c 20 2a 2c 20 61 6e 64 20 5e 20 61 72 65 20
74 68 65 20 73 61 6d 65 20 6f 70 65 72 61 74 69
6f 6e 2e 0a 22 36 34 30 4b 20 6f 75 67 68 74 20
74 6f 20 62 65 20 65 6e 6f 75 67 68 22 20 2d 2d
20 42 69 6c 6c 20 47 2e 2c 20 31 39 38 34 2e 20
22 54 68 65 20 49 6e 74 65 72 6e 65 74 20 69 73
20 6e 6f 74 20 61 20 70 72 69 6d 61 72 79 20 67
6f 61 6c 20 66 6f 72 20 50 43 20 75 73 61 67 65
END;

(I just made that syntax up, so the details are not final, but 
you get
the idea.) I would propose supporting this in D, but then D 
already has
way too many different ways of writing strings, some of 
questionable

utility, so I will refrain.

Of course, the above syntax might actually be implementable 
with a
suitable mixin template that takes a compile-time string. 
Maybe we
should lobby for such a template to go into Phobos -- that 
might

motivate people to fix CTFE in dmd so that it doesn't consume
unreasonable amounts of memory when the size of CTFE input gets
moderately large (see other recent thread on this topic).


T


Yeah, I like this. I'd prefer brackets over quotes but it not a 
big dig as the qoutes in the above are not very noticeable. It 
should look distinct from textual strings.

As you said, this could/should be implemented as a template.

Vote++


** not a big deal


Re: Const ref and rvalues again...

2012-10-19 Thread foobar

On Friday, 19 October 2012 at 07:53:30 UTC, Jacob Carlborg wrote:

On 2012-10-19 04:48, Timon Gehr wrote:


Then how to specify that the value of x cannot be escaped?
I'm in favour of doing it the other way round and disallow 
escaping of

ref parameters without an unsafe cast.


scope is supposed to be used to prevent this.


I like Timon's idea. scope is a bad fit in that the default 
should be the safe option. Unfortunately this does have the 
potential to brake lots of code, perhaps even if we limit it to 
@safe code.
An argument could be made that it's worth the breakage for @safe 
code to insure better safety.




Re: Regarding hex strings

2012-10-19 Thread foobar

On Friday, 19 October 2012 at 00:14:18 UTC, Nick Sabalausky wrote:

On Thu, 18 Oct 2012 12:11:13 +0200
foobar f...@bar.com wrote:


How often large binary blobs are literally spelled in the 
source code (as opposed to just being read from a file)?



Frequency isn't the issue. The issues are *Is* it ever 
needed? and
When it is needed, is it useful enough? The answer to both is 
most

certainly yes. (Remember, D is supposed to usable as a systems
language, it's not merely a high-level-app-only language.)


Any real-world use cases to support this claim? Does C++ have 
such a feature?
My limited experience with kernels is that this feature is not 
needed. The solution we used for this was to define an extern 
symbol and load it with a linker script (the binary data was of 
course stored in separate files).




Keep in mind, the question Does it pull it's own weight? is 
for

adding new features, not for going around gutting the language
just because we can.


Ok, I grant you that but remember that the whole thread started 
because the feature _doesn't_ work so lets rephrase - is it worth 
the effort to fix this feature?




In any case, I'm not opposed to such a utility library, in 
fact I think it's a rather good idea and we already have a 
precedent with oct!
I just don't think this belongs as a built-in feature in the 
language.


I think monarch_dodra's test proves that it definitely needs to 
be

built-in.


It proves that DMD has bugs that should be fixed, nothing more.


Re: Regarding hex strings

2012-10-19 Thread foobar

On Friday, 19 October 2012 at 13:19:09 UTC, Don Clugston wrote:


We can still have both (assuming the code points are valid...):
string foo = \ua1\ub2\uc3; // no .dup


That doesn't compile.
Error: escape hex sequence has 2 hex digits instead of 4


Come on, assuming the code points are valid. It says so 4 lines 
above!


Re: Regarding hex strings

2012-10-19 Thread foobar

On Friday, 19 October 2012 at 15:07:44 UTC, Don Clugston wrote:

On 19/10/12 16:07, foobar wrote:

On Friday, 19 October 2012 at 13:19:09 UTC, Don Clugston wrote:


We can still have both (assuming the code points are 
valid...):

string foo = \ua1\ub2\uc3; // no .dup


That doesn't compile.
Error: escape hex sequence has 2 hex digits instead of 4


Come on, assuming the code points are valid. It says so 4 
lines above!


It isn't the same.
Hex strings are the raw bytes, eg UTF8 code points. (ie, it 
includes the high bits that indicate the length of each char).

\u makes dchars.

\u00A1 is not the same as xA1 nor is it x00 A1. It's two 
non-zero bytes.


Yes, the \u requires code points and not code-units for a 
specific UTF encoding, which you are correct in pointing out are 
four hex digits and not two.
This is a very reasonable choice to prevent/reduce Unicode 
encoding errors.


http://dlang.org/lex.html#HexString states:
Hex strings allow string literals to be created using hex data. 
The hex data need not form valid UTF characters.


I _already_ said that I consider this a major semantic bug as it 
violates the principle of least surprise - the programmer's 
expectation that the D string types which are Unicode according 
to the spec to, well, actually contain _valid_ Unicode and _not_ 
arbitrary binary data.
Given the above, the design of \u makes perfect sense for 
_strings_ - you can use _valid_ code-points (not code units) in 
hex form.


For general purpose binary data (i.e. _not_ UTF encoded Unicode 
text) I also _already_ said IMO should be either stored as 
ubyte[] or better yet their own types that would ensure the 
correct invariants for the data type, be it audio, video, or just 
a different text encoding.


In neither case the hex-string is relevant IMO. In the former it 
potentially violates the type's invariant and in the latter we 
already have array literals.


Using a malformed _string_ to initialize ubyte[] IMO is simply 
less readable. How did that article call such features, WAT?


Re: Regarding hex strings

2012-10-19 Thread foobar

On Friday, 19 October 2012 at 18:46:07 UTC, foobar wrote:

On Friday, 19 October 2012 at 15:07:44 UTC, Don Clugston wrote:

On 19/10/12 16:07, foobar wrote:
On Friday, 19 October 2012 at 13:19:09 UTC, Don Clugston 
wrote:


We can still have both (assuming the code points are 
valid...):

string foo = \ua1\ub2\uc3; // no .dup


That doesn't compile.
Error: escape hex sequence has 2 hex digits instead of 4


Come on, assuming the code points are valid. It says so 4 
lines above!


It isn't the same.
Hex strings are the raw bytes, eg UTF8 code points. (ie, it 
includes the high bits that indicate the length of each char).

\u makes dchars.

\u00A1 is not the same as xA1 nor is it x00 A1. It's two 
non-zero bytes.


Yes, the \u requires code points and not code-units for a 
specific UTF encoding, which you are correct in pointing out 
are four hex digits and not two.
This is a very reasonable choice to prevent/reduce Unicode 
encoding errors.


http://dlang.org/lex.html#HexString states:
Hex strings allow string literals to be created using hex 
data. The hex data need not form valid UTF characters.


I _already_ said that I consider this a major semantic bug as 
it violates the principle of least surprise - the programmer's 
expectation that the D string types which are Unicode according 
to the spec to, well, actually contain _valid_ Unicode and 
_not_ arbitrary binary data.
Given the above, the design of \u makes perfect sense for 
_strings_ - you can use _valid_ code-points (not code units) in 
hex form.


For general purpose binary data (i.e. _not_ UTF encoded Unicode 
text) I also _already_ said IMO should be either stored as 
ubyte[] or better yet their own types that would ensure the 
correct invariants for the data type, be it audio, video, or 
just a different text encoding.


In neither case the hex-string is relevant IMO. In the former 
it potentially violates the type's invariant and in the latter 
we already have array literals.


Using a malformed _string_ to initialize ubyte[] IMO is simply 
less readable. How did that article call such features, WAT?


I just re-checked and to clarify string literals support _three_ 
escape sequences:

\x__ - a single byte
\u - two bytes
\U - four bytes

So raw bytes _can_ be directly specified and I hope the compiler 
still verifies the string literal is valid Unicode.





Re: private is non-virtual: Stuck in C++-thinking?

2012-10-19 Thread foobar

On Friday, 19 October 2012 at 21:09:05 UTC, Nick Sabalausky wrote:

My understanding is that this is intentionally disallowed:

---
module foo;

class Foo
{
private void func() {}
}

class Bar : Foo
{
// Disallowed:
private override void func() {}
}

void foobar(Foo f)
{
f.func();
}
---

If D had C++'s private, that restriction would make a lot of 
sense
(except possibly for nested classes, but I dunno). That's 
because: How

can you override a class you can't even access?

But D doesn't have a true private in the C++ sense. Instead, 
there

is code outside a class which *is* permitted to access private
members.

So am I missing something, or was the sample case above 
overlooked when

making the private must be non-virtual decision?


virtual private is an obscure C++ idiom which I think the 
argument for is extremely week. I think Walter made the right 
decision here in favor of more readable code.


I'd do the following:
---
module foo;
class Foo {
private void func() { funcImpl(); }
protected void funcImpl() {}
}

class Bar : Foo {
protected override void funcImpl() {}
}

void foobar(Foo f) {
f.func();
}
---


Re: Regarding hex strings

2012-10-18 Thread foobar

On Thursday, 18 October 2012 at 02:47:42 UTC, H. S. Teoh wrote:

On Thu, Oct 18, 2012 at 02:45:10AM +0200, bearophile wrote:
[...]
hex strings are useful, but I think they were invented in D1 
when
strings were convertible to char[]. But today they are an 
array of

immutable UFT-8, so I think this default type is not so useful:

void main() {
string data1 = xA1 B2 C3 D4; // OK
immutable(ubyte)[] data2 = xA1 B2 C3 D4; // error
}


test.d(3): Error: cannot implicitly convert expression
(\xa1\xb2\xc3\xd4) of type string to ubyte[]

[...]

Yeah I think hex strings would be better as ubyte[] by default.

More generally, though, I think *both* of the above lines 
should be

equally accepted.  If you write xA1 B2 C3 in the context of
initializing a string, then the compiler should infer the type 
of the
literal as string, and if the same literal occurs in the 
context of,
say, passing a ubyte[], then its type should be inferred as 
ubyte[], NOT

string.


T


IMO, this is a redundant feature that complicates the language 
for no benefit and should be deprecated.
strings already have an escape sequence for specifying 
code-points \u and for ubyte arrays you can simply use:

immutable(ubyte)[] data2 = [0xA1 0xB2 0xC3 0xD4];

So basically this feature gains us nothing.



Re: Const ref and rvalues again...

2012-10-18 Thread foobar

On Thursday, 18 October 2012 at 06:11:26 UTC, monarch_dodra wrote:
On Thursday, 18 October 2012 at 04:30:17 UTC, Jonathan M Davis 
wrote:

On Thursday, October 18, 2012 06:24:08 jerro wrote:

What would be the problem with const ref taking rvalues?


Read the thread that I already linked to:

http://forum.dlang.org/thread/4f84d6dd.5090...@digitalmars.com

- Jonathan M Davis


I read the thread, and not a single one of the problematic 
cases are actually valid C++.


Yes: the faulty MSVC has taught people to do retarded things, 
or be afraid of things that were illegal to begin with (in 
particular, pass an rvalue to a ref, WHICH IS ILLEGAL IN C++), 
such as increment(5).


There is actually nothing wrong with creating a temporary when 
something is bound to a const ref, provided the compiler 
follows the rules:


*Only LValues with an EXACT type match may be passed to a 
reference.
*In regards to *const* references, RValues may be copied in a 
temporary, and that temporary bound the the ref.


I'm not saying we particularly *need* this in D (C++ has a by 
ref paradigm that makes it more important, but D *rarelly* 
ever passes by const ref).


But if the compiler respects the above two rules (which it 
should), then RValue to const ref is both perfectly doable and 
safe (as safe as refs get anyways).


By allowing the the C++ semantics the function looses semantic 
information - whether the actual parameter was lvalue or rvalue. 
This semantic info can be used bot for compiler optimizations and 
move semantics. This is the reason C++11 added  references.


General question (might not be relevant to current design of D):
How about leaving the decision to the compiler and let the 
programmer only specify usage intent?

E.g.: (I'm speaking semantics here, not syntax)
void foo(const Type t); // 1. I only read the value
void foo (mutate Type t); // 2. I want to also mutate the actual 
parameter

void foo (move Type t); // 3. I want to move the actual parameter

In case 1 above, the compiler is free to pass lvalues by const 
and rvalues by value or perhaps optimize above certain size to 
const too.
In case 2, the compiler passes a ref to lvalue, rvalues are not 
accepted at CT.
If I want move semantics, I can use option 3 which accepts 
rvalues by ref. btw, what's the correct semantics for lvalues 
here?


What do you think?


Re: Regarding hex strings

2012-10-18 Thread foobar

On Thursday, 18 October 2012 at 09:42:43 UTC, monarch_dodra wrote:

On Thursday, 18 October 2012 at 08:58:57 UTC, foobar wrote:


IMO, this is a redundant feature that complicates the language 
for no benefit and should be deprecated.
strings already have an escape sequence for specifying 
code-points \u and for ubyte arrays you can simply use:

immutable(ubyte)[] data2 = [0xA1 0xB2 0xC3 0xD4];

So basically this feature gains us nothing.


Have you actually ever written code that requires using code 
points? This feature is a *huge* convenience for when you do. 
Just compare:


string nihongo1 = xe697a5 e69cac e8aa9e;
string nihongo2 = \ue697a5\ue69cac\ue8aa9e;
ubyte[] nihongo3 = [0xe6, 0x97, 0xa5, 0xe6, 0x9c, 0xac, 0xe8, 
0xaa, 0x9e];


BTW, your data2 doesn't compile.


I didn't try to compile it :) I just rewrote berophile's example 
with 0x prefixes.


How often do you actually need to write code-point _literals_ in 
your code?
I'm not arguing that it isn't convenient. My question would be 
rather Anderi's does it pull it's own weight? meaning does the 
added complexity in the language and having more than one way for 
doing something worth that convenience?


Seems to me this is in the same ballpark as the built-in complex 
numbers. Sure it's nice to be able to write 4+5i instead of 
complex(4,5) but how frequently do you actually ever need the 
_literals_ even in complex computational heavy code?


Re: Regarding hex strings

2012-10-18 Thread foobar

On Thursday, 18 October 2012 at 10:05:06 UTC, bearophile wrote:

The docs say:
http://dlang.org/lex.html

Hex strings allow string literals to be created using hex data. 
The hex data need not form valid UTF characters.


But this code:


void main() {
immutable ubyte[4] data = xF9 04 C1 E2;
}



Gives me:

temp.d(2): Error: Outside Unicode code space

Are the docs correct?

--

foobar:

Seems to me this is in the same ballpark as the built-in 
complex numbers. Sure it's nice to be able to write 4+5i 
instead of complex(4,5) but how frequently do you actually 
ever need the _literals_ even in complex computational heavy 
code?


Compared to oct!5151151511, one problem with code like this 
is that binary blobs are sometimes large, so supporting a x 
syntax is better:


immutable ubyte[4] data = hex!F9 04 C1 E2;

Bye,
bearophile


How often large binary blobs are literally spelled in the source 
code (as opposed to just being read from a file)?
In any case, I'm not opposed to such a utility library, in fact I 
think it's a rather good idea and we already have a precedent 
with oct!
I just don't think this belongs as a built-in feature in the 
language.


Re: Regarding hex strings

2012-10-18 Thread foobar

On Thursday, 18 October 2012 at 10:11:14 UTC, foobar wrote:

On Thursday, 18 October 2012 at 10:05:06 UTC, bearophile wrote:

The docs say:
http://dlang.org/lex.html

Hex strings allow string literals to be created using hex 
data. The hex data need not form valid UTF characters.




This is especially a good reason to remove this feature as it 
breaks the principle of least surprise and I consider it a major 
bug, not a feature.


I expect D's strings which are by definition Unicode to _only_ 
ever allow _valid_ Unicode. It makes no sense what so ever to 
allow this nasty back-door. Other text encoding should be either 
stored and treated as binary data (ubyte[]) or better yet stored 
in their own types that will ensure those encodings' invariants.


Re: Regarding hex strings

2012-10-18 Thread foobar

On Thursday, 18 October 2012 at 14:29:57 UTC, Don Clugston wrote:

On 18/10/12 10:58, foobar wrote:

On Thursday, 18 October 2012 at 02:47:42 UTC, H. S. Teoh wrote:

On Thu, Oct 18, 2012 at 02:45:10AM +0200, bearophile wrote:
[...]
hex strings are useful, but I think they were invented in D1 
when
strings were convertible to char[]. But today they are an 
array of
immutable UFT-8, so I think this default type is not so 
useful:


void main() {
   string data1 = xA1 B2 C3 D4; // OK
   immutable(ubyte)[] data2 = xA1 B2 C3 D4; // error
}


test.d(3): Error: cannot implicitly convert expression
(\xa1\xb2\xc3\xd4) of type string to ubyte[]

[...]

Yeah I think hex strings would be better as ubyte[] by 
default.


More generally, though, I think *both* of the above lines 
should be

equally accepted.  If you write xA1 B2 C3 in the context of
initializing a string, then the compiler should infer the 
type of the
literal as string, and if the same literal occurs in the 
context of,
say, passing a ubyte[], then its type should be inferred as 
ubyte[], NOT

string.


T


IMO, this is a redundant feature that complicates the language 
for no

benefit and should be deprecated.
strings already have an escape sequence for specifying 
code-points \u

and for ubyte arrays you can simply use:
immutable(ubyte)[] data2 = [0xA1 0xB2 0xC3 0xD4];

So basically this feature gains us nothing.


That is not the same. Array literals are not the same as string 
literals, they have an implicit .dup.
See my recent thread on this issue (which unfortunately seems 
have to died without a resolution, people got hung up about 
trailing null characters without apparently noticing the more 
important issue of the dup).


I don't see how that detail is relevant to this discussion as I 
was not arguing against string literals or array literals in 
general.


We can still have both (assuming the code points are valid...):
string foo = \ua1\ub2\uc3; // no .dup
and:
ubyte[3] goo = [0xa1, 0xb2, 0xc3]; // implicit .dup


Re: Import improvement

2012-10-17 Thread foobar
On Wednesday, 17 October 2012 at 15:16:12 UTC, Andrei 
Alexandrescu wrote:

On 10/16/12 2:49 AM, Jacob Carlborg wrote:

On 2012-10-16 02:10, Peter Alexander wrote:

It's cute, but I think it is terribly misleading. I wouldn't 
recommend

that to anyone.


I agree. I'm using foo.bar._, that's the same used by Scala.


Sounds good. Arbitrary + precedent  arbitrary.

Andrei


Let's be accurate here:
Meaningful  Arbitrary + precedent  arbitrary.

If I want to truly import an _entire_ package than both:
import package.all;
import package.*;
make sense/ meaningful.

If I want to have a special file that includes specific public 
imports for the package's public API than it should be called 
appropriately. e.g:

import package.api;

I've seen such usage of an api package in Google's Android 
platform for instance.


Re: D seems interesting, but...

2012-10-15 Thread foobar

On Monday, 15 October 2012 at 13:11:29 UTC, bearophile wrote:

Adam D. Ruppe:


You could just version it:

version(foo_main)
void main() {}


That's not good enough.

What I as talking about is: when the D compilers know a module 
is

the main module, it defines a _standard_ version boolean flag,
named like is_main_module as true. And it gives a compiler
error if it can't find a main. Otherwise is_main_module is
false.

It's meant to be used as:


module modulea;
int foo() { return 0; }
static if (is_main_module) {
   unittest {}
   void main() { // demo code
 import std.stdio;
 writeln(foo());
   }
}



module moduleb;
import modulea;
int bar() { return 1; }
static if (is_main_module) {
   unittest {}
   void main() { // demo code
 import std.stdio;
 writeln(foo());
 writeln(bar());
   }
}


When you compile modulea, defines its is_main_module as true, it
runs its unittests (if you have used -unittest), and its main,
that is a demo for the A module.

If you compile the moduleb (with rdmd or something), it knows
moduleb has to contain the main, it defines is_main_module=true
in moduleb and defines is_main_module=false for modulea. So it
compiles the main of moduleb and ignores the main of modulea. So
it runs the demo code for moduleb only.

Using a non-standard user-defined version as you suggest misses
all this, and it's not good enough. Standardization and
automation is important here.

Bye,
bearophile


I'm sorry to say but that *is* a _horrible_ _hack_. It looks 
almost as awful as it does in python with the underscores.


Java has the correct DRY solution - each class can define a 
static main method but the compiler only uses the one specified 
by a compiler switch.
The above basically asks the programmer to endlessly repeat the 
same trivial implementation boilerplate that should be written 
just once _in_ the compiler.


Re: D seems interesting, but...

2012-10-15 Thread foobar
On Monday, 15 October 2012 at 15:22:38 UTC, Andrei Alexandrescu 
wrote:

snip


Yes, this is a nice thing Java, .NET and Python have.


Wonder if a simple convention would suffice, e.g. every module 
that wanna defines a moduleMain(string[] args) and then you 
have one module main.d that has:


void main(string[] args) { import wuddever; moduleMain(args); }


Andrei


Great idea! But why add another (redundant) level of indirection?
It should go in the C main in druntime together with a mechanism 
to call the correct D main, by e.g. reading the module name from 
the command line.





  1   2   3   4   >