Re: Synchronized const methods

2010-06-11 Thread Daniel Keep

immutable means no one can modify this.

const means someone might be able to modify this, but not you can't.


Re: Yet more OPTLINK woes

2010-05-13 Thread Daniel Keep

Some general replies:

There have been three responses along the lines of are you sure OPTLINK
is running?.  Quoting myself:

Invoking OPTLINK directly changes nothing.

Or to be more specific:

 link AstTest,AstTest,,user32+kernel32/noi+tango.lib;
(zero-byte .map file pops into existence)

Yes, I'm sure.  I'm also sure it's the DigitalMars link.exe and in the
correct directory.

 I've had problems before with DMD silently exiting without an error
 message and with error success and leaving behind a corrupt .obj.

I had a look at the .obj file (I actually used lib to stuff it into a
.lib file and then dump the symbols), and it looked fine.

Well, except for this:

_D11TokenStream808d8d5_ctorMFC6Sourcef6P809091
  DFS8Location808989AaYvJS68085cfs5f4Zb80
  99aaZC819a87

(broken across 3 lines; xx are bytes in hex since several of them were
non-printable.)

The same had happened to a number of symbols from tango.io.stream.Format.

In the case of the first one, the appropriate declarations (with
fully-qualified module name commented) are:

 final class /*TokenStream.*/TokenStream
 {
 alias bool function(Source, LocErr, out Token) NextToken;
 this(Source src, NextToken next, LocErr err) { ... }
 }

 final class /*Source.*/Source { ... }

 alias void delegate(Location, char[], ...) /*Location.*/LocErr;

 struct /*Location.*/Location { ... }

As far as I understand D's name mangling, that symbol name is corrupt.

 CTFE recursion is the only reported unfixed bug that does that ...

There is exactly one CTFE function that calls itself.  However, it
cannot recurse more than once (it does so to change types) *and* this
function is used in the LexerTest program which does compile.

AstTest uses an additional CTFE function, but this just concatenates
some strings together.

 Try and remove stuff until it starts working

I've gutted the changes between LexerTest and AstTest to the point that
I get an .exe.  This involved stripping out more or less every global
and member function that was added and every derived class.

What tipped it over into compiling was removing the reference to
StructuredOutput from AstDumpVisitor.  Which is odd, because
StructuredOutput is still being used in AstTest.

StructuredOutput, once gutted, is this:

 module StructuredOutput;

 import tango.io.model.IConduit : OutputStream;
 import tango.io.stream.Format : FormatOutput;

 final class StructuredOutput
 {
 alias StructuredOutput This;
 this(OutputStream os)
 {
 }
 }

I honestly can't see what it could be upset about.

 Post the source and I'll try to help. I like debugging weird problems.
 :)

Attached both regular and decaffeinated^Hgutted versions.


matheval.7z
Description: Binary data


matheval-gutted.7z
Description: Binary data


Yet more OPTLINK woes

2010-05-12 Thread Daniel Keep

That's right, it's time for everyone's favourite [1] game: guess why
OPTLINK's not working! [2]

*sigh*  I'm writing a math eval library.  There are two test
applications.  LexerTest only touches part of the code.  AstTest touches
everything.

Now, the following works and creates an executable:

dmd -ofLexerTest (appropriate .d files)

So far, so good.  I get LexerTest.map, LexerTest.obj and LexerTest.exe.
 Let's try the other one...

dmd -ofAstTest (more .d files)

This creates a legitimate-looking AstTest.obj and a completely empty
AstTest.map file.

That's it.

No executable, no error message, no register dump, nothing.

Adding or removing -g, -debug, -unittest, -release, -inline, -O does
nothing.  Changing the target filename does nothing useful.

There are no spurious link.exe or dmd.exe processes running.  Invoking
OPTLINK directly changes nothing.

Does anyone have any idea, any idea at all, on what could be causing
this?  I've tried everything myself and several others on #d could think of.

*miserable sob*

After over five years of this sort of shit, I am so, so completely and
utterly sick to death of OPTLINK.



[1] I am, of course, being sarcastic.

[2] It is, of course, entirely possible that it's not OPTLINK's fault.
Frankly though, I find that hard to believe.


Re: metaprogramming question

2010-04-18 Thread Daniel Keep

http://while-nan.blogspot.com/2007/06/wrapping-functions-for-fun-and-profit.html

It shouldn't be too difficult to inject an extra parameter; just add it
to the end of the call to the wrapped function after args.


Re: gdc and Make

2010-04-10 Thread Daniel Keep

bud, rebuild and xfbuild were designed so we wouldn't NEED Makefiles in
the first place.

Unless you've got a good reason, just use a recent dmd and xfbuild.


Re: enum values without initializer

2010-04-06 Thread Daniel Keep


bearophile wrote:
 Nick Sabalausky:
 
 If you don't want that doplication you can also write:
 enum auto f = Foo();
 Can't you do:
 enum f = Foo();
 ?
 
 In my opinion that's a semantic mess, I don't write that. auto is for 
 automatic local type inference and enum is to ask for a compile time constant.

No it isn't.  'auto' is a storage class, it has NOTHING to do with type
inference.

Type inference is triggered when the type is omitted from a declaration.
 It just turns out that in the majority of cases (variables), the
easiest way to do this is to use the default storage class which is used
if you don't otherwise specify one: auto.

This is why 'const blah = 42;' works: const is used as a storage class
and the type is omitted.


Re: is pointer

2010-03-20 Thread Daniel Keep

bearophile wrote:
 (I am looking for rough corners in D, or in my knowledge of D.)
 
 In this page:
 http://www.digitalmars.com/d/2.0/templates-revisited.html
 
 In the section Template Parameters there is written:
 
 P:P*, // P must be a pointer type
 
 -
 
 So I have written this D2 program:
 
 
 template IsPointer1(T) {
 enum bool IsPointer1 = is(T : T*);
 }
 void main() {
 int* ptr;
 static assert(IsPointer1!(typeof(ptr))); // Err
 }
 
 
 But it asserts, do you know why?

You do realise that Template Parameters are a completely different
thing to is expressions, right?


Re: exceptions

2010-02-24 Thread Daniel Keep


Ellery Newcomer wrote:
 On 02/24/2010 03:10 AM, bearophile wrote:
 Ellery Newcomer:
 Okay, does anyone know a good way to figure out where something like
 this is coming from:
 object.Exception: lengths don't match for array copy

 void main() {
  auto a1 = new int[5];
  auto a2 = new int[4];
  a1[] = a2;
 }

 Bye,
 bearophile
 
 I want line numbers

You could use Tango and enable stack tracing.  That or hook up a debugger.


Re: When is array-to-array cast legal, and what does actually happen?

2010-02-22 Thread Daniel Keep

 ...

 I see that neither the constructor nor the postblit is called.
 Apparently the bit representation is used. This has the risk of
 violating struct invariants.
 
 Is it legal?
 
 Thank you,
 Ali

cast is to value conversions what a tactical nuclear strike is to
peaceful negotiations.  cast is specifically *designed* to circumvent
the type system's protections [1].

If you want to do a value conversion, *do a value conversion*.  Allocate
a new array and convert each member.  cast doesn't call the constructor
or the postblit because it's doing a pointer conversion.

Your code is basically equivalent to this:

void main()
{
auto tmp = hellod;
auto mine = cast(MyChar*)(tmp.ptr)
[0..(tmp.length*typeof(tmp[0]).sizeof)/MyChar.sizeof)];
}

That is, it's doing an unsafe, unchecked pointer cast, then re-slicing
the array.

To answer your question: yes, it's legal.  Not what you wanted, but legal.



[1] Except for int-float.  Oh, and objects.  Really, this is one thing
I could just about strangle KR for: conflating value-preserving,
non-value-preserving *AND* unsafe conversions all into a single
construct.  Walter, gets slapped with a fish for not putting a bullet in
cast's head when he had the chance.  Argh!


Re: immutable string literal?

2010-02-21 Thread Daniel Keep

strtr wrote:
 On winXP (D1) I can compile/run this code without a problem.
 Not even a warning.
 
 void main() {
   char[] s= immutable literal?;
   s[$-1] = '!';
   writefln(s);
 } 
 Codepad runs into a segmentation fault.
 http://codepad.org/NQfsRoR5
 
 Why doesn't it result in a compiler error or warning?
 If it did I would have noticed this quirk earlier.

There's no compiler error because D1 doesn't have a const/immutable system.

There's no crash because Windows doesn't write-protect the data segment
which contains the literal.


Re: Commmandline arguments and UTF8 error

2010-02-21 Thread Daniel Keep


Nils Hensel wrote:
 Hello, group!
 
 I have a problem writing a small console tool that needs to be given
 file names as commandline arguments. Not a difficult task one might
 assume. But everytime a filename contains an Umlaut (ä, ö, ü etc.) I
 receive Error: 4invalid UTF-8 sequence.
 
 Here's the sample code:
 
 import std.stdio;
 
 int main(string[] argv)
 {
foreach (arg; argv)
{
   writef(arg);
}
return 0;
 }
 
 I use dmd v1.046 by the way.
 
 How do I make the argument valid? I need to be able to use std.path and
  std.file methods on the file names.
 
 Any help would be greatly appreciated.
 
 Regards,
 Nils Hensel

If you look at the real main function in src\phobos\internal\dmain2.d,
you'll see this somewhere around line 109 (I'm using 1.051, but it's
unlikely to be much different in an earlier version):

 for (size_t i = 0; i  argc; i++)
 {
 auto len = strlen(argv[i]);
 am[i] = argv[i][0 .. len];
 }

 args = am[0 .. argc];

 result = main(args);

In other words, Phobos never bothers to actually convert the arguments
to UTF-8.

Tango does (tango\core\rt\compiler\dmd\rt\dmain2.d:238 for a recent-ish
trunk).


Re: use variant as associative array

2010-02-11 Thread Daniel Keep


Daniel Keep wrote:
 I got the following to work with Tango's Variant (dmd 1.051 + pre-0.99.9
 trunk):
 
 Variant[char[]][int] aa;
 
 aa[0] = typeof(aa[0]).init;
 aa[0][Month] = Variant(Jan);
 aa[0][Profit] = Variant(500);
 
 aa[1] = typeof(aa[0]).init;
 aa[1][Month] = Variant(Feb);
 aa[1][Profit] = Variant(800);
 
 There's actually two problems at work here:
 
 1. You can't use a nested associative array without initialising it.

Scratch that; it does work.  Huh.  Fancy that.

 2. You apparently can't assign to an aa of Variants for some reason.
 
 Keep in mind that Variants are basically a hack on the language; that
 assigning to a Variant value in an AA doesn't work isn't entirely
 surprising.

Another thing that occurred to me; is there any reason you can't do this:

 struct Record
 {
 char[] month;
 int profit;
 }

 Record[int] aa;

 aa[0] = Record(Jan, 500);
 aa[1] = Record(Feb, 800);

Or even this:

 Record[] arr;
 arr ~= Record(Jan, 500);
 arr ~= Record(Feb, 800);

Or even even this:

 enum Month { Jan, Feb, Mar, /* and the rest */ }
 struct Record { Month month; int profit }
 Record[] arr;
 arr ~= Record(Month.Jan, 500);
 arr ~= Record(Month.Feb, 800);

?


Re: D memory consumption/runtime speed problem

2010-01-13 Thread Daniel Keep


sybrandy wrote:
 Hello,
 
 I've been writing a bit of compression code and I noticed some strange
 behavior that's driving me a bit batty.  I don't know if it's a bug with
 D or something I did.  All I know is I can't figure it out.
 
 ...
 
 Am I doing something wrong?  I've tried every trick that I could find by
 reading the documentation.  Btw: The last time I tried this was with the
 latest version of D released at the beginning of the month.

I haven't verified this, but I'd be *deeply* suspicious of encodeNumber.
 I don't usually use array literals but, if I remember correctly, every
time it is called you're performing a heap allocation.  Even worse,
those concatentations might be performing separate allocations, too.

You could eliminate the overhead by using a passed-in buffer design like so:

ubyte[] encodeNumber(in uint count, ref ubyte[4] buffer)
{
if (count = ONE_BYTE_VAL)
{
buffer[0] = cast(ubyte)(ONE_BYTE_MASK | count);
return buffer[0..1];
}
// ...
}

Then, in the calling function:

{
ubyte[4] temp;
foreach( ... )
{
appOutput.put(encodeNumber(count, temp));
}
}

See if that helps.


Re: Getting access to the variables of an imported class

2009-12-05 Thread Daniel Keep

jicman wrote:
 aalm Wrote:
 import dfl.all;
 import myform2;
  
 void main()
 {
   //Form d = new MyForm();
   //MyForm d = new MyForm();
   auto d = new MyForm();
   d.text = Hello...;
   d.Name.text = name;
   d.show();
 }
 
 thanks.  That worked.  Would you care to explain? :-)  I know what auto does, 
 but I thought that a Form was a form and a Class was a class.  Does auto here 
 would suffice for all other kinds of variables?
 
 Thanks for the help.
 
 jos�

Sometimes, I think all compiler errors should be replaced with
Something went wrong.  No one ever seems to *read* them.  :|

 testDFL.d(8): Error: no property 'Name' for type 'dfl.form.Form'

You were trying to access a 'Name' property for an object of type
'Form'.  But 'Form's do not have a 'Name' property.  Objects of type
'MyForm' do, but you've explicitly told the compiler that 'd' is of type
'Form' not 'MyForm'.


Re: why can't structs implement interfaces?

2009-11-24 Thread Daniel Keep


Bill Baxter wrote:
 On Tue, Nov 24, 2009 at 3:09 PM, Saaa em...@needmail.com wrote:
 
 I wanted to do something like this:

 class C : I {};
 struct S : I {};
 S s;
 I[] i =[new C(), s ];
 Yeh, that's never going to work because that's acting as a dynamic
 polymorphic interaface.  Referring polymorphically to a struct like
 that pretty much makes it not a struct anymore, and requires having
 the hidden pointer to a vtable that was mentioned.  That's what
 classes are for.
 Why is a hidden pointer necessary? (Just curious :)

 My simplistic view was like this:
 i[1] would just hold the location of s and s would be checked to have
 all it needs to be an I.
 
 I think it could be done with a different implementation of interfaces
 from the one D uses, one based on fat pointers.
 With that design an I referring to an S would be a fat pointer, one
 pointer pointing to the S and one pointing to S's table of function
 pointers (vtable) for the I interface.
 
 That's not how D does it AFAIR, but I don't actually recall how D does it.
 
 --bb

(This is all off the top of my head.)

In D, interfaces are pointers to the vtable which implements the
interface for a particular class.  In order to actually get the this
reference, D stores a pointer to the class' InterfaceInfo (or something)
for that interface in the first slot of the vtable.

This InterfaceInfo indicates how far from the start of an instance the
pointer to the vtable is contained.  To get this, you take the pointer
to the interface vtable and subtract this offset.

This is why interfaces cannot be implemented by structs in D: it would
require structs to grow magical hidden fields, which is explicitly
against the stated purpose of structs: plain old data.

Even then, there's a worse problem.  All interfaces can be cast to
Object, and then upcast to any valid class.  This is done via the use of
the first slot of the object's vtable, which contains the ClassInfo.

But if you allow structs as interfaces, you're suddenly in the position
where you might not actually have an object at all.  If you tried to
cast a struct to an Object, it might not actually fail; if you're lucky,
you'll get a segfault.

The only solution there is to give structs a vtable.  At which point,
congratulations, you've just re-invented classes.

To allow structs to implement interfaces would require redesigning how
interfaces are actually implemented.  You'd probably have to also
redesign RTTI as well, object casting, etc.


Re: Using ANSI codes

2009-11-05 Thread Daniel Keep

funog wrote:
 Stewart Gordon Wrote:
 
 Funog wrote:
 How can I get a D1 console program to use ANSI codes? Currently it just 
 prints the escape character like any other...
 At first I thought you meant the ANSI character set, but then I realised 
 you're probably talking about ANSI.SYS.

 This is an operating system issue, not a D issue.  What OS version are 
 you using?  Try searching the web for info related to yours.

 Alternatively, check out disp.h, which comes with DMC, and use that 
 instead.  I once began writing D bindings for it

 Stewart.
 
 You are right. I was using Vista Premium, but it works fine on linux.

http://github.com/DanielKeep/gb/blob/master/src/gb/io/Ansi.d

Should stand on its own, but only works with Tango.

  -- Daniel


Re: The length of strings vs. # of chars vs. sizeof

2009-11-01 Thread Daniel Keep


Rainer Deyke wrote:
 Jesse Phillips wrote:
 I believe the documentation you are looking for is:

 http://www.prowiki.org/wiki4d/wiki.cgi?DanielKeep/TextInD

 It is more about understanding UTF than it is about learning strings.
 
 One thing that page fails to mention is that D has no awareness of
 anything higher-level than code points.  In particular:
   - dchar contains a code point, not a logical character.
   - D has no awareness of canonical forms and precomposed/decomposed
 characters (at the language level).  (Some characters can be represented
 as either one or two code points.  D does not know that these are
 supposed to represent the same character.)
   - Although D stops you from outputting an incomplete code point, it
 does not stop you from outputting an incomplete logical character.
 
 Also, some D library functions only work on the ASCII subset of utf-8.

Well, it *is* on a Wiki.


Re: version specific enum members

2009-10-29 Thread Daniel Keep


Phil Deets wrote:
 Hi, is there a way to add members to an enum based on conditional
 compilation symbols. I tried
 
 enum Tag {
A, B,
version (symbol) {
   C, D,
}
E,
 }
 
 but it doesn't work. I know I could do
 
 version (symbol) {
enum Tag { A, B, C, D, E }
 } else {
enum Tag { A, B, E }
 }
 
 but I don't want to do that since in my case, there can be quite a few
 elements outside of the version, and I don't want to repeat them all.

template Version(char[] ident)
{
mixin(`version(`~ident~`) const Version = true;
   else const Version = false;`);
}

char[] genEnum(bool flag1, bool flag2)
{
return A, B, 
 ~ (flag1 ? C, D,  : )
 ~ E, F, 
 ~ (flag2 ? G, H,  : )
 ~ G, ;
}

mixin(genEnum( Version!(`symbol`), Version!(`somethingElse`) ));

... is about the best you can do, I think.


Re: amazing function behavior

2009-10-19 Thread Daniel Keep


Zarathustra wrote:
 Function is never called but why?

It shouldn't even COMPILE.

You can't use member functions as Windows callbacks.  You haven't even
used the correct calling convention on it.

Callbacks for Win API functions have to be, I believe, extern(Windows),
and they have to be free functions or static members.


Re: Getting started - D meta-program question

2009-10-03 Thread Daniel Keep

Justin Johansson wrote:
 There was mention** on the general discussion group that the D foreach_reverse
 language construct could be replaced (emulated?) with a (D) meta-program.
 
 ** Even a novice programmer can write a meta-program to replace
 foreach_reverse without any runtime performance hit.
 

 http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.Darticle_id=97362
   
 As I'm less than a novice with the D meta-programming facilities (at this 
 stage of my journey into D),
 if someone would kindly show me the D meta-program solution to do this,
 I'd really appreciate the enlightenment.
 
 Thanks again.

Short answer: you can't.

Long answer: you can, provided you aren't trying to reverse an opApply,
which is patently impossible.

As for the meta-program, I would suspect whoever said that was talking
about writing a templated type or function to handle it.  You would need
to use template specialisation or static ifs to switch on what type
you've been given to reverse.

http://digitalmars.com/d/1.0/template.html

http://digitalmars.com/d/1.0/version.html#staticif


Re: Sizeof class instance

2009-10-03 Thread Daniel Keep


Jarrett Billingsley wrote:
 On Sat, Oct 3, 2009 at 5:50 PM, Justin Johansson n...@spam.com wrote:
 How does one determine the sizeof (in bytes) of an instance of a class in D?

 .sizeof works as advertised for structs, but for reference types,
 .sizeof yields the sizeof the referencing variable (effectively same as size 
 of a pointer)
 and not the size of the underlying instance.

 I did try scanning the NG and read spec_D1.00.pdf.  Perhaps I missed it in 
 the latter.

 btw. I was poking under the hood of std.xml and though, wow, instances of 
 Element
 class look humongous, and so I'm interested to how exactly how humongous.

 Thanks for all help.
 Justin
 
 There's no way to get it at compile-time in D1. The best you can do is
 Class.classinfo.init.length.

What nonsense, of course there is!

http://gist.github.com/140531

Note: this is VERY old code, but I have no reason to think it won't
still work.  I may need a little dusting off...


Re: Sizeof class instance

2009-10-03 Thread Daniel Keep


Daniel Keep wrote:
 ...
 Note: this is VERY old code, but I have no reason to think it won't
 still work.  I may need a little dusting off...

*It* may need a little dusting off.  Argh.


Re: What if gc.disable at all

2009-09-24 Thread Daniel Keep


Sam Hu wrote:
 Ah yes,I once translated most of Tango's tango.util.container.* into D2 
 excluding one or two modules  which heavily depends on Tango other modules.It 
 get compiled.However,the test program crashed with below error message:
 Error 42:Symbol Undefined _D5tango4core6Memory2GC6addrOfFpvZPv 
 ---errorlevel 1 
 
 I have no clue what this means and where to restart.
 
 Regards,
 Sam

How about by reading the error message?

Error 42:Symbol Undefined _D5tango4core6Memory2GC6addrOfFpvZPv

--

Error 42:Symbol Undefined void* tango.core.Memory.GC.addrOf(void*)

Ergo, you didn't link in tango.core.Memory, which it wants.


Re: Linking in an .so on linux with rebuild?

2009-09-23 Thread Daniel Keep


Jarrett Billingsley wrote:
 On Wed, Sep 23, 2009 at 1:11 AM, Daniel Keep
 daniel.keep.li...@gmail.com wrote:
 Now I just have to figure out how to fix THIS:

 ../build/dsss_objs/D/sandbox.minid_repl.o: In function `_Dmain':
 sandbox/minid_repl.d:(.text._Dmain+0x6f): undefined reference to
 `_D5minid11commandline45__T3CLITS5minid11commandline14MDConsoleInputZ3CLI11interactiveMFPS5minid5types8MDThreadZv'

 I *hate* linker errors.  :(
 
 Oh boy, looks like templates are at it again. I'm not sure what the
 problem is there. Maybe minid.commandline isn't actually being
 compiled somehow, only imported?

Yeah, I got around it by manually adding minid/commandline.d to the
compile line.


Re: Linking in an .so on linux with rebuild?

2009-09-22 Thread Daniel Keep


Nick Sabalausky wrote:
 I can't seem to get that to work. Tried all sorts of stuff. Off the top of 
 my head:
 
 -llthelibname
 -llthelibname.so
 -L-l thelibname
 -L-l thelibname.so
 -L-l -Lthelibname
 -L-l -Lthelibname.so
 
 None of them were able to find the file (and, yes, the name+path are right), 
 and I'm not using any links.

I've had exactly the same problem in trying to compile MiniD on Ubuntu
last night.

MiniD wants libhistory, but -llhistory doesn't work.

What's worrying me is that even if I call ld directly and pass
-lhistory, IT says it can't find it, either.  It's in /lib, so I have no
idea what's going on.

Passing the .so directly on the command line, like on Windows, doesn't
appear to work as either rebuild or DMD is chucking a wobbly at the .so
file, complaining it doesn't know what that extension is for.


Re: Linking in an .so on linux with rebuild?

2009-09-22 Thread Daniel Keep


Jarrett Billingsley wrote:
 On Wed, Sep 23, 2009 at 12:41 AM, Daniel Keep
 daniel.keep.li...@gmail.com wrote:
 I found a solution.

 See
 http://stackoverflow.com/questions/335928/linux-gcc-linking-ld-cannot-find-a-library-that-exists

 For me, I needed readline and history, so I did this:

 $ cd /lib
 $ sudo ln -s libreadline.so.5 libreadline.so
 $ sudo ln -s libhistory.so.5 libhistory.so

 After that, ld didn't complain.

 
 Oh yay. I was going to suggest that but I had never had that kind of
 problem on Ubuntu when building MiniD before. Maybe we're using
 different versions or something.

Now I just have to figure out how to fix THIS:

../build/dsss_objs/D/sandbox.minid_repl.o: In function `_Dmain':
sandbox/minid_repl.d:(.text._Dmain+0x6f): undefined reference to
`_D5minid11commandline45__T3CLITS5minid11commandline14MDConsoleInputZ3CLI11interactiveMFPS5minid5types8MDThreadZv'

I *hate* linker errors.  :(


Re: delegate reference

2009-09-09 Thread Daniel Keep


Saaa wrote:
 abstract class C
 {
  int method();
 }
 class C2:C
 {
  int method() return 2;
 }
 class C3:C
 {
  int method() return 3;
 }
 int delegate() deleg;
 void main()
 {
  C c;
  C2 c2 = new C2;
  C3 c3 = new C3;
  c=c2;
  deleg = c.method;
  writefln(deleg()); // 2
  c=c3;
  writefln(deleg()); // 2
  // I expected this to write 3, why is this not so?

Because you didn't reassign deleg.


Re: delegate reference

2009-09-09 Thread Daniel Keep


Saaa wrote:
 Daniel Keep daniel.keep.li...@gmail.com wrote in message 
 news:h88cck$1or...@digitalmars.com...

 Saaa wrote:
 abstract class C
 {
  int method();
 }
 class C2:C
 {
  int method() return 2;
 }
 class C3:C
 {
  int method() return 3;
 }
 int delegate() deleg;
 void main()
 {
  C c;
  C2 c2 = new C2;
  C3 c3 = new C3;
  c=c2;
  deleg = c.method;
  writefln(deleg()); // 2
  c=c3;
  writefln(deleg()); // 2
  // I expected this to write 3, why is this not so?
 Because you didn't reassign deleg.
 but isn't deleg pointing to c's method? 

Yes... just because you change what c points to doesn't magically
rewrite all other references.

You might want to read http://digitalmars.com/d/1.0/type.html#delegates


Re: delegate reference

2009-09-09 Thread Daniel Keep

Saaa wrote:
 Ok, disregard my last comment :D
 How should I do this then? 

class Foo
{
  C* c;

  this(ref C c)
  {
this.c = c;
  }

  int invoke()
  {
return (*c).method();
  }
}

void main()
{
  // ...
  deleg = (new Foo(c)).invoke;
}

Or something similar.

This is dangerous.  Do not allow either the Foo instance or the delegate
to survive past the end of c's scope.

It is simpler and safer to just update the delegate.


Re: Structs by ref in D2

2009-08-22 Thread Daniel Keep

bearophile wrote:
 Daniel Keep:
 In my own code, I usually record my intent by using inout for
 variables I intend to modify and ref for ones which I don't.
 Always seemed reasonable to me.
 
 for the compiler they mean the same thing, but inout is being deprecated.
 
 Bye,
 bearophile

I realise this.  My point is that the two keywords pretty nicely sum up
a difference in intent.


Re: Structs by ref in D2

2009-08-21 Thread Daniel Keep


Steven Schveighoffer wrote:
 ...
 
 The issue is possibly with ref.  There are two reasons to use ref, 1 is
 to be able to change the data referenced, 2 is for passing speed.
 
 1 is bad for rvalues.  2 should be ok for rvalues.
 
 If there was a way to signify you only want to use ref for reason 2,
 there would be a good solution.  Most of the time, that's const ref, but
 what you really want is head-const ref, which isn't currently possible. 
 If a struct has references to other values, they might be lvalues, and
 you may want to be able to change them.
 
 I'm uncertain as to how often you would want to pass an rvalue as a ref
 that had lvalue reference in it, but at the very least, ref const should
 be valid.
 
 -Steve

In my own code, I usually record my intent by using inout for
variables I intend to modify and ref for ones which I don't.

Always seemed reasonable to me.


Re: Semi Automated Object wrapping

2009-08-13 Thread Daniel Keep


Bill Baxter wrote:
 On Thu, Aug 13, 2009 at 12:43 AM, Rory McGuirerjmcgu...@gmail.com wrote:
 On Wed, 12 Aug 2009 17:03:17 -0700, Bill Baxter wrote:

 On Wed, Aug 12, 2009 at 4:52 PM, Rory McGuirerjmcgu...@gmail.com
 wrote:
 Here is some code I wrote which enables wrapping a proxy around an
 object. I am using it for my serialization library. It works in
 D1(1.046) and D2 (2.031)

 Posting it here for reference by all before I add to much of the stuff
 specific to my use, should make it easier to follow.

 usage: new ProxyClass!(A, cast(string)getInt setInt getString); would
 implement the methods getInt setInt and getString from A in the new
 class.

 the code below will fail to compile but not before printing the
 generated code to stdout.

 Shin Fujishiro has made some new templates for D2 which will make it so
 I can get rid of the setInt getInt getString part which would make
 the usage for D2: new ProxyClass!A;
 which would be great!

 -Rory

  // author: Rory McGuire,
 rjmcgu...@gmail.com import std.stdio;
 import std.typetuple;
 import std.traits;
 import std.metastrings;

 //import serializer;

 // this CTF from somewhere on news.digitalmars.com string[]
 splitFuncs(string str) {
string[] res;
while (str.length  0) {
while (str.length  0  (' ' == str[0] || ',' == str[0])) {
str = str[1..$];
}
int to = 0;
for (; to  str.length  str[to] != ' '  str[to] != ',';
++to)
 {}
if (to  0) {
res ~= str[0..to];
str = str[to..$];
}
}
return res;
 }

 string MethodTypeTuple_mixin(alias a)(string[] methods) {
string ret = TypeTuple!(~
typeof(C.init.~methods[0]~); foreach (method;
methods[1..$]) {
ret ~= ,typeof(C.init.~method~);
}
ret ~= );
return ret;
 }



 // test case

 class A {
int a;
this(int a) {
this.a = a;
}
int getInt(string intname) {
return a;
}

void setInt(int i) {
a = i;
}
string getString(string s) {
return s ~1234;
}
 }


 string ProxyMethods_mixin(alias C, string methodstr)() {
string ret;
foreach(i, t; mixin(MethodTypeTuple_mixin!(C)(splitFuncs
 (methodstr {
// output function header
ret ~= \t~ReturnType!(t).stringof ~ ~
splitFuncs
 (methodstr)[i]~(;
// output first arg
ret ~= ParameterTypeTuple!(t)[0].stringof~
arg; // output remainder of args
foreach (j, t1; ParameterTypeTuple!(t)[1...$]) {
ret ~= ,~t1.stringof~
 arg~std.metastrings.ToString!(j);
}
// output body
ret ~= ) {\n;
// output serialization code
// send method name
ret ~= \t\twritefln(\serialize docall id\);
// the
 method call byte id\n;
ret ~= \t\tbuffer ~=
serialize!(string)(\~splitFuncs
 (methodstr)[i]~\, s_state); /+ the method name +/\n;
// send args
ret ~= \t\tbuffer ~= serialize!(~
ParameterTypeTuple!(t)
 [0].stringof~)(arg, s_state); /+ the first argument +/\n;
foreach (j, t1; ParameterTypeTuple!(t)[1...$]) {
ret ~= \t\tbuffer ~= serialize!(~
t1.stringof
 ~)(arg~ToString!(j)~, s_state); /+ argument ~ToString!(j)~ +/\n;
}
// receive return type
static if (!is(ReturnType!(t) == void)) {
ret ~= \t\treturn deserialize!(~
ReturnType!
 (t).stringof ~)(buffer, des_state);\n;
}
ret ~= \t}\n;
}
return ret;
 }


 class ProxyClass(alias C, string methodstr) {
ubyte[] buffer;
mixin(ProxyMethods_mixin!(C,methodstr)());
pragma(msg, class ProxyClass!(~C.stringof~,
\~
 methodstr ~\) {\n\tubyte[] buffer;\n  SerializerState s_state;\n
 DeserializerState des_state;\n  this() {s_state = new
 SerializerState(); des_state = new DeserializerState(); }\n\n~
 ProxyMethods_mixin! (C,methodstr)() ~\n}\n);

 }

 void main() {
auto pc = new ProxyClass!(A, cast(string)getInt setInt
 getString);
writefln(ProxyClass: ~ pc.getString(asdf));
 }


 That code is screaming for some macros. Or variable interpolation at
 least.

 --bb
 Where would you propose that one would use 'macro'?

 
 It doesn't exist yet, so there's not much you can do about it.
 Unfortunately code that generates code in D pretty much has to look
 like what you wrote there.  I'm just saying it's not a lot of fun to
 read such code.  Compare with Lisp macros that are almost as readable
 as regular Lisp functions.
 
 

Re: calling function templates

2009-08-09 Thread Daniel Keep


Jos van Uden wrote:
 I noticed that I don't always have to use the bang notation for
 function templates. I played around with that a little, but got
 an error when I used a static array. I think it's because of a
 casting problem or wrong type inference... I don't imagine it's
 a bug. Just not possible.
 
 ...
 
 int[20] arr4;
 putNumbers(arr4, 0, 3); // ERROR, stat array, regular notation
 
 }
 
 test.d(8): Error: cast(int[])r is not an lvalue
 test.d(25): Error: template instance test.putNumbers!(int[20u],int)
 error instantiating

You're instantiating the template as putNumbers!(int[20u],int) because
arr4 is of type int[20u].

This means Range is int[20u].  Here's the code for put:

 void put(T, E)(ref T[] a, E e) {
 assert(a.length);
 a[0] = e; a = a[1 .. $];
 }

r.put(i) is rewritten by the compiler as put(r, i)... except that put
wants an int[], not an int[20u].  So it implicitly casts it to the
correct type, giving put(cast(int[])r, i).

But put ALSO expects its first argument to be passed by reference, and
you cannot pass the result of a cast by-reference.

(There are a LOT of things you can't pass by reference; it's a constant
thorn in my side, and many others' sides.)

The problem here is that put is fundamentally incompatible with
fixed-size arrays.  The solution is to change line 25 to read:

auto arr4_temp = arr4[]; putNumbers(arr4_temp, 0, 3);


Re: how does range.put work

2009-08-08 Thread Daniel Keep


Jos van Uden wrote:
 Oliver wrote:
 The source code for the standard library comes with the compiler.
 If you look in std\array.d, you find this around line 279 (reflowed for
 readability):
 void put(T, E)(ref T[] a, E e) {
 assert(a.length);
 a[0] = e; a = a[1 .. $];
 }
 
 Would anybody care to explain what this is used for? I find
 the example in array.d rather unhelpful.
 
 Example:
 
 void main()
 {
 int[] a = [ 1, 2, 3 ];
 int[] b = a;
 a.put(5);
 assert(a == [ 2, 3 ]);
 assert(b == [ 5, 2, 3 ]);
 }
 
 You're putting an element in a, but then the first element is moved out
 of a and the new one shows up in b? Weird. I guess I don't understand
 what a range is.
 
 Jos

No; read the code.  Before the put, a and b are pointing to the same
span of memory.  a.put(5) puts the value 5 into the front (first
element) of the array, then advances the array.

However, put can't see b, so it doesn't get updated along with a.  The
end result is that b = [5,2,3] and a = b[1..3] = [2,3].

Why do it like this?  Here's an example:

void putNumbers(Range)(Range r)
{
int i = 0;
while( !r.empty )
{
r.put(i);
++i;
}
}

void main()
{
int[10] ten_numbers;
putNumbers(ten_numbers);
assert( ten_numbers = [0,1,2,3,4,5,6,7,8,9] );
}

Note that putNumbers will work with any type that supports the range
API, not just arrays.


Re: how does range.put work

2009-08-06 Thread Daniel Keep


O.K. wrote:
 Hello,
 could someone plz clearify what the exact semantics of put
 are ?
 Put works with an appender, but gives me a runtime exception
 when using an array.
 
 Best regards,
 Oliver

The source code for the standard library comes with the compiler.

If you look in std\array.d, you find this around line 279 (reflowed for
readability):

 void put(T, E)(ref T[] a, E e) {
 assert(a.length);
 a[0] = e; a = a[1 .. $];
 }


Re: byte to char safe?

2009-07-30 Thread Daniel Keep


Harry wrote:
 Again hello, 
 
 char[6] t = ragain ~ cast(char)7 ~ rhello;
 
 use only own write functions
 is ok?
 
 thank you!

I think a more significant problem is that again\x07hello can't
possibly fit in six characters, unless you're using some crazy numbering
system I'm not familiar with.


Re: How to search for an element in the array. D2 phobos.

2009-07-13 Thread Daniel Keep


bearophile wrote:
 Eldar Insafutdinov:
 I think I completely misunderstood how to use it.
 
 Yes, it's too much complex. It tries to do many different things in the most 
 efficient way possible, the result is a high complexity in usage. That's one 
 of the faults of Andrei's code, it's not tested by letting  average coders 
 use it.
 A solution for this problem is to offer simple functions (like you can find 
 in Tango. In my dlibs the situation is intermediate, I think) with a simple 
 API for the most common purposes.
 
 Bye,
 bearophile

It should work.  Taken from the algorithm docs:

 Example:

  int[] a = [ 1, 4, 2, 3 ];
  assert(find(a, 4) == [ 4, 2, 3 ]);

That said, find is too complex for his purposes.  Amazingly, Phobos
still appears to lack a basic indexOf function.

Phobos2: can build a working sentient AI that can feel love up from
individual atoms, but can't find the index of an array element.  :P


Re: Array slice length confusion

2009-07-09 Thread Daniel Keep


Tim Matthews wrote:
 Kagamin wrote:
 Tim Matthews Wrote:

 I thought a slice would behave slighty different due to some sort of
 meta data that is a separate area of memory so it doesn't effect D's
 abi.

 Current plan is to introduce new type - array - into the language.
 
 Do you know the ng posts or where ever that was posted?

Best bet would be to search for T[new].


Re: How to release memory? (D2.0.30)

2009-07-04 Thread Daniel Keep

BCS wrote:
 ... The good news is that with virtual memory, all of that has almost
 zero cost. What matters is how much ram you are actively using.

You've obviously never used a netbook with no swap file.  :)


Re: why __traits not in trait module and not name it trait

2009-06-24 Thread Daniel Keep


Sam Hu wrote:
 Yes,__traits did not stole my girl friend,but isn't better to name it trait? 
 And I have thought I can find it in trait moudle but I was wrong.

It's not in a module because it's a keyword.  You don't find function
defined in any library.

As for being called __traits instead of traits, I suspect that's for at
least one of two reasons:

1. so it won't invalidate existing code that uses the identifier
traits, and/or

2. because it's not something regular programmers should have to use; it
should be used to build a higher-level API using templates.


Re: D compiler for .NET

2009-06-09 Thread Daniel Keep


Jason House wrote:
 Earlier today, I tried to use the D compiler for .NET from 
 http://dnet.codeplex.com/
 
 Beyond compilation of the compiler, I found zero instructions on what to do 
 next.  How do I integrate the compiler into the .NET framework/visual 
 studio?  I'd like to be able to add D files to existing solutions (with C# 
 code).  If I can do that, I'll probably push for some small adoption of D at 
 work.  (I'm hoping mixins and templates will inspire the initial use of D)
 
 Any tips or documentation on how to get started would be appreciated.
 

The back-end code is not of production quality, it is intended for
research and educational purposes. The D Programming Language is a
fairly complex language, and non-trivial features such as TLS and
closures make it an interesting case study for generating IL code.

Why do people never read the big red label saying Warning: not ready
for use!?

As for VS integration, so far as I know, there isn't any.  I'm also
fairly certain that you can't combine different languages in a single
project period.


Re: legal identifier check

2009-05-31 Thread Daniel Keep


Saaa wrote:
 ...
 
 I know use this (in the ddata thread above):
 
 foreach(char c; identifier)
 {
  if( !inPattern( c, `_a-zA-Z0-9`) )
  {
   return false;
  }
 } 

That's not correct.  http://digitalmars.com/d/1.0/lex.html#identifier


Re: Encoding problems...

2009-05-28 Thread Daniel Keep


Robert Fraser wrote:
 BCS wrote:
 Reply to Robert,


 Hmm... I'd say x.⊆(y) is preferable x.isSubsetOf(y), but it's not a
 huge deal.


 Only until you have to type it. I think universal alpha includes only
 the union of things that can be easily typed on standard keyboards. I
 don't think any keyboard (ok maybe an APL keyboard) has the subset
 symbol on it.
 
 I have 10 configurable keys on my keyboard, none of which are in use. I
 could also remap my numpad (cause, seriously, who uses this?) Also, many
 editors can be configured so that a sequence of characters converts to a
 single one.

Which would possibly make D the first language to *require* a
specialised keyboard and/or editor since APL.

Not a good precedent.

Oh, and don't try to argue it isn't mandatory.  If you can overload
those operators, people WILL use them and WILL complain that it's too hard.

 There appears to be no reason that mathematical symbols aren't allowed
 in identifiers... Think of how awesome it would be to write
 assert(x⊇y→∀a∈x∃b∈y(a⊇b)) ... Okay, that would require overloading of
 those operators (and instantiating variables in a new way), but still!

I think that example you gave is an excellent reason not to allow them.  :D

It would be nice, but it's really not feasible without widespread editor
and/or keyboard support for extra symbols, which I just don't see happening.


Re: How many people here use stackoverflow.com?

2009-05-23 Thread Daniel Keep


Tim Matthews wrote:
 On Sat, 23 May 2009 08:36:44 +1200, hasen hasan.alj...@gmail.com wrote:
 
 If I have some questions about D, should I ask on stackoverflow
 instead of here? Are there enough D'ers there?

 I personally think that asking there would bring more public attention
 to D, but it all depends on whether there are enough people there who
 know about D.

 For instance, I might have a couple of question about gtkD, as I'm
 trying to play with it right now.

 So, do you regularly visit http://stackoverflow.com/ or no?
 
 
 http://stackoverflow.com/questions/tagged/d
 
 I remeber seeing a post on annoucements a long time ago about when you
 type d on the tags page here http://stackoverflow.com/tags you dont get
 the d tag. IIRC that guy sent en email to jeff atwood about it but it is
 still not working.

I use the feed at http://stackoverflow.com/feeds/tag/d to keep an eye on
any D questions as they pop up.

  -- Daniel


Re: DMD Modifications

2009-05-21 Thread Daniel Keep

white_man wrote:
 Does it possible to modify DMD and publish it in that form. Of course with 
 full information about authors. Does it legal? 

It depends.  If you ONLY modify the front-end (front-end files are
identified as being licensed under GPL [1]), then you can distribute the
modified front-end.

However, if you modify the back end, you cannot redistribute those
files.  You also cannot distribute a compiled version.

To be safe, it's probably best to just distribute any changes you make
as a patch.

  -- Daniel


[1] There's another license involved, but I forget what it's called.


Re: D1/D2 co-install?

2009-05-17 Thread Daniel Keep


BCS wrote:
 Does anyone have a good solution to installing both D1 and D2 on the
 same system?

I have... (goes to check) 10 different compilers on my system.  There's
\dmd\bin\dmd-default which is the only one on the PATH (and is basically
a stable version of Tango and DMD).  If I want to use the others, I use
the full path to them.

OR, you can use rebuild and configure it with extra compiler profiles,
then use (for example):

 rebuild -dc=dmd-1.035 stuff

  -- Daniel


Re: 3 variant questions

2009-05-12 Thread Daniel Keep


Saaa wrote:
 ...
 var_arg!(T) will convert _argptr into the type you specify and it will
 also advance _argptr to the next argument.
 What would happen if you'd cast it incorrectly if it wasn't a simple pointer 
 ? :D

Same as would happen if you incorrectly cast anything.

i.e. anything.  Segfault if you're lucky.  If you're unlucky, random
crashes.

  -- Daniel


Re: Resource availability: fonts

2009-05-05 Thread Daniel Keep


Tyro[a.c.edwards] wrote:
 One cannot necessarily rely on particular font being available on a system, 
 and for security reasons asminsistrators restrict instalation of fonts (among 
 other things) onto systems in a network. I would like to know if it is 
 possible to embed a font into my code so that I know that it will always be 
 there, or can I provide it with the exe but not have to rely on it being 
 installed (i.e. use it from the same folder in which the exe resides)? 
 
 Thanks,
 Andrew

That depends.  What are you using the font for?

If you're using a library that requires a family name, then probably
not.  If you're using a library that can accept a file name, then
probably yes.

Remember that the system doesn't care if you append crap to the end of
an executable.  One trick you can use is to just append whatever files
you want to the end of the executable, and then have a little 1K block
at the end that tells you where the files are and how big they are; you
can then extract the files at run time and delete them when you terminate.


  -- Daniel


Re: how to initialize an array of typedef-ed type?

2009-05-02 Thread Daniel Keep


Jarrett Billingsley wrote:
 On Sat, May 2, 2009 at 12:21 AM, Daniel Keep
 daniel.keep.li...@gmail.com wrote:
 
 import std.conf;
 b = to!(long[])(a);

 That should work, in theory.
 
 In reality, it's std.conv ;)

Those letters are like RIGHT NEXT to each otter!  Don't judfe ne!

 (or tango.util.Convert, with identical syntax)

Never heard of it.  :)

  -- Daniel


Re: How to get the base type of a typedef

2009-05-01 Thread Daniel Keep


bearophile wrote:
 MLT:
 Is there a way to get the base type of location?
 
 See the BaseTypedef() template in the templates module of my dlibs (they 
 are for Phobos):
 http://www.fantascienza.net/leonardo/so/libs_d.zip
 
 Bye,
 bearophile

It's probably something along the lines of:

template BaseTypedef(T)
{
static if( is( T U == typedef ) )
alias U BaseTypedef;
else
alias T BaseTypedef;
}

  -- Daniel


Re: how to initialize an array of typedef-ed type?

2009-05-01 Thread Daniel Keep


Jarrett Billingsley wrote:
 On Fri, May 1, 2009 at 11:34 AM, MLT n...@anone.com wrote:
 
 Is there an easy way to convert arrays from one type to another?
 int[] a=[1,2,3,4] ;
 long[] b ;
 
 Not really.  The best you can do is:
 
 b.length = a.length;
 foreach(i, ref v; b) v = a[i];

import std.conf;
b = to!(long[])(a);

That should work, in theory.

  -- Daniel


Re: enum in template

2009-04-29 Thread Daniel Keep


Sam Hu wrote:
 Hello everybody!
 
 Convert integral value to string literal:
 
 template myToString(ulong n,
   string suffix=nuint.max?UL:U
 {
  static if (n10)
 enum myToString=cast(char)(n+'0')-suffix; //q1
 else
 enum myToString=.myToString!(n/10,)-  
   .myToString!(n%10,)-suffix;//q2
 
 Here is my questions,sir:

No need to be so formal.  Also keep in mind that sir only applies to
men, and is thus excluding any women in this NG.  :P

 q1.what the key word enum here is doing? not key word char[] or 'string' or 
 something else?

enum defines a manifest constant.  In other words, it defines a
constant that does NOT consume any storage anywhere in the program: it
exists only at compile-time.

 enum blah = 42; // single manifest constant

 enum { blah = 42 } // again, but in a block, potentially with others

 enum Stuff { blah = 42 } // again, but in a named enumeration

 q2. How does this works?Say n=12,then how can the result be 12?

Recursion.  I assume you have modified the code from its original since
'-' would be invalid.  It should be '~' which is the concatenation
operator in D.

 Thanks and best regards,
 Sam

  -- Daniel


Re: Get the name of a function and the parameters?

2009-04-28 Thread Daniel Keep


Jarrett Billingsley wrote:
 On Tue, Apr 28, 2009 at 3:07 PM, grauzone n...@example.net wrote:
 I'd like to pass several functions at once. Is there a way to make this
 variadic? The obvious approach (writing NameOfFunc(alias f...)) fails with
 a syntax error.
 
 Sure, you'd just make it NameOfFunc(f...) and then recursively
 instantiate, converting one item at a time to its name until f.length
 == 0.
 
 Alternatively, you can write a compile-time map and use NameOfFunc as
 the mapping predicate.

That requires f to be a type, which loses you the actual names.  And you
cannot (last time I checked) have aliases in a tuple.

  -- Daniel


Re: Get the name of a function and the parameters?

2009-04-26 Thread Daniel Keep


Daniel Keep wrote:
 
 Jacob Carlborg wrote:
 Is it possible to get the name of a function and the names of the
 function parameters?
 
 I don't believe so, no.
 
   -- Daniel

I should perhaps qualify, in light of Jarrett's response, that I thought
you meant from inside the function ala __FUNCTION__ or somesuch.

  -- Daniel


Re: i need a serialization framework for d

2009-04-23 Thread Daniel Keep


BCS wrote:
 http://stackoverflow.com/questions/783482/i-need-a-serialization-framework-for-d

Put my AU$0.02 in.

 OT: would anyone be interested in a one way stackoverflow-NNTP hookup
 kinda like is used with the bugzilla?

I think that'd be pretty cool; have it post questions to D.learn so they
get better exposure.

  -- Daniel


Documentation on DMD source

2009-04-18 Thread Daniel Keep

Is there any guide to, or documentation for the DMD compiler source?

I'm currently trying to make TypeInfo_Function not completely useless,
but I'm not sure my code is actually being run.

  -- Daniel


Re: Documentation on DMD source

2009-04-18 Thread Daniel Keep


Daniel Keep wrote:
 Is there any guide to, or documentation for the DMD compiler source?
 
 I'm currently trying to make TypeInfo_Function not completely useless,
 but I'm not sure my code is actually being run.
 
   -- Daniel

Found this page: http://www.prowiki.org/wiki4d/wiki.cgi?DMDSourceGuide
although it's fairly bare-bones.

  -- Daniel


Re: Widening a type

2009-04-16 Thread Daniel Keep


Doctor J wrote:
 OK, here's one for you that sounds like it ought to be easy, but I don't 
 immediately see how to do it in a pretty way.
 
 Given a type parameter T of a template:
 If T is an integral type, I want to declare a variable 'widest' of type ulong;
 If T is a floating-point type, I want to declare a variable 'widest' of type 
 double.
 And it has to be prettier than my solution.  :)
 
 static if (is (T: ulong))
 ulong widest = 0;
 else if (is (T: double))
 double widest = 0.0;
 else
 static assert (false, Unimplemented type  ~ T.stringof) ;
 
 Now, I thought this sounds like a great job for a mixin:
  
 template Widen (T, alias varname)
 {
 static if (is (T: ulong))
 ulong varname = 0;
 else if (is (T: double))
 double varname = 0.0;
 else
 static assert (false, Unimplemented type  ~ T.stringof) ;
 }
 
 mixin Widen!(T, widest);
 
 but alas, Declaration expected, not 'if'.
 
 Help?

The error tells you everything you need to know if you read it.

Actually, you have two problems: you're trying to use if where you
should be using static if, and you can't alias a symbol name then use
it in a declaration.  Here's a fixed, expanded version.

template Widen (T, char[] varname)
{
static if (is (T: ulong))
{
mixin(`ulong `~varname~` = 0;`);
}
else
{
static if (is (T: double))
{
mixin(`double `~varname~` = 0.0`);
}
else
{
static assert (false, Unimplmented type  ~ T.stringof);
}
}
}

You can remove those braces, I just wanted to point out that putting
static out the front of an if doesn't magically make the else
branch static as well.

  -- Daniel


Re: static initialization of associative arrays

2009-04-15 Thread Daniel Keep


Tyro[a.c.edwards] wrote:
 Is it yet possible to statically initialize an associative array? If so,
 please point me to the documentation. I am using DMD v2.028.
 
 Currently I'm able to do this:
 
 import std.stdio;
 
 string[string] types;
 static this(){
 types = [ void:void, bool:bool ];
 }
 
 void main(){
 writeln(types);
 }
 
 Output = [void:void,bool:bool] which is exactly what I want.
 
 However, removing static this() results in an error.
 
 string[string] types = [ void:void, bool:bool ];
 
 Result:
 api.d(77): Error: non-constant expression [void:void,bool:bool]
 
 How do I make the initialization constant?
 
 Thanks,
 Andrew

I think Walter said something a while back to the effect that making it
possible to statically initialise AAs isn't feasible because it requires
setting up a complex structure on the heap.  The best you could do would
be to *pretend* to statically initialise them, and actually really
initialise them in a module ctor.

Which is exactly what you currently have to do.

Could be wrong; that's just what I remember from the last time this came up.

  -- Daniel


Re: D1 and read-only views?

2009-04-12 Thread Daniel Keep

As others have stated, your surmise is correct.

On a related note, I recently wrote a very simple cstring struct that
acts like const(char)[] does in D2.  I was using unique interned
strings, and didn't want any surprises.  You can still get a mutable
reference to the string by using .toString, but the struct is really
only there to prevent accidental modifications.

  -- Daniel


Re: Wht std.complex is needed?

2009-04-06 Thread Daniel Keep


Steven Schveighoffer wrote:
 On Mon, 06 Apr 2009 08:36:18 -0400, Don nos...@nospam.com wrote:
 
 Sam Hu wrote:
 Thank you!
 Anothe silly question then:What's the disadvantage to have the
 built-in type of i-type?
  Regards,
 Sam

 It's a very nasty type. It supports *, but isn't closed under *.
 Which is really annoying for generic programming.

 idouble x = 2i;
 x *= x; // oops, this isn't imaginary. (BTW this currently compiles :o).
 
 This may be a dumb question, but aren't all real numbers also
 technically imaginary numbers with a 0i term?  that is, I would expect
 the above to evaluate to:
 
 -4 + 0i
 
 Which I would view as an imaginary number.  Am I completely wrong here?

You're thinking of complex.  -4 is real, 2i is imaginary, -4+2i is
complex.

Regarding Don's example, imaginary*imaginary always yields a real,
real*imaginary always yields an imaginary.  It's the only builtin type I
know of that changes type under multiplication with itself.

  -- Daniel


Re: cast a LinkSeq

2009-04-06 Thread Daniel Keep


Qian Xu wrote:
 Adam Burton wrote:
 I wouldn't think so, cos LinkSeq!(Apple) does not inherit
 LinkSeq!(Fruit), they are 2 separate types. However your apples
 automatically downcast (or up, depending which way you like to draw
 your diagrams :-) ) so unless you  intend to pass the LinkSeq!(Apple)
 into a function expecting LinkSeq!(Fruit)  it shouldn't be a problem.
 If you are passing about LinqSeq!(Fruit) and want  your
 LinkSeq!(Apple) to fit you might need to write some adapters and make
 use of the models available to you or something along them lines.

 That's my understanding anyway.
 

 
 yes. I can cast all Apple-object to Fruit-objects one by one. I hope
 there is an one-line-solution :-)

You can't do it.  Imagine you cast your LinkSeq!(Apple) to
LinkSeq!(Fruit).  You can now add a Banana to your LinkSeq!(Fruit), thus
corrupting the original object.

You get a similar problem with arrays.

The most direct way would probably be to create a LinkSeqView!(T) class
which did the cast on the fly and prohibited mutating operations.

  -- Daniel


Re: Universel toString

2009-03-20 Thread Daniel Keep


Qian Xu wrote:
 Hi All,
 
 I want to write an universel toString() method for debugging propose.
 However I cannot write in one version. The compiler says error all the time.
 Could someone tell me, how to write an universel one?
 
 What I want, is to convert primtive types (int, int*, bool, bool*, etc.) to
 string using tango.text.Convert.to() and convert object to string by
 calling obj.toString.

 ...
 
 Best regards
 --Qian Xu

to!(char[]) should call toString.  to!(T) should support all atomic
types, strings, structs and classes.

  -- Daniel


Re: enum to string

2009-03-13 Thread Daniel Keep


Ary Borenszweig wrote:
 Lionello Lunesu wrote:

 Brad Roberts bra...@bellevue.puremagic.com wrote in message
 news:alpine.deb.2.00.0903121755240.4...@bellevue.puremagic.com...
 That said, I don't think this really helps the desired usecase much. 
 It's
 useful, don't get me wrong, but still requires code to build up the
 bi-directional translations.  Or am I missing something?  Seems to be
 happening to me a lot lately, so I'm very prepared to be wrong here too.
 :)


 You're not wrong :)
 The problem is that the foreach variable is not evaluatable to a
 compile-time string. I don't know why, but I'll figure it out tonight.

 I've also managed to convert an enum to an AssocArrayLiteralExp* (with
 the name/string as the key and the value/int as the value) but it
 seems that it cannot be foreached at compile time, even if it's a
 literal expression. But hell, I've spent about 1 hour browsing through
 dmd's code, so I'm pretty sure it's possible with a little more research.
 
 Can you foreach at compile-time? I thought you could only do that in
 CTFE (or templates?). Maybe that's why it's not working. How do you do
 it to pragma msg the members of a struct?
 
 I remember someone proposed static foreach some time ago...

We have a sort-of static foreach.  The trick is that the aggregate HAS
to be a tuple.  When in doubt, you can always fall back on the following
construct:

template Tuple(T...)
{
alias T Tuple;
}

template Range(int n)
{
static if( n = 0 )
alias Tuple!() Range;
else
alias Tuple!(Range!(n-1), n-1) Range;
}

void blah()
{
// Note that static foreach ONLY works inside a function
foreach( i ; Range!(n) )
{
// do stuff with i, which should be a const int
}
}

There have been times when directly accessing some CT construct would
make the compiler choke, but going via an index worked fine.

-- Daniel


Re: recognizing asciiz, utf ...

2009-03-13 Thread Daniel Keep


newbee wrote:
 Jarrett Billingsley Wrote:
 
 On Fri, Mar 13, 2009 at 3:04 PM, newbee new...@newbee.com wrote:
 Hi all,

 How does one check for asciiz, utf ...?
 I do get a buffer with characters as parameter in a function, but i don�t 
 know if it is asciiz or utf or wchar. Is it possible to find out in dmd1 
 and dmd2?

 Any help is appreciated.
 How are you getting this buffer?  What type is it, char[]?  D strings
 are supposed to be Unicode, always.  If you read the data in from a
 file, there's little to no guarantee as to what encoding it is (unless
 it started with a Unicode BOM).

 If you have a zero-terminated char* that a C function gives you, you
 can turn it into a D string with std.string.toString (Phobos) or
 tango.stdc.stringz.fromStringz (Tango).
 
 
 i get it from a tcp buffer and do not know in advace if it is char[], asciiz 
 or wchar. is it possible to check for that?

If you're getting data from a network connection and you have no idea
what it is, then the language certainly isn't going to help you with that.

Perhaps reading the documentation for the network protocol is in order? :P

  -- Daniel


Re: lvalue - opIndexAssign - Tango

2009-03-13 Thread Daniel Keep


The Anh Tran wrote:
 Hi,
 
 When porting from c++ to D, i encounter this strange discrimination:
 1. Built-in AA:
 int[int] arr;
 arr[123] += 12345;
 arr[321]++;
 
 2. Tango HashMap:
 auto hm = new HashMap!(int, int)();
 hm[123] += 12345; // error not lvalue
 hm[123]++;// error
 
 D document says current opIndexAssign does not work as lvalue. But why
 can builtin AA can that? How can i copy builtin AA behaviour?

You can't.  This is a hole in the language at the moment, hopefully
solved by the introduction of ref returns (but that's in D 2.0 which you
don't want to use at the moment.)

 Forgive my noob, where is the place to ask question, report bug for Tango?

You could try the Tango IRC channel:

irc://irc.freenode.org/#d.tango

That, or the Tango forums:

http://dsource.org/projects/tango/forums

You can report problems with Tango via the ticket system:

http://dsource.org/projects/tango/report (New Ticket is down the
bottom of the page.)

 1. I can't compile D code using tango hashmap in debug mode:
 
 import tango.util.container.HashMap;
 void main()
 {
 auto hm = new HashMap!(uint, uint)();
 }
 
 dmd -w -g -debug  hello.d // error

When posting problems with compiling something, it helps to mention the
version of the compiler you're using, your platform, the version of
Tango (in this case) and what the error actually is.

 2. Compile D code using Tango Regex by GDC emit lots of link errors.
 
 3. Bug in Tango atomicIncrement, atomicDecrement:
 
 int task_done = 0;
 atomicIncrement(task_done);
 
 That function is compiled in asm:
 lock inc byte ptr[task_done];
 Which is wrong. It'll wrap to 0 at 255.
 It should be: lock inc dword ptr[task_done];
 
 4. There is no atomicAdd(ref original, int newvalue) family. GCC
 equivalence is __syn_fetch_and_add ...

  -- Daniel


Re: Newbie question: COM programming and linking to Windows libraries

2009-03-11 Thread Daniel Keep


Patrick Kristiansen wrote:
 ...
 
 Now, this is probably obvious to some people - but not to me. Why doesn't 
 this work? Why does OPTLINK fail and tell me that the format of the .lib file 
 is wrong? Is it because Digital Mars compilers produce .lib files in a 
 different format? Is it because I have the 64 bit SDK installed, and DMD and 
 optlink only produce and consume 32 bit object files and libraries?
 
 Please enlighten me ;-)
 
 Thanks in advance.
 
 -Patrick

The DM toolchain produces and consumes OMF object files, while I suspect
the SDK uses COFF.  Also, the toolchain is 32-bit, not 64-bit.

There's a tool called implib which can generate a .lib file that
DMD/OPTLINK can use.

Documentation is here: http://www.digitalmars.com/ctg/implib.html.

You can get it by going to http://www.digitalmars.com/, clicking on
Download Digital Mars C compiler, accept the agreement, and then
scroll down to Basic Utilities.

  -- Daniel


Re: array and pointer

2009-03-05 Thread Daniel Keep


takeshi wrote:
 Hello, I have just started learning D.
 
 I cannot compile the code in the documentation on array and pointer
 either with dmd (D 2.0) and gdmd (D 1.0).
 
 Is some compile option or cast required?
 
 int* p;
 int[3] s;
 p = s;

If that's the example, then it's out of date.  It should be this:

int* p;
int[3] s;
p = s.ptr;

  -- Daniel


Re: Reading and writing Unicode files

2009-02-28 Thread Daniel Keep


jicman wrote:
 Ok, the only reason that I say Unicode is that when I open the file in 
 Notepad and I do a SaveAs, the Encoding says Unicode.  So, when i read this 
 file and I write it back to the another file, the Encoding turns to UTF8.  I 
 want to keep it as Unicode.

There is no such thing as a Unicode file format.  There just isn't.  I
know the option you speak of, and I have no idea what it's supposed to
be; probably UCS-2 or UTF-16.

 I will give the suggestion a try.  I did not try it yet.  Maybe Phobos should 
 think about taking care of the BOM byte and provide support for these 
 encodings.  I am a big fan of Phobos. :-)  I have not tried Tango yet, 
 because I would have to uninstall Phobos and I have just spend two years 
 using Phobos and we already have an application based in Phobos and changing 
 back to Tango will slow us down and put us back.  Maybe version 2.0.

There's std.stream.EndianStream, which looks like it can read and write
BOMs.  As for converting between UTF encodings, std.utf.

  -- Daniel


Re: Dynamic Array Garbage collection

2009-02-24 Thread Daniel Keep


wolftousen wrote:
 I have a function defined as:
 
 some_function(int[] array) { ... };  //this function does not ever modify 
 values of array
 
 When I call this function (once every program cycle) from an object using an 
 array of type short:
 
 //member variable in an object
 short[] x = new short[4];
 
 //object calls this
 some_function([ x[0], x[1], x[2], x[3] ]);
 
 After a few seconds of the program running, x[0] and x[1] values are set to 0 
 and a couple values of another array in the object are modified as well.
 
 I have found that this bug is corrected by calling delete at the end of 
 some_function of the variable array.  This tells me that the garbage 
 collector is acting funny if I do not call delete on the array.  (I have 
 watched the memory usage of the program and it doesn't fluctuate or pause or 
 anything to signal the freeing/allocating of memory)
 
 Any Idea what is going on?

This sounds like something else is going on, although what I'm not sure.
  Maybe it's because I just woke up, but I can't see how that code could
compile anyway, since you can't pass a short[] to a function expecting
an int[].  Do you have a minimal, reproducible test case we can look at?

  -- Daniel


Re: Generic functions to convert to void* and from void*

2009-02-24 Thread Daniel Keep

TSalm wrote:
 In my case, there's also no possibility to get the wrong type, because
 it is managed by the type of the ColumnMem.

You still have to get the code right.  There's a surprising number of
corner cases trying to store arbitrary types.

 And about Object, if I want to store base type like int,double,etc...,
 if I do something like :
 
  Object o;
  int a = 30 ;
  o = cast(Object) a ;
 
 is this syntax is GC safe ?

It's not safe, period.  If the compiler lets you do that, I'd be
tremendously surprised; even more surprised if it doesn't cause major
problems later.  This is what I'm worried about; you're doing dangerous
things with a type system you don't understand.  Don't do this.

Here's the problem: void* isn't going to work for everything.  It'll
work for Object references, other pointers, and that's it.  You can't
store arrays, and you can't store value types like structs or primitive
types.  For that, you need to allocate heap storage, copy the value and
then store the pointer to that.  Oh, and don't forget that fixed-length
arrays have value semantics whereas dynamic arrays and slices have
reference semantics; although you generally solve that issue by having a
special template for your type which rewrites T[n] as T[].  Also,
delegates won't fit, but function pointers will.

This is why I was pointing you at Variant because I already went through
the trouble to solve all this once.  :P

If you still want to do this with void*, build that code in isolation
and test the heck out of it.

  -- Daniel


Re: Any way to track memory allocations?

2009-02-24 Thread Daniel Keep


wade wrote:
 Thanks again for all the help.  I found what the problem was and it wasn't 
 obvious (at least to me):
 
 float[uint] arr;
 
 foreach (uint k; arr.keys)
 {
  ...
 }
 
 Changing this to:
 
 foreach (uint k, float v; arr)
 {
 
 }
 
 fixes the leak.  I guess the keys array is constructed on the fly?
 
 wade

Yup.

It's a pity that we don't have, oh I don't know, some sort of efficient
iterable interface that doesn't cause a heap allocation that the runtime
could use instead *cough*hint*cough*andrei*cough*ranges*cough*.

  -- Daniel


Re: Dynamic Array Garbage collection

2009-02-24 Thread Daniel Keep


Jarrett Billingsley wrote:
 On Tue, Feb 24, 2009 at 6:45 PM, Daniel Keep
 daniel.keep.li...@gmail.com wrote:
 
  Maybe it's because I just woke up, but I can't see how that code could
 compile anyway, since you can't pass a short[] to a function expecting
 an int[].
 
 You missed the array literal.

I saw that, but thought that it would be a short[] literal since it's
usually the type of the first argument.

  -- Daniel


Re: Any way to track memory allocations?

2009-02-24 Thread Daniel Keep


Jarrett Billingsley wrote:
 On Tue, Feb 24, 2009 at 8:23 PM, Daniel Keep
 daniel.keep.li...@gmail.com wrote:
 
 Yup.

 It's a pity that we don't have, oh I don't know, some sort of efficient
 iterable interface that doesn't cause a heap allocation that the runtime
 could use instead *cough*hint*cough*andrei*cough*ranges*cough*.
 
 You can use foreach(k; aa) and foreach(_, v; aa).
 
 The thing is they're not always substitutes for .keys and .values.
 For example, if you want to modify the AA during the foreach loop, you
 have to use something like foreach(k; aa.keys) since you need a
 snapshot of the keys as they were before you started modifying it.

True; although I'm one of those people who stays up at night, plotting
the gruesome demise of invisible allocations, so I tend to do manually
create and destroy the storage for the keys.

In a perfect world, we'd have extension methods, and then we could just
do this:

RangeType!(T)[] toArray(T)(ref T this) if isRange!(T)
{
  ...
}

foreach( k ; aa.keys.toArray ) ...

My own policy is that if you have to choose between two designs, one
where you always allocate and the other where you can optionally
allocate, go for the second.

  -- Daniel


Re: Generic functions to convert to void* and from void*

2009-02-23 Thread Daniel Keep

TSalm wrote:
 I'm trying to build function which have the hability to convert a type
 to void* and from void*.

 First of all, I have to ask: have you looked at std.variant /
 tango.core.Variant?

 Yes, but it seems that Variant class uses more memory than void* .

The Phobos Variant will use however much space you reserve as the
maximum, plus 4 bytes for a function pointer, but it can only store
types as big as you allow for.  The Tango version will use
max(real.sizeof,void[].sizeof) + 4 bytes for the typeid and can store
anything you throw at it.

For that extra space, both of these will give you runtime type safety,
meaning you can't accidentally get the types wrong.  They're MUCH safer
than void*.

 [...]
 
 I get the distinct impression that you're seriously over-thinking this.
  Both of these functions could be rewritten as casts.  Aside from that,
 you've given no context for me to have any idea what you're trying to
 accomplish here.

 
 I'm really a newbie concerning the use of void* ( I think you have
 notice this ;-)  )
 Thanks for your usefull remarks.

void* is just a pointer like any other.  It doesn't have any special
properties except that you cannot dereference it; that's it.  If you're
not sure how to use pointers, then don't.

For example, you could store objects instead; this takes the same amount
of storage in the DBMS, and allows for safe casting back to the original
type.  Plus, you don't have to stuff about with casting things to void*
and back.

 I'm simply trying to make a little and lightweight DBMS in memory.
 Simply made by classes like TableMem, RowMem and ColumnMem(T).
 There's also a private class which aims to store datas, using void*[][].

Unless you really need to store small value types like integers, etc. in
that private data, objects might be the best bet for now.

  -- Daniel


Re: Generic functions to convert to void* and from void*

2009-02-22 Thread Daniel Keep


TSalm wrote:
 
 I'm trying to build function which have the hability to convert a type
 to void* and from void*.

First of all, I have to ask: have you looked at std.variant /
tango.core.Variant?

 I must use ref in the toPtr function because of this :
 http://www.digitalmars.com/pnews/read.php?server=news.digitalmars.comgroup=digitalmars.D.learnartnum=15600


 Do you think that what I done is correct ?


 /* - CODE - */

 /***
   * Convert a value to a void*
   * Params:
   * val =
   * Returns:
   */
 void* toPtr(T)(ref T val)
 {
void* p ;

static if ( is( T b : Type ) )

What is this test doing?  You're checking to see if T can be implicitly
cast to Type... but Type isn't defined.  And what is 'b' doing there?

{
  p = new T ;
  p = val ;

You never use the freshly-allocated T.  You assign it to p and then
immediately overwrite it with val.

}
else
{
  p = val ;
}

return p ;
 }

So the function is basically doing this:

T fromPtr(T)(ref T val)
{
return val;
}

 /***
   * Convert a void* to his value
   * Params:
   * ptr =
   * Returns:
   */
 T fromPtr(T)(void* ptr)
 {
return *(cast(T*)ptr) ;
 }
 /* --- END CODE  */

 
 I've forget to say that toPtr can't be call with constants.

I get the distinct impression that you're seriously over-thinking this.
 Both of these functions could be rewritten as casts.  Aside from that,
you've given no context for me to have any idea what you're trying to
accomplish here.

  -- Daniel


Re: Symbol undefined on interface with public getter and package setter

2009-02-20 Thread Daniel Keep


TSalm wrote:

 I'm not sure but I think package is not virtual.
 
 :-(
 So there's really no way to have a method declared package in an
 interface ?

You also can't have a private function in an interface.  This once lost
me four days trying to figure out why my program wouldn't link despite
the function very obviously being there.

Stick to public functions only.

  -- Daniel


Re: Unicode problems?

2009-02-16 Thread Daniel Keep


Trass3r wrote:
 Wikipedia states that D still has some Unicode problems:
 Operations on Unicode strings are unintuitive (compiler accepts Unicode
 source code, standard library and foreach constructs operate on UTF-8,
 but string slicing and length property operate on bytes rather than
 characters).
 
 Is this information correct?

They're not bugs, if that's what you mean.  It's just a side-effect of
how Unicode works.

http://www.prowiki.org/wiki4d/wiki.cgi?DanielKeep/TextInD

Long story short: they operate on bytes because operating on actual code
points can't be done efficiently [1].

  -- Daniel

[1] Given that strings are implemented as arrays with a given,
non-changing width and that you're not using UTF-32 which no one does
because it's too big and that we don't add some fancy caching stuff to
char[] arrays specifically, blah blah blah.


Re: get a struct member pointer

2009-02-16 Thread Daniel Keep


grauzone wrote:
 bearophile wrote:
 Daniel Keep:
 void lookup(T)(T[] s, size_t offset)
 {
   char[] text = *cast(char[]*)(cast(void*)(s[0]) + offset);
 }

 I am learning still this topic, but can't this create an aliasing
 problem, as in C?
 http://www.cellperformance.com/mike_acton/2006/06/understanding_strict_aliasing.html

 
 My theory is, that Walter's code generator is too primitive to care
 about aliasing. But I guess it's possible, that aliasing rules will be
 added later to the language, when LDC (hopefully) gets big?
 
 By the way, wtf is Daniel's code doing at all?
 
 Bye,
 bearophile

Unless I cocked it up (which is entirely possible, mind you) I'm trying
to get a pointer to the struct, cast to void* because I can never
remember if (ptr + int) multiplies the offset by (*ptr).sizeof or not,
casting THAT to a pointer to a char[], then dereferencing it to get the
value.

It is also, in a round-about way, trying to demonstrate that trying to
do this is really just not pretty and Jeffry might like to investigate
alternate ways of getting those fields.  :P

  -- Daniel


Re: Template conflict?

2009-02-15 Thread Daniel Keep


Mike L. wrote:
 Derek Parnell Wrote:
 
 On Sun, 15 Feb 2009 02:20:50 -0500, Mike L. wrote:

 Can anybody explain why I get the following error:

 test.d(28): Error: test.tblahTemplate!(uint).tblah at test.d(13) conflicts 
 with
 test.tblahTemplate!(int).tblah at test.d(13)
 tblah(3);
 It fails because of the literal '3'. The compiler cannot be sure if you
 want the 'int' or 'uint' function called because '3' matches both of them.

 You need to make the literal explicit...

  tblah(3u); -- uint call
  tblah(cast(int)3); -- int call


 -- 
 Derek Parnell
 Melbourne, Australia
 skype: derek.j.parnell
 
 But what confuses me is that it needs it for the template, but not when I 
 create blah() without templates. Why the inconsistency?

It's a side-effect of the mixins.  AFAIK, the compiler is treating those
mixins as coming from different sources.  When it encounters multiple
symbols from different sources, it's designed to be overly cautious and
assume you didn't know.

I think you can override this by changing the two mixin lines to this:

alias tblahTemplate!(uint) tblah;
alias tblahTemplate!(int) tblah;

  -- Daniel


Re: state of win32 headers?

2009-02-03 Thread Daniel Keep
akcom wrote:
 What is the state of the win32 headers?  Is there any place where I can get 
 win32 headers including winsock2?

http://www.dsource.org/projects/bindings/wiki/WindowsApi

Haven't checked on them in a while, but they should be usable.

  -- Daniel


Re: switch off GC?

2009-02-03 Thread Daniel Keep

Weed wrote:
 It is possible to disable GC?

Yes.  See std.gc or tango.core.Memory.

 That it has not been included in result binary for an increasing
 performance of ref operations and reduction of the size of the binary

I don't know what ref operations are, but odds are disabling the GC
will not alter their performance.  Disabling the GC just prevents
collections from occurring.  Collections ONLY occur during allocation,
so the only thing you'll speed up are allocations.

Whilst it's possible to replace the GC in D, it's not exactly
straightforward.  I'm not sure what the situation with Phobos is, but
last I checked, the GC is built as part of Phobos, so you would need to
make a custom version.

Tango is slightly better in this respect; the GC is compiled separately,
and is then linked in.  I also believe Tango has a stub GC that
doesn't actually do any garbage collection; you just need to link that
in instead of the proper GC.

  -- Daniel


Re: Some performance questions

2009-02-02 Thread Daniel Keep


Lars Kyllingstad wrote:
 [snip]
 From a performance
 perspective, however, it carries with it the overhead of an extra
 function call, which I'm not sure I want.
 
 -Lars

You're worried about a second function call which could potentially be
inlined, yet you're seemingly not worried about the overhead of virtual
calls or heap allocations...

Allow me to quote Donald Knuth:

 We should forget about small efficiencies, say about 97% of the time:
 premature optimization is the root of all evil.

Unless you're doing something where you *know* you're going to need
every last cycle, just go with whichever design works best.  Your
response to Jarrett implies that you've already got a design in mind,
and are just fishing for a magic make it go faster button.

Believe me, if Walter had invented such a thing, he wouldn't be wasting
his time putting up with us; he'd be too busy smoking $100 bills from
the comfort of his SPACE FORTRESS.  :D

In any case, I'm willing to bet that if there *are* inefficiencies
you're not going to know exactly where until you've written the code,
anyway.  :P

If classes work, and make for an elegant design, go for it.

  -- Daniel


Re: Segmentation error at the end problem (148 line program listing)

2009-01-31 Thread Daniel Keep


grauzone wrote:
 The garbage collector isn't guaranteed to to free and destroy an
 unreachable object. That's because the GC is conservative. So if you
 want to be sure the object's resources are freed, you have to do it
 explicitly.
 
 I think you have two choices:
 1. Remove close() from the destructor, and call close() manually when
 you're done.
 2. Use scope or delete to ensure the destructor is always directly
 called, and never by the GC.
 
 
 Here's how you can use scope:
 
 {
 scope BlockFile f = new BlockFile(...);
 //... do something with f
 } //f goes out of scope, and the compiler inserts delete f;

If you're going to do that, you really should make the it a scope class
to ensure you never accidentally let the GC try to delete it.

I (and a few others) petitioned what feels like years ago for a simple
argument to dtors to distinguish between deterministic destruction
(delete/scope) and automatic destruction (GC).  Never gained any ground,
sadly.

  -- Daniel


Re: casting int[] to bool[]

2009-01-29 Thread Daniel Keep


Saaa wrote:
 This will take some time to understand.
 Things I have never used before : D
 Tuple, variadic function, template, mixin
 ..stringof(can't find this one), static if
 
 I'll read up until I understand this.
 
 One question I can ask.
 Why is that foreach loop run at compile time?
 The compiler checks for a template parameter?
 
 [snip]

Tuples are like arrays that have a fixed length, where each element can
be of absolutely any type at all.

What this means is that it potentially takes different code to access
each element of a tuple.  So when you see

 foreach( i ; Range!(4) ) foo(i);

What is actually being generated is this:

 foo(0);
 foo(1);
 foo(2);
 foo(3);

It's not really doing the foreach at compile time, but it is unrolling
it.  You might think but why doesn't this happen for arrays?  Because
you can't do THIS with arrays:

 foreach( i,x ; Tuple!(0, b, 3.0) ) writefln(Element %s == %s,i,x);

Which expands to:

 writefln(Element %s == %s,0,0);
 writefln(Element %s == %s,1,b);
 writefln(Element %s == %s,2,3.0);

 -- Daniel


Re: Moving from C to D

2009-01-28 Thread Daniel Keep


bob wrote:
 do IN become in maybe?
 
 BLS Wrote:
 
 BCS wrote:
 Reply to bob,

 sorry i copy wrong line. how do i do this line:

 int PASCAL FAR mycnt ( IN SOCKET s, IN const struct sockaddr FAR *name, 
 IN int namelen );
 bob Wrote:

 step 1 would be get the output from the preprocessor and take a look at 
 it. I'm guessing that PASCAL, FAR and IN are macros

 step 0 is try htod:   http://www.digitalmars.com/d/1.0/htod.html


 I think
 int PASCAL FAR mycnt()
 becomes :
 extern (Pascal) int mycnt()

 The FAR* thingy seems to be a 16 bit relict...

 Guess the IN is not nessesary in D..., not sure though

 Bjoern
 

in means pass argument by value, and is the default for arguments.

Also, I believe that PASCAL is the same as the Windows cc, so my guess
at the conversion would be:

For D 1.x:

extern(Windows) int mycnt ( SOCKET s, sockaddr* name, int namelen );

For D 2.x:

extern(Windows) int mycnt ( SOCKET s, const sockaddr* name, int namelen );

Note that you'd have to supply definitions of SOCKET and sockaddr.

  -- Daniel


Re: Prevent default-initialised struct

2009-01-28 Thread Daniel Keep

grauzone wrote:
 Use a class instead.

That would defeat the purpose of defining a non_null template in the
first place.

  -- Daniel


Re: Moving from C to D

2009-01-28 Thread Daniel Keep


BLS wrote:
 Daniel Keep wrote:
 [snip]

 Also, I believe that PASCAL is the same as the Windows cc, so my guess
 at the conversion would be:

 For D 1.x:

 extern(Windows) int mycnt ( SOCKET s, sockaddr* name, int namelen );

 For D 2.x:

 extern(Windows) int mycnt ( SOCKET s, const sockaddr* name, int
 namelen );

 Note that you'd have to supply definitions of SOCKET and sockaddr.

   -- Daniel
 
 I am pretty sure that PASCAL means  __pascal
 
 so the D1 translation is :
 extern (Pascal) int mycnt ( SOCKET s, sockaddr* name, int namelen );
 
 See :http://www.digitalmars.com/d/1.0/htomodule.html  at the bottom
 
 Bjoern

Aah yes; I didn't realise Pascal was defined; I thought it was limited
to C, D, Windows and System for D1, adding C++ for D2.

  -- Daniel


Re: Is there a way to remove the requirement for parenthesis?

2009-01-28 Thread Daniel Keep


Charles Hixson wrote:
 Suppose that you have four types, equivalent to, say, float.
 Call one of them Horiz, one Vertic, one Radians, and one Radius.
 These are all floats, but when you specify, say,
 float dist (Horiz x, Vert y)
 {  return sqrt(x * x + y * y);  }
 It's important that the arguments aren't Radius and Radians.  Or Horiz
 and Horiz.
 
 [snip]

There's no problem with that: make them structs that implement the
appropriate operators.

See, what I don't get (note: this is how I perceive it) is the desire to
have this sort of type protection, but require the compiler to somehow
be psychic in order to know when and where you don't care and throw it away.

You either have distinct types that aren't automatically compatible, or
you don't.

  -- Daniel


OT: Alan Turing [Was: Re: halting problem :)]

2009-01-27 Thread Daniel Keep

Alan Turing wrote:
 Maybe I can help...

At first glance, this might look like someone being silly and not at all
helpful... but in truth, Mr. Turing has probably already fixed your
source code with his incredible powers.  If you notice your firewall has
melted into a pile of slag, and your PC seems to be running a lot
faster, that'd be him.

Most people seem to think he's dead; this is only partially true.
Whilst his physical body died, his mind lives on in the Internet, ever
vigilant to ensure the safe delivery of our daily LOLCATs.

Some other random Alan Turing facts:

* The only reason Alan Turing hadn't solved the halting problem is that
it was too busy running from him in fear.
* Alan Turing could tell what a RAM chip contains simply by smelling it.
* Alan Turing programmed computers in raw machine code, using a
magnetised pin.
* Alan Turing didn't bother programming; he just stared at a computer
until it submits to his will.
* Alan Turing only designed the bombe because he just stared at
ciphertexts for 10 seconds and wrote down the plaintext wouldn't make
for an interesting documentary 70 years later.
* Steve Ballmer lives in perpetual fear of the day Alan Turing will
return to unmake Microsoft.
* When Alan Turing crashes a machine, all the other machines on the same
subnet dump core out of fear.
* Alan Turing can break RSA encryption up to 4096 bits; he doesn't
bother because it's not challenging enough.
* Alan Turing knows what you were browsing last summer.

  -- Daniel insomnia is a terrible thing... Keep


Prevent default-initialised struct

2009-01-26 Thread Daniel Keep
Hi all,

is there any way to prevent a struct from being created directly?
Basically, I want to prevent this:

{
  non_null!(T) a;
}

I want people to have to use provided functions to create a structure:

{
  auto a = non_null!(T)(new T);
}

  -- Daniel


Re: Class and Interface Fun

2009-01-25 Thread Daniel Keep


 [snip]

 B inherits all the functions from A implicitly. You stil may
 override any of the I interface functions if need be:

 class B : A, I
 {
  override void foo() { ... }
  // int bar() is inherited from A
 }

 Having B explicitly override all the base class virtual functions
 and forward them to A implementation just to make compiler happy is
 unintuitive and plain dumb to me.

 C# allows that and I see absolutely no reason why D doesn't.


 I think you are missing somethinghere. Change the B definition from:

 class B : A, I

 to just:

 class B : A

 then interfaces become impicit.

 No, I don't:

 class B : private A, public I
 {
 }


 
 Other example:
 
 interface IOStream : InputStream, OutputStream
 {
 }
 
 class A : InputStream
 {
   // implement InputStream
 }
 
 class B : A, IOStream
 {
   // implement OutputStream interface *only*
 }
 
 You can't define B like this: class B : A, OutputStream { ... } because
 this way it won't be castable to IOStream.
 

I believe the rationale behind this is so that you can't implement an
interface by accident.  For example, you might be implementing an
interface, miss one method, and not know because the base class
implements it.

Alternately, you might be relying on such inheritance.  Then, the base
class changes, and you're left with compile errors and wondering why it
doesn't work.

Forcing you to specify each method removes this ambiguity from the code.

That said, I could have SWORN that aliasing a method from the superclass
worked.  If this isn't a bug, it should be.

Personally, yes it is a bit tedious, but this is why we have templates
and mixins...

  -- Daniel


Re: C++ operator new

2009-01-25 Thread Daniel Keep

This might also be of interest, as it has an example of overriding
allocation/deallocation to use malloc:

http://digitalmars.com/d/1.0/memory.html#newdelete


Re: How to get the implementer of an interface?

2009-01-22 Thread Daniel Keep


Qian Xu wrote:
 Hello All,
 
 how to get the implementer of an interface?
 
 Here is an example:
 -
 interface intf_1 {}
 class c_1 : intf_1 {}
 class c_2 : c_1 {}
 
 c_1 aaa = new c_1;
 c_2 bbb = new c_2;
 auto list = [cast(intf_1)(bbb), cast(intf_1)(aaa)];
 foreach (intf_1 i; list)
 {
   print_intf_implementor(i);
   // bbb should return c_2
   // aaa should return c_1
 }
 -
 
 
 --Qian

I don't think you can.  i.classinfo returns intf_1's ClassInfo.  Also,
the only two bits of hidden information on an object are the monitor
object and the vtable, so I don't know that you could use those, either.

Of course, I could be wrong.

  -- Daniel


Re: how to use dll

2009-01-21 Thread Daniel Keep


reimi gibbons wrote:
 Hi all,
 
 I'm currently developing a software with D and Tango. I don't have much 
 knowledge on DLL, but i do know when linking to static lib you need a .h 
 header file, but do i need .h for linking with DLL as well?
 
 also can anybody please provide a quick and small example to link with DLL.
 
 *im trying to link my software with ICU lib, since mango seems outdated.
 
 Thanks,
 Reimi.

You need two things to link to a DLL:

1. You need the interface of the DLL.  In C/C++, this is provided by .h
files; in D, this is simply provided by a D module.

2. Loader code.

You can either roll your own, or generate the above two.  You can use
htod (it's somewhere on the official D pages) which tries to convert a C
header file into a D import module.

As for the loader code, you can either write a dynamic loader, or just
use implib on the DLL to generate one (I think; it's been a while since
I've had to roll one.)

If I can remember more specific details, I'll post again, but that's the
basic gist of it.

  -- Daniel


Re: loop through specific class members

2009-01-19 Thread Daniel Keep
Trass3r wrote:
 Is there any way to loop through specific members of a class, e.g. all
 public functions?
 I've already seen a function getMembers in druntime's ClassInfo class
 but I can't find anything related to the attributes there.

Assuming you're using D2, http://digitalmars.com/d/2.0/traits.html might
prove to be of interest.

  -- Daniel


Re: time measurement under linux?

2009-01-19 Thread Daniel Keep


Trass3r wrote:
 I wrote a module to ease time measurement in my projects.
 Does anyone know how to get elapsed milli- or nanoseconds under linux?
 Want to make it portable :)
 [snip]

Check std.perf; it's documented, but sadly doesn't show up in the docs.

  -- Daniel


Re: loop through specific class members

2009-01-19 Thread Daniel Keep


BCS wrote:
 Reply to Daniel,
 
 
 It depends on what exactly you're trying to do.  Some time ago, I
 wrote a library that created XML loaders for structs, and it needed to
 know the names of fields.  Pre-traits, this is what I used:

 struct Stuff
 {
 int foo;
 char[] bar;
 alias Tuple!(foo, bar) _fields;
 }
 Then I just looped over _fields.

 -- Daniel

 
 you can get the names even in D1.0. Not exactly clean but...
 
 http://codepad.org/Eu16XqFu

I remember trying that, but abandoning it for some reason.  This code is
getting old now; over two years now, so that might not have worked back
then.

  -- Daniel


Re: array questions

2009-01-11 Thread Daniel Keep



yes wrote:

[snip]
also, can this be done?

int size;
size = 10; //runtime
void function( int[size][] array){}

No, static arrays are static, i.e. compile time.

I meant it to be an dynamic array argument, but that the function wouldn't need 
to check the size of all the elements itself.


Dynamic arrays do not have a fixed size, thus code needs to check the 
number of elements when it uses them.


Static arrays have a fixed size, but that size MUST be fixed at compile 
time.


You can convert static arrays into dynamic arrays, but not the other way 
around (at least, not without copying the contents).


When you compile with the -release flag, it disables range checking. 
You can also avoid it by going via pointers, but that's just asking for 
trouble.


  -- Daniel


Re: Foreach problem

2009-01-10 Thread Daniel Keep



Tim M wrote:


Why is this an error. Dmd wants to make sure that I declare a new 
variable in the foreach statement and not use an existing one?


module test;

void main()
{
int i;
int[] nums;
foreach(i; nums)
{
//
}
}


dmd test.d

test.d(7): Error: shadowing declaration test.main.i is deprecated


Yes; as the error states, you're not allowed to define variables with 
the same name as variables in an enclosing scope any more.


  -- Daniel


  1   2   >