Re: some regex vs std.ascii vs handcode times

2012-03-21 Thread Juan Manuel Cabo
On Wednesday, 21 March 2012 at 05:49:29 UTC, Juan Manuel Cabo 
wrote:

On Monday, 19 March 2012 at 04:12:33 UTC, Jay Norwood wrote:

[]

Ok, this was the good surprise.  Reading by chunks was faster 
than reading the whole file, by several ms.


// read files by chunk ...!better than full input
//finished! time: 23 ms
void wcp_files_by_chunk(string fn)
{
auto f = File(fn);
foreach(chunk; f.byChunk(1_000_000)){
}
}




mmm, I just looked in std/file.d and std/stdio.d.
The std.file.read() function calls GetFileSize()
before reading, and you are dealing with very tight
differences (23ms vs 31ms). So there is a chance that
either the difference is accounted for by the extra
GetFileSize() (and extra stat() in the posix version),
or your threads/process loosing their scheduled slice
for that extra I/O call of GetFileSize().
  Also, in windows, std.file.read() uses ReadFile, while
byChunk uses fread(), though it should all be the same
in the end.

  It is better to try with files big enough to see whether
the timing difference gets either bigger or stays
just around those 8ms.

I'll later try all this too!!! Nice benchmarking
by the way!! Got me interested!

--jm





Re: getHash inconsistency

2012-03-21 Thread Daniel Murphy
"H. S. Teoh"  wrote in message 
news:mailman.951.1332306541.4860.digitalmar...@puremagic.com...
>
> Here's the current hashing code for char[] and string:
>
>foreach (char c; s)
>hash = hash * 11 + c;
>
> For const(char)[], it's rt.util.hash.hashOf, which is Paul Hsieh's
> SuperFastHash algorithm with very good hash distribution properties. It
> does seem to involve a lot more operations that the simple loop above,
> though; so I assume the above simple loop was chosen because hashing
> strings are a very common operation and, for the most part, only need a
> simple hash function.
>
> So I'm kinda leaning towards SuperFastHash, but worried about whether it
> will cause performance degradation, in which case we should stick with
> the simple loop.
>
>
> T
>
> -- 
> "Maybe" is a strange word.  When mom or dad says it it means "yes", but 
> when my big brothers say it it means "no"! -- PJ jr.

Benchmark time! 




Re: Premake support for D

2012-03-21 Thread Gour
On Tue, 20 Mar 2012 13:57:50 +1100
Andrew Gough  wrote:

Hello Andrew,

> The fork supports DMD, GDC, and LDC - but only for D2, and currently
> only for (g)make. If anyone would like to add support for other
> toolchains (MSVC/VisualD, Code::Blocks etc) that would be fantastic.

I'm very happy seeing the prospect of having D support in premake which
looks very clean and being of declarative nature.

Now I wonder how difficult is to add support for  other toolchains and
asked about it on the mailing list where Jason replied with: "I did try
to abstract out common functions between the C++ and C# support. The
more data points I have to work with, the easier it will be to identify
the areas that need more abstraction (and what it should look like)."

Does adding such support involve only Lua skills?

> I have successfully built my own projects and druntime/phobos with it
> in the past, so I know it can work.

I plan to start playing with it as soon as I finish some other non-D
related tasks.

Thank you for working on it.


Sincerely,
Gour


-- 
But for one who takes pleasure in the self, whose human life 
is one of self-realization, and who is satisfied in the self only, 
fully satiated — for him there is no duty.

http://atmarama.net | Hlapicina (Croatia) | GPG: 52B5C810


signature.asc
Description: PGP signature


Re: Proposal: user defined attributes

2012-03-21 Thread Jacob Carlborg

On 2012-03-20 22:36, deadalnix wrote:


It is more tricky if the property isn't a simple attribute to read.
Again, consider what is done with this simple example :
http://projectlombok.org/

We have the opportunity here to introduce in D the concept of aspect
oriented programming. This is HUGE. If you are afraid of the addition of
a functionnality to the language, don"t worry, you are not just adding a
functionnality, but a whole new paradigm.

And, BTW, this would allow us to drop some functionalities that now can
be provided by phobos (synchronized for example is an obvious one). Same
goes for override, deprecated, and the fun thing is that we can
implement our own to extends the language even more as lib.

Even the propagation of pure, @safe, nothrow and const that has been
discussed recently can be done with that feature.

If you are worried about introducing language features (I am) you should
definitively introduce that one, because lot of features has already
been included just because that one is lacking.

Adding compile time information to a type is the visible part of the
iceberg. Really.


I couldn't agree more.

--
/Jacob Carlborg


Re: Three Unlikely Successful Features of D

2012-03-21 Thread Jacob Carlborg

On 2012-03-20 23:58, Nick Sabalausky wrote:

- Type inference
- alias
- foreach
- Everything about arrays/slices
- Built-in associative arrays that support nearly any type as a key
- Reference semantics for classes
- All the niceities of ctors compared with C++'s ctors
- Backtick strings
- Scope guards (And even finally: I head somewhere C++ doesn't even have
finally: Is that true?!?)
- GC
- Name any of D's metaprogramming features

Many of those can seem like simple things, but I'd *hate* to have to get by
without them. Heck, most of them I now take for granted.

Alias in particular is a much bigger deal than it seems since it's seemingly
trivial but can be *incredibly* helpful with templates *and* with importing.

Actually, looking at this list, I'm now starting to get a little worried
about an upcoming C++ project... No doubt I'll be trying to reinvent a lot
of D in it. Probably in ugly hackish ways.


I did that in one project. I emulated properties, using boost I emulated 
foreach, auto, lambdas and other features. If you're using C++11 you'll 
have these features native, expect for properties.


I did the mistake and learned D before I learned C++.

--
/Jacob Carlborg


Re: Three Unlikely Successful Features of D

2012-03-21 Thread Nick Sabalausky
"H. S. Teoh"  wrote in message 
news:mailman.949.1332305140.4860.digitalmar...@puremagic.com...
>
> Yeah, AA's with int keys are like arrays enhanced with O(1)
> insertion/removal and sparse storage (if you have very large indices,
> e.g.). :-) You can even have (pseudo) linear access if you iterate keys
> from 0 to $.

Exactly.

> For example, it lets you accept keys/values that are not strictly the
> AA's key/value type, but can be implicitly converted to them. It lets
> you return keys and values without needing the ugly typeinfo and void*
> casts that are necessary in aaA.d.  This in turn lets you mark many AA
> methods as pure, and almost all as @safe or @trusted. It lets you
> cleanly interoperate with types that define opAssign (currently aaA.d
> does a blind binary copy of data from key/value pointers, which leads to
> potential bugs when the data has subobjects.)
>
> It also makes it *much* easier to fix many existing AA bugs in the
> bugtracker. So far, I have working unittests for the following issues:
> 3824, 3825, 4337, 4463, 5685, 6210, 7512, 7512, 7602, 7632, 7665, 7665,
> 7704. I haven't looked through all AA-related issues yet; this list may
> very well grow. :-) To fix these in the current aaA.d implementation can
> be rather tricky, and quite possibly requires compiler changes.
>

I see. Cool stuff.

> Better yet, I thought of a way of making AA's instantiable at
> compile-time via CTFE and mixins: this will let you write AA literals
> that can be evaluated at compile-time and have them turn into object
> code directly without needing runtime initialization.
>

Ah! Now *that's* fucking awesome! That limitation has kinda stuck out as an 
odd, annoying wart.

>
>> And even *that* still doesn't work if you don't catch *every*
>> exception (and then rethrow the ones you don't care about? Ick!).
>
> Actually, you can catch "..." and it will catch *everything*. And I
> believe a single "throw;" will rethrow whatever it is you caught.
>

I see. It has been awhile since I've been in the C++ loop.

>
>> I've seen C++ programmers swear off exceptions because of this, and I
>> can't blame them at all.  Exception systems *need* a finally.
>
> Yeah. "catch(...)" sorta works, but it's very ugly. And while being able
> to throw *anything* at all is nice (I'm guilty of writing code that
> throws char*, for example), not being able to make *any* assumptions at
> all about what you caught (e.g., no common exception superclass with
> some useful methods, like .msg) is, shall we say, practically useless in
> a large enough project?
>

Boy, it really has been awhile. I knew you could throw any class object in 
C++, but I thought that was all. Haxe lets you throw literally anything, 
even Int, and I found that to be more of a problem than a feature (In very 
much the same way as VB's ability to change the lower bound of an array: It 
gains little and just means you have to remember to do the rediculous 
"UBound(arr) - LBound(arr)".)  Just have a proper Exception class and 
nothing else should be throwable (D's "Error" notwithstanding).

> (Actually, the lack of .msg was what drove me to throw char*. Obviously
> checking return codes for every lousy function I call is out of the
> question, but so is throwing error codes that come from different
> subsystems, since you've no way of telling which error code scheme to
> use to look up the error. So I said to myself, why not throw a string
> that actually tells you what the error is? Furthermore, if these strings
> were predefined in char arrays that had unique pointer addresses, the
> value of the pointer itself serves as a kind of "global error number".
> So this worked as a kind of a poor man's error code + message exception
> that can be freely thrown around without problems

That is an interesting work around.

> the reason I shied
> away from throwing class objects in the first place was because early
> implementations of C++ had problems that sometimes caused pointer bugs
> and all kinds of nasty side effects when a class object is thrown.

Ouch!

>
> Scope guards rule. Ironically, D's GC mostly alleviates the need for
> scope guards. :-) They're still immensely useful when you acquire
> resources that must be cleaned up no matter what happens later. D is the
> first and only language I know that got resource cleanup done right.
> Cleanups belong with the acquisition code, not dangling somewhere 200
> lines down at the end of the scope, with who knows how many possible
> leaks in between due to goto's, exceptions, returns, and who knows what!
>

I've even come across at least a couple uses of scope guard that aren't 
strictly related to releasing resources. Actually, I've just been working 
with both of them today:

- Temporarily changing a value:

int bar;
void foo()
{
// Change bar temporarily
auto saveBar = bar;
bar = 777;
scope(exit) bar = saveBar;

[...do anything here...]
}

- Timing a section o

Re: Three Unlikely Successful Features of D

2012-03-21 Thread Martin Nowak

It's probably far too early to think about this with all the other
important issues you're addressing but have you given much thought to
improving the hashing function?  I haven't hit any issues with the speed  
of

the current hasher but better performance is always welcome. MurmurHash
seems to be all the rage these days with a lot of languages and systems
adopting it  (it compiles down  
to

~52 instructions on x86). It'd be interesting to see benchmarks with it.
I'm not sure where the current hashing function lives to see what it's  
like.


Regards,
Brad Anderson


More throughput but higher latency.
http://codepad.org/kCVQ8eoq
Murmurhash was a little slower than CityHash but
both are a little expensive for very few bytes.


Re: Proposal: user defined attributes

2012-03-21 Thread Jacob Carlborg

On 2012-03-21 01:35, Adam D. Ruppe wrote:

On Wednesday, 21 March 2012 at 00:03:28 UTC, James Miller wrote:
So you'd just very simply do:

struct MyAttribute { bool activated; }

// @note is just like doing internalTuple ~= MyAttribute(true)
// and MyAttribute is of course just a plain old struct
initializer
@note(MyAttribute(true)) int a;

To check it:

foreach(note; __traits(getNotes, member_a))
static if(is(typeof(note) == MyAttribute) {
// do what you want here, ignore types you don't know
}


That's basically my initial proposal and how annotations work in Java.


What data can be packed into annotations?


Being able to use custom types is an
important part of my idea here.


I think any type that a template can take (as a value) + other 
attributes/annotations.


--
/Jacob Carlborg


Re: What about putting array.empty in object.d?

2012-03-21 Thread Jacob Carlborg

On 2012-03-21 04:54, Nick Sabalausky wrote:

Hear me out... ;)

Using empty seems to be emerging as the recommended practice for testing
whether an array is empty. And that makes sense as it's consistent with
other ranges. I'm all in favor of that.

But I've found myself avoiding empty (and instead doing arr=="" or checking
the .length) just because empty doesn't work on arrays unless you've already
imported std.array (unless my knowledge is out-of-date, which is possible
considering how fast things are moving ;) ). So doing "arr.empty" is a
little messy and increases my cognitive load, whereas arr=="", arr==[], and
arr.length == 0, "just work".

Considering that:

1. Arrays are (from the user's perspective) a built-in type that doesn't
need to be explicitly imported.

2. Calling 'empty' is (for good reason) the recommended standard practice
for checking if arrays are empty.

...Perhaps it would make sense for empty(T)(T[] a) to be moved into
object.d, or at least somewhere it will always be implicitly included? Being
a standard part of arrays and input ranges already effectively elevates
"empty" to a relatively special status anyway.


Sure, why not. Do we want an "any" function as well, that is the opposite?

--
/Jacob Carlborg


Re: some regex vs std.ascii vs handcode times

2012-03-21 Thread Martin Nowak
On Mon, 19 Mar 2012 08:56:28 +0100, Dmitry Olshansky  
 wrote:



There doesn't appear to be any significant overhead to reading dchar vs
char. I haven't looked at the code (or decode) underneath. I presume it
is decoding and expanding into dchar...
 // read dchar lc by chunk ...same
//finished! time: 34 ms
void wcp_dchar(string fn)
{
ulong l_cnt;
auto f = File(fn);
foreach(chunk; f.byChunk(1_000_000)){
foreach(dchar c;chunk){
if (c=='\n')
l_cnt++;
}
}
}
 That was strange - decoding takes time, that surely trips few msesc in  
favor of non-decoding version. Probably I/o is hiding the facts here.


1.5x-3x and we haven't even ported back the faster phobos
std.utf.decode to druntime which is called by foreach.


Re: Proposal: user defined attributes

2012-03-21 Thread Tove

On Wednesday, 21 March 2012 at 08:08:12 UTC, Jacob Carlborg wrote:

On 2012-03-21 01:35, Adam D. Ruppe wrote:
On Wednesday, 21 March 2012 at 00:03:28 UTC, James Miller 
wrote:

So you'd just very simply do:

struct MyAttribute { bool activated; }

// @note is just like doing internalTuple ~= MyAttribute(true)
// and MyAttribute is of course just a plain old struct
initializer
@note(MyAttribute(true)) int a;

To check it:

foreach(note; __traits(getNotes, member_a))
static if(is(typeof(note) == MyAttribute) {
// do what you want here, ignore types you don't know
}


That's basically my initial proposal and how annotations work 
in Java.



What data can be packed into annotations?


Being able to use custom types is an
important part of my idea here.


I think any type that a template can take (as a value) + other 
attributes/annotations.


With the mixin improvement proposal any arbitrarily complex 
feature can be implemented in the library, appearing to enjoy 
first class syntax with just 1 extra character penalty vs the 
compiler.


#struct Foo
{
  @NonSerialized int x;
  @NonSerialized int y;
  int z;
}

Just imagine the next step, if the CTFE interface was based on 
AST:s instead of strings...




Re: What about putting array.empty in object.d?

2012-03-21 Thread Nick Sabalausky
"Jacob Carlborg"  wrote in message 
news:jkc321$25pv$1...@digitalmars.com...
> On 2012-03-21 04:54, Nick Sabalausky wrote:
>> Hear me out... ;)
>>
>> Using empty seems to be emerging as the recommended practice for testing
>> whether an array is empty. And that makes sense as it's consistent with
>> other ranges. I'm all in favor of that.
>>
>> But I've found myself avoiding empty (and instead doing arr=="" or 
>> checking
>> the .length) just because empty doesn't work on arrays unless you've 
>> already
>> imported std.array (unless my knowledge is out-of-date, which is possible
>> considering how fast things are moving ;) ). So doing "arr.empty" is a
>> little messy and increases my cognitive load, whereas arr=="", arr==[], 
>> and
>> arr.length == 0, "just work".
>>
>> Considering that:
>>
>> 1. Arrays are (from the user's perspective) a built-in type that doesn't
>> need to be explicitly imported.
>>
>> 2. Calling 'empty' is (for good reason) the recommended standard practice
>> for checking if arrays are empty.
>>
>> ...Perhaps it would make sense for empty(T)(T[] a) to be moved into
>> object.d, or at least somewhere it will always be implicitly included? 
>> Being
>> a standard part of arrays and input ranges already effectively elevates
>> "empty" to a relatively special status anyway.
>
> Sure, why not. Do we want an "any" function as well, that is the opposite?
>

I think "!array.empty" is plenty sufficient. Besides, there are other good 
uses of "any" that have been brought up before.




I do a really bad job as marketer

2012-03-21 Thread Dmitry Olshansky
See this is Jun 2012 post on perl group speaking of unicode support on 
development branch:

http://code.activestate.com/lists/perl5-porters/173477/

Now, keep in mind, that std.regex had O(1) trie lookup for these things 
from day one, because inversion lists with O(lnN) lookup  alone were too 
slow.


--
Dmitry Olshansky


Re: What about putting array.empty in object.d?

2012-03-21 Thread Jacob Carlborg

On 2012-03-21 09:42, Nick Sabalausky wrote:

"Jacob Carlborg"  wrote in message

Sure, why not. Do we want an "any" function as well, that is the opposite?



I think "!array.empty" is plenty sufficient. Besides, there are other good
uses of "any" that have been brought up before.


Actually I was thinking something like "any?" in Ruby:

http://www.ruby-doc.org/core-1.8.7/Enumerable.html#method-i-any-3F

--
/Jacob Carlborg


Re: Three Unlikely Successful Features of D

2012-03-21 Thread so

On Tuesday, 20 March 2012 at 19:02:16 UTC, Andrei Alexandrescu
wrote:
I plan to give a talk at Lang.NEXT 
(http://channel9.msdn.com/Events/Lang-NEXT/Lang-NEXT-2012) with 
the subject above. There are a few features of D that turned 
out to be successful, in spite of them being seemingly 
unimportant or diverging from related consecrated approaches.


What are your faves? I have a few in mind, but wouldn't want to 
influence answers.



Thanks,

Andrei


. ctfe - mixin
. explain them why templates without "static if" is like a
language without "if".
. string, float and anything that matters can be used as template
parameters.


Re: CTFE bug causes null check to pass on null pointers (Issue 7602)

2012-03-21 Thread Jens Mueller
Don wrote:
> On 19.03.2012 18:25, H. S. Teoh wrote:
> >On Mon, Mar 19, 2012 at 09:49:07AM +0100, Don Clugston wrote:
> >[...]
> >>Yes. The existing D2 AA implementation is hopelessly broken.
> >>You have to understand that the whole implementation of AAs in D2 is
> >>a HACK. It is extremely complicated and the slightest change to any
> >>code in the compiler or the runtime can break it. Basically CTFE has
> >>to reverse-engineer the druntime code in order to make it to work.
> >>It's not an implementation issue, it's a fundamental design flaw.
> >
> >I'm working on my AA implementation, hopefully to get it to the point it
> >can replace the current mess. It already fixes a number of AA-related
> >issues in the bug tracker.
> >
> >The main idea is to require a minimal number of lowerings from the
> >compiler (effectively nothing more than syntactic sugar such as V[K] and
> >AA literal syntax), and everything else will be done via existing
> >operator overloading and templating mechanisms. Ideally, CTFE will "just
> >work" with this implementation instead of requiring druntime-specific
> >hacks in the compiler (but I'm not sure whether this will work, since it
> >has to do memory allocations -- does CTFE support that?).
> 
> Yes, CTFE supports 'new'. The big issue for the runtime is
> supporting AA literals. CTFE needs to be able to take the output of
> the runtime functions, and pass it as an AA literal to the rest of
> the compiler.

Interesting. How do I make use of this?

struct Foo {}

Foo* foo()
{
auto a = new Foo;
return a;
}

unittest
{
//enum b = foo(); // fails
}

=> Error: cannot use non-constant CTFE pointer in an initializer

What's the trick to use memory allocated in a CTFE. Say e.g. I want to
build a tree at compile time using CTFE.

Jens


Re: CTFE bug causes null check to pass on null pointers (Issue 7602)

2012-03-21 Thread David Nadlinger

On Wednesday, 21 March 2012 at 09:51:43 UTC, Jens Mueller wrote:

Interesting. How do I make use of this?

[…]

What's the trick to use memory allocated in a CTFE. Say e.g. I 
want to

build a tree at compile time using CTFE.


You can't do that right now (i.e. converting CTFE-allocated 
memory to initializers for run-time values), but it enables you 
to use classes, etc. _during_ CTFE.


David


Re: CTFE bug causes null check to pass on null pointers (Issue 7602)

2012-03-21 Thread Jens Mueller
David Nadlinger wrote:
> On Wednesday, 21 March 2012 at 09:51:43 UTC, Jens Mueller wrote:
> >Interesting. How do I make use of this?
> >
> >[…]
> >
> >What's the trick to use memory allocated in a CTFE. Say e.g. I
> >want to
> >build a tree at compile time using CTFE.
> 
> You can't do that right now (i.e. converting CTFE-allocated memory
> to initializers for run-time values), but it enables you to use
> classes, etc. _during_ CTFE.

Just for clarification:
Why do you say "initializers for _run-time_ values"? I believe I just
want to allocate memory at compile-time.

I just found out you are not allowed to return an instance. But you can
use out parameters. That means I can achieve what I have in mind using
classes. Even though it looks a bit clumsy and not like I do it in
non-CTFE code.

Many Thanks.

Jens


Re: CTFE bug causes null check to pass on null pointers (Issue 7602)

2012-03-21 Thread Don Clugston
On 21/03/12 11:22, Jens Mueller wrote:
> David Nadlinger wrote:
>> On Wednesday, 21 March 2012 at 09:51:43 UTC, Jens Mueller wrote:
>>> Interesting. How do I make use of this?
>>>
>>> […]
>>>
>>> What's the trick to use memory allocated in a CTFE. Say e.g. I
>>> want to
>>> build a tree at compile time using CTFE.
>>
>> You can't do that right now (i.e. converting CTFE-allocated memory
>> to initializers for run-time values), but it enables you to use
>> classes, etc. _during_ CTFE.
> 
> Just for clarification:
> Why do you say "initializers for _run-time_ values"? I believe I just
> want to allocate memory at compile-time.

Any heap-allocated object is on the CTFE heap. At runtime, it needs to
be on the runtime heap. There is currently no mechanism in the back-end
for transferring data from the CTFE heap to the runtime heap, so it
currently generates an error message.

You can return structs and arrays, because we have struct literals and
array literals, but there is no such thing as a class literal. CTFE will
currently allow you to return a class, but only if it is null.

> I just found out you are not allowed to return an instance. But you can
> use out parameters.

Oh dear. That sounds like a bug. There is just no way you can
automatically instantiate a class at runtime, using CTFE data. There
would need to be code in the runtime to do it, and it just doesn't exist!

That means I can achieve what I have in mind using
> classes. Even though it looks a bit clumsy and not like I do it in
> non-CTFE code.
> 
> Many Thanks.
> 
> Jens



Re: Premake support for D

2012-03-21 Thread Andrew Gough
On Wed, 21 Mar 2012 08:07:34 +0100
Gour  wrote:

> On Tue, 20 Mar 2012 13:57:50 +1100
> Andrew Gough  wrote:
> 
> Hello Andrew,
> 
> > The fork supports DMD, GDC, and LDC - but only for D2, and currently
> > only for (g)make. If anyone would like to add support for other
> > toolchains (MSVC/VisualD, Code::Blocks etc) that would be fantastic.
> 
> I'm very happy seeing the prospect of having D support in premake
> which looks very clean and being of declarative nature.
> 
> Now I wonder how difficult is to add support for  other toolchains and
> asked about it on the mailing list where Jason replied with: "I did
> try to abstract out common functions between the C++ and C# support.
> The more data points I have to work with, the easier it will be to
> identify the areas that need more abstraction (and what it should
> look like)."
> 
> Does adding such support involve only Lua skills?

Mostly, yes.  The internals of premake are completely Lua - on the
positive side, Lua is really easy (syntactically, anyway).

The internal abstractions are quite good, and there is a strong
decoupling between the internals data structures for project
configurations, and the final build artefact generation (ie. the
Makefile or VS solution etc).  This means it should be relatively easy
to add other toolchain support - you just need to generate a valid
project/solution from the various configurations.
'src/actions/make/make_d.lua' creates the D Makefiles as a starting
point, and there are other toolchain examples for VS, Code::Blocks etc
for C++/C#, so it shouldn't be a big step.

> 
> > I have successfully built my own projects and druntime/phobos with
> > it in the past, so I know it can work.
> 
> I plan to start playing with it as soon as I finish some other non-D
> related tasks.
> 
> Thank you for working on it.
> 
> 
> Sincerely,
> Gour
> 
> 

-- 
Andrew Gough
M: 0408 596 656
and...@goughy.org


signature.asc
Description: PGP signature


Re: opEquals/opCmp returning other types

2012-03-21 Thread Don Clugston

On 19/03/12 01:54, Brian Palmer wrote:

I'm working on a DSL for generating SQL queries, based loosely on
Python's SQLAlchemy and Ruby's Sequel. One nice thing about the DSL is
the compact syntax for specifying WHERE clauses. With some fiddling, I
got it working for opEquals, a simplified example:

foreach(network; db["networks"].each) {
writefln("network: %s", network.name);
foreach(host; db["hosts"].where(db.c.id == network.id)) {
writefln("\thost: %s", host.address);
}
}

This works because db.c.id returns a struct which defines an opEquals
which returns a "Filter" struct, rather than an int. I'm not positive
that it should really be allowed by the compiler, but it works:

struct Filter { ... }
struct Column {
Filter opEquals(T)(T rhs) { ... }
}

Then the .where call takes a filter, and uses it to output a snippet of
sql like "id = 5"

However, this won't work for comparison operators like < and >, which
all map to opCmp, or for != (since that's rewritten to !(a == b))

I guess I have two questions, one, am I going to shoot myself in the
foot by going down this path, because it only happens to work due to the
compiler being too lax? And is there interest in extending D to allow
the rest of the operators to return non-boolean results? I'm thinking
something like falling back to opBinary!("<"), etc, if opCmp isn't
defined for a struct.


I don't think this is EVER what you really want.
I believe that if you think you want this feature, 100% of the time, 
what you really want is a syntax tree of the entire expression. That is, 
either you want ">" to be a comparison, and "+" to be an addition, OR 
you want a syntax tree.






Re: CTFE bug causes null check to pass on null pointers (Issue 7602)

2012-03-21 Thread Jens Mueller
Don Clugston wrote:
> On 21/03/12 11:22, Jens Mueller wrote:
> > David Nadlinger wrote:
> >> On Wednesday, 21 March 2012 at 09:51:43 UTC, Jens Mueller wrote:
> >>> Interesting. How do I make use of this?
> >>>
> >>> […]
> >>>
> >>> What's the trick to use memory allocated in a CTFE. Say e.g. I
> >>> want to
> >>> build a tree at compile time using CTFE.
> >>
> >> You can't do that right now (i.e. converting CTFE-allocated memory
> >> to initializers for run-time values), but it enables you to use
> >> classes, etc. _during_ CTFE.
> > 
> > Just for clarification:
> > Why do you say "initializers for _run-time_ values"? I believe I just
> > want to allocate memory at compile-time.
> 
> Any heap-allocated object is on the CTFE heap. At runtime, it needs to
> be on the runtime heap. There is currently no mechanism in the back-end
> for transferring data from the CTFE heap to the runtime heap, so it
> currently generates an error message.

That's fine with me. Just want to use new at compile-time.
But being able to move memory from CTFE heap to runtime heap would be
nice and probably finds its uses.

> You can return structs and arrays, because we have struct literals and
> array literals, but there is no such thing as a class literal. CTFE will
> currently allow you to return a class, but only if it is null.

Aha.

> > I just found out you are not allowed to return an instance. But you can
> > use out parameters.
> 
> Oh dear. That sounds like a bug. There is just no way you can
> automatically instantiate a class at runtime, using CTFE data. There
> would need to be code in the runtime to do it, and it just doesn't exist!

I'm doing it all at compile-time. I need to build some data structure
(using pointers) at compile time to generate a string that gets mixed
in.
I think there is no bug. It behaves perfectly as you say.

Many Thanks Don for bringing run-time to compile-time. Making
compile-time programming less awkward.

Jens


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: CTFE bug causes null check to pass on null pointers (Issue 7602)

2012-03-21 Thread Jacob Carlborg
On 2012-03-21 11:53, Don Clugston wrote:
> You can return structs and arrays, because we have struct literals and
> array literals, but there is no such thing as a class literal. CTFE will
> currently allow you to return a class, but only if it is null.

What about anonymous nested classes, would that kind of like class literals?

http://dlang.org/class.html#anonymous

-- 
/Jacob Carlborg


Re: String mixin syntax sugar

2012-03-21 Thread Mantis

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?


Re: String mixin syntax sugar

2012-03-21 Thread dennis luehring

and what about attribute parameters like @serialize(version=2)

Am 21.03.2012 13:35, schrieb Mantis:

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?




Re: Three Unlikely Successful Features of D

2012-03-21 Thread Jan Knepper

On 03/20/2012 17:43, Walter Bright wrote:

On 3/20/2012 12:02 PM, Andrei Alexandrescu wrote:

What are your faves? I have a few in mind, but wouldn't want to
influence answers.


Although array slices have been in D nearly since the beginning, I had
little idea they would become so darn useful and foundational. They
originated from an idea by Jan Knepper.

The unexpected utility of them explains why they haven't appeared in
other languages (yet).


Oh... I remember those early D-Days...


Re: Keyword arguments / Named parameters library implementation

2012-03-21 Thread bearophile
Andrei Alexandrescu:

bearophile:
> > Right. Even if your code is good, named arguments are a feature that
> > needs to be built-in, or it will not happen. Creative usage of the
> > language has its limits.
> 
> I think we're very far away from them.

With a less sleepy brain I understand, your "them" refers to the limits.
I agree that probably there are several creative uses to be invented still of 
the currently present D features. But I don't think the creative use of the 
current D features will give us good enough named parameters :-)

Bye,
bearophile


Re: Three Unlikely Successful Features of D

2012-03-21 Thread Masahiro Nakagawa
On Tuesday, 20 March 2012 at 19:02:16 UTC, Andrei Alexandrescu 
wrote:
I plan to give a talk at Lang.NEXT 
(http://channel9.msdn.com/Events/Lang-NEXT/Lang-NEXT-2012) with 
the subject above. There are a few features of D that turned 
out to be successful, in spite of them being seemingly 
unimportant or diverging from related consecrated approaches.


What are your faves? I have a few in mind, but wouldn't want to 
influence answers.



Thanks,

Andrei


1. Compile time reflection

This feature enables MessagePack to (de)serialize existing class 
and struct :)


2. Template friends

Easy syntax, static if(and is), alias,  mixin and other features 
are very useful.

An essential parts ingredient to write D program.

3. Built-in array and slice

I heavily use this feature in many cases.
Template engine, complex computation and network programming :)


Masahiro


Re: Proposal: user defined attributes

2012-03-21 Thread Adam D. Ruppe

On Wednesday, 21 March 2012 at 08:29:23 UTC, Tove wrote:
With the mixin improvement proposal any arbitrarily complex 
feature can be implemented in the library, appearing to enjoy 
first class syntax with just 1 extra character penalty vs the 
compiler.


My main concern with the library implementation isn't
syntax.

The big question is still: where will you put the
annotation data?


Re: Three Unlikely Successful Features of D

2012-03-21 Thread Patrick Down

On Wednesday, 21 March 2012 at 02:47:20 UTC, Walter Bright wrote:
Andrei discovered an amazing use of auto. It enables you to 
create variables with voldemort types "that may not be named".


+1 LOL for Voldemort types





Re: Proposal: user defined attributes

2012-03-21 Thread Steven Schveighoffer
On Tue, 20 Mar 2012 12:16:41 -0400, Andrei Alexandrescu  
 wrote:



On 3/20/12 11:09 AM, Steven Schveighoffer wrote:

On Tue, 20 Mar 2012 11:17:02 -0400, Andrei Alexandrescu
 wrote:

I'm afraid I disagree. A targeted language feature definitely makes a
library approach inferior, by definition. But adding features is
cheating, like printing money is for a government: very tempting, with
apparently good short-term benefits, but with devastating cumulative
effects.


Not exactly. We could all be writing code in assembly if "adding
features" was always caustic.


This is trivializing my point. Please.


Well, then let's not compare the hyperinflation of the economy to adding a  
compiler feature.  There are certainly good reasons to add compiler  
features, without devastating cumulative effects.



What is nice about adding this feature is it provides a custom solution
to hooking the compiler's TypeInfo generation. We are setting up the
compiler to give us hooks so we *don't* have to extend the compiler
every time we want new reflection features.


There is something nice about every new feature.


Yes, but this nicety is not just syntax sugar or a shortcut, it's adding a  
whole new opportunity of communication through the compile-time/runtime  
barrier.


I think Adam Ruppe's post on how he tried to use library code to  
accomplish this is quite telling.  The comparison to OO programming in C  
vs. C++/D seems quite appropriate.  And I've written Xt widgets, so I can  
vouch for how shitty it is to do OO programming in C.



One of the oft-requested features of D is reflection capability. The
answer is generally that we have compile-time reflection, which can
theoretically be used to build runtime reflection. However, the rebuttal
I always come back with is "yeah, but why should I build at runtime that
which is obvious at compile time?"


I thought there were discussions that didn't add runtime overhead.


I haven't seen that.  Perhaps a link?


Note that one library that did attempt runtime reflection capability
(flectioned) does all this at runtime, and does some really funky shit,
like opening /proc/self/map on Linux, or requiring you to pass an
OPTLINK map file. I don't look at these as "innovations" as much as I do
as workarounds.


Maybe there's a better approach than flectioned. Consider the language  
is frozen solid. How would you solve problems with it?


I think the closest anyone has come is Jacob, with his orange library.   
Maybe he can respond to this point.


-Steve


Re: Proposal: user defined attributes

2012-03-21 Thread Adam D. Ruppe

On Wednesday, 21 March 2012 at 08:08:12 UTC, Jacob Carlborg wrote:
That's basically my initial proposal and how annotations work 
in Java.


Cool. I did not realize that.


Re: What about putting array.empty in object.d?

2012-03-21 Thread Steven Schveighoffer
On Wed, 21 Mar 2012 00:54:51 -0400, Daniel Murphy  
 wrote:


FWIW, I would rather see `if (array)` translated to `if (array.length)`  
and
this become the recomended way to check if an array is empty.  Wouldn't  
that

remove the dependency on std.array for most of the cases?


+1

-Steve


Re: Three Unlikely Successful Features of D

2012-03-21 Thread Adam D. Ruppe
On Wednesday, 21 March 2012 at 02:14:26 UTC, Nick Sabalausky 
wrote:
Ooh, nested functions and closures are another good one (or 
two).


I wouldn't call that unlikely, since nested functions are
one of the things I considered a potential killer feature
when I started with D.

(and indeed, it is very useful!)

Nested functions, auto, and scope guards were the
three killers in the pre-D1 that roped me in. And
they rok, oh they rok. But that is "likely success" :)

(well, and fast compilation; going back to Digital Mars
after some years of slow ass g++ was/is heaven)


One that surprised me personally though is import. Indeed,
import is why I passed over D the first time I looked
at it (in 2004 IIRC) - I saw "import" and said "gah
include is fine, eff this Java like poo..

Even when I got into D, I had to give myself comfort
that I can still have #include with mixin(import()) -
something I have never actually wanted to use after
writing the first line of real code.


import is amazing. D gets it all right, even with
stuff like bug 314, it is awesome.



But, is import unlikely success, or is this just a
leftover feeling from my massive bias in the early
days? I have to say it is my bias, since everyone
else uses import and they all know it is good.


Re: opEquals/opCmp returning other types

2012-03-21 Thread Brian Palmer

On Wednesday, 21 March 2012 at 11:05:41 UTC, Don Clugston wrote:


I don't think this is EVER what you really want.
I believe that if you think you want this feature, 100% of the 
time, what you really want is a syntax tree of the entire 
expression. That is, either you want ">" to be a comparison, 
and "+" to be an addition, OR you want a syntax tree.


Well yes, the whole point is to build up a syntax tree that can 
be manipulated before being outputted as a raw sql string. The 
operator overloading is a convenient way to do that, that has 
turned out to be intuitive and easy for developers to use in many 
other DSLs. To say that's not EVER what you really want seems a 
bit silly, considering all the libraries in other languages that 
utilize this technique.


That said, if this isn't the D way, it's not the D way, I'm 
certainly not going to try and shoe-horn it in based on undefined 
behavior or something.


Re: Three Unlikely Successful Features of D

2012-03-21 Thread Steven Schveighoffer
On Tue, 20 Mar 2012 15:02:15 -0400, Andrei Alexandrescu  
 wrote:


I plan to give a talk at Lang.NEXT  
(http://channel9.msdn.com/Events/Lang-NEXT/Lang-NEXT-2012) with the  
subject above. There are a few features of D that turned out to be  
successful, in spite of them being seemingly unimportant or diverging  
from related consecrated approaches.


What are your faves? I have a few in mind, but wouldn't want to  
influence answers.


The two that I would cite are auto and slice syntax.  I see others have  
chimed in with the same two.


These were two features that did *not* attract me to D, but I found them  
to be two of my favorites, and ones I miss the most when writing in other  
languages.


If I had to pick a third, I'd say the omitting parentheses for 1-arg  
templates was something I didn't expect to be as great as it is.


Possibly one other thing I didn't expect to be so nice was shared (more  
specifically, the implications when something is *not* shared).  That  
enabled weak-pure functions which I think are going to be a HUGE feature  
for D.


-Steve


Re: Three Unlikely Successful Features of D

2012-03-21 Thread pillsy
On Tuesday, 20 March 2012 at 19:02:16 UTC, Andrei Alexandrescu 
wrote:


There are a few features of D that turned out to be successful, 
in spite of them being seemingly unimportant or diverging from 
related consecrated approaches.


What are your faves? I have a few in mind, but wouldn't want to 
influence answers.


I know people have said all of these already, but I still want to 
vote for
them, because they're so useful, and I routinely find myself 
wishing I had

them in other languages.

1. Array slices. These allow for a lot of gains from structure
   sharing and "flyweighting"; safe structure sharing is one 
of the
   potential big wins from GC, but in most languages with GC 
it's
   tricky to share structure that's in arrays, leading to a 
lot of

   extra space overhead for pointers and worse cache behavior
   due to excessive scattering of objects around the heap.

2. Scope guard. At first I thought it was a neat little 
curiosity,
   but it makes it so easy to write and (more importantly) 
*read*
   error handling code that, whenever I use D, I find myself 
thinking
   about and dealing with potential failure modes that I 
would gloss

   over in another language.

3. Template syntax. When I first saw that it used an infix 
'!' of all
   things, and that the parentheses were optional, I thought 
it was the
   dumbest syntax ever. In practice, though, it's so much 
better than

   C++'s <> disaster that it's just not funny.

A bunch of other features, like type inference, I totally 
expected to be extremely useful. The way auto lets you work with 
objects that have
unutterable types is pretty cool, though I picked that up from 
the C++11
materials I've seen. They really need the feature to make the new 
lambdas

work.

Cheers,
Pillsy


Re: Proposal: user defined attributes

2012-03-21 Thread Jacob Carlborg

On 2012-03-21 14:54, Steven Schveighoffer wrote:

On Tue, 20 Mar 2012 12:16:41 -0400, Andrei Alexandrescu
 wrote:


Maybe there's a better approach than flectioned. Consider the language
is frozen solid. How would you solve problems with it?


I think the closest anyone has come is Jacob, with his orange library.
Maybe he can respond to this point.

-Steve


With Orange I'm doing everything with compile time reflection. 
Flectioned was all about runtime reflection. It's possible to replace 
methods with flectioned at runtime and do a lot of crazy things.


In Orange I'm using mixins, tupleof and stringof to accomplish most of 
the compile time reflection. Example:


class Foo
{
int a;
int b;

mixin NonSerialized!(b);
}

serialize(new Foo);

"mixin NonSerialized!(b);" is expanded to:

static const __nonSerialized = ["a"];

The fields are enumerated and serialized using tupleof. It also checks 
all structs and classes if they have "__nonSerialized" defined.


--
/Jacob Carlborg


Re: Proposal: user defined attributes

2012-03-21 Thread Jacob Carlborg

On 2012-03-21 15:02, Adam D. Ruppe wrote:

On Wednesday, 21 March 2012 at 08:08:12 UTC, Jacob Carlborg wrote:

That's basically my initial proposal and how annotations work in Java.


Cool. I did not realize that.


Here's my proposal:

http://forum.dlang.org/thread/bccwycoexxykfgxve...@forum.dlang.org?page=3#post-jk2d4t:242ban:241:40digitalmars.com

--
/Jacob Carlborg


Re: Proposal: user defined attributes

2012-03-21 Thread Andrei Alexandrescu

On 3/21/12 9:57 AM, Jacob Carlborg wrote:

On 2012-03-21 14:54, Steven Schveighoffer wrote:

On Tue, 20 Mar 2012 12:16:41 -0400, Andrei Alexandrescu
 wrote:


Maybe there's a better approach than flectioned. Consider the language
is frozen solid. How would you solve problems with it?


I think the closest anyone has come is Jacob, with his orange library.
Maybe he can respond to this point.

-Steve


With Orange I'm doing everything with compile time reflection.
Flectioned was all about runtime reflection. It's possible to replace
methods with flectioned at runtime and do a lot of crazy things.

In Orange I'm using mixins, tupleof and stringof to accomplish most of
the compile time reflection. Example:

class Foo
{
int a;
int b;

mixin NonSerialized!(b);
}


I think the liability here is that b needs to appear in two places, once 
in the declaration proper and then in the NonSerialized part. (A 
possible advantage is that sometimes it may be advantageous to keep all 
symbols with a specific attribute in one place.) A possibility would be 
to make the mixin expand to the field and the metadata at once.



serialize(new Foo);

"mixin NonSerialized!(b);" is expanded to:

static const __nonSerialized = ["a"];

The fields are enumerated and serialized using tupleof. It also checks
all structs and classes if they have "__nonSerialized" defined.


Did you mean

static const __nonSerialized = ["b"];

?

In case there are several non-serialized variables, how do you avoid 
clashes between different definitions of __nonSerialized?



Thanks,

Andrei


Re: Proposal: user defined attributes

2012-03-21 Thread Adam D. Ruppe
On Wednesday, 21 March 2012 at 13:54:29 UTC, Steven Schveighoffer 
wrote:
I think the closest anyone has come is Jacob, with his orange 
library.  Maybe he can respond to this point.


I have some runtime reflection in web.d, but the way I do
it is to build up the info at startup, and there's a
special field in the class to hold it.

simplified:

struct Reflection {
   string name;
   ClassInfo[string] objects;
   FunctionInfo[string] functions;
   // etc
}
class ApiProvider { immutable(Reflection)* reflection; }
immutable(Reflection)* prepareReflection(T)(T t) {
   Reflection* r = new Reflection();
   foreach(member; __traits(allMembers, T))
  static if(type..)
r.typeInfo[member] = prepareReflection(getMember);
}


To call functions, it makes a wrapper that converts
strings to the right types in a ParameterTypeTuple:

functionInfo.caller = wrap!func;

string delegate(string[][string]) wrap(alias func)() {
   return delegate string(string[][string] uriArgs) {
  foreach(type; ParameterTypeTuple!func)
   blah = to!typeof(blah)(uriArgs[name]);

  return to!string(func(args));
   }
}

and so on. Of course, the real thing is a lot longer than
this, but you can see the idea.



Once it is all populated at startup, you can do:

myobj.reflection.functions["cool"].call(decodeUriVars("sweet=yes&awesome=def"));


and have it work.


Re: Proposal: user defined attributes

2012-03-21 Thread F i L

Andrei Alexandrescu wrote:
In case there are several non-serialized variables, how do you 
avoid clashes between different definitions of __nonSerialized?


struct A {
   int a, b;
   mixin NonSerialized!(a, b);
}

static const __nonSerialized = ["a", "b"];



Re: Three Unlikely Successful Features of D

2012-03-21 Thread Don Clugston

On 21/03/12 03:47, Walter Bright wrote:

On 3/20/2012 4:39 PM, H. S. Teoh wrote:

On Tue, Mar 20, 2012 at 06:58:31PM -0400, Nick Sabalausky wrote:

- Type inference


Yeah I forgot about this one. Being able to write:

auto veryLongNamedObject = new VeryLongNamedClass(veryLongArguments);

is a big boon over C++ or Java's stuttering verbosity:

VeryLongNamedClass veryLongNamedObject = new
VeryLongNamedClass(veryLongArguments);

Plus, it's immensely useful when dealing with Range templates... can you
imagine the horrifically long typenames you'd have to type you have to
explicitly specify the type of a long chain of functional expressions
involving 15+ std.algorithm and std.range templates?


Andrei discovered an amazing use of auto. It enables you to create
variables with voldemort types "that may not be named".

For example:

auto foo()
{
struct S { ... }
S s;
return s;
}

auto x = foo();

And now x is an instance of a voldemort type! It's completely encapsulated.


That idiom is already built into the language. Anonymous nested classes 
don't have a name at all.


auto x = new class {  ... }



Re: Proposal: user defined attributes

2012-03-21 Thread F i L

On Wednesday, 21 March 2012 at 15:20:35 UTC, F i L wrote:

Andrei Alexandrescu wrote:
In case there are several non-serialized variables, how do you 
avoid clashes between different definitions of __nonSerialized?


struct A {
   int a, b;
   mixin NonSerialized!(a, b);
}

static const __nonSerialized = ["a", "b"];


Also, if where meant how could you store multiple types, you 
could just use an Associative Array:


struct A {
  int a;
  float b;
  mixin NonSerialized!(a, b);
}

static const __nonSerialized = ["int":"a", "int":"b"];




Re: Proposal: user defined attributes

2012-03-21 Thread F i L

static const __nonSerialized = ["int":"a", "int":"b"];


Typo, I meant: ["int":"a", "float":"b"];



Re: CTFE bug causes null check to pass on null pointers (Issue 7602)

2012-03-21 Thread H. S. Teoh
On Wed, Mar 21, 2012 at 10:55:05AM +0100, David Nadlinger wrote:
> On Wednesday, 21 March 2012 at 09:51:43 UTC, Jens Mueller wrote:
> >Interesting. How do I make use of this?
> >
> >[…]
> >
> >What's the trick to use memory allocated in a CTFE. Say e.g. I want
> >to build a tree at compile time using CTFE.
> 
> You can't do that right now (i.e. converting CTFE-allocated memory to
> initializers for run-time values), but it enables you to use classes,
> etc. _during_ CTFE.
[...]

Actually you can... though it requires hacks using string mixins.

Basically, you create the structure in CTFE, then walk the structure and
construct a string containing declarations of the form:

"struct node __node_1234 = { value1, value2, ... };"

then use a string mixin to instantiate them. This will create the tree
nodes as module globals, so they are compiled into the object file. They
therefore also have runtime addresses, so the root of the tree can be
assigned into a runtime tree pointer, for example.


T

-- 
Let X be the set not defined by this sentence...


Re: What about putting array.empty in object.d?

2012-03-21 Thread Xinok

On Wednesday, 21 March 2012 at 04:54:54 UTC, Daniel Murphy wrote:
FWIW, I would rather see `if (array)` translated to `if 
(array.length)` and
this become the recomended way to check if an array is empty.  
Wouldn't that

remove the dependency on std.array for most of the cases?


Nope. .length is a requirement for finite random-access ranges, 
but not for forward or bidirectional ranges. .empty is the only 
primitive required by all input ranges.


So if you pass an array to a function expecting a forward range, 
it may not work if the primitive .empty doesn't exist.


Re: Three Unlikely Successful Features of D

2012-03-21 Thread Kagamin

On Tuesday, 20 March 2012 at 21:43:25 UTC, Walter Bright wrote:

On 3/20/2012 12:02 PM, Andrei Alexandrescu wrote:
What are your faves? I have a few in mind, but wouldn't want 
to influence answers.


Although array slices have been in D nearly since the 
beginning, I had little idea they would become so darn useful 
and foundational. They originated from an idea by Jan Knepper.


The unexpected utility of them explains why they haven't 
appeared in other languages (yet).


As to me, slices are the most important feature of D, and they 
were the major improvement from the start, aimed to fix the 
buffer overflow vulnerabilities - the plague of low level 
languages - at the lowest cost. What can do more than that? I 
thought they were born to be epic: safety, minimalism a 
efficiency combined.


Re: Three Unlikely Successful Features of D

2012-03-21 Thread Brad Anderson
On Wed, Mar 21, 2012 at 2:06 AM, Martin Nowak  wrote:

> It's probably far too early to think about this with all the other
>> important issues you're addressing but have you given much thought to
>> improving the hashing function?  I haven't hit any issues with the speed
>> of
>> the current hasher but better performance is always welcome. MurmurHash
>> seems to be all the rage these days with a lot of languages and systems
>> adopting it 
>> >
>> (it compiles down to
>> ~52 instructions on x86). It'd be interesting to see benchmarks with it.
>> I'm not sure where the current hashing function lives to see what it's
>> like.
>>
>> Regards,
>> Brad Anderson
>>
>
> More throughput but higher latency.
> http://codepad.org/kCVQ8eoq
> Murmurhash was a little slower than CityHash but
> both are a little expensive for very few bytes.
>

Interesting.  Thanks for the link.

Regards,
Brad Anderson


Re: I do a really bad job as marketer

2012-03-21 Thread Simen Kjærås
On Wed, 21 Mar 2012 10:12:31 +0100, Dmitry Olshansky  
 wrote:


See this is Jun 2012 post on perl group speaking of unicode support on  
development branch:

http://code.activestate.com/lists/perl5-porters/173477/

Now, keep in mind, that std.regex had O(1) trie lookup for these things  
from day one, because inversion lists with O(lnN) lookup  alone were too  
slow.




June 2012, eh? When you're done with it, can I borrow your time machine?


Re: Three Unlikely Successful Features of D

2012-03-21 Thread F i L
Another feature I like a lot about D, is it's approach to nested 
classes. I'm not sure how it compares to other languages, but in 
C# nested classes can be instanced individually and therefor 
don't have access to their containing class's variables. D's 
approach is much more logical, and works great for simple state 
systems:


  abstract class Actor {
interface State {
  void update();
}
State state;
final void update() {
  assert(state, "State is null");
  state.update();
}
  }

  class Fighter : Actor {
Idle : State {
  void update() {
punch(); // can punch automatically
  }
}
Idle idleState = new Idle();
this() {
  state = idleState;
}
void punch() { ... }
  }

In C# I'd have to manually pass an Fighter reference to Idle's 
constructor and manually manage the reference. It's a small 
thing, but considering referencing the container class is a core 
mechanic of any Stated object, it's a pain having to rewrite it, 
while D just works.


Re: Proposal: user defined attributes

2012-03-21 Thread Adam D. Ruppe

On Wednesday, 21 March 2012 at 15:02:15 UTC, Jacob Carlborg wrote:

Here's my proposal:


Ah yes, I think I did read that before.

I'm not in love with the key=value or the explicit
@attribute on the classes, which is the two biggest
differences we have.

The key=value is nice, but it isn't in the language today,
so it'd be a bunch of special code in the @attribute parser
in the compiler.

If we were to have key=value syntax, I say we should do it
generically (like C style struct initializers?) so it can
work in regular code too, then pick it up naturally here.


I'd prefer to use the existing language syntax in there
so the implementation can literally be as simple as:

if(token == TOKnote) {
   token.next();
   annotations ~= parseExpression();
}


D's existing struct syntax can handle arguments easily
enough with the StructName("member", "member"); style.
Reusing that here keeps the implementation simple,
and it might be more flexible:

enum MyNote = Something("with args", 2);

@note(MyNote) int foo;
@note(MyNote) bool bar;


this would work too with the simple setup, since the
enum is already handled by the compiler's regular code.
Ditto with ctfe, which is an open hook for some potentially
cool stuff down the line without any extra implementation.



The other thing is @attribute struct {} rather than just
struct {}. I don't any benefit to that.  If I want to
reuse a regular, runtime struct to store info at compile
time, why shouldn't I be able to do that?


I'm thinking of @note(X) as meaning simply:

enum tmp = X; // evaluate ctfe, etc
decl.annotations ~= tmp; // store it for later


Re: Proposal: user defined attributes

2012-03-21 Thread Andrei Alexandrescu

On 3/21/12 10:20 AM, F i L wrote:

Andrei Alexandrescu wrote:

In case there are several non-serialized variables, how do you avoid
clashes between different definitions of __nonSerialized?


struct A {
int a, b;
mixin NonSerialized!(a, b);
}

static const __nonSerialized = ["a", "b"];


That's may be a problem because it makes it impossible to put together 
fields and their non-serializable property.


Ideally the above should work, and also mixing in several NonSerialized 
instances within the same type should also work.



Andrei



Re: Proposal: user defined attributes

2012-03-21 Thread Andrei Alexandrescu

On 3/21/12 10:26 AM, F i L wrote:

On Wednesday, 21 March 2012 at 15:20:35 UTC, F i L wrote:

Andrei Alexandrescu wrote:

In case there are several non-serialized variables, how do you avoid
clashes between different definitions of __nonSerialized?


struct A {
int a, b;
mixin NonSerialized!(a, b);
}

static const __nonSerialized = ["a", "b"];


Also, if where meant how could you store multiple types, you could just
use an Associative Array:

struct A {
int a;
float b;
mixin NonSerialized!(a, b);
}

static const __nonSerialized = ["int":"a", "int":"b"];


Is this implemented, or a thought?

Andrei


Re: String mixin syntax sugar

2012-03-21 Thread RivenTheMage

On Wednesday, 21 March 2012 at 12:37:50 UTC, Mantis wrote:
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?


What about "@" for built-in annotations and "@!" for user-defined?

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


Re: Proposal: user defined attributes

2012-03-21 Thread Timon Gehr

On 03/20/2012 10:36 PM, deadalnix wrote:

Even the propagation of pure, @safe, nothrow and const that has been
discussed recently can be done with that feature.



I'm sceptical. How would that work exactly?



Re: Proposal: user defined attributes

2012-03-21 Thread F i L

Andrei Alexandrescu wrote:

Is this implemented, or a thought?


Just a thought (I even accidentally reversed the key-value 
order), but I don't see why it couldn't work. I'll try and make 
up a quick implementation.





Re: Three Unlikely Successful Features of D

2012-03-21 Thread H. S. Teoh
On Tue, Mar 20, 2012 at 11:54:37PM -0600, Brad Anderson wrote:
[...]
> It's probably far too early to think about this with all the other
> important issues you're addressing but have you given much thought to
> improving the hashing function?  I haven't hit any issues with the
> speed of the current hasher but better performance is always welcome.
> MurmurHash seems to be all the rage these days with a lot of languages
> and systems adopting it  (it
> compiles down to ~52 instructions on x86). It'd be interesting to see
> benchmarks with it.  I'm not sure where the current hashing function
> lives to see what it's like.
[...]

The current implementation actually has (at least) two different hash
functions:

- Paul Hsieh's SuperFastHash (rt.util.hash.hashOf)
- A custom hash for char[] and string: look in rt/typeinfo/ti_Ag.d for
  class TypeInfo_Aa, which has this:

hash_t hash = 0;
foreach (char c; s)
hash = hash * 11 + c;

I'm going to benchmark both hash functions to see which is actually
faster. I suspect the custom hash is faster for small strings, though it
may not have good hash distribution.


T

-- 
Microsoft is to operating systems & security ... what McDonalds is to gourmet 
cooking.


Re: Proposal: user defined attributes

2012-03-21 Thread Andrei Alexandrescu

On 3/21/12 11:15 AM, F i L wrote:

Andrei Alexandrescu wrote:

Is this implemented, or a thought?


Just a thought (I even accidentally reversed the key-value order), but I
don't see why it couldn't work. I'll try and make up a quick
implementation.


Wouldn't a better approach rely on a compile-time structure instead of a 
hash?


Andrei



Re: Proposal: user defined attributes

2012-03-21 Thread Andrei Alexandrescu

On 3/21/12 11:17 AM, Timon Gehr wrote:

On 03/20/2012 10:36 PM, deadalnix wrote:

Even the propagation of pure, @safe, nothrow and const that has been
discussed recently can be done with that feature.



I'm sceptical. How would that work exactly?


I, too, am highly skeptical. For one thing these attributes must be made 
part of the type and have deep connections with code semantics.


Andrei


Re: Proposal: user defined attributes

2012-03-21 Thread F i L
On Wednesday, 21 March 2012 at 16:21:21 UTC, Andrei Alexandrescu 
wrote:

On 3/21/12 11:15 AM, F i L wrote:

Andrei Alexandrescu wrote:

Is this implemented, or a thought?


Just a thought (I even accidentally reversed the key-value 
order), but I

don't see why it couldn't work. I'll try and make up a quick
implementation.


Wouldn't a better approach rely on a compile-time structure 
instead of a hash?


I'm not sure, you're understand of D's compiler-time structures 
is much better than mine. Serialization "attributes" are mostly 
used at runtime, so having mixing in a static enum *should* mean 
reflection upon the property at both runtime and compiletime.





Re: opEquals/opCmp returning other types

2012-03-21 Thread H. S. Teoh
On Wed, Mar 21, 2012 at 03:29:21PM +0100, Brian Palmer wrote:
> On Wednesday, 21 March 2012 at 11:05:41 UTC, Don Clugston wrote:
> 
> >I don't think this is EVER what you really want.
> >I believe that if you think you want this feature, 100% of the
> >time, what you really want is a syntax tree of the entire
> >expression. That is, either you want ">" to be a comparison, and
> >"+" to be an addition, OR you want a syntax tree.
> 
> Well yes, the whole point is to build up a syntax tree that can be
> manipulated before being outputted as a raw sql string. The operator
> overloading is a convenient way to do that, that has turned out to
> be intuitive and easy for developers to use in many other DSLs. To
> say that's not EVER what you really want seems a bit silly,
> considering all the libraries in other languages that utilize this
> technique.
> 
> That said, if this isn't the D way, it's not the D way, I'm
> certainly not going to try and shoe-horn it in based on undefined
> behavior or something.

The "D way" is to use strings for DSELs which get evaluated at
compile-time, or a custom set of methods that you can build expressions
out of. Operator overloading really should be limited to arithmetic
types (for numerical classes) and built-in operations like array lookups
and stuff.

Trying to shoehorn language-level operators to do something they weren't
intended to do only leads to problems. (C++'s overloading of << and >>
for I/O is a very bad design decision IMO.)


T

-- 
Why is it that all of the instruments seeking intelligent life in the universe 
are pointed away from Earth? -- Michael Beibl


Re: I do a really bad job as marketer

2012-03-21 Thread Dmitry Olshansky

On 21.03.2012 19:54, Simen Kjærås wrote:

On Wed, 21 Mar 2012 10:12:31 +0100, Dmitry Olshansky
 wrote:


See this is Jun 2012 post on perl group speaking of unicode support on
development branch:
http://code.activestate.com/lists/perl5-porters/173477/

Now, keep in mind, that std.regex had O(1) trie lookup for these
things from day one, because inversion lists with O(lnN) lookup alone
were too slow.



June 2012, eh? When you're done with it, can I borrow your time machine?


Ah, it's a nice typo.
It nevertheless underlines how far behind the perl folks are ;)

--
Dmitry Olshansky


Re: Proposal: user defined attributes

2012-03-21 Thread Jacob Carlborg

On 2012-03-21 16:11, Andrei Alexandrescu wrote:
I think the liability here is that b needs to appear in two places, once

in the declaration proper and then in the NonSerialized part. (A
possible advantage is that sometimes it may be advantageous to keep all
symbols with a specific attribute in one place.) A possibility would be
to make the mixin expand to the field and the metadata at once.


Yes, but that just looks ugly:

class Foo
{
int a;
mixin NonSerialized!(int, "b");
}

That's why it's so nice with attributes.


Did you mean

static const __nonSerialized = ["b"];

?


Yes, sorry.


In case there are several non-serialized variables, how do you avoid
clashes between different definitions of __nonSerialized?


In my current implementation you are forced to only mixin one 
NonSerialized per type:


class Foo
{
int a;
int b;
mixin NonSerialized!(a, b);
}

Of course there are ways around that with various pros and cons.

--
/Jacob Carlborg


Re: Proposal: user defined attributes

2012-03-21 Thread Jacob Carlborg

On 2012-03-21 16:26, F i L wrote:


Also, if where meant how could you store multiple types, you could just
use an Associative Array:

struct A {
int a;
float b;
mixin NonSerialized!(a, b);
}

static const __nonSerialized = ["int":"a", "int":"b"];


Only the name of the variables are necessary in my serialization library.

--
/Jacob Carlborg


Re: Proposal: user defined attributes

2012-03-21 Thread Jacob Carlborg

On 2012-03-21 16:20, F i L wrote:

Andrei Alexandrescu wrote:

In case there are several non-serialized variables, how do you avoid
clashes between different definitions of __nonSerialized?


struct A {
int a, b;
mixin NonSerialized!(a, b);
}

static const __nonSerialized = ["a", "b"];



Exactly.

--
/Jacob Carlborg


Re: Three Unlikely Successful Features of D

2012-03-21 Thread F i L
And for my third favorite (in no order), I like custom 
allocators/deallocators. They're nice for creating "invisible" 
memory pools:


  static class Pool(T, uint size = 100) {
static T[size] pool;
static void* alloc() { ... }
static void free(void* p) { ... }
  }

  mixin template UsePool(T, uint size = 100) {
new(uint s) {
  return Pool!(T, size).alloc();
}
delete(void* p) {
  Pool!(T, size).free(p);
}
  }

  class Test {
mixin UsePool!(Test, 50);
  }

then later in you code, you can just instantiate Test like any 
other object:


  auto t = new Test();

But if instances of Test are often created/released the 
performance is much better. Or you can wired it up so that you 
can pass custom Pools (overriding a default):


  auto t = new(CustomPool) Test();



Re: Three Unlikely Successful Features of D

2012-03-21 Thread Walter Bright

On 3/21/2012 8:21 AM, Don Clugston wrote:

On 21/03/12 03:47, Walter Bright wrote:

And now x is an instance of a voldemort type! It's completely encapsulated.


That idiom is already built into the language. Anonymous nested classes don't
have a name at all.

auto x = new class { ... }



True, but it's the ability to return them from a function that's new & cool!

(Yes, I know you can return x as type "Object".)


Re: Three Unlikely Successful Features of D

2012-03-21 Thread Dmitry Olshansky

On 21.03.2012 21:14, F i L wrote:

And for my third favorite (in no order), I like custom
allocators/deallocators. They're nice for creating "invisible" memory
pools:


Sorry to spoil the excitement, but aren't they deprecated?
[snip]

--
Dmitry Olshansky


Re: Three Unlikely Successful Features of D

2012-03-21 Thread Walter Bright

On 3/21/2012 7:23 AM, Adam D. Ruppe wrote:

But, is import unlikely success, or is this just a
leftover feeling from my massive bias in the early
days? I have to say it is my bias, since everyone
else uses import and they all know it is good.


I knew import would be good :-)

It's because I've used languages before with an import, and as a compiler guy, I 
knew what a kludge #include is. The preprocessor in C/C++ is a crutch to make up 
for deficiencies in the language.


Re: What about putting array.empty in object.d?

2012-03-21 Thread Steven Schveighoffer

On Wed, 21 Mar 2012 11:50:46 -0400, Xinok  wrote:


On Wednesday, 21 March 2012 at 04:54:54 UTC, Daniel Murphy wrote:
FWIW, I would rather see `if (array)` translated to `if (array.length)`  
and
this become the recomended way to check if an array is empty.  Wouldn't  
that

remove the dependency on std.array for most of the cases?


Nope. .length is a requirement for finite random-access ranges, but not  
for forward or bidirectional ranges. .empty is the only primitive  
required by all input ranges.


So if you pass an array to a function expecting a forward range, it may  
not work if the primitive .empty doesn't exist.


from std/range.d:

module std.range;

public import std.array;

-Steve


Re: Proposal: user defined attributes

2012-03-21 Thread F i L

Jacob Carlborg wrote:
Only the name of the variables are necessary in my 
serialization library.


Wouldn't mixing in an enum be more useful? You could use it at 
compile time that way.


Re: Three Unlikely Successful Features of D

2012-03-21 Thread Walter Bright

On 3/21/2012 1:01 AM, Nick Sabalausky wrote:

Of course, to C++'s credit, its templates (AIUI) weren't really designed for
metaprogramming, just for generics. The metaprogramming was just a happy
accident (At least that's my understanding, maybe I'm wrong...)


You're correct. Metaprogramming was an emergent property of C++ templates, and 
was discovered, not designed.


Re: Proposal: user defined attributes

2012-03-21 Thread Adam D. Ruppe
On Wednesday, 21 March 2012 at 16:02:22 UTC, Andrei Alexandrescu 
wrote:
Ideally the above should work, and also mixing in several 
NonSerialized instances within the same type should also work.



Oh god, I feel like the spawn of Hacktan.

I'm taking the DSL identifiers to the max. Consider
the following:

http://arsdnet.net/dcode/omg.d


Bottom line:

struct A {
int a;
int b;
mixin Note!(a, q{ "NonSerialized" });
mixin Note!(a, q{ "Awesome" });
mixin Note!(b, q{ "Filthy Hack" });
}

void main() {
pragma(msg, getNotes!(A.a));
}

$ dmd omg.d
["NotSerialized", "Awesome"]



How does it work?



What it does is for each note, it creates a dummy
enum.

The enum's name is a D expression, encoded as a
valid identifier. This expression is a ~= op here.

The struct looks like this:

struct A{
  int a;
  int b;
  enum _attr_mixin_a_32_4c_NonSerialized;
  enum _attr_mixin_a_32_4c_Awesome;
  enum _attr_mixin_b_32_4c_Filthy_32_Hack;
}


getNotes looks for this pattern, decodes it,
and then mixes in the expression:

string[] notes;
if(identifier is the right item)
mixin("notes " ~ decoded_identifier);

return notes;




So, it embeds D code to rebuild the requested
data as the names of identifiers.

We run it every time we want to get it.



Note that everything I said in my long post still
applies here. Like I said before, we *can* make it
work, but it comes with a lot of baggage that hurts
maintainability and interop with third party code.

Remember, you have to add code to your library just
to *ignore* these attributes.

You can't just ignore them, no, you have to add special
code to skip them.

That's no good. This also has duplicated names and the
other problems mentioned before with overloading,
inheritance and more.


The compiler keeping a list of notes attached to the
declaration remains the only *right* way to do it. That
it is slightly prettier is an added benefit, but not the
main reason why we need it there.


Re: Three Unlikely Successful Features of D

2012-03-21 Thread Walter Bright

On 3/21/2012 7:45 AM, Steven Schveighoffer wrote:

If I had to pick a third, I'd say the omitting parentheses for 1-arg templates
was something I didn't expect to be as great as it is.


Yes, Andrei was the lone advocate of that for a while. Everyone else pooh-poohed 
it, including me.


Re: Proposal: user defined attributes

2012-03-21 Thread Adam D. Ruppe

On Wednesday, 21 March 2012 at 17:26:19 UTC, Adam D. Ruppe wrote:

The compiler keeping a list of notes attached to the
declaration remains the only *right* way to do it.


Another note on correctness btw, this thing is wrong
if in other modules.


mixin Note!(a, q{ NotSerialized() });

that string loses the exact type. But, let's
say we solved that, and uses the module name
or something.


But then, what if:

module cool;

import serialization.attributes;

struct cool {
   int a;
   mixin Note!(a, serialization.attributes.amazing);
}

==

// another module
import cool;
void main() {
   getNotes!(cool.cool.a);
}


That won't compile. When it tries to mixin the note,
it will say undefinied identifier "amazing" because
the mixin is evaluated in another scope than the original
declaration.

So while module cool imported serilization.attributes,
module main or module notes (I'm not sure exactly where this
is mixed in by the time we're all said and done tbh but it
doesn't matter) has not.


Thus the mixin will fail.



I had this same problem when trying to do default arguments
in web.d by parsing stringof and mixing it in.

It works for built-in types like string and int, but
it doesn't work for user defined types, which are perfectly
valid function params (they work fine in the rest of web.d).

But the mixin scope is wrong so those types become undefined.







Again, we can get kinda close with these D tricks, but it
just cannot go all the way - and much of the interesting stuff
is behind that barrier.


The compiler can do it easily though, and get it right, enabling
us to do a lot more in the library down the line.


Re: Three Unlikely Successful Features of D

2012-03-21 Thread F i L
On Wednesday, 21 March 2012 at 17:16:55 UTC, Dmitry Olshansky 
wrote:

On 21.03.2012 21:14, F i L wrote:

And for my third favorite (in no order), I like custom
allocators/deallocators. They're nice for creating "invisible" 
memory

pools:


Sorry to spoil the excitement, but aren't they deprecated?
[snip]


Come on, really? What's the reason for this? I did here about 
delete being depreciated, though I guess I didn't make the 
connection. Why is delete being removed anyways?


I really liked this ability, and I hope that it doesn't 
completely disappear, even if it's only sugar.


Re: Proposal: user defined attributes

2012-03-21 Thread Jacob Carlborg

On 2012-03-21 17:00, Adam D. Ruppe wrote:

On Wednesday, 21 March 2012 at 15:02:15 UTC, Jacob Carlborg wrote:

Here's my proposal:


Ah yes, I think I did read that before.

I'm not in love with the key=value or the explicit
@attribute on the classes, which is the two biggest
differences we have.

The key=value is nice, but it isn't in the language today,
so it'd be a bunch of special code in the @attribute parser
in the compiler.

If we were to have key=value syntax, I say we should do it
generically (like C style struct initializers?) so it can
work in regular code too, then pick it up naturally here.


Would "key: value" be possible. The syntax we have for AA literals?


I'd prefer to use the existing language syntax in there
so the implementation can literally be as simple as:

if(token == TOKnote) {
token.next();
annotations ~= parseExpression();
}


D's existing struct syntax can handle arguments easily
enough with the StructName("member", "member"); style.
Reusing that here keeps the implementation simple,
and it might be more flexible:

enum MyNote = Something("with args", 2);


That would be nice.


@note(MyNote) int foo;
@note(MyNote) bool bar;


But I don't like the @note syntax. I really would like this:

@MyNote int foo;



The other thing is @attribute struct {} rather than just
struct {}. I don't any benefit to that. If I want to
reuse a regular, runtime struct to store info at compile
time, why shouldn't I be able to do that?


I just throw that in because Java has it. Don't know if it's needed or 
not. Java has a kind of special syntax for default values with annotations.


--
/Jacob Carlborg


Re: MessagePack

2012-03-21 Thread Andrej Mitrovic
On 3/21/12, Masahiro Nakagawa  wrote:
> This feature enables MessagePack to (de)serialize existing class
> and struct :)

Hi,

it seems MessagePack won't compile with 2.058:

src\msgpack.d(2823): Error: template msgpack.MPObject.opEquals(Tdummy
= void) does not match any function template declaration
src\msgpack.d(2823): Error: template msgpack.MPObject.opEquals(Tdummy
= void) cannot deduce template function from argument types
!()(const(MPObject[]))
src\msgpack.d(2824): Error: template msgpack.MPObject.opEquals(Tdummy
= void) does not match any function template declaration
src\msgpack.d(2824): Error: template msgpack.MPObject.opEquals(Tdummy
= void) cannot deduce template function from argument types
!()(const(MPObject[MPObject]))

I don't really know how to fix it.


Wrong lowering for a[b][c]++

2012-03-21 Thread H. S. Teoh
A question was asked on the d-learn forum about why this throws a
RangeError:

int[string][int] map;
map["abc"][20]++;

This is understandable, since the compiler translates the second line to:

map.opIndex("abc").opIndexUnary!"++"(20);

Since map["abc"] doesn't exist yet, opIndex throws RangeError before we
ever get to the ++.

I'd like to propose the following fix: if a given chained indexing
expression has any operator applied to its final result (either a unary
operator like ++ or --, or an assignment operator like +=), then instead
of translating previous indexes into opIndex, the compiler should map it
to a new operator overload, say opIndexCreate, which creates the
relevant entry with default value if it doesn't exist yet. That is to
say:

map["abc"][20]++;

should be translated to:

map.opIndexCreate("abc").opIndexUnary!"++"(20);

where opIndexCreate looks something like:

Slot opIndexCreate(Key k) {
Slot *s = findSlot(k);
if (s is null) {
s = createNewSlot(k);
}
return s;
}

Similar changes should be made for expressions like a[b][c][d]=100, or
a[b][c][d]+=100.

In other words, if the tail of a chain of indexing operations maps to
opIndexAssign, opIndexUnary, or opIndexOpAssign, then all preceding
opIndex calls should be converted to opIndexCreate instead.

Comments?


T

-- 
One Word to write them all, One Access to find them, One Excel to count them 
all, And thus to Windows bind them. -- Mike Champion


Re: MessagePack

2012-03-21 Thread Andrej Mitrovic
On 3/21/12, Andrej Mitrovic  wrote:
> On 3/21/12, Masahiro Nakagawa  wrote:
>> This feature enables MessagePack to (de)serialize existing class
>> and struct :)
>
> Hi,
>
> it seems MessagePack won't compile with 2.058:

It seems to work if I change two opEquals functions from:

bool opEquals(T : MPObject[])(in T other) const
bool opEquals(T : MPObject[MPObject])(in T other) const

to:
bool opEquals()(auto ref const MPObject[] other) const
bool opEquals()(auto ref const MPObject[MPObject] other) const


Re: MessagePack

2012-03-21 Thread Andrej Mitrovic
On 3/21/12, Andrej Mitrovic  wrote:
> It seems to work if I change two opEquals functions from:
>
> bool opEquals(T : MPObject[])(in T other) const
> bool opEquals(T : MPObject[MPObject])(in T other) const
>
> to:
> bool opEquals()(auto ref const MPObject[] other) const
> bool opEquals()(auto ref const MPObject[MPObject] other) const
>

Disregard that. It compiles but it doesn't work at runtime, it just
exits the application after a pack() call with no stacktrace or
errors.. Really bizarre.


Re: Wrong lowering for a[b][c]++

2012-03-21 Thread Jonathan M Davis
On Wednesday, March 21, 2012 11:29:14 H. S. Teoh wrote:
> A question was asked on the d-learn forum about why this throws a
> RangeError:
> 
> int[string][int] map;
> map["abc"][20]++;
> 
> This is understandable, since the compiler translates the second line to:
> 
> map.opIndex("abc").opIndexUnary!"++"(20);
> 
> Since map["abc"] doesn't exist yet, opIndex throws RangeError before we
> ever get to the ++.
> 
> I'd like to propose the following fix: if a given chained indexing
> expression has any operator applied to its final result (either a unary
> operator like ++ or --, or an assignment operator like +=), then instead
> of translating previous indexes into opIndex, the compiler should map it
> to a new operator overload, say opIndexCreate, which creates the
> relevant entry with default value if it doesn't exist yet. That is to
> say:
> 
> map["abc"][20]++;
> 
> should be translated to:
> 
> map.opIndexCreate("abc").opIndexUnary!"++"(20);
> 
> where opIndexCreate looks something like:
> 
> Slot opIndexCreate(Key k) {
> Slot *s = findSlot(k);
> if (s is null) {
> s = createNewSlot(k);
> }
> return s;
> }
> 
> Similar changes should be made for expressions like a[b][c][d]=100, or
> a[b][c][d]+=100.
> 
> In other words, if the tail of a chain of indexing operations maps to
> opIndexAssign, opIndexUnary, or opIndexOpAssign, then all preceding
> opIndex calls should be converted to opIndexCreate instead.
> 
> Comments?

IMHO, it's _horrible_ that C++ creates entries in a std::map when you ask for 
values that aren't there. A RangeError is _exactly_ what should be happening 
here. There's no element to increment, because it hasn't been added yet. I 
think that the current behavior is very much what the behavior _should_ be.

- Jonathan M Davis


Re: Three Unlikely Successful Features of D

2012-03-21 Thread Andrei Alexandrescu

On 3/21/12 12:14 PM, F i L wrote:

And for my third favorite (in no order), I like custom
allocators/deallocators.


They don't exist anymore.

Andrei



Re: Wrong lowering for a[b][c]++

2012-03-21 Thread David Nadlinger

On Wednesday, 21 March 2012 at 18:27:30 UTC, H. S. Teoh wrote:
A question was asked on the d-learn forum about why this throws 
a

RangeError:

int[string][int] map;
map["abc"][20]++;


Wait a second – aren't AAs _supposed_ to throw if accessing a 
key that doesn't exist yet? To be able to increment something, 
there already has to be a value to start from…


David


Re: Three Unlikely Successful Features of D

2012-03-21 Thread Andrei Alexandrescu

On 3/20/12 2:02 PM, Andrei Alexandrescu wrote:

I plan to give a talk at Lang.NEXT
(http://channel9.msdn.com/Events/Lang-NEXT/Lang-NEXT-2012) with the
subject above. There are a few features of D that turned out to be
successful, in spite of them being seemingly unimportant or diverging
from related consecrated approaches.

What are your faves? I have a few in mind, but wouldn't want to
influence answers.


It's official: 
http://channel9.msdn.com/Events/Lang-NEXT/Lang-NEXT-2012/Three-Unlikely-Successful-Features-of-D


Andrei



Re: Three Unlikely Successful Features of D

2012-03-21 Thread Andrei Alexandrescu

On 3/21/12 12:26 PM, Walter Bright wrote:

On 3/21/2012 7:45 AM, Steven Schveighoffer wrote:

If I had to pick a third, I'd say the omitting parentheses for 1-arg
templates
was something I didn't expect to be as great as it is.


Yes, Andrei was the lone advocate of that for a while. Everyone else
pooh-poohed it, including me.


I appreciate you implemented it in spite of not finding it compelling.

Andrei


Re: Proposal: user defined attributes

2012-03-21 Thread Steven Schveighoffer

On Wed, 21 Mar 2012 13:47:56 -0400, Jacob Carlborg  wrote:


On 2012-03-21 17:00, Adam D. Ruppe wrote:



The other thing is @attribute struct {} rather than just
struct {}. I don't any benefit to that. If I want to
reuse a regular, runtime struct to store info at compile
time, why shouldn't I be able to do that?


I just throw that in because Java has it. Don't know if it's needed or  
not. Java has a kind of special syntax for default values with  
annotations.


Really, the only requirement for an annotation expression should be that  
it's evaluated at compile time.


But we could see weird things with annotations if we don't specifically  
say what's an annotation and what is not.


For example:

// used as a normal datatype in most places
struct Point2d
{
  int X;
  int Y;
}

@Point2d int x; // ??
or
@note(Point2d) int x; // ??

In my proposal, I specified that the annotation can be applied only to  
module-level functions (normal or templated), and the result of those  
functions is what gets saved.  So with that capability, you should be able  
to store any CTFE-evaluatable struct:


@annotation auto makeAPoint() {Point2d p;  return p;}

@makeAPoint int x;

Which is as confusing as the above two examples, but at least *someone*  
declared it made sense to them ;)  Note that the @annotation function need  
not be stored in the EXE, it's only valid during CTFE.


I look at it similar to in C++ being able to throw any arbitrary type.   
Sure, you can just avoid creating an exception type that wraps an int, but  
it may not make sense to anyone if you just throw an int.


-Steve


Re: Proposal: user defined attributes

2012-03-21 Thread Andrei Alexandrescu

On 3/21/12 12:06 PM, Jacob Carlborg wrote:

On 2012-03-21 16:11, Andrei Alexandrescu wrote:
I think the liability here is that b needs to appear in two places, once

in the declaration proper and then in the NonSerialized part. (A
possible advantage is that sometimes it may be advantageous to keep all
symbols with a specific attribute in one place.) A possibility would be
to make the mixin expand to the field and the metadata at once.


Yes, but that just looks ugly:

class Foo
{
int a;
mixin NonSerialized!(int, "b");
}

That's why it's so nice with attributes.


Well if the argument boils down to nice vs. ugly, as opposed to possible 
vs. impossible - it's quite a bit less compelling.


Andrei




Re: "Forward reference" eror message improvement?

2012-03-21 Thread Mehrdad

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

"Daniel Murphy"  wrote in message news:jkbnqu$1l52$1...@digitalmars.com... 

"Mehrdad"  wrote in message 
news:jkak36$2skq$1...@digitalmars.com...

auto fact(int n) { return n > 1 ? fact(n - 1) : 0; }

// Error: forward reference to fact


I think the error message could be improved... maybe something like 
"forward reference to inferred return type" like we get with templates?


Please open an enhancement request. 



Re: Wrong lowering for a[b][c]++

2012-03-21 Thread Andrej Mitrovic
On 3/21/12, H. S. Teoh  wrote:
> Comments?

Initially I was against hash[key]++ working on non-existent keys, but
I've changed my mind about this. However it still throws me off that
hash[key1][key2]++ doesn't work if key1 doesn't exist.

So you get a +1 vote from me.


Re: What about putting array.empty in object.d?

2012-03-21 Thread Jonathan M Davis
On Wednesday, March 21, 2012 15:54:51 Daniel Murphy wrote:
> FWIW, I would rather see `if (array)` translated to `if (array.length)` and
> this become the recomended way to check if an array is empty. Wouldn't that
> remove the dependency on std.array for most of the cases?

The problem with checking whether length == 0 is that it's inefficient for some 
containers, so it's generally good practice to use empty rather than length. 
And while length == 0 is fine for arrays, it promotes bad habits in general, so 
I'm against it and think that code should pretty much always use empty rather 
than length == 0.

if(array)

is a bit different, because you're not specifically checking the length, but

if(container)

doesn't work in the general case, and stuff like

if(array || cond)

doesn't work. So, making

if(array)

be equivalent to

if(array.length != 0)

and

if(!array.empty)

rather than

if(array !is null)

may be a good idea, but it doesn't work in the general case. In the general 
case, you're still going to have to choose between length == 0 and empty, and 
I definitely think that empty is the correct choice, because it promotes good 
habits, whereas length == 0 promotes bad habits. So, there's value in putting 
empty in _object.d regardless of what happens with if.

Now, I find that I use enough other stuff in std.array, that it always gets 
imported anyway, but I don't think that putting empty in _object.d is a bad 
idea.

- Jonathan M Davis


Re: Wrong lowering for a[b][c]++

2012-03-21 Thread Andrej Mitrovic
On 3/21/12, Jonathan M Davis  wrote:
> I think that the current behavior is very much what the behavior _should_ be.

But the current behavior is already at odds. This already works:

int[string] foo;
foo["bar"]++;


Re: Wrong lowering for a[b][c]++

2012-03-21 Thread H. S. Teoh
On Wed, Mar 21, 2012 at 02:39:04PM -0400, Jonathan M Davis wrote:
[...]
> IMHO, it's _horrible_ that C++ creates entries in a std::map when you
> ask for values that aren't there. A RangeError is _exactly_ what
> should be happening here. There's no element to increment, because it
> hasn't been added yet. I think that the current behavior is very much
> what the behavior _should_ be.
[...]

Then what about:

int[string][int] map;
map["abc"][30] = 123;

?

Here, you clearly intend to create a new entry, but currently this
doesn't work. It will throw a RangeError when it tries to look up "abc".
You need the ugly workaround:

int[string][int] map;
map["abc"] = int[int].init;
map["abc"][30] = 123;


T

-- 
What doesn't kill me makes me stranger.


Re: Wrong lowering for a[b][c]++

2012-03-21 Thread Andrej Mitrovic
On 3/21/12, H. S. Teoh  wrote:
>   int[string][int] map;
>   map["abc"] = int[int].init;
>   map["abc"][30] = 123;

I think you meant:

int[int][string] map;
map["abc"] = (int[int]).init;
map["abc"][30] = 123;

You can however init with null if the value is a hash:

int[int][string] map;
map["abc"] = null;
map["abc"][30] = 123;

But otherwise I agree it would be nice if there was a shortcut for this.


Re: Wrong lowering for a[b][c]++

2012-03-21 Thread H. S. Teoh
On Wed, Mar 21, 2012 at 07:29:44PM +0100, David Nadlinger wrote:
> On Wednesday, 21 March 2012 at 18:27:30 UTC, H. S. Teoh wrote:
> >A question was asked on the d-learn forum about why this throws a
> >RangeError:
> >
> > int[string][int] map;
> > map["abc"][20]++;
> 
> Wait a second – aren't AAs _supposed_ to throw if accessing a key
> that doesn't exist yet? To be able to increment something, there
> already has to be a value to start from…
[...]

If it doesn't exist, it should default to typeof(value).init, IMO.

But perhaps that was the wrong example to use. What if you wanted to do
this:

map["abc"][20] = 1;

Currently this doesn't work. You have to explicitly create map["abc"]
first.


T

-- 
Time flies like an arrow. Fruit flies like a banana.


Re: Wrong lowering for a[b][c]++

2012-03-21 Thread Ali Çehreli

On 03/21/2012 11:29 AM, H. S. Teoh wrote:
> A question was asked on the d-learn forum about why this throws a
> RangeError:
>
>int[string][int] map;
>map["abc"][20]++;

Hey! That syntax is following the broken syntax of C and C++. ;)

This works:

import std.stdio;

void main()
{
int[string][int] map;
map[20]["abc"]++;

writeln(map);
}

The output:

[20:["abc":1]]

Ali



Re: Three Unlikely Successful Features of D

2012-03-21 Thread Andrej Mitrovic
On 3/21/12, Andrei Alexandrescu  wrote:
> It's official:
> http://channel9.msdn.com/Events/Lang-NEXT/Lang-NEXT-2012/Three-Unlikely-Successful-Features-of-D

"Go In Three Easy Pieces" followed by "Three Unlikely Successful Features of D".

Conspiracy? :P


Re: Wrong lowering for a[b][c]++

2012-03-21 Thread Andrej Mitrovic
On 3/21/12, Ali Çehreli  wrote:
> This works:

For some reason thought it didn't work without double-checking. Heh. :p


  1   2   >