Re: template+alias as an object's "namespace"

2012-04-18 Thread kennytm
"F i L"  wrote:
> Would it be prudent to make Templates be able to be used without
> parameters? (Or something along those lines) Consider the following:
> 
>   struct Foo1 {
> string name = "Foo1";
> 
> alias Unsafe!() unsafe;
>   
> template Unsafe() {
>   string name = "Bar";
> 
>   void bar() {
> writeln(this.name, name);
>   }
> }
>   }
> 
>   struct Foo2 {
> string name = "Foo2";
> string unsafe_name = "Bar";
> 
> void unsafe_bar() {
>   writeln(name, unsafe_name);
> }
>   }
> 
>   void main() {
> auto foo1 = Foo1();
> auto foo2 = Foo2();
> 
> foo1.Unsafe!().bar(); // ugly
> foo1.unsafe.bar(); // nice
> foo2.unsafe_bar(); // classic
>   }
> 
> The classic way works, or course, but it's not as pretty :)
> I may be breaking some sacred rule of OOP here, but I think this kind of
> classification comes in handy. In fact, I think D's the only language
> that actually allows for this syntax without increasing an objects memory 
> footprints.
> 
> It could be *useful* in situations where you want to simplistically wrap
> a complex system, say X11, and provide _a few_ convenience functions,
> while still providing complete access to X11 objects, but grouping them
> into logical subsection. Example:
> 
>   class Window {
> private XDisplay* _display;
> 
> void create(...) { /* use _display; */ }
> void delete(...) { /* ditto */ }
> 
> template X11 {
>   @property auto display() { return _display; }
> }
>   }
> 
> The only thing that erks me is the name "template" doesn't really match
> it's function at this point. Maybe something like "alias template" would make 
> more sense:
> 
>   alias template X11 { ... }
> 
> idk. What are peoples thoughts on this? Good? Bad? Ugly?

struct Foo1 {
struct Unsafe {
static:
void bar() { ... }
}
}
Foo1 f;
f.Unsafe.bar();


Re: String mixin syntax sugar

2012-03-21 Thread kennytm
Mantis  wrote:
> 21.03.2012 13:35, kennytm пишет:
>> Mantis  wrote:
>>> [...]
>>> # identifier statement
>>> 
>> You mean 'declaration'.
> 
> Not necessarily, this could be used anywhere a mixin can be.
>>> [...]
>> The syntax may conflict with '#line'.
> 
> I didn't know. The choice for the symbol is not that important however.
> 
>> What to do where there are multiple attributes? E.g.
>> 
>> #license!"BSD" @safe #memoize pure nothrow auto invertMatrix(T)(T[]
>> elements) if (isArithmetic!T) { ... }
> 
> Evaluation order stays the same as in this example, the improvement is purely 
> syntactical:
> //
> import std.stdio, std.array;
> 
> string m1( string s ) { return replace( s, "foo", "bar" ); }
> string m2( string s ) { return replace( s, "bar", "baz" ); }
> 
> mixin( m1( q{ mixin( m2( q{ void foo( int i ) {
> writeln( i );
> }}));}));
> 
> void main() {
> baz( 42 );
> }
> //
>> What to do with .di files?
>> 
>> // in .di
>> #handler void onLoad();
>> // in .d
>> #handler void onLoad() {  }
> 
> Since the function receives a string, it can deal with declarations
> differently from definitions, it's only a matter of parser.
>> Besides, what's wrong with using '@'?
>> 
>> @serialize int a;
> Builtin annotations' names are not reserved keywords, so this would be
> possible and ambiguous:
> 
> string safe( string s );
> @safe void foo(); // what @safe stands for?

They could be contextual keywords, just like the 'exit' in scope(exit).
Your # has the same problem. 

So we have

AttributeIdentifier:
any Identifier except 'safe', 'system', 'trusted', 'disable' and
'property'. 

(Alternatively, implement these 5 things using the CTFE method. )


Re: String mixin syntax sugar

2012-03-21 Thread kennytm
Mantis  wrote:
> Hello,
> 
> since people discussed a lot about user-defined attributes recently, I've
> been thinking about a way to implement it with a string mixins. The
> problem with them is their syntax - it's far from what we want to use in
> everyday job. I understand, they should be easily distinguished at use
> site, but perhaps this may be accomplished in other ways as well. My idea
> is to translate this kind of statements:
> 
> # identifier statement
> 

You mean 'declaration'. 

> into this:
> 
> mixin( identifier( q{ statement } ) );
> 
> where an identifier is a, possibly templated, function that accepts one
> string argument and returns a string. Here are some possible use cases:
> 
> #serialize int a; // marked to be serializable
> #serialize!not int b; // -.- non-serializable
> 
> #readonly float c; // generate trivial private setter and public getter
> 
> #handles!Events.Foo void handler(); // event handler
> 
> #attribute!"Foo" void foo(); // function with additional compile-time info
> 
> Most of these examples require some D parser, but, since it is planned to
> add parser-generation into Phobos, this shouldn't be a problem.
> What do you think, does it have some value for the language, and, if yes,
> is it possible to implement?

The syntax may conflict with '#line'. 

What to do where there are multiple attributes? E.g.

#license!"BSD" @safe #memoize pure nothrow auto invertMatrix(T)(T[]
elements) if (isArithmetic!T) { ... }

What to do with .di files?

// in .di
#handler void onLoad();
// in .d
#handler void onLoad() {  }

Besides, what's wrong with using '@'?

@serialize int a;


Re: toHash => pure, nothrow, const, @safe

2012-03-13 Thread kennytm
Andrei Alexandrescu  wrote:
> On 3/13/12 6:02 AM, Peter Alexander wrote:
>> On Monday, 12 March 2012 at 09:40:15 UTC, Walter Bright wrote:
>>> On 3/12/2012 1:08 AM, Martin Nowak wrote:
 What's wrong with auto-inference. Inferred attributes are only
 strengthening
 guarantees.
>>> 
>>> Auto-inference is currently done for lambdas and template functions -
>>> why? - because the function's implementation is guaranteed to be
>>> visible to the compiler. For other functions, not so, and so the
>>> attributes must be part of the function signature.
>> 
>> Dumb question:
>> 
>> Why not auto-infer when the function body is available, and put the
>> inferred attributes into the automatically generated .di file?
>> 
>> Apologies if I've missed something completely obvious.
> 
> Because in the general case functions call one another so there's no way
> to figure which to look at first.
> 
> Andrei

That's no difference from template functions calling each others right?

int a()(int x) { return x==0?1:b(x-1); }
int b()(int x) { return x==0?1:a(x-1); }


Re: Review of Jose Armando Garcia Sancio's std.log

2012-03-07 Thread kennytm
"Richard van Scheijen"  wrote:
> When logging the severity level should convey a certain insight that the
> developer has about the code. This can be done with a 3 bit field. These
> are: known-cause, known-effect and breaks-flow.
> 
> This creates the following matrix:
> 
> KC KE BF Severity
> =
> 1  1  0  Trace
> 0  1  0  Info
> 1  0  0  Notice
> 0  0  0  Warning
> 1  1  1  Error
> 0  1  1  Critical
> 1  0  1  Severe
> 0  0  1  Fatal
> 

Minor nit: if you rearrange it as

AllowFlow / KnownEffect / KnownCause

Then the description will correspond exactly to their integer values. 

111 (7) = Trace
110 (6) = Info
101 (5) = Notice
100 (4) = Warning
011 (3) = Error
010 (2) = Critical
001 (1) = Severe
000 (0) = Fatal

> A known cause is when the developer knows why a log event is made. e.g.:
> if you cannot open a file, you do not know why.
> A known effect is when he/she knows what happens after. Basically, you
> can tell if it is a catch-all by this flag.
> 
> When a severity should only be handled by a debugger, the normal debug
> statement should be used. This is in essence a 4th bit.
> 
> I hope this helpful in the search for a good level system.


Re: [Feature Request] Forwardable as Ruby does

2012-03-05 Thread kennytm
bioinfornatics  wrote:
> Le lundi 05 mars 2012 ‡ 17:55 +0000, kennytm a Ècrit :
>> bioinfornatics  wrote:
>>> dear,
>>> I would like a easy way to forward as does ruby:
>>> http://www.ruby-doc.org/stdlib-1.9.3/libdoc/forwardable/rdoc/Forwardable.html
>>> 
>>> I have already something close: 
>>> - https://gist.github.com/1969776 (me)
>>> - http://paste.pocoo.org/show/uoD89CCjX5H3m6GvPvW6/ (dav1d)
>>> 
>>> But it works only for array.
>>> 
>>> 
>>> I have try to do this purpose: https://gist.github.com/1974033
>>> 
>>> but i am too new in D
>>> 
>>> This feature will be really awesome and could be go into std.traits
>> 
>> Check 'opDispatch' and 'alias this'.
> 
> alias this is not the answer as it forward all, i fyo want select for
> this member forwad this method and for another this one  ...
> 
> opDispaytch is not really easy to use for this. my first code do this in
> 1 line and it is easy to understand hat it do. In 1 line i forward 3
> method to a member. This save time, code and bug.

You can just mixin an opDispatch function, like (not tested, only works for
functions)

mixin template Forward(alias member, s...) {
auto opDispatch(string name, T...)(T args) {
static assert(canFind(s, name));
return mixin("member." ~ name ~ "(args)");
}
}

or use a foreach over 's' and mixin the function/member definitions for
each name.


Re: [Feature Request] Forwardable as Ruby does

2012-03-05 Thread kennytm
bioinfornatics  wrote:
> dear,
> I would like a easy way to forward as does ruby:
> http://www.ruby-doc.org/stdlib-1.9.3/libdoc/forwardable/rdoc/Forwardable.html
> 
> I have already something close: 
> - https://gist.github.com/1969776 (me)
> - http://paste.pocoo.org/show/uoD89CCjX5H3m6GvPvW6/ (dav1d)
> 
> But it works only for array.
> 
> 
> I have try to do this purpose: https://gist.github.com/1974033
> 
> but i am too new in D
> 
> This feature will be really awesome and could be go into std.traits

Check 'opDispatch' and 'alias this'.


Re: Extending UFCS to templates

2012-03-03 Thread kennytm
Andrej Mitrovic  wrote:
> I thought I'd be cool if we could use UFCS for templates. For example
> instead of this:
> 
> template isOneOf(X, T...)
> {
> static if (!T.length)
> enum bool isOneOf = false;
> else static if (is(Unqual!X == T[0]))
> enum bool isOneOf = true;
> else
> enum bool isOneOf = isOneOf!(Unqual!X, T[1..$]);
> }
> 
> void test(T)(T t)
> if (isOneOf!(T, int, double))
> { }
> 
> void main() {
> test(1);
> }
> 
> We would be able use code like this:
> 
> void test(T)(T t)
> if (T.isOneOf!(int, double))  // UFCS (or maybe Uniform Template
> Instantiation Syntax? :p)
> { }
> 
> A far-fetched dream?

This only works for types. Values (thus, aliases) would be ambiguous. 

1.isOneOf!(2, 3)
// could be isOneOf!(1, 2, 3)
// or isOneOf!(2, 3)(1)


Re: Tuples citizenship

2012-03-02 Thread kennytm
"Jonathan M Davis"  wrote:

> It's not like using out is fantastic and tuple sucks. They both have pros and 
> cons. My point is that it's not the case that always returning tuples is 
> better, which seems to be the point that Bearophile is trying to push. There 
> _are_ downsides to returning tuples. Whether a tuple or an out parameter is 
> better depends on the function and the context in which it is used.
> 
> - Jonathan M Davis

bearophile's example (frexp, remquo) are good examples where tuple return
is better than 'out' parameters though. Another Phobos function, I think,
which should use 'out' instead of Tuples is:

-  std.file.getTimes (have the two 'out' parameters, and the function
itself returns 'void'!)

While some functions should remain using 'out':

- std.stream.InputStream.read (due to overloading)

And of course the extern(C) functions need to use 'out' instead of Tuple
return :)


Re: Tuples citizenship

2012-03-02 Thread kennytm
Jonathan M Davis  wrote:
> On Friday, March 02, 2012 09:53:19 kennytm wrote:
>> You can just chain with
>> 
>> return doSomething(findSplit(haystack, needle)[0]);
>> 
>> if you just need the return value. Compare with 'out':
>> 
>> R4 ignored;
>> R5 ignored2;
>> return doSomething(findSplit(haystack, needle, ignored, ignored2));
>> 
>> How do you chain with _partial_ amount of return values with 'out'?
> 
> If the function uses out, then you can chain the return value without losing 
> the values which were assigned to the out arguments, but if you have a tuple, 
> and you select one of the elements in the tuple to chain, you lose the 
> others. 
> The only way to get _all_ of the values in the tuple is to assign the tuple 
> to 
> a variable, in which case, you can't chain at all.
> 
> - Jonathan M Davis

I see what you mean. However, this is useful only when you know one of the
return value is special, and make the rest 'out' parameters, e.g.

File openFile(string fn, string mode, out ErrorCode errCode);

because the API designer know people seldom focus on the 'errCode'. But if
not all return values are considered unimportant (such as findSplit and
remquo), randomly making some of them as the 'out' parameter just make the
normal use cases more messy.

Besides, you can't use type inference with 'out' parameters. You don't
actually know the types R4 and R5 in my findSplit2 example.


Re: Tuples citizenship

2012-03-02 Thread kennytm
Jonathan M Davis  wrote:
> On Friday, March 02, 2012 09:31:14 kennytm wrote:
>> Jonathan M Davis  wrote:
>>> That's assuming that you're passing all of the pieces of the tuple to the
>>> function. Often, that's not the case at all. Take the findSplit trio, for
>>> instance. What are the odds that you're going to want to pass all of the
>>> elements in the tuples that any of the return to another function? About
>>> zero, I'd say. It's _much_ more likely that you're going to want to take
>>> the results and then pass _one_ of them to another function. So, as it
>>> stands, chaining with those functions just doesn't work unless you only
>>> care about one of the results in the tuple.
>>> 
>>> - Jonathan M Davis
>> 
>> How does 'out' make chaining any easier? Suppose we have a `R3
>> findSplit2(R1, R2, out R4, out R5)`, how to chain if we want to pass the R4
>> to another function?
>> 
>> R5 ignored;
>> R4 theRange;
>> findSplit2(haystack, needle, theRange, ignored);
>> return doSomething(theRange);
>> 
>> vs
>> 
>> return doSomething(findSplit(haystack, needle)[1]);
> 
> True, you can't chain using the out parameters, but you _can_ chain using the 
> return value, whereas if you have a tuple, you can't chain _at all_ unless 
> you 
> actually need all of the returned values (either as a tuple or expanded) or 
> if 
> you only need _one_ of the returned values, in which case you can use the 
> subscript operator. So, you can definitely chain better without a tuple than 
> with.
> 
> - Jonathan M Davis

You can just chain with

return doSomething(findSplit(haystack, needle)[0]);

if you just need the return value. Compare with 'out':

R4 ignored;
R5 ignored2;
return doSomething(findSplit(haystack, needle, ignored, ignored2));

How do you chain with _partial_ amount of return values with 'out'?


Re: Tuples citizenship

2012-03-02 Thread kennytm
Jonathan M Davis  wrote:

> That's assuming that you're passing all of the pieces of the tuple to the 
> function. Often, that's not the case at all. Take the findSplit trio, for 
> instance. What are the odds that you're going to want to pass all of the 
> elements in the tuples that any of the return to another function? About 
> zero, 
> I'd say. It's _much_ more likely that you're going to want to take the 
> results 
> and then pass _one_ of them to another function. So, as it stands, chaining 
> with those functions just doesn't work unless you only care about one of the 
> results in the tuple.
> 
> - Jonathan M Davis

How does 'out' make chaining any easier? Suppose we have a `R3
findSplit2(R1, R2, out R4, out R5)`, how to chain if we want to pass the R4
to another function?

R5 ignored;
R4 theRange;
findSplit2(haystack, needle, theRange, ignored);
return doSomething(theRange);

vs

return doSomething(findSplit(haystack, needle)[1]);


Re: Tuples citizenship

2012-03-01 Thread kennytm
"Jonathan M Davis"  wrote:

> When you're looking to mutate existing variables in the caller, using out 
> parameters results in cleaner code. Tuples are inherently messier, because 
> you 
> have to deal with multiple return values. They also often do poorly when you 
> need to use the functional programming, because often you want all of the 
> return values for later use but only want to pass _one_ of them to the 
> function that you're passing the result to.
> 

You use 'ref' to mutate existing variable, not 'out'. Multiple return value
doesn't replace the use case of ref. 

Not sure how messy it is to extract one value out of the tuple. It is much
more messier to ignore an 'out' parameter than a field in a tuple in the
call site. 

> At other times, tuples are nicer - like when you actually _want_ the return 
> value packed together (though often, if that's what you really want, a struct 
> might be better). And if you're not looking to assign the parts of a tuple to 
> existing variables, then they're not quite as bad as when you are, since you 
> don't necessarily have to then assign the pieces to other variables.
> 
> Both have value, though if you need a lot of either, you should probably 
> consider whether a struct or class would suit what you're doing better.
> 
> - Jonathan M Davis


Re: Tuples citizenship

2012-03-01 Thread kennytm
bearophile  wrote:
(snip) 
> It's good for tuples to become more common in D code. Some time ago I
> have asked the built-in associative arrays to grow a method to iterate on
> key-value pairs, named "byPair":
> http://d.puremagic.com/issues/show_bug.cgi?id=5466
> 
(snip)
> Bye,
> bearophile

Associative arrays (should) have UFCS, so one could just define

@property auto byPair(AA)(AA aa) {
return zip(aa.byKey, aa.byValue);
}

in std.array. Or object.di could just define a Pair!(K,V) structure which a
Tuple!(K,V) has an opAssign defined for it.


Re: Conclusions of the exception discussion

2012-02-25 Thread kennytm
"Daniel Murphy"  wrote:
> "deadalnix"  wrote in message 
> news:jiagbg$liu$1...@digitalmars.com...
>> Le 25/02/2012 07:26, Daniel Murphy a Ècrit :
>>> https://github.com/D-Programming-Language/dmd/pull/738
>> 
>> I do think this approach have a flaw. If we go in that direction, then it 
>> push devs to create new Exception type just to catch them, because this is 
>> the only way we have.
>> 
> 
> This is a different issue to whether or not we have the syntax to catch 
> multiple exceptions with a single catch block.
> 
>> If I understand properly your pull request, the compiler will be 
>> duplicating catch block ? If it is the case, would it be possible to use 
>> static if to use type specific stuff of E1, E2 or E3, depending on which 
>> one we are facing ?
>> 
> 
> No, it just creates stub catch blocks that jump to the real one. 
> Duplicating the blocks would have weird effects on things like static 
> variables.  I think that kind of code duplication is better done with 
> something that works like mixing in case statements.
> 
> catch(auto e : E1, E2) { body; }
> ->
> 
> catch(E1 e)
> {
>   goto catchE2;
> }
> catch(E2 e)
> {
> catchE2:
>   body;
> }

Won't work unless the compiler enforce that 'body' does not use code which
requires typeof(e) == E2.


Re: no matching function for call to ‘Type::d efaultInitLiteral()’?

2012-02-21 Thread kennytm
Andre Tampubolon  wrote:
> I just fetched the latest source code, and when I was trying to build dmd, I 
> got this:
> 
> func.c: In member function ‘MATCH 
> FuncDeclaration::leastAsSpecialized(FuncDeclaration*)’:
> func.c:2493:45: error: no matching function for call to 
> ‘Type::defaultInitLiteral()’
> func.c:2493:45: note: candidate is:
> mtype.h:304:25: note: virtual Expression* Type::defaultInitLiteral(Loc)
> mtype.h:304:25: note:   candidate expects 1 argument, 0 provided
> make: *** [func.o] Error 1
> 
> Any help?

Modify func.c as described in
https://github.com/D-Programming-Language/dmd/commit/907c94d#diff-2

Hopefully this will be fixed by tonight.


Re: The Right Approach to Exceptions

2012-02-20 Thread kennytm
"H. S. Teoh"  wrote:
> On Mon, Feb 20, 2012 at 03:17:44PM -0500, Nick Sabalausky wrote:
> [...]
>> 2. The solution fails to cover the *entire* scope of the *real* problem: 
>> Classes that need to write boilerplate ctors which merely forward to the 
>> base class's ctors.  This issue is *not* limited to Exceptions, but Andrei's 
>> proposes solution *only* covers the case with Exceptions.
>> 
>> A better solution has already been proposed:
>> 
>> class AcmeException : Exception
>> {
>> mixin inheritCtors!();  // Actual name open for bikeshedding
>> }
> 
> Somewhere in this giant thread, somebody has proposed that there should
> be language support for implicitly inheriting base class ctors. That is,
> if you write:
> 
>   class Base {
>   this(string, int, float) { ... }
>   }
> 
>   class Derived : Base { }
> 
> then the compiler will automatically insert this into Derived:
> 
>   this(string s, int i, float f) {
>   super(s, i, f);
>   }
> 
> I think this is a very useful mechanism that should be added to D. It
> will eliminate a lot of ctor boilerplate that you have to put in derived
> classes (not just exceptions, but in general). For example, if you have:
> 
>   class Base {
>   this(string) {...}
>   this(int) {...}
>   this(float) {...}
>   }
> 
> then currently, *every single derived class* must write wrappers to
> forward ctor arguments to each of those ctors, if they want to provide
> the same construction API as the base class. With the proposed
> enhancement, you'd just "inherit" all of the ctors automatically. (Not
> in the strict sense of inherit, but the compiler will create forwarding
> ctors for you automatically.)
> 
> 
> T

Note that this should work:

class Derived : Base {
  this(T...)(T values) { 
super(values);
  }
}


Re: size_t + ptrdiff_t

2012-02-19 Thread kennytm
Manu  wrote:
> I propose size_t + ssize_t should both exist, and represent the native
> integer size. 

sizediff_t (currently just aliased to ptrdiff_t but the link could be
broken). 

> Also something like ptr_t, and ptrdiff_t should also exist,
> and represent the size of the pointer.
> 

core.stdc.stdint.uintptr_t


Re: Version Identifiers for Platforms / Architectures not supported byDMD

2011-11-10 Thread kennytm
Jonathan M Davis  wrote:
> On Thursday, November 10, 2011 05:08:03 kennytm wrote:
>> Jonathan M Davis  wrote:
>>> On Thursday, November 10, 2011 04:07:43 kennytm wrote:
>>>> Perhaps DMD should generate a warning if a version of platforms does
>>>> not
>>>> have an else clause or that version's else clause's content is not
>>>> another version statement or a static assert.
>>> 
>>> Well, that does get a bit fuzzy. For instance, rather than duplicating
>>> that else clause all over the place in std.file, only the first static
>>> if-else clause has the else with the static assert in it. All of the
>>> others just have the branches that work and don't have an else clause.
>>> If we were to require that there be an else like that, then std.file
>>> wouldn't compile. And while it wouldn't be all that bad to have to put
>>> an else on all of those static-ifs, it _would_ result in unnecessary
>>> code duplication.
>>> 
>>> - Jonathan M Davis
>> 
>> I said version(Platform)s, not static if.
> 
> LOL. Yes. And I meant version(Platform). I obviously had my wires crossed 
> when 
> I wrote that. std.file uses
> 
> version(Posix)
> {}
> else version(Windows)
> {}
> 
> without an else block, except for the first one in the file which _does_ have 
> an 
> else which has a static assert(0) in it. Requiring that all such version 
> blocks had elses would invalidate that approach.
> 
> - Jonathan M Davis

Yes, but imagine there's a non-POSIX non-Windows platform (e.g. an embedded
system), and we make stdio to support it. After we add a
version(NewPlatform) branch to the one containing the static assert, the
compiler can no longer help us  to know some version statement in the
middle may have missed the NewPlatform. 

This is a contrived example, and I agree it would often be too strict, so I
think there should be individual warning switches.


Re: Version Identifiers for Platforms / Architectures not supported byDMD

2011-11-09 Thread kennytm
Jonathan M Davis  wrote:
> On Thursday, November 10, 2011 04:07:43 kennytm wrote:
>> Perhaps DMD should generate a warning if a version of platforms does not
>> have an else clause or that version's else clause's content is not another
>> version statement or a static assert.
> 
> Well, that does get a bit fuzzy. For instance, rather than duplicating that 
> else clause all over the place in std.file, only the first static if-else 
> clause 
> has the else with the static assert in it. All of the others just have the 
> branches that work and don't have an else clause. If we were to require that 
> there be an else like that, then std.file wouldn't compile. And while it 
> wouldn't be all that bad to have to put an else on all of those static-ifs, 
> it 
> _would_ result in unnecessary code duplication.
> 
> - Jonathan M Davis

I said version(Platform)s, not static if.


Re: Version Identifiers for Platforms / Architectures not supported byDMD

2011-11-09 Thread kennytm
Walter Bright  wrote:
> On 11/9/2011 6:46 AM, Daniel Murphy wrote:
>> But, as it is a breaking change (very slightly), and a
>> special case, I doubt this will ever happen unless Walter loves the idea.
>> Walter?
> 
> Sorry, I don't love the idea. I dislike it for its inconsistency with the
> rest of the language. The trend in programming languages and operating
> systems has, for a long time, been towards case sensitivity.
> 
> BTW, the correct way to write version sensitive code is:
> 
> version (linux)
> {
>...
> }
> else version (OSX)
> {
>...
> }
> else
>static assert(0, "unsupported OS version");
> 
> 
> Otherwise, it's miserable to find and tweak all the version sensitive
> code in your codebase. Here's a WRONG WRONG WRONG way:
> 
> version (linux)
> {
> ...
> }
> else /* Windows */
> {
> ...
> }
> 
> Looks stupid, but I tend to often see stuff like this in C, C++ and D
> source code. Even in my own. This is also why there's no ! for versions:
> 
> version (!linux)
> {
> ...
> }
> 
> Aaaaggg. I'm pretty fed up with seeing that crap in C code. And if
> you see any of it in dmd or phobos sources, please file a bugzilla report! 
> Show no mercy.

Perhaps DMD should generate a warning if a version of platforms does not
have an else clause or that version's else clause's content is not another
version statement or a static assert.


Re: an old topic (pun intended)

2011-10-28 Thread kennytm
Davidson Corry  wrote:
> On 10/27/2011 2:12 PM, Timon Gehr wrote:
>> Yes, this design has indeed a keyword-issue that your proposal has not.
>> I am all for not making it a keyword. The 'body' keyword imho should be
>> removed too, there is only one place in the grammar where it is ever
>> needed (and there it is completely redundant), therefore it could just
>> be lexed as an identifier. That would not break any code.
> 
> Agreed. In fact, it occurred to me the other day that we could write 
> contracts as
> 
> void foo(T t)
> {
> scope(in) {
>  // pre-condition contracts
> }
> scope(out) {
>  // post-condition contracts
> }
> // ...body of function...
> }
> 
> and eliminate the 'in', 'out' and 'body' keywords/constructs entirely.
> 
> Similarly, an invariant could appear in the default constructor of a class as
> 
> this()
> {
> scope(invariant) {
> // invariant guarantees...
> }
> // ...body of constructor...
> }
> 
> Or *any* constructor, really, although you would probably want the
> compiler to enforce that no more than one constructor defined a
> scope(invariant) block. This notation also suggests (correctly) that the
> invariant doesn't take effect until you have entered the constructor.
> (Exited it, really, but...)
> 
> -- Davidson

The contracts are parts of the function's interface, not implementation. If
you put the scope(in/out) inside the '{ ... }' how would a .di file handle
it?

And class invariant is also checked outside the constructor. Your syntax
makes it look like it will run only when the constructor is called.


Re: NULL indicator in Variant

2011-10-27 Thread kennytm
Steve Teale  wrote:
> How big a deal would it be to add a NULL indicator to the VariantN struct.
> 
> I use the term NULL as opposed to null deliberately. Variant already 
> provides the hasValue() method, which can serve as a null indicator. But 
> in using it as a parameter in database modules, it would be useful to be 
> able to give a Variant instance a type, as in v = "", but also to set it 
> explicitly as NULL with setNull() or whatever.
> 
> Could this fly without breaking existing code?
> 
> Steve

Just store a std.typecons.Nullable!T in the Variant.


Re: Why the hell doesn't foreach decode strings

2011-10-22 Thread kennytm
Walter Bright  wrote:
> On 10/22/2011 2:21 AM, Peter Alexander wrote:
>> Which operations do you believe would be less efficient?
> 
> All of the ones that don't require decoding, such as searching, would be
> less efficient if decoding was done.

You can std.algorithm.find to do searching, not foreach. The former can
decide whichever efficient method to use.


Re: Simple features that I've always missed from C...

2011-10-17 Thread kennytm
Manu  wrote:
> 
> *Min/Max operators:* GCC has the lovely ? operators... a  min(a, b) .. Why this hasn't been adopted by all C compilers is beyond me.
> Surely this couldn't be much trouble to add? Again, super useful in
> vector/maths heavy code too.
>

FYI, g++ has deprecated these operators long time ago (since 4.0). 

http://gcc.gnu.org/onlinedocs/gcc-4.0.4/gcc/Deprecated-Features.html


Re: BigInt memory usage

2011-10-12 Thread kennytm
Jay Norwood  wrote:
> I haven't looked at the std implementation, but I liked this guy's
> package in c++ .  He uses strings to hold the data, but you choose how
> the string packs the digits, with one of the choices being base 256 for
> the most efficient storage.It might be a nice fit for a D port.
> 

D's big-int *is* using base-256. (actually, base-(size_t.max+1))

> http://www.hvks.com/Numerical/arbitrary_precision.html
> 
> bearophile Wrote:


Re: Curious thoughts, regarding functional programming

2011-10-12 Thread kennytm
"Nick Sabalausky"  wrote:
> "Jacob Carlborg"  wrote in message 
> news:j740a6$2t8m$1...@digitalmars.com...
>> 
>> When this delegate is called you want to both be able to just return from 
>> the delegate but also return from "foo".
>> 
>> iterate(1, 10 ; int a)
>> {
>> if (a == 2)
>> yield; // soft return, just returns from the delegate
>> 
>> else if (a == 4)
>> return; // hard return, return from both the delegate and the 
>> function that called the delegate
>> }
>> 
>> Currently we only have "soft" returns from delegates.
>> 
> 
> Better (IMHO):
> 
> void foo()
> {
> iterate(int a; 1, 10)
> {
> if (a == 2)
> continue; // return from just the delegate
> 
> else if (a == 4)
> break; // return from both delegate and iterate
> 
> else if (a == 6)
> return; // return from the delegate, iterate, and foo
> }
> }
> 
> Ie, same syntax and semantics as foreach. Also, a couple new things that 
> foreach doesn't have to deal with:
> 
> auto x = map(i; 1, 10)
> {
> //continue; // Error: map's dg can't return void
> continue i*2; // OK
> }
> assert(x == [2, 4, 6, etc...]); // Conventiently ignoring ranges just for 
> the sake of illustration
> 
> Of course, maybe it would be better to require "yield" in such a case (and 
> maybe make "yield" synonymous with "continue" for void delegates?), but 
> there's a lot of resistance against new keywords.
> 
> And, one last thing to take care of:
> 
> auto x = iterate(i; 1, 10)
> {
> if(i == 4)
> {
> //break; // Error: need a return value
> break i*2; // OK
> }
> }
> assert(x == 8);

The 'break ' syntax conflicts with the 'break ' syntax, so -1
to this. 

i:
auto x = iterate(i; 1, 10) {
   foreach (j; 0 .. i)
  break i;   // what should it do?
   break i;
}

Perhaps you need to require parenthesis, like 'break (i);' and 'break
(i*2);'.


Re: Formal Review of std.regex (FReD)

2011-10-12 Thread kennytm
Dmitry Olshansky  wrote:
> On 12.10.2011 23:32, kennytm wrote:
>> Dmitry Olshansky  wrote:
>>> Fresh version of documentation is here:
>>> http://blackwhale.github.com/
>>> 
>>> This fixes all typos reported so far, adds missing overload of replace
>>> (ouch!) and introduces a brand new syntax table.
>> 
>> The '.' really matches any character, including the new line '\n'?
> 
> Hm, yes. Is that a problem?

Most regex flavors don't match '\n' by default unless you supply the "s"
flag -- including ECMAScript (well it doesn't even provide the "s" flag to
allow '.' to match all characters). 

While I am OK with having "s" turned on by default, this should at least be
documented explicitly.


Re: Formal Review of std.regex (FReD)

2011-10-12 Thread kennytm
Dmitry Olshansky  wrote:
> Fresh version of documentation is here:
> http://blackwhale.github.com/
> 
> This fixes all typos reported so far, adds missing overload of replace
> (ouch!) and introduces a brand new syntax table.

The '.' really matches any character, including the new line '\n'?


Re: questions: remove from SList

2011-10-11 Thread kennytm
"Steven Schveighoffer"  wrote:

> Yes, I'd agree either remove's implementation or its constraint 
> specification are buggy.  It should not specify that it needs a forward 
> range and then use bi-directional range primitives.
> 

I think remove's constraint is fine. With a SList you don't really want to
remove the current node, but the 'next' node. SList should provide the O(1)
removeNext and insertNext functions (c.f. C++11's std::forward_list).


Re: Matrix-type-friendly syntax and more

2011-10-10 Thread kennytm
"Robert Jacques"  wrote:
> On Mon, 10 Oct 2011 08:46:05 -0400, kennytm  wrote:
>> Don  wrote:
>>> On 10.10.2011 04:41, kenji hara wrote:
>>>> 2011/10/10 bearophile:
>>>>> So is this:
>>>>> y[$-6, 0..$:2]
>>>>> 
>>>>> Translated like this?
>>>>> y.opIndex(y.opDollar!0 - 6, y.opSlice!1(0, y.opDollar!1, 2))
>>>> 
>>>> I have no thought about it.
>>>> I'm not sure that the additional stepping is really useful, but I
>>>> think adding it into syntax is not impossible -- it might not conflict
>>>> with associative array literal.
>>>> 
>>>> Kenji Hara
>>> 
>>> Personally, I think that since strided operations are so inefficient,
>>> they should remain ugly.
>> 
>> Slicing an nD static array is just as in/efficient as strides. That said,
>> I'm still -1 on having a..b:c since (1) I see no practical need for strides
>> and (2) even if we striding it doesn't need to be in the form a..b:c, e.g.
>> arr[stride(0..$, 2)].
>> 
> 
> Regarding (1), from a computer vision/graphics perspective, being able to
> only operate on the red channel, for example, is very nice. And I use
> striding all the time in my CUDA code, but that's not as applicable in D,
> yet. Striding tends to be most useful for working with packed data of some 
> kind.

Why not use a 'Color' struct?


Re: Matrix-type-friendly syntax and more

2011-10-10 Thread kennytm
Don  wrote:
> On 10.10.2011 04:41, kenji hara wrote:
>> 2011/10/10 bearophile:
>>> So is this:
>>> y[$-6, 0..$:2]
>>> 
>>> Translated like this?
>>> y.opIndex(y.opDollar!0 - 6, y.opSlice!1(0, y.opDollar!1, 2))
>> 
>> I have no thought about it.
>> I'm not sure that the additional stepping is really useful, but I
>> think adding it into syntax is not impossible -- it might not conflict
>> with associative array literal.
>> 
>> Kenji Hara
> 
> Personally, I think that since strided operations are so inefficient,
> they should remain ugly.

Slicing an nD static array is just as in/efficient as strides. That said,
I'm still -1 on having a..b:c since (1) I see no practical need for strides
and (2) even if we striding it doesn't need to be in the form a..b:c, e.g.
arr[stride(0..$, 2)].


Re: Static arrays, typeof and IFTI?

2011-10-10 Thread kennytm
Norbert Nemec  wrote:
> Hi there,
> 
> after a very busy and eventful year in my personal life, I have now
> finally found some time to play with D2. I am very impressed by the
> progress!
> 
> One thing I noticed was that static arrays are somehow strangely limited:
> 
> It is possible to overload based on the length:
> 
> 
> void f(int[3] x) {
>writeln("int[3]: ",x);
> }
> 
> void f(int[4] x) {
>writeln("int[4]: ",x);
> }
> 
> int main(string argv[]) {
>f([1,2,3]);
>f([1,2,3,4]);
>return 0;
> }
> 
> 
> However, used as function template argument, a static array is casted to
> a dynamic array:
> 
> ---
> void g(T)(T x) {
>static assert (__traits(isStaticArray,T));
>enum N = T.init.length;
>writeln(N,": ",x);
> }
> 
> int main(string argv[]) {
>g([1,2,3]);
>return 0;
> }
> 
> 
> gives the error message:
> 
> |  Error: static assert  (__traits(isStaticArray,int[])) is false
> | instantiated from here: g!(int[])
> 
> Without the assertion, N is defined to 0.
> 
> Further investigation shows:
> 
> ---
>   g!(int[3])([1,2,3]);  // passes a static array
> ---
>   int[3] x3 = [1,2,3];
>   g(x3);// passes a static array
> ---
>   auto z3 = [1,2,3];// defines z3 as dynamic array
>   g(y3);// passes a dynamic array
> ---
> 
> So it seems, the problem is that array literals on their own turned into
> dynamic arrays unless you explicitly state a static array type in some way.
> 
> Wouldn't it make more sense the other way around? After all, turning a
> static array into a dynamic array is easy, the other way around is
> prohibited by the compiler. If array literals simply had a static array
> type, they could be implicitly casted to dynamic arrays when necessary
> but stay static if possible.
> 
> Greetings,
> Norbert

I think you could use something like

void f(T, size_t n)(T[n] param) { ... }

(not tested)


Re: How much to do

2011-10-07 Thread kennytm
bearophile  wrote:
> Recently lot of work has being done about "inout", and I think it is now 
> usable in D2.
> 
> So this has made me ask how much needs to be done (in D language and/or
> Phobos) to allow the correct compilation of exactly this useless demo
> program (I think it is correct):
> 
> 
> import std.algorithm, std.range, std.array;
> auto foo(in int[] data) pure {
> immutable int n = count!q{ a % 2 == 1 }(data);
> return map!q{ a * 2 }([n, n+1, n+2]);
> }
> void main() {
> auto a = array(iota(10));
> assert(equal(foo(a), [10, 12, 14]));
> }
> 
> 
> Currently count can't digest a const array and that map isn't pure. It
> runs if you remove "in" and "pure".
> 
> Once this program compiles I think std.algorithm becomes significantly more 
> usable.
> 
> Bye,
> bearophile

Allow a template argument to treat a const(T[]) as a const(T)[] is a
different and a known problem IIRC.


Re: Thoughts on improving operators

2011-10-05 Thread kennytm
Gor Gyolchanyan  wrote:
> The whole point was to put the question mark to a better use.
> I mean, it's used in the ternary operator exclusively.
> It's such a waste of a token.
> The question mark logically belongs to bools (which goes good with the
> ternary operator), but the bools are much more ofter worked with in
> the form of predicates, so I'd want to make that question mark more
> useful.

That could be said to '-' which is only used for subtaction. What a waste
of token. 

I'd say as long as the symbol alone is a valid token, it should never be
part of an identifier, doing else just gonna confuse anybody coming from
C-like languages, i.e. C, C++, C#, D, Java, JavaScript, etc.   

-1.

You've got a slightly better chance if you've suggested '#'.


Re: std.getopt suggestion

2011-10-05 Thread kennytm
Andrei Alexandrescu  wrote:
> On 10/5/11 6:53 AM, Regan Heath wrote:
>> On Tue, 04 Oct 2011 20:39:42 +0100, Andrei Alexandrescu
>>  wrote:
>>> Did it ever prevent you from getting anything done with it?
>> 
>> That's not the question we should be asking. The question we should be
>> asking is, will anyone ever want to re-use getopts parser for something
>> other than a once off command line parse for a command line application.
> 
> I don't think yours is the right question either. This thread has become
> illustrative of a trend that would be great to change course a bit. I
> sustained my position in this thread longer than necessary in an attempt
> to explain this to me and others.
> 
> Let me give a little context. This summer there was serious talk about
> using D at Facebook for a project that would last three months in
> development. D fulfilled all requirements, but had problems with library
> availability. For example, I was asked about D's connectivity to OpenSSL
> and MySQL. I told them they can translate the appropriate C headers
> manually or semi-automatically. They looked into it but they gave up
> because they saw this effort as a foreshadow of several other missing
> libraries. The barrier of entry for using OpenSSL or MySQL in Python is
> very low. The project was written in Python.
> 
> A friend of mine, startup owner, read TDPL cover to cover and loved it.
> Then he did some more research and spent $7000 on a top-of-the-line
> machine to run his service-based application, written in Python. This is
> because he figured he has a lot of libraries already available for Python
> that will accelerate his productivity, and estimated that for his
> projected load he can compensate the speed difference. "Not everybody is
> Google, Facebook, or Yahoo", he said.
> 
> There are other similar stories; these are the most recent I remember. We
> now have the GNU integration to get busy with, and we need a host of
> other APIs that connect us to the world. The right question is, can we
> afford to discuss packing three globals into one struct in std.getopt at this 
> time?
> 
> Making working code a tad better could go on forever, and might seem like
> progress. But it's not - it's asymptotic progress towards a local
> optimum, while we're looking at a hill of potential ahead.
> 
> I kindly suggest anyone with an interest in D's future to focus on moving
> the big rocks. We can worry about the gravel and the sand later.
> 
> 
> Thanks,
> 
> Andrei

I don't buy this. You make it sounds like the community cannot contribute
with more than 1 focus concurrently. The fact is that, the GCC integration,
making wrappers of C library and switching to non-global in std.getopt are
done in parallel by different subgroup of interests. I doubt if GDC will be
locked out of GCC or people will stop writing D wrappers just because 3
globals are proposed to be removed.


Re: The problem with std.conv.emplace

2011-10-04 Thread kennytm
Timon Gehr  wrote:
> On 04.10.2011 08:05, Benjamin Thaut wrote:
>> I'm currently trying to fix the problem I have with std.conv.emplace to
>> fully replace the deprecated new/delete operator overloading with a
>> template.
>> However it discovered that this is currently not possible, at least not
>> to my knowdelge. The problem is as follows:
>> 
>> class Foo {
>> }
>> 
>> class Test {
>> private:
>> Foo m_foo;
>> public:
>> this(Foo foo){
>> m_foo = foo;
>> }
>> 
>> void SetFoo(Foo foo){
>> m_foo = foo;
>> }
>> }
>> 
>> void main(){
>> void[__traits(classInstanceSize,Test)] mem = typeid(Test).init[];
>> emplace!Test(mem,null); //do not know how to create a object of type
>> test with args (void*)
>> }
>> 
>> If I however do the following it works (ignore the missing init part here):
>> void main(){
>> void[__traits(classInstanceSize,Test)] mem = typeid(Test).init[];
>> Test t = cast(Test)mem.ptr;
>> t.__ctor(null);
>> }
>> 
>> The same problem occurs when you do:
>> void CallSetFoo(T)(Test c,T arg){
>> c.SetFoo(arg);
>> }
>> 
>> CallSetFoo(new Test(),null);
>> 
>> It seems that null actually has it's own type but that type is not
>> exposed into the language and is lost as soon as null is passed to a
>> template. To a template null just looks like a void* and therefore can
>> not be used correctly any more.
>> 
>> Now one could write some code that would query all possible constructors
>> find a matching one and manually cast void* to the correct reference
>> type however this would require a runtime check for null to avoid
>> casting any void* to a reference, and I would highly prefer a solution
>> that would not require runtime checks to be safe.
>> 
>> My suggestion would be to actually give null it's own type and expose
>> that into the language so it can be correctly used with templates.
>> 
>> Any other ideas how to fix this? Maybe there is a way with the current
>> type system I don't know of.
>> 
> This works.
> 
> emplace!Test(mem,cast(Foo)null);
> 
> But I am totally supporting your suggestion. null should not decay to a
> void* on template argument boundaries, it has bugged me multiple times.
> 
> Is there already an enhancement request/bug report for this?

I did mention nullptr_t in 5899 .


Re: Mixed int/BigInt foreach interval

2011-09-27 Thread kennytm
"Jonathan M Davis"  wrote:
> On Tuesday, September 27, 2011 12:22 bearophile wrote:
>> Jonathan M Davis:
 foreach (i; 1 .. BigInt(10)) {}
>>> 
>>> No. That's foreach. BigInt isn't going to work with the .. syntax
>>> regardless of what isIntegral does. I assume what you're really asking
>>> is whether
>> 
>> I'm asking about foreach, not about iota. Fixing iota is easy, it's just a
>> matter of changing Phobos.
>> 
>> This is why at the top of my original post I have written:
>>> In my opinion it's important to make BigInts work in most places where
>>> normal ints work. I think it's even worth modifying D language a bit (if
>>> and where necessary) to allow this.
>> 
>> The point of my post was to talk about foreach. The title of this thread is
>> "Mixed int/BigInt foreach interval".
> 
> I'd be _very_ surprised to see that happen, since BigInt is in Phobos as 
> opposed to being at the language level. Ranges could be added to foreach, 
> because they're entirely API-based, and so the compiler doesn't have to care 
> about what Phobos is doing. It just has to do the appropriate lowerings. But 
> BigInt is a specific type in Phobos. Making it work with foreach would mean 
> that the compiler would have to know and understand about BigInt. I don't 
> expect that to ever happen. Best case, I would think that you could get it to 
> work by having BigInt be implicitly convertible to int, but since that's a 
> narrowing conversion, that's a _bad_ idea IMHO.
> 
> - Jonathan M Davis

foreach (a; b .. c) d;   is also a lowering, and i'd say the 'int + BigInt'
not able to typeCombine (statement.c:2282) a bug.

By the way, the statement

foreach (a; BigInt(1) .. 10) ...

does compile and work, at least for the toolset from git master.


Re: Issue 4705

2011-09-16 Thread kennytm
Andrei Alexandrescu  wrote:

> Heh, thanks. I reckon doing the equivalent for pointers would require
> some unsavory manipulation.
> 
> Andrei

You may want you check Python's "cmp_to_key" function. In terms of D it
would be like:

struct CmpToKey(alias binaryPred, T) {
  int opCmp(other) { return binaryPred(this, other); }
  T wrapped;
}

Then sort/min/max by `cmpToKey!"a

Re: Issue 4705

2011-09-16 Thread kennytm
kennytm  wrote:
> Andrei Alexandrescu  wrote:
> 
>> Heh, thanks. I reckon doing the equivalent for pointers would require
>> some unsavory manipulation.
>> 
>> Andrei
> 
> You may want you check Python's "cmp_to_key" function. In terms of D it
> would be like:
> 
> struct CmpToKey(alias binaryPred, T) {
>   int opCmp(other) { return binaryPred(this, other); }
>   T wrapped;
> }
> 
> Then sort/min/max by `cmpToKey!"a

Re: Pull 375 and related enhancements

2011-09-12 Thread kennytm
bearophile  wrote:
> Don:
> 
>> As I said in my other post, we could deal with this using a CTFE library 
>> solution.
> 
> Currently this works:
> 
> ubyte[10] a = [1, 2];
> void main() {}
> 
> But if you write this, I think padArrayLiteral returns an int[], so D
> refuses the implicit cast:
> 
> ubyte[10] a = padArrayLiteral(256, [1, 2]);
> void main() {}
>

Why you're padding to 256 entries when a ubyte[10] is needed? ;)
 
> So I think you have to write something like:
> 
> ubyte[10] a = padArrayLiteral!ubyte(256, [1, 2]);
> void main() {}
> 
> Bye,
> bearophile

Or:

auto a = staticArray!(ubyte[10])([1, 2]);

(staticArray() is like array() which can take arbitrary ranges, but it
returns a static array formed by take-ing the range and padding with
ElementType.init.)


Re: StaticFilter, PApply, Compose, template predicates

2011-09-05 Thread kennytm
bearophile  wrote:
> Robert Jacques:
> 
>>> Seconded.  StaticIota is extremely useful for loop unrolling optimizations, 
>>> e.g.:
>> 
>> vote++
> 
> vote--
> 
> StaticIota is not the good solution. I have explained why elsewhere:
> http://d.puremagic.com/issues/show_bug.cgi?id=4085
> 
> Bye,
> bearophile

vote += 2;

Who said staticIota is only used in static foreach? What if I want to
supply staticMap!(staticToString, staticIota!('a', 'z'+1)) as the default
argument of parameter names for 'naryFun'?


Re: toString or not toString

2011-09-01 Thread kennytm
Timon Gehr  wrote:
> On 09/01/2011 09:41 PM, Don wrote:
>> On 31.08.2011 14:35, Timon Gehr wrote:
>>> On 08/31/2011 04:41 AM, Jonathan M Davis wrote:
 Objects would have writeTo and toString would presumably be
 deprecated.
 
>>> 
>>> I have never understood the rationale behind deprecating toString once
>>> we have writeTo. Why should it be deprecated?
>> 
>> Code bloat. Every struct contains string toString().
>> Quite unnecessarily, since it can always be synthesized from the more
>> complete version.
> 
> I was just suggesting to keep the existing support for toString() inside
> to, format etc. Of course, all the structs in Phobos should probably
> completely migrate to writeTo.
> 
>> 
>> toString is great in case
>>> you just want to quickly and easily convert something to a string, and
>>> later, if formatting or more efficient output etc. is needed, the method
>>> can transparently be replaced by writeTo.
>> 
>> BTW, you do realize that code using writeTo is shorter in most cases?
>> The reason is, that it can omit all the calls to format().
>> Pretty much the only time when toString is simpler, is when it is a
>> single call to format().
>> It's only really the signature which is more complicated.
>> 
> 
> I am not convinced:
> 
> struct S{
> int x,y,z;
> void writeTo(void delegate(const(char)[]) sink, string format = null){
> sink("(");
> .writeTo(x,sink,"d"); // still no UFCS
> sink(", ");
> .writeTo(y,sink,"d");
> sink(", ");
> .writeTo(z,sink,"d");
> sink(")");
> }
> 
> string toString(){return "("~join(map!(to!string)([x,y,z]),", ")~")";}
> }

to!string of array can support multiple arguments:

string toString() {
return to!string([x, y, z], "(", ", ", ")");
}

and I believe writeTo could be made to accept extra arguments too:

struct S {
void writeTo(SomeType sink, const char[] format = null) {
[x, y, z].writeTo(sink, format, "(", ", ", ")");
}
...
}

void writeTo(T)(T[] arr, SomeType sink, const char[] format = null, const
char[] open = "[", etc) {
  ...
}


Re: NotNull pointers

2011-08-31 Thread kennytm
Timon Gehr  wrote:
> On 09/01/2011 01:03 AM, Timon Gehr wrote:
>> On 09/01/2011 12:26 AM, Simen Kjaeraas wrote:
>>> On Wed, 31 Aug 2011 23:54:04 +0200, Timon Gehr  wrote:
>>> 
> [2 * x ; x <- iota(10), log(x), x*x > 4]
> 
> or, in a library:
> 
> compr!q {2 * x ; x <- iota(10), log(x), x*x > 4};
> 
> 
 
 compr!q{2 * x ; x <- iota(10), log(x), x*x > 4};
>>> 
>>> The library solution has problems with scope variables.
>> 
>> I know, that is why I have not implemented this yet. Basically it should
>> be possible to implicitly pass a whole scope to a template, or at least,
>> to have local templates.
>> 
>>> Example:
>>> 
>>> auto foo(Range)(int n, Range r) {
>>> return compr!q{x * n; x <- arr, log(x), x*x > 4};
>>> }
>> 
>> Workaround:
>> auto foo(Range)(int n, Range r) {
>> mixin Compr!q{x * n ; x <- arr, log(x), x*x > 4};
>> return compr;
>> }
>> 
>> 
> 
> but
> 
> auto foo(Range)(int n, Range r) {
> return mixin(compr!q{x * n ; x <- arr, log(x), x*x > 4});
> }
> 
> is clearly better.

Hey guys, the expression 'x <- arr' always means "is x less than negation
of arr?" in D. Please choose another symbol.


Re: NotNull pointers

2011-08-31 Thread kennytm
Walter Bright  wrote:

> You might be surprised, then, that I'll often temporarily replace an
> assert with a HLT instruction so I can use a debugger on it :-)

> It's also possible for the program to have its own seg fault handler that
> reads its own symbolic debug info and generates a line number and stack
> trace. There was a patch to Phobos that did this a while back.
> 
> Optlink's register dump on a seg fault is not Windows' doing, it installs
> a seg fault handler which does this.

Please stop caring only about Windows. In Mac OS X because of the broken
dSYM and the ancient gdb (having no D support) supplied by Xcode, it's
almost impossible to get any valuable information - in particular the
__FILE__ and __LINE__ - from the debugger. 

> 15 bytes. And yes, this stuff adds up surprisingly quickly, especially if
> you're the type that wants to leave the asserts on even in release mode.

Then you should just kill D's RTTI, the TypeInfos from the unused template
instances pile up at a much faster rate. 15 bytes mean nothing then the
executable size is already in megabytes. Also, the proposal only affects
asserts of the form

assert(classObj);

all other asserts won't have those extra 15 bytes. I believe you're
strongly exaggerating, and I'd challenge you to compile Phobos with and
without the patch and compare if the size is really bloated a lot.


Re: Article about problems & suggestions for D 2.0

2011-08-28 Thread kennytm
Andrei Alexandrescu  wrote:
> On 8/27/11 12:14 PM, Benjamin Thaut wrote:
>> After having used the D 2.0 programming language for a year now and
>> having completed 3 projects with it, I wrote a small article about the
>> problems I had with the D 2.0 programming language and what suggestions
>> I have to improve it.
>> 
>> http://3d.benjamin-thaut.de/?p=18
> 
> On reddit:
> 
> http://www.reddit.com/r/programming/comments/jwkvx/suggestions_for_the_d_20_programming_language/
> 
> 
> Andrei

On the pattern matching syntax for templates in the comments -- Sigh, the
spec gotta advertise this valid syntax in the operator overloading page
more:

Foo opBinary(string op:"+")(...) { ... }


Re: Optional braces

2011-08-26 Thread kennytm
"Steven Schveighoffer"  wrote:

> Hm... the only problem I see with simply disallowing if(a) if(b) is this:
> 
> if(a)
>   while(condition)
> if(b)
>   statement;
> else // oops! this goes with if(b)
>   statement;
> 
> Or would this be disallowed as well?  This could not be combined into a 
> single if statement obviously, so the only the option to fix this is  adding 
> braces.
> 
> I'd hate to see this disallowed, which seems perfectly legitimate:
> 
> if(a)
>while(condition)
>   if(b)
> statement;
> 
> -Steve

I've created a patch* for dangling else checking. Your first example will
be banned and the second is allowed. Check the test cases there for more
examples.  

*: https://github.com/D-Programming-Language/dmd/pull/336


Re: Optional braces

2011-08-25 Thread kennytm
Walter Bright  wrote:

> We've already put a number of special cases in the grammar to ward off "bugs".
> 
> But I worry that we might wind up tarting up the language with too many a
> boatload of them, to the point where it becomes a confusing mass. At what
> point should Meg Ryan stop with the plastic surgery? :-)

The surgery is just that you need to add an error or warning when you see
an IfStatementWithElse (and TryStatement too?) used directly in a
ScopeStatement, and change ElseStatement's rule to IfStatementWithElse |
ScopeStatement.


Re: Optional braces

2011-08-24 Thread kennytm
Walter Bright  wrote:
> On 8/19/2011 8:12 AM, Andrei Alexandrescu wrote:
>> One thing I'd subjectively like is to require braces on both branches of 
>> if/else
>> if at least one has braces.
> 
> It's rather simple to just disallow the form:
> 
> if (a) if (b) statement
>^ error: use if(a&&b) or if(a){if(b)statement}
> 
> and not even pay attention if there's a dangling else or not. I've always
> viewed things like:
> 
> if (a)
>   if (b)
>  ...
> ...
> 
> with suspicion, anyway, dangling else or not.

Not sure if it's a big enough problem, but what about dangling else of this
form?

if (a.length > 0)
foreach (i, ref e; a)
if (i > 0)
 e += a[i-1];
else  // oops
throw new Exception("empty array");


Re: Optional braces

2011-08-19 Thread kennytm
Trass3r  wrote:
> Am 19.08.2011, 14:16 Uhr, schrieb Timon Gehr :
>> I think this makes code harder to read for no obvious benefit.
>> I don't think this is any better than
>> 
>> class Foo{
>>  private int a_;
>>  int a(){return a_;}
>>  int a(int a){return a_ = a;}
>> }
> 
> +1
> 
> Optional braces should be limited to statements.

I agree. Besides, a minor problem is that 'if' statements may be mistaken
as template conditions:

void f1(T)(T x)   if (isFoo!T) { x ++; } 
void f2(T)(T x) { if (isFoo!T) { x ++; } }


Re: Why do struct literals count as lvalues?

2011-08-19 Thread kennytm
Timon Gehr  wrote:
> On 08/19/2011 03:46 PM, kennytm wrote:
>> Timon Gehr  wrote:
>> 
>>> auto ref currently treats struct literals as lvalues too. (therefore, as
>>> ref). And passing by value would be considerably less efficient for large 
>>> structs.
>>> 
>>> As I understand it, the only issue with allowing literals and function
>>> results as lvalues is that generic code cannot detect if it is working
>>> with a temporary or not. I don't know if this would be useful in D though.
>>> 
>>> each code segment of the form:
>>> 
>>> void foo(ref S);
>>> ...
>>> foo(S(...));
>>> 
>>> is equivalent to one explicitly declaring the temporary:
>>> 
>>> {auto __temp=S(...); foo(__temp);}
>>> 
>>> The difference is that the first is more pleasant to write. If
>>> temporaries would become rvalues everyone would always have to write the
>>> second form manually. So imho it is just a syntax sugar issue.
>>> 
>>> I'd actually argue that ref-passing should work for arbitrary function 
>>> results too.
>> 
>> Here I propose that we go a step further and abolish the notion of rvalue
>> and lvalue entirely, and let the compiler insert necessary temporary
>> variable when needed, so that we can finally write things like
>> 
>>  uint w;
>>  memcpy(w,&5.0f, w.sizeof);
>>  13u = w;
>> 
>> 
> 
> And then of course you could do:
> 
> 5=6;
> assert(5==6);
> 
> It hasn't been working since the good ol' days of fortran =(.

Actually that assignment would just become an expensive no-op because it
will be rewritten into

(int __lvalue1243 = 5, __lvalue1243) = 6;

So the assert would still assert.


Re: newsgroup availability

2011-08-19 Thread kennytm
Timon Gehr  wrote:
> On 08/19/2011 03:44 PM, Steven Schveighoffer wrote:
>> Has there been some strange issue with the newsgroup lately? Frequently,
>> I'm getting load errors (I assume this means the NG load is too large to
>> deal with my communication).
>> 
>> It seems to be happening daily...
>> 
>> -Steve
> 
> It has been the same for me.

It's the same for everyone because it's a problem of the newsgroup server,
not the client. I guess the server(s) needs more CPU running in parallel to
reduce load.


Re: Why do struct literals count as lvalues?

2011-08-19 Thread kennytm
Timon Gehr  wrote:

> auto ref currently treats struct literals as lvalues too. (therefore, as
> ref). And passing by value would be considerably less efficient for large 
> structs.
> 
> As I understand it, the only issue with allowing literals and function
> results as lvalues is that generic code cannot detect if it is working
> with a temporary or not. I don't know if this would be useful in D though.
> 
> each code segment of the form:
> 
> void foo(ref S);
> ...
> foo(S(...));
> 
> is equivalent to one explicitly declaring the temporary:
> 
> {auto __temp=S(...); foo(__temp);}
> 
> The difference is that the first is more pleasant to write. If
> temporaries would become rvalues everyone would always have to write the
> second form manually. So imho it is just a syntax sugar issue.
> 
> I'd actually argue that ref-passing should work for arbitrary function 
> results too.

Here I propose that we go a step further and abolish the notion of rvalue
and lvalue entirely, and let the compiler insert necessary temporary
variable when needed, so that we can finally write things like

uint w;
memcpy(w, &5.0f, w.sizeof);
13u = w;




Re: Why do struct literals count as lvalues?

2011-08-18 Thread kennytm
Trass3r  wrote:
> struct A {}
> static A bar()
> {
> return A();
> }
> void foo(ref A a) {}
> void main()
> {
> foo(A());   // works
> foo(bar()); // doesn't
> }
> 
> Where's the difference?

The difference -- you've answered yourself in the title ;).

Reason why struct literals are lvalues -- because Walter and others believe
this is valid. Check the discussion in bugzilla issues 5178 and 5889. 

BTW, C99's compound literals also give lvalues.


Re: CURL review request

2011-08-18 Thread kennytm
Andrei Alexandrescu  wrote:

> I think we need to include curl with the Windows distribution. It's
> reasonable to assume connectivity is a broadly needed feature. We must
> solve the zip bloating issue for Unix people by breaking the zip per
> platform. Next to nobody ever wants to have Windows, Linux, FreeBSD, OSX,
> etc. files in the same distribution.
> 
> 
> Andrei

+1.

I've seen the per-platform zip suggestions many times, but still till now
no actions are taken. :( 


Re: About built-in AAs

2011-08-16 Thread kennytm
bearophile  wrote:
> 
> Now and then I compare the running time of C++0x code that uses
>  with the running time of the same operations done with D
> AAs and I don't see good timings for D. Are D AAs true templates or do
> they use some runtime typeid function? If they aren't true templates
> isn't it better to change this?
> 
> Bye,
> bearophile

They use runtime typeid functions. Some V[K] type and methods are converted
to AssociativeArray!(K, V) which itself is a proxy to those extern(C)
aaGetX() functions. Some methods will resolve to those aaGetX directly in
DMD. These functions can only know what types they're working on via the
typeid.  

IMO in DMD V[K]'s methods shouldn't be special. They should be treated just
as a syntactic substitution for the AssociativeArray!(K, V) type. The
latter shall implement opIndex etc for its normal operation. Druntime gets
to decide whether to continue using the C interface or turn it into a
concrete templated structure.  This also solves bug 5350.


Re: CURL review request

2011-08-16 Thread kennytm
Alix Pexton  wrote:

> 
> Some (all?) of the @property members of Protocol are documented as
> functions. (Perhaps an artefact of the ddoc mixin issue mentioned before this 
> section?)
>

Bug 3445. 
 
> Protocol.onProgress represents transfer statistics using doubles?
>

Unfortunately curl's API uses double.


Re: CURL review request

2011-08-16 Thread kennytm
Jonas Drewsen  wrote:
> Hi all,
> 
>This is a review request for the curl wrapper. Please read the "known
> issues" in the top of the source file and if possible suggest a solution.
> 
> We also need somebody for running the review process. Anyone?
> 
> Code:
>   https://github.com/jcd/phobos/blob/curl-wrapper/etc/curl.d
> Docs:
>   http://freeze.steamwinter.com/D/web/phobos/etc_curl.html
> 
> Demolish!
> 
> /Jonas

1) Why 'Http' and 'Ftp' but 'SMTP' is in all caps?
2) Some links in the doc says 'std.curl'


Re: Why callers should explicitly document storage classes

2011-08-14 Thread kennytm
Timon Gehr  wrote:
> On 08/14/2011 10:00 PM, Vladimir Panteleev wrote:
>> On Sun, 14 Aug 2011 22:48:18 +0300, Timon Gehr  wrote:
>> 
>>> requiring lazy before lazy arguments basically destroys the reason for
>>> lazy being in the language:
>>> 
>>> int foo(lazy 2*3);
>>> 
>>> is not better than
>>> 
>>> int foo({return 2*3});
>> 
>> What about requiring "lazy" only for non-pure delegates?
>> 
> 
> Actually I would rather require lazy arguments to be pure, so that they
> can be guaranteed to be executed at most once.

One problem: It is expected that the lazy argument can be re-evaluated. D's
`lazy` is actually call-by-name, which allowed stuff like 


void dotimes(int count, lazy void exp)
{
for (int i = 0; i < count; i++)
   exp();
}
void foo()
{
int x = 0;
dotimes(10, writef(x++));
}


as documented in http://www.d-programming-language.org/lazy-evaluation.html


Re: ref parameters: there is no escape

2011-08-14 Thread kennytm
Andrei Alexandrescu  wrote:
> Walter and I have had a long discussion and we thought we'd bring an idea
> for community review.
> 
> We believe it would be useful for safety purposes to disallow escaping
> addresses of ref parameters. Consider:
> 
> class C {
>   int * p;
>   this(ref int x) {
> p = &x; // escapes the address of a ref parameter
>   }
> }
> 
> Such code is accepted today. We believe it is error-prone and dangerous,
> particularly because the caller has no syntactic cue that the address of
> the parameter is passed into the function (in this case constructor). 

Well, you could adopt bug 6442 and call the constructor as

auto c = new C(ref x);

 

> Worse, such a function cannot be characterized as @safe.
>
> So we want to make the above an error. The workaround is obvious - just
> take int* as a parameter instead of ref int. What a function can do with
> a ref parameter in general is:
> 
> * use it directly just like a local;
> 
> * pass it down to other functions (which may take it by value or reference);
> 
> * pass its address down to pure functions because a pure function cannot
> escape the address anyway (cool insight by Walter);
>

Does this mean strongly pure? Because for now we can write a weakly pure
function 

pure int* escape(int* q) { return q; }

and change that constructor to 

this(ref int x) { p = escape(&x); } 
 
> * take its address as long as the address doesn't outlive the frame of the 
> function.
> 
> The third bullet is not easy to implement as it requires flow analysis,
> but we may start with a conservative version first. Probably there won't
> be a lot of broken code anyway.
> 
> Please chime in with any comments you might have!
> 
> 
> Thanks,
> 
> Andrei


Re: DB ORM

2011-08-12 Thread kennytm
zhang  wrote:
>> Graham Fawcett wrote.
>>> On Thu, 11 Aug 2011 20:10:15 +0800, zhang wrote:
>>> 
>> I think D needs user defined attributes first.
 
 About attribute, here is an example:
 
 
 
 There is a problem that is D's basic type is not nullable. In C#,
 the nullable integer type can be defined as "Int?" or
 "Nullable".
>>> 
>>> You don't need attributes for that: you can just define a "struct
>>> Nullable(T)" that wraps the value, and provides a way to express a
>>> null value.
>>> 
>>> struct Person {
>>>   int ID;   // required
>>>   Nullable!int age; // optional
>>>   ...
>>> }
>>> 
>>> void foo(Person p) {
>>>   if (p.age.isNull) ...
>>>   else writeln(p.age + 100);
>>> }
>>> 
>>> Graham
>> 
>> Alternatively you just use a class to wrap the value:
>> 
>> template Nullable(T){
>> static if(is(T == class)) alias T Nullable;
>> else class Nullable{T v; alias v this;}
>> }
>> 
>> 
>> The benefit of this approach is that you don't have to invent new ways to 
>> test for
>> null values.
> 
> That's it. So, the nullable basic type is not a problem. Thanks.
> --
> Zhang 

There used to be std.typecons.Nullable, but was disabled. Can you please
check if there's any improvements to
https://github.com/D-Programming-Language/phobos/pull/153?


Re: Signed-unsigned comparisons in Phobos

2011-08-12 Thread kennytm
Don  wrote:

> I've had a look at a dozen or so of these, and they were all real. I
> didn't see any which require a cast to "make the compiler shut up".
> That's pretty impressive. In C++ I find that such messages are nearly
> always false positives.
> 
> The one case where it's a bit annoying is this:
> 
> int [] x = new int[6]; // or x = some array literal.
> for (int i = 0; i < x.length; ++i) {...}
> 
> Here is a suggestion for how we could eliminate such false positives.
> http://d.puremagic.com/issues/show_bug.cgi?id=6478

Doesn't this require flow analysis? And the type of index 'i' should be
'size_t' anyway.


Re: DIP11

2011-08-11 Thread kennytm
"Steven Schveighoffer"  wrote:
> On Thu, 11 Aug 2011 17:20:04 -0400, Nick Sabalausky  wrote:
> 
> > "Andrei Alexandrescu"  wrote in
> > message
> > news:j21g1a$ea4$1...@digitalmars.com...
> >>
> >> It's difficult to get all dependencies when not all sources have
> > > been  >> yet
> >> downloaded.
> >>
> >
> > With DIP11, yes. With a traditional-style package manager, no.
> 
> With either style, you need to download a package in order to
> determine if  you need to download other packages (package a may
> depend on package b  even though your project does not depend on
> package b).  The DIP11 version  does this JIT, whereas your version
> does it before compilation.  It's not  really any different.
> 
> -Steve
> 

In Debian's apt, there will be a central index that records all
dependencies for packages in the repository. So the client only needs to
synchronize that index file regularly. The system will know package A
depends on B which depends on C and D and download all 4 packages.

That said, since you need to download the pakcgaes anyway, having a
central index doesn't reduce the bytes you need to transfer and parse if
DIP11 doesn't support updating.


Re: halt with optional message?

2011-08-11 Thread kennytm
"Jonathan M Davis"  wrote:
[snip] 
> Because that would be inefficient. As it stands, there's no way to
> tell the 
> compiler, "use this library in release mode but use this library in
> debug 
> mode." 

Can't you use -defaultlib and -debuglib?


Re: Why do shift operators undergo integral promotion?

2011-08-10 Thread KennyTM~

On Aug 10, 11 01:06, Walter Bright wrote:

On 8/9/2011 2:46 AM, Don wrote:

From a discussion on D.learn.

If x and y are different integral types, then in an expression like
x >> y
the integral promotion rules are applied to x and y.
This behaviour is obviously inherited from C, but why did C use such a
counter-intuitive and bug-prone rule?
Why isn't typeof(x >> y) simply typeof(x) ?
What would break if it did?

You might think the the rule is that typeof( x >> y) is typeof( x + y),
but it isn't: the arithmetic conversions are NOT applied:
typeof(int >> long) is int, not long, BUT
typeof(short >> int) is int.
And we have this death trap (bug 2809):

void main()
{
short s = -1;
ushort u = s;
assert( u == s );
assert ( (s >>> 1) == (u >>> 1) ); // FAILS
}



That last is why we can't just change the behavior from C.


Does C or C++ even have a '>>>' operator? If we need to have a 
type-promotion rule like C, it could be made as


x >>> y   ==  cast(promoted type) cast(typeof(x)) (unsigned(x) >> y)

e.g.

cast(short)(-1) >>> 1  == 0x7f.


Re: PSP emulator written in D

2011-08-10 Thread KennyTM~

On Aug 10, 11 05:15, bearophile wrote:

This again shows that some common basic exceptions are needed in Phobos:
http://code.google.com/p/pspemu/source/browse/trunk/src/pspemu/Exceptions.d


These exceptions are not common or basic. I think it's better to make 
constructors inheritable when there are no new members, or add something 
like this to std.exception:


---
mixin template ExceptionConstructors() {
this(string msg, string file = __FILE__, size_t line = __LINE__, 
Throwable next = null) {

super(msg, file, line, next);
}
this(string msg, Throwable next, string file = __FILE__, size_t 
line = __LINE__) {

super(msg, next, file, line);
}
}
---

So those custom exceptions can be created as

class TimeoutException : Exception {
   mixin ExceptionConstructors;
}


Re: Post-ctor ctor

2011-08-08 Thread KennyTM~

On Aug 9, 11 05:05, Andrej Mitrovic wrote:

Done deal:

import std.traits;

string FieldInit(T, int len, string fun)()
{
 string result;
 auto fields = [__traits(allMembers, T)];

 result ~= "this(";

 foreach (y, x; (RepresentationTypeTuple!T)[0..len])
 {
 result ~= x.stringof ~ " " ~ fields[y] ~ ", ";
 }

 result = result[0.. $-2] ~ ") { ";

 foreach (x; 0 .. len)
 {
 result ~= "this." ~ fields[x] ~ " = " ~ fields[x] ~ "; ";
 }

 result ~= fun ~ "();";
 result ~= "}";

 return result;
}

struct Foo
{
 int a;
 int b;
 int c;
 int d;

 mixin( FieldInit!(typeof(this), 4, "_this") );

 int sum;
 int average;

 void _this()
 {
 sum = a + b + c + d;
 average = (a + b + c + d) / 4;
 }
}

void main()
{
 auto foo = Foo(1, 2, 3, 4);

 assert(foo.sum == 10);
 assert(foo.average == 2);
}

Mostly.. Of course it doesn't work too good if the fields are placed
below some functions.


Template-mixin is often shorter and less error-prone.


-

mixin template FieldInit(size_t count, alias fun)
{
this(RepresentationTypeTuple!(typeof(this))[0..count] params)
{
foreach (y, x; __traits(allMembers, typeof(this))[0..count])
__traits(getMember, this, x) = params[y];
fun();
}
}

struct Foo
{
int a;
int b;
int c;
int d;

int sum;
int average;

void _this()
{
sum = a + b + c + d;
average = (a + b + c + d) / 4;
}

mixin FieldInit!(4, _this);
}

-


Re: CTFE writeln again (__ctfeWriteln)

2011-08-08 Thread KennyTM~

On Aug 9, 11 03:19, bearophile wrote:

KennyTM~:


I understand that you could implement `writeln` in terms of `write`, but
I question its practical value.   Why do you need to print a tree at
compile time?  pragma(msg) and __ctfeWriteln are mainly for debugging,
and adding a newline is very suitable (e.g. it won't mess up the error
message in the next line).


What if you are debugging a program (as I have written) that uses trees? I'd 
like the freedom to print textual trees one piece at a time (in Python I have 
written two or three small programs that print trees textually). It's not just 
trees, it's also other 2D tables. If you add the newline then I am forced to 
print one table line at a time, I can't print its items one after the other.

Even if printing at compile-time is mainly for debugging, if you add that 
newline you make other unexpected future usages harder. You do not know how D 
will be used ten years from now.

In Python2 there the main printing statement adds a space between printed 
items. This is quite handy. But what if you do not want that space? Things gets 
harder. They have had to wait for Python3 to fix this design mistake.

The moral of the Python2 story is that you are allowed to add a handy printing 
function (that adds newlines and spaces) only if you _also_ have a function 
that prints nude strings (or nude chars). But if you have only one function, 
then it has to be a function that doesn't add extra things that you can't 
remove.

(An alternative design, if you want a single function is a function templated 
on a boolean __ctfeWrite!(bool newline=true)(...). I don't know how much nice 
this is).

Bye,
bearophile


A __ctfeWrite could certainly be added 10 year from now if that's 
required, but at the current stage, I still see no compelling reason for 
that. If you have a tree, probably you'd write a toString() anyway, and 
for a 2D table, you could write a whole row at a time as an array.


foreach (row; twoDarray) {
  __ctfeWriteln(row);
  ...
}

Meanwhile, using __ctfeWrite improperly could easily mess up with error 
messages which breaks IDE on locating the line of error.


1, 2, 3, x.d(55): Error: dereference of null pointer 'null'
x.d(47): Error: cannot evaluate delegate pure nothrow @system int()

Python's print statement/function is irrelevant. We're not talking about 
printing at runtime where having the possibility to format things pretty 
is essential. Printing things at compile time should always be for 
debugging or error reporting which should be kept simple.


Unless there are more _people_ supporting this, or the authority (those 
who can commit into DMD directly) require having a __ctfeWrite, I'll 
refrain from adding this generalization to D2.


Re: Tagging of arguments ref/out, or just out

2011-08-08 Thread KennyTM~

On Aug 9, 11 02:32, Kagamin wrote:

bearophile Wrote:


This is a recently opened (not by me) enhancement request thread:
http://d.puremagic.com/issues/show_bug.cgi?id=6442


D is the language to save keystrokes. This proposal is plain invalid.


I disagree. If you want to save keystrokes, use Perl.

"D is a multi-paradigm programming language that combines a principled 
approach with a focus on practicality. In D you get to harness the power 
and high performance of C and C++ and also the safety and programmer 
productivity of modern languages such as Ruby and Python. Special 
attention is given to the needs of quality assurance, documentation, 
portability, and reliability."


Nowhere mentions saving keystrokes. The proposal is OK, as a mean to 
provide reliability (where you ensure a variable passed is not modified 
in opaque because it is pass by 'ref') and documentation at call-site.


Re: CTFE writeln again (__ctfeWriteln)

2011-08-08 Thread KennyTM~

On Aug 8, 11 06:45, bearophile wrote:

KennyTM~:


__ctfeWrite is not complex, but I don't see the need for it.


I don't understand your point. Given __ctfeWrite you are able to create a 
__ctfeWriteln but you can't do the opposite.

If I have to print something complex, like something tree-shaped, and I have 
just __ctfeWriteln, to create the printing I need to first put everything into 
a huge string, and print it. If I have __ctfeWrite I am able to write it one 
bit at a time.

Not having a compulsive newline was the strongest requirement in my original 
enhancement request:
http://d.puremagic.com/issues/show_bug.cgi?id=3952

The obligatory newline of pragma(msg) has given me several problems, it's much 
less useful because of this.

Bye,
bearophile


I understand that you could implement `writeln` in terms of `write`, but 
I question its practical value.   Why do you need to print a tree at 
compile time?  pragma(msg) and __ctfeWriteln are mainly for debugging, 
and adding a newline is very suitable (e.g. it won't mess up the error 
message in the next line).


Re: CTFE writeln again (__ctfeWriteln)

2011-08-07 Thread KennyTM~

On Aug 8, 11 05:56, bearophile wrote:

KennyTM~:


So I go for my 2nd alternative, which is to add a magic function __ctfeWriteln
that does the same.

In my implementation, __ctfeWriteln will print the interpreted arguments
to stdmsg when CTFE-ed, and is a no-op in runtime (it can be configured
to throw an exception or actually print the arguments or anything you like).


Important: if there is a single function then I do *not* want it to print a 
newline. Adding a newline when you need it is much simpler than removing it if 
you do not want it. If you really want a newline too, then create two 
functions, (similar to write and writeln), but the most important is the one 
without newline.

What's the purpose of the two leading underscores? I prefer it without them. This is 
supposed to be a clean and nice function, not an unsafe ugly thing :-) So I think a 
"ctfeWrite" name is better.



Two leading underscores means it's a reserved identifier which should 
have no chance of collision.  It does not mean unsafe.  Also, it's named 
after the existing identifier '__ctfe'.



Generally I'd like this functions to print equally at compile-time and 
run-time, but I see there are some problems in doing this...

If the function"ctfeWrite" becomes too much complex (to print arbitrary 
things), then for me it's acceptable it to print just strings too (with no newline added).



__ctfeWrite is not complex, but I don't see the need for it.


Bye and thank you for your work,
bearophile




CTFE writeln again (__ctfeWriteln)

2011-08-07 Thread KennyTM~

Pull request: https://github.com/D-Programming-Language/dmd/pull/296

Previous discussion: 
http://www.digitalmars.com/d/archives/digitalmars/D/CTFE_writeln_140241.html


This is the 2nd try to add a compile-time printing facility to D. The 
previous pull request uses std.stdio.writeln which causes some concern, 
and then left unattended for a few weeks after the last comment. So I go 
for my 2nd alternative, which is to add a magic function __ctfeWriteln 
that does the same.


In my implementation, __ctfeWriteln will print the interpreted arguments 
to stdmsg when CTFE-ed, and is a no-op in runtime (it can be configured 
to throw an exception or actually print the arguments or anything you like).


Re: Run Microsoft Analyzer over dmd source code

2011-08-07 Thread KennyTM~

On Aug 8, 11 03:08, KennyTM~ wrote:

On Aug 8, 11 02:45, bearophile wrote:

Vladimir Panteleev:


http://thecybershadow.net/d/vcanalysis/


As with (first report of) Clang I see that assert(p); p->foo... are
marked as "Dereferencing NULL pointer".


Do you know the purpose of this?
os->name = strdup(name);
warning C4996: 'strdup': The POSIX name for this item is deprecated.
Instead, use the ISO C++ conformant name: _strdup. See online help for
details. c:\Program Files (x86)\Microsoft Visual Studio
10.0\VC\include\string.h(238) : see declaration of 'strdup'



http://stackoverflow.com/questions/14386/fopen-deprecated-warning



Oops sorry that link is for those silly _s versions. _strdup is actually 
worse, it's only because Microsoft has chosen to add a '_' to all POSIX 
functions with no good reason (maybe just §17.6.4.3.2=[global.names]/1).


http://msdn.microsoft.com/en-us/library/y471khhc%28v=VS.100%29.aspx

I recommend ignoring all C4996 since the DMD source code shouldn't just 
accommodate for MSVC.




And do you know what kind of troubles this warning helps to avoid?
c:\projects\extern\d\dmd\src\root\dchar.h(164): warning C6328: 'char'
passed as parameter '1' when 'unsigned char' is required in call to
'isalpha'



You could search the error code in Google to get the info in MSDN.

http://msdn.microsoft.com/en-us/library/ms245348%28v=VS.100%29.aspx:

"For routines starting with is*, passing an argument of type char might
yield unpredictable results. For example, an SBCS or MBCS single-byte
character of type char with a value greater than 0x7F is negative. If a
char is passed, the compiler might convert the value to a signed int or
a signed long. This value could be sign-extended by the compiler, with
unexpected results."


Bye,
bearophile






Re: Run Microsoft Analyzer over dmd source code

2011-08-07 Thread KennyTM~

On Aug 8, 11 02:45, bearophile wrote:

Vladimir Panteleev:


http://thecybershadow.net/d/vcanalysis/


As with (first report of) Clang I see that assert(p); p->foo... are marked as 
"Dereferencing NULL pointer".


Do you know the purpose of this?
   os->name = strdup(name);
warning C4996: 'strdup': The POSIX name for this item is deprecated. Instead, 
use the ISO C++ conformant name: _strdup. See online help for details. 
c:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\string.h(238) : 
see declaration of 'strdup'



http://stackoverflow.com/questions/14386/fopen-deprecated-warning



And do you know what kind of troubles this warning helps to avoid?
c:\projects\extern\d\dmd\src\root\dchar.h(164): warning C6328: 'char' passed as 
parameter '1' when 'unsigned char' is required in call to 'isalpha'



You could search the error code in Google to get the info in MSDN.

http://msdn.microsoft.com/en-us/library/ms245348%28v=VS.100%29.aspx:

"For routines starting with is*, passing an argument of type char might 
yield unpredictable results. For example, an SBCS or MBCS single-byte 
character of type char with a value greater than 0x7F is negative. If a 
char is passed, the compiler might convert the value to a signed int or 
a signed long. This value could be sign-extended by the compiler, with 
unexpected results."



Bye,
bearophile




Re: Run Microsoft Analyzer over dmd source code

2011-08-07 Thread KennyTM~

On Aug 7, 11 22:23, Vladimir Panteleev wrote:

On Sun, 07 Aug 2011 13:29:20 +0300, Walter Bright
 wrote:


It's less complex (!) if you are not trying to make a working dmd. It
just needs to compile.


OK, that wasn't actually too bad.
https://github.com/CyberShadow/dmd/tree/compile-on-vs10

2979 warnings with code analysis with the "Microsoft Minimum Recommended
Rules" ruleset.
http://dump.thecybershadow.net/2e0571641194d945869a1b12b29aacdc/DMD.log

I'll see if I can get it in a more readable format (something like the
HTML files clang's scan-build outputs).



Just at a glance, half of them are false positive, or is arguably safe:

1. 382 (13%) of them are C4996 (use those Microsoft _s functions)
2. 401 (13%) of them are C4068 (unknown pragma)
3. 505 (17%) of them are C6328 (passing 'signed char' to the ctype 
functions)
4. 67 (2%) of them are C6239 (true && something) or C6240 (something && 
true) - many of them are of them (!I16 && stuff), so that's legacy code 
for 16-bit platform??
5. 37 (1%) of them are C6255 (using alloca) or C6263 (using alloca in a 
loop).

6. 56 (2%) of them are C4305 or C4309 (double -> float)

And 37% of them can be caught trivially with some -Wall flag.

4. 262 (9%) of them are C4244 (stuff like int64 -> int32)
5. 415 (14%) of them are C4018 (signed/unsigned comparison)
6. 157 (5%) of them are C4101 (unused locals)
7. 50 (2%) of them are C4102 (unused labels)
8. 212 (7%) of them are C6246 or C6244 or C4258 (local variable name 
hiding outer scope)

9. 8 (0.3%) of them are C4390 ('if(stuff);')

The really interesting things:

8. 117 (4%) of them are C6211 (leak on exception) - but a bigger problem 
is DMD is using too much memory even without leaking.

9. 34 (1%) of them are C6001 (using uninitialized memory)
10. 125 (4%) of them are C6011 (NULL dereferencing)
11. 6 (0.2%) of them are C6386 and 17 (0.6%) of them are C6385 (buffer 
overrun)


Re: Two bugs found: GC bug as well as scope delegate bug

2011-08-07 Thread KennyTM~

On Aug 7, 11 14:47, Mehrdad wrote:

Everyone, apologies for this in hindsight, it's quite ridiculous. x_x

In trying to reproduce a similar bug I saw in my code, I made a
completely stupid example which made no sense.

I'll proofread better next time, hopefully I can isolate it then.


Next time you should file the bug directly to bugzilla 
(http://d.puremagic.com/issues/).


Re: What library functionality would you most like to see in D?

2011-08-03 Thread KennyTM~

On Aug 3, 11 13:53, Lutger Blijdestijn wrote:

Jimmy Cao wrote:


2011/8/2 so


On Tue, 02 Aug 2011 03:51:56 +0300, Brad Roberts<
bra...@slice-2.puremagic.com>  wrote:

  I don't think that any gui library belongs in phobos because there's

essentially no agreement about what cross-platform library is standard.
Pick any random 10 gui developers about what library they used (assuming
they do anything cross-platform) and you'll get more than 1 answer.  I'd
be shocked if you get a clear enough majority to suggest 1 that'd make a
big set of people happy.

Sorry, the gui library landscape just doesn't approach being obvious
enough to be in the standard library.

My 2 cents,
Brad



I agree, GUIs (and other huge libraries that everyone has their own
favorite) don't belong standard library. Other languages get away with it
because they are either platform themselves or support only one platform.
Another reason not to include them to the standard library, remember
phobos has rules (we might need to change many things).
But if we have something small, simple and cross-platform somewhere, why
not!



If a GUI library were included in Phobos, that would make D a much better
competitor against C#.  That's why I hope such an inclusion would be
possible in the future.  I see why it might not be possible, though.


I really doubt that. You don't get to really compete with C# until D runs on
.NET and perhaps even until microsoft adopts it. I don't think a standard
gui lib will make any difference.



There was a D.net (which seems no longer updated), and when D runs on 
.NET, the language can use all .NET libraries like WinForms and WPF 
immediately, and there's no need to have another GUI lib.


(And why D needs to compete against C#?)


Re: pi benchmark on ldc and dmd

2011-08-02 Thread KennyTM~

On Aug 2, 11 20:00, Jason House wrote:

The post says they did "dmd -O". They did not mention "-inline -noboundscheck 
-release". There may be extra flags that are required.

Walter Bright Wrote:


http://www.reddit.com/r/programming/comments/j48tf/how_is_c_better_than_d/c29do98

Anyone care to examine the assembler output and figure out why?




Let dmd have an '-O' flag to as a synonym of '-O -inline 
-noboundscheck -release' so people won't miss the extra flags in 
benchmarks. [/joke]


Re: What does C++ do better than D? - StackOverflow.com

2011-08-01 Thread KennyTM~

On Aug 2, 11 02:29, Kagamin wrote:

Walter Bright Wrote:


Now on reddit!

http://www.reddit.com/r/programming/comments/j48tf/how_is_c_better_than_d/


C++ has a better thought out type system.
Nice joke.
http://blog.llvm.org/2011/05/c-at-google-here-be-dragons.html


Note that D fails to catch the 2nd error (sizediff_t kMaxDiskSpace = 10 
<< 30) either.


Re: Fixing enum names in Phobos

2011-08-01 Thread KennyTM~

On Aug 1, 11 16:00, Alex Rønne Petersen wrote:

On 01-08-2011 09:39, Jonathan M Davis wrote:

On Monday 01 August 2011 15:02:54 KennyTM~ wrote:

On Aug 1, 11 13:56, %u wrote:

How do you plan on camelCasing pure, nothrow, out, ref, etc?


pure_, nothrow_, out_, ref_

pureAttribute, nothrowAttribute, outAttribute, refAttribute


Yeah. Something like that. You'd have to add a prefix or a suffix to
them all.
But the fact that you can't actually just camelcase them might be a good
argument for leaving them as-is. If we're willing to change them
though, a
simple prefix or suffix shouldn't be all that big a deal - especially
if it's
shorter rather than longer.

- Jonathan M Davis


I may very well be biased since I come from .NET land, but I have to
say, camel case enum member names do seem a bit weird to me. While enum
members could be argued to be fields, they certainly don't have those
semantics, so maybe pascal case might not be so bad?

- Alex


In .NET (almost) everything is CapitalCamelCased :D

Anyway, the rule of thumb is
 - Things are CapitalCamelCased if they can create a type
 - Otherwise, they are smallLetterCamelCased

Enum members aren't types, so they shouldn't be CapitalCamelCased.



Re: Idea for @annotations

2011-08-01 Thread KennyTM~

On Aug 1, 11 13:42, %u wrote:

An idea for a potential use of annotations:

How about being able to annotate _anything_ with a template?

It would be the equivalent of Python's annotations: the template's
first parameter would be an alias to the thing being annotated, and
its return value would be the code generated for that element. Of
course, if there's no transformation being done, then it should
simply "return" the alias itself.



+1.


This would allow you to say something like:

auto memoize(alias Fn, T...)(T args) { /* memoize code here */ }

@memoize
int fib(int n) { ... }

which would be somewhat (but not completely) "equivalent" to

mixin memoize!(function int(int n) { ... });



I believe you mean

alias memoize!() fib;

your @property below won't work as a mixin.

Also, self-reference should be handled:

@memoize
ulong fib(ulong n) {
   return n < 2 ? 1 : fib(n - 2) + fib(n - 1);
//^^^ recursion^^^
}

@exportName("F/List")
class F_List {
   int content;
   F_List next;
// ^^ self-reference
}

This works in Python trivially because functions and classes are 
looked-up by name in runtime. This isn't true in D, at least if it's a 
simple alias-ing.




And more trivial things like @property would simply be
template property(alias A) { alias A property; }
with their sole effect being extra information found with
reflection.



I'd prefer to make it more explicit, e.g. use a __traits to include that 
extra information:


alias __traits(setAnnotation, X, "foo.prop", 1234) Y;
// Y is a copy or reference of X but with the extra property

enum prop = __traits(getAnnotationy, Y, "foo.prop");
// returns 1234, compile-time error if 'foo.prop' does not exist.

enum prop = __traits(getAnnotationy, Y, "foo.bar", false);
// same as above but with a default value.

static if (__traits(hasAnnotation, Y, "foo.prop"))
alias __traits(removeAnnotation, Y, "foo.prop") Z;

So, e.g. one could write

template serializable(alias F) if (is(f == struct) || ...) {
alias __traits(setAnnotation, F, "mymodule.serializable", true) 
serializable;

}

...

@serializable
struct MyObject {
   int x;
   ...
}

and the serializer can check with

auto serialize(F)(F x) if (__traits(getAnnotation, F, 
"mymodule.serializable", false)) {

   ...
}



Implementing this would obviously be difficult as I would assume,
but does it sound like a reasonable idea?


Would you mind to write a DIP? 
(http://www.prowiki.org/wiki4d/wiki.cgi?LanguageDevel/DIPs)


(Speaking of which, what happened to DIP11?)


Re: Fixing enum names in Phobos

2011-08-01 Thread KennyTM~

On Aug 1, 11 13:56, %u wrote:

How do you plan on camelCasing pure, nothrow, out, ref, etc?


pure_, nothrow_, out_, ref_

pureAttribute, nothrowAttribute, outAttribute, refAttribute


Re: What library functionality would you most like to see in D?

2011-07-31 Thread KennyTM~

On Jul 31, 11 13:27, Jonathan M Davis wrote:

I think that it would be useful to query the community for what piece of
library functionality they don't currently have in D and would most like to
see. For instance, there is no official logging framework in D or any 3rd party
libraries which do it AFAIK. So, that could be one type of functionality that
you may like to see. Now, there is a prospective implementation for std.log
which shouldn't be all that far away from being reviewed, so listing that here
wouldn't be all that useful, since it's on its way. But what other major
functionality do you miss in D that other languages' that you use have
available in their libraries?

My hope here would be that we could get some good ideas going here such that
we have can have a better idea what type of functionality it would be
particularly useful to be working on for Phobos or 3rd party D libraries for
the community, and maybe it'll even get some people to actually go and work on
these ideas so that we can improve the libraries that we have to work with in
D. We can always use more help, and we definitely need a richer library
ecosystem for D. But even just discussing ideas could be of benefit.

So, what major functionality which we don't currently have would you like to
see in either Phobos or in a 3rd party library so that you could use it in
your D programs?

- Jonathan M Davis


1. An officially endorsed XML *and* HTML library that supports Xpath. 
Preferably with an interface as easy to use as Python's lxml. I don't 
know how long the current std.xml will stay, if it's upon rewrite please 
do consider supporting Xpath (or CSS3 selector).


(lxml is based on libxml2 and libxslt which are MIT license and may not 
be compatible with Boost; lxml's source code itself is in BSD)


2. More containers, including:
- std.container.HashTable (or allow void[T] in the language).
- std.container.List (doubly linked list)
- std.container.Deque
- std.container.IntervalSet
- std.container.Trie (or PatriciaTrie)
- Adaptors to RedBlackTree and HashTable, making it a Set, 
Dictionary (map) and CountedSet (bag/multiset).

- Ordered associative array

3. A std.variant.Algebraic that does not rely on typeid (like C++'s 
Boost.Variant).


4. Wrapper to GSL (= GNU Scientic Library, GPL of course).

5. Unicode normalization (the NFKD stuff) and other Unicode support, 
preferably as a wrapper to ICU (non-restrictive license: 
http://source.icu-project.org/repos/icu/icu/trunk/license.html).


6. Rational numbers (std.fraction?).

7. Serialization library (yes I know there's Orange).

8. Support for CSV and plist

9. More pure/@safe/const :)


Re: std.path review: second update

2011-07-30 Thread KennyTM~

On Jul 30, 11 17:00, Lars T. Kyllingstad wrote:

On Sat, 30 Jul 2011 03:47:55 +0800, KennyTM~ wrote:


On Jul 30, 11 02:06, Lars T. Kyllingstad wrote:

[snip]


Thanks for the nice work!

Comments:

- pathSplitter: empty, front, back could be const. Also, make the struct
'static struct'.


Will do.



- hasDrive, isDriveRoot: the path

  "#:\x"

should not pass hasDrive. In Windows only /[a-zA-Z]/ are supported drive
letters. '#:' may work but is not officially supported.


True, but then "#:" must be considered a directory name, which is not
much better.  The module generally assumes that any path you pass to it
is well-formed.  If not, the results are undefined.

The rationale for this is that you don't know whether a path is valid,
i.e. well-formed AND correct (pointing to the right place in the file
system), until you try to use it.  std.path can in principle verify well-
formedness, but since it cannot verify correctness, both may just as well
be taken care of by the OS.


Fair enough.





- Bug 6390 (= 6337) has been fixed. Some CTFE tests can be enabled.


I know, but the fix hasn't been released yet.  I'd prefer if people
didn't have to build the compiler from repo to test the module.  I'll be
sure to enable the tests when DMD 2.055 has been released.



If this module is accepted, it will be released along with 2.055 which 
carries the fix of 6337 also. Have to delay those tests to 2.056 doesn't 
sound reasonable to me. It's OK if those are just disabled to ease 
reviewing, but I'd argue that in the final commit, the tests must be 
enabled whenever the trunk allows it.





- baseName, dirName "TODO: @safe pure nothrow": Mention which bugs are
preventing this (std.conv.to and std.string.chomp?).


Will do.



- buildPath, More than two path components: looks like a perfect
candidate for  std.algorithm.reduce. And this should probably accept a
range, but I'm not sure.


I'll look into using reduce.  I have considered letting the function take
a general range, but variadic parameters likely cover the vast majority
of use cases.  If there is a real need for a range version, however, I'd
be happy to add it.  Otherwise, I'd rather avoid the API clutter.



OK.




- CaseSensitive.osDefault: As I mentioned before, version(OSX) should
set this to 'no'.


Sorry, forgot about that.  I'll fix it.



- globMatch: only UTF-8 is supported?


Except for the name change (fnmatch ->  globMatch), this function is not
written by me.  It is taken from the current std.path, and is for all
intents and purposes not part of my submission.

However, if it is trivial to redefine it in terms of general string
types, I will do so.  I'll check.



OK.




- extension: Note that the DDoc text of 'extension' is highlighted.


Thanks!

-Lars




Re: State of the Unicode in D

2011-07-29 Thread KennyTM~

On Jul 30, 11 07:37, Andrej Mitrovic wrote:

That \N syntax sugar could easily be replacable with a Phobos function
called via CTFE.


Possible, but don't do it :). The table would have like 0x18000 entries 
(just a guess). If each character name is 20 letter long, Phobos need to 
supply a 2 MB file for this rarely used feature. Besides, D has '\𝔞' 
already.


There are more important features like Unicode properties, normalization 
(á <-> a´), locale-specific casing (dotless i), collation etc. that 
should be supported before having \N.


(I'd prefer these be done via a wrapper to ICU, as most are database-based.)


Re: std.path review: second update

2011-07-29 Thread KennyTM~

On Jul 30, 11 02:06, Lars T. Kyllingstad wrote:

Here's a new update based on your comments and requests.  Code and docs
are in the usual place,

   https://github.com/kyllingstad/phobos/blob/std-path/std/path.d
   http://www.kyllingen.net/code/std-path/phobos-prerelease/std_path.html

Here are the highlights:

* UNC paths, i.e. \\server\share\..., are now (hopefully) handled
correctly on Windows.  See the baseName(), dirName(), rootName(),
driveName(), pathSplitter(), etc. docs for examples.

* Support for //foo/bar paths on POSIX has been removed.

* rootName() is new.

* pathSplitter() now returns a bidirectional range.

* pathCharMatch() and fcmp() have been replaced by improved functions
filenameCharCmp() and filenameCmp(), respectively, with optional case
sensitivity.

* joinPath() has been renamed to buildPath().

* Added a function buildNormalizedPath(), which performs normalization
while joining the segments.

* Redefined normalize() in terms of buildNormalizedPath().

I am still unsure of the extent to which long UNC paths (i.e. \\?\...)
should be supported, if at all.  If anyone has anything to say on the
matter, please do. :)

-Lars


Thanks for the nice work!

Comments:

- pathSplitter: empty, front, back could be const. Also, make the struct 
'static struct'.


- hasDrive, isDriveRoot: the path

"#:\x"

should not pass hasDrive. In Windows only /[a-zA-Z]/ are supported drive 
letters. '#:' may work but is not officially supported.


- Bug 6390 (= 6337) has been fixed. Some CTFE tests can be enabled.

- baseName, dirName "TODO: @safe pure nothrow": Mention which bugs are 
preventing this (std.conv.to and std.string.chomp?).


- buildPath, More than two path components: looks like a perfect 
candidate for  std.algorithm.reduce. And this should probably accept a 
range, but I'm not sure.


- CaseSensitive.osDefault: As I mentioned before, version(OSX) should 
set this to 'no'.


- globMatch: only UTF-8 is supported?

- extension: Note that the DDoc text of 'extension' is highlighted.


Re: opBinary failes with templates

2011-07-27 Thread KennyTM~

On Jul 28, 11 05:25, Asger Dam Hoedt wrote:

2011/7/27 Steven Schveighoffer mailto:schvei...@yahoo.com>>

On Wed, 27 Jul 2011 15:48:24 -0400, Asger Dam Hoedt
mailto:asgerho...@gmail.com>> wrote:

Hey

I've very recently started playing around with D, but I seem to
have hit my
head against a bug in dmd. I want to create a Vector class
templated with
its dimension. This works fine until I try to overload the +
operator for my
vector and use it. I then get the error

Error: incompatible types for ((vec) + (vec)): 'Vector!(3)' and
'Vector!(3)'

I've boiled it down to a small example

struct Vector(int D) {
float es[D];

public:
this(immutable float x, immutable float y, immutable float z) {
es[0] = x; es[1] = y; es[2] = z;
}

Vector!(D) opBinary(string s)(immutable Vector!(D) rhs) if
(s == "+") {
Vector!(D) ret;
for(int i = 0; i < D; ++i)
ret.es [i] = es[i] + rhs.es [i];
return ret;
}

}

alias Vector!(3) Vector3;

void main() {
Vector3 vec = Vector3(0,1,2);
vec = vec.opBinary!("+")(vec); // This works fine
vec = vec + vec; // This line fails miserably
}

If I replace the template argument in for the argument rhs with
3, then
everything works, but that's not really a nice solution :)

Is it me trying to use templates in a way they aren't meant to
be used or is
this a bug in dmd? If it is a bug, does anyone have an idea how
to solve
this? I wouldn't mind fixing it in dmd myself, I just need some
guidelines.


It is a bug, someone just brought up almost exactly this problem in
d.learn.


http://www.digitalmars.com/__webnews/newsgroups.php?art___group=digitalmars.D.learn&__article_id=28455



The proper workaround (and actually, the cleaner solution) is to use
Vector and not Vector!D.  Inside a template, the name of the
template is the same as if you invoked the template with the same
template parameters.

If you actually do need a different value for D, I'm not sure what
works.

-Steve


Oh nice. I'll go with the clean solution then and disregard the bug for
now. Thanks for the quick help.

/asger


Actually you shouldn't need to write a vector struct if "+" is all it 
required, as D supports array operation already:




void main() {
float[3] x = [1, 3, 5], y = [5, -6, 2];
x[] = x[] + y[];
assert(x == [6, -3, 7]);
}


It is also more efficient than the for-loop since this could use SIMD 
operations in some cases.


Re: OS X 10.7 (Lion) breaks DMD-compiled executables due to ASLR (?)

2011-07-25 Thread KennyTM~

On Jul 25, 11 07:26, David Nadlinger wrote:

On 7/25/11 12:48 AM, KennyTM~ wrote:

On Jul 24, 11 13:24, David Nadlinger wrote:

I have been observing crashes in semi-random places around my D
applications (Segmentation fault/Bus errors) on the recently released OS
X 10.7, dubbed Lion. They miraculously disappeared every time I ran the
executables from GDB, and as I found out (thanks wm4 for the hint), this
was due to GDB disabling ASLR by default. And indeed, if I »set
disable-aslr off«, the crashes also happened within the debugger.

This is not totally surprising as Lion is the first OS X release to
include full ASLR for both 32 bit and 64 bit applications, but I have
not been able to track down what exactly goes on.

Any guesses what could go wrong here without additional details (I'm not
at all sure where to look right now)? Maybe something related to the OS
X-specific things like TLS handling?

David


Seems to be due to throwing exceptions, not TLS.

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


Yeah, can confirm that, all my issues seem to be somehow related to
exceptions to (even though in non-obvious ways sometimes).

David


This fixes the issue for me:

https://github.com/D-Programming-Language/druntime/pull/42


Re: OS X 10.7 (Lion) breaks DMD-compiled executables due to ASLR (?)

2011-07-24 Thread KennyTM~

On Jul 24, 11 13:24, David Nadlinger wrote:

I have been observing crashes in semi-random places around my D
applications (Segmentation fault/Bus errors) on the recently released OS
X 10.7, dubbed Lion. They miraculously disappeared every time I ran the
executables from GDB, and as I found out (thanks wm4 for the hint), this
was due to GDB disabling ASLR by default. And indeed, if I »set
disable-aslr off«, the crashes also happened within the debugger.

This is not totally surprising as Lion is the first OS X release to
include full ASLR for both 32 bit and 64 bit applications, but I have
not been able to track down what exactly goes on.

Any guesses what could go wrong here without additional details (I'm not
at all sure where to look right now)? Maybe something related to the OS
X-specific things like TLS handling?

David


Seems to be due to throwing exceptions, not TLS.

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


Re: WithStatement

2011-07-24 Thread KennyTM~

On Jul 25, 11 03:44, Shahid wrote:

I've been using the WithStatement alot recently and there's a situation
that's really bugging me.

my code is similar to the following:

struct Struct
{
enum Enum1 { A, B, C }
enum Enum2 { D, E, F }

...
}

T foo( ... )
{
with ( Struct )
{
bar( Enum1.A );
...
...
}
}

I'm wondering what others think about extending the WithStatement to take
a colon, which would create an implicit scope similar to how Attributes
work. eg:

T func( ... )
{
with ( Struct ):

bar( Enum1.A );
...
...
}


@property string usingNamespace(S)() {
string res = "";
enum prefix = "alias " ~ S.stringof ~ '.';
foreach (m; __traits(allMembers, S)) {
res ~= prefix ~ m ~ ' ' ~ m ~ ';';
}
return res;
}

struct Struct {
enum Enum1 { A, B, C }
enum Enum2 { D, E, F }
}

void main() {
mixin(usingNamespace!Struct);
auto a = Enum1.A;
auto b = Enum2.F;
}




Re: WithStatement

2011-07-24 Thread KennyTM~

On Jul 25, 11 03:51, bearophile wrote:

Shahid:


I'm wondering what others think about extending the WithStatement to take
a colon, which would create an implicit scope similar to how Attributes
work. eg:

T func( ... )
{
with ( Struct ):

bar( Enum1.A );
...


If you extend this idea to if/while/for statements too, the end result is a 
Python-D:
http://delight.sourceforge.net/

Bye,
bearophile


Not exactly. The ':' scope isn't terminated with de-dent, e.g. the 
language have to choose one of the two meanings in the following:


foreach (i; a1):
  do_something_with(i);
 foreach (j; a2):
   do_something_with(j);

(Actually this applies to this 'with' statement too. In

with (A):
 with (B):

should 'B' be nested in or replacing 'A'?)


Re: 16-bit inline assembler?

2011-07-24 Thread KennyTM~

On Jul 25, 11 02:14, Mehrdad wrote:

Hi!

Is 16-bit inline assembly possible with DMD? If not, would it be
difficult to add the feature?
That way you might actually be able to write a boot loader in pure D. :)


That's unlikely. D has no plan to support < 32-bit systems*.

http://d-programming-language.org/overview.html


Re: What happened to the language reference at d-p-l.org?

2011-07-17 Thread KennyTM~

On Jul 17, 11 23:07, Johann MacDonagh wrote:

On 7/17/2011 6:30 AM, Jacob Carlborg wrote:

On 2011-07-17 12:29, Piotr Szturmaj wrote:

q66 wrote:

Yes, I get the same issue. Though, if you directly navigate to certain
article
from language reference, like
http://www.d-programming-language.org/property.html,
the list appears though, so it's a bug. Also, some Phobos
documentation is
incomplete on d-p-l.org, like etc.c.curl.


The list is invisible only in
http://www.d-programming-language.org/lex.html and "Language reference"
is linked to that page.


Ok, I see, thanks.


Yup, I submitted this a few days ago:

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


The navigational panel is back for lex.html, but all all tables in 
lex.html are broken, and the links for 
http://d-programming-language.org/hash-map.html are also missing.


Re: Deprecating things without a replacement

2011-07-17 Thread KennyTM~

On Jul 17, 11 23:28, Robert Clipsham wrote:

Also note that you can't use dirEntries() ~ dirEntries() or
chain(dirEntries(), dirEntries()) as DirIterator is not a range.


This compiles and runs for me:

---
import std.file, std.range, std.algorithm, std.stdio;
void main() {
auto dFiles = filter!`endsWith(a.name, ".d")`(dirEntries(".", 
SpanMode.depth));
auto cFiles = filter!`endsWith(a.name, ".c")`(dirEntries("./foo", 
SpanMode.depth));


foreach (file; chain(dFiles, cFiles)) {
writeln(file.name);
}
}
---

The problem is *not* DirIterator not being a range, but that DirIterator 
is not a range of *string*. The foreach loop you're using


foreach (string file; obj) { ... }

requires an *opApply* which outputs strings from 'obj', but the range 
interface of 'DirIterator' outputs 'DirEntry'.


Re: Byte Order Swapping Function

2011-07-17 Thread KennyTM~

On Jul 17, 11 15:44, Jonathan M Davis wrote:

On Sunday 17 July 2011 15:31:36 KennyTM~ wrote:

On Jul 17, 11 05:51, Jonathan M Davis wrote:

On Saturday 16 July 2011 15:38:29 Andrei Alexandrescu wrote:

Just paste the code here.


This is what I have at the moment:

import core.bitop;


[snip]


private T swapEndianImpl(T)(T val)

  if(is(Unqual!T == ulong))

{

  return ((val&   0xff00UL)>>   56) |

 ((val&   0x00ffUL)>>   40) |
 ((val&   0xff00UL)>>   24) |
 ((val&   0x00ffUL)>>   8) |
 ((val&   0xff00UL)<<   8) |
 ((val&   0x00ffUL)<<   24) |
 ((val&   0xff00UL)<<   40) |
 ((val&   0x00ffUL)<<   56);

}


Why not just 'bswap' the two uint parts?


If that will work sure, but thinking about it, I couldn't think of how you
could use bswap like that. bswap swaps the 4 bytes that it's given. But you
have to swap each end with each end, not an end with the middle. So, it's not
like you can use bswap on half of it and then on the other half. I suppose
that you could use bswap for the middle 4 bytes and then bitshifts for the 2
bytes on each side, and that would probably be faster. But I don't see how you
could use bswap to swap any two pieces of a 64-bit integer and properly swap
it. Now, it may very well be possible and I just don't see it, but I don't see
it. So, if you know how, please tell me.

- Jonathan M Davis


import core.bitop;
private ulong swapEndianImpl(ulong val) {
ulong res = bswap(val & 0x_);
return res << 32 | bswap(val >> 32);
}
unittest {
assert(swapEndianImpl(0xfedcba98_76543210UL) == 0x10325476_98badcfeUL);
}




Re: Byte Order Swapping Function

2011-07-17 Thread KennyTM~

On Jul 17, 11 05:51, Jonathan M Davis wrote:

On Saturday 16 July 2011 15:38:29 Andrei Alexandrescu wrote:

Just paste the code here.


This is what I have at the moment:

import core.bitop;


[snip]


private T swapEndianImpl(T)(T val)
 if(is(Unqual!T == ulong))
{
 return ((val&  0xff00UL)>>  56) |
((val&  0x00ffUL)>>  40) |
((val&  0xff00UL)>>  24) |
((val&  0x00ffUL)>>  8) |
((val&  0xff00UL)<<  8) |
((val&  0x00ffUL)<<  24) |
((val&  0xff00UL)<<  40) |
((val&  0x00ffUL)<<  56);
}


Why not just 'bswap' the two uint parts?




[snip]



Re: bugzilla template

2011-07-15 Thread KennyTM~

On Jul 16, 11 05:02, Steven Schveighoffer wrote:

On Fri, 15 Jul 2011 16:25:25 -0400, KennyTM~  wrote:


On Jul 15, 11 23:45, Steven Schveighoffer wrote:


3. If any errors are output by the compiler, list them here

4. What is your expected result?

5. What is the actual result?

Note: please use the selectors above to fill out as much detailed
information as possible (OS, architecture, version of D, etc.)
-

I'm not stuck on this form, probably the most prolific bug fixers could
come up with a better one.

-Steve


It's getting worse: http://d.puremagic.com/issues/show_bug.cgi?id=6327.

Anyway, item 5 shouldn't be mandatory. The actual result is in item 3.
And even item 4 is optional. The expected result is item 3 shouldn't
happen.


There are cases where the code does compile, and outputs the wrong
result. They could have nothing to do with the compiler.



Yes, you can always include additional information. And change item 3 to 
"errors output by the compiler or the executed program".





http://d.puremagic.com/issues/page.cgi?id=bug-writing.html

I believe no one had read this :)


Nobody probably knows it exists (including myself until now!)

-Steve




Re: Next in Review Queue: The New std.path

2011-07-15 Thread KennyTM~

On Jul 16, 11 04:16, Lars T. Kyllingstad wrote:

On Sat, 16 Jul 2011 00:17:03 +0800, KennyTM~ wrote:


On Jul 16, 11 00:05, Jonathan M Davis wrote:

On Friday 15 July 2011 23:48:39 KennyTM~ wrote:

On Jul 15, 11 23:26, Lars T. Kyllingstad wrote:

   So here you have had to use Unqual
   immutable(Unqual!C1)[] setExtension(C1, C2)(in C1[] path, in C2[]
   ext) immutable(Unqual!C1)[] defaultExtension(C1, C2)(in C1[]
   path, in C2[] ext)

   Instead of Unqual isn't it nicer to use a Deconst!() template?


Hmm, I guess you're right.  "shared" shouldn't be stripped, for
instance.


Given that immutable( const(char) ) == immutable(char), I think the
Unqual! should simply be removed.


I'd still put the Unqual in there. Perhaps it's due to compiler bugs,
but from what I've seen, it can get kind of funny when you try and have
an immutable const or a const immutable. Using  Unqual makes it very
clear what you mean.

- Jonathan M Davis


OK. But I think you should file the compiler bug :) From what I see,
it's that 'immutable' always win.

--
alias const(char) CC;
alias immutable(char) IC;
alias immutable(CC) ICC;
alias const(IC) CIC;
pragma(msg, ICC);
pragma(msg, CIC);
--
immutable(char)
immutable(char)
--


True, but this doesn't apply to the present case.  Since the parameters
are marked with 'in', they become const(immutable(char)[]), not const
(immutable(char))[].  This isn't too hard to fix, but I prefer to use
Unqual, Deconst, Mutable, or whatever it ends up being called.

-Lars


Even if `typeof(path)` becomes `const(string)`, C1 is still an 
`immutable(char)`, so `immutable(C1)[]` will still work.



immutable(C1)[] setExtension(C1, C2)(in C1[] path, in C2[] ext) {
pragma(msg, typeof(return), " <- ", C1);
return typeof(return).init;
}
void main() {
setExtension("1", "2");
setExtension("3".dup, "4".dup);
setExtension(cast(const)"5".dup, cast(const)"6".dup);
}

string <- immutable(char)
string <- char
string <- const(char)






Re: bugzilla template

2011-07-15 Thread KennyTM~

On Jul 15, 11 23:45, Steven Schveighoffer wrote:

Many times, a new user of D (and even some experienced ones) will post a
bug to bugzilla with not enough or just enough information, but could be
way more informative.

For example, take http://d.puremagic.com/issues/show_bug.cgi?id=6323

I have to download this code and compile it, to see what he is talking
about (no error messages or explanation of what's wrong). (sorry to pick
on this bug, it's not the only one, but the most recent)

I think requiring someone to download code and compile it is way too
much overhead to determine whether a bug is trivial, duplicate, invalid,
etc.

In other bug reporting systems I've used, when you create a new bug, it
gives you a template to fill out (i.e. steps to reproduce, any relevant
error messages). I think this would go a long way to getting more
informative bug reports.

Is it possible to add something like this to D's bugzilla? Do other
people think this is a good idea?

I'll give a sample:

-
Please answer the following mandatory questions

1. List an example that causes the bug (please reduce as much as
possible). Do not paste more than 100 lines of code.

2. If relevant, list the command line used to compile, including any
flags passed to the compiler

3. If any errors are output by the compiler, list them here

4. What is your expected result?

5. What is the actual result?

Note: please use the selectors above to fill out as much detailed
information as possible (OS, architecture, version of D, etc.)
-

I'm not stuck on this form, probably the most prolific bug fixers could
come up with a better one.

-Steve


It's getting worse: http://d.puremagic.com/issues/show_bug.cgi?id=6327.

Anyway, item 5 shouldn't be mandatory. The actual result is in item 3. 
And even item 4 is optional. The expected result is item 3 shouldn't happen.


There is actually this page:

   http://d.puremagic.com/issues/page.cgi?id=bug-writing.html

I believe no one had read this :)


Re: Next in Review Queue: The New std.path

2011-07-15 Thread KennyTM~

On Jul 16, 11 00:05, Jonathan M Davis wrote:

On Friday 15 July 2011 23:48:39 KennyTM~ wrote:

On Jul 15, 11 23:26, Lars T. Kyllingstad wrote:

  So here you have had to use Unqual
  immutable(Unqual!C1)[] setExtension(C1, C2)(in C1[] path, in
  C2[] ext) immutable(Unqual!C1)[] defaultExtension(C1, C2)(in
  C1[] path, in C2[] ext)

  Instead of Unqual isn't it nicer to use a Deconst!() template?


Hmm, I guess you're right.  "shared" shouldn't be stripped, for
instance.


Given that immutable( const(char) ) == immutable(char), I think the
Unqual! should simply be removed.


I'd still put the Unqual in there. Perhaps it's due to compiler bugs, but from
what I've seen, it can get kind of funny when you try and have an immutable
const or a const immutable. Using  Unqual makes it very clear what you mean.

- Jonathan M Davis


OK. But I think you should file the compiler bug :) From what I see, 
it's that 'immutable' always win.


--
alias const(char) CC;
alias immutable(char) IC;
alias immutable(CC) ICC;
alias const(IC) CIC;
pragma(msg, ICC);
pragma(msg, CIC);
--
immutable(char)
immutable(char)
--


  1   2   3   4   5   6   >