Re: link from a dll to another function in another dll?

2011-04-21 Thread maarten van damme
Hello, I'm back (I've been ill, nothing serious)
I woul really like a bit more explanation with that particular approach.
Would declaring the functions I want to keep from the renamed dll in a
extern(c) block and linking that to the renamed dll while also declaring
them as export work?
And the function I want to change I declare myself and write in d?

I haven't really mastered the d language and I'm simply playing around with
it, simply checking if I've understood it.

2011/4/18 Robert Jacques 

> On Mon, 18 Apr 2011 04:11:16 -0400, maarten van damme <
> maartenvd1...@gmail.com> wrote:
>
>  The problem with that aproach would be that the functions are in another
>> location in the export table.
>> I've read that the locations need to stay exactly the same.
>> Am I wrong about this?
>>
>
> I don't know for sure, but my gut would say that not knowing the exact
> layout of the DLL is half the point. In practice, I've used D with DLLs that
> have drastically added to/changed their layout (according to dumpbin)
> without a problem.
>


Re: Implementing std.log

2011-04-21 Thread Denis Koroskin

On Thu, 21 Apr 2011 01:34:29 +0400, so  wrote:

For me, Logger needs to be simple but feature complete. Here is my  
ideal syntax:


Logger log = new Logger();
log.warn("bewarned");
log.error("error code: %d", 42);
log.fatal("Derp");


Fine if you remove the first line, switching the output is something we  
rarely do, so we shouldn't mandate this for each use.


note("just a note :", 5);
note!warn("bewarned");
note!error(c, ", ", d);


Having different loggers for different parts of programs (e.g. separate  
logger for my rendering, separate one for audio, separate for physics, and  
so on) is a must for me.
Because when you debug your code by analyzing log output, you want to be  
able to filter out non-relevant stuff. If you only have ONE logger, you  
will start adding stupid prefixes like this:


error("GAME/GAMEMODE_CHALLENGE/OBJECTIVE_CHECKER: match data frame is not  
valid");


instead of

log.error("match data frame is not valid");


Re: Implementing std.log

2011-04-21 Thread Jens Mueller
Denis Koroskin wrote:
> On Thu, 21 Apr 2011 01:34:29 +0400, so  wrote:
> 
> >>For me, Logger needs to be simple but feature complete. Here is
> >>my ideal syntax:
> >>
> >>Logger log = new Logger();
> >>log.warn("bewarned");
> >>log.error("error code: %d", 42);
> >>log.fatal("Derp");
> >
> >Fine if you remove the first line, switching the output is
> >something we rarely do, so we shouldn't mandate this for each use.
> >
> >note("just a note :", 5);
> >note!warn("bewarned");
> >note!error(c, ", ", d);
> 
> Having different loggers for different parts of programs (e.g.
> separate logger for my rendering, separate one for audio, separate
> for physics, and so on) is a must for me.
> Because when you debug your code by analyzing log output, you want
> to be able to filter out non-relevant stuff. If you only have ONE
> logger, you will start adding stupid prefixes like this:
> 
> error("GAME/GAMEMODE_CHALLENGE/OBJECTIVE_CHECKER: match data frame
> is not valid");
> 
> instead of
> 
> log.error("match data frame is not valid");

This can be solved by taking the compilation unit into account. I.e.
each logging statement is associated with a file, namely the file it was
used in, i.e. __FILE__. Then one only needs the ability to
disable/enable logging per compilation unit. See e.g. glog's
VLOG/--vmodule on http://google-glog.googlecode.com/svn/trunk/doc/glog.html

Jens


Re: std.parallelism: VOTE IN THIS THREAD

2011-04-21 Thread Bruno Medeiros

On 19/04/2011 14:47, Russel Winder wrote:

On Tue, 2011-04-19 at 06:13 -0500, Caligo wrote:
[ . . . ]

I would like to make a comment if that's okay.  If a person is not an
expert on parallelism, library development, or we can't verify his or
her background and such, I don't see why their vote should count.  I'm
not voting because I'm just an ordinary D user, and I have no
expertise in parallelism.  And since this a public vote, if would be
great if people who are voting did not hide behind an alias, such as
bearophile.


I think there is an very interesting and important issue here.  There
are really four (or more/less) roles of people who might vote:

Has detailed knowledge of implementation and usage.
Has some knowledge of implementation and/or usage.
Perhaps just using the API.
No actual interest.

And then there are:

Sock puppet aka shill
Troll

but let's ignore them.

Although the general belief is "one person, one vote", some decisions
are best influenced by considering the weighting to a vote provided by
annotating with role.

Two cases perhaps highlight this:

If a person using the library but having no knowledge of the
implementation finds a problematic API issue then this should count as
much as any view of people more knowledgeable about the internals.

If a person without knowledge of the theory and practice votes yes where
the domain experts are able to argue there is a blocking problem, then
the person leading the vote should have the option of cancelling and
re-entering review even if there was a clear majority vote for.

I think the issue here is not to be bound too rigidly by votes and
statistics, this is not after all politics, but instead to ensure that
everyone has the right sort of say about these things and that the
majority of people always feel the right decisions are getting made.

Consider the system not being one of the review leader managing the
votes, but of the review leader having a single golden vote which then
has to be justified by argumentation.


P.S.
I can't wait for std.parallelism to become part of Phobos.


Me too.



I generally agree with this perspective, being aware of this issue, and 
not making the voting completely democratic (that's why I'm not voting 
on this one). On the other hand, one would also hope that those with D's 
best interest in mind will also be mindful of this, and not vote if they 
feel they have insuficient knowledge to evaluate the proposal. In other 
words, one would hope the community would self-regulate to avoid this 
problem, and no formal additional rules should be needed. Let's see.


In any case it seems this won't matter for this proposal, everyone is 
voting yes :) . But it's worthwhile to keep in mind for the future.



--
Bruno Medeiros - Software Engineer


Re: Hidden argument kind antipattern

2011-04-21 Thread Bruno Medeiros

On 20/04/2011 00:09, Vladimir Panteleev wrote:

To elaborate, I mean allowing code which appears to behave surprisingly
different from the at-a-glance interpretation, unless the programmer
knows the function's signature. I've noticed a worrying adoption in D of
this "antipattern", which, frankly, I believe doesn't belong in a
well-designed programming language. One classic example of this is
passing arguments by reference, something D inherited from C++. For
example:

int x, y;
// ...
someObject.updateCoords(x, y);

What can you say about this code? The unobvious and surprising
interpretation of it is that updateCoords will change the values of x
and y. C# solved this problem neatly by requiring to specify the "ref"
keyword before the function arguments:

someObject.updateCoords(ref x, ref y); // much clearer

This problem carries over to lazy parameters, as well. I'll quote a line
of code from a recent post by David Simcha:


This problem is also very similar to the named arguments problem 
(figuring out which argument corresponds to which parameter when there 
are many parameters and they all have the same type).


My response is the same as the named arguments issue: I think it is 
preferable (if not preferable, then at least sufficiently good) to use 
an IDE to look up the full function signature, than to make language 
additions to make the call clearer by just looking at the source text.


Your post actually adds a bit more value to my approach, because it 
shows my approach is the same no matter what you want to figure out 
about the arguments (if they are ref, lazy, to which named parameter the 
argument corresponds, etc.), and it also brings up the full DDoc with 
the full information describing what the function does.
Conversely, your approach does not scale in a sense, because you need to 
keep adding stuff for each new thing you want to know about the 
parameter (ref, lazy, named argument, etc.). Should we add variadic 
parameters to the mix as well? What else? Taking this approach to the 
extreme, we might as well replicate all the information in the function 
signature in the function call...


--
Bruno Medeiros - Software Engineer


Re: Implementing std.log

2011-04-21 Thread Jacob Carlborg

On 2011-04-21 14:37, Denis Koroskin wrote:

On Thu, 21 Apr 2011 01:34:29 +0400, so  wrote:


For me, Logger needs to be simple but feature complete. Here is my
ideal syntax:

Logger log = new Logger();
log.warn("bewarned");
log.error("error code: %d", 42);
log.fatal("Derp");


Fine if you remove the first line, switching the output is something
we rarely do, so we shouldn't mandate this for each use.

note("just a note :", 5);
note!warn("bewarned");
note!error(c, ", ", d);


Having different loggers for different parts of programs (e.g. separate
logger for my rendering, separate one for audio, separate for physics,
and so on) is a must for me.
Because when you debug your code by analyzing log output, you want to be
able to filter out non-relevant stuff. If you only have ONE logger, you
will start adding stupid prefixes like this:

error("GAME/GAMEMODE_CHALLENGE/OBJECTIVE_CHECKER: match data frame is
not valid");

instead of

log.error("match data frame is not valid");


"log" could be a default instance of a class or struct (Logger for 
example), instead of a function, implementing opCall. Then you could use 
it like this:


log("info message or whatever is the default");
log.error("error message"); // and so on

auto gameLog = new Logger;
// set custom settings for the game logging
gameLog("info message");

--
/Jacob Carlborg


Re: link from a dll to another function in another dll?

2011-04-21 Thread Robert Jacques
On Thu, 21 Apr 2011 07:49:14 -0400, maarten van damme  
 wrote:



Hello, I'm back (I've been ill, nothing serious)
I woul really like a bit more explanation with that particular approach.
Would declaring the functions I want to keep from the renamed dll in a
extern(c) block and linking that to the renamed dll while also declaring
them as export work?
And the function I want to change I declare myself and write in d?

I haven't really mastered the d language and I'm simply playing around  
with

it, simply checking if I've understood it.

2011/4/18 Robert Jacques 


On Mon, 18 Apr 2011 04:11:16 -0400, maarten van damme <
maartenvd1...@gmail.com> wrote:

 The problem with that aproach would be that the functions are in  
another

location in the export table.
I've read that the locations need to stay exactly the same.
Am I wrong about this?



I don't know for sure, but my gut would say that not knowing the exact
layout of the DLL is half the point. In practice, I've used D with DLLs  
that

have drastically added to/changed their layout (according to dumpbin)
without a problem.



Hmm... It should work, but I've never tried it. Def files allow you to  
rename DLL functions, so you could rename the single function you want to  
override something else, or leave it out entirely. The only thing to be  
careful of is call style and name mangling (i.e. System vs C, etc.)


Re: Implementing std.log

2011-04-21 Thread Denis Koroskin
On Thu, 21 Apr 2011 16:58:17 +0400, Jens Mueller   
wrote:



Denis Koroskin wrote:

On Thu, 21 Apr 2011 01:34:29 +0400, so  wrote:

>>For me, Logger needs to be simple but feature complete. Here is
>>my ideal syntax:
>>
>>Logger log = new Logger();
>>log.warn("bewarned");
>>log.error("error code: %d", 42);
>>log.fatal("Derp");
>
>Fine if you remove the first line, switching the output is
>something we rarely do, so we shouldn't mandate this for each use.
>
>note("just a note :", 5);
>note!warn("bewarned");
>note!error(c, ", ", d);

Having different loggers for different parts of programs (e.g.
separate logger for my rendering, separate one for audio, separate
for physics, and so on) is a must for me.
Because when you debug your code by analyzing log output, you want
to be able to filter out non-relevant stuff. If you only have ONE
logger, you will start adding stupid prefixes like this:

error("GAME/GAMEMODE_CHALLENGE/OBJECTIVE_CHECKER: match data frame
is not valid");

instead of

log.error("match data frame is not valid");


This can be solved by taking the compilation unit into account. I.e.
each logging statement is associated with a file, namely the file it was
used in, i.e. __FILE__. Then one only needs the ability to
disable/enable logging per compilation unit. See e.g. glog's
VLOG/--vmodule on  
http://google-glog.googlecode.com/svn/trunk/doc/glog.html


Jens


That could work, I guess. Either way, one line of code is that much of a  
difference, I believe.


Re: link from a dll to another function in another dll?

2011-04-21 Thread maarten van damme
There is another problem, I don't know the return types of the functions
from that dll, so I gave them the type "void *". I think this is incorrect.
I've tried with the little knowledge I have from d and in the link is my
kernel32.d. I have compiled it succesfully in a .dll but the application
using that dll states that that dll isn't valid.

thank you for taking your time to answer this question :) .


http://dl.dropbox.com/u/15024434/kernel32.d

>
> 2011/4/21 Robert Jacques 
>
>> On Thu, 21 Apr 2011 07:49:14 -0400, maarten van damme <
>> maartenvd1...@gmail.com> wrote:
>>
>>  Hello, I'm back (I've been ill, nothing serious)
>>> I woul really like a bit more explanation with that particular approach.
>>> Would declaring the functions I want to keep from the renamed dll in a
>>> extern(c) block and linking that to the renamed dll while also declaring
>>> them as export work?
>>> And the function I want to change I declare myself and write in d?
>>>
>>> I haven't really mastered the d language and I'm simply playing around
>>> with
>>> it, simply checking if I've understood it.
>>>
>>> 2011/4/18 Robert Jacques 
>>>
>>>  On Mon, 18 Apr 2011 04:11:16 -0400, maarten van damme <
 maartenvd1...@gmail.com> wrote:

  The problem with that aproach would be that the functions are in
 another

> location in the export table.
> I've read that the locations need to stay exactly the same.
> Am I wrong about this?
>
>
 I don't know for sure, but my gut would say that not knowing the exact
 layout of the DLL is half the point. In practice, I've used D with DLLs
 that
 have drastically added to/changed their layout (according to dumpbin)
 without a problem.


>> Hmm... It should work, but I've never tried it. Def files allow you to
>> rename DLL functions, so you could rename the single function you want to
>> override something else, or leave it out entirely. The only thing to be
>> careful of is call style and name mangling (i.e. System vs C, etc.)
>>
>
>


Re: Implementing std.log

2011-04-21 Thread so
On Thu, 21 Apr 2011 15:37:42 +0300, Denis Koroskin <2kor...@gmail.com>  
wrote:



On Thu, 21 Apr 2011 01:34:29 +0400, so  wrote:

For me, Logger needs to be simple but feature complete. Here is my  
ideal syntax:


Logger log = new Logger();
log.warn("bewarned");
log.error("error code: %d", 42);
log.fatal("Derp");


Fine if you remove the first line, switching the output is something we  
rarely do, so we shouldn't mandate this for each use.


note("just a note :", 5);
note!warn("bewarned");
note!error(c, ", ", d);


Having different loggers for different parts of programs (e.g. separate  
logger for my rendering, separate one for audio, separate for physics,  
and so on) is a must for me.
Because when you debug your code by analyzing log output, you want to be  
able to filter out non-relevant stuff. If you only have ONE logger, you  
will start adding stupid prefixes like this:


error("GAME/GAMEMODE_CHALLENGE/OBJECTIVE_CHECKER: match data frame is  
not valid");


instead of

log.error("match data frame is not valid");


So you want the iostream way, global logger objects, otherwise i don't see  
how this solves the problem you are suggesting.


Re: std.parallelism: VOTE IN THIS THREAD

2011-04-21 Thread Graham Fawcett
On Tue, 19 Apr 2011 07:25:06 +, Lars T. Kyllingstad wrote:

> As announced a week ago, the formal review process for David Simcha's
> std.parallelism module is now over, and it is time to vote over whether
> the module should be included in Phobos.  See below for more information
> on the module and on previous reviews.
> 
> Please vote in this thread, by replying with
> 
>   - "YES" if you think std.parallelism should be included in Phobos
> in its present form,
> 
>   - "NO" if you think it shouldn't.

YES

--Graham


Re: Implementing std.log

2011-04-21 Thread Denis Koroskin

On Thu, 21 Apr 2011 19:08:38 +0400, so  wrote:

On Thu, 21 Apr 2011 15:37:42 +0300, Denis Koroskin <2kor...@gmail.com>  
wrote:



On Thu, 21 Apr 2011 01:34:29 +0400, so  wrote:

For me, Logger needs to be simple but feature complete. Here is my  
ideal syntax:


Logger log = new Logger();
log.warn("bewarned");
log.error("error code: %d", 42);
log.fatal("Derp");


Fine if you remove the first line, switching the output is something  
we rarely do, so we shouldn't mandate this for each use.


note("just a note :", 5);
note!warn("bewarned");
note!error(c, ", ", d);


Having different loggers for different parts of programs (e.g. separate  
logger for my rendering, separate one for audio, separate for physics,  
and so on) is a must for me.
Because when you debug your code by analyzing log output, you want to  
be able to filter out non-relevant stuff. If you only have ONE logger,  
you will start adding stupid prefixes like this:


error("GAME/GAMEMODE_CHALLENGE/OBJECTIVE_CHECKER: match data frame is  
not valid");


instead of

log.error("match data frame is not valid");


So you want the iostream way, global logger objects, otherwise i don't  
see how this solves the problem you are suggesting.


No globals, of course, loggers are part of objects. In most cases,  
everyone who adds log entry creates its own logger and add it into a  
hierarchy.


Re: link from a dll to another function in another dll?

2011-04-21 Thread maarten van damme
according to dllexp.exe (a dll examiner) my dll does not export any
functions.
So there is something wrong in my declaration:

pragma(lib,kernel33.lib);
extern(C){
export void * functionfromkernel33.lib () ;
...
}

How can one write this correctly?

2011/4/21 maarten van damme 

> There is another problem, I don't know the return types of the functions
> from that dll, so I gave them the type "void *". I think this is incorrect.
> I've tried with the little knowledge I have from d and in the link is my
> kernel32.d. I have compiled it succesfully in a .dll but the application
> using that dll states that that dll isn't valid.
>
> thank you for taking your time to answer this question :) .
>
>
> http://dl.dropbox.com/u/15024434/kernel32.d
>
>
>> 2011/4/21 Robert Jacques 
>>
>>> On Thu, 21 Apr 2011 07:49:14 -0400, maarten van damme <
>>> maartenvd1...@gmail.com> wrote:
>>>
>>>  Hello, I'm back (I've been ill, nothing serious)
 I woul really like a bit more explanation with that particular approach.
 Would declaring the functions I want to keep from the renamed dll in a
 extern(c) block and linking that to the renamed dll while also declaring
 them as export work?
 And the function I want to change I declare myself and write in d?

 I haven't really mastered the d language and I'm simply playing around
 with
 it, simply checking if I've understood it.

 2011/4/18 Robert Jacques 

  On Mon, 18 Apr 2011 04:11:16 -0400, maarten van damme <
> maartenvd1...@gmail.com> wrote:
>
>  The problem with that aproach would be that the functions are in
> another
>
>> location in the export table.
>> I've read that the locations need to stay exactly the same.
>> Am I wrong about this?
>>
>>
> I don't know for sure, but my gut would say that not knowing the exact
> layout of the DLL is half the point. In practice, I've used D with DLLs
> that
> have drastically added to/changed their layout (according to dumpbin)
> without a problem.
>
>
>>> Hmm... It should work, but I've never tried it. Def files allow you to
>>> rename DLL functions, so you could rename the single function you want to
>>> override something else, or leave it out entirely. The only thing to be
>>> careful of is call style and name mangling (i.e. System vs C, etc.)
>>>
>>
>>
>


Re: Implementing std.log

2011-04-21 Thread so
So you want the iostream way, global logger objects, otherwise i don't  
see how this solves the problem you are suggesting.


No globals, of course, loggers are part of objects. In most cases,  
everyone who adds log entry creates its own logger and add it into a  
hierarchy.


class A {
logger log;
}

class B {
A a;
logger log;
}

void some_function() {
	auto log = new logger("where to? why would i care who call this? why do i  
need this line anyways? :)")

log.error(...);
}

---

I think we are looking this from fairly different angles.
Most of the times all i want to do just :

module logger;

void note(uint level, A...)(A a);
void note_redirect(uint level, string);
void note_enable(uint level, bool on);
uint note_new(string);

// default levels
enum {
warning = 0,
error,
fatal,
}

import logger;

void some_function() {
...
note(...);
...
note!error(...);
...
note!fatal(...);
...
note!my_level(...);
}


codemirror.net

2011-04-21 Thread Andrei Alexandrescu
Regarding Adam's excellent recent work on making D code samples 
compilable on the website, I think we could use codemirror.net for 
syntax highlighting and indentation amenities.


Andrei


Re: Implementing std.log

2011-04-21 Thread Andrei Alexandrescu

On 4/21/11 11:53 AM, so wrote:

So you want the iostream way, global logger objects, otherwise i
don't see how this solves the problem you are suggesting.


No globals, of course, loggers are part of objects. In most cases,
everyone who adds log entry creates its own logger and add it into a
hierarchy.


class A {
logger log;
}

class B {
A a;
logger log;
}

[snip]

Again, I'd _much_ rather prefer if someone just implemented this:

http://google-glog.googlecode.com/svn/trunk/doc/glog.html

It's simple, to the point, and brings the bacon home.

In fact I'm putting dibs on this. I'll implement the thing and make a 
proposal.



Andrei


Re: Implementing std.log

2011-04-21 Thread Kagamin
Denis Koroskin Wrote:

> Having different loggers for different parts of programs (e.g. separate  
> logger for my rendering, separate one for audio, separate for physics, and  
> so on) is a must for me.
> Because when you debug your code by analyzing log output, you want to be  
> able to filter out non-relevant stuff. If you only have ONE logger, you  
> will start adding stupid prefixes like this:
> 
> error("GAME/GAMEMODE_CHALLENGE/OBJECTIVE_CHECKER: match data frame is not  
> valid");
> 
> instead of
> 
> log.error("match data frame is not valid");

If you parameterize logger with just a class name, that's not enough. log4net 
uses similar approach, and I constantly need to prefix log messages with method 
name, its signature and sometimes even line number to know, where the logging 
took place. If I don't do this, it's difficult to determine where it blew up 
just by the class name because there're many identical log calls throughout a 
class.


Re: std.parallelism: VOTE IN THIS THREAD

2011-04-21 Thread Jonathan Crapuchettes

Yes
JC


Low Level Bounded Model Checker

2011-04-21 Thread Ulrik Mikaelsson
I just saw this on Google Tech talks, and thought others on the list
might enjoy it; http://www.youtube.com/watch?v=vajMUlyXw_U

It's about LLBMC, an automated program-prover targeting automated
proofing for functional-style programs. The idea is to go a step
beyond specific test-cases, and prove function correctness for all
possible input values. The method is to compile the source (currently
only C supported, with C++ on the way) using Clang to LLVM-IR, and
perform the analysis on the LLVM-IR-level.

Now, in D I think most of the meta-information framework required is
already present in the language (for C, they've added some
meta-keywords), especially DBC-programming with in and out-validators.
A LLBMC-like version for D should in theory be able to use only the
existing in/out/invariant/assert-clauses. However, it would be a VERY
useful tool able to auto-validate all functional code against it's
contract.

http://baldur.iti.uka.de/llbmc/


Re: postincrement behaviour (differences between dmd and gdc)

2011-04-21 Thread maarten van damme
This is something I also came across in java.
When you do that in java it follows the dmd behaviour.

Simply my 2 cents :p


opDispatch, duck typing, and error messages

2011-04-21 Thread Adam D. Ruppe
I just made an innocent little change to one of my programs, hit
compile, and got this vomit:

/home/me/d/dmd2/linux/bin/../../src/phobos/std/conv.d(97): Error: template
std.conv.toImpl(T,S) if (!implicitlyConverts!(S,
T) && isSomeString!(T) && isInputRange!(Unqual!(S)) &&
isSomeChar!(ElementType!(S))) toImpl(T,S) if (!implicitlyConverts!(S
,T) && isSomeString!(T) && isInputRange!(Unqual!(S)) &&
isSomeChar!(ElementType!(S))) matches more than one template declar
ation, /home/me/d/dmd2/linux/bin/../../src/phobos/std/conv.d(185):toImpl(T,S)
if (isSomeString!(T) && !isSomeChar!(ElementT
ype!(S)) && (isInputRange!(S) || isInputRange!(Unqual!(S and
/home/me/d/dmd2/linux/bin/../../src/phobos/std/conv.d(289)
:toImpl(T,S) if (is(S : Object) && isSomeString!(T))



Who... took a bit to figure out what it was saying. The bottom
line: one of my classes matched both Object and isInputRange because
it offers an unrestricted opDispatch.

The fix:

// note the constraint
string opDispatch(string name)() if(name != "popFront") {}


(I'm sure empty or front would have worked just as well, but popFront
I'm sure I didn't actually use anywhere for this.)


This post is to serve as two things: an FYI in case you see something
like this yourself, and to have a discussion on what we can do to
improve the situation.

A constraint like this wouldn't work of the Object was actually
supposed to be a range.


So, what can we do to improve that message? As it is now, it's
close to useless. Yeah, I was able to track down what it meant, but
only after I hacked up my copy of Phobos to tell me what T and S
actually were in the instantiation of to... then, it was obvious what
the error meant, but before, well, I pity the poor newbie who
stumbles upon that!


Things I think would help:

a) If the compiler gave some kind of stack trace in this instance. An
error message pointing solely at std.conv doesn't help much. In a
lot of template error messages, the kind of trace I want
already exists, so I suspect 90% of the work to implement it is
already done.

b) Format those constraints a little. Just put a "\n\t" before the
if and a "\n" before the function name. I think some whitespace
would help a lot in readability. Sure, newbs might still not get it,
but at least it won't be a blob of wtf.

Alas, I've looked at the compiler, but aren't to the point where I
can contribute code to it myself. Well, maybe I could do the
formatting change, but I haven't tried yet.

Regardless, let's look at other options.


c) Maybe Phobos could help out somehow? Another thing to!()
annoys the living crap of me with is it's runtime errors. It, again,
doesn't tell me where in my code the problem occurred.

Perhaps have it take default __FILE__ and __LINE__ args to print out
too? I think this can help both compile and runtime errors.

d) Also in Phobos, I wonder if we can beautify the message somehow.
I don't have any idea how to do this in a scalable way.

It could static if (matches constraint 1 and constraint 2)
static assert("pretty message"), but there's no chance that would
scale well.

So I don't know here.


Or, there's a whole new approach:

e) Duck typing for ranges in to!() might be a bad idea. Again, remember,
a class might legitimately offer a range interface, so it would
trigger this message without opDispatch.

If ranges are meant to be structs, maybe isInputRange should check
is(T == struct)? This doesn't sit right with me though. The real
problem is to!() - other range functions probably don't overload
on classes separately than ranges, so it won't matter there.


I think the best thing to do is simply to prefer Object over range.

toImpl(T) if (isInputRange!(T) && (!is(T : Object)))

Or something along those lines. Why? If the object has it's own
toString/writeTo methods, it seems fairly obvious to me anyway that
to!string ought to simply call them, regardless or what else there is.



I kinda blabbered here, but in the end, I think my previous paragraph
is the big thing. It's a fairly minor Phobos change. Any objections
to it?

Note btw that I'd still like the error messages to be prettier, but
I'm ok doing it one step at a time.


Re: opDispatch, duck typing, and error messages

2011-04-21 Thread bearophile
Adam D. Ruppe:

> c) Maybe Phobos could help out somehow? Another thing to!()
> annoys the living crap of me with is it's runtime errors. It, again,
> doesn't tell me where in my code the problem occurred.
> 
> Perhaps have it take default __FILE__ and __LINE__ args to print out
> too? I think this can help both compile and runtime errors.

This is a more general problem of runtime errors, not just of to!(). Maybe 
exceptions nature should be changed a little so they store __FILE__ and 
__LINE__ on default (exceptions without this information are kept on request, 
for optimization purposes).

Bye,
bearophile


Re: opDispatch, duck typing, and error messages

2011-04-21 Thread Jonathan M Davis
> Adam D. Ruppe:
> > c) Maybe Phobos could help out somehow? Another thing to!()
> > annoys the living crap of me with is it's runtime errors. It, again,
> > doesn't tell me where in my code the problem occurred.
> > 
> > Perhaps have it take default __FILE__ and __LINE__ args to print out
> > too? I think this can help both compile and runtime errors.
> 
> This is a more general problem of runtime errors, not just of to!(). Maybe
> exceptions nature should be changed a little so they store __FILE__ and
> __LINE__ on default (exceptions without this information are kept on
> request, for optimization purposes).

Most exceptions end up with file and line numbers. The problem is generally 
not that they don't have a file or line number, it's that the file and line 
number is from inside of a function that you called instead of your own code. 
As long as you have a stack trace, it's not all that big a problem, but if 
you're on Windows, then there are no stack traces yet and you're screwed. It 
_does_ generally make sense for the file and line number to be from the throw 
point rather than the point where you called the function (especially when the 
throw point could be several function calls away in the stack), but without a 
proper stack trace, you have no way of knowing where in your code the problem 
is.

Now, in the case of something like to, the types are known at compile time, so 
in many cases, it should be able to give a compile time error via a template 
constraint, but it's not able to do that in all cases. One example of that is 
converting a string to anything else. The value of the string determines 
whether the conversion is valid rather than the types being enough at compile 
time. So, in some cases, you _have_ to have an exception at runtime rather 
than a compile time error. Whether to does as good a job with making errors 
compile time errors as much as it can, I don't know, but on some level, we're 
stuck.

But generally, I think that the real problem is the lack of a stack trace. You 
generally get them on Linux but not Windows. Most exceptions _should_ be 
grabbing the file and line number that they're thrown from. I don't recall of 
Exception can or not (Error _can't_ due to some low level stuff), but pretty 
much everything derived from Exception certainly can and should.

- Jonathan M Davis


Re: opDispatch, duck typing, and error messages

2011-04-21 Thread Andrej Mitrovic
> This is a more general problem of runtime errors, not just of to!(). Maybe
> exceptions nature should be changed a little so they store __FILE__ and
> __LINE__ on default (exceptions without this information are kept on
> request, for optimization purposes).

Vote up for that. At least it should do that in -debug mode. It's
completely useless getting an error message with a file and line
number for an internal Phobos function, like some funcImpl() private
function, when the fault is a runtime argument.


OOP, faster data layouts, compilers

2011-04-21 Thread bearophile
Through Reddit I've found a set of wordy slides, "Design for Performance", on 
designing efficient games code:
http://www.scribd.com/doc/53483851/Design-for-Performance
http://www.reddit.com/r/programming/comments/guyb2/designing_code_for_performance/

The slide touch many small topics, like the need for prefetching, desing for 
cache-aware code, etc. One of the main topics is how to better lay data 
structures in memory for modern CPUs. It shows how object oriented style leads 
often to collections of little trees, for example  arrays of object references 
(or struct pointers) that refer to objects that contain other references to sub 
parts. Iterating on such data structures is not so efficient.

The slides also discuss a little the difference between creating an array of 
2-item structs, or a struct that contains two arrays of single native values. 
If the code needs to scan just one of those two fields, then the struct that 
contains the two arrays is faster.

Similar topics were discussed better in "Pitfalls of Object Oriented 
Programming" (2009):
http://research.scee.net/files/presentations/gcapaustralia09/Pitfalls_of_Object_Oriented_Programming_GCAP_09.pdf

In my opinion if D2 has some success then one of its significant usages will be 
to write fast games, so the design/performance concerns expressed in those two 
sets of slides need to be important for D design.

D probably allows to lay data in memory as shown in those slides, but I'd like 
some help from the compiler too.  I don't think the compilers will be soon able 
to turn an immutable binary tree into an array, to speedup its repeated 
scanning, but maybe there are ways to express semantics in the code that will 
allow them future smarter compilers to perform some of those memory layout 
optimization, like transposing arrays. A possible idea is a 
@no_inbound_pointers that forbids taking the addess of the items, and allows 
the compiler to modify the data layout a little.

Bye,
bearophile


Re: opDispatch, duck typing, and error messages

2011-04-21 Thread Andrej Mitrovic
Btw, there is a stack trace for Windows and D2, see here:
http://3d.benjamin-thaut.de/?p=15


Re: opDispatch, duck typing, and error messages

2011-04-21 Thread Adam D. Ruppe
bearophile wrote:
>  Maybe exceptions nature should be changed a little so they store
> __FILE__ and __LINE__ on default (exceptions without this
> information are kept on request, for optimization purposes).

I'd like that. Even with a stack trace, it's nice to have that
available right at the top.

A while ago, someone posted a stack tracer printer for Linux to
the newsgroup. Using that, this program:

void main() {
throw new Exception("test");
}

 dmd test60 -debug -g backtrace.d

Prints:

object.Exception: test

./test60(_Dmain+0x30) [0x807a5e8]
./test60(extern (C) int rt.dmain2.main(int, char**) . void runMain()+0x1a) 
[0x807d566]
./test60(extern (C) int rt.dmain2.main(int, char**) . void tryExec(void
delegate())+0x24) [0x807d4c0]
./test60(extern (C) int rt.dmain2.main(int, char**) . void runAll()+0x32) 
[0x807d5aa]
./test60(extern (C) int rt.dmain2.main(int, char**) . void tryExec(void
delegate())+0x24) [0x807d4c0]
./test60(main+0x96) [0x807d466]
/lib/libc.so.6(__libc_start_main+0xe6) [0xf75a5b86]
./test60() [0x807a4e1]



No line or file info! I'd really like to have something there.
Though, actually, whether it's in the message or in the stack
trace doesn't really matter. As long as it's there somewhere.

Most my custom exceptions use default params in their constructor
to add it. Perhaps the base Exception should too?


Re: opDispatch, duck typing, and error messages

2011-04-21 Thread Jonathan M Davis
> bearophile wrote:
> > Maybe exceptions nature should be changed a little so they store
> > 
> > __FILE__ and __LINE__ on default (exceptions without this
> > information are kept on request, for optimization purposes).
> 
> I'd like that. Even with a stack trace, it's nice to have that
> available right at the top.
> 
> A while ago, someone posted a stack tracer printer for Linux to
> the newsgroup. Using that, this program:
> 
> void main() {
> throw new Exception("test");
> }
> 
> dmd test60 -debug -g backtrace.d
> 
> Prints:
> 
> object.Exception: test
> 
> ./test60(_Dmain+0x30) [0x807a5e8]
> ./test60(extern (C) int rt.dmain2.main(int, char**) . void runMain()+0x1a)
> [0x807d566] ./test60(extern (C) int rt.dmain2.main(int, char**) . void
> tryExec(void delegate())+0x24) [0x807d4c0]
> ./test60(extern (C) int rt.dmain2.main(int, char**) . void runAll()+0x32)
> [0x807d5aa] ./test60(extern (C) int rt.dmain2.main(int, char**) . void
> tryExec(void delegate())+0x24) [0x807d4c0]
> ./test60(main+0x96) [0x807d466]
> /lib/libc.so.6(__libc_start_main+0xe6) [0xf75a5b86]
> ./test60() [0x807a4e1]
> 
> 
> 
> No line or file info! I'd really like to have something there.
> Though, actually, whether it's in the message or in the stack
> trace doesn't really matter. As long as it's there somewhere.
> 
> Most my custom exceptions use default params in their constructor
> to add it. Perhaps the base Exception should too?

I just checked. Exception _does_ take a default file and line number. So, 
anything derived from Exception doesn't have a file and line number, something 
is amiss.

- Jonathan M Davis


Re: opDispatch, duck typing, and error messages

2011-04-21 Thread Sean Kelly
On Apr 21, 2011, at 4:10 PM, Andrej Mitrovic wrote:

> Btw, there is a stack trace for Windows and D2, see here:
> http://3d.benjamin-thaut.de/?p=15

Already in the next DMD release.


Re: opDispatch, duck typing, and error messages

2011-04-21 Thread Adam D. Ruppe
Jonathan M Davis wrote:
> It _does_ generally make sense for the file and line number to be
> from the throw point rather than the point where you called the
> function (especially when the throw point could be several function
> calls away in the stack), but without a proper stack trace, you
> have no way of knowing where in your code the problem is.

I believe I agree completely.

> Now, in the case of something like to, the types are known at
> compile time, so in many cases, it should be able to give a
> compile time error via a template constraint, but it's not able
> to do that in all cases.

Indeed. And it usually does. The problem is that the error can be
pretty hard to read.

Here's one simple case:

===

import std.conv;

struct Test {}

void main() {
Test t;
int a = to!int(t);
}

===

/home/me/d/dmd2/linux/bin/../../src/phobos/std/conv.d(95): Error: template
std.conv.toImpl(T,S) if (!implicitlyConverts!(S,T) && isSomeString!(T) &&
isInputRange!(Unqual!(S)) && isSomeChar!(ElementType!(S))) does not match any
function template declaration
/home/me/d/dmd2/linux/bin/../../src/phobos/std/conv.d(95): Error: template
std.conv.toImpl(T,S) if (!implicitlyConverts!(S,T) && isSomeString!(T) &&
isInputRange!(Unqual!(S)) && isSomeChar!(ElementType!(S))) cannot deduce 
template
function from argument types !(int)(Test)
/home/me/d/dmd2/linux/bin/../../src/phobos/std/conv.d(95): Error: template
instance errors instantiating template
/home/me/d/dmd2/linux/bin/../../src/phobos/std/conv.d(7): Error: template 
instance
std.conv.to!(int).to!(Test) error instantiating


Holy crap!

But, if you know the secret there - to look at the last line -
it does tell you enough to do some useful stuff. Alas, it doesn't
tell where in *your* code the problem is, but it does tell the
types you asked for, so it's pretty useful.

Still, I'd like it if that was formatted nicer, and it went the
final step of telling me where in my code the problem is too.


Then, you have the problem if your type matches two templates.
Then you have the vomit in my opening post, where it doesn't even
tell you what types it's having trouble with!

> One example of that is converting a string to anything else. The
> value of the string determines whether the conversion is valid
> rather than the types being enough at compile time.

The runtime error is actually pretty good. If it had a nice
stack trace with line numbers I'd call it outright excellent.


So I agree with your conclusion too about the stack trace!


BTW, while I'm talking about this, is RangeError at all possible
to include the actual key that was out of range?

int[] b;
int c = b[3];
core.exception.RangeError@test60(7): Range violation

Good, but I'd call it great if it could say Range violation (3) or
something like that.

I imagine since it's an Error there might be memory allocation
restrictions... but if it's possible, that'd be way cool too.


Re: opDispatch, duck typing, and error messages

2011-04-21 Thread Adam D. Ruppe
Jonathan M Davis wrote:
> I just checked. Exception _does_ take a default file and line number.

Huh, maybe my dmd is getting old.

Maybe we should revisit this after the next dmd release. Sounds like
one is coming pretty soon with a lot of yummy goodness in it. All
of this Exception stuff may be moot.


Re: opDispatch, duck typing, and error messages

2011-04-21 Thread Jonathan M Davis
> Jonathan M Davis wrote:
> > It _does_ generally make sense for the file and line number to be
> > from the throw point rather than the point where you called the
> > function (especially when the throw point could be several function
> > calls away in the stack), but without a proper stack trace, you
> > have no way of knowing where in your code the problem is.
> 
> I believe I agree completely.
> 
> > Now, in the case of something like to, the types are known at
> > compile time, so in many cases, it should be able to give a
> > compile time error via a template constraint, but it's not able
> > to do that in all cases.
> 
> Indeed. And it usually does. The problem is that the error can be
> pretty hard to read.
> 
> Here's one simple case:
> 
> ===
> 
> import std.conv;
> 
> struct Test {}
> 
> void main() {
> Test t;
> int a = to!int(t);
> }
> 
> ===
> 
> /home/me/d/dmd2/linux/bin/../../src/phobos/std/conv.d(95): Error: template
> std.conv.toImpl(T,S) if (!implicitlyConverts!(S,T) && isSomeString!(T) &&
> isInputRange!(Unqual!(S)) && isSomeChar!(ElementType!(S))) does not match
> any function template declaration
> /home/me/d/dmd2/linux/bin/../../src/phobos/std/conv.d(95): Error: template
> std.conv.toImpl(T,S) if (!implicitlyConverts!(S,T) && isSomeString!(T) &&
> isInputRange!(Unqual!(S)) && isSomeChar!(ElementType!(S))) cannot deduce
> template function from argument types !(int)(Test)
> /home/me/d/dmd2/linux/bin/../../src/phobos/std/conv.d(95): Error: template
> instance errors instantiating template
> /home/me/d/dmd2/linux/bin/../../src/phobos/std/conv.d(7): Error: template
> instance std.conv.to!(int).to!(Test) error instantiating
> 
> 
> Holy crap!
> 
> But, if you know the secret there - to look at the last line -
> it does tell you enough to do some useful stuff. Alas, it doesn't
> tell where in *your* code the problem is, but it does tell the
> types you asked for, so it's pretty useful.
> 
> Still, I'd like it if that was formatted nicer, and it went the
> final step of telling me where in my code the problem is too.
> 
> 
> Then, you have the problem if your type matches two templates.
> Then you have the vomit in my opening post, where it doesn't even
> tell you what types it's having trouble with!

Template errors tend to be fairly good (especially if you're used to reading 
them) when you're only dealing with one template, but as soon as the template 
is overloaded, you're screwed. It generally just gives the first template and 
says that you didn't match it, and often the template that you're actually 
trying to use is quite different. But short of giving _all_ of the possible 
template declarations that it failed, I'm not quite sure what we could do to 
fix that.

- Jonathan M Davis


Re: opDispatch, duck typing, and error messages

2011-04-21 Thread Jonathan M Davis
> Jonathan M Davis wrote:
> > I just checked. Exception _does_ take a default file and line number.
> 
> Huh, maybe my dmd is getting old.
> 
> Maybe we should revisit this after the next dmd release. Sounds like
> one is coming pretty soon with a lot of yummy goodness in it. All
> of this Exception stuff may be moot.

It was in dmd 2.052. I don't know when the change was made though. I might 
have been the one to change it too. I made several changes a while back to 
make it so that Exception and Error types had default file and line numbers 
(and I actually had to remove several on various Errors, because the way that 
they're actually created makes them not work with default arguments).

- Jonathan M Davis


Re: opDispatch, duck typing, and error messages

2011-04-21 Thread Andrej Mitrovic
On 4/22/11, Sean Kelly  wrote:
> On Apr 21, 2011, at 4:10 PM, Andrej Mitrovic wrote:
>
>> Btw, there is a stack trace for Windows and D2, see here:
>> http://3d.benjamin-thaut.de/?p=15
>
> Already in the next DMD release.
>

Whoa, the next release is gonna be big.


Re: opDispatch, duck typing, and error messages

2011-04-21 Thread Adam D. Ruppe
Jonathan M Davis wrote:
> It was in dmd 2.052.

This is almost definitely my error then... I still have 2.050!

I didn't realize so much has passed since my last update :S


Re: opDispatch, duck typing, and error messages

2011-04-21 Thread Robert Jacques
On Thu, 21 Apr 2011 18:24:55 -0400, Adam D. Ruppe  
 wrote:

[snip]

Or, there's a whole new approach:

e) Duck typing for ranges in to!() might be a bad idea. Again, remember,
a class might legitimately offer a range interface, so it would
trigger this message without opDispatch.

If ranges are meant to be structs, maybe isInputRange should check
is(T == struct)? This doesn't sit right with me though. The real
problem is to!() - other range functions probably don't overload
on classes separately than ranges, so it won't matter there.


I think the best thing to do is simply to prefer Object over range.

toImpl(T) if (isInputRange!(T) && (!is(T : Object)))

Or something along those lines. Why? If the object has it's own
toString/writeTo methods, it seems fairly obvious to me anyway that
to!string ought to simply call them, regardless or what else there is.


There's actually a bug report regarding the toString vs range semantics  
issue, it's issue 5354 (  
http://d.puremagic.com/issues/show_bug.cgi?id=5354 ). Also note that  
classes (but not structs as of yet, see bug 5719) can provide their own  
to!T conversions.


However, what you ran into deserves a new bug report, since to!string  
should always be able to fall back to toString and it didn't.




Re: link from a dll to another function in another dll?

2011-04-21 Thread Robert Jacques
On Thu, 21 Apr 2011 12:31:56 -0400, maarten van damme  
 wrote:



according to dllexp.exe (a dll examiner) my dll does not export any
functions.
So there is something wrong in my declaration:

pragma(lib,kernel33.lib);
extern(C){
export void * functionfromkernel33.lib () ;
...
}

How can one write this correctly?


You need a dll main function. Check out the dll example that comes with  
dmd (i.e. dmd2\samples\d\mydll) for the complete example.


Re: Temporarily disable all purity for debug prints

2011-04-21 Thread dennis luehring

On 17.04.2011 22:45, Andrew Wiley wrote:

On Sun, Apr 17, 2011 at 3:30 PM, dennis luehring  wrote:

On 11.04.2011 23:27, bearophile wrote:


  From what I am seeing, in a D2 program if I have many (tens or more) pure
functions that call to each other, and I want to add (or activate) a
printf/writeln inside one (or few) of those functions to debug it, I may
need to temporarily comment out the "pure" attribute of many functions
(because printing can't be allowed in pure functions).

As more and more D2 functions become pure in my code and in Phobos,
something like a -disablepure compiler switch (and printf/writeln inside
debug{}) may allow more handy debugging with prints (if the purity is well
managed by the compiler then I think disabling the pure attributes doesn't
change the program output).

Bye,
bearophile


sounds a little bit like the need to see an private/protected part of an
interface in unittest scenarios - just to be able to test it in a
whitebox-testing without changing the attributes of the productive-code


Isn't this already there because "private" makes things visible to all
other code in the same module?


ok - but what about protected? as a whitebox tester im not able(allowed) 
to change productive code,but i need to test through all the code 
(especially when doing code-coverage stuff)