Re: question/suggestion about protection attributes

2009-12-23 Thread Sergey Gromov

Rainer Deyke wrote:

Zarathustra wrote:

Why protection attributes aren't divided into two groups?


...  Because there is no valid
reason for protecting fields from functions in the same module...


Encapsulation anyone?  If you pack related functionality into a single 
module you don't have *any* means of enforcing encapsulation at the 
language level.  "private" becomes a pure convention.  And if you use 
modules to systematically enforce encapsulation you end up with Tango: 
dozens of micro-modules which require either dozens of imports to use 
them, or ugly collective import modules which require constant attention 
and maintenance.


Re: Local variable inside delegate literal

2009-12-23 Thread Sergey Gromov

Daniel wrote:

int delegate()[] funcs;
funcs.length = 3;

foreach(i, ref f; funcs)
{
  f = int() { return i; }
}

foreach(f; funcs)
{
  writeln(f());
}


First, there are syntax errors in your example.  It should be

f = delegate int() { return i; };

Second, this works in D2:

foreach(i, ref f; funcs)
{
  void blah() {
auto j = i;
f = delegate int() { return j; };
  }
  blah();
}

But this doesn't, outputs 2, 2, 2:

foreach(i, ref f; funcs)
{
  auto j = i;
  f = delegate int() { return j; };
}

And this crashes:

foreach(i, ref f; funcs)
{
  ({
auto j = i;
f = delegate int() { return j; };
  })();
}

I think these 3 variants should be equivalent.


Re: opEquals(const ref yadaYada)

2009-12-15 Thread Sergey Gromov

Simen kjaeraas wrote:

Steven Schveighoffer  wrote:


On Mon, 14 Dec 2009 11:44:18 -0500, lws  wrote:


On 2009-12-14 07:01:47 -0800, dsimcha  said:

1.  Well, stuff like this is good warning to whomever about the 
code.   Since D is a imperative language, it should at least give you 
a warning when you're doing something really inefficient that has a 
boilerplate way of accomplishing it that is much faster.


It's not faster, it's slower.  Passing a reference to an integer or 
smaller value type is not as efficient passing the value type itself.


This is hardly true on modern architectures. I don't have the numbers on
it, but even for ints and floats, ref is just as fast (and sometimes
faster).


To return a reference you must allocate the value.  And to use the value 
you must dereference the reference.  All this takes cycles no matter how 
modern your architecture is.


Re: Windows multi-threading performance issues on multi-core systems only

2009-12-15 Thread Sergey Gromov

dsimcha wrote:

== Quote from Simen kjaeraas (simen.kja...@gmail.com)'s article

dsimcha  wrote:

Timing with affinity for all 4 CPUs:  28390 milliseconds

Timing with affinity for only 1 CPU:  533 milliseconds

Tested this on a Core 2 Duo, same options. OS is Windows 7, 64bit. It
scales roughly inverse linearly with number of threads:
163ms for 1,
364ms for 2,
886ms for 4


Maybe you mean core 2 quad?


This is quite different from your numbers, though.


Yea, forgot to mention my numbers were on Win XP.  Maybe Windows 7 critical
sections are better implemented or something.   Can a few other people with a
variety of OS's run this benchmark and post their numbers?


Core 2 duo laptop, 1.8GHz, XP Pro:

860ms   1 core
11369ms 2 cores


Re: Input ranges do not compose

2009-12-02 Thread Sergey Gromov

Andrei Alexandrescu wrote:

Sergey Gromov wrote:

There are actually two issues:

1.  Most of the std.algorithm and std.range functions claim that they 
accept input ranges but take them *by value*.  This violates input 
ranges' non-copyable contract.


2.  A whole bunch of algorithms is required similar to those we have 
now but accepting their range arguments by reference and mutating them.


Do I miss something?  The ranges do not seem as universal to me anymore.


This issue is solved by save(), see 
http://erdani.com/publications/on-iteration.html. We need to make one 
more pass through the ranges and the range-related stuff in Phobos to 
use save().


Thinking about it, save() can save the day if all the range manipulation 
functions are changed to receive ranges by reference and to keep value 
ranges by pointer internally, and use save() if they really want a copy. 
 Otherwise, if take() still returns Take!() value and copy() still 
receives it by value, save() won't change anything.


Re: dynamic classes and duck typing

2009-12-02 Thread Sergey Gromov

BCS wrote:
I'm not arguing on that point. What I'm arguing is that (at least for 
me) the primary advantages of metaprogramming are static checks (for 
non-perf benefits) and performance. Both of these must be done at 
compile time. Runtime metaprogramming just seems pointless *to me.*


One of important applications of metaprogramming is code generation 
which would be too tedious or bug-prone to generate and support 
manually.  Dynamic languages can definitely provide for that.


Input ranges do not compose

2009-12-02 Thread Sergey Gromov

Say I want to present a file as an input range:

class RangeFile {
bool empty() {...}
ubyte front() {...}
void popFront() {...}
// some private stuff
}

I'm parsing it.  There are chunks, one byte for size then data of that size:

void parse(RangeFile rf) {
while (!rf.empty) {
int size = rf.front;
rf.popFront();
popFrontN(rf, size);
}
}

It works.  Now let's do something useful with the chunks' contents. 
There are strings in there, byte for length, then that much characters. 
 Read 'em:


void parse(RangeFile rf) {
while (!rf.empty) {
int size = rf.front;
rf.popFront();
auto chunk = take(size, rf);
while (!chunk.empty) {
int len = chunk.front;
chunk.popFront();
auto str = new char[len];
copy(take(len, chunk), str);
}
}
}

BANG.  This does not work.  The chunk won't end where it should.  The 
problem is that second take() creates a copy of the chunk data, and the 
copy() does not update chunk's remaining size while copying.


This behavior is fine and expected and desired for forward ranges and up 
but makes no sense for input ranges.


I thought I could fix it rewriting copy:

copy(take(len, &chunk), str);

But it didn't compile.  Told me something about something not being lvalue.

There are actually two issues:

1.  Most of the std.algorithm and std.range functions claim that they 
accept input ranges but take them *by value*.  This violates input 
ranges' non-copyable contract.


2.  A whole bunch of algorithms is required similar to those we have now 
but accepting their range arguments by reference and mutating them.


Do I miss something?  The ranges do not seem as universal to me anymore.


Re: News/info on Go and Java

2009-11-26 Thread Sergey Gromov
Thu, 26 Nov 2009 11:58:23 -0500, bearophile wrote:

> Sergey Gromov:
>> var slice []int = array[5:7];
> 
> Is []int better than int[] ?

Well, try to read aloud int[5][10]. I come up with "Integer, five of
them, ten times."  While [10][5]int is "Array of ten arrays of
integers."  It's *much* clearer.

> [5:7] is a slice syntax a bit better than [5..7] (and it's used in
> Python). But in D [5:7] is the literal for an AA... 

In Go, it'd be map[int]int{5:7}.


Re: News/info on Go and Java

2009-11-26 Thread Sergey Gromov
Wed, 25 Nov 2009 12:27:59 +0300, Denis Koroskin wrote:

> On Wed, 25 Nov 2009 03:03:59 +0300, bearophile   
> wrote:
> 
>> This looks a lot like D:
>> http://research.swtch.com/2009/11/go-data-structures.html
> 
> Looks like go has arrays that support slices. Do they support appending?  
> If so, what's their behavior and how do they solve stomping issues?

Arrays are values and cannot be resized after creation.

var array [10]int;

Arrays can be sliced like in D:

var slice []int = array[5:7];

The length of this slice is len(slice) == 7 - 5 == 2.   The *capacity*
of this slice is cap(slice) == 10 - 5 == 5.

You can slice a slice beyond its length, up to capacity:

var slice2 []int = slice[4:5];

Effectively slice is a tail of an array, with optional subdivision into
sub-head and sub-tail.

There is no array nor slice concatenation, nor any other way to change
slice length except slicing.


Re: Revamping associative arrays

2009-10-18 Thread Sergey Gromov
Sun, 18 Oct 2009 06:18:34 -0400, bearophile wrote:

>> Then I couldn't understand why the hell iterating on collection
>> returns a key in the first place. It's so not intuitive.<
> 
> What's intuitive on iterating on values? Well, I think Walter agrees
> with you, I remember his explanation (iterating on a normal array
> doesn't yield its indexes), but beside what's intuitive you have also
> to keep in mind what's handy, and iterating on keys is more useful.

It's easy to see what's intuitive if you consider what a collection
contains.  To me, it contains *values*, always.  These values may be
indexed: by an arbitrary key (AA), by an integral index (array), or not
at all (single-linked list).  But the index is not the point, it's only
a way to access values.  And when I iterate over a collection, I
definitely wan to iterate over the values it contains, regardless of an
indexing scheme this particular collection uses.


Re: T[new] misgivings

2009-10-17 Thread Sergey Gromov
Thu, 15 Oct 2009 23:18:22 -0500, Andrei Alexandrescu wrote:

> Jeremie Pelletier wrote:
>> Andrei Alexandrescu wrote:
>>> Jeremie Pelletier wrote:
 Andrei Alexandrescu wrote:
> Walter Bright wrote:
>> Andrei Alexandrescu wrote:
>>> This goes into something more interesting that I thought of after 
>>> the conversation. Consider:
>>>
>>> T[new] a;
>>> T[] b;
>>> ...
>>> a = b;
>>>
>>> What should that do?
>>
>> Error. T[] cannot be implicitly converted to T[new]
>
> Then your argument building on similarity between the two is weakened.
>
> T[new] a;
> T[] b;
> ...
> a = [1, 2, 3];
> b = [1, 2, 3];
>
> Central to your argument was that the two must do the same thing. 
> Since now literals are in a whole new league (they aren't slices 
> because slices can't be assigned to arrays), the cornerstone of your 
> argument goes away.
>
>
> Andrei

 Simple, assignment to a fails 'cannot cast T[3] to T[new]'.

 It's already consistent with slices of different types:
 char[] a = "foo"; // error, cannot cast immutable(char)[] to char[]
 int[new] b = [1, 2, 3]; // error, cannot cast int[3] to int[new]

 you have to do:
 char[] a = "foo".dup;
 int[new] b = [1, 2, 3].dup;

 Jeremie
>>>
>>> I'd be _very_ unhappy to have to explain to people how in the world we 
>>> managed to make the most intuitive syntax not work at all.
>>>
>>> Andrei
>> 
>> I agree it can be confusing, the first time i tried to assign a string 
>> literal to a char[] in D2 I had to pause for a second to understand what 
>> was happening :)
>> 
>> But what I don't like is that assigning memory from the static data 
>> segment to a resizable array isn't safe. Unless the GC can detect that 
>> the memory it is trying to resize isn't part of the heap and 
>> automatically create a new allocation for it, you're gonna have nasty 
>> side effects.
>> 
>> The compiler could also implicitly copy the slice, but then it should 
>> also automatically copy a "foo" literal when assigned to char[] to keep 
>> consistent.
>> 
>> Jeremie
> 
> Speaking of which, a funny fallout of this a = [1, 2, 3] thing is that 
> we, while striving to avoid all hidden allocations, ended up doing the 
> worst hidden allocation with the simplest and most intuitive syntax.

How about this specification: [1, 2, 3] is an array literal which
*allocates* an array but the allocation can be optimized away if
assigned to a slice.


Re: T[new] misgivings

2009-10-17 Thread Sergey Gromov
Thu, 15 Oct 2009 21:55:07 -0500, Andrei Alexandrescu wrote:

> int[new] a;
> ...
> a = [1, 2, 3];
> 
> What should that do?

To me a is an array, a reference type.  Therefore assignment here means
rebinding a to a new array created from a literal.

> A: Ok, then how do I say the common operation "I want to overwrite 
> whatever the array had with 1, 2, 3"? I can only presume there must be 
> an obvious and simple way to do so, and I thought a = [1, 2, 3] was the 
> obvious syntax to achieve that.

I'd say

a.replace([1, 2, 3]);

> T[new] a;
> T[] b;
> ...
> a = b;
> 
> What should that do?

Error: type mismatch.  Use

a = b.dup;


Re: Sugar around string mixins

2009-10-04 Thread Sergey Gromov
Sat, 3 Oct 2009 21:33:37 -0400, Jarrett Billingsley wrote:

> On Sat, Oct 3, 2009 at 9:22 PM, Sergey Gromov  wrote:
> 
>> While I like and support the idea, I think that hijacking the "macro"
>> keyword now will make it very hard to re-design later.  It would be much
>> better to reuse the "mixin" keyword for this since it's exactly what's
>> happening: defining a function for mixing in:
>>
>> mixin max(int a, int b) {...}
>>
>> It could be problematic from the grammar perspective though.
> 
> Newp. 'mixin' could be followed by one of four things:
> 
> - '(', it's a string mixin.
> - 'ident' '!', it's a template mixin.
> - 'ident' ';' it's also a template mixin.
> - 'ident' '(', it's a mixin declaration.
> 
> Not tough. But then you're really overloading the keyword by using it
> for three very different purposes.

I cannot see how this is "very different" from what it does currently.
I'm declaring a function intended specifically for mixing in.  That's
what you usually do.  I'm just moving the "mixin" keyword from every
single function invocation to its declaration, reducing the unnecessary
typing and ugliness.

I can see a problem with this approach though, that something that looks
lke a function call can be actually a mixin with full access to the
container function scope.  Explicit mixins are, well, explicit in this
respect.


Re: Multiple subtyping with alias this and nested classes

2009-10-04 Thread Sergey Gromov
Sun, 04 Oct 2009 00:10:30 +0200, Yigal Chripun wrote:

> > interface IBlipper
> > {
> > void blip();
> > void nameCollision();
> > }
> > template Blipper()
> > {
> > void blip() {}
> > void nameCollision() {}
> > }
> >
> > interface IFlipper
> > {
> > void flip();
> >  void nameCollision();
> > }
> > template Flipper()
> > {
> > void flip() {}
> > void nameCollision() {}
> > }
> 
> interfaces implement virtual MI, so FlippingBlipper must implement one 
> nameCollision which is shared by both interfaces.

That's not correct if you're talking about virtual MI in C++.  There,
you'd have to create a common root for the virtual inheritance to
actually work:

class INameCollider
{
public:
virtual void nameCollision() = 0;
};

class IFlipper: public virtual INameCollider
{
public:
virtual void flip() = 0;
};

class IBlipper: public virtual INameCollider
{
public:
virtual void blip() = 0;
};

class FlippingBlipper: public IFlipper, public IBlipper
{
public:
// Contains single, common nameCollision()
virtual void nameCollision() {}
virtual void flip() {}
virtual void blip() {}
};

Otherwise, if IFlipper and IBlipper are unrelated, you have two separate
nameCollision() functions which you must disambiguate as
IFlipper::nameCollision() and IBlipper::nameCollision() both when
defining and when calling via a FlippingBlipper instance.


Sugar around string mixins (was: Why not move cast to the standard library?)

2009-10-03 Thread Sergey Gromov
Fri, 25 Sep 2009 15:35:11 -0400, Adam D. Ruppe wrote:
> 
> macro max(int a, int b) {
>   return a ~ " > " ~ b ~ " ? " ~ a ~ " : " ~ b;
> }
> 
> void main() {
>   auto num1 = 10;
>   auto num2 = 20;
> 
>   auto result = max(num1, num2);
> }
> 

While I like and support the idea, I think that hijacking the "macro"
keyword now will make it very hard to re-design later.  It would be much
better to reuse the "mixin" keyword for this since it's exactly what's
happening: defining a function for mixing in:

mixin max(int a, int b) {...}

It could be problematic from the grammar perspective though.


Re: Making Metaprogramming Pleasant and Fun

2009-08-30 Thread Sergey Gromov
Mon, 24 Aug 2009 00:25:19 -0400, Chad J wrote:

> Suggestion 1:
> 
> For any template whose argument list ends with a string argument, such
> as this one:
> 
> template foo( T, string arg )
> {
> ...
> }
> 
> ... allow it to be instantiated (or mixed in) like so:
> 
> foo!(T)
> {
> // Some token string.
> }
> 
> or
> 
> mixin foo!(T)
> {
> // Some token string.
> }

I agree it would be nice to add some sugar to mixin usage.  But I'm
afraid this particular proposal has too many corner cases and parsing
ambiguities.  I cannot point out any right now, it's just an impression.


Re: Notepad++

2009-08-20 Thread Sergey Gromov
Tue, 18 Aug 2009 20:40:37 +0100, Stewart Gordon wrote:

> Sergey Gromov wrote:
>> Exactly.  There is a 32-bit "style" known for every character, plus
>> another 32-bit field associated with every line.  A lexer is free to use
>> these fields for any purpose, except the lower byte of a style defines
>> the characters' color.
> 
> Does it keep around in memory the style of every character, or only the 
> 32-bit field associated with the line so that the lexer can re-style the 
> characters on repaint/scroll?

It can tell about any character of which style it is.  This is to
repaint unchanged lines without ever calling a lexer.

> 
>>> [DelimitedToken9]
>>> Start = '
>>> End = '
>>> Esc = \
>>> Type = Char
>>> SpanLines = No
>>> Nest = No
>>>
>>> There, we have all of D1 covered now, and not a regexp in sight.
>> 
>> Yes and no, because your ad-hoc format doesn't cover subtle differences
>> between C and D strings.  Like C strings don't support embedded EOLs.
> 
> I don't understand.  How does SpanLines not achieve this?
> 
> Then what _does_ SpanLines achieve according to whatever conclusion 
> you've come to?

Here's a string which is valid in D but is invalid in C:

"foo
bar"

Here's another string which is, on the contrary, valid in C but is
invalid in D:

"foo\
bar"

They both "span lines."


Re: Notepad++

2009-08-17 Thread Sergey Gromov
Mon, 17 Aug 2009 10:37:47 +0200, Don wrote:

> Sergey Gromov wrote:
>> Then you have q"{foo}" where "{" and "}" can be any of ()[]<>{}.
>> Regexps cannot translate while substituting, so you must create regexps
>> for all possible parens.
> 
> Remember that the whole point of q{} strings was that they should NOT be 
> highlighted as strings!

You confuse q{} and q"{}" here.  The former is a token string which may
contain only valid D tokens.  The latter is a delimited string with
nesting delimiters.  Like q"<hello>".


Re: Notepad++

2009-08-17 Thread Sergey Gromov
Mon, 17 Aug 2009 21:23:56 +0100, Stewart Gordon wrote:

> Sergey Gromov wrote:
>> Highlighting the whole file every time a charater is typed is slow.
>> Scintilla doesn't do that.  It provides the lexer with a range of
>> changed lines.  The lexer is then free to choose a larger range if it
>> cannot deduce context from the initial range.  I tried to ignore this
>> range and re-highlight the whole file in my lexer.  The performance was
>> unacceptable.
> 
> Of course.  I suppose now that the right strategy is line-by-line with 
> some preservation of state between lines:
> 
> - Keep a note of the state at the beginning of each line
> - When something is changed, re-highlight those lines that have changed
> - Carry on re-highlighting until the state is back in sync with what was 
> there before.  If this means going way beyond the visible area of the 
> file, record the state of the next however many lines as unknown (so 
> that it will have another go when/if those lines are later scrolled into 
> view).
> - If a range of lines that has just come into view begins in unknown 
> state, it's up to the particular lexer module to start from the first 
> visible line or backtrack as far as it likes to get some context.
> 
> Is this anything like how Scintilla works?

Exactly.  There is a 32-bit "style" known for every character, plus
another 32-bit field associated with every line.  A lexer is free to use
these fields for any purpose, except the lower byte of a style defines
the characters' color.

> 
> 
>> It's actually trivial* to implement a lexer for Scintilla which would
>> work exactly as TextPad does, including use of the same configuration
>> files.
>> 
>> * That is, if you know exactly how TextPad works.
> 
> It would also be straightforward to improve TextPad's scheme to support 
> an arbitrary number of string/comment types.  How about this as an 
> all-in-one replacement for TP's comment and string syntax directives?
> 
> [...]
> 
> [DelimitedToken8]
> Start = "
> End = "
> Esc = \
> Type = String
> SpanLines = Yes
> Nest = No
> 
> [DelimitedToken9]
> Start = '
> End = '
> Esc = \
> Type = Char
> SpanLines = No
> Nest = No
> 
> There, we have all of D1 covered now, and not a regexp in sight.

Yes and no, because your ad-hoc format doesn't cover subtle differences
between C and D strings.  Like C strings don't support embedded EOLs.
Though you may consider this minor.

> 
>> Basically yes, but they're going to be much more complex.  3Lu...5 is
>> also a range.  0x3e22.f5p6fi is a valid floating-point number.  And
>> still, regexps don't nest.  Don't you want to highlight DDoc sections
>> and macros?
> 
> That would be nice as well, as would being able to do things with 
> Doxygen comments.  But let's not try to run before we can walk.

This assumes that TextPad could run at some point.  ;)  This is exactly
where I'm sceptical.  I think that when it runs it'll have so many weird
rules and settings that it won't be fun anymore.  And they won't be
powerful enough for anything authors didn't consider anyway.


Re: Notepad++

2009-08-15 Thread Sergey Gromov
Sat, 15 Aug 2009 01:36:26 +0100, Stewart Gordon wrote:

> Sergey Gromov wrote:
>> 
>> "foo
>> bar"
> 
> So there is a problem if the highlighter works by matching regexps on a 
> line-by-line basis.  But matching regexps over a whole file is no harder 
> in principle than matching line-by-line and, when the maximal munch 
> principle is never called to action, it can't be much less efficient. 
> (The only bit of C or D strings that relies on maximal munch is octal 
> escapes.)

Highlighting the whole file every time a charater is typed is slow.
Scintilla doesn't do that.  It provides the lexer with a range of
changed lines.  The lexer is then free to choose a larger range if it
cannot deduce context from the initial range.  I tried to ignore this
range and re-highlight the whole file in my lexer.  The performance was
unacceptable.

>> Then you want to highlight string escapes and probably format
>> specifiers.  Therefore you need not simple regexps but hierarchies of
>> them, and also you need to know where *internals* of the string start
>> and end.
> 
> Let's just concentrate for the moment on the simple process of finding 
> the beginning and end of a string.  Here's a snippet of a TextPad syntax 
> file:
> 
> StringsSpanLines = Yes
> StringStart = "
> StringEnd = "
> StringEsc = \
> 
> A possible snippet of lexer code to handle this (which FAIK might be 
> [...]

Sure, TextPad uses a dozen of simple hacks specific to lexing
programming languages.  They're ad-hoc and they're limited to exactly
what TextPad authors thought were important.

Regexps is a different approach.  They are more generic but are limited,
too, because they're slow and don't nest naturally.  Slow means they
must try to re-color as little lines as possible.  Not nestable means
you need to invent some framework around regexps which is another sort
of description language.  If you implement the former naively and ignore
the latter you'll get what presumably N++ has: not a very powerful
system.

It's actually trivial* to implement a lexer for Scintilla which would
work exactly as TextPad does, including use of the same configuration
files.

* That is, if you know exactly how TextPad works.

>> And these are only strings.  Try to write regexp which treats .__15 as
>> number(.__15), .__foo as operator(.), ident(__foo), and 2..3 as
>> number(2), operator(..), number(3).
> 
> 
> We'd need many regexps to handle all possible cases, but a possible set 
> to cover these cases and a few others (listed in a possible order of 
> priority) is:
> 
> \._*[0-9][0-9_]*
> ([1-9][0-9]*)(\.\.)
> [0-9]+\.[0-9]*
> [1-9][0-9]*
> \.\.
> \.
> [a-zA-Z_][a-zA-Z0-9_]*

Basically yes, but they're going to be much more complex.  3Lu...5 is
also a range.  0x3e22.f5p6fi is a valid floating-point number.  And
still, regexps don't nest.  Don't you want to highlight DDoc sections
and macros?


Re: Notepad++

2009-08-14 Thread Sergey Gromov
Thu, 13 Aug 2009 22:57:24 +0100, Stewart Gordon wrote:

> Sergey Gromov wrote:
>> Well I think it's hard to create a regular expression engine flexible
>> enough to allow arbitrary highlighting.
> 
> I can't see how it can be at all complicated to find the beginning and 
> end of a C string or character literal.
> 
> This (Posix?) regexp
> 
> "(\\.|[^\\"])*"
> 
> works as I try (though not in the tiny subset of Posix regexps that N++ 
> understands).  But that's an aside - you don't need regexps at all to 
> get it working at this basic level, only a rudimentary concept of escape 
> sequences.
> 
>> I think the best such engine
>> I've seen was Colorer by Igor Russkih, and even there I wasn't able to
>> express D's WYSIWYG or delimited strings.  You need a real programming
>> language for that.
> 
> For WYSIWYG strings, all that's needed is a generic highlighter that 
> supports:
> - the aforementioned string escapes
> - multiple types of string literals distinguished by whether they 
> support string escapes, and not just delimiters
> 
> TextPad's syntax highlighting engine manages 2/3 of this without any 
> regexps (or anything to that effect).  That said, I've just found that 
> it can do a little bit of what remains: I can make it do `...` but not 
> r"..." at the expense of distinguishing string and character literals.
> 
> But token-delimited strings are indeed more complex to deal with.  (How 
> many people do we have putting them to practical use at the moment, for 
> that matter?)

Well, you can write a regexp to handle a simple C string.  That is, if
your regexp is matched against the whole file, which is usually not the
case.  Otherwise you'll have troubles with C string:

"foo\
bar"

or D string:

"foo
bar"

Then you want to highlight string escapes and probably format
specifiers.  Therefore you need not simple regexps but hierarchies of
them, and also you need to know where *internals* of the string start
and end.

Then you have r"foo" which probably can be handled with regexps.

Then you have q"/foo/" where "/" can be anything.  Still can be handled
by extended regexps, even though they won't be regular expressions in
scientific sense.

Then you have q"{foo}" where "{" and "}" can be any of ()[]<>{}.
Regexps cannot translate while substituting, so you must create regexps
for all possible parens.

And of course q"BLAH
whatever BLAH here
BLAH", well, probably nice for help texts.

And these are only strings.  Try to write regexp which treats .__15 as
number(.__15), .__foo as operator(.), ident(__foo), and 2..3 as
number(2), operator(..), number(3).

> Scintilla's definition of a plugin is confusing - normally plugins are 
> things that can be dynamically loaded at runtime, rather than having to 
> compile them in.  If only

I'm not sure they call them "plugins".  They're lexer modules made so
that lexer is relatively easily extendable.


Re: Notepad++

2009-08-12 Thread Sergey Gromov
Wed, 12 Aug 2009 21:35:02 -0500, Andrei Alexandrescu wrote:

> Sergey Gromov wrote:
>> 2.  Lexers are written in C++ and interface with the rest of Scintilla
>> via C++ classes.  Therefore if a field is added or removed anywhere, or
>> if you use a different compiler to build your DLL than that used to
>> build Scintilla, you'll get GPF, or worse.
> 
> If they use binary interfacing with virtual functions a la COM's
> binary standard, then field presence shouldn't matter.

They don't, unfortunately.  Every lexer defines a static instance of a
LexerModule class.  The coloring function receives a reference to an
Accessor class.  They're full-blown classes, with fields and stuff.

> Also, most compilers on Windows respect the basic ABI. No?

Even though they don't use inheritance, and therefore most compilers
will likely build identical data layouts for them, there is still zero
compatibility between different versions of those classes.


Re: Notepad++

2009-08-12 Thread Sergey Gromov
Thu, 13 Aug 2009 01:40:47 +0100, Stewart Gordon wrote:

> Sergey Gromov wrote:
>> Wed, 12 Aug 2009 18:12:41 +0100, Stewart Gordon wrote:
> 
>> Scintilla uses plugins to highlight source.  These plugins are written
>> in C++ and have almost full access to the buffer so the highlighter code
>> may be arbitrarily complex.  I actually wrote such a plugin to highlight
>> D a while back:
>> 
>> http://dsource.org/projects/scrapple/browser/trunk/scilexer
> 
> "1.  If you have SciTE 1.76 for Windows installed simply replace
> SciLexer.dll and d.properties with the supplied files.
> 
> 2.  If you wish to build Scintilla from source:"
> 
> Can it be used in Scintilla-based editors besides SciTE short of 
> acquiring the whole Scintilla source and rebuilding it?

There are two problems at least:

1.  SciLexer.dll contains *all* of the built-in lexer modules.
Replacing your DLL with another version will remove any extra lexers
which 3rd party put there, like an XML-configurable lexer in case of
Notepad++.

2.  Lexers are written in C++ and interface with the rest of Scintilla
via C++ classes.  Therefore if a field is added or removed anywhere, or
if you use a different compiler to build your DLL than that used to
build Scintilla, you'll get GPF, or worse.

Good news is that Notepad++ is on SourceForge so that the "from source"
way is at least possible.

> For the record, there's a SciLexer.dll in my Notepad++ dir, but no 
> d.properties to be found.  The SciLexer.dll reports itself as file 
> version 1.7.8.0, product version 1.78.  So maybe the question is of what 
> effect replacing it with a fork of version 1.76 would have.  (Do SciTE 
> versions correspond directly to Scintilla versions?)

Yes, SciTE versions seem to be in sync with Scintilla versions.

>> It seems like Notepad++ developers added their own highlighter plugin
>> which takes userDefineLang.xml as its configuration.  Such a
>> configurable plugin is presumably much less flexible than pure C++
>> implementation for a particular language.  It's very likely that PHP
>> highlighter is written in C++ and comes bundled with Scintilla.
> 
> It puzzles me that they didn't make this plugin powerful enough to 
> highlight the language it (and indeed the whole of Notepad++) is written 
> in.  Even more so considering the sheer number of C-like languages out 
> there, which people are likely to want to use N++ to write.

Well I think it's hard to create a regular expression engine flexible
enough to allow arbitrary highlighting.  I think the best such engine
I've seen was Colorer by Igor Russkih, and even there I wasn't able to
express D's WYSIWYG or delimited strings.  You need a real programming
language for that.

---

I've just had a look at Notepad++ sources.  The Scintilla they use
contains Scintilla's built-in D lexer.  I think it's just not
configured.  SciTE uses *.properties files to configure stuff.
Notepad++ uses XML files for the same purpose.  I think it's all in
langs.model.xml.  My current idea is to take d.properties from the
corresponding release of SciTE and try to translate it into the
langs.model.xml format.  I'll probably try it later when I have time.

Of course it would be nice to replace the original D lexer with mine.
Or, even better, to ask Scintilla developers to include my lexer into
the official bundle.  May be worth a try.


Re: Properties, opIndex, and expression rewriting.

2009-08-12 Thread Sergey Gromov
Tue, 11 Aug 2009 22:15:15 -0400, Chad J wrote:

>> I've noticed an optimization which reduces number of calls to a getter.
>> I think you shouldn't do that: you should call getter as many times as
>> the expression suggests, and leave the rest to the optimizer.
> 
> It's not so much an optimization.
> 
> I removed those extra calls because it would create an asymmetry between
> how many times the getter is called and how many times the setter is
> called.  I suppose it could be argued that the extra setter calls should
> be left in as well, and maybe that would be alright.  To be honest, I'm
> not too entirely sure how to deal with that.

I think it's a matter of definition.  Try to define the rewriting
behavior, in English, as simply and unambiguous as possible: how many
times getters and setters are called, and in which order.  I'm sure this
will filter away many behaviors as unpredictable.  Then you say that
compiler may optimize some calls if it can guarantee the same result and
order of side effects.  Then you make a straight-forward implementation
of your specification.  Then you see what you can do about
optimizations.

Sorry if it's all obvious.  I didn't mean to lecture you, honestly.


Re: Notepad++

2009-08-12 Thread Sergey Gromov
Wed, 12 Aug 2009 18:12:41 +0100, Stewart Gordon wrote:

> What's the best anybody's managed to get Notepad++ to syntax-highlight 
> D?  (I'm on version 5.4.5, if that makes a difference.)
> 
> My userDefineLang.xml file is as given here
> http://www.prowiki.org/wiki4d/wiki.cgi?EditorSupport/NotepadPlus
> (note that I've fixed a few errors I've no idea how got there).
> 
> Notepad++ does a good job of syntax-highlighting PHP files, whose 
> syntactic structure is more complex than that of D.  So clearly, 
> Notepad++ is a powerful syntax-highlighter (or Scintilla is, whatever). 
>   However, at the moment I can't even seem to get it up to C standard! 
> (Can anybody find a full reference of the userDefineLang.xml format, for 
> that matter?)

Scintilla uses plugins to highlight source.  These plugins are written
in C++ and have almost full access to the buffer so the highlighter code
may be arbitrarily complex.  I actually wrote such a plugin to highlight
D a while back:

http://dsource.org/projects/scrapple/browser/trunk/scilexer

It seems like Notepad++ developers added their own highlighter plugin
which takes userDefineLang.xml as its configuration.  Such a
configurable plugin is presumably much less flexible than pure C++
implementation for a particular language.  It's very likely that PHP
highlighter is written in C++ and comes bundled with Scintilla.


Re: Properties, opIndex, and expression rewriting.

2009-08-11 Thread Sergey Gromov
Tue, 11 Aug 2009 03:19:42 -0400, Chad J wrote:

> So, Walter, how about some expression rewriting logic to solve some of
> the problems with properties, opIndex, and related lvalueness stuff?
> 
> (I refer to the expression rewriting in the Wiki4D article on
> properties:
> http://prowiki.org/wiki4d/wiki.cgi?DocComments/Property#Semantic)
> 
> Syntax can be broached later.
> 
> I've also attached some D-like pseudocode of what I think such an
> expression rewriting algorithm would look like (propertyrewrite.d).  The
> other file is a potential test-case.  I used it to figure out what a
> trace of the algorithm might look like, and designed it accordingly.  If
> it can wait a few weeks, I might try to put it into dmd and write a
> patch.  I'll only do it if there's interest though.

It would be nice if you made a patch.  This way we could see for
ourselves if it worked and vote for it.

I've noticed an optimization which reduces number of calls to a getter.
I think you shouldn't do that: you should call getter as many times as
the expression suggests, and leave the rest to the optimizer.


Re: reddit.com: first Chapter of TDPL available for free

2009-08-10 Thread Sergey Gromov
Sun, 09 Aug 2009 16:10:38 -0500, Andrei Alexandrescu wrote:

> Michel Fortin wrote:
>> On 2009-08-09 14:10:10 -0400, Andrei Alexandrescu 
>>  said:
>> 
 But shouldn't they work with *ranges* in general, a string being only 
 a specific case?
>>>
>>> That's true as well! In my dreams, me and the famous actress... oh 
>>> wait, wrong dream. In my dreams, I eliminate std.string and put all of 
>>> its algorithms, properly generalized, in std.algorithm, to work on 
>>> more than just arrays, and more than just characters.
>> 
>> And what is preventing the dream from comming true, I mean, the one 
>> about string functions? Is there someone who doesn't want this?
> 
> 1. Time. 2. It would break a lot of code that uses strings (I know, not 
> a very strong argument.) Time is the main issue.

std.string could stay as a compatibility wrapper around std.algorithm.
Though this puts even more stress on the "Time" concern.


Re: proposed syntax change

2009-08-10 Thread Sergey Gromov
Fri, 07 Aug 2009 17:02:33 -0700, Robert Jacques wrote:

>> Moreover compiler intrinsics are
>> functions which compiler recognizes and treats specially, usually by
>> replacing them with a single processor instruction.
> 
> We weren't discussing implementation with intrinsics, but as with a  
> standard library function.

Intrinsics were Yigal's point which he made twice:

Thu, 06 Aug 2009 23:34:21 +0300, Yigal Chripun wrote:
> auto f = std.math.div(5, 2); // intristic that does integer division

Fri, 07 Aug 2009 11:22:31 +0300, Yigal Chripun wrote:
> you've ignored case f which seems to me the most important: instead of 
> currently 5/2 == 2 there should be a div intristic function such that 
> div(5, 2) == 2  and that intristic will be the appropriate ASM 
> instruction for integer division.

Well, he called them "intristics," bit it's easy to see what he actually
wanted to say.


Re: unittext extension proposal

2009-08-10 Thread Sergey Gromov
Sat, 08 Aug 2009 17:32:30 -0400, Jeremie Pelletier wrote:

> I just had an idea to help keep track of unittests, right now we're turning 
> on printf's at the beginning of a test to know which one fails, and adding 
> printfs everywhere quickly becomes redundant. Also if the test succeeds and 
> execution fails at some other point, the last printf is then misleading.
> 
> ---
> module sample;
> unittest("myTest") {}
> ---

Named unittests is a rather often requested feature.  Others also wanted
__UNITTEST__ to expand into a name of the current unittest.  Also a
'weak assert' was requested which tests and prints a message but delays
exit until the end of the current unit test.

Somebody should really write a DIP on this.


Re: T[new]

2009-08-10 Thread Sergey Gromov
Sun, 09 Aug 2009 13:29:21 -0700, Walter Bright wrote:

> D has a number of subtle problems (performance and semantic) that arise 
> when arrays are resized. The solution is to separate resizeable array 
> types from slices. Slices will retain the old:
> 
> T[] slice;
> 
> syntax. Resizeable arrays will be declared as:
> 
> T[new] array;

Good news.  I'm all for it.  The T[new] syntax is a bit... weird... bit
I'm OK with it as well.  Thanks!


Re: T[new]

2009-08-09 Thread Sergey Gromov
Mon, 10 Aug 2009 01:56:35 +0200, Michiel Helvensteijn wrote:

> Walter Bright wrote:
> 
>>> But I know, unique isn't easy to implement to fit all the use cases we'd
>>> like to solve. I'm just sharing a dream.
>> 
>> We explored unique at length, and trying to make it work would render
>> the rest of the language nearly unusably complex.
> 
> I've heard 'unique' mentioned on this group now and then. What does it mean
> in the context of programming languages?

Unique reference is a reference which is statically known to be the only
reference to the underlying data.  They have some interesting
properties:

- Modification of underlying data does not cause side effects
- Can be implicitly cast to immutable
- Can be implicitly cast to mutable

They prove to be rather tricky both to specify and to implement though.


Re: proposed syntax change

2009-08-07 Thread Sergey Gromov
Fri, 07 Aug 2009 13:47:31 -0700, Robert Jacques wrote:

> On Fri, 07 Aug 2009 12:03:43 -0700, Yigal Chripun   
> wrote:
> 
>> regarding the div() function above, I was thinking about using D's naked  
>> asm feature. From what little I know about this, the compiler doesn't  
>> generate the usual asm code for this sort of function to handle  
>> registers, stack, etc, and you're supposed to do everything yourself in  
>> asm.
> 
> IIRC naked asm only works for zero-argument and single arguments of size  
> 1,2 or 4 functions, which div is not.
> 
>> I don't think your comment above about the function call overhead  
>> applies if div is implemented in such a way but I'm no expert and  
>> someone more knowledgeable can shed more light on this. (Don?)
> 
> If you check the D ABI, one of the arguments must be passed on the stack,  
> the other in a specific register (EAX).
> http://www.digitalmars.com/d/2.0/abi.html
> So the backend can't do things like ECX = EBX / EDX. Instead it has to  
> save/restore whatever's in EAX, ECX and EDX before/after the div call.

Inlined functions become integral part of their outer functions and
therefore are not obliged to follow ABI.  They don't have prologues,
epilogues, call overhead, etc.  Moreover compiler intrinsics are
functions which compiler recognizes and treats specially, usually by
replacing them with a single processor instruction.


Re: Properties and Copy Constructors

2009-08-06 Thread Sergey Gromov
Thu, 06 Aug 2009 18:08:00 -0400, Chad J wrote:

> [snip]
> 
> The jist is that you have some value type like a Matrix or BigInt that
> might actually have memory allocated to it.  It is a value type though,
> so whenever it is copied, any memory allocated to it needs to also be
> copied and new memory allocated for the copy.
> 
> [snip]
> 
> Onwards!:
> 
> I really like Steven's suggestion, though it seems difficult to actually
> /do/.  Thus I feel this deserves to be broken down a bit more so that we
> can have our cake and eat it too.
> 
> I see two ways out of this dilemma:
> 1.  The property proxies these memory-conserving transactions.
> 2.  The getter doesn't /necessarily/ return a copy.  The setter also
> doesn't /necessarily/ create it's own copy.
> 
> Going down road (1) is tricky.  If we don't make this supremely easy to
> automate, then this will become a tedious C++-ism where any property
> ever that accesses a Matrix will have to implement the same biolerplate
> acquire/release over and over and over.  Yuck.  Even if the common cases
> are allowed to fall back to get/set, this is still yuck.  Still, there
> may be some way to automate this.  I'm just not clear what it is.
> 
> Option (2) is what I'm currently biased towards.  It also comes with
> caveats though:  if you choose to return a reference to the matrix, then
> without any guarantee that your reference is singular you will smack
> right into the aliasing problem.  Nonetheless, my cursory look at
> ref-returns seems to suggest they have this property of being singular
> in most cases.  Then we can have something like the following:
> 
> class Blah
> {
>   property foo
>   {
>   ref BigInt get() { ... }
>   ref BigInt set(ref BigInt m) { ... }
>   }
> 
>   // etc
> }
> 
> struct BigInt
> {
>   void swap( ref BigInt other )
>   {
>   // BigInt defines it's own swap internally.
>   }
> 
>   // etc
> }
> 
> void main()
> {
>   auto b1 = new Blah();
>   auto b2 = new Blah();
>   // Do things with b1 and b2.
> 
>   // Now we want to swap big integers for whatever reason.
>   b1.foo.swap(b2.foo);
> }
> 
> Now I'm assuming the ref return and ref passing of these BigInts doesn't
> invoke their copy-constructors.  Is there any reason this can't work?

Wouldn't it be better if BigInt implemented share-on-copy, copy-on-write
semantics?  This really boils down to a single reference counter within
BigInt's allocated data and working struct constructors/destructors.


Re: Naming things in Phobos - std.algorithm and writefln

2009-08-05 Thread Sergey Gromov
Wed, 05 Aug 2009 17:29:11 +1000, Daniel Keep wrote:

> Michel Fortin wrote:
>> In std.algorithm, wouldn't it be clearer if "splitter" was called
>> "splitLazily" or "splitLazy"? "splitter" is a noun, but as a function
>> shouldn't it be a verb. "makeSplitter" or "toSplitter" perhaps?
> 
> This is a specious argument.
> 
> splitter's only purpose is to return an instance of a Splitter struct.
> You can't call it "splitLazily" or "splitLazy" because that implies that
> the function is doing work, when it really isn't.

That's if you know how it works.

But if you just use these functions, it's not even remotely obvious what
the difference is, and the difference in naming is so subtle that many
people will be doomed to forever confuse these functions, myself
included.  I confuse getopt and getopts shell functions in the same way.
I simply can't remember which is which.


Re: DIP6: Attributes

2009-08-04 Thread Sergey Gromov
Tue, 04 Aug 2009 11:58:27 -0300, Ary Borenszweig wrote:

> Sergey Gromov wrote:
>> Tue, 04 Aug 2009 22:46:22 +1000, Daniel Keep wrote:
>> 
>>> Sergey Gromov wrote:
>>>> Tue, 04 Aug 2009 17:22:50 +1000, Daniel Keep wrote:
>>>>
>>>>> Don wrote:
>>>>>> ...
>>>>>>
>>>>>> A question: in C#/Java, can you have annotations on function pointer and
>>>>>> delegate declarations?
>>>>>>
>>>>>> void foo( int delegate(int) pure dg) {
>>>>>>   ...
>>>>>> }
>>>>>> What would this look like with annotations?
>>>>> Well, Java doesn't HAVE delegates and C# doesn't (AFAIK) allow you to
>>>>> define them inline; they have a special declaration syntax that can't be
>>>>> used in an expression.
>>>> C#:
>>>>
>>>> List ls;
>>>> ls.Sort((x, y) => y - x);
>>>>
>>>> or
>>>>
>>>> ls.Sort((x, y) => { int a; a = y; a -= x; return a; });
>>> That's not a delegate type, that's a delegate literal.
>> 
>> Sorry, you said: "C# doesn't ... allow you to define them (delegates)
>> inline".  Delegate literal *is* an inline definition of a delegate.
>> What you say now is that C# doesn't allow to define a delegate type
>> inside a function which is definitely true and is very annoying.
> 
> Have you seen the Func delegates? They are exactly for that.
> 
> The above example would be:
> 
> void foo(Func dg) { ... }

Func defines a delegate with one argument and a non-void return.  There
are lots of others like Action, Predicate, Comparator etc. which you
must either remember or look up every time you need a specific delegate
signature.


Re: DIP6: Attributes

2009-08-04 Thread Sergey Gromov
Tue, 04 Aug 2009 22:46:22 +1000, Daniel Keep wrote:

> Sergey Gromov wrote:
>> Tue, 04 Aug 2009 17:22:50 +1000, Daniel Keep wrote:
>> 
>>> Don wrote:
>>>> ...
>>>>
>>>> A question: in C#/Java, can you have annotations on function pointer and
>>>> delegate declarations?
>>>>
>>>> void foo( int delegate(int) pure dg) {
>>>>   ...
>>>> }
>>>> What would this look like with annotations?
>>> Well, Java doesn't HAVE delegates and C# doesn't (AFAIK) allow you to
>>> define them inline; they have a special declaration syntax that can't be
>>> used in an expression.
>> 
>> C#:
>> 
>> List ls;
>> ls.Sort((x, y) => y - x);
>> 
>> or
>> 
>> ls.Sort((x, y) => { int a; a = y; a -= x; return a; });
> 
> That's not a delegate type, that's a delegate literal.

Sorry, you said: "C# doesn't ... allow you to define them (delegates)
inline".  Delegate literal *is* an inline definition of a delegate.
What you say now is that C# doesn't allow to define a delegate type
inside a function which is definitely true and is very annoying.


Re: DIP6: Attributes

2009-08-04 Thread Sergey Gromov
Tue, 04 Aug 2009 17:22:50 +1000, Daniel Keep wrote:

> Don wrote:
>> ...
>> 
>> A question: in C#/Java, can you have annotations on function pointer and
>> delegate declarations?
>> 
>> void foo( int delegate(int) pure dg) {
>>   ...
>> }
>> What would this look like with annotations?
> 
> Well, Java doesn't HAVE delegates and C# doesn't (AFAIK) allow you to
> define them inline; they have a special declaration syntax that can't be
> used in an expression.

C#:

List ls;
ls.Sort((x, y) => y - x);

or

ls.Sort((x, y) => { int a; a = y; a -= x; return a; });


Re: property syntax strawman

2009-08-04 Thread Sergey Gromov
Tue, 4 Aug 2009 01:15:45 +0400, Sergey Gromov wrote:

> Mon, 03 Aug 2009 11:06:53 -0400, Steven Schveighoffer wrote:
> 
>> I just thought of another issue with property definitions.  How do you  
>> declare a property of an array?  Today it's:
>> 
>> char[] chomped(char[] input);
>> 
>> Note that any getter property contains an argument which is the object  
>> you're calling the property on (normally implied because the definition is  
>> inside an aggregate definition).  But with arrays it's explicit.
>> 
>> So how does this fit in Walter's proposed syntax?
>> 
>> char[] chomped {...}
>> 
>> Where does the input go?
> 
> I proposed a keyword, 'inject', a year ago.  Or it could be an
> annotation.  I suppose such a keyword might significantly simplify
> implmentation of external functions and properties:
> 
> @inject @property char[] chomped(char[] arr) {...}
> @inject void sort!(alias pred, T)(T[] arr) {...}
> 
> Though prepending 'this' to the first parameter may also work, C# style.

Or, this can work with Walter's syntax:

@extension!char[] char[] chomped {...}


Re: Iterators Must Go video online

2009-08-04 Thread Sergey Gromov
Mon, 03 Aug 2009 12:47:40 -0500, Andrei Alexandrescu wrote:

> A while ago I mentioned the video of my BoostCon keynote "Iterators Must 
> Go" will be soon available online. Here it is:
> 
> http://boostcon.blip.tv/
> 
> Andrei

Nice talk!  The "Try THAT with iterators, @"($#* !" part was especially
entertaining. XD

What I didn't get was why range.front is so much superior to *i.  At the
end of the day they're both just functions returning whatever they
please.


Re: Just a thought: read-only fields

2009-08-04 Thread Sergey Gromov
Mon, 3 Aug 2009 22:04:51 -0400, Nick Sabalausky wrote:

> It's been established in the recent epic-discussions on properties that one 
> of the biggest uses for properties is to implement publically read-only (but 
> privately-writable) fields. That got me thinking, why not actually have real 
> publically read-only fields instead of merely emulating them with 
> properties? They are, after all, a fairly common idiom.
> 
> // *Not* an actual syntax proposal, but just to get the idea across:
> 
> private @publicread int foo;
> 
> // The class sees it as "int", but everything else sees it as "const(int)"
> // ...or something like that...

Um... @publiconst? XD

or

private int foo;
public alias const foo foo;

or even

private public(const) int foo;

Weird...  OTOH this should be trivial from the implementation POV.  On
the even other hand this only worth considering if actual properties are
dropped because properties are more generic and you *can* implement a
read-only field with them.  Maybe some syntactic sugar is in order if it
really is such a common thing.


Re: DIP6: Attributes

2009-08-03 Thread Sergey Gromov
Mon, 03 Aug 2009 15:16:25 -0400, Yigal Chripun wrote:

> grauzone Wrote:
> 
>> yigal chripun wrote:
>>> this is a good start but as already noted by others, you can't specify 
>>> types with structs. we also can't use type tuples cause of the auto flatten 
>>> behavior. 
>> 
>> And why can't we use structs? Unless I've missed something, it wasn't 
>> explained in this thread.
> 
> how can you pass types as arguments to your annotation if that annotation is 
> a struct? 
> for instance, what would be the struct for:
>  @my_annotation(int, 4)

Perhaps @my_annotation!int(4)


Re: property syntax strawman

2009-08-03 Thread Sergey Gromov
Mon, 03 Aug 2009 11:06:53 -0400, Steven Schveighoffer wrote:

> I just thought of another issue with property definitions.  How do you  
> declare a property of an array?  Today it's:
> 
> char[] chomped(char[] input);
> 
> Note that any getter property contains an argument which is the object  
> you're calling the property on (normally implied because the definition is  
> inside an aggregate definition).  But with arrays it's explicit.
> 
> So how does this fit in Walter's proposed syntax?
> 
> char[] chomped {...}
> 
> Where does the input go?

I proposed a keyword, 'inject', a year ago.  Or it could be an
annotation.  I suppose such a keyword might significantly simplify
implmentation of external functions and properties:

@inject @property char[] chomped(char[] arr) {...}
@inject void sort!(alias pred, T)(T[] arr) {...}

Though prepending 'this' to the first parameter may also work, C# style.


Re: new DIP5: Properties 2

2009-08-02 Thread Sergey Gromov
Sun, 02 Aug 2009 01:13:45 -0700, Walter Bright wrote:

> Very sensible points.

I'm really glad I can help.


Re: new DIP5: Properties 2

2009-08-02 Thread Sergey Gromov
Sat, 01 Aug 2009 23:36:57 -0400, Robert Jacques wrote:

> On Sat, 01 Aug 2009 20:48:58 -0400, Andrei Alexandrescu  
>  wrote:
>> Sergey Gromov wrote:
>>> Fri, 31 Jul 2009 21:37:06 -0500, Andrei Alexandrescu wrote:
>>>
>>>> To clarify: if there was any extra checking by the compiler, any  
>>>> guarantee that the feature would provide at all, I'd be glad to pay  
>>>> the price of thinking more when putting together a design. But you  
>>>> want to define a language feature that allows people to require "()"  
>>>> or not as they please, and that's all. It's a frivolous detail to be  
>>>> spending time on when designing an API. I simply don't believe that's  
>>>> good language design.
>>>  That's not "all."  To me it's mostly maintainability.
>>>  If there is a property 'foo' and you allow to set it both as 'foo = 5'
>>> and 'foo(5)' then somebody *will* use the foo(5) form.  Making it hard,
>>> or even impossible for you, the maintainer, to switch from a property
>>> back to a regular field for 'foo'.
>>>  If you allow to call function 'bar()' both with and without  
>>> parentheses,
>>> and a project is maintained by more than one person, they *will* call it
>>> differently making the source look inconsistent.
>>>  Dropping the 'omittable parentheses' thing happens to solve these, and
>>> the delegate return problem, and helps to disambiguate words with
>>> overloaded meanings.
>>
>> Thanks for these great points. As an additional example, most ranges  
>> define the method
> 
> Great points?
> Sorry, but all it takes is one person to subclass and overload foo, and  
> then it can never be turned back into a field. That is, if you're worrying  
> about maintainability.

Yes, I agree, properties are still not fields, and subtle differences in
behavior may lead to problems when switching implementation.  One can
overload a getter, or take an address of a setter, or pass a field by
reference.

Though the less such differences exist, the less bugs you're going to
cause in user code when actually switching.  We can even avoid some of
these potential problems:

*  User cannot overload a property in a final class, or when getter and
setter are declared final.  Therefore it's up to an interface designer
whether they want to allow overloading

*  Taking a getter/setter address should not be allowed, at all

*  Passing a property by reference should only work for ref-returning
getters, and produce a nice compile-time error otherwise

If the last two were implemented then we'd be left with only one gotcha
which manifests itself at compile time, is trivial to fix, and may even
be resolved by compiler in the future---see discussions about functions
returning structs.

> As for source code consistency, I view no-(), () and not caring as part  
> whole code format/variable issue. I mean, code::block has 5 different  
> layout styles (+custom definitions). What about variable names, hmm?  
> e/empty/isEmpty/is_empty? I would think any project than can maintain code  
> consistency of those other issues, they can also manage ()/no-()/mixed.

This is exactly Nick's point: you have to establish yet another
arbitrary convention instead of relying on the language rules.  Sure
most of us are used to obeying such conventions but it would be better
not to compilcate them even more.


Re: property syntax strawman

2009-08-02 Thread Sergey Gromov
Sun, 02 Aug 2009 00:43:43 -0700, Walter Bright wrote:

> Having optional parentheses does lead to unresolvable ambiguities. How 
> much of a problem that really is is debatable, but let's assume it 
> should be resolved. To resolve it, a property must be distinguishable 
> from a regular function.
> 
> One way is to simply add a "property" attribute keyword:
>
> The problem is that:
> 
> 1. there are a lot of keywords already
> 2. keywords are global things
> 
> The alternative is to have a unique syntax for properties. Ideally, the 
> syntax should be intuitive and mimic its use. After much fiddling, and 
> based on n.g. suggestions, Andrei and I penciled in:
> 
>bool empty { ... }
>void empty=(bool b) { ... }
> 
> [snip]
> 
>bool empty{}

I don't like this part.  When I look at this syntax I think about weird
corner cases which will surface sooner or later.

You still didn't voice your opinion on annotations.  But if you do
consider them useful and think that they will get into the compiler
sooner or later, I propose this solution:

1.  Hack the front-end to allow '@' in *keywords*
2.  Add a "@property" keyword

This solution:

*  Cancels the "keywords are global" concern: @property can never
interfere with user-defined symbols
*  Does not add a keyword to the specs: @property being a keyword is
merely an implementation detail which goes away as soon as arbitrary
annotations are supported by the compiler
*  Implementation complexity is roughly the same as for simple keyword
addition which I believe is less complex than specialized syntaxes like
prop=()


Re: OS X Installer

2009-08-01 Thread Sergey Gromov
Sat, 1 Aug 2009 07:55:08 -0400, Michel Fortin wrote:

> On 2009-08-01 04:41:38 -0400, Anders F Björklund  said:
> 
>> Jacob Carlborg wrote:
>> 
 Speaking of that OS X DMD installer, are you sure installing it at
 /usr/share/dmd/ is a good idea? [...]
>>> I looked at a gdc installer and looked where it placed the compiler and 
>>> did the same. I don't know where it's best to place the compiler.
>> 
>> You can use /opt/dmd and /opt/dmd2, if you don't
>> want to use the regular file hierarchy in hier(7)
>> 
>> DMD = /opt/dmd2/osx/bin/dmd
>> 
>> Or you can use e.g. /usr/local/bin and rename to
>> dmd2 and dmd2.conf (which takes some trickery...)
>> 
>> DMD = dmd2
> 
> In hier(7), it says that "/usr/local" is for "executables, libraries, 
> etc. not included by the basic operating system", so I guess DMD fits 
> this quite well.
> 
> I'm preparing an installer for D for Xcode and made it install DMD at 
> /usr/local/dmd and /usr/local/dmd2, with symlinks at /usr/local/bin/dmd 
> (system-prefered version) /usr/local/bin/dmd1 (1.x) and 
> /usr/local/bin/dmd2 (2.x). This makes it easy to choose the version you 
> want within Xcode.
> 
> For some reasons, the symlinks works fine with Xcode. But they aren't 
> working from the command line (dmd complains that it can't find 
> object.o). I've made a small C program to replace the symlink:
> 
>   #include 
> 
>   int main(unsigned int argc, char **argv) {
>   argv[0] = "/usr/local/dmd/osx/bin/dmd";
>   execv("/usr/local/dmd/osx/bin/dmd", argv);
>   }
> 
> No more problem from the command line.

Here's a nice document about directory layout in UNIX-like OSes:

http://www.pathname.com/fhs/pub/fhs-2.3.html

I think MacOS should follow this layout at least in part.  In particular
/usr/local/ is used for locally installed packages which otherwise
respect the standard directory structure found in / or /usr/.  That is,
binaries go into /usr/local/bin/, libraries in /usr/local/lib/ etc.  If
a package wants to keep its own structure it's supposted to go into
/opt/, like /opt/dmd2/whatever.


Re: new DIP5: Properties 2

2009-08-01 Thread Sergey Gromov
Fri, 31 Jul 2009 21:37:06 -0500, Andrei Alexandrescu wrote:

> To clarify: if there was any extra checking by the compiler, any 
> guarantee that the feature would provide at all, I'd be glad to pay the 
> price of thinking more when putting together a design. But you want to 
> define a language feature that allows people to require "()" or not as 
> they please, and that's all. It's a frivolous detail to be spending time 
> on when designing an API. I simply don't believe that's good language 
> design.

That's not "all."  To me it's mostly maintainability.

If there is a property 'foo' and you allow to set it both as 'foo = 5'
and 'foo(5)' then somebody *will* use the foo(5) form.  Making it hard,
or even impossible for you, the maintainer, to switch from a property
back to a regular field for 'foo'.

If you allow to call function 'bar()' both with and without parentheses,
and a project is maintained by more than one person, they *will* call it
differently making the source look inconsistent.

Dropping the 'omittable parentheses' thing happens to solve these, and
the delegate return problem, and helps to disambiguate words with
overloaded meanings.


Re: new DIP5: Properties 2

2009-07-31 Thread Sergey Gromov
Fri, 31 Jul 2009 00:02:16 -0400, Benji Smith wrote:

> Nick Sabalausky wrote:
>> "Andrei Alexandrescu"  wrote in message 
>> news:h4lsuo$au...@digitalmars.com...
>>> For me, I get a breath of fresh air whenever I get to not write "()". I 
>>> can't figure how some are missing it.
>>>
>> 
>> Every time I call a parameterless function in D, I curse under my breath at 
>> how incredibly sloppy it is. Great, just what I need: Yet another thing that 
>> forces me to make the completely unnecessary choice between using something 
>> inconsistently or making up and sticking to a completely arbitrary 
>> convention that can't be enforced. Sloppy, sloppy, sloppy. Especially 
>> considering it's all for the sake of a "feature" that doesn't accomplish a 
>> damn thing, doesn't solve any problem, not even a trivial one, doesn't do 
>> anything but clutter the language. 
> 
> My thoughts exactly.

+1


Re: Some things to fix

2009-07-31 Thread Sergey Gromov
Fri, 31 Jul 2009 04:57:23 -0400, Sjoerd van Leent wrote:

> Robert Fraser Wrote:
> 
>> Ary Borenszweig wrote:
>>> 2. modifiers that don't make sense should be disallowed.
>> 
>> There's been wars about this one. IMO, this is a good thing for writing 
>> templated/generic code -- if a modifier only makes sense in one instance 
>> of a template, all the others should not be marked as errors.
>> 
>> I think _conflicting_ modifiers should be made an error, i.e. "public 
>> private int x;".
> 
> I disagree, what about:
> 
> public
> {
> .
> .
> .
> private
> {
> }
> .
> .
> .
> }
> 
> Perhaps a warning in obvious cases (public private) should be raised.

Even better:

public:
.
.
.
private:
.
.
.


Re: A simple rule

2009-07-31 Thread Sergey Gromov
Thu, 30 Jul 2009 21:57:33 +0200, downs wrote:

> 1) If it's a word, put it in the standard library.
> 2) Otherwise, put it in the compiler.
> 
> For example:
> 
> assert() -> library.
> complex -> library.
> void -> C-derived, compiler.
> real -> C-derived via long float, compiler.
> cfloat -> library.
> for -> compiler.
> foreach -> library.
> T[] -> compiler.
> T.dup, T.sort, T.reverse -> library.

This is one weird rule.  This is probably because I'm not a native
English speaker, but I fail to see why 'complex' and 'foreach' are words
but 'for' is not.  You probably need to clarify what a 'word' is.

Should all key /words/ go into the library?


Re: overloading functions against function templates

2009-07-31 Thread Sergey Gromov
Thu, 30 Jul 2009 14:09:21 -0700, Walter Bright wrote:

> Currently, that can't be done. But it would be good to get it in for D2. 
> The question is, what rule to use?
> 
> I suggest that:
> 
> 1. if any functions match, then overload functions the usual way
> 
> 2. if no functions match, then overload the function templates the usual way
> 
> Or reverse the priority of the two.
> 
> What do you think?

I think regular functions should go first.

Let's take 4 functions for example:

void foo(int);
void foo(long);
void foo(T)(T);
void foo(T : int)(T);

and call foo(5);

If regular functions go first, we can order ours by match quality:

void foo(int);  <= best
void foo(long);
void foo(T : int)(T);
void foo(T)(T); <= worst

That's OK, the worst match is the least specialized template.  But if we
consider templates first:

void foo(T : int)(T);   <= best
void foo(T)(T);
void foo(int);
void foo(long); <= worst

What I strongly dislike about this is that a generic, non-specialized
foo(T)(T) effectively hides any non-templated and obviously more
specialized regular functions.  I think this simply won't work.


Re: Properties: a.b.c = 3

2009-07-29 Thread Sergey Gromov
Wed, 29 Jul 2009 13:39:50 +1000, Daniel Keep wrote:

> Walter Bright wrote:
>> The issue is what if b is a property, returns a temporary object, and
>> that temp's .c field is uselessly set to 3?
>> 
>> It's a classic problem with properties that are implemented as functions.
>> 
>> I don't see how C#'s special property syntax adds any value for dealing
>> with this.
>> 
>> One thought I had was to simply disallow the '.' to appear after a
>> function style property.
> 
> Maybe the compiler could rewrite the above as:
> 
> auto t = a.b;
> t.c = 3;
> a.b = t;
> 
> Unless it can prove it doesn't need to.  Same solution as to the op=
> conundrum.

vote++

Though I'm not sure what to do with this:

void foo(ref int x) {
x++;
}
foo(a.b.c);

Probably it's not that hard anyway.  Perhaps it's enough to rewrite
property access every time a value-returning property is used as lvalue:

auto t = a.b;
foo(t.c);
a.b = t;


Re: Developing a plan for D2.0: Getting everything on the table

2009-07-28 Thread Sergey Gromov
Wed, 29 Jul 2009 00:42:31 +0100, Stewart Gordon wrote:

> Sergey Gromov wrote:
>> Mon, 27 Jul 2009 07:59:40 -0500, Andrei Alexandrescu wrote:
>> 
>>>> Is it appropriate to define multiple classes, structs, templates, etc 
>>>> within a single module? What considerations should inform the decision 
>>>> regarding the placement of module boundaries?
>>> I think it's appropriate because many pieces of functionality come as a 
>>> bundle. The rule of thumb is, module provides the functionality, and 
>>> it's up to the designer to decide what that entails.
>> 
>> That's the problem.  On one hand, it's desirable to see a module as a
>> functionality bundle.  On the other hand, module is the smallest
>> available unit of encapsulation.  That is, if you have a class and
>> change its private implementation, this may affect *anything* in the
>> same module.  Hence Tango's hundreds of modules in dozens of packages, I
>> think.
> 
> I guess that's meant to encourage you to keep your modules small enough 
> that you know what you're doing.

Yes you can do a finer-grained encapsulation, but then you end up
without "functionality bundle."  And even if you create a collective
import module I think there is no way to make it stand out as such.
Though this is no different from C.

> At the smallest level, it would be a matter of: If in C++ you would 
> declare Qwert to be a friend of Yuiop, then in D you put Qwert and Yuiop 
> in the same module.  You could implement the converse as well, but for a 
> bunch of small classes it usually isn't worth it.

This is understandable.

>> It also adds to the problem that most people familiar with OO paradigm
>> consider classes to be such encapsulation units.  Surprizes are
>> inevitable.
> 
> I once came up with the idea a 'veryprivate' protection attribute that 
> would do this, but I can't seem to find the post now.

I wonder how much code will break if "private" keyword becomes really
private.  You can always implement tight coupling with package
visibility which C++ lacks.


Re: Dynamic D Library

2009-07-28 Thread Sergey Gromov
Tue, 28 Jul 2009 21:01:33 + (UTC), BCS wrote:

> Reply to teo,
> 
>> On Mon, 27 Jul 2009 20:34:44 +, BCS wrote:
>> 
>>> Reply to teo,
>>> 
 I did some tests and here are the results: D cannot be used in
 Shared Objects. The only case that works is when no classes are
 exported and when there are no references to Phobos within the
 library.
 
>>> this works:
>>> 
>> it doesn't work with v2.031
>> 
>>> module test;
>>> int test1() { return 0; }
>> dmd complains:
>> 
>>> char[] test2() { return "hello world"; }
>>> 
>> test.d(3): Error: cannot implicitly convert expression ("hello world")
>> of type immutable(char)[] to char[]
>> 
>> when I change it to:
>> string test2() { return "hello world"; }
>> $ dmd main.d -L-L`pwd` -L-ltest
>> main.d(6): Error: undefined identifier test2
>> main.d(6): Error: function expected before (), not test2 of type int
>> main.d(7): Error: identifier 'C' is not defined
>> main.d(7): Error: C is used as a type
>> main.d(7): Error: new can only create structs, dynamic arrays or class
>> objects, not void's
>> main.d(7): Error: no property 'get' for type 'void'
>> main.d(7): Error: function expected before (), not __error of type int
> 
> That's not a SO realted problem. Try building it as a non-SO program, fix 
> any errors you get there and then go back to the SO version.
> 
> for starters try:
> 
> public string test2() { return "hello world"; }

Maybe "export string test2() {...}" ?

teo, such discussions belong in D.learn.


Re: Properties poll

2009-07-28 Thread Sergey Gromov
Tue, 28 Jul 2009 18:57:03 -0300, Ary Borenszweig wrote:

> Andrei Alexandrescu escribió:
>> Ary Borenszweig wrote:
>>> Actually it's not about properties, is about what "a.filter" and 
>>> "a.filter()" mean to you when you look at them. I used "filter" and 
>>> not "foo" because "foo" doesn't mean anything.
>>>
>>> Maybe the question should be other, maybe the answers too. Feel free 
>>> to propose other polls.
>>>
>>> http://poll.pollcode.com/Iy0
>> 
>> I'd find it very difficult to figure what the question is without the 
>> background of this lengthy discussion. I'm almost fearing I gave the 
>> wrong answer :o).
> 
> Regardless of the result, you can see the webpage chose red for the 
> first option and green for the last. You know what that means.

Yeah.  Red means real world.  Green...  There's no such pill.


Re: properties

2009-07-28 Thread Sergey Gromov
Tue, 28 Jul 2009 13:20:30 -0400, Steven Schveighoffer wrote:

> Let me come at another angle.  You can't view properties as some sort of  
> enforcement by the compiler.  The compiler is not guaranteeing that if you  
> call something without parentheses, it doesn't execute arbitrary code, it  
> has nothing to do with what the compiler guarantees.  But the *meaning*  
> that the author of the function wishes to convey is available via the  
> requirement of parentheses or lack thereof.  The author of the code is  
> saying "I wrote this function as if it were a field."

I think the reason is purely syntactical.  Specifically to distinguish
nouns from verbs.

Many English words can be used as both.  "Empty" may mean "contains
nothing" or "to throw everything away" and both meanings are equally
valid.  You need context to derive the correct meaning of a word.  You
always have such context in human language because of its nature.
Programming languages are much more formalized which robs you of
context.

Parentheses make a perfect syntactic convention for anybody familiar
with C family languages: verbs have parens, nouns (adjectives, adverbs)
don't.  Because functions do things but variables do not.  So when I
define "empty" as a property in C# I don't promise pure behavior or O(1)
complexity.  I simply state: "This *word* is not a verb. Read it
accordingly."  And it's immediately clear to me that "empty" is "nothing
inside" while "empty()" is "do cleanup".


Re: properties

2009-07-28 Thread Sergey Gromov
Tue, 28 Jul 2009 11:30:00 -0500, Andrei Alexandrescu wrote:

 The presence or absence of parens is a hard-coded accepted meaning of 
 field vs. function.
>>>
>>> I understand how some people want to derive meaning from obj.foo() 
>>> versus obj.foo. I think they shouldn't in D. I mean D has had for 
>>> years the behavior that you could drop the trailing empty parentheses.
>> 
>> And for years, there have been complaints about it.  This will 
>> continuously be a thorn in the side of D adoption until it is resolved.
> 
> Again, most complaints have been directed towards writeln = 5. I think 
> that's the major problem to be resolved.

I think it is mentioned more often because you tend to agree with it.
There are many more as valid arguments which you discard or ignore,
mainly maintainability.


Re: Developing a plan for D2.0: Getting everything on the table

2009-07-28 Thread Sergey Gromov
Mon, 27 Jul 2009 07:59:40 -0500, Andrei Alexandrescu wrote:

>> Is it appropriate to define multiple classes, structs, templates, etc 
>> within a single module? What considerations should inform the decision 
>> regarding the placement of module boundaries?
> 
> I think it's appropriate because many pieces of functionality come as a 
> bundle. The rule of thumb is, module provides the functionality, and 
> it's up to the designer to decide what that entails.

That's the problem.  On one hand, it's desirable to see a module as a
functionality bundle.  On the other hand, module is the smallest
available unit of encapsulation.  That is, if you have a class and
change its private implementation, this may affect *anything* in the
same module.  Hence Tango's hundreds of modules in dozens of packages, I
think.

It also adds to the problem that most people familiar with OO paradigm
consider classes to be such encapsulation units.  Surprizes are
inevitable.


Re: Reddit: why aren't people using D?

2009-07-27 Thread Sergey Gromov
Wed, 22 Jul 2009 23:10:53 +0200, Michiel Helvensteijn wrote:

> * Tuples (no dedicated syntax, no parallel assignment, no non-flattening
> tuples without workarounds, no returning tuples)

I'm planning to write a DIP on better tuple support.  Here is a brief
overview of my ideas.  I think I'll blog a bit more before filing an
actual DIP.

http://snakecoder.wordpress.com/2009/07/28/language-support-for-tuples-in-d


Re: Reddit: why aren't people using D?

2009-07-27 Thread Sergey Gromov
Sun, 26 Jul 2009 21:23:35 -0500, Andrei Alexandrescu wrote:

> Sergey Gromov wrote:
>> Fri, 24 Jul 2009 16:58:50 -0500, Andrei Alexandrescu wrote:
>> 
>>>>>> deterministic destructors,  arbitrary copy constructors, and optional
>>>>>> lack of default constructor.
>>>>> Struct have that except for default constructor. In D, currently default
>>>>> constructors cannot execute code. This is a limitation that we might
>>>>> need to address, although it has some advantages.
>>>> There are things that copy constructors can do that the post-blit
>>>> operator can't do.
>>> Yes, mostly wrong things. I think it would be a huge loss if D copied 
>>> C++'s model.
>> 
>> This means that structs cannot hold on external resources, ever:
>> 
>> struct RAII {...}
>> var a = RAII("foo");
>> var b = RAII("bar");
>> a = b; // you just leaked a and corrupted b
> 
> You may be making a confusion between assignment and copy construction.

Sure I'm confusing them, silly me.

The only thing copy-construction is useful for is implementing move
semantics, think std::auto_ptr.  Seems like everything else can be done
in post-blit.

The inability to overload opAssign(typeof(this)) is a blocker for robust
RAII though.


Re: Reddit: why aren't people using D?

2009-07-26 Thread Sergey Gromov
Fri, 24 Jul 2009 16:58:50 -0500, Andrei Alexandrescu wrote:

 deterministic destructors,  arbitrary copy constructors, and optional
 lack of default constructor.
>>> Struct have that except for default constructor. In D, currently default
>>> constructors cannot execute code. This is a limitation that we might
>>> need to address, although it has some advantages.
>> 
>> There are things that copy constructors can do that the post-blit
>> operator can't do.
> 
> Yes, mostly wrong things. I think it would be a huge loss if D copied 
> C++'s model.

This means that structs cannot hold on external resources, ever:

struct RAII {...}
var a = RAII("foo");
var b = RAII("bar");
a = b; // you just leaked a and corrupted b


Re: D compiler as a C++ preprocessor

2009-06-28 Thread Sergey Gromov
Sat, 30 May 2009 04:16:09 -0400, Dmitry Sychov wrote:

> Can D compiler be used only as a C++ preprocessor, that it to
> generate  C++ output (platform independent) to be later compiled via
> the target platform C++ compiler? 

I'm sure translation from D into C were discussed before, not even once,
as a means of diversifying the list of supported platforms.  The culprit
was exception handling.  The conversion to C++ were discussed too IIRC,
but not as enthusiastically for some reason.  I cannot think of any real
blockers for such a `preprocessor'.  Maybe forward references, but the
current D compiler has problems with them as well.


Re: assignment: left-to-right or right-to-left evaluation?

2009-06-21 Thread Sergey Gromov
Sat, 09 May 2009 11:43:09 -0500, Andrei Alexandrescu wrote:

> If we want to get rid of newID, we'd write:
> 
>writeln(dic.length, '\t', word);
>dic[word] = dic.length;
> 
> by the Python rule, and
> 
>writeln(dic.length, '\t', word);
>dic[word] = dic.length - 1;
> 
> by the C# rule.
> 
> What's best?

If you use the Python rule you can rewrite

dic[word] = dic.length;

as

dic.opIndexAssign(word, dic.length);

By the C# rule you cannot do without opIndexForAssignment sort of thing.
It's not a matter of best/worse IMO, it's a matter of feasible/not
feasible.


Re: demangle tool

2009-04-12 Thread Sergey Gromov
Fri, 10 Apr 2009 14:25:30 -0700, Andrei Alexandrescu wrote:

> Sergey Gromov wrote:
>> Thu, 09 Apr 2009 13:40:36 -0700, Andrei Alexandrescu wrote:
>> 
>>> The line wraps are all garbled, but you get the idea: all symbols quoted 
>>> `like this' have been demangled appropriately. Below is the source of 
>>> the demangle script:
>>>
>>> #!/home/andrei/bin/rdmd
>>> import std.algorithm, std.demangle, std.getopt, std.stdio;
>>>
>>> void main(string[] args)
>>> {
>>>  string lSep = "`", rSep = "'";
>>>  getopt(args, "lsep", &lSep, "rsep", &rSep);
>>>  foreach (line; stdin.byLine())
>>>  {
>>>  auto sym = find(line, lSep);
>>>  if (!sym.length)
>>>  {
>>>  writeln(line);
>>>  continue;
>>>  }
>>>  sym = sym[1 .. $];
>>>  auto before = line[0 .. $ - sym.length];
>>>  sym = sym[0 .. $ - find(sym, rSep).length];
>>>  auto after = line[before.length + sym.length .. $];
>>>  writeln(before, demangle(sym.idup), after);
>>>  }
>>> }
>> 
>> What happened to the range boolean operations, those
>> before/after/whatever?  Do you still plan to implement them?
> 
> Curiously, I didn't find a need for them in std.algorithm so far. I only 
> defined sameHead, and that's only to help a little improvement in the 
> bringToFront algorithm.

I asked because I thought that "blah[foo.length .. $ - bar.length]"
stuff wasn't very nice.  Compare:

sym.advance; // popFront, or sym[1 .. $]
auto s1 = line.before(sym);
auto s3 = find(sym, rSep);
writeln(s1, demangle(sym.before(s3).idup), s3);


Re: demangle tool

2009-04-10 Thread Sergey Gromov
Thu, 09 Apr 2009 13:40:36 -0700, Andrei Alexandrescu wrote:

> The line wraps are all garbled, but you get the idea: all symbols quoted 
> `like this' have been demangled appropriately. Below is the source of 
> the demangle script:
> 
> #!/home/andrei/bin/rdmd
> import std.algorithm, std.demangle, std.getopt, std.stdio;
> 
> void main(string[] args)
> {
>  string lSep = "`", rSep = "'";
>  getopt(args, "lsep", &lSep, "rsep", &rSep);
>  foreach (line; stdin.byLine())
>  {
>  auto sym = find(line, lSep);
>  if (!sym.length)
>  {
>  writeln(line);
>  continue;
>  }
>  sym = sym[1 .. $];
>  auto before = line[0 .. $ - sym.length];
>  sym = sym[0 .. $ - find(sym, rSep).length];
>  auto after = line[before.length + sym.length .. $];
>  writeln(before, demangle(sym.idup), after);
>  }
> }

What happened to the range boolean operations, those
before/after/whatever?  Do you still plan to implement them?


Re: why Unix?

2009-04-07 Thread Sergey Gromov
Tue, 07 Apr 2009 21:03:54 +0200, grauzone wrote:

>> I can log into ANY Linux, Solaris, BSD, OSX, etc system and have a 
>> reasonable /bin/sh that allows at least bourne shell functionality.  The 
>> same can't be said for almost any other scripting language you can throw 
>> at me.
> 
> Sure, /bin/sh is the least common denominator. But is there a UNIX that 
> can't run python?

Sure there is.  My external disk array runs one.  It's OS fits on a 16
MiB ram-drive, with 3 MiB free, with almost all the shell commands
implemented by an extremely stripped BusyBox.  Still I can telnet into
it and run scripts which Windows can only dream of.


Re: why Unix?

2009-04-07 Thread Sergey Gromov
Tue, 07 Apr 2009 19:06:04 -0400, Steven Schveighoffer wrote:

> On Tue, 07 Apr 2009 18:48:19 -0400, Sergey Gromov   
> wrote:
> 
>> Using Cygwin tools is a pain because Cygwin emulates a Unix-like file
>> system view while other tools produce and expect native Windows paths.
> 
> just as an aside, have you looked at cygwin's cygpath tool?  Not a  
> complete solution, but it certainly helps.

Great, I didn't know such tool existed.  Thanks!

Though with as limited stdout capture support as in .BAT files it's a
pain anyway.


Re: why Unix?

2009-04-07 Thread Sergey Gromov
Mon, 06 Apr 2009 20:19:40 -0400, Jussi Jumppanen wrote:

>> As a commandline utility, it can be combined with other stuff such 
>> as ls, sort, grep, sed, awk, etc... I don't know if I'd start there 
>> though...
> 
> Replace ls with dir, download the Win32 version of grep, sed, awk 
> and you can run all those tools just fine from the Windows command 
> line, or from within any decent editor.
> 
> You don't have to go to Unix to find the command line.

Windows shell (cmd) sucks.  And Windows scripting (BAT-files) suck.
Using Cygwin tools is a pain because Cygwin emulates a Unix-like file
system view while other tools produce and expect native Windows paths.
And FAR, being the best shell available, still doesn't support path
auto-completion while even standard CMD does.

Windows is my main development platform, and it drives me nuts.  I'd
move to Linux but I'm afraid of little important things getting in the
way, like a requirement to use Outlook for my corporate mail, and Flash
CS4 for development.  Even if it's possible I can't afford being
semi-paralyzed for at least a couple of weeks while all those nuances
are being sorted out.


Re: The new, new phobos sneak preview

2009-04-07 Thread Sergey Gromov
Mon, 06 Apr 2009 14:23:20 -0700, Andrei Alexandrescu wrote:

> I just committed all of Phobos into svn on dsource.org. That is not an
> official release and has known and unknown bugs, limitations, and
> rhinodemons. I expect some ripples before we stabilize, but when we will
> we'll stabilize at a higher potential.

Looks scary, but great. :D

-

* There are two std.regexp and no std.regex in the package list
* std.range.advance docs mention 'drop' instead of 'advance'
* std.range.retreatN docs metnion 'advanceRight' instead of 'retreatN'


Re: X11 binding, XGetWindowProperty, and different behaviour for similar code between D and C++ (D fails)

2009-04-02 Thread Sergey Gromov
Fri, 03 Apr 2009 13:55:12 -0400, Simon Gomizelj wrote:

> For curiousities sake, is there any interest to adding my bindings to any  
> standard library? I know bindings for X.h and Xlib.h exist, but I created  
> a more complete set: X.d, Xlib.d, Xatom.d, Xproto.d, Xregion.d Xutil.d and  
> Xinerama.d and xf86vmode.h

If you have a dsource account, you automatically have write access to
the bindings project.  Simply update it if you think your version is
better.


Re: Declaring Ref Variables Inside Function Calls

2009-03-31 Thread Sergey Gromov
Tue, 31 Mar 2009 18:55:10 -0700, Andrei Alexandrescu wrote:

> Sergey Gromov wrote:
>> Tue, 31 Mar 2009 18:38:35 -0700, Andrei Alexandrescu wrote:
>> 
>>> Sergey Gromov wrote:
>>>> Comma expression is not ambiguous.  It's a comma expression.  Renaming
>>>> it into a tuple constructor expression does not add any ambiguity.
>>>> Parentheses here are only required to separate the comma expression from
>>>> an assignment expression which otherwise would become a part of comma
>>>> expression.  Sure there are problems with making tuples first-class, but
>>>> this is certainly not one of them.
>>> I don't understand. So are you suggesting that the comma expression gets 
>>> sacked?
>> 
>> Now comma expression drops all the results but the last one.  You lose
>> nothing by making it keep other results as well.  Then you can make it
>> extract the last element as a result of an implicit cast.
> 
> That won't work because you'd paste C code into your D code and it'll
> compile with different results.

It should be possible to make the C pattern work as expected.  I need to
think about this in more detail to be sure.

>>>> I'm putting together a blog post about a possible design of first-class
>>>> tuples in D.  Hope it won't take too long.
>>> What does "first-class" mean?
>> 
>> First-class values, like, native, with built-in compiler support.
> 
> A tuple is a parameterized type, not a value. And first-class doesn't 
> mean with built-in compiler support.

Probably I've mis-used the first-class thing here.


Re: Declaring Ref Variables Inside Function Calls

2009-03-31 Thread Sergey Gromov
Tue, 31 Mar 2009 18:38:35 -0700, Andrei Alexandrescu wrote:

> Sergey Gromov wrote:
>> Comma expression is not ambiguous.  It's a comma expression.  Renaming
>> it into a tuple constructor expression does not add any ambiguity.
>> Parentheses here are only required to separate the comma expression from
>> an assignment expression which otherwise would become a part of comma
>> expression.  Sure there are problems with making tuples first-class, but
>> this is certainly not one of them.
> 
> I don't understand. So are you suggesting that the comma expression gets 
> sacked?

Now comma expression drops all the results but the last one.  You lose
nothing by making it keep other results as well.  Then you can make it
extract the last element as a result of an implicit cast.

Disallowing the C-style usage of comma expression is also an option.

>> I'm putting together a blog post about a possible design of first-class
>> tuples in D.  Hope it won't take too long.
> 
> What does "first-class" mean?

First-class values, like, native, with built-in compiler support.


Re: Declaring Ref Variables Inside Function Calls

2009-03-31 Thread Sergey Gromov
Tue, 31 Mar 2009 17:54:30 -0700, Andrei Alexandrescu wrote:

> Bill Baxter wrote:
>> On Wed, Apr 1, 2009 at 6:16 AM, Andrei Alexandrescu
>>  wrote:
>>> Bill Baxter wrote:
>>>> On Wed, Apr 1, 2009 at 5:03 AM, Sergey Gromov 
>>>> wrote:
>>>>> Tue, 31 Mar 2009 12:18:21 -0700, Andrei Alexandrescu wrote:
>>>>>
>>>>>> Jarrett Billingsley wrote:
>>>>>>> On Tue, Mar 31, 2009 at 1:32 PM, Andrei Alexandrescu
>>>>>>>  wrote:
>>>>>>>> Jarrett Billingsley wrote:
>>>>>>>>> 2009/3/30 dsimcha :
>>>>>>>>>> // How it works now:
>>>>>>>>>> uint foo;
>>>>>>>>>> string bar;
>>>>>>>>>> unpack(foo, bar) = someFunction();
>>>>>>>>>>
>>>>>>>>>> // vs. how I want it to work:
>>>>>>>>>> unpack(auto foo, auto bar) = someFunction();
>>>>>>>>> Cute, but uh, I'd much rather see tuples just be returnable.
>>>>>>>> They are.
>>>>>>> template Tuple(T...)
>>>>>>> {
>>>>>>> alias T Tuple;
>>>>>>> }
>>>>>>>
>>>>>>> Tuple!(int, float) foo()
>>>>>>> {
>>>>>>> return Tuple!(3, 4.5);
>>>>>>> }
>>>>>>>
>>>>>>> foo.d(10): Error: functions cannot return a tuple
>>>>>>>
>>>>>>> Unless you're using some prerelease compiler, they are not.
>>>>>> import std.typecons;
>>>>>>
>>>>>> Tuple!(int, float) foo()
>>>>>> {
>>>>>> return tuple(2, 4.5);
>>>>>> }
>>>>>>
>>>>>> The addition of the alias this feature and of constructor templates
>>>>>> makes std.typecons.Tuple even better.
>>>>>>
>>>>>> Andrei
>>>>> Unfair---std.typecons.Tuple is actually a struct!
>>>>>
>>>>> Well, basically struct is a run-time tuple, anyway.
>>>>>
>>>>> I think that all the buzz around "actual tuple support" boils down to
>>>>> requests for syntax sugar for construction and decomposition of
>>>>> anonymous structs.  While typecons.Tuple is sorta OK for construction,
>>>>> things are still pretty ugly on the "decomposition" end.
>>>> Right.  In my ideal world I could use tuples like this:
>>>>
>>>> (int,float) a;
>>> That sucks. Is int(int, float) a function type or a juxtaposition of two
>>> types?
>> 
>> I should say that by "in my ideal world" what I meant was "forgetting
>> about all the baggage that D already has for a moment and starting
>> from a more or less clean slate".   Things like the useless comma
>> operator.
>> 
>> But isn't a juxtaposition of two types a syntax error?  So the above
>> would be a function type, not a juxtaposition of two types.
>> 
>>> Is (A, B) an expression or a type? And so on.
>> 
>> How does that differ from asking   "Is A an expression or a type?"
>> 
>> If A and B are types, then (A,B) is a type.
>> 
>>>> (int,float) z = returns_tuple();
>>> Blech.
>> 
>> Blech to that, but you like
>>Tuple!(int,float) z = returns_tuple();
>> correct?
>> 
>>>> (int x, float y) = returns_tuple();
>>> I'd like that too, but what we should have is make any definition an
>>> expression.
>>>
>>>> auto tup = (2, 3.4);
>>> Belch (sic).
>> 
>> Belch to that, but again, you're saying this is great
>>auto tup = Tuple!(2, 3.4);
>> correct?
>> 
>> --bb
> 
> Yah, sorry for the dismissive comments... what I meant was that the 
> literal you suggested is so ambiguous grammatically, it's a 
> non-improvement compared to just writing Tuple! there.

Comma expression is not ambiguous.  It's a comma expression.  Renaming
it into a tuple constructor expression does not add any ambiguity.
Parentheses here are only required to separate the comma expression from
an assignment expression which otherwise would become a part of comma
expression.  Sure there are problems with making tuples first-class, but
this is certainly not one of them.

I'm putting together a blog post about a possible design of first-class
tuples in D.  Hope it won't take too long.


Re: Declaring Ref Variables Inside Function Calls

2009-03-31 Thread Sergey Gromov
Tue, 31 Mar 2009 12:18:21 -0700, Andrei Alexandrescu wrote:

> Jarrett Billingsley wrote:
>> On Tue, Mar 31, 2009 at 1:32 PM, Andrei Alexandrescu
>>  wrote:
>>> Jarrett Billingsley wrote:
 2009/3/30 dsimcha :
> // How it works now:
> uint foo;
> string bar;
> unpack(foo, bar) = someFunction();
>
> // vs. how I want it to work:
> unpack(auto foo, auto bar) = someFunction();
 Cute, but uh, I'd much rather see tuples just be returnable.
>>> They are.
>> 
>> template Tuple(T...)
>> {
>>  alias T Tuple;
>> }
>> 
>> Tuple!(int, float) foo()
>> {
>>  return Tuple!(3, 4.5);
>> }
>> 
>> foo.d(10): Error: functions cannot return a tuple
>> 
>> Unless you're using some prerelease compiler, they are not.
> 
> import std.typecons;
> 
> Tuple!(int, float) foo()
> {
>  return tuple(2, 4.5);
> }
> 
> The addition of the alias this feature and of constructor templates 
> makes std.typecons.Tuple even better.
> 
> Andrei

Unfair---std.typecons.Tuple is actually a struct!

Well, basically struct is a run-time tuple, anyway.

I think that all the buzz around "actual tuple support" boils down to
requests for syntax sugar for construction and decomposition of
anonymous structs.  While typecons.Tuple is sorta OK for construction,
things are still pretty ugly on the "decomposition" end.


Re: Eric S. Raymond on GPL and BSD licenses. & Microsoft coming to Linux

2009-03-31 Thread Sergey Gromov
Tue, 31 Mar 2009 05:15:24 -0400, Kagamin wrote:

> Sergey Gromov Wrote:
> 
>>> This is a lie. There is just no way for cigarette-chomping executives to 
>>> not know, what are licenses and how they work.
>> 
>> Sure they know.  They know too well that one wrong step, one ignorant
>> developer, and they may kiss good-bye to their precious intellectual
>> property.
> 
> Your guess is wrong and you're far from their level :)

Oh you know me too well.  Probably you also know the color of my
underwear.  I give up.


Re: Eric S. Raymond on GPL and BSD licenses. & Microsoft coming to Linux

2009-03-31 Thread Sergey Gromov
Mon, 30 Mar 2009 18:09:21 -0400, Steven Schveighoffer wrote:

> On Mon, 30 Mar 2009 18:03:02 -0400, Bill Baxter  wrote:
> 
>> On Tue, Mar 31, 2009 at 6:36 AM, Steven Schveighoffer
>>  wrote:
>>> On Mon, 30 Mar 2009 16:00:02 -0400, Yigal Chripun 
>>> wrote:
>>>
 people in the US sued MacDonald's because their coffee was hot (and  
 they
 even won the case!). other people sued a company since their peanuts
 contains nuts.
>>> [...]
>>> Other examples of lawsuits are definitely frivolous.  If that peanut  
>>> case is
>>> true, I'd use that one instead (it sounds too ridiculous to be true, I'd
>>> appreciate a citation).
>>
>> Peanuts aren't actually nuts, you know.  They're legumes.  So there
>> might well be a case where the lable said "100% peanuts" and someone
>> allergic to nuts ate up, knowing that peanuts aren't in fact nuts.
> 
> If someone was allergic to nuts, and they are going around eating peanuts  
> because technically they aren't nuts, I'd say they were in fact nuts :)
> 
> I'd be hugely hugely surprised if any jury awarded a judgement based on  
> that.

I'd expect an allergic person to be very well aware of what's dangerous
to them, and therefore to know exactly the difference between nuts and
peanuts.  People tend to know a lot of things in the areas of their
interest, for whatever reasons the interest is.


Re: Eric S. Raymond on GPL and BSD licenses. & Microsoft coming to Linux

2009-03-30 Thread Sergey Gromov
Mon, 30 Mar 2009 05:03:49 -0400, Kagamin wrote:

> Georg Wrede Wrote:
>  
>> Seems BSD should be Our Way:
>> 
>> [...] has a downside, the downside is that people, especially lawyers, 
>> especially corporate bosses look at the GPL and experience fear. Fear 
>> that all of their corporate secrets, business knowledge, and special 
>> sauce will suddenly be everted to the outside world by some inadvertent 
>> slip by some internal code. I think that fear is now costing us more 
>> than the threat[...]
> 
> This is a lie. There is just no way for cigarette-chomping executives to not 
> know, what are licenses and how they work.

Sure they know.  They know too well that one wrong step, one ignorant
developer, and they may kiss good-bye to their precious intellectual
property.


Re: Keeping a list of instances and garbage-collection

2009-03-30 Thread Sergey Gromov
Sun, 29 Mar 2009 17:42:48 -0400, Chad J wrote:

> Simon TRENY wrote:
>> Hello,
>> 
>> I have a class "A" and I'd like to keep a list of all the created instances 
>> of this class. To do that, I have a static List!(A) in the A class and, in 
>> the constructor, I add each new instance to this list. This gives me the 
>> following code:
>> 
>> class A {
>>private static List!(A) s_instances;
>> 
>>public this() {
>>   s_instances.add(this);
>>}
>> 
>>public ~this() {
>>   s_instances.remove(this);
>>}
>> 
>>public static void printAll() {
>>   foreach (A instance; s_instances)
>>  print(instance.toString());
>>}
>> }
>> 
>> But then, since all the instances are referenced by the static list, they 
>> are never garbage-collected, which could be a problem. In some other 
>> languages, this can be solved using weak references, but I haven't found any 
>> informations about using weak references in D. Is there any way to solve 
>> this problem?
>> 
>> Thanks,
>> Simon
>> 
> 
> Maybe what you are looking for are the GC.removeRoot or GC.removeRange
> functions which are available in both Phobos and Tango?
> http://www.dsource.org/projects/tango/docs/current/tango.core.Memory.html
> http://www.digitalmars.com/d/2.0/phobos/std_gc.html
> http://www.digitalmars.com/d/1.0/phobos/std_gc.html

You can remove only something previously added.  Since a static array is
not a root nor a range of roots, you can't make it invisible to GC this
way.


Re: DMC to Create C .lib ?

2009-03-29 Thread Sergey Gromov
Sun, 29 Mar 2009 04:00:47 -0400, Chris Andrews wrote:

> Sergey Gromov Wrote:
> 
>> I just wanted to double-check that you did the conversion correctly.  So
>> I ended up finding out what the hell TCOD was.  Sorry for the spoiler!
>> :D
> 
> Hah, no biggie.  Good news though, I removed my extern(Windows) and
> tried the code against the coffimplib altered library and... SUCESS!!
>  So that works... like its supposed to when you're not a huge noob. 
> :p  Thanks for the advice in getting that straightened out. 

Nice to hear!

I hope that you actually not "removed your extern(Windows)" but replaced
it with extern(C).  Otherwise you risk getting D linkage for those
functions which is neither C nor C++.

>> This post really belongs to D.learn.
> 
> Oops, sorry.  I'm still picking up the flow of these boards.  Advice
> and questions goes in Learn, while D is for discussion about the
> language itself, yes?

Well, your question was about linking D with C++ code.  Good interaction
with C/C++ code is one of D's main selling points.  One therefore could
guess that there's not much to discuss but rather to ask what they do
wrong.

No worries though.  There are no angry moderators with big plus-throwers
here.  ;D


Re: Eric S. Raymond on GPL and BSD licenses. & Microsoft coming to Linux

2009-03-29 Thread Sergey Gromov
Sun, 29 Mar 2009 09:29:33 +0200, "Jérôme M. Berger" wrote:

> -BEGIN PGP SIGNED MESSAGE-
> Hash: SHA1
> 
> Sergey Gromov wrote:
>> Sat, 28 Mar 2009 15:38:45 +0300, Yigal Chripun wrote:
>> 
>>> When you buy 
>>> a car you are free to look under the hood and the same should apply to 
>>> software. sure, the manufacturer can and probably should void any 
>>> warranty if you mess with the internals of its product, but they 
>>> shouldn't prevent you access to those internals.
>> 
>> I hear automotive analogies here and there as "explanations" why open
>> source is good.  But automotive does not apply.
>> 
>> Yes you can buy Ford, modify it and sell it at a higher price.  But you
>> cannot put Ford out of business this way because you must start from
>> scratch on every single car you modify and that's a significant amount
>> of work.  And if you actually try to manufacture copies of Ford cars
>> you'll be sued for patent infringement.
>> 
>> Now, how would you make money on free, as in libre, software?  How would
>> you make a free, single-player RPG and still stay in business?  All you
>> can under GPL is take payment for distribution, as long as nobody else
>> starts to distribute it for free.  This means giving your hard work for
>> free, as in gratis, not business.
> 
>   Ask RedHat, or any of the increasingly large number of companies
> that *do* make money on free, as in libre, software. Basically, you
> make your customers pay for specific developments and
> customizations. Once the software is released you still get paid for
> tech support and maintenance.

Yeah, sure.  How much support a single-player game needs?  Or a
3D-modeling tool?  I agree with Nick: to make a profit on support you
must create something unusable in the first place, and then charge money
for fixing it.

I agree that support is sometimes a valid business model, like when you
create customized Linux kernels for various hardware and requirements.
But it's definitely not universal enough to apply to every software
created out there.


Re: Eric S. Raymond on GPL and BSD licenses. & Microsoft coming to Linux

2009-03-28 Thread Sergey Gromov
Sat, 28 Mar 2009 15:38:45 +0300, Yigal Chripun wrote:

> When you buy 
> a car you are free to look under the hood and the same should apply to 
> software. sure, the manufacturer can and probably should void any 
> warranty if you mess with the internals of its product, but they 
> shouldn't prevent you access to those internals.

I hear automotive analogies here and there as "explanations" why open
source is good.  But automotive does not apply.

Yes you can buy Ford, modify it and sell it at a higher price.  But you
cannot put Ford out of business this way because you must start from
scratch on every single car you modify and that's a significant amount
of work.  And if you actually try to manufacture copies of Ford cars
you'll be sued for patent infringement.

Now, how would you make money on free, as in libre, software?  How would
you make a free, single-player RPG and still stay in business?  All you
can under GPL is take payment for distribution, as long as nobody else
starts to distribute it for free.  This means giving your hard work for
free, as in gratis, not business.


Re: State of Play

2009-03-27 Thread Sergey Gromov
Thu, 26 Mar 2009 22:30:50 -0700, Walter Bright wrote:

> Bill Baxter wrote:
>> It seems to me the only people who would know which compilers deserve
>> the "stable" label are the folks using dmd on a daily basis to build
>> their software.  Yet I've never seen the question come up here or
>> anywhere else of what version of D the users find to be the most
>> stable.   My impression is frankly that Walter just arbitrarily slaps
>> the label on a rev that's about 10 steps back from current.  Probably
>> there's more to it than that, but that's what it seems like.
> 
> The current "stable" D1 is that way because it's the one that people 
> supplied me with a bundled version that has the major libraries 
> specifically tested and working with it.
> 
> I think that is a fairly reasonable definition of it.

Official stable Tango is bundled with 1.033 for a very long time
already.


Re: DMC to Create C .lib ?

2009-03-27 Thread Sergey Gromov
Fri, 27 Mar 2009 00:18:47 -0400, Chris Andrews wrote:

> Sergey Gromov Wrote:
> 
>> You're talking about Doryen Library project, right?
>> 
>> My thought is that TCOD_console_flush is actually cdecl and must be
>> declared as extern(C), while you seem to declare it as extern(Windows)
>> which is stdcall.  What you get with linkdef is corrupted stack.  This
>> is why coffimplib is absolute best when you have the right COFF import
>> library: it allows to catch this sort of errors.
> 
> Hah, you got me.  Yeah, I'm toying with a wrapper for Doryen Library
> in D.  I'm trying to not talk too much about it, since I don't know
> if I'm skilled enough to write and implement it, nor dedicated enough
> to finish it. :p  We'll see. 

I just wanted to double-check that you did the conversion correctly.  So
I ended up finding out what the hell TCOD was.  Sorry for the spoiler!
:D

> All the methods were preprended by TCODLIB_API, which is a typedef to
> __declspec(dllexport) ( or __declspec(import) ) which I thought
> (according to the guide) translates as export extern(Windows) 

__declspec(dllexport) just directs the compiler to make this function
available from outside your DLL.  It does not change calling convention.
It's equivalent to just "export" in D.

By default, C uses "cdecl" calling convention ("extern(C)" in D), and
C++ uses "fastcall", I think ("extern(C++)" in D).  C++ also uses cdecl
if explicitly told so via 'extern "C" { ...' construct, usually
somewhere in a header with function prototypes.

Since every calling convention uses different mangling rules (symbol
naming) you can usually tell them apart: functions with simple names
with "_" prepended are cdecl, funky long names are fastcall, simple
names with @num are stdcall (extern(Windows), extern(System)).

> I guess I'll try externing to C instead, and try to coffimp the
> library again.  Perhaps the "visual studio" library is a bad one to
> use, and I should try the "Mingw" .a file.

Visual Studio library should be perfectly fine.

P.S.
This post really belongs to D.learn.


Re: DMC to Create C .lib ?

2009-03-25 Thread Sergey Gromov
Tue, 24 Mar 2009 22:31:52 -0400, Chris Andrews wrote:

> Sergey Gromov Wrote:
> 
>> "Want to create an import library? Ask me how!"
> 
> Well since you offered... ;) 
> 
> I tried out coffimplib, but it's not yeilding the results I need.  I compared 
> the linkdef generated .def files with coffimplib's and the missing part is 
> pretty clear:
> 
> linkdef:
> EXPORTS
>_tcod_console_fl...@0 = TCOD_console_flush
>_tcod_console_init_r...@16 = TCOD_console_init_root
> 
> coffimplib:
> EXPORTS
>   _TCOD_console_flush = TCOD_console_flush
>   _TCOD_console_init_root = TCOD_console_init_root
> 
> Those missing numbers (something to do with the size of the parameters, 
> right?) are needed and not being provided by the tool.  Thoughts?

You're talking about Doryen Library project, right?

My thought is that TCOD_console_flush is actually cdecl and must be
declared as extern(C), while you seem to declare it as extern(Windows)
which is stdcall.  What you get with linkdef is corrupted stack.  This
is why coffimplib is absolute best when you have the right COFF import
library: it allows to catch this sort of errors.


Re: crossplatform linking?

2009-03-24 Thread Sergey Gromov
Tue, 24 Mar 2009 14:13:34 +0800, davidl wrote:

> 在 Mon, 23 Mar 2009 18:18:55 +0800,Frits van Bommel  
>  写道:
> 
>> Yigal Chripun wrote:
>>> it's not a platform issue but more of a linker issue. after all, mingw  
>>> uses elf on windows, right?
>>
>> Actually, I'm pretty sure it uses a COFF variant. (Unless this has  
>> changed recently?)
> 
> I wish a unified object format, a unified linker. That's all. The  
> crossplatform shit is just annoying.

Add to this a unified compiler and a unified language.  ;-)

The reason behind different OSes and object file formats is exactly the
same as the reasons behind different programming languages.


Re: Benchmark of try/catch

2009-03-23 Thread Sergey Gromov
Mon, 23 Mar 2009 17:11:56 -0400, bearophile wrote:

> bearophile:
>> N = 1_000_000_000:
>>   C++: 0.06 s
>>   D:   5.10 s
> 
> I think GCC compiles most things away, so the run time is constant.

Yes, I think it detected there was no side effects and eliminated the
whole loop.  That's why my original benchmark was in two modules.


Re: Benchmark of try/catch

2009-03-23 Thread Sergey Gromov
Mon, 23 Mar 2009 09:07:16 -0400, bearophile wrote:

> grauzone:
> 
>>From your site:<
> 
> I don't own LiveJournal :-) That's just my blog, my site is elsewhere.
> 
>> Using exceptions in a string->int conversion routine is really horrible and 
>> incredibly stupid.<
> 
> I agree that it's not nice looking, but in Python that's the standard idiom.
> In D I do the same thing when I want to know if a string contains an integer 
> or float, with toInt/toFloat, how can I do it with no exceptions?
> 
> Python3 also removes the find() method of strings, and leaves only the 
> index() method, that is like find(), but raise ValueError when the substring 
> is not found. So you are forced to use exceptions here too.
> 
> So far in D I have used exceptions to control flow only once, in this library 
> module (original code idea by Witold Baryluk, modified):
> http://www.fantascienza.net/leonardo/so/dlibs/generators.html

D is designed to make normal execution flow fast and allow error
handling be not-so-fast:

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

so Python idioms simply do not fit.  Different languages require
different idioms, that's my strong opinion.  One really important
benchmark would be something like this:

*
*
D exceptions

-main.d-
import worker;
void main() {
  for (int i = 0;; i++) {
try {
  do_stuff(i);
} catch (TerminateException e) {
  break;
}
  }
}
--worker.d
class TerminateException {}
void do_stuff(int i)
{
  if (i == 1_000_000_000)
throw new TerminateException;
}
---

***
***
C++ exceptions

--main.cpp
#include "worker.h"
int main() {
  for (int i = 0;; i++) {
try {
  do_stuff(i);
} catch (const TerminateException & e) {
  break;
}
  }
  return 0;
}
--worker.h
struct TerminateException {};
void do_stuff(int i);
--worker.cpp
#include "worker.h"
void do_stuff(int i)
{
  if (i == 10)
throw TerminateException();
}
--

***
***
results

D: 5.52s
C++: 4.96s


Re: new D2.0 + C++ language

2009-03-22 Thread Sergey Gromov
Sat, 21 Mar 2009 20:16:07 -0600, Rainer Deyke wrote:

> Sergey Gromov wrote:
>> I think this is an overstatement.  It's only abstract write buffers
>> where GC really doesn't work, like std.stream.BufferedFile.  In any
>> other resource management case I can think of GC works fine.
> 
> OpenGL objects (textures/shader programs/display lists).
> SDL surfaces.
> Hardware sound buffers.
> Mutex locks.
> File handles.
> Any object with a non-trivial destructor.
> Any object that contains or manages one of the above.
> 
> Many of the above need to be released in a timely manner. For example,
> it is a serious error to free a SDL surface after closing the SDL video
> subsystem, and closing the SDL video subsystem is the only way to close
> the application window under SDL.  Non-deterministic garbage collection
> cannot work.
> 
> Others don't strictly need to be released immediately after use, but
> should still be released as soon as reasonably possible to prevent
> resource hogging.  The GC triggers when the program is low on system
> memory, not when the program is low on texture memory.
> 
> By my estimate, in my current project (rewritten in C++ after abandoning
> D due to its poor resource management), about half of the classes manage
> resources (directly or indirectly) that need to be released in a timely
> manner.  The other 50% does not need RAII, but also wouldn't benefit
> from GC in any area other than performance.

Thanks for the explanation, it really helps to keep this picture in
mind.


Re: new D2.0 + C++ language

2009-03-21 Thread Sergey Gromov
Sat, 21 Mar 2009 00:59:22 -0600, Rainer Deyke wrote:

> GC is useless for resource management.

I think this is an overstatement.  It's only abstract write buffers
where GC really doesn't work, like std.stream.BufferedFile.  In any
other resource management case I can think of GC works fine.


Re: Returning a struct by reference

2009-03-21 Thread Sergey Gromov
Sat, 21 Mar 2009 09:55:13 -0400, Simon TRENY wrote:

>//This syntax is not working
>public ref Position position() {
>   return m_position;
>}

D2 supports this.
D1 won't, ever.  I think.


Re: Dynamic loading of D modules

2009-03-20 Thread Sergey Gromov
Fri, 20 Mar 2009 05:53:18 -0400, Steve Teale wrote:

> Is there anyone out there these days working on dynamic loading of D modules 
> in D - preferably using Phobos.

DDL?

http://dsource.org/projects/ddl


Re: DMC to Create C .lib ?

2009-03-19 Thread Sergey Gromov
Thu, 19 Mar 2009 17:27:30 -0400, Chris Andrews wrote:

> I'm working on a wrapper to a C dll and I think that I'll need to create a 
> .lib file eventually to connect my D code to the C library.  
> 
> I've experimented with this a little, including using ipmlib to create the 
> lib, which creates a lib but not one that works right (I think it mangles the 
> names wrong.)  However, the excellent linkdef tool works to create a good 
> .def which allows implib to create a proper lib.
> 
> Still, that seems a fussy way to build this: write it wrong, break it, use 
> linkdef and implib to fix it.  I have the source code for that dll, so what 
> I'm wondering is, can I just use some other DM tools (DMC?) to compile that C 
> code and get a proper .lib from that?

Use coffimplib on your regular .lib file:

http://www.digitalmars.com/ctg/coffimplib.html

Get it at ftp.digitalmars.com.

I'm advertising coffimplib so much that I probably need a badge already,
"Want to create an import library? Ask me how!"


Re: What is throwable

2009-03-19 Thread Sergey Gromov
Thu, 19 Mar 2009 20:44:51 + (UTC), Sean Kelly wrote:

> == Quote from Don (nos...@nospam.com)'s article
>> Andrei Alexandrescu wrote:
>>> Denis Koroskin wrote:
 On Thu, 19 Mar 2009 19:39:52 +0300, Andrei Alexandrescu
  wrote:

> Ary Borenszweig wrote:
>> Andrei Alexandrescu wrote:
>>> Anyhow, we should implement a model in D that allows such multiple
>>> throws.
>>  What for?
>
> For allowing destructors to throw.
>
> Andrei

 Are you sure this is sound?
>>>
>>> Yes. The notion that throwing destructors should terminate the
>>> application pronto is a prejudice we got from C++.
>>>
>>> Andrei
>> And it causes lots of problems, in my experience. Since it usually
>> doesn't terminate the app, just the thread with the defective
>> destructor. Which is unnecessarily difficult to debug.
> 
> I've considered letting the user supply a custom "unhandled
> exception" handler for threads.  It just seemed messy given that
> calling join() on a thread now will rethrow the unhandled exception
> if there was one.  I figured that the user would join threads he cared
> about, and if one he didn't care about terminated unexpectedly the
> perhaps that's not a problem.

The problem is when you have a worker thread which never terminates and
sends notifications to the main thread.  Like game logic thread versus
main GUI thread.  If logic thread throws, your game suddenly stops
working for no apparent reason.


Re: memcpy vs slice copy

2009-03-19 Thread Sergey Gromov
Mon, 16 Mar 2009 11:36:50 -0700, Walter Bright wrote:

> Don wrote:
>> Oh. I didn't see it was only 6 bytes. And the compiler even KNOWS it's 
>> six bytes -- it's in the asm. Blimey. It should just be doing that as a 
>> direct sequence of loads and stores, for anything up to at least 8 bytes.
> 
> The compiler will replace it with a simple mov if it is 1, 2, 4 or 8 bytes.

It didn't, actually.

I've just filed a patch which should fix this issue:

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

For instance, the benchmark in the original post were compiling to

L31:mov ECX,EDX
mov EAX,6
lea ESI,010h[ESP]
mov ECX,EAX
mov EDI,EDX
rep
movsb
add EDX,6
add EBX,6
cmp EBX,011E1A300h
jb  L31

With my patch it's just

L3A:lea ESI,0Ch[ESP]
mov EDI,EAX
movsd
movsb
movsb
add EAX,6
add ECX,6
cmp ECX,011E1A300h
jb  L3A

as it probably was meant to be.


Re: for in D versus C and C++

2009-03-19 Thread Sergey Gromov
Thu, 19 Mar 2009 06:35:37 -0400, Steve Teale wrote:

> for (; a 
> is illegal in D.
> 
> Doesn't this break a lot of C and C++ code?

for (; a

A bug in the back-end?

2009-03-18 Thread Sergey Gromov
I was reading the 1.041's back-end code.  Here's something that looked
wrong to me: in cgelem.c, in function elcmp(), at line 3318:

case 4:
if (sz > 2)
e = el_una(OPu32_64,TYshort,e);
else
e = el_una(OP32_16,TYshort,e);
break;

Specifically the line

e = el_una(OPu32_64,TYshort,e);

looks wrong, the unary operator type should be 64 bit, not short.  Am I
missing something?


Re: new D2.0 + C++ language

2009-03-18 Thread Sergey Gromov
Wed, 18 Mar 2009 13:48:55 -0400, Craig Black wrote:

> bearophile Wrote:
> 
>> Weed:
>>> I want to offer the dialect of the language D2.0, suitable for use where
>>> are now used C/C++. Main goal of this is making language like D, but
>>> corresponding "zero-overhead principle" like C++:
>>>...
>>> The code on this language almost as dangerous as a code on C++ - it is a
>>> necessary cost for increasing performance.
>> 
>> No, thanks...
>> 
>> And regarding performance, eventually it will come a lot from a good usage 
>> of multiprocessing, that in real-world programs may need pure functions and 
>> immutable data. That D2 has already, while C++ is less lucky.
>> 
>> Bye,
>> bearophile
> 
> Multiprocessing can only improve performance for tasks that can run
> in parallel.  So far, every attempt to do this with GC (that I know
> of) has ended up slower, not faster.  Bottom line, if GC is the
> bottleneck, more CPU's won't help. 
> 
> For applications where GC performance is unacceptable, we either need
> a radically new way to do GC faster, rely less on the GC, or drop GC
> altogether. 
> 
> However, in D, we can't get rid of the GC altogether, since the
> compiler relies on it.  But we can use explicit memory management
> where it makes sense to do so. 
> 
> -Craig

I think that the "shared" memory concept in D2 is introduced
specifically to improve multi-processing GC performance.  There going to
be thread-local GC for every thread allocating memory, and, since
thread-local will be the default allocation strategy, most memory will
be GCed without synchronizing with other threads.


Re: Proposal: fixing the 'pure' floating point problem.

2009-03-17 Thread Sergey Gromov
Tue, 17 Mar 2009 03:38:23 -0700, Walter Bright wrote:

> Don wrote:
>> Walter Bright wrote:
>>> Don wrote:
 A has called a function in B. B is not a floatingpoint module, so b() 
 can only be called when the mode is set back to the default. a() 
 violates this contract, so a() is incorrect. There's nothing wrong 
 with b() or c(). If a() wants to call b(), it needs to restore the 
 mode first; or else change b() into another floatingpoint module.
>>>
>>> Ok, this was the missing piece in my understanding of the proposal.
>>>
>>> But this requires that std.math either be floatingpoint, or two 
>>> versions of it must exist if you want to do change the rounding modes 
>>> on it.
>> 
>> I'm proposing that std.math would be floatingpoint. The docs contain 
>> references to the sticky flags; I just went to a lot of trouble to make 
>> sure that exp() sets the sticky flags correctly.
> 
> If std.math was floatingpoint, then its functions could not be pure.

Let's see.

int foo(int x)
{
  return x * x;
}

This function receives its argument in a thread-local register EAX and
returns its result in a thread-local register EAX.  You say this
function *can* be pure.

Now this function:

module(floatingpoint)
double bar(double x)
{
  return x * x;
}

This function receives its arguments on a thread-local FPU stack, in a
thread-local FPU mode register, and in a thread-local FPU flags
register.  It returns its result on a thread-local FPU stack, in a
thread-local FPU mode register, and in a thread-local FPU flags
register.  You say this function *can not* be pure.  Why?


Re: memcpy vs slice copy

2009-03-16 Thread Sergey Gromov
Mon, 16 Mar 2009 10:34:33 +0100, Don wrote:

> Sergey Gromov wrote:
>> Sun, 15 Mar 2009 13:17:50 + (UTC), Moritz Warning wrote:
>> 
>>> On Sat, 14 Mar 2009 23:50:58 -0400, bearophile wrote:
>>>
>>>> While doing some string processing I've seen some unusual timings
>>>> compared to the C code, so I have written this to see the situation
>>>> better. When USE_MEMCPY is false this little benchmark runs about 3+
>>>> times slower:
>>> I did a little benchmark:
>>>
>>> ldc -release -O5
>>> true: 0.51
>>> false: 0.63
>>>
>>> dmd -release -O
>>> true: 4.47
>>> false: 3.58
>>>
>>> I don't see a very big difference between slice copying and memcpy (but 
>>> between compilers).
>>>
>>> Btw.: http://www.digitalmars.com/pnews/read.php?
>>> server=news.digitalmars.com&group=digitalmars.D.bugs&artnum=14933
>> 
>> The original benchmark swapped insanely on my 1GB laptop so I've cut the
>> number of iterations in half, to 50_000_000.  Compiled with -O -release
>> -inline.  Results:
>> 
>> slice: 2.31
>> memcpy:  0.73
>> 
>> That's 3 times difference.  Disassembly:
>> 
>> slice:
>> L31:mov ECX,EDX
>> mov EAX,6
>> lea ESI,010h[ESP]
>> mov ECX,EAX
>> mov EDI,EDX
>> rep
>> movsb
>> add EDX,6
>> add EBX,6
>> cmp EBX,011E1A300h
>> jb  L31
>> 
>> memcpy:
>> L35:push6
>> lea ECX,014h[ESP]
>> pushECX
>> pushEBX
>> callnear ptr _memcpy
>> add EBX,6
>> add ESI,6
>> add ESP,0Ch
>> cmp ESI,011E1A300h
>> jb  L35
>> 
>> Seems like rep movsb is /way/ sub-optimal for copying data.
> 
> Definitely! The difference ought to be bigger than a factor of 3. Which 
> means that memcpy probably isn't anywhere near optimal, either.
> rep movsd is always 4 times quicker than rep movsb. There's a range of 
> lengths for which rep movsd is optimal; outside that range, there's are 
> other options which are even faster.
> 
> So there's a factor of 4-8 speedup available on most memory copies. 
> Low-hanging fruit! 

Don't disregard the function call overhead.  memcpy is called 50 M
times, copying only 6 bytes per call.


Re: Proposal: fixing the 'pure' floating point problem.

2009-03-15 Thread Sergey Gromov
Sun, 15 Mar 2009 13:50:07 -0700, Walter Bright wrote:

> Don wrote:
>> Something interesting about my proposal is that although it is motivated 
>> by the purity problem, that's simply a rule for the compiler -- the 
>> rules for programmers do not involve purity at all.(See my other post). 
>> Do not call _any_ functions in non-floatingpoint modules (pure or not) 
>> without restoring the rounding modes back to the default.
> 
> They could be done in terms of pure - if you call any pure function, the 
> modes must be set to the default.

In Don's proposal, the following is legal:

-
module A(floatingpoint);
pure void a()
{
 set mode;
 b();
 restore mode;
}

module B(floatingpoint);
pure void b()
{
 do stuff;
}
-

because, from compiler's perspective, they're

struct FpuState { mode; sticky; }
pure FpuState a(FpuState s);
pure FpuState b(FpuState s);

and can be actually cached, if compiler so wishes.  IIUC, this is
exactly the use case when you implement range arithmetics.


  1   2   >