Re: an extremely naive question regarding synchronized...

2016-11-15 Thread Kapps via Digitalmars-d-learn

On Monday, 14 November 2016 at 17:43:37 UTC, WhatMeWorry wrote:


I was reading this fasciniating article:

https://davesdprogramming.wordpress.com/2013/05/06/low-lock-singletons/

And to quote a section of it:
-
static MySingleton get() {
synchronized {
  if (instance_ is null) {
instance_ = new MySingleton;
  }
}
return instance_;
  }

Now, if Thread 1 calls get(), it has a chance to finish 
instantiating instance_ and storing a reference to it before 
Thread 2 checks whether instance_ is null.  There’s only one 
problem with this:  It comes at a huge performance cost 
(benchmarks forthcoming).  Entering a synchronized block is 
expensive.

-

Why is the synchronized block so expensive?  Isn't it just 
doing one conditional and a new command?  Again, to my naive 
way of thinking, this seems like a very small blocking window.


And the graph shows 1B get() calls.  I assume B stands for 
billion.  What use case would require so many gets?


Thanks.


Keep in mind, this is only slow for such a large amount of calls.
If you're calling this only a hundred times a second, then who 
cares if it's slower. After all, with GDC we were looking at 1 
billion calls in 21 seconds. That's 47,000 calls per 
*millisecond*.


Re: newbie problem with nothrow

2016-10-31 Thread Kapps via Digitalmars-d-learn

On Monday, 31 October 2016 at 17:04:28 UTC, Temtaime wrote:

On Monday, 31 October 2016 at 16:55:51 UTC, WhatMeWorry wrote:


Is there a way to turn off nothrow or work around it? Because 
to me it looks like nothrow prevents me from doing anything 
useful.


extern(C) void onKeyEvent(GLFWwindow* window, int key, int 
scancode, int action, int modifier) nothrow

{
if(queue.roomInQueue())
{
auto event = new Event;
event.type = EventType.keyboard;
event.keyboard.key = cast(Key) key;

// etc.
}

Error: function 'event_handler.CircularQueue.roomInQueue' is 
not nothrow
Error: function 'event_handler.onKeyEvent' is nothrow yet may 
throw



The compiler wouldn't let me just remove "nothrow" from the 
function. I tried a kludge where I had this function just pass 
all its parameters to another throwable function, but this 
caused errors as well.


So I'm stuck.  Anyone know how to proceed.
Thanks.


Wrap a body of the function to try {} catch {} and it'll work.


Assuming you're sure it'll never throw. To enforce this, use try 
{ } catch { throw new Error("blah"); }. You can still throw 
errors, just not exceptions (as errors are not meant to be 
caught).


Re: How to debug (potential) GC bugs?

2016-09-27 Thread Kapps via Digitalmars-d-learn
On Sunday, 25 September 2016 at 16:23:11 UTC, Matthias Klumpp 
wrote:

Hello!
I am working together with others on the D-based 
appstream-generator[1] project, which is generating software 
metadata for "software centers" and other package-manager 
functionality on Linux distributions, and is used by default on 
Debian, Ubuntu and Arch Linux.


For Ubuntu, some modifications on the code were needed, and 
apparently for them the code is currently crashing in the GC 
collection thread: http://paste.debian.net/840490/


The project is running a lot of stuff in parallel and is using 
the GC (if the extraction is a few seconds slower due to the GC 
being active, it doesn't matter much).


We also link against a lot of 3rd-party libraries and use a big 
amount of existing C code in the project.


So, I would like to know the following things:

1) Is there any caveat when linking to C libraries and using 
the GC in a project? So far, it seems to be working well, but 
there have been a few cases where I was suspicious about the GC 
actually doing something to malloc'ed stuff or C structs 
present in the bindings.


2) How can one debug issues like the one mentioned above 
properly? Since it seems to happen in the GC and doesn't give 
me information on where to start searching for the issue, I am 
a bit lost.


3) The tool seems to leak memory somewhere and OOMs pretty 
quickly on some machines. All the stuff using C code frees 
resources properly though, and using Valgrind on the project is 
a pain due to large amounts of data being mmapped. I worked 
around this a while back, but then the GC interfered with 
Valgrind, making information less useful. Is there any 
information on how to find memory leaks, or e.g. large structs 
the GC cannot free because something is still having a needless 
reference on it?


Unfortunately I can't reproduce the crash from 2) myself, it 
only seems to happen at Ubuntu (but Ubuntu is using some 
different codepaths too).


Any insights would be highly appreciated!
Cheers,
   Matthias

[1[: https://github.com/ximion/appstream-generator


First, make sure any C threads calling D code use 
Thread.attachThis (thread_attachThis maybe?). Otherwise the GC 
will not suspend those threads during a collection which will 
cause crashes. I'd guess this is your issue.


Second, tell the GC of non-GC memory that has pointers to GC 
memory by using GC.addRange / GC.addRoot as needed. Make sure to 
remove them once the non-GC memory is deallocated as well, 
otherwise you'll get memory leaks. The GC collector is also 
conservative, not precise, so false positives are possible. If 
you're using 64 bit programs, this shouldn't be much of an issue 
though.


Finally, make sure you're not doing any GC allocations in dtors.


Re: Proper way to work around `Invalid memory operation`?

2016-09-27 Thread Kapps via Digitalmars-d-learn
On Sunday, 25 September 2016 at 16:07:12 UTC, Matthias Klumpp 
wrote:

Hello!

I have a class similar to this one:
```
class Dummy
{

private:

string tmpDir;

public:

this (string fname)
{
tmpDir = buildPath ("/tmp", fname.baseName);
std.file.mkdirRecurse (tmpDir);
}

~this ()
{
close ();
}

void close ()
{
if (std.file.exists (tmpDir))
std.file.rmdirRecurse (tmpDir);
}
}
```

When the GC calls the classes destructor, I get a
`core.exception.InvalidMemoryOperationError@/<...>/ldc/runtime/druntime/src/core/exception.d(693):
 Invalid memory operation`

Looks like rmdirRecurse tries to allocate with the GC, and the 
GC doesn't like that.
Is there any good way to get the temporary directory deletet 
automatically when the object is freed?
At time, I work around this bug by calling close() manually at 
the appropriate time, but this feel like a rather poor solution.


Cheers,
Matthias


As seen, you can't make GC allocations in dtors. And you should 
never rely on the GC calling your dtor to close things like file 
handles anyways. Consider making Dummy a struct and maybe using 
std.typecons(?).RefCounted with it.




Re: Simple performance question from a newcomer

2016-02-21 Thread Kapps via Digitalmars-d-learn

On Monday, 22 February 2016 at 07:10:23 UTC, Kapps wrote:
If you do want to test the differences between the range 
approach and the loop approach, something like:

auto sumtest4(Range)(Range range) @safe pure {
return range.reduce!((a, b) => a + b);
}
is a more fair comparison. I get results within 15% of sumtest2 
with this using dmd. I think with ldc this would be identical, 
but the version in homebrew is too old to compile this.


Using LDC with the mir version of ndslice so it compiles, and the 
following code:

sw.reset();
sw.start();
foreach (unused; 0..times) {
for (int i=0; i<N; ++i) {
res4[i] = sumtest4(f[i]);
}
}
t3 = sw.peek().msecs;

and

auto sumtest4(Range)(Range range) {
return range.reduce!((a, b) => a + b);
}

I get:
145 ms
19 ms
19 ms
19 ms

So, with LDC, there is no performance hit doing this. The only 
performance hit is when .sum uses a different algorithm for a 
more accurate result. Also, the LDC version appears to be roughly 
5x faster than the DMD version.


Re: Simple performance question from a newcomer

2016-02-21 Thread Kapps via Digitalmars-d-learn
If you do want to test the differences between the range approach 
and the loop approach, something like:

auto sumtest4(Range)(Range range) @safe pure {
return range.reduce!((a, b) => a + b);
}
is a more fair comparison. I get results within 15% of sumtest2 
with this using dmd. I think with ldc this would be identical, 
but the version in homebrew is too old to compile this.


Re: Is this nogc? dmd and gdc disagree

2016-02-13 Thread Kapps via Digitalmars-d-learn

On Saturday, 13 February 2016 at 00:41:35 UTC, tsbockman wrote:

On Friday, 12 February 2016 at 23:46:09 UTC, Kapps wrote:
You'll encounter this pretty often in Phobos I think. I really 
don't think @nogc is ready, and tend to avoid it in my code. 
Exceptions are a big reason for it, and lots of functions in 
Phobos throw exceptions which prevents them from being used in 
@nogc (barring ugly hacks). I don't want to discourage you 
before you try it, but I feel like @nogc is not yet worth 
using until something is done about issues such as exceptions, 
allowing Phobos to properly be able to handle @nogc.


On the other hand... Realistically, the only way that Phobos 
will reach usability with @nogc, is if people keep trying and 
complaining when something doesn't work that should.


I guess the problem is that a lot of this stuff requires RC 
exceptions to be realistically fixable. (Not this case though.)


Yeah. I originally intended to go through and make what I needed 
@nogc, but then I realized that it was pointless thanks to 
exceptions. Hopefully one day...


Re: Is this nogc? dmd and gdc disagree

2016-02-12 Thread Kapps via Digitalmars-d-learn

On Thursday, 11 February 2016 at 12:41:16 UTC, rcorre wrote:

On Thursday, 11 February 2016 at 04:20:13 UTC, tsbockman wrote:

On Thursday, 11 February 2016 at 03:09:51 UTC, rcorre wrote:
I recently tried compiling enumap with GDC, and found that it 
disagrees with DMD on whether a function is @nogc. Here's a 
semi-reduced test-case:


Here's an @nogc version of `byKeyValue()`:

@nogc auto byKeyValue() const {
  static immutable keys = [EnumMembers!K];
  return zip(keys[], _store[]);
}

Using zip and slices guarantees that the structure returned 
will be only 5*size_t.sizeof bytes, regardless of the types of 
K and V.


I'm on the DMD 2.070 release, so maybe its fixed in master.
Either way, thanks for the suggestion!
Somehow I didn't realize what I was doing was an 
over-complicated zip :)


You'll encounter this pretty often in Phobos I think. I really 
don't think @nogc is ready, and tend to avoid it in my code. 
Exceptions are a big reason for it, and lots of functions in 
Phobos throw exceptions which prevents them from being used in 
@nogc (barring ugly hacks). I don't want to discourage you before 
you try it, but I feel like @nogc is not yet worth using until 
something is done about issues such as exceptions, allowing 
Phobos to properly be able to handle @nogc.


Re: nogc Array

2016-01-25 Thread Kapps via Digitalmars-d-learn

On Tuesday, 26 January 2016 at 04:31:07 UTC, Igor wrote:

On Tuesday, 26 January 2016 at 03:06:40 UTC, maik klein wrote:

On Tuesday, 26 January 2016 at 03:03:40 UTC, Igor wrote:
Is there a GC-less array that we can use out of the box or do 
I have to create my own?


https://dlang.org/phobos/std_container_array.html


How do we use std.algorithm with it? I could like to use find 
but I have no luck.


I have

std.container.array!MyClass classes;

then std.algorithm.find!("a.myInt == b")(classes, 3)

I was hoping this would find the first object in classes who 
has myInt == 3 but I just get many errors about not being able 
to find the right definition.


I guess std.container.array isn't a range? Or am I using it 
wrong?


First, should be std.container.array.Array!MyClass. However I 
don't think(?) that the Array struct is a range itself, you might 
have to use classes[] instead to get a slice of the array.


Re: Voldemort Type Construction Error

2016-01-15 Thread Kapps via Digitalmars-d-learn

On Friday, 15 January 2016 at 20:04:47 UTC, Nordlöw wrote:

On Friday, 15 January 2016 at 16:51:24 UTC, Anon wrote:

On Friday, 15 January 2016 at 14:04:50 UTC, Nordlöw wrote:

What have I missed?


In line 126, `static struct Result()` is a template. Either 
drop the parens there, or change the call on line 187 to 
`Result!()(haystack, needles)`.


Ahh, annoying mistake.

Why is this allowed?

/Per


At least for functions, making them templates provides some 
benefits like inferring attributes. Not sure if it behaves the 
same way on structs by making all functions within it templates.




Re: question about the implementation of Variant

2016-01-04 Thread Kapps via Digitalmars-d-learn

On Monday, 4 January 2016 at 09:13:25 UTC, Jonathan M Davis wrote:
On Monday, January 04, 2016 07:30:50 aki via 
Digitalmars-d-learn wrote:

But wait, how does GC detect there still be a live reference to
the object Foo?
Because store is just a fix sized array of bytes.
ubyte[size] store;
GC cannot be aware of the reference, right?


As I understand it, the GC doesn't actually care about whether 
something is a pointer when it tries to figure out whether 
something refers to something - or at least, it'll treat 
integers as if they were pointers so that if you tried to do 
something like


size_t i;
{
auto p = new int(5);
i = cast(size_t)p;
}
// GC will not collect p even if it runs now

then the fact that i matches the value of the address that p 
points to is enough for the GC to not collect the memory 
pointed to by p, even if there are no longer any pointers 
referring to it. This prevents problems when you do stuff like 
cast pointers to integers to store their values (which normally 
is crazy but on rare occasions makes sense). The downside is 
that the GC then has to treat all integers as if they were 
pointers, so if you have an integer whose value happens to 
match that of a memory address in GC-allocated memory (a so 
called false pointer), then that memory won't be freed, even if 
nothing is really pointing to it anymore. Fortunately, however, 
false pointers are primarily limited to 32-bit programs, and 
64-bit programs don't have that problem because of how large 
their address space is (but 32-bit programs which allocate most 
of their address space can definitely run into problems where 
memory that should be freed isn't thanks to false pointers).


- Jonathan M Davis


That's only because we don't have a precise garbage collector and 
can't be relied upon. It's more of a bug / limitation rather than 
something to actually use.


In the case of std.variant, it's not just byte[size] store, it's 
actually a union:


union
{
ubyte[size] store;
// conservatively mark the region as pointers
static if (size >= (void*).sizeof)
void*[size / (void*).sizeof] p;
}

Which tells the garbage collector that it may be pointers there, 
making it valid even for precise garbage collectors (which would 
have to conservatively handle such a union).


Re: Speeding up text file parser (BLAST tabular format)

2015-09-14 Thread Kapps via Digitalmars-d-learn

On Monday, 14 September 2015 at 18:31:38 UTC, H. S. Teoh wrote:
I decided to give the code a spin with `gdc -O3 -pg`. Turns out 
that the hotspot is in std.array.split, contrary to 
expectations. :-)  Here are the first few lines of the gprof 
output:


[...]


Perhaps using the new rangified splitter instead of split would 
help.


Re: (De)Serializing interfaces

2015-08-22 Thread Kapps via Digitalmars-d-learn

On Saturday, 22 August 2015 at 19:14:16 UTC, nims wrote:
I think interfaces are very powerful and I heavily use them. 
The only problem I have with them is that 
serializing/deserializing them to XML or JSON doesn't seem to 
work. So far I got to try Orange and painlessjson. Using Orange 
all I got was a lot of compiler errors. Painlessjson did 
compile normally but just ignores all interface class members.


I've never used Orange, but one thing you could try is casting 
your object from MyInterface to Object, and registering the type 
Foobar like in 
http://dsource.org/projects/orange/wiki/Tutorials/SerializeBase, 
then serializing/deserializing it as Object rather than 
MyInterface. I'm not sure if this will work, but it's worth a try 
if it doesn't handle interfaces. Interfaces are a bit odd in some 
ways, as they are not necessarily classes (and thus not 
implicitly convertible to Object) in situations like with COM / 
extern(C++).


Re: How disruptive is the GC?

2015-07-29 Thread Kapps via Digitalmars-d-learn

On Wednesday, 29 July 2015 at 17:09:52 UTC, Namespace wrote:

On Wednesday, 29 July 2015 at 09:25:50 UTC, Snape wrote:
I'm in the early stages of building a little game with OpenGL 
(in D) and I just want to know the facts about the GC before I 
decide to either use it or work around it. Lots of people have 
said lots of things about it, but some of that information is 
old, so as of today, what effect does the GC have on the 
smooth operation of a real-time application? Is it pretty 
noticeable with any use of the GC or only if you're 
deallocating large chunks at a time?


http://3d.benjamin-thaut.de/?p=20


Note that this was 3 years ago, so there have been GC 
improvements since then. I'm not sure what the results would be 
like today (or what the code is like in terms of needless 
allocations).


That being said, you probably want to avoid the GC as much as 
possible for games. Luckily we have tools like -vgc to help with 
that now (and @nogc, but I still consider this mostly unusable 
thanks largely to exceptions).


Re: how to avoid cycle detected?

2015-07-02 Thread Kapps via Digitalmars-d-learn

On Wednesday, 1 July 2015 at 09:09:53 UTC, aki wrote:

Following code causes run-time error.
How can I use static this() without causing error?
It's difficult to avoid this situation because
actual code is more complex.

file main.d:
void main() {
}

file a.d:
import b;
class A {
static this() {}
};

file b.d:
import a;
class B {
static this() {}
};

object.Exception@src\rt\minfo.d(162): Aborting: Cycle detected 
between modules w

ith ctors/dtors:
a - b - a


An ugly solution, but the approach used in Phobos is to create 
something like a_init.d which a.d imports, provided that the 
static ctors don't actually rely on things from the static ctor 
of b.




Re: Shouldn't std.conv.emplace be @nogc?

2015-03-02 Thread Kapps via Digitalmars-d-learn

On Monday, 2 March 2015 at 12:37:33 UTC, drug wrote:
I guess the reason why std.conv.emplace is not @nogc-ed is that 
nobody added it yet? I didn't see using of gc in the emplace 
sources.


Soon:
https://github.com/D-Programming-Language/phobos/pull/2999


Re: stdio.lines doesn't have popFront, but works with foreach

2014-12-11 Thread Kapps via Digitalmars-d-learn
On Thursday, 11 December 2014 at 20:11:21 UTC, Andrew Klaassen 
wrote:
The docs for stdio.lines say that it's a struct.  stdio.lines 
works with foreach.


The docs for foreach say:

Iteration over struct and class objects can be done with 
ranges. For foreach, this means the following properties and 
methods must be defined: .empty ... .front ... .popFront()


But when I try to access any of those properties or methods for 
stdio.lines, I get compilation errors:


  1 import io = std.stdio;
  2
  3 void main(string[] args) {
  4
  5 auto infile = io.File(args[1], r);
  6
  7 auto filelines = io.lines(infile);
  8
  9 io.writeln(filelines.front);
 10 io.writeln(filelines.empty);
 11 io.writeln(filelines.popFront());
 12 }

test_filechunking.d(9): Error: no property 'front' for type 
'lines'
test_filechunking.d(10): Error: no property 'empty' for type 
'lines'
test_filechunking.d(11): Error: no property 'popFront' for type 
'lines'


Why is this?

I'm using ldc2 for compilation, FWIW.

Andrew


Ranges are one way of allowing foreach. The other is through the 
use of opApply, which is what std.stdio.lines does.


http://dlang.org/statement.html#ForeachStatement


Re: Check type is a struct at compile time?

2014-12-05 Thread Kapps via Digitalmars-d-learn

On Friday, 5 December 2014 at 20:38:31 UTC, Gary Willoughby wrote:
How can i check that a type is a struct at compile time? I know 
i can test for a class like this:


static if(is(T == class))
{
...
}

But how to do the same thing for a struct?


Same thing but with struct: is(T == struct)

Note that this returns false for things like 'int'.

Ex:

struct Foo { }

void foo(T)(T inst) {
static if(is(T == struct))
writeln(T.stringof,  is a struct);
else
writeln(T.stringof,  is NOT a struct);
}

void main() {
Foo a;
foo(a);
foo(3);
}

--

Foo is a struct
int is NOT a struct


Re: [dub] Size of executable

2014-11-28 Thread Kapps via Digitalmars-d-learn

On Thursday, 27 November 2014 at 09:33:49 UTC, Chris wrote:

[Maybe this has been asked before.]

I usually use dub to create and build projects. I built one of 
the projects with dub and then by hand with dmd[1] passing all 
the files etc. Turned out that the executable built with dub 
was 1.4 MB whereas the one built by hand was only 807 kB. Why 
is that?


Another thing, I've spotted a typo in dub's[2] command line 
help:


clean [package] Removes intermetiate build files and 
cached build

results

It should read intermediate (with d), else it sounds like 
the Goths in Asterix :-)




[1] dmd 2.066.0
[2] DUB version 0.9.22, built on Sep 16 2014


Dub builds with debug symbols by default. Using dub build -v will 
tell you how it invokes DMD.


Re: undefined reference to class template

2014-11-23 Thread Kapps via Digitalmars-d-learn

On Friday, 14 November 2014 at 23:29:34 UTC, Satoshi wrote:
Hi, Im using GDC 4.9.0 compiler. I have template classes like 
public class LinkedList(T) {...} and when I try compile it 
together, everything works fine. But when I compile every 
source file to separate object file and link it together with 
ld Ill get errors like:


/os/KernelLand/Kernel/TaskManager/Thread.d:99: undefined 
reference to 
`_D7Library10LinkedList45__T10LinkedListTC11TaskManager6Thread6ThreadZ10LinkedList6__ctorMFNaNbNfZC7Library10LinkedList45__T10LinkedListTC11TaskManager6Thread6ThreadZ10LinkedList'


Im compiling it with command like:
gdc -mcmodel=kernel -nostdlib -mno-red-zone -Wall -masm=intel 
-frelease -finline-functions -O3 -o obj-x86_64/abc.d.o -c abc.d


Here is
full error log http://pastebin.com/SjnYjqKh

makefile 
https://github.com/Bloodmanovski/Trinix/blob/dc80f3197f59fe96e9f4e29cea670ff2c7eaa342/KernelLand/Kernel/Makefile#L104


LinkedList class 
https://github.com/Bloodmanovski/Trinix/blob/dc80f3197f59fe96e9f4e29cea670ff2c7eaa342/KernelLand/Kernel/Library/LinkedList.d



Can anyone help me how to solve this problem? Thanks
(Sorry for bad english)


Sounds like you're not passing in LinkedList.d while compiling a 
file that uses it. You need to include all used files, including 
imports, on the command line when compiling. The undefined 
reference indicates it can't find the source code or di file 
containing LinkedList. Tools like rdmd do this for you by looking 
at the imports used automatically.


If not that, I'm not sure if this will help, but try using 
-femit-templates (similar to -allinst in DMD I believe?).


Besides that, all I can really suggest is double checking that 
you're actually including the object file containing LinkedList 
when you're linking and the source file when compiling.


Re: new(malloc) locks everything in multithreading

2014-10-24 Thread Kapps via Digitalmars-d-learn

On Friday, 24 October 2014 at 10:49:42 UTC, tcak wrote:

On Friday, 24 October 2014 at 10:46:57 UTC, tcak wrote:

On Friday, 24 October 2014 at 10:29:10 UTC, Kagamin wrote:
Looks like your IDE filters too much. Can you configure it to 
filter less and show address locations?


This is what I have found:

Main Thread
http://i.imgur.com/6ElZ3Fm.png

Second Thread (TestThread)
http://i.imgur.com/w4y5gYB.png


BTW, instead of using Monodevelop with Mono-D, I used same code 
on a text
file, and compiled with dmd test.d, then run with ./test, 
then everything
works fine. When I run it with gdb ./test, then I can see 
those errors again.


Not sure if this is the same issue, but by default gdb breaks on 
signals that the GC uses, which would explain why it's breaking 
in gdb but not normally.


What happens if you try:
handle SIGUSR1 noprint nostop
handle SIGUSR2 noprint nostop

In GDB before starting execution of the program?


Re: new(malloc) locks everything in multithreading

2014-10-24 Thread Kapps via Digitalmars-d-learn

On Friday, 24 October 2014 at 18:38:39 UTC, tcak wrote:

On Friday, 24 October 2014 at 16:51:02 UTC, Kapps wrote:

On Friday, 24 October 2014 at 10:49:42 UTC, tcak wrote:

Not sure if this is the same issue, but by default gdb breaks 
on signals that the GC uses, which would explain why it's 
breaking in gdb but not normally.


What happens if you try:
handle SIGUSR1 noprint nostop
handle SIGUSR2 noprint nostop

In GDB before starting execution of the program?


This is what I did on shell: (I put some spaces for readability)

tolga@tolga:~/dev/d/bug$ dmd -gc -debug test.d

tolga@tolga:~/dev/d/bug$ gdb ./test



Yes, GDB is stopping on SIGUSR1 / SIGUSR2 since that's the 
default settings. D's GC uses these signals for suspending / 
resuming threads during a collection. You need to type what I 
said above, prior to typing 'run'.


Re: Beginner ?. Why does D suggest to learn java

2014-10-21 Thread Kapps via Digitalmars-d-learn

On Thursday, 16 October 2014 at 22:26:51 UTC, RBfromME wrote:
I'm a newbie to programming and have been looking into the D 
lang as a general purposing language to learn, yet the D 
overview indicates that java would be a better language to 
learn for your first programming language. Why?  Looks like D 
is easier than Java...


Honestly, I'd recommend starting with VB.net or C# (preferably 
C#) over D, as:

1) They're simpler, no template magic, not as low level, etc.
2) Having an excellent IDE is very nice for starting out, seeing 
errors right as you type them, seeing all the methods and how to 
call them, having the documentation right there in your IDE, and 
not having to worry about whether what you just wrote is 
something that the IDE's parser can't handle or is actually 
invalid code.
3) Being significantly more popular is in general a boon, more 
tutorials are available (though D has some nice resources like 
Ali's book), and you're more likely to find a solution to a 
problem through Google as more people have come across it.
4) Having to deal with any compiler bugs would be very 
frustrating when starting to learn programming. D still has 
plenty, even if they're much less noticeable now. Trying to 
figure out why something doesn't work only to realize it's a 
compiler bug is frustrating.
5) Having a drag-and-drop GUI designer is very nice. D is still 
difficult to use for GUIs, and when starting it's really nice to 
see something significant on the screen right away.
6) You probably won't use most of D's features when you're just 
learning, so much of D's advantages are gone.


D is an awesome language, but I would not recommend it for 
someone completely new to programming. Once you get the hang of 
programming, D is an excellent language, until then something 
simpler, more popular, and more supported, would be better.


Re: Beginner ?. Why does D suggest to learn java

2014-10-21 Thread Kapps via Digitalmars-d-learn
On Tuesday, 21 October 2014 at 09:14:08 UTC, ketmar via 
Digitalmars-d-learn wrote:

On Tue, 21 Oct 2014 09:01:32 +
Kapps via Digitalmars-d-learn 
digitalmars-d-learn@puremagic.com wrote:



no template magic
that's very bad. it's time to stop making people think that 
templates

are inevitably arcane.


I like D's templates, it's one of the things that makes me like D 
more than C#. But they can definitely get quite complex. C# 
limits templates to generic types, like Listint, and for a 
beginner I think that's an easier way to handle things.


Re: Can someone explain how glfw3.dll gets created?

2014-10-13 Thread Kapps via Digitalmars-d-learn
Derelict provides bindings to C libraries, and loads them at 
runtime. So glfw3.dll is actually an existing C library (you can 
get it at http://www.glfw.org/download.html), which Derelict 
provides bindings for. Derelict / your code does not generate the 
actual dll.


Re: Threadpools, difference between DMD and LDC

2014-08-04 Thread Kapps via Digitalmars-d-learn
On Monday, 4 August 2014 at 05:14:22 UTC, Philippe Sigaud via 
Digitalmars-d-learn wrote:


I have another question: it seems I can spawn hundreds of 
threads
(Heck, even 10_000 is accepted), even when I have 4-8 cores. Is 
there:

is there a limit to the number of threads? I tried a threadpool
because in my application I feared having to spawn ~100-200 
threads

but if that's not the case, I can drastically simplify my code.
Is spawning a thread a slow operation in general?


Without going into much detail: Threads are heavy, and creating a 
thread is an expensive operation (which is partially why 
virtually every standard library includes a ThreadPool). Along 
with the overhead of creating the thread, you also get the 
overhead of additional context switches for each thread you have 
actively running. Context switches are expensive and a 
significant waste of time where your CPU gets to sit there doing 
effectively nothing while the OS manages scheduling which thread 
will go and restoring its context to run again. If you have 
10,000 threads even if you won't run into limits of how many 
threads you can have, this will provide very significant overhead.


I haven't looked into detail your code, but consider using the 
TaskPool if you just want to schedule some tasks to run amongst a 
few threads, or potentially using Fibers (which are fairly 
light-weight) instead of Threads.


Re: Programming a Game in D? :D

2014-08-02 Thread Kapps via Digitalmars-d-learn

On Sunday, 3 August 2014 at 03:39:25 UTC, Rikki Cattermole wrote:


Lastly the game dev industry is very hesitant to change 
languages for a lot of reasons. And one of those is platform 
support. They won't be seeing D on e.g. Xbox One anytime soon 
if you get my drift.


Apparently D already works on the Xbox One using Windows with 
-m64 (and thus COFF) and Visual Studio's toolchain, at least in 
conjunction with some C++ (I'm not sure about standalone, though 
I don't see why not).


Re: Small part of a program : d and c versions performances diff.

2014-07-09 Thread Kapps via Digitalmars-d-learn
Measure a larger number of loops. I understand you're concerned 
about microseconds, but your benchmark shows nothing because your 
timer is simply not accurate enough for this. The benchmark that 
bearophile showed where C took ~2 nanoseconds vs the ~7000 D took 
heavily implies to me that the C implementation is simply being 
optimized out and nothing is actually running. All inputs are 
known at compile-time, the output is known at compile-time, the 
compiler is perfectly free to simply remove all your code and 
replace it with the result. I'm somewhat surprised that the D 
version doesn't do this actually, perhaps because of the dynamic 
memory allocation. I realize that you can't post your actual 
code, but this benchmark honestly just has too many flaws to 
determine anything from.


As for startup cost, D will indeed have a higher startup cost 
than C because of static constructors. Once it's running, it 
should be very close. If you're looking to start a process that 
will run for only a few milliseconds, you'd probably want to not 
use D (or avoid most static constructors, including those in the 
runtime / standard library).


Re: Small part of a program : d and c versions performances diff.

2014-07-09 Thread Kapps via Digitalmars-d-learn

On Wednesday, 9 July 2014 at 13:18:00 UTC, Larry wrote:


You are definitely right, I did mess up while translating !

I run the corrected codes (the ones I was meant to provide :S) 
and on a slow macbook I end up with :

C : 2
D : 15994

Of course when run on very high end machines, this diff is 
almost non existent but we want to run on very low powered 
hardware.


Ok, even with a longer code, there will always be a launch 
penalty for d. So I cannot use it for very high performance 
loops.


Shame for us..
:)

Thanks and bye


This to me pretty much confirms that almost the entirety of your 
C code is being optimized out and thus not actually executing.


Re: Problem Linking Phobos git master

2014-07-04 Thread Kapps via Digitalmars-d-learn
Possibly something related to: 
https://github.com/D-Programming-Language/dmd/pull/3715


Have you tried updating to git master today?


Re: import except one?

2014-06-29 Thread Kapps via Digitalmars-d-learn

A bit late, but you should also be able to do:

import scriptlike;
alias Config = std.process.Config;


Re: httpS post fail at tango

2014-06-29 Thread Kapps via Digitalmars-d-learn

On Thursday, 26 June 2014 at 17:07:30 UTC, JJDuck wrote:

On Thursday, 26 June 2014 at 16:33:57 UTC, JJDuck wrote:


I tried to use phobos , but there is no such function exists 
for posting to https too


With Phobos, you can use 
http://dlang.org/phobos/std_net_curl.html#post. Depending on the 
SSL certificate (i.e., if it's self-signed), you may need to use 
the C API to cURL and disable SSL verification 
(http://dlang.org/phobos/etc_c_curl.html). With curl, if it works 
for http it works for https, provided no certificate issues are 
found.


Tango isn't really used much anymore and Phobos is the official 
standard library now (though you can use Tango alongside it), so 
you'd probably have a hard time finding help for Tango on these 
forums.


Re: Concurrency on Windows (spawn)

2014-06-18 Thread Kapps via Digitalmars-d-learn

On Wednesday, 18 June 2014 at 15:03:55 UTC, Ali Çehreli wrote:

On 06/18/2014 06:28 AM, Chris wrote:

On Wednesday, 18 June 2014 at 11:57:06 UTC, Chris wrote:
Windows: in a D-DLL I'm trying to spawn a thread. However, 
nothing

happens

auto myThread = spawn(myFunction, thisTid);
send(myThread, arg);

The thread is never called. Any ideas? Thanks!

PS In an old DLL it used to work, there I called it with only 
one
argument, i.e. spawn(myFunction). Is thisTid messing it up, 
do I need

to pass something else?


Mystery solved. There was an audio delay so that the program 
had already
finished, before the thread was properly executed. I _lve_ 
Windows!

Not!


That can happen on Linux as well. So, the owner may have to 
call thread_joinAll() to wait for the worker:


import core.thread;

auto myThread = spawn(myFunction, thisTid);
send(myThread, arg);

// ... sometime before the program ends:
thread_joinAll();

Ali


Alternatively, one should use non-daemon threads for this purpose.
http://dlang.org/phobos/core_thread.html#.Thread.isDaemon


Re: what is going on with cgcs.c:351?

2014-06-16 Thread Kapps via Digitalmars-d-learn

Possibly https://issues.dlang.org/show_bug.cgi?id=11763 or
https://issues.dlang.org/show_bug.cgi?id=11903


Re: Does __gshared have shared semantics?

2014-06-13 Thread Kapps via Digitalmars-d-learn

On Saturday, 14 June 2014 at 01:24:05 UTC, Mike Franklin wrote:

In other words, is 'shared __gshared' redundant?


All __gshared does is makes the variable not go into thread-local 
storage, nothing more. Shared does this, as well as modify the 
type to be shared(T) instead of just T. So yes, it's redundant.


Re: Source File and Position of User Defined Type

2014-06-11 Thread Kapps via Digitalmars-d-learn

On Tuesday, 10 June 2014 at 20:58:41 UTC, Nordlöw wrote:
Is there a way to, programatically (trait), lookup the source 
file and position of a user defined type either dynamically or, 
even better, statically?


I don't believe this is possible. Perhaps you would be able to
generate the .json file and use that at runtime, but I don't know
if even that will handle situations like using mixins.


Re: Cannot understand deprecation message recently added to Phobos

2014-06-11 Thread Kapps via Digitalmars-d-learn

On Wednesday, 11 June 2014 at 20:59:25 UTC, Nordlöw wrote:

Can somebody explain the meaning of split in the error message

Deprecation: function core.time.Duration.weeks is deprecated - 
Please use split instead. weeks was too frequently confused for 
total!weeks.


given by function

shortDurationString()

at

https://github.com/nordlow/justd/blob/master/pprint.d


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


Re: Class Data Members Name Reflection

2014-06-10 Thread Kapps via Digitalmars-d-learn

On Tuesday, 10 June 2014 at 16:13:31 UTC, Adam D. Ruppe wrote:
Two options: do allMembers and filter it out to only be data 
members, or do some slicing of tupleof.stringof:


S s;
foreach(idx, member; s.tupleof) {
   writeln(Name: , s.tupleof[idx].stringof[2..$]);
}


The tupleof[idx] inside the loop is important instead of just 
using member because then you get the name, then the slicing is 
because you get:


s.foo

for example, and you want to slice off the s. to leave just 
the name.


You may not want to use stringof for this, because stringof is 
explicitly defined as being able to change across versions, and 
no actual format is defined. Instead use __traits(identifier, 
s.tupleof[idx]).


Also note that .tupleof will not return static fields.


Re: Class Data Members Name Reflection

2014-06-10 Thread Kapps via Digitalmars-d-learn

On Tuesday, 10 June 2014 at 20:01:37 UTC, Nordlöw wrote:


Notice that A.init.tupleof segfaults for classes so that is 
_not_ an adviced solution in a generic solution!




There's no need to use .init:

import std.stdio;

struct Foo {
int a, b;
}

void main() {
writeln(__traits(identifier, Foo.tupleof[0]));
}


Re: Basic dynamic array question. Use of new versus no new.

2014-06-10 Thread Kapps via Digitalmars-d-learn

On Wednesday, 11 June 2014 at 02:30:01 UTC, WhatMeWorry wrote:

In Mr. Cehreli's book it says

Additionally, the length of dynamic arrays can be changed by 
assigning a value to this property:


int[] array; // initially empty
array.length = 5; // now has 5 elements

while in Mr. Alexandrescu's book, it says

To create a dynamic array, use a new expression (§ 2.3.6.1 on 
page 51) as follows:


int[] array = new int[20]; // Create an array of 20 integers


Could someone please compare and contrast the two syntaxes. I 
presume the new command places the 2nd array in heap memory.


They both do the same, create an array of n integers on the heap 
and set the length to n. You can also use .capacity instead of 
.length to allocate n but not adjust length.


Re: XamarinStudio dependency issues(Mono-D)

2014-05-15 Thread Kapps via Digitalmars-d-learn

On Friday, 16 May 2014 at 00:23:00 UTC, Jack wrote:
I recently downloaded Xamarin Studio from the Mono-Develop 
site(as this was the only available installer on that site) and 
was looking to try out Mono-D.


Then this showed up: http://puu.sh/8NV4V.png

Was wondering where I can get those dependencies, or how to 
solve this particular problem... Thank you


The problem occurs because MonoDevelop 5 is coming out, and the 
4.2.2 version I believe isn't supported anymore. I think that if 
you go into Help - Check for Updates and set yourself to the 
Alpha channel it might work on Windows.


Re: XamarinStudio dependency issues(Mono-D)

2014-05-15 Thread Kapps via Digitalmars-d-learn

On Friday, 16 May 2014 at 01:07:28 UTC, Kapps wrote:

On Friday, 16 May 2014 at 00:23:00 UTC, Jack wrote:
I recently downloaded Xamarin Studio from the Mono-Develop 
site(as this was the only available installer on that site) 
and was looking to try out Mono-D.


Then this showed up: http://puu.sh/8NV4V.png

Was wondering where I can get those dependencies, or how to 
solve this particular problem... Thank you


The problem occurs because MonoDevelop 5 is coming out, and the 
4.2.2 version I believe isn't supported anymore. I think that 
if you go into Help - Check for Updates and set yourself to 
the Alpha channel it might work on Windows.


I should clarify, I think that the 4.2.2 version isn't supported
by Mono-D anymore (might be wrong). The installation instructions
say to make sure you're on the alpha channel and thus 4.3. But if
this doesn't work, you might get more useful help on
http://mono-d.alexanderbothe.com, Alex is quite active and
helpful with questions.


Re: Array!T and find are slow

2014-05-14 Thread Kapps via Digitalmars-d-learn

On Wednesday, 14 May 2014 at 17:20:37 UTC, David Nadlinger wrote:

On Wednesday, 14 May 2014 at 15:42:13 UTC, Damian Day wrote:
On Wednesday, 14 May 2014 at 14:54:57 UTC, David Nadlinger 
wrote:


Could you post a short benchmark snippet explicitly showing 
the problem?


Benchmark found here:
http://dpaste.dzfl.pl/0058fc8341830


Unfortunately, I don't have the time to look at the details 
right now, but 
https://github.com/D-Programming-Language/phobos/pull/1713 
might have improved the situation somewhat.


David


That pull shows that the previous behaviour was to use enforce?
Isn't this very expensive, particularly considering that enforce
uses lazy non-scope arguments?


Re: Array!T and find are slow

2014-05-14 Thread Kapps via Digitalmars-d-learn

On Wednesday, 14 May 2014 at 23:50:34 UTC, Meta wrote:
On the topic of lazy, why *is* it so slow, exactly? I thought 
it was just shorthand for taking a function that evaluates the 
expression, and wrapping said expression in that function at 
the call site. That is, I thought that:


int doSomething(lazy int n)
{
return n();
}

Was more or less equivalent to:

int doSomething(int function(int) n)
{
return n();
}


It's more equivalent to:

int doSomething(int delegate(int) n)
{
return n();
}

And (I could be very likely wrong here), I believe that it's 
expensive because it's not scope and possibly requires a closure. 
Again, very likely may be wrong.


Re: Configuring Phobos from the 1-click installer

2014-05-12 Thread Kapps via Digitalmars-d-learn

On Monday, 12 May 2014 at 15:02:54 UTC, Moses wrote:
PATH environment variable is not related at all with phobos2 
sources paths.


All Linux packages (Ubuntu too) includes 
-I/usr/include/dmd/phobos on /etc/dmd.conf configuration 
file.
If you need to explicit pass this argument to dmd compiler, 
may be due to several reasons.


- You've edited your /etc/dmd.conf file.

- You've created a new dmd.conf on your current directory, 
on you home directory or on dmd command directory (/usr/bin/).


Any dmd.conf file on these places, overrides /etc/dmd.conf

Take a look at:
$ cat /etc/dmd.conf

Regard,



I didn't find any extra dmd.conf files, but I found that adding
#!/usr/include/dmd/phobos
to the top of my D program solved the problem to my 
satisfaction. Thanks so much for your help.


It really does seem like you have an extra dmd.conf that's being
loaded.

Type dmd -v abc.d - The first few lines should include what
config it's using.


Re: Create many objects using threads

2014-05-06 Thread Kapps via Digitalmars-d-learn

On Monday, 5 May 2014 at 22:11:39 UTC, Ali Çehreli wrote:

On 05/05/2014 02:38 PM, Kapps wrote:

 I think that the GC actually blocks when
 creating objects, and thus multiple threads creating
instances would not
 provide a significant speedup, possibly even a slowdown.

Wow! That is the case. :)

 You'd want to benchmark this to be certain it helps.

I did:

import std.range;
import std.parallelism;

class C
{}

void foo()
{
auto c = new C;
}

void main(string[] args)
{
enum totalElements = 10_000_000;

if (args.length  1) {
foreach (i; iota(totalElements).parallel) {
foo();
}

} else {
foreach (i; iota(totalElements)) {
foo();
}
}
}

Typical run on my system for -O -noboundscheck -inline:

$ time ./deneme parallel

real0m4.236s
user0m4.325s
sys 0m9.795s

$ time ./deneme

real0m0.753s
user0m0.748s
sys 0m0.003s

Ali


Huh, that's a much, much, higher impact than I'd expected.
I tried with GDC as well (the one in Debian stable, which is 
unfortunately still 2.055...) and got similar results. I also 
tried creating only totalCPUs threads and having each of them 
create NUM_ELEMENTS / totalCPUs objects rather than risking that 
each creation was a task, and it still seems to be the same.


Using malloc and emplace instead of new D, results are about 50% 
faster for single-threadeded and ~3-4 times faster for 
multi-threaded (4 cpu 8 thread machine, Linux 64-bit). The 
multi-threaded version is still twice as slow though. On my 
Windows laptop (with the program compiled for 32-bit), it did not 
make a significant difference and the multi-threaded version is 
still 4 times slower.


That being said, I think most malloc implementations while being 
thread-safe, usually use locks or do not scale well.


Code:
import std.range;
import std.parallelism;
import std.datetime;
import std.stdio;
import core.stdc.stdlib;
import std.conv;

class C {}

void foo() {
//auto c = new C;
enum size = __traits(classInstanceSize, C);
void[] mem = malloc(size)[0..size];
emplace!C(mem);
}

void createFoos(size_t count) {
foreach(i; 0 .. count) {
foo();
}
}

void main(string[] args) {
StopWatch sw = StopWatch(AutoStart.yes);
enum totalElements = 10_000_000;
if (args.length = 1) {
foreach (i; iota(totalElements)) {
foo();
}
} else if(args[1] == tasks) {
foreach (i; parallel(iota(totalElements))) {
foo();
}
} else if(args[1] == parallel) {
for(int i = 0; i  totalCPUs; i++) {
taskPool.put(task(createFoos, totalElements / 
totalCPUs));

}
taskPool.finish(true);
} else
writeln(Unknown argument ', args[1], '.);
sw.stop();
writeln(cast(Duration)sw.peek);
}

Results (Linux 64-bit):
shardsoft:~$ dmd -O -inline -release test.d
shardsoft:~$ ./test
552 ms, 729 μs, and 7 hnsecs
shardsoft:~$ ./test
532 ms, 139 μs, and 5 hnsecs
shardsoft:~$ ./test tasks
1 sec, 171 ms, 126 μs, and 4 hnsecs
shardsoft:~$ ./test tasks
1 sec, 38 ms, 468 μs, and 6 hnsecs
shardsoft:~$ ./test parallel
1 sec, 146 ms, 738 μs, and 2 hnsecs
shardsoft:~$ ./test parallel
1 sec, 268 ms, 195 μs, and 3 hnsecs





Re: Create many objects using threads

2014-05-06 Thread Kapps via Digitalmars-d-learn

On Tuesday, 6 May 2014 at 15:56:11 UTC, Kapps wrote:

On Monday, 5 May 2014 at 22:11:39 UTC, Ali Çehreli wrote:

On 05/05/2014 02:38 PM, Kapps wrote:

 I think that the GC actually blocks when
 creating objects, and thus multiple threads creating
instances would not
 provide a significant speedup, possibly even a slowdown.

Wow! That is the case. :)

 You'd want to benchmark this to be certain it helps.

I did:

import std.range;
import std.parallelism;

class C
{}

void foo()
{
   auto c = new C;
}

void main(string[] args)
{
   enum totalElements = 10_000_000;

   if (args.length  1) {
   foreach (i; iota(totalElements).parallel) {
   foo();
   }

   } else {
   foreach (i; iota(totalElements)) {
   foo();
   }
   }
}

Typical run on my system for -O -noboundscheck -inline:

$ time ./deneme parallel

real0m4.236s
user0m4.325s
sys 0m9.795s

$ time ./deneme

real0m0.753s
user0m0.748s
sys 0m0.003s

Ali


Huh, that's a much, much, higher impact than I'd expected.
I tried with GDC as well (the one in Debian stable, which is 
unfortunately still 2.055...) and got similar results. I also 
tried creating only totalCPUs threads and having each of them 
create NUM_ELEMENTS / totalCPUs objects rather than risking 
that each creation was a task, and it still seems to be the 
same.


snip


I tried with using an allocator that never releases memory, 
rounds up to a power of 2, and is lock-free. The results are 
quite a bit better.


shardsoft:~$ ./test
1 sec, 47 ms, 474 μs, and 4 hnsecs
shardsoft:~$ ./test
1 sec, 43 ms, 588 μs, and 2 hnsecs
shardsoft:~$ ./test tasks
692 ms, 769 μs, and 8 hnsecs
shardsoft:~$ ./test tasks
692 ms, 686 μs, and 8 hnsecs
shardsoft:~$ ./test parallel
691 ms, 856 μs, and 9 hnsecs
shardsoft:~$ ./test parallel
690 ms, 22 μs, and 3 hnsecs

I get similar results on my laptop (which is much faster than the 
results I got on it using DMD's malloc):

test

1 sec, 125 ms, and 847 ╬╝s

test

1 sec, 125 ms, 741 ╬╝s, and 6 hnsecs


test tasks

556 ms, 613 ╬╝s, and 8 hnsecs

test tasks

552 ms and 287 ╬╝s


test parallel

554 ms, 542 ╬╝s, and 6 hnsecs

test parallel

551 ms, 514 ╬╝s, and 9 hnsecs


Code:
http://pastie.org/9146326

Unfortunately it doesn't compile with the ancient version of gdc 
available in Debian, so I couldn't test with that. The results 
should be quite a bit better since core.atomic would be faster. 
And frankly, I'm not sure if the allocator actually works 
properly, but it's just for testing purposes anyways.




Re: Create many objects using threads

2014-05-05 Thread Kapps via Digitalmars-d-learn

On Monday, 5 May 2014 at 17:14:54 UTC, Caslav Sabani wrote:

Hi,


I have just started to learn D. Its a great language. I am 
trying to achieve the following but I am not sure is it 
possible or should be done at all:


I want to have one array where I will store like 10  
objects.


But I want to use 4 threads where each thread will create 25000 
objects and store them in array above mentioned. And all 4 
threads should be working in parallel because I have 4 core 
processor for example. I do not care in which order objects are 
created nor objects should be aware of one another. I just need 
them stored in array.


Can threading help in creating many objects at once?

Note that I am beginner at working with threads so any help is 
welcome :)



Thanks


I could be wrong here, but I think that the GC actually blocks 
when creating objects, and thus multiple threads creating 
instances would not provide a significant speedup, possibly even 
a slowdown.


You'd want to benchmark this to be certain it helps.



Re: Optimize my code =)

2014-02-18 Thread Kapps

On Tuesday, 18 February 2014 at 09:05:33 UTC, Stanislav Blinov
wrote:


allocationTest ...
Time required: 2 hnsecs (o_O)
identityMatrixTest ...
Time required: 4 hnsecs (o_O)


LDC is probably detecting that you're never actually using the
results of the operation and that none of the steps have
side-effects, so it's optimizing the call out. One way of
avoiding this is to do something like writeln the result of an
operation.


Re: 64 bit size_t

2014-02-17 Thread Kapps

On Monday, 17 February 2014 at 07:46:02 UTC, Steve Teale wrote:

On Monday, 17 February 2014 at 07:17:06 UTC, Steve Teale wrote:


What is size_t for 64 bit?

Steve


Sorry parent.children is just a straightforward array


Sorry again - forget about it. I'd forgotten that D actually 
says int is 32 bits, and ulong is 64, and size_t for a 64 bit 
machine is obviously 64.


I'll just go through the code and either change int to ulong or 
use a cast.


;=(


Rather than change it to int/ulong, just change it to 'size_t len 
= parent.children.length+1' (or auto instead of size_t). This way 
it's proper for both 32-bit and 64-bit and you don't need to 
worry about architecture. If you do need a signed version, you 
can use ptrdiff_t.


Re: Optimize my code =)

2014-02-17 Thread Kapps

On Monday, 17 February 2014 at 11:34:43 UTC, bearophile wrote:



  foreach (ref T element; this.data) {
  element *= scalar;
  }


Try to use:

data[] *= scalar;



  for (auto i = 0; i  this.dim.size; ++i) {
  this.data[i] += other.data[i];
  }


Try to use:

data[] += other.data[];



  for (auto i = 0; i  this.dim.size; ++i) {
  this.data[i] -= other.data[i];
  }


Try to use:

data[] -= other.data[];




While it is cleaner, I remember array operations (such as data[] 
-= other.data[]) being significantly slower than doing it 
yourself. I don't know if this has been fixed. Perhaps using -m64 
helps this.



Also, I stress again that if you aren't compiling for 64-bit 
(-m64), it's very likely to give a significant improvement 
(because the optimizer will probably convert some of your 
operations into SIMD operations). Using LDC / GDC would also give 
a significant improvement.


Re: Optimize my code =)

2014-02-14 Thread Kapps

On Friday, 14 February 2014 at 16:00:09 UTC, Robin wrote:
As I am very new to D I instantly ran into certain optimizing 
issues. E.g. the simple matrix multiplication based in my java 
implementation requires about 1.5 secs for multiplying two 
1000x1000 matrices, however my D implementation requires 39 
seconds without compiler optimizations and about 14 seconds 
with -inline, -O, -noboundscheck and -release. So I am sure 
that I just missed some possible optimization routines for D 
and that I could miss entire patters used in D to write more 
optimized code - especially when looking at the const and 
immutability concepts.


Try with and without -noboundscheck. Sometimes using it seems to
make things slower, which is odd.

Also, compiling for 64-bit may help significantly. When you
compile for 32-bit, you won't get benefits of SIMD instructions
as it's not guaranteed to be supported by the CPU. Since Java
runs a JIT, it would use these SIMD instructions.

Also, you'll get significantly faster code if you use LDC or GDC.


class Matrix(T = double) {
private T[] data;
private Dimension dim;
}


This should be final class or struct, you don't need virtual
methods.



This is my class with its templated data as a one dimensional 
array (as I don't like jagged-arrays) and a dimension (which is 
a struct). The dimension object has some util functionality 
such as getting the total size or mapping (row, col) to a 
one-dimensional index besides the getter for rows and columns.


this(size_t rows, size_t cols) {
this.dim = Dimension(rows, cols);
this.data = new T[this.dim.size];
enum nil = to!T(0);
foreach(ref T element; this.data) element = nil;
}


You don't need to!T for setting to 0, just use plain 0. Using
this to will probably result in overhead. Note that this may
evaluated every time you use 'nil', so using a constant will help.



T opIndex(size_t row, size_t col) const {
immutable size_t i = this.dim.offset(row, col);
if (i = this.dim.size) {
// TODO - have to learn exception handling in D first. :P
}
return this.data[i];
}


You're using -noboundscheck then manually implementing bounds
checks, and probably less efficiently than the compiler does.
Either change this to an assert, or remove it. In either case,
the compiler will do it's own built in bounds checking.

This call is especially expensive since you're doing entirely
virtual methods because you specified class instead of final
class or using a struct. None of your Matrix calls will be
inlined.



Which calls:

size_t size() @property const {
return this.rows * this.cols;
}

I think and hope that this is getting optimized via inlining. =)
This works similar for opIndexAssign.


Not unless you final class / struct.



The function I am mainly benchmarking is the simple matrix 
multiplication where one of the multiplied matrices is 
tranposed first in order to improve cache hit ratio.


Matrix opMul(ref const(Matrix) other) {
	if (this.dim.rows != other.dim.cols || this.dim.cols != 
ther.dim.rows) {

// TODO - still have to learn exception handling first ...
}
auto m = new Matrix(this.dim.rows, other.dim.cols);
auto s = new Matrix(other).transposeAssign();
size_t r1, r2, c;
T sum;
for (r1 = 0; r1  this.dim.rows; ++r1) {
for (r2 = 0; r2  other.dim.rows; ++r2) {
sum = to!T(0);
for (c = 0; c  this.dim.cols; ++c) {
sum += this[r1, c] * other[r2, c];
}
m[r1, r2] = sum;
}
}
return m;
}


These allocations may potentially hurt.
Also, again, the virtual calls here are a huge hit.
Using to!T(0) is also a waste of performance, as youc an just do
straight 0.


I am aware that there are faster algorithms for matrix 
multiplication but I am mainly learning how to write efficient 
D code in general and not based on any algorithm.


Using SIMD instructions manually would of course be much, much,
faster, but I understand that it defeats the point somewhat and
is much more ugly.



This is more or less the same algorithm I am using with java 
and c++. Both require about 1.5 secs (after java warm-up) to 
perform this task for two 1000x1000 matrices. D compiled with 
DMD takes about 14 seconds with all (known-to-me) optimize flag 
activated. (listed above)


If you used LDC or GDC 64-bit with the changes above, I'd guess
it would be similar. I wouldn't expect D to out-perform Java much
for this particular scenario, there's very little going on and
the JIT should be able to optimize it quite well with SIMD stuff.



I wanted to make s an immutable matrix in order to hopefully 
improve performance via this change, however I wasn't 
technically able to do this to be honest.


I don't think this would improve performance.


Re: std.algorithm for changing array values

2014-01-15 Thread Kapps

On Wednesday, 15 January 2014 at 20:34:32 UTC, Andre wrote:

foreach(entry;entries){
if (entry.key == 3){
entry.value = 42;
found = true;
}
}



One thing to keep in mind is that structs are passed by value, so
this foreach would be operating on a copy of the entry. So your
setting the value to 42 would have no effect.

Instead you would need foreach(ref entry; entries) in order to
have the change take effect (regardless of whether or not you use
std.algorithm).


Re: Server is not active?

2013-09-28 Thread Kapps
This is just a guess, but it is because you're setting the socket 
to be blocking after the call to accept? If it defaults to 
non-blocking, this would cause accept to return immediately, so 
the client connecting would fail as the server isn't currently 
accepting connections. Also to verify it's not a firewall issue, 
for connecting try using 127.0.0.1.


Re: Support implicit conversion between types

2013-09-04 Thread Kapps

On Wednesday, 4 September 2013 at 21:14:26 UTC, Ali Çehreli wrote:

On 09/04/2013 01:46 PM, Adam D. Ruppe wrote:

 D does not support implicit struct construction.

That's what I knew.

 Interestingly though, it *does* support it for functions
taking classes:

 class Foo {
  this(int i) {}
 }

 void foo(Foo f...) {}

 void main() {
  foo(10);
 }

WHAT? :) It even new's one?

But it works only for the ellipsis.

I wonder why the discrepancy...

Ali


http://dlang.org/function.html Under Typesafe Variadic Functions 
- For class objects.


Re: Tools for building a dynamic derived type? I need a push in the right direction.

2013-08-20 Thread Kapps

On Tuesday, 20 August 2013 at 18:55:44 UTC, Gary Willoughby wrote:
I've been researching ways to accomplish creating a template 
that creates a special kind of derived type and i think i need 
a push in the right direction. Take this simple class:


class Person
{
private string _name;
private int _age;

this(string name, int age)
{
this._name = name;
this._age  = age;
}

public string getName()
{
return this._name;
}

public int getAge()
{
return this._age;
}
}

I want to create a mock of this class which would mean 
achieving the following:


1). Extend the class
2). Override all public methods to do nothing (or look for 
enabled methods)
3). Provide a way of dynamically enabling methods with new 
return values


Extending the class is pretty easy and adding methods 
dynamically looks to be solved (TDPL 12.11.1) but it's the 
override all public methods to do something different which is 
beating me. I know it will probably involve mixins and dealing 
with tuples somewhere along the line but documentation is 
lacking everywhere i look.


std.traits gives me information about a type but using that 
information is where i need the documentation. e.g. i know the 
traits methods return tuples but how do you work with these 
tuples? how to Iterate through them? I seem to always get stuck 
when trying to iterate through tuples and generate compiler 
errors.


I've taken a look at the std.typecons source especially 
BlackHole and WhiteHole templates but i get lost. They are 
almost doing what i want but for abstract methods.


The general usage is probably going to be something like this:

class Mock(T) : T
{
// Implementation
}

auto cat = Mock!Cat(Ginger); // constructors supported.

auto person = Mock!Person();

person.addMethod(getName, delegate(){
return Foo;
});

person.addMethod(getAge, delegate(){
return 10;
});

Any help will be greatly appreciated.


AutoImplement 
(http://dlang.org/phobos/std_typecons.html#.AutoImplement) from 
std.typecons should do what you want. Instead of implementing 
only abstract methods, you could make it implement all non-final 
methods by changing the 'what' template parameter to simply 
return true (final methods are skipped regardless). Then you 
could change the 'how' template parameter to return 
ReturnType!parent.init unless an argument is set in an AA. I 
can't say I've ever tried this though, so I'm not sure how well 
it would work in reality.


https://github.com/QAston/DMocks-revived may interest you as well.


Getting vtable for inherited Interface instance

2013-08-20 Thread Kapps
I'm trying to implement a runtime reflection module, and am 
having some issues with figuring out the function pointer to 
invoke an interface on a class that derives from the one that 
implements the interface.


For example, given the following code, we can call an interface 
function using a delegate with http://pastie.org/8255612 - but 
even with the derived instance passed in it will invoke Bar's 
implementation as we're using the function pointer for Bar's 
implementation. I figured typeid(DerivedBar).interfaces would 
return it's own Interface instance for DerivedBar, but it doesn't 
and instead Bar's has to be used. The ABI page doesn't seem to 
mention much about inheriting from a class that implements an 
interface and overrides it's functions. Is there a way for me to 
get the function pointer to the overridden version of foo?


Re: Getting vtable for inherited Interface instance

2013-08-20 Thread Kapps
I should mention that there's no knowledge of Bar nor DerivedBar 
at compile-time, but there is of Foo. The vtable index of bar 
within Foo is known as well, but without knowledge of Bar or 
DerivedBar I can't just do the same with their implementation.


Re: how to get enclosing function as symbol ? (eg: __function__.stringof ==__FUNCTION__)

2013-08-17 Thread Kapps

On Sunday, 18 August 2013 at 01:52:50 UTC, Timothee Cour wrote:

Is there any way to get the enclosing function as symbol ?

I'd like something like that:
alternative names would be:
__function__
__context__


auto fun(alias caller=__function__)(){
  //caller represents fun1!double
  return ReturnType!caller.init;
}

T fun1(T)(T x){
  assert(__function__.stringof==__FUNCTION__);
  alias fun=__function__;
  assert( is(ReturnType! __function__) == T);
  return fun();
}
void main(){fun1!double();}




I don't think you can pass it in to the function, but you can use 
__traits(parent) on a variable within the function to get the 
function.


Re: Struct's alignment

2013-08-13 Thread Kapps

On Saturday, 10 August 2013 at 20:36:24 UTC, Temtaime wrote:

Hello, guys!

I have Matrix class(that contains an array of 16 floats) and 
SSE code to mult it.

It's neccessary to have an array alignment 16.

I'm figured out simple test-code:

align(16) struct S {
align(16) int a;
}


void main() {
align(16) S s;
writeln(cast(void *)s.a);
}

And it prints 18FCC8, but must ends with 0. What i'm doing 
wrong?


Thanks.


Perhaps core.simd (http://dlang.org/phobos/core_simd.html) could 
be of help. I believe that those types should be aligned.


Re: Win32 + OpenGL bindings

2013-04-20 Thread Kapps

On Saturday, 20 April 2013 at 03:26:29 UTC, Diggory wrote:
I've been trying to write a win32 app using opengl in D, but 
none of the bindings I've found have been sufficient:


- core.sys.windows.windows:
Missing large parts of wingdi.h, including PFD_* constants, 
ChoosePixelFormat(), SwapBuffers(), wgl*() functions.


- win32.windows:
Apparantly out of date and gives linker errors, although it 
does declare all the functions needed.


- derelict.util.wintypes:
Declares a small number of useful windows functions, many of 
which conflict with those declared in 
core.sys.windows.windows (such as PIXELFORMATDESCRIPTOR). 
However, SetPixelFormat is not declared.


- derelict.opengl.gl:
Has all of opengl plus wgl* functions needed for windows, but 
has more dependencies than an ideal opengl binding would have.


Why isn't there a simple relationship between C/C++ header 
files and D modules, instead of this weird mix where some 
things are duplicated and others not declared at all?


All of the windows specific functions including wgl* are 
supposed to be in windows.h, and opengl functions in gl/gl.h


It's a shame because I really like the ideas behind D - in fact 
the reason I found it is that I'd come up with a whole bunch of 
ideas I wanted in an ideal language and it turned out D already 
implemented them all...


Deimos has some OpenGL bindings for up to 3.1 core here 
https://github.com/D-Programming-Deimos/OpenGL/tree/master/deimos/gl
I also have my own that are up to 4.2 core here 
https://bitbucket.org/Kapps/shardgraphics/src (gl.d, glfuncs.d, 
gltypes.d, and possibly glfw.d if you need that), which include 
loading the function pointers, but there may be some licensing 
issues because they're parsed from the OpenGL man pages. Also 
there may be some incorrect functions in mine because of parsing 
errors.


Re: foreach for ranges?

2012-07-17 Thread Kapps
On Wednesday, 18 July 2012 at 04:54:51 UTC, Jonathan M Davis 
wrote:

On Wednesday, July 18, 2012 06:27:28 Mike L. wrote:
Thanks for the reply. Not sure how I missed it there. 
Interesting

that the compiler has to be made aware of a concept that I had
thought was only supposed to be part of phobos. Would it be
possible to implement it in std.range using the new UFCs?


You can do

for(; !range.empty; range.popFront())
{
auto e = range.front;
}

without the compiler doing anything at all. But if you want

for(e; range)
{}

you need a way in the language for the compiler to translate 
that into the
above. UFCS has nothing to do with it. All UFCS does is take 
a.b(c, d) and

make it b(a, c, d).

- Jonathan M Davi


If UFCS worked on operators, you would be able to make ranges 
without any compiler support.


int opApply(T)(T Range) if(isInputRange!T) {
// Stuff.
}


Re: align(16) struct member throws an exception with movdqa

2012-06-16 Thread Kapps

On Monday, 11 June 2012 at 03:19:08 UTC, ixid wrote:

struct a
{   align(16) int[4] test = [1,2,3,4];
}
a test;

asm
{
movdqa XMM0, test   ;
addps XMM0, XMM0;
movdpa test, XMM0   ;
}

This works fine with unaligned movdqu but throws an access 
violation exception with movdqa. Why isn't align letting me do 
an aligned read? How should I do an aligned read?


IIRC, you're supposed to be able to do something like align(16) 
struct a, but it doesn't work when a is created on the stack. 
That was the conclusion I found when trying to implement my own 
vector type a year ago anyways.


Re: shared status

2012-04-15 Thread Kapps
On Saturday, 14 April 2012 at 10:48:16 UTC, Luis Panadero 
Guardeño wrote:

What is the status of shared types ?

I try it with gdmd v4.6.3
And I not get any warring/error when I do anything over a 
shared variable

without using atomicOp. It's normal ?

shared ushort ram[ram_size];


ram[i] = cast(ushort) (bytes[0] | bytes[1]  8);


Shared is at the moment (in my opinion anyways) not useable. Very 
little in Phobos is shared friendly. Most benefits of shared 
aren't implemented yet. I personally avoid it.


Re: D slower ~1s from C ?!

2012-04-05 Thread Kapps

On Thursday, 5 April 2012 at 17:22:38 UTC, Minas wrote:
Many of you should know the website projecteuler.net, where 
there are mathematical problems to solve with computers.


I am doing those in D, and after I finished one today, I 
decided to compile it in C as well to compare the results.


The problem was:

The number 3797 has an interesting property. Being prime 
itself, it is possible to continuously remove digits from left 
to right, and remain prime at each stage: 3797, 797, 97, and 7. 
Similarly we can work from right to left: 3797, 379, 37, and 3.


Find the sum of the only eleven primes that are both 
truncatable from left to right and right to left.


NOTE: 2, 3, 5, and 7 are not considered to be truncatable 
primes.


My solution in D:



First, you should compile with -O -release -inline and, in this 
case, -noboundscheck.


The main issue here seems to be the for loop.
Changing:
for(ulong i = 2; i = cast (ulong)sqrt(cast(double)n+1); ++i)
if( n % i == 0 )
return false;
To:
ulong End = cast (ulong)sqrt(cast(double)n+1);
for(ulong i = 2; i = End; ++i)
if( n % i == 0 )
return false;

Results in a 26 times performance increase for me, based off of 
using a StopWatch at start of main and stopping it at end of 
main. It's possible that the C compiler can recognize that this 
is a constant expression (sqrt might be an intrinsic). D should 
be able to do this even better; sqrt is strongly pure and takes 
in arguments that do not change, thus it should be able to 
automatically make the change I did above. It (at least DMD) does 
not seem to however.


I did not try the C version, and the D version was compiled with 
DMD on Windows.


Re: HelloWordl in Webserver

2012-03-17 Thread Kapps

On Saturday, 17 March 2012 at 20:52:33 UTC, Xan wrote:

So, there is not built-in functions?

Thanks,
Xan.



There's no built in webserver class, and it's not something that 
should be in the standard library in the first place.





Re: Method invocation -- why it's not working?

2012-03-08 Thread Kapps

On Thursday, 8 March 2012 at 07:53:02 UTC, Jonathan M Davis wrote:
It would be nice, but I honestly don't understand the people 
who think that
the lack of it is crippling. It's just one of those 
nice-to-have features.

Most languages don't have anything of the sort.

- Jonathan M Davis


Speaking of UFCS...
https://github.com/D-Programming-Language/dmd/commit/b7742f7a733ff73d364c6ed54af70d875d7e911b
:D


Re: MySQL connection strange behavior (again...)

2012-02-22 Thread Kapps

On Wednesday, 22 February 2012 at 21:18:32 UTC, miazo wrote:

Problem solved. :-)

I found that it was @4 suffix that was missing. With a 
libmysql.def file as below:


LIBRARY libmysql
EXETYPE NT
SUBSYSTEM WINDOWS
EXPORTS
_mysql_init@4 = mysql_init

I was able to generate working libmysql.lib file with implib 
(with /system switch).


That, with changing from extern (C) to extern (System), removed 
the problematic issue.


Thank you for all your hints!


You shouldn't have to manually create a .def file. Try using 
coffimplib (I think it's bundled with dmc?) instead of implib and 
use it on libmysql.lib (coffimplib libmysql.lib _libmysql.lib, 
back up the original libmysql.lib, replace the original with the 
generated _libmysql.lib, and then link to it). Then create your 
headers with extern(System). It seems that adding it manually 
into the .def file is working for you, but it's a lot more effort 
than needed.




Re: MySQL

2012-01-22 Thread Kapps

The way I did it is
1) Download C connector from mysql's website, 6.0.2 is version headers 
were made for. Remember you'll need the 32-bit one if you're using DMD 
on Windows.

2) Create the binding functions using extern(System).
3) For Windows, use 'coffimplib libmysql.dll libmysql.lib', and build 
with PathToFile/libmysql.lib. Example: 'dmd test.d libmysql.lib'
3b) For Linux, just link to libmysqlclient. a with -Llibmysqlclient.a 
or by just passing path.
4) Make sure that libmysql.dll (for Windows) is in the application 
folder otherwise you'll get errors when trying to run.


On 21/01/2012 3:38 PM, Mars wrote:

Hello everyone.
I've been trying to use MySQL in an application on Windows, but I always
get

Symbol Undefined _mysql_init

I've put the lib in the correct folder, so I don't know what the problem
might be. I've tried several libs, and tried to compile it myself
(always converted using coffimplib), but it fails, no matter what. I've
also tried to make a def file out of the lib, and the functions are
definitly listed as exports there.
Any idea what I might doing wrong?

Mars




Re: Reading web pages

2012-01-19 Thread Kapps
The host is www.google.com - http is only a web protocol. The DNS lookup 
is independent of HTTP, and thus should not include it. Note that you're 
also missing a space after the GET. Also, in terms of the example given, 
some servers won't like you not using the Host header, some won't like 
the GET being an absolute path instead of relative (but the two combined 
should make most accept it). There's a CURL wrapper added, and a higher 
level version should be available within the next release or two, you 
make want to look into that.


On 19/01/2012 9:30 AM, Xan xan wrote:

Hi,

I want to simply code a script to get the url as string in D 2.0.
I have this code:

//D 2.0
//gdmd-4.6
import std.stdio, std.string, std.conv, std.stream;
import std.socket, std.socketstream;

int main(string [] args)
{
 if (args.length  2) {
writeln(Usage:);
writeln(   ./aranya {url1,url2, ...});
return 0;
}
else {
foreach (a; args[1..$]) {
Socket sock = new TcpSocket(new InternetAddress(a, 80));
scope(exit) sock.close();
Stream ss = new SocketStream(sock);
ss.writeString(GET ~ a ~  HTTP/1.1\r\n);
writeln(ss);
}
return 0;
}
}


but when I use it, I receive:
$ ./aranya http://www.google.com
std.socket.AddressException@../../../src/libphobos/std/socket.d(697):
Unable to resolve host 'http://www.google.com'

What fails?

Thanks in advance,
Xan.




Re: associative arrays

2012-01-09 Thread Kapps

Looks like this is fixed for 2.058.

https://github.com/D-Programming-Language/dmd/commit/3e23b0f5834acb32eaee20d88c30ead7e03bb2f4

On 08/01/2012 3:43 AM, Jonathan M Davis wrote:

On Sunday, January 08, 2012 03:24:22 Kapps wrote:

Ah, found the bug / pull request.

https://github.com/D-Programming-Language/dmd/pull/597
http://d.puremagic.com/issues/show_bug.cgi?id=4523


Ah, TDPL says that it returns bool. Well, then it definitely needs to be
changed, and it's good to see that that there's a pull request for it. So, it
should be fixed in the next release. In fact, the number of TDPL-related bugs
fixed for the next release should be quite high, which is great.

- Jonathan M Davis




Re: associative arrays

2012-01-08 Thread Kapps

Ah, found the bug / pull request.

https://github.com/D-Programming-Language/dmd/pull/597
http://d.puremagic.com/issues/show_bug.cgi?id=4523

On 08/01/2012 1:39 AM, Kapps wrote:

For most languages (such as C# and maybe Java), the Remove method on
collections returns a boolean indicating whether it was removed. So you
could write:

enforce(MyAA.remove(lenght))
or
bool Result = MyAA.remove(lenght);
assert(Result);

I'm not sure why it doesn't in D, but I thought I remembered seeing a
pull request or change that added it. Maybe I'm imagining things since I
can't find it now.

On 07/01/2012 4:11 PM, RenatoL wrote:

Very quick question

import std.stdio;
void main()
{
auto arr1 = [uno:1, due:2, tre:3];
arr1.remove(xxx);
}

also in this case the compiler does not say anything and the
program goes out silently ... why? Would not it be better if an
exception was raised? After all if i write:

writeln(arr1[xxx]);

runtime expresses its disappointment...






Re: associative arrays

2012-01-07 Thread Kapps
For most languages (such as C# and maybe Java), the Remove method on 
collections returns a boolean indicating whether it was removed. So you 
could write:


enforce(MyAA.remove(lenght))
or
bool Result = MyAA.remove(lenght);
assert(Result);

I'm not sure why it doesn't in D, but I thought I remembered seeing a 
pull request or change that added it. Maybe I'm imagining things since I 
can't find it now.


On 07/01/2012 4:11 PM, RenatoL wrote:

Very quick question

import std.stdio;
void main()
{
auto arr1 = [uno:1, due:2, tre:3];
arr1.remove(xxx);
}

also in this case the compiler does not say anything and the
program goes out silently ... why? Would not it be better if an
exception was raised? After all if i write:

writeln(arr1[xxx]);

runtime expresses its disappointment...




Re: Make a variable single-assignment?

2011-11-21 Thread Kapps
For one reason, public fields that lack a set without having to create a 
backing field, followed by a bulky property. It does sound lazy, but 
when it's something you have to repeat many times, it gets annoying.


On 21/11/2011 9:43 AM, Ary Manzana wrote:

On 11/21/11 11:04 AM, Alex Rønne Petersen wrote:

Hi,

Is there any way to make a variable single-assignment, regardless of its
type? I.e.:

void foo()
{
some magical keyword? int i = 0;
i = 2; // Error: i cannot be reassigned
}

I realize const and immutable will do this, but they are transitive and
infect the type, which I do *not* want. I simply want the variable to be
single-assignment. Is it possible?

- Alex


Why do you want that?