Re: DUnit: Advanced unit testing toolkit.

2013-09-23 Thread Dicebot

On Monday, 23 September 2013 at 16:40:56 UTC, jostly wrote:
In specd, the actual code inside the unittest { } sections only 
collect results, and the reporting is called from a main() 
supplied by compiling with version specrunner set. I haven't 
checked to see if your dunit do something similar.


I think more D-way would have been to simply separate tests in 
logically separated unittest blocks and run those using static 
reflection, catching assert error. That way you will get first 
failure in a set and then continue to other sets. Does that make 
sense?


Re: DUnit: Advanced unit testing toolkit.

2013-09-23 Thread jostly

On Sunday, 22 September 2013 at 13:13:29 UTC, linkrope wrote:

Have a look at https://github.com/linkrope/dunit, especially at
the Related Projects.

Until now, my preferred tool for (large-scale) unit testing in D
would be the combination of my dunit framework (of course),
DMocks-revived for mocks, and the 'must' matchers of specd.


I think it's great to see the D unit testing ecosystem growing. 
Since it's still relatively small, I think we have a good chance 
here to create interoperability between the different frameworks.


As I see it, we have:

1. Running unit tests

This is where D shines with the builting facility for unit tests. 
However, it suffers a bit from the fact that, if we use assert, 
it will stop on the first assertion failure, and there is (as far 
as I've been able to tell) no reliable way to run specific code 
before or after all the unit tests. If I'm wrong on that 
assumption, please correct me, that would simplify the spec 
running for specd.


In specd, the actual code inside the unittest { } sections only 
collect results, and the reporting is called from a main() 
supplied by compiling with version specrunner set. I haven't 
checked to see if your dunit do something similar.


2. Asserting results

Varies from the builtin assert() to xUnit-like assertEquals() to 
the more verbose x.must.equal(y) used in specd.


This could easily be standardized by letting all custom asserts 
throw an AssertError, though I would prefer to use another 
exception that encapsulates the expected and actual result, to 
help with bridging to reporting.


3. Reporting results

If we have moved beyond basic assert() and use some kind of unit 
test runner, then we have the ability to report a summary of run 
tests, and which (and how many) failed.


This is one area where IDE integration would be very nice, and I 
would very much prefer it if the different unit test frameworks 
agreed on one standard unit test runner interface, so that the 
IDE integration problem becomes one of adapting each IDE to one 
runner interface, instead of adapting each framework to each IDE.


In my experience from the Java and Scala world, the last point is 
the biggest. Users expect to be able to run unit tests and see 
the report in whatever standard way their IDE has. In practice 
this most often means that various libraries pretend to be JUnit 
when it comes to running tests, because JUnit is supported by all 
IDEs.


Let's not end up in that situation, but rather work out a common 
API to run unit tests, and the D unit test community can be the 
envy of every other unit tester. :)


Re: DUnit: Advanced unit testing toolkit.

2013-09-23 Thread Russel Winder
On Mon, 2013-09-23 at 18:40 +0200, jostly wrote:
[…]
 I think it's great to see the D unit testing ecosystem growing. 
 Since it's still relatively small, I think we have a good chance 
 here to create interoperability between the different frameworks.

There is also integration and system testing of course, not just unit
testing. The same testing framework can generally be used for all forms.

In the Java sphere, JUnit gave way to TestNG exactly because TestNG
supports all forms of testing not just unit testing. Now though TestNG
is giving way to Spock enabling elements of BDD as well as TDD.

D has some unit testing capability built in, which i good, but it is
also good to have an external testing framework that can do unit,
integration and system testing supporting TDD and BDD. 

 As I see it, we have:
 
 1. Running unit tests
 
 This is where D shines with the builting facility for unit tests. 
 However, it suffers a bit from the fact that, if we use assert, 
 it will stop on the first assertion failure, and there is (as far 
 as I've been able to tell) no reliable way to run specific code 
 before or after all the unit tests. If I'm wrong on that 
 assumption, please correct me, that would simplify the spec 
 running for specd.

So the built-in is not entirely up to the task of real unit testing?

 In specd, the actual code inside the unittest { } sections only 
 collect results, and the reporting is called from a main() 
 supplied by compiling with version specrunner set. I haven't 
 checked to see if your dunit do something similar.
 
 2. Asserting results
 
 Varies from the builtin assert() to xUnit-like assertEquals() to 
 the more verbose x.must.equal(y) used in specd.

In the Scala variant of the JVM arena, ScalaTest mingles really nicely
all the classic TDD asserts styles, along with Hamcrest matchers, but
also supports the more BDD style test specifications. Spock also does
this. Corollary, D must do this.

NB Go is going through all this just now. The built in unit test
capability is minimalist and for testing the Go implementation. GoCheck
is classic TDD assert style, and there are some candidate BDD styles on
the horizon. Will Go beat D to having the capability that the JVM
languages already enjoy?

Note that Groovy and the py.test Python test framework dispense with the
need for assertEquals and that family of JUnit thingies, in favour of
using the built-in assert and catching the AssertionError exception,
doing detailed stack analysis and provided very detailed information
about the evaluated expression: power asserts. Why should D follow 1990s
thinking when there is 2010s thinking that is much better?

 This could easily be standardized by letting all custom asserts 
 throw an AssertError, though I would prefer to use another 
 exception that encapsulates the expected and actual result, to 
 help with bridging to reporting.

See above :-)

 3. Reporting results
 
 If we have moved beyond basic assert() and use some kind of unit 
 test runner, then we have the ability to report a summary of run 
 tests, and which (and how many) failed.
 
 This is one area where IDE integration would be very nice, and I 
 would very much prefer it if the different unit test frameworks 
 agreed on one standard unit test runner interface, so that the 
 IDE integration problem becomes one of adapting each IDE to one 
 runner interface, instead of adapting each framework to each IDE.
 
 In my experience from the Java and Scala world, the last point is 
 the biggest. Users expect to be able to run unit tests and see 
 the report in whatever standard way their IDE has. In practice 
 this most often means that various libraries pretend to be JUnit 
 when it comes to running tests, because JUnit is supported by all 
 IDEs.
 
 Let's not end up in that situation, but rather work out a common 
 API to run unit tests, and the D unit test community can be the 
 envy of every other unit tester. :)

Currently, and very sadly, this generally means writing an XML file
using the JUnit schema. On the other hand if D did this Eclipse, IDEA,
NetBeans, etc. would immediately render excellent data displays.

-- 
Russel.
=
Dr Russel Winder  t: +44 20 7585 2200   voip: sip:russel.win...@ekiga.net
41 Buckmaster Roadm: +44 7770 465 077   xmpp: rus...@winder.org.uk
London SW11 1EN, UK   w: www.russel.org.uk  skype: russel_winder


signature.asc
Description: This is a digitally signed message part


Re: DUnit: Advanced unit testing toolkit.

2013-09-23 Thread Gary Willoughby

On Monday, 23 September 2013 at 16:40:56 UTC, jostly wrote:
Let's not end up in that situation, but rather work out a 
common API to run unit tests, and the D unit test community can 
be the envy of every other unit tester. :)


You've raised some nice ideas and got me thinking. However, i do 
think we are missing some way of knowing when unit tests start 
and stop. I like the built in unittest blocks but it would be 
nice to have something like:


beforetests
{
...
}

aftertests
{
...
}

To apply code before and after the unit tests have run. These 
could be used to setup and the execute the reporting environment? 
I can't think of a way to do this automatically without these 
constructs.


Re: DUnit: Advanced unit testing toolkit.

2013-09-23 Thread Rory McGuire
Can you not just change to going through each module running the hosts
manually? Then you can do what you like before and after each.

If your lib had  a host that started a thread which received messages about
a unittest registering itself in other user modules you could run the
unittests as  you feel like and you could stick with the -unittest dmd arg.
Reason for the thread is you can't control order of module initialization.
On 23 Sep 2013 21:30, Gary Willoughby d...@nomad.so wrote:

 On Monday, 23 September 2013 at 16:40:56 UTC, jostly wrote:

 Let's not end up in that situation, but rather work out a common API to
 run unit tests, and the D unit test community can be the envy of every
 other unit tester. :)


 You've raised some nice ideas and got me thinking. However, i do think we
 are missing some way of knowing when unit tests start and stop. I like the
 built in unittest blocks but it would be nice to have something like:

 beforetests
 {
 ...
 }

 aftertests
 {
 ...
 }

 To apply code before and after the unit tests have run. These could be
 used to setup and the execute the reporting environment? I can't think of a
 way to do this automatically without these constructs.



Re: DUnit: Advanced unit testing toolkit.

2013-09-23 Thread Rory McGuire
Sorry in my last mail host should be unittest (swype auto correct errors
:))


Re: Will Java go native?

2013-09-23 Thread PauloPinto

On Sunday, 22 September 2013 at 02:04:11 UTC, Paul Jurczak wrote:

On Thursday, 19 September 2013 at 09:48:15 UTC, Joakim wrote:
On Thursday, 19 September 2013 at 08:26:03 UTC, Russel Winder 
wrote:
Java is no longer under-performant compared to C, C++, 
Fortran, D, Go, Rust. Check the benchmarks.
Interesting.  Java people have been saying this for years and 
it's never been quite true, so I just looked up the benchmark 
shootout to see if you're right.  It shows Java 7 doing pretty 
well against C++ these days, roughly equivalent speed or at 
worst half as fast:


http://benchmarksgame.alioth.debian.org/u64q/benchmark.php?test=alllang=javadata=u64q
[...]


It doesn't do that well when single core is selected (always 
slower, 4x worst case):


http://benchmarksgame.alioth.debian.org/u64/benchmark.php?test=alllang=javalang2=gppdata=u64

It means that Java VM/libraries can explore multiple cores 
better that C++.


Which in a day and age that you can hardly buy single core 
machines, is a big advantage.



--
Paulo


Re: DIP45: fixing the dllimport/dllexport issue

2013-09-23 Thread Rainer Schuetze



On 23.09.2013 07:22, Benjamin Thaut wrote:

Am 10.09.2013 05:50, schrieb Martin Nowak:

Can we deal with vtable entries pointing to imported functions on
Windows? The kind of thing that happens when you inherit across a DLL
boundary.


I can't answer that and with dmd's current implementation of export its
not possible to try this. I would say we implement the DIP and see on
the way if this becomes a issue.



It is the same as initializing a global variable with a pointer into 
another DLL, i.e. it needs some init code to set the value.


Re: DIP45: fixing the dllimport/dllexport issue

2013-09-23 Thread Rainer Schuetze



On 19.09.2013 21:42, Benjamin Thaut wrote:

Am 19.09.2013 20:24, schrieb Rainer Schuetze:



On 19.09.2013 13:58, Benjamin Thaut wrote:

Am 12.09.2013 07:54, schrieb Rainer Schuetze:



This sounds interesting. Stripping an existing library isn't even
needed
because it is normally never created with exports anyway (-lib implies
that no exports are created to start with). Stripping object files
might
be necessary, though, in case they have been built separately with -c.


Can't we get around stripping object files by always using -c together
with -lib in case the object file is supposed to go into a static
library?


That could work, though it has it's own set of side effects, like
splitting a module into pseudo modules per function which also ruins
running unittests built into the library. Building modules with -c and
combining these into a library afterwards avoids this.


Ah ok, I didn't know that. How much work would it be to implement object
file stripping? I'm not confident I can do this.



I just checked the OMF and COFF docs: it should be possible to wipe out 
the export records without having to rewrite the object files, so it's 
not too involved. Don't know about ELF or mach-o, though.


Re: Will Java go native?

2013-09-23 Thread Dmitry Leskov

On Friday, 20 September 2013 at 07:19:44 UTC, deadalnix wrote:
On Friday, 20 September 2013 at 05:31:09 UTC, Dmitry Leskov 
wrote:
Our AOT compiler does inline virtual calls of non-final 
methods that are not overloaded in any subclass known at 
compile time. Of course, there is a runtime check and a backup 
virtual call, but the check is cheap and code size increase in 
negligible.


What we don't do (yet) is profile-guided optimizations, but 
that is on our to-do list.




So basically what you do is :

funptr = load from vtbl;
if (funptr == compile_time_known_value) {
compile_time_known_value();
} else {
funptr();
}

Which avoid the indirection if the function is actually called 
most of the time. Am I right ?


Almost:

funptr = load from vtbl;
if (funptr == compile_time_known_value) {
// Inlined body of compile_time_known_value() goes here
} else {
funptr();
}


Re: std.allocator needs your help

2013-09-23 Thread QAston

On Monday, 23 September 2013 at 04:19:34 UTC, Manu wrote:

You've just described C++ verbatim.
And you've previously agreed that C++'s approach totally 
failed. Can you
explain how this is different from C++, and how it solves the 
issues that

defeated that design?

One possibility I'm keeping in mind is that of defining a 
dynamic interface


Once you have static allocator you can go dynamic easily:

interface DynamicAllocator // isAllocator==true
{
// whatever the interface is
}

struct StaticAllocator // isAllocator==true
{
}

struct Container(ALLOCATOR = DynamicAllocator) if 
(isAllocator!ALLOCATOR)

{
this(ALLOCATOR a){}

}

class DynamicAllocatorWrapper(T) : DynamicAllocator if (is(T) == 
struct)

{
// wraps any static allocator to be callable using dynamic 
interface

}

With that boilerplate you can easily create allocator agnostic 
containers:


auto c = Container(new 
DynamicAllocatorWrapper!(StaticAllocator)())


and you can create specialized version if you need speed very 
much:


auto c = Container!(StaticAllocator)(StaticAllocator());


Re: std.allocator needs your help

2013-09-23 Thread Jacob Carlborg

On 2013-09-23 01:49, Andrei Alexandrescu wrote:


I am making good progress on the design of std.allocator, and I am
optimistic about the way it turns out. D's introspection capabilities
really shine through, and in places the design does feel really
archetypal - e.g. this is the essence of a freelist allocator. It's a
very good feeling. The overall inspiration comes from Berger's
HeapLayers, but D's introspection takes that pattern to a whole new level.


I agree with Manu here. I thought the whole point was to come up with a 
design and API how the allocators are supposed to be used. How they 
integrate with user code.


Here's a quick idea:

I can think of at least four different usage patterns how an allocator 
can be set. Hopefully this will be backwards compatible as well.


1. Globally - The same allocator is used in the whole application by all 
threads


2. Thread local - The allocator is set per thread. Different threads can 
used different allocators


3. Function local - This is the most intrusive. Sets the allocator for a 
given function call


4. Block local - The allocator is used during a given block

This will require some interaction with the runtime and library and 
probably use OOP. We define two module variables in some module in 
druntime, say rt.allocator:


module rt.allocator:

shared Allocator globalAllocator;
Allocator allocator;

shared this ()
{
globalAllocator = GCAllocator.allocator;
}

The global allocator is, by default, a GC allocator (the GC we're 
currently using). For each thread we set the thread local allocator to 
be the same as the global allocator:


allocator = globalAllocator;

By default all code will use new to allocate memory. druntime will 
have three functions which the new keyword is lowered to. They could 
look something like this:


extern (C) ubyte[] _d_tl_new (size_t size)
{
return _d_new(size, rt.allocator.allocator);
}

extern (C) ubyte[] _d_global_new (size_t size)
{
return _d_new(size, rt.allocator.globalAllocator);
}

extern (C) ubyte[] _d_new (size_t size, Allocator allocator)
{
if (memory = allocator.allocate(size))
return memory;

onOutOfMemoryError();
}

By default new is lowered to a call to _d_tl_new, which will 
allocate using the thread local allocator, which is by default the same 
as the global allocator, that is, the GC. In this way we maintain the 
current method of allocating memory.


When using new shared, it's lowered to a function call to 
_d_global_new, which uses the global allocator.


For block local allocator an ideal syntax would be:

allocator (GCAllocator.allocator)
{
// explicitly use the GC allocator within this block.
}

If that's not possibly we can define a function look like this:

useAllocator (alias allocator, alias block) ()
{
auto currentAllocator = core.allocator.allocator;
scope (exit)
core.allocator.allocator = currentAllocator;

block();
}

Which is used, something like this:

useAllocator!(GCAllocator.allocator, {
// explicitly use the GC allocator within this block.
});

Or alternately, using a struct:

struct UseAllocator
{
private Allocator currentAlloctor;

this (Allocator allocator)
{
currentAlloctor = core.allocator.allocator;
}

~this ()
{
rt.allocator.allocator = currentAlloctor;
}
}

UseAllocator useAllocator (Allocator allocator)
{
return UseAllocator(allocator);
}


{
auto _ = useAllocator(GCAllocator.allocator);
// explicitly use the GC allocator within this block.
}

Of curse it's also possible to explicitly set the thread local or global 
allocator for a more fine grained control. The above functions are just 
for convenience and to make sure the allocator is restored.


Function local allocator would just be a function taking an allocator as 
a parameter, example:


void process (Allocator) (int a, Allocator allocator = 
core.allocator.allocator)

{
auto _ = useAllocator(allocator);
// use the given allocator throughout the rest of this function scope
}

Some bikeshedding:


struct NullAllocator
{
 enum alignment = real.alignof;
 enum size_t available = 0;
 ubyte[] allocate(size_t s) shared { return null; }
 bool expand(ref ubyte[] b, size_t minDelta, size_t maxDelta) shared
 { assert(b is null); return false; }
 bool reallocate(ref ubyte[] b, size_t) shared
 { assert(b is null); return false; }
 void deallocate(ubyte[] b) shared { assert(b is null); }
 void collect() shared { }
 void deallocateAll() shared { }
 static shared NullAllocator it;
}


I would put the asserts in an in block.


* it is an interesting artifact. Allocators may or may not hold
per-instance state. Those that don't are required to define a global
shared or thread-local singleton called it that will be used for all
calls related to allocation. Of course, it is preferred for maximum
flexibility that it is shared so as to clarify that the allocator is
safe to 

Re: std.allocator needs your help

2013-09-23 Thread Dicebot
On Sunday, 22 September 2013 at 23:49:56 UTC, Andrei Alexandrescu 
wrote:

...


In general I like it though I do agree with concerns mentioned 
that without speculation about high-level API and usage examples 
it is rather hard to evaluate its practical applicability. For 
example, you have mentioned somewhere in comments that it is 
planned to embed allocator as part of template site like in C++ 
and it does not really sound a good idea.




Re: std.serialization: pre-voting review / discussion

2013-09-23 Thread Jacob Carlborg

On 2013-09-21 15:13, mrd wrote:


Is this the right way?

There are special formats (Protocol Buffers, for example) for a binary
format what can be changed over time without breaking old code.

But for normal serialization is not this redundant?
Besides, search by name slower compared with other methods (field
numbers, for example).


Not necessarily. I could implement that by default it will use the field 
number, if the names doesn't match it could fallback to do a lookup by name.


I would like to avoid having a dependency on the orders of the fields.

--
/Jacob Carlborg


Re: std.serialization: pre-voting review / discussion

2013-09-23 Thread Jacob Carlborg

On 2013-09-21 14:48, mrd wrote:


What is the purpose of the keys?


Fields are looked up by name. This is to avoid a dependency of the order 
of the fields. I guess I can look up by field order instead and fallback 
to a name look up if a name don't match.



If they really needed, can it be realised as option and disable them?
(I see also that they are forces to add a lot of duplicate functions.)


Yeah, I guess so.


I guess if it succeeded binary format can be made very compact (and
possibly faster) as Protocol Buffers.


I'm working on a binary archive as well. It ignores the name and look up 
by field order instead. It assume that the archived data and the 
class/struct has the same field order.


--
/Jacob Carlborg


Re: std.allocator needs your help

2013-09-23 Thread qznc
On Monday, 23 September 2013 at 07:31:46 UTC, Jacob Carlborg 
wrote:

On 2013-09-23 01:49, Andrei Alexandrescu wrote:

I am making good progress on the design of std.allocator, and 
I am
optimistic about the way it turns out. D's introspection 
capabilities

really shine through, and in places the design does feel really
archetypal - e.g. this is the essence of a freelist 
allocator. It's a

very good feeling. The overall inspiration comes from Berger's
HeapLayers, but D's introspection takes that pattern to a 
whole new level.


I agree with Manu here. I thought the whole point was to come 
up with a design and API how the allocators are supposed to be 
used. How they integrate with user code.


Here's a quick idea:

I can think of at least four different usage patterns how an 
allocator can be set. Hopefully this will be backwards 
compatible as well.


1. Globally - The same allocator is used in the whole 
application by all threads


2. Thread local - The allocator is set per thread. Different 
threads can used different allocators


3. Function local - This is the most intrusive. Sets the 
allocator for a given function call


4. Block local - The allocator is used during a given block


5. Class local - The allocator is used for specific types (e.g. 
ASTNode in a compiler)


6. Class-hierarchy - The allocator is used for a specific type 
hierarchy (e.g. ASTNode might have sub classes 
Statement,BinOp,etc)


7. Container local - The C++ way which binds allocation to a 
wrapping container


8. Task local - like Thread local but for std.parallelism.Task

That's it for now.

This is quite a long list, which means it is probably exhaustive. 
There should be a generic approach which encompasses at least 
those cases.


Re: std.allocator needs your help

2013-09-23 Thread Manu
On 23 September 2013 15:37, Walter Bright newshou...@digitalmars.comwrote:

 On 9/22/2013 9:19 PM, Manu wrote:

 Following this train of thought, I can imagine a really nice end goal
 would be
 that the existing GC is effectively plugged in as a library, and people
 can
 easily substitute it for their own GC if they want/need to.


 It already is, and has been from the beginning. Rainer, for example, uses
 a different GC for VisualD.

 dmd knows naught about the GC.


Sure, true. But little things like separate it into its own lib, so you can
easily link a different one, or not link one at all.
Also, what about language support? How much language support is there
currently?
I don't think I could currently write the ref-counting GC that I'd like
without extensive language support.
inc/dec ref calls would need to be inserted all over the place by he
compiler, and optimiser would need to know how to remove redundant inc/dec
sequences.


Re: std.allocator needs your help

2013-09-23 Thread Andrej Mitrovic
On 9/23/13, Benjamin Thaut c...@benjamin-thaut.de wrote:
 Why ubyte[] and not void[]?

Probably to make the GC avoid scanning into the array.


possible mixin template bug?

2013-09-23 Thread growler

This compiles and runs but I think it is a bug.
---
import std.stdio;
mixin template TestMixin(T) {
int testMixin;
}
struct Test {
int testMixin;
mixin TestMixin!Test;
}
void main() {
Test t;
t.testMixin = 10;
writefln(%s, t);
}
---
$ ./hack
Test(10, 0)

I can also change the struct to be:
---
struct Test {
   string testMixin;
   mixin TestMixin!Test;
}
// and the assignment in main() to
t.testMixin = some string;
---
$ ./hack
Test(some string, 0)

so whether this is a bug or not, I think it is bad. Any thoughts?

G.


Re: [OT] Which IDE / Editor do you use?

2013-09-23 Thread Bruno Medeiros

On 21/09/2013 16:07, Manu wrote:

I'm also not 'average-joe-numskull', at least I don't like to think I
am, but that doesn't mean I want to know how a car is built, and then in
turn how each individual part was built, and how to fix it, before I can
have confidence it will get me to Sydney in one piece.
I don't actually really care about how linux works, or any of the little
bits and pieces that form it's awkward foundation... and I shouldn't
need to in order to like the premise of an open system, and want to use
it on that merit alone.
I don't actually enjoy OPERATING a computer, I enjoy the creative
process of working, and getting work done. Solving interesting problems.
If the computer gets in my way, it has failed me at some level.
That might sound strange coming from a software engineer, but I guess
that's how I see it. I just don't have the patience to mess with my OS
anymore.


My feelings exactly. I learned about Linux and studied it when I was in 
high-school (Windows 98/Me era), and I was quite excited about it. 
Windows was more shite those days, and I knew Linux was not for the 
average user, but I thought that once I learned it well enough (shell, 
network, configuring partitions, automounting, the X server, etc.), it 
would be worthwhile to use.
That wasn't the case unfortunately. There was always new stuff that 
would come up that you would need to learn how to configure, or need to 
thinker, or there would be shortcomings in application functionality. 
After a certain point it was just annoying. It might be fun for people 
who get kicks out of working the innards of a system and being closer to 
how things work, but on my computer I wanted to either have my leisure 
time, or get real work done. And spending time configuring stuff (that 
in Windows just worked out of the box) is not a productive use of one's 
time in any way, shape or form.


True, this was like 10 years ago and Linux distros got better, but so 
has Windows, and nowdays there is little motivation now for me to try a 
different OS/desktop-environment.


--
Bruno Medeiros - Software Engineer


Re: [OT] Which IDE / Editor do you use?

2013-09-23 Thread Dicebot
On Monday, 23 September 2013 at 11:52:28 UTC, Bruno Medeiros 
wrote:

On 21/09/2013 16:07, Manu wrote:

...


My feelings exactly. I learned about Linux and studied it when 
I was in high-school (Windows 98/Me era), and I was quite 
excited about it. Windows was more shite those days, and I knew 
Linux was not for the average user, but I thought that once I 
learned it well enough (shell, network, configuring partitions, 
automounting, the X server, etc.), it would be worthwhile to 
use.
That wasn't the case unfortunately. There was always new stuff 
that would come up that you would need to learn how to 
configure, or need to thinker, or there would be shortcomings 
in application functionality. After a certain point it was just 
annoying. It might be fun for people who get kicks out of 
working the innards of a system and being closer to how things 
work, but on my computer I wanted to either have my leisure 
time, or get real work done. And spending time configuring 
stuff (that in Windows just worked out of the box) is not a 
productive use of one's time in any way, shape or form.


True, this was like 10 years ago and Linux distros got better, 
but so has Windows, and nowdays there is little motivation now 
for me to try a different OS/desktop-environment.


Ironically, this is exactly the reason I have never succeeded in 
using the Windows for daily work. Amount of manual configuration 
and subverting the defaults needed to make it actually usable for 
my programming flow is outstanding. In the same time on my Linux 
distro it is mostly `pacman -Sy gnome gnome-extra xorg-server 
nvidia dlang vim git` and I am ready to work on a fresh install.


Re: possible mixin template bug?

2013-09-23 Thread Kenji Hara
The symbols that are introduced by mixin template never override/conflict
with the formally defined symbols.
It's a designed behavior.

Kenji Hara


2013/9/23 growler growler...@gmail.com

 This compiles and runs but I think it is a bug.
 ---
 import std.stdio;
 mixin template TestMixin(T) {
 int testMixin;
 }
 struct Test {
 int testMixin;
 mixin TestMixin!Test;
 }
 void main() {
 Test t;
 t.testMixin = 10;
 writefln(%s, t);
 }
 ---
 $ ./hack
 Test(10, 0)

 I can also change the struct to be:
 ---
 struct Test {
string testMixin;
mixin TestMixin!Test;
 }
 // and the assignment in main() to
 t.testMixin = some string;
 ---
 $ ./hack
 Test(some string, 0)

 so whether this is a bug or not, I think it is bad. Any thoughts?

 G.



Re: Bartosz Milewski seems to like D more than C++ now :)

2013-09-23 Thread renoX

On Friday, 20 September 2013 at 15:23:20 UTC, Paulo Pinto wrote:

Am 20.09.2013 16:24, schrieb renoX:
That said, he made the same mistake as Haskell's authors: 
currying is a

*mathematical detail* which shouldn't obscure function type:
'f: a-b-c' is less readable than 'f: a,b-c'.

renoX


That is standard in all languages of the ML family, not only 
Haskell.


I know, but 'standard' doesn't mean that it is a good idea..

renoX




Re: Bartosz Milewski seems to like D more than C++ now :)

2013-09-23 Thread PauloPinto

On Monday, 23 September 2013 at 12:08:48 UTC, renoX wrote:

On Friday, 20 September 2013 at 15:23:20 UTC, Paulo Pinto wrote:

Am 20.09.2013 16:24, schrieb renoX:
That said, he made the same mistake as Haskell's authors: 
currying is a

*mathematical detail* which shouldn't obscure function type:
'f: a-b-c' is less readable than 'f: a,b-c'.

renoX


That is standard in all languages of the ML family, not only 
Haskell.


I know, but 'standard' doesn't mean that it is a good idea..

renoX


I guess it depends on the reader, I always found it quite natural.

But then again, I enjoy ML languages since I learned Caml Light.

--
Paulo


Re: std.allocator needs your help

2013-09-23 Thread Jacob Carlborg

On 2013-09-23 11:31, qznc wrote:


5. Class local - The allocator is used for specific types (e.g. ASTNode
in a compiler)

6. Class-hierarchy - The allocator is used for a specific type hierarchy
(e.g. ASTNode might have sub classes Statement,BinOp,etc)

7. Container local - The C++ way which binds allocation to a wrapping
container

8. Task local - like Thread local but for std.parallelism.Task

That's it for now.

This is quite a long list, which means it is probably exhaustive. There
should be a generic approach which encompasses at least those cases.


That's a good addition to the list.

--
/Jacob Carlborg


Re: std.allocator needs your help

2013-09-23 Thread Andrei Alexandrescu

On 9/22/13 9:03 PM, Manu wrote:

On 23 September 2013 12:28, Andrei Alexandrescu
seewebsiteforem...@erdani.org mailto:seewebsiteforem...@erdani.org
wrote:
My design makes it very easy to experiment by allowing one to define
complex allocators out of a few simple building blocks. It is not a
general-purpose allocator, but it allows one to define any number of
such.

Oh okay, so this isn't really intended as a system then, so much a
suggested API?


For some definition of system and API, yes :o).


That makes almost all my questions redundant. I'm interested in the
system, not the API of a single allocator (although your API looks fine
to me).
I already have allocators I use in my own code. Naturally, they don't
inter-operate with anything, and that's what I thought std.allocator was
meant to address.


Great. Do you have a couple of nontrivial allocators (heap, buddy system 
etc) that could be adapted to the described API?



The proposed design makes it easy to create allocator objects. How
they are used and combined is left to the application.

Is that the intended limit of std.allocator's responsibility, or will
patterns come later?


Some higher level design will come later. I'm not sure whether or not 
you'll find it satisfying, for reasons I'll expand on below.



Leaving the usage up to the application means we've gained nothing.
I already have more than enough allocators which I use throughout my
code. The problem is that they don't inter-operate, and certainly not
with foreign code/libraries.
This is what I hoped std.allocator would address.


Again, if you already have many allocators, please let me know if you 
can share some.


std.allocator will prescribe a standard for defining allocators, with 
which the rest of std will work, same as std.range prescribes a standard 
for defining ranges, with which std.algorithm, std.format, and other 
modules work. Clearly one could come back with but I already have my 
own ranges that use first/done/next instead of front/empty/popFront, so 
I'm not sure what we're gaining here.



An allocator instance is a variable like any other. So you use the
classic techniques (shared globals, thread-local globals, passing
around as parameter) for using the same allocator object from
multiple places.


Okay, that's fine... but this sort of manual management implies that I'm
using it explicitly. That's where it all falls down for me.


I think a disconnect here is that you think it where I think them. 
It's natural for an application to use one allocator that's not provided 
by the standard library, and it's often the case that an application 
defines and uses _several_ allocators for different parts of it. Then 
the natural question arises, how to deal with these allocators, pass 
them around, etc. etc.



Eg, I want to use a library, it's allocation patterns are incompatible
with my application; I need to provide it with an allocator.
What now? Is every library responsible for presenting the user with a
mechanism for providing allocators? What if the author forgets? (a
problem I've frequently had to chase up in the past when dealing with
3rd party libraries)


If the author forgets and hardcodes a library to use malloc(), I have no 
way around that.



Once a library is designed to expect a user to supply an allocator, what
happens if the user doesn't? Fall-back logic/boilerplate exists in every
library I guess...


The library wouldn't need to worry as there would be the notion of a 
default allocator (probably backed by the existing GC).



And does that mean that applications+libraries are required to ALWAYS
allocate through given allocator objects?


Yes, they should.


That effectively makes the new keyword redundant.


new will still be used to tap into the global shared GC. std.allocator 
will provide other means of allocating memory.



And what about the GC?


The current global GC is unaffected for the time being.


I can't really consider std.allocator intil it presents some usage patterns.


Then you'd need to wait a little bit.


It wasn't clear to me from your demonstration, but 'collect()'
implies
that GC becomes allocator-aware; how does that work?


No, each allocator has its own means of dealing with memory. One
could define a tracing allocator independent of the global GC.


I'm not sure what this means. Other than I gather that the GC and
allocators are fundamentally separate?


Yes, they'd be distinct. Imagine an allocator that requests 4 MB from 
the GC as NO_SCAN memory, and then does its own management inside that 
block. User-level code allocates and frees e.g. strings or whatever from 
that block, without the global GC intervening.



Is it possible to create a tracing allocator without language support?


I think it is possible.


Does the current language insert any runtime calls to support the GC?


Aside from operator new, I don't think so.


I want a ref-counting 

Re: std.allocator needs your help

2013-09-23 Thread Andrei Alexandrescu

On 9/22/13 9:19 PM, Manu wrote:

On 23 September 2013 13:01, Andrei Alexandrescu
seewebsiteforem...@erdani.org mailto:seewebsiteforem...@erdani.org
wrote:
Containers and other objects that want to allow customization of
their allocation would be parameterized during compilation with an
allocator type. Functions that need to allocate memory may similarly
accept a parameter of allocator type.

You've just described C++ verbatim.
And you've previously agreed that C++'s approach totally failed. Can you
explain how this is different from C++, and how it solves the issues
that defeated that design?


As I just wrote in my previous post, the two mistakes in C++'s allocator 
design are:


1. Allocators are parameterized by type.

2. Allocators cannot have state.

I fix both.


One possibility I'm keeping in mind is that of defining a dynamic
interface (i.e. in the OOP sense) for a global allocator. Then
people can globally change what allocator must be used for operator
new invocations.

Right, this is getting warmer. It's a stark contrast to what you suggest
above though, and when I try and think this through, it gets very
complex, very fast.
I can't imagine how such a system could ever be declared safe. However,
this is more or less what I want. I don't know how to reconcile the 2
requirements.


There are possibilities, which I hope to get to soon.


How much have you thought on this? This is where I think some serious
creativity will need to be applied...

Following this train of thought, I can imagine a really nice end goal
would be that the existing GC is effectively plugged in as a library,
and people can easily substitute it for their own GC if they want/need to.


Sean has already done that. The current GC is entirely replaceable (and 
in particular extricable).



Andrei




Re: D2 is really that stable as it is claimed to be?

2013-09-23 Thread Jacob Carlborg

On 2013-09-21 21:47, Walter Bright wrote:


That's gcc, and 4 is the line number (and the wrong line number) of the
error. No column number.


It's time you start using clang instead of gcc.

--
/Jacob Carlborg


Re: std.allocator needs your help

2013-09-23 Thread Manu
On 24 September 2013 00:04, Andrei Alexandrescu 
seewebsiteforem...@erdani.org wrote:

 On 9/22/13 10:20 PM, Benjamin Thaut wrote:

 Am 23.09.2013 01:49, schrieb Andrei Alexandrescu:

 Hello,


 2. Untyped allocator - traffics exclusively in ubyte[].


 Why ubyte[] and not void[]?


 It's the logical choice at this level.

 ubyte[] == these are octets


Isn't that what void[] also means?
Except it says these are un-typed octets, ie, not a sequence of typed
integers in the range 0-255.


Re: std.allocator needs your help

2013-09-23 Thread Andrei Alexandrescu

On 9/22/13 10:37 PM, Walter Bright wrote:

On 9/22/2013 9:19 PM, Manu wrote:

Following this train of thought, I can imagine a really nice end goal
would be
that the existing GC is effectively plugged in as a library, and
people can
easily substitute it for their own GC if they want/need to.


It already is, and has been from the beginning. Rainer, for example,
uses a different GC for VisualD.


Correct.


dmd knows naught about the GC.


Well except for plugging a library call for calls to new. But that's 
expected.


(I'm already pretending delete doesn't exist :o).)


Andrei




Re: std.allocator needs your help

2013-09-23 Thread Manu
On 23 September 2013 23:38, Jacob Carlborg d...@me.com wrote:

 On 2013-09-23 11:31, qznc wrote:

  5. Class local - The allocator is used for specific types (e.g. ASTNode
 in a compiler)

 6. Class-hierarchy - The allocator is used for a specific type hierarchy
 (e.g. ASTNode might have sub classes Statement,BinOp,etc)

 7. Container local - The C++ way which binds allocation to a wrapping
 container

 8. Task local - like Thread local but for std.parallelism.Task

 That's it for now.

 This is quite a long list, which means it is probably exhaustive. There
 should be a generic approach which encompasses at least those cases.


 That's a good addition to the list.


Another situation that I've encountered on a few occasions...
Imagine I declare a particular allocator for my application, when dealing
with 3rd party libs, I expect it to allocate within my application's heap.
Seems like a situation where I might set a global allocator...
Mr 3rd party library also has its own allocators though, things like pools
or groups which it uses explicitly within it's code.
I don't actually want to override these allocators, since they're
effectively a higher-level construct, but I *do* want to override these
allocator's memory source. Ie, they should allocate their pools from my
application's heap, rather than the default heap.
So in this way, it's important to be able to set overrides at multiple
levels.


Re: std.allocator needs your help

2013-09-23 Thread Andrei Alexandrescu

On 9/22/13 10:20 PM, Benjamin Thaut wrote:

Am 23.09.2013 01:49, schrieb Andrei Alexandrescu:

Hello,


2. Untyped allocator - traffics exclusively in ubyte[].



Why ubyte[] and not void[]?


It's the logical choice at this level.

ubyte[] == these are octets


Andrei



Re: D2 is really that stable as it is claimed to be?

2013-09-23 Thread Jacob Carlborg

On 2013-09-22 07:22, Walter Bright wrote:


I'm not rejecting the idea outright. I've actually implemented this in
the dmc compiler. It's just not terribly useful, and it has costs.


Several people has asked for it and the LLVM community thinks it's worth it.

--
/Jacob Carlborg


Re: std.allocator needs your help

2013-09-23 Thread Andrei Alexandrescu

On 9/23/13 1:03 AM, Dicebot wrote:

On Sunday, 22 September 2013 at 23:49:56 UTC, Andrei Alexandrescu wrote:

...


In general I like it though I do agree with concerns mentioned that
without speculation about high-level API and usage examples it is rather
hard to evaluate its practical applicability. For example, you have
mentioned somewhere in comments that it is planned to embed allocator as
part of template site like in C++ and it does not really sound a good idea.


That is undecided at this point. It's possible that we collectively get 
convinced the efficiency impact of indirect calls is not too high, in 
which case we can have containers using a dynamic allocator interface.


Andrei




Re: std.allocator needs your help

2013-09-23 Thread Andrei Alexandrescu

On 9/23/13 4:39 AM, Andrej Mitrovic wrote:

On 9/23/13, Benjamin Thaut c...@benjamin-thaut.de wrote:

Why ubyte[] and not void[]?


Probably to make the GC avoid scanning into the array.


No, that's determined at runtime by how the blocks are allocated.

Andrei



Re: D2 is really that stable as it is claimed to be?

2013-09-23 Thread Jacob Carlborg

On 2013-09-22 04:38, Paul Jurczak wrote:


That would do: 255 means column 256 or higher (256+). You would please
more than 99.99% of users :-)


We have lines with over 400 columns at work. Yes I know, horrible.

--
/Jacob Carlborg


Re: std.allocator needs your help

2013-09-23 Thread Andrei Alexandrescu

On 9/23/13 12:31 AM, Jacob Carlborg wrote:

On 2013-09-23 01:49, Andrei Alexandrescu wrote:


I am making good progress on the design of std.allocator, and I am
optimistic about the way it turns out. D's introspection capabilities
really shine through, and in places the design does feel really
archetypal - e.g. this is the essence of a freelist allocator. It's a
very good feeling. The overall inspiration comes from Berger's
HeapLayers, but D's introspection takes that pattern to a whole new
level.


I agree with Manu here. I thought the whole point was to come up with a
design and API how the allocators are supposed to be used. How they
integrate with user code.


This is a disconnect. I say Well, I'm exploring car engines and this 
Otto cycle looks promising, here's how a transmission would work, and 
the brake system would be hydraulic... and you say but I want to know 
how to drive a car, and road regulations, and laws!


Both are important, but they are very difficult to handle simultaneously 
in the same conversation.



Andrei



Re: std.allocator needs your help

2013-09-23 Thread Simen Kjaeraas

On 2013-09-23, 15:58, Andrei Alexandrescu wrote:


I had imagined going into this that, like the range interface which the
_language_ understands and interacts with, the allocator interface would
be the same, ie, the language would understand this API and integrate it
with 'new', and the GC... somehow.


The D language has no idea what a range is. The notion is completely  
defined in std.range.


The language has some knowledge of ranges, or foreach (e; myRange) would
not work.

--
  Simen


Re: std.allocator needs your help

2013-09-23 Thread Andrei Alexandrescu

On 9/23/13 7:07 AM, Manu wrote:

On 24 September 2013 00:04, Andrei Alexandrescu
seewebsiteforem...@erdani.org mailto:seewebsiteforem...@erdani.org
wrote:

On 9/22/13 10:20 PM, Benjamin Thaut wrote:

Am 23.09.2013 01:49, schrieb Andrei Alexandrescu:

Hello,


2. Untyped allocator - traffics exclusively in ubyte[].


Why ubyte[] and not void[]?


It's the logical choice at this level.

ubyte[] == these are octets


Isn't that what void[] also means?
Except it says these are un-typed octets, ie, not a sequence of typed
integers in the range 0-255.


I think void[] means objects of unknown type.

Andrei



Re: std.allocator needs your help

2013-09-23 Thread ponce
Great news! It looks like a big improvement on akward C++ 
allocators.


(For what it's worth I have a working implementation of aligned 
malloc/free/realloc here 
https://github.com/p0nce/gfm/blob/master/gfm/core/memory.d, which 
can be the basis for an allocator layered upon another)


Re: std.allocator needs your help

2013-09-23 Thread Andrei Alexandrescu

On 9/23/13 7:22 AM, ponce wrote:

Great news! It looks like a big improvement on akward C++ allocators.

(For what it's worth I have a working implementation of aligned
malloc/free/realloc here
https://github.com/p0nce/gfm/blob/master/gfm/core/memory.d, which can be
the basis for an allocator layered upon another)


Awesome, thanks. Will look at it.

Andrei


Re: std.allocator needs your help

2013-09-23 Thread Manu
On 24 September 2013 00:49, Andrei Alexandrescu 
seewebsiteforem...@erdan.org wrote:

 Simen Kjaeraas simen.kja...@gmail.com wrote:
  On 2013-09-23, 15:58, Andrei Alexandrescu wrote:
 
  I had imagined going into this that, like the range interface which the
  _language_ understands and interacts with, the allocator interface
 would
  be the same, ie, the language would understand this API and integrate
 it
  with 'new', and the GC... somehow.
 
  The D language has no idea what a range is. The notion is completely  
  defined in std.range.
 
  The language has some knowledge of ranges, or foreach (e; myRange) would
  not work.

 Great point. I amend my claim.


Mmm, precisely what I was talking about.


Re: [OT] Which IDE / Editor do you use?

2013-09-23 Thread H. S. Teoh
On Mon, Sep 23, 2013 at 02:01:02PM +0200, Dicebot wrote:
 On Monday, 23 September 2013 at 11:52:28 UTC, Bruno Medeiros wrote:
 On 21/09/2013 16:07, Manu wrote:
 ...
 
 My feelings exactly. I learned about Linux and studied it when I
 was in high-school (Windows 98/Me era), and I was quite excited
 about it. Windows was more shite those days, and I knew Linux was
 not for the average user, but I thought that once I learned it
 well enough (shell, network, configuring partitions, automounting,
 the X server, etc.), it would be worthwhile to use.
 That wasn't the case unfortunately. There was always new stuff
 that would come up that you would need to learn how to configure,
 or need to thinker, or there would be shortcomings in application
 functionality. After a certain point it was just annoying. It
 might be fun for people who get kicks out of working the innards
 of a system and being closer to how things work, but on my
 computer I wanted to either have my leisure time, or get real work
 done. And spending time configuring stuff (that in Windows just
 worked out of the box) is not a productive use of one's time in
 any way, shape or form.
 
 True, this was like 10 years ago and Linux distros got better, but
 so has Windows, and nowdays there is little motivation now for me
 to try a different OS/desktop-environment.
 
 Ironically, this is exactly the reason I have never succeeded in
 using the Windows for daily work. Amount of manual configuration and
 subverting the defaults needed to make it actually usable for my
 programming flow is outstanding. In the same time on my Linux distro
 it is mostly `pacman -Sy gnome gnome-extra xorg-server nvidia dlang
 vim git` and I am ready to work on a fresh install.

Ditto.

I'm surprised at people talking about the amount of time spent
configuring stuff on Linux, etc., because it's never happened to me! I
mean, OK, in the early days you had to manually configure X11 and deal
with all of the obscure problems, but that's no longer the case today.
All I have to do is 'apt-get install package' and it Just Works(tm).

I do like to tweak stuff -- and this is where Windows falls flat for me,
'cos it forces you to work a certain way, and when you go outside of
that, things just stop working or it becomes an uphill battle
(disclaimer: I haven't touched Windows for over a decade, so this may no
longer be true today) -- but the default settings installed by apt-get
*do* work. So I've no idea what people are talking about when they
complain about needing to tweak this and that by hand. Linux *lets* you
tweak stuff by hand, but, at least as far as Debian is concerned, the
defaults pretty much Just Work.

The whole bit about me recompiling the kernel and stuff -- the whole
point was that I *wanted* to run a custom kernel, and Linux lets me do
that. On Windows, this isn't even an option to begin with. The stock
Debian kernel actually just works out of the box -- and had I wanted to,
I could have just used that instead and never needed to do anything
else.


T

-- 
INTEL = Only half of intelligence.


Re: std.allocator needs your help

2013-09-23 Thread Andrei Alexandrescu

On 9/23/13 8:02 AM, Adam D. Ruppe wrote:

We should really deprecate the new keyword. It'd break like all code
ever, but with D's templates, there's no need for it, and when it is
there, it is going to spark problems about replacing global allocators
or the library allocators being second class citizens.

Maybe we could minimize the breakage by just rewriting the keyword into
a library function call, which could then be overridden with local
variables or imports  via normal scoping.


I'd think new already is translated into a library call. Walter?

Andrei


Re: std.allocator needs your help

2013-09-23 Thread Manu
On 24 September 2013 00:05, Andrei Alexandrescu 
seewebsiteforem...@erdani.org wrote:

 On 9/22/13 10:37 PM, Walter Bright wrote:

 On 9/22/2013 9:19 PM, Manu wrote:

 Following this train of thought, I can imagine a really nice end goal
 would be
 that the existing GC is effectively plugged in as a library, and
 people can
 easily substitute it for their own GC if they want/need to.


 It already is, and has been from the beginning. Rainer, for example,
 uses a different GC for VisualD.


 Correct.


  dmd knows naught about the GC.


 Well except for plugging a library call for calls to new. But that's
 expected.

 (I'm already pretending delete doesn't exist :o).)


delete is important if your class is being allocated by a pool or
something...
But you said before, people won't use 'new' if they are using an allocator.
I'm really not sure that's a good idea.
Most people (library authors!) don't actually care about their memory
allocation, they will continue to use 'new', just because it's a keyword.
It also screws with generic code; X should be allocated with 'new', but Y
should be allocated with yAllocator.alloc()?
What if you decide that Z, which allocates with 'new', becomes a problem
and you want to switch it into a pool? You now need to track down every
instance of 'new Z', and change it.


Re: std.allocator needs your help

2013-09-23 Thread Adam D. Ruppe
We should really deprecate the new keyword. It'd break like all 
code ever, but with D's templates, there's no need for it, and 
when it is there, it is going to spark problems about replacing 
global allocators or the library allocators being second class 
citizens.


Maybe we could minimize the breakage by just rewriting the 
keyword into a library function call, which could then be 
overridden with local variables or imports  via normal scoping.


Re: std.allocator needs your help

2013-09-23 Thread Andrei Alexandrescu
Simen Kjaeraas simen.kja...@gmail.com wrote:
 On 2013-09-23, 15:58, Andrei Alexandrescu wrote:
 
 I had imagined going into this that, like the range interface which the
 _language_ understands and interacts with, the allocator interface would
 be the same, ie, the language would understand this API and integrate it
 with 'new', and the GC... somehow.
 
 The D language has no idea what a range is. The notion is completely  
 defined in std.range.
 
 The language has some knowledge of ranges, or foreach (e; myRange) would
 not work.

Great point. I amend my claim.

Andrei


Re: std.allocator needs your help

2013-09-23 Thread Andrei Alexandrescu

On 9/23/13 7:50 AM, Manu wrote:

delete is important if your class is being allocated by a pool or
something...


It's important as an API function, but not as a language primitive. 
new should also have been a function.



But you said before, people won't use 'new' if they are using an
allocator. I'm really not sure that's a good idea.


I don't see another way if people are to define and use multiple allocators.


Most people (library authors!) don't actually care about their memory
allocation, they will continue to use 'new', just because it's a keyword.


new considered harmful etc.


It also screws with generic code; X should be allocated with 'new', but
Y should be allocated with yAllocator.alloc()?
What if you decide that Z, which allocates with 'new', becomes a problem
and you want to switch it into a pool? You now need to track down every
instance of 'new Z', and change it.


We can only improve that situation by allowing people to replace the 
global allocator with their own allocators. Again, there's a disconnect 
here - I'm discussing how to make it easy for people to define 
allocators and you discuss how to make it possible for people to plug 
allocators, once defined, as the global allocator. These are two 
distinct endeavors. At the level I'm at, I'm concerned with making good 
allocators easy to implement. You may say you don't care, and that's 
good feedback, but it's what I have for the time being.



Andrei



Re: std.allocator needs your help

2013-09-23 Thread Andrei Alexandrescu

On 9/23/13 7:22 AM, ponce wrote:

Great news! It looks like a big improvement on akward C++ allocators.

(For what it's worth I have a working implementation of aligned
malloc/free/realloc here
https://github.com/p0nce/gfm/blob/master/gfm/core/memory.d, which can be
the basis for an allocator layered upon another)


I gave this a read, nice work.

One question: what circumstances require run-time alignment values, and 
what values would those be? I'm currently under the assumption that 
alignments are known during compilation.



Thanks,

Andrei



Re: std.allocator needs your help

2013-09-23 Thread Manu
On 23 September 2013 23:58, Andrei Alexandrescu 
seewebsiteforem...@erdani.org wrote:

 On 9/22/13 9:03 PM, Manu wrote:

 On 23 September 2013 12:28, Andrei Alexandrescu
 seewebsiteforem...@erdani.org 
 mailto:SeeWebsiteForEmail@**erdani.orgseewebsiteforem...@erdani.org
 

 wrote:
 My design makes it very easy to experiment by allowing one to define
 complex allocators out of a few simple building blocks. It is not a
 general-purpose allocator, but it allows one to define any number of
 such.

 Oh okay, so this isn't really intended as a system then, so much a
 suggested API?


 For some definition of system and API, yes :o).


  That makes almost all my questions redundant. I'm interested in the
 system, not the API of a single allocator (although your API looks fine
 to me).
 I already have allocators I use in my own code. Naturally, they don't
 inter-operate with anything, and that's what I thought std.allocator was
 meant to address.


 Great. Do you have a couple of nontrivial allocators (heap, buddy system
 etc) that could be adapted to the described API?


Err, not really actually. When I use custom allocator's, it's for
performance, which basically implies that it IS a trivial allocator :)
The common ones I use are: stack-based markrelease, circular buffers,
pools, pool groups (collection of different sized pools)... that might be
it actually. Very simple tools for different purposes.

 The proposed design makes it easy to create allocator objects. How
 they are used and combined is left to the application.

 Is that the intended limit of std.allocator's responsibility, or will
 patterns come later?


 Some higher level design will come later. I'm not sure whether or not
 you'll find it satisfying, for reasons I'll expand on below.


  Leaving the usage up to the application means we've gained nothing.
 I already have more than enough allocators which I use throughout my
 code. The problem is that they don't inter-operate, and certainly not
 with foreign code/libraries.
 This is what I hoped std.allocator would address.


 Again, if you already have many allocators, please let me know if you can
 share some.

 std.allocator will prescribe a standard for defining allocators, with
 which the rest of std will work, same as std.range prescribes a standard
 for defining ranges, with which std.algorithm, std.format, and other
 modules work. Clearly one could come back with but I already have my own
 ranges that use first/done/next instead of front/empty/popFront, so I'm not
 sure what we're gaining here.


No, it's just that I'm saying std.allocator needs to do a lot more than
define a contract before I can start to consider if it solves my problems.
This is a good first step though, I'm happy to discuss this, but I think
discussion about the practical application may also reveal design details
at this level.

It's like you say, I can rename my allocator's methods to suit an agreed
standard, that'll take me 2 minutes, but it's how the rest of the universe
interacts with that API that matters, and if it effectively solves my
problems.

 An allocator instance is a variable like any other. So you use the
 classic techniques (shared globals, thread-local globals, passing
 around as parameter) for using the same allocator object from
 multiple places.


 Okay, that's fine... but this sort of manual management implies that I'm
 using it explicitly. That's where it all falls down for me.


 I think a disconnect here is that you think it where I think them.
 It's natural for an application to use one allocator that's not provided by
 the standard library, and it's often the case that an application defines
 and uses _several_ allocators for different parts of it. Then the natural
 question arises, how to deal with these allocators, pass them around, etc.
 etc.


No, I certainly understand you mean 'them', but you lead to what I'm
asking, how do these things get carried/passed around. Are they discreet,
or will they invade argument lists everywhere? Are they free to flow in/out
of libraries in a natural way?
These patterns are what will define the system as I see it.
Perhaps more importantly, where do these allocators get their memory
themselves (if they're not a bottom-level allocator)? Global override
perhaps, or should a memory source always be explicitly provided to a
non-bottom-level allocator?

 Eg, I want to use a library, it's allocation patterns are incompatible
 with my application; I need to provide it with an allocator.
 What now? Is every library responsible for presenting the user with a
 mechanism for providing allocators? What if the author forgets? (a
 problem I've frequently had to chase up in the past when dealing with
 3rd party libraries)


 If the author forgets and hardcodes a library to use malloc(), I have no
 way around that.


Sure, but the common case is that the author will almost certainly use
keyword 'new'. How can I affect that as a 3rd 

Re: std.allocator needs your help

2013-09-23 Thread Manu
On 24 September 2013 01:02, Andrei Alexandrescu 
seewebsiteforem...@erdani.org wrote:

 On 9/23/13 7:50 AM, Manu wrote:

 delete is important if your class is being allocated by a pool or
 something...


 It's important as an API function, but not as a language primitive. new
 should also have been a function.


I like operator new. It goes blue, and the statement isn't riddled with
exclamation marks.
Imagine if new was a template (it would have to be a template). Allocating
a template would require nested template syntax every time, which is pretty
ugly.

  X x = new!(X!arg(args...)); // ewoo, paren spam...

 But you said before, people won't use 'new' if they are using an
 allocator. I'm really not sure that's a good idea.


 I don't see another way if people are to define and use multiple
 allocators.


Well if an allocator is somehow associated with a class/struct, then 'new
MyClass' would invoke that allocator.
If you:
  pushThreadAllocator(myAllocator);
  X x = new X;
  popThreadAllocator();

Then new will use your thread-local allocator.
Continue for global, fiber, etc.

Maybe there's opportunity for 'scope' to offer some nice convenience here?

 Most people (library authors!) don't actually care about their memory
 allocation, they will continue to use 'new', just because it's a keyword.


 new considered harmful etc.


  It also screws with generic code; X should be allocated with 'new', but
 Y should be allocated with yAllocator.alloc()?
 What if you decide that Z, which allocates with 'new', becomes a problem
 and you want to switch it into a pool? You now need to track down every
 instance of 'new Z', and change it.


 We can only improve that situation by allowing people to replace the
 global allocator with their own allocators. Again, there's a disconnect
 here - I'm discussing how to make it easy for people to define allocators
 and you discuss how to make it possible for people to plug allocators,
 once defined, as the global allocator. These are two distinct endeavors.
 At the level I'm at, I'm concerned with making good allocators easy to
 implement. You may say you don't care, and that's good feedback, but it's
 what I have for the time being.


Well, I'm discussing how do people affect/override 'new' in various
circumstances?

But sure, I said before, if we're limiting this discussion to the API of an
allocator then it looks fine, I see no obvious issues.
But I think the question requires consideration of the intended goal to
make informed decisions about the design, even at this level.


Re: std.allocator needs your help

2013-09-23 Thread ponce
On Monday, 23 September 2013 at 15:45:25 UTC, Andrei Alexandrescu 
wrote:

On 9/23/13 7:22 AM, ponce wrote:
Great news! It looks like a big improvement on akward C++ 
allocators.


(For what it's worth I have a working implementation of aligned
malloc/free/realloc here
https://github.com/p0nce/gfm/blob/master/gfm/core/memory.d, 
which can be

the basis for an allocator layered upon another)


I gave this a read, nice work.

One question: what circumstances require run-time alignment 
values, and what values would those be? I'm currently under the 
assumption that alignments are known during compilation.



Thanks,

Andrei


I don't know of a use case for run-time alignment values.


Re: std.allocator needs your help

2013-09-23 Thread Andrei Alexandrescu

On 9/23/13 9:47 AM, Benjamin Thaut wrote:

I always understood void[] as block of unkown data. Which a allocator
should return in my opinion. Whats the point of void having a size in
D if we still do it the C way? In my opinion ubyte[] is a array of
values in the range of 0-255 like manu says. Also if you get a ubyte[]
you might get the opinion that it is initialized to all zeros or
something. Which might not be true for all allocators (performance ...)
If you get a void[] you know, all bets are off, and you have to check if
the allocator preinitialized it or not.


You might be right. For example, ubyte[] allows arithmetic on its 
elements, which is something one shouldn't ever care to do in an 
allocation library.


I'm unclear on what void[] means starting from its semantics. That said, 
I replaced ubyte[] with void[] throughout my existing code and it works.



Andrei



Re: std.allocator needs your help

2013-09-23 Thread deadalnix
On Sunday, 22 September 2013 at 23:49:56 UTC, Andrei Alexandrescu 
wrote:

Hello,



First of all, awesome !

Now the mh part.

I really think the it thing is not good. I don't think it is 
desirable or necessary. We should get rid of it.


You can't deal with ubyte[] like that, that is incorrect in 
regard to - unimplemented - aliasing rules. Allocator should deal 
with void[] .


What you call safe really isn't. Allocate something on the GC, 
store a pointer on a custom allocated location, collect, enjoy 
the memory corruption. All operation are safe according to your 
proposal. Allocation can only be safe if the GRAND MASTER GC is 
aware of it.


You proposal allocate shared memory. This is common in C/C++ 
world as memory is shared by default, but shouldn't be in D. It 
is highly desirable to allocate with different methods for 
different type qualifier. How does your design adapt to that ?


Finally, we got to decide how these basics block are used to form 
typed allocators, and interact with language constructs.


Sorry if this has been mentioned before, it is really ate here 
and I can't read the whole thread, especially since Manu is on 
steroids :D


Re: std.allocator needs your help

2013-09-23 Thread Johannes Pfau
Am Tue, 24 Sep 2013 00:50:02 +1000
schrieb Manu turkey...@gmail.com:

 [...] It also screws with generic code; X should be allocated with
 'new', but Y should be allocated with yAllocator.alloc()?
 What if you decide that Z, which allocates with 'new', becomes a
 problem and you want to switch it into a pool? You now need to track
 down every instance of 'new Z', and change it.

That's not a problem with the proposed GC allocator. We should add
proper overloads to emplace and a create function and then all
code should use create!(Allocator, MyClass)(args) or
create!MyClass(allocatorInstance, args).

New should then be considered as deprecated and replaced by
create!(GCAllocator, Class)().


Re: std.allocator needs your help

2013-09-23 Thread Andrej Mitrovic
On 9/23/13, Johannes Pfau nos...@example.com wrote:
 New should then be considered as deprecated and replaced by
 create!(GCAllocator, Class)().

What? That's never gonna happen. For one thing, it looks ugly as hell.
And for another, it's going to break everything written in D.


Re: std.allocator needs your help

2013-09-23 Thread Benjamin Thaut

Am 23.09.2013 16:16, schrieb Andrei Alexandrescu:

On 9/23/13 7:07 AM, Manu wrote:

On 24 September 2013 00:04, Andrei Alexandrescu
seewebsiteforem...@erdani.org mailto:seewebsiteforem...@erdani.org
wrote:

On 9/22/13 10:20 PM, Benjamin Thaut wrote:

Am 23.09.2013 01:49, schrieb Andrei Alexandrescu:

Hello,


2. Untyped allocator - traffics exclusively in ubyte[].


Why ubyte[] and not void[]?


It's the logical choice at this level.

ubyte[] == these are octets


Isn't that what void[] also means?
Except it says these are un-typed octets, ie, not a sequence of typed
integers in the range 0-255.


I think void[] means objects of unknown type.

Andrei



I always understood void[] as block of unkown data. Which a allocator 
should return in my opinion. Whats the point of void having a size in 
D if we still do it the C way? In my opinion ubyte[] is a array of 
values in the range of 0-255 like manu says. Also if you get a ubyte[] 
you might get the opinion that it is initialized to all zeros or 
something. Which might not be true for all allocators (performance ...)
If you get a void[] you know, all bets are off, and you have to check if 
the allocator preinitialized it or not.


Kind Regards
Benjamin Thaut


Re: std.allocator needs your help

2013-09-23 Thread Johannes Pfau
Am Mon, 23 Sep 2013 18:36:57 +0200
schrieb Andrej Mitrovic andrej.mitrov...@gmail.com:

 On 9/23/13, Johannes Pfau nos...@example.com wrote:
  New should then be considered as deprecated and replaced by
  create!(GCAllocator, Class)().
 
 What? That's never gonna happen. For one thing, it looks ugly as hell.
 And for another, it's going to break everything written in D.

That's why I say considered and not really deprecated. But if you
want to / have to write allocator aware code which can use the GC it's a
nice solution:

auto list(Payload, Allocator = GCAllocator)()
{
create!(Allocator) ...
}

Of course the API should be improved.
For example create could default to the GC allocator. Then it's
auto a = new Class(...) vs auto a = create!Class(...).

But IIRC when emplace was first implemented and class allocators were
removed it was quite clear that new could be easily replaced by a
template function and has no real place as a builtin anymore. It's just
too late to remove it.


Re: std.allocator needs your help

2013-09-23 Thread Benjamin Thaut

Am 23.09.2013 17:02, schrieb Adam D. Ruppe:

We should really deprecate the new keyword. It'd break like all code
ever, but with D's templates, there's no need for it, and when it is
there, it is going to spark problems about replacing global allocators
or the library allocators being second class citizens.



Its not possible to replace new with a library function in all cases. 
There are many examples where it breaks (I tried it believe me). Just 
let me give a few:



class A
{
  class B
  {
  }

  B m_b;

  this()
  {
// uses the sourrounding context
// not possible with library function
m_b = new B();
  }
}

Also there is the problem that D does not have perfect forwarding. That 
means if new is a library function it will cause additional copies / 
moves of structs which are not the case with the buildin new. Next there 
are implict conversions of literals. Those work just fine with the 
buildin new, but will break with a templated library new.


E.g.

class C
{
  this(ubyte a, ubyte b)
  {
  }
}

new C(5,3); // fine
New!C(5,3); // Error: can not implicitly convert int to ubyte

Unless of course you want to write a template metaprogram that does 
those implict conversions. Although the problem would remain that you 
can't know if the value you get comes from a literal or from a function 
call, variable, etc.


The next thing are arrays. While you get the nice array syntax with the 
buildin new, a library new just looks ugly.


new int[5];
vs.
NewArray!int(5); // Can't use New! here because it would conflict with 
the New! for creating objects / structs


I'm using library implemented new / delete since over a year and its 
annoying and makes the language look ugly and feel strange to use. See 
my allocator and New / Delete implementation here:


https://github.com/Ingrater/druntime/blob/master/src/core/allocator.d

I would rather want new to be overloadable and have 2 sets of parameters

new (allocator)(arg1, arg2)

Where allocator would go to the overloaded version of new and arg1 
and arg2 will be passed to the constructor.


I think its a really bad idea to deprecate new.

Replacing Delete works just fine with a library function though.

Kind Regards
Benjamin Thaut


Re: std.allocator needs your help

2013-09-23 Thread Andrei Alexandrescu

On 9/23/13 10:01 AM, deadalnix wrote:

On Sunday, 22 September 2013 at 23:49:56 UTC, Andrei Alexandrescu wrote:

Hello,



First of all, awesome !

Now the mh part.

I really think the it thing is not good. I don't think it is desirable
or necessary. We should get rid of it.


The singleton allocator it is instrumental for supporting stateful and 
stateless allocators with ease. It took me a few iterations to get to 
that, and I'm very pleased with the results. I think it would be 
difficult to improve on it without making other parts more difficult.



You can't deal with ubyte[] like that, that is incorrect in regard to -
unimplemented - aliasing rules. Allocator should deal with void[] .


I think I'll do that.


What you call safe really isn't. Allocate something on the GC, store a
pointer on a custom allocated location, collect, enjoy the memory
corruption.


I don't understand this. There are no pointers at this level, only 
untyped memory. The main chance of corruption is to access something 
after it's been freed.



All operation are safe according to your proposal.


No, for most allocators freeing and reallocating are unsafe.


Allocation can only be safe if the GRAND MASTER GC is aware of it.


I don't think so.


You proposal allocate shared memory.


No. It allocates unshared memory off of a shared or unshared allocator. 
The memory just allocated is as of yet unshared for the simple reason 
that only one thread has as of yet access to it.



This is common in C/C++ world as
memory is shared by default, but shouldn't be in D. It is highly
desirable to allocate with different methods for different type
qualifier. How does your design adapt to that ?


The typed allocators will have distinct methods for shared and unshared 
allocation. Even at this level it's possible to design an allocator that 
allocates in different ways with a shared vs. an unshared allocator 
object (overload on shared). So far I've only designed non-shared 
allocators, or wrap those that are already shared (malloc and new).



Finally, we got to decide how these basics block are used to form typed
allocators, and interact with language constructs.


Sure. Again: I describe the Otto cycle and you discuss how to paint the 
road.



Andrei



Re: std.allocator needs your help

2013-09-23 Thread Andrei Alexandrescu

On 9/23/13 8:32 AM, Manu wrote:

On 23 September 2013 23:58, Andrei Alexandrescu
seewebsiteforem...@erdani.org mailto:seewebsiteforem...@erdani.org
wrote:
This is a good first step though, I'm happy to discuss this, but I think
discussion about the practical application may also reveal design
details at this level.


Absolutely. This is refreshing since I've gone through the cycle of 
types must be integrated into allocators and with the global GC ... - 
... untyped allocators can actually be extricated once. It is now 
great to revisit the assumptions again.


One matter I'm rather surprised didn't come up (I assumed everyone would 
be quite curious about it) is that the allocator does not store the 
allocated size, or at least does not allow it to be discovered easily. 
This is a definitely appropriate topic for the design at hand.


The malloc-style APIs go like:

void* malloc(size_t size);
void free(void*);

Note that the user doesn't pass the size to free(), which means the 
allocator is burdened with inferring the size of the block from the 
pointer efficiently. Given that most allocators make crucial strategic 
choices depending on the size requested, this API shortcoming is a bane 
of allocator writers everywhere, and a source of inefficiency in 
virtually all contemporary malloc-style allocators.


This is most ironic since there is next to nothing that user code can do 
with a pointer without knowing the extent of memory addressed by it. (A 
notable exception is zero-terminated strings, another questionable 
design decision.) It all harkens back to Walter's claim of C's biggest 
mistake (with which I agree) of not defining a type for a bounded 
memory region.


Upon studying a few extant allocators and D's lore, I decided that in D 
things have evolved sufficiently to have the user pass the size upon 
deallocation as well:


void[] allocate(size_t size);
void deallocate(void[] buffer);

This is because the size of D objects is naturally known: classes have 
it in the classinfo, slices store it, and the few cases of using bald 
pointers for allocation are irrelevant and unrecommended.


This all makes memory allocation in D a problem fundamentally simpler 
than in C, which is quite an interesting turn :o).



No, I certainly understand you mean 'them', but you lead to what I'm
asking, how do these things get carried/passed around. Are they
discreet, or will they invade argument lists everywhere?


Since there's a notion of the default allocator, there will be ways to 
push/pop user-defined allocators that temporarily (or permanently) 
replace the default allocator. This stage of the design is concerned 
with allowing users to define such user-defined allocators without 
having to implement them from scratch.



Are they free
to flow in/out of libraries in a natural way?
These patterns are what will define the system as I see it.
Perhaps more importantly, where do these allocators get their memory
themselves (if they're not a bottom-level allocator)? Global override
perhaps, or should a memory source always be explicitly provided to a
non-bottom-level allocator?


There are a few obvious bottom allocators, such as malloc, new, sbrk, or 
Windows heap. All other allocators will compose by parameterizing on 
their parent allocator.



Sure, but the common case is that the author will almost certainly use
keyword 'new'. How can I affect that as a 3rd party?
This would require me overriding the global allocator somehow... which
you touched on earlier.


The way I'm thinking of this is to install/uninstall user-defined 
allocators that will satisfy calls to new. Since not all allocators 
support tracing, some would require the user to deallocate stuff manually.



The library wouldn't need to worry as there would be the notion of a
default allocator (probably backed by the existing GC).

Right. So it's looking like like the ability to override the global
allocator is a critical requirement.


Again, this is difficult to handle in the same conversation as should 
we pass size upon deallocation. Yes, we need road laws, but it's hard 
to talk about those and engine lubrication in the same breath. For me,
critical right now is to assess whether the untyped API misses an 
important category of allocators, what safety level it has (that's why 
expand is so different from realloc!) etc.



And does that mean that applications+libraries are required to
ALWAYS
allocate through given allocator objects?


Yes, they should.


Then we make keyword 'new' redundant?


Probably not. Typed allocators will need to integrate with (and 
occasionally replace) the global shared GC.



The problem is that installing an allocator does not get to define
what a pointer is and what a reference is.

Why not?


Because that requires a language change. I'm not sure you realize but 
you move the goalposts all the time. We were talking within the context 
of libraries and installing 

Re: D2 is really that stable as it is claimed to be?

2013-09-23 Thread Iain Buclaw
On Sep 23, 2013 6:30 PM, Sean Kelly s...@invisibleduck.org wrote:

 On Sep 21, 2013, at 10:22 PM, Walter Bright newshou...@digitalmars.com
wrote:

  On 9/21/2013 8:54 PM, Michel Fortin wrote:
  I don't think it should be a priority, but rejecting the idea outright
is
  shortsighted in my opinion.
 
  I'm not rejecting the idea outright. I've actually implemented this in
the dmc compiler. It's just not terribly useful, and it has costs.

 I'd consider it in a similar class as the dictionary lookup that occurs
when an unknown symbol is encountered.  Totally unnecessary, but it's a
nice time-saver.  Is it clang that displays the line in error with a carat
underneath the error?  Though if there really isn't an efficient way to do
it in DMD then I don't think it's worthwhile.  I was only thinking of the
parser when I mentioned the beginning-of-line pointer.  I hadn't considered
the AST.

GCC has a carat too now.

Regards
-- 
Iain Buclaw

*(p  e ? p++ : p) = (c  0x0f) + '0';


Re: D2 is really that stable as it is claimed to be?

2013-09-23 Thread Sean Kelly
On Sep 21, 2013, at 10:22 PM, Walter Bright newshou...@digitalmars.com wrote:

 On 9/21/2013 8:54 PM, Michel Fortin wrote:
 I don't think it should be a priority, but rejecting the idea outright is
 shortsighted in my opinion.
 
 I'm not rejecting the idea outright. I've actually implemented this in the 
 dmc compiler. It's just not terribly useful, and it has costs.

I'd consider it in a similar class as the dictionary lookup that occurs when an 
unknown symbol is encountered.  Totally unnecessary, but it's a nice 
time-saver.  Is it clang that displays the line in error with a carat 
underneath the error?  Though if there really isn't an efficient way to do it 
in DMD then I don't think it's worthwhile.  I was only thinking of the parser 
when I mentioned the beginning-of-line pointer.  I hadn't considered the AST.

Re: std.allocator needs your help

2013-09-23 Thread BLM768

On Monday, 23 September 2013 at 17:01:47 UTC, deadalnix wrote:
What you call safe really isn't. Allocate something on the GC, 
store a pointer on a custom allocated location, collect, enjoy 
the memory corruption. All operation are safe according to your 
proposal. Allocation can only be safe if the GRAND MASTER GC is 
aware of it.


I don't see why the GC can't be allocator-agnostic. In principle, 
it should be possible to register arbitrary allocators with the 
GC (possibly by storing a pointer to the allocator in each 
GC-managed block of memory). The GC would have a default 
allocator which would be used with the new operator, and 
something like the aforementioned create!() syntax could be used 
for custom allocators:


SomeClass c1 = new SomeClass(arg);
//Managed by the GC
SomeClass c2 = gcCreate!SomeClass(someAllocator, arg);
//Another possible syntax (much prettier!):
SomeClass c3 = someAllocator.new SomeClass(arg);

This could also integrate with DIP46; instead of pushing and 
popping a GC object, one would push and pop the GC's default 
allocator (for the current thread, of course).


There would be a bit of overhead, but that seems to be 
unavoidable in a sufficiently generic design, and I doubt that it 
would cut performance to an unacceptable level, especially 
because really performance-critical code would avoid the GC 
anyway.


You proposal allocate shared memory. This is common in C/C++ 
world as memory is shared by default, but shouldn't be in D. It 
is highly desirable to allocate with different methods for 
different type qualifier. How does your design adapt to that ?


If the aforementioned thread-local GC reference is implemented, 
it should be possible to provide decent thread-local allocation. 
I'm not sure exactly how to design that, but it seems like 
thread-local GC allocation would require some work at the GC 
level; a global GC won't necessarily play nicely with 
thread-local allocators.


For non-GC thread-local allocations, I'd imagine that you could 
just create a thread-local allocator.





Re: std.allocator needs your help

2013-09-23 Thread Walter Bright

On 9/23/2013 3:17 AM, Manu wrote:

Sure, true. But little things like separate it into its own lib, so you can
easily link a different one, or not link one at all.


To link in a different one, put the different one on the link command before 
libphobos2.a. The different one will override the one in the library.



Also, what about language support?


How it's done is deliberately not part of the language.


How much language support is there currently?


Zero.


I don't think I could currently write the ref-counting GC that I'd like without
extensive language support.
inc/dec ref calls would need to be inserted all over the place by he compiler,
and optimiser would need to know how to remove redundant inc/dec sequences.


A ref counting system is something entirely different than just plugging in 
another GC.


Re: std.allocator needs your help

2013-09-23 Thread deadalnix
On Monday, 23 September 2013 at 13:58:42 UTC, Andrei Alexandrescu 
wrote:
If the author forgets and hardcodes a library to use malloc(), 
I have no way around that.




We should consider the lib writer use new and/or automatic 
allocation like for closures. In practice, this is what will 
happen.


new will still be used to tap into the global shared GC. 
std.allocator will provide other means of allocating memory.




That uterly suck and we can do better using type informations.

At this point collect() is only implemented by the global GC. 
It is possible I'll drop it from the final design. However, 
it's also possible that collect() will be properly defined as 
collect all objects allocated within this particular allocator 
that are not referred from any objects also allocated within 
this allocator. I think that's a useful definition.




I don't think collect is usefull with no type information (not 
even if the data may contain pointers).


The D language has no idea what a range is. The notion is 
completely defined in std.range.




foreach has some idea of what a range is.


Re: compiled code file size

2013-09-23 Thread Sean Kelly
On Sep 21, 2013, at 8:49 AM, Manu turkey...@gmail.com wrote:

 On 21 September 2013 21:34, Temtaime temta...@gmail.com wrote:
 Are you saying about passing a function via pointer to winapi for example?
 The logic is simple: if someone gets function address, then function cannot 
 be stripped. It's logic of all c++ compilers.
 
 Totally OT, but every single time I read your name when you post, I can't 
 help but start hearing lines from Terry Prachett's Hogfather in my head…

Same here.


Re: compiled code file size

2013-09-23 Thread H. S. Teoh
On Sat, Sep 21, 2013 at 09:41:30PM +0200, Vladimir Panteleev wrote:
 On Friday, 20 September 2013 at 16:20:34 UTC, Duke Normandin wrote:
 I'm re-visiting the D language. I've compared the file sizes of 2
 executables - 1 is compiled C code using gcc; the other is D code
 using dmd.
 
 helloWorld.d = helloWorld.exe = 146,972 bytes
 ex1hello.c = ex1-hello.exe = 5,661 bytes
 
 Why such a huge difference???
 
 You can upload a .map file here, and see what's taking up all the
 space:
 http://thecybershadow.net/d/mapview/

Ah, you beat me to it. :-)


T

-- 
All problems are easy in retrospect.


Re: D2 is really that stable as it is claimed to be?

2013-09-23 Thread bearophile
Regarding the improving the error messages of D compilers, I 
think having the column number is nice, but there are two 
improvements that I think are more important:


1) One of them is the aka, that is showing both the name of 
aliases and the aliased types/values:

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

2) The other improvement I'd like for D error messages and 
warnings is to give a standard error number. This is a simple 
improvement, but it makes simpler to write explanation pages for 
the errors. The C# compiler and other compilers have them.


Bye,
bearophile


Re: [OT] Which IDE / Editor do you use?

2013-09-23 Thread Bruno Medeiros

On 23/09/2013 15:50, H. S. Teoh wrote:

I'm surprised at people talking about the amount of time spent
configuring stuff on Linux, etc., because it's never happened to me! I
mean, OK, in the early days you had to manually configure X11 and deal
with all of the obscure problems, but that's no longer the case today.
All I have to do is 'apt-get install package' and it Just Works(tm).


Yeah, that was several years ago. Nowadays the hardware support and 
configuration seems to work straight out from the box as well.

The remaining reasons that keep me away from Linux are other now.

--
Bruno Medeiros - Software Engineer


Re: std.allocator needs your help

2013-09-23 Thread Jacob Carlborg

On 2013-09-23 17:47, Manu wrote:


I like operator new. It goes blue, and the statement isn't riddled with
exclamation marks.


For Ruby, many editors and IDE's highlight standard built in functions 
as keywords. Like new, require, attr_accessor (and friends) to 
mention a few.



Imagine if new was a template (it would have to be a template).
Allocating a template would require nested template syntax every time,
which is pretty ugly.

   X x = new!(X!arg(args...)); // ewoo, paren spam...


Why not:

X x = new!X(args);

--
/Jacob Carlborg


Re: std.allocator needs your help

2013-09-23 Thread Robert Schadek
On 09/23/2013 07:16 PM, Andrei Alexandrescu wrote:
 On 9/23/13 10:01 AM, deadalnix wrote:

 Finally, we got to decide how these basics block are used to form typed
 allocators, and interact with language constructs.

 Sure. Again: I describe the Otto cycle and you discuss how to paint
 the road.
IMO there is a problem with this metaphor. If the road is painted
metallic the Otto motor (cycle) needs cooling, otherwise ... boom. So I
think the overall picture has to be kept in sight.



Re: std.allocator needs your help

2013-09-23 Thread Jacob Carlborg

On 2013-09-23 20:59, Jacob Carlborg wrote:


http://wiki.dlang.org/Runtime_Hooks


Search for new.

--
/Jacob Carlborg


Re: std.allocator needs your help

2013-09-23 Thread Jacob Carlborg

On 2013-09-23 16:05, Manu wrote:


Another situation that I've encountered on a few occasions...
Imagine I declare a particular allocator for my application, when
dealing with 3rd party libs, I expect it to allocate within my
application's heap. Seems like a situation where I might set a global
allocator...
Mr 3rd party library also has its own allocators though, things like
pools or groups which it uses explicitly within it's code.
I don't actually want to override these allocators, since they're
effectively a higher-level construct, but I *do* want to override these
allocator's memory source. Ie, they should allocate their pools from my
application's heap, rather than the default heap.
So in this way, it's important to be able to set overrides at multiple
levels.


You might be able to combine two different allocators. Basically create 
a new allocator that somehow extends the third party allocator but 
allocates in your own heap instead.


--
/Jacob Carlborg


Re: std.allocator needs your help

2013-09-23 Thread Jacob Carlborg

On 2013-09-23 17:03, Andrei Alexandrescu wrote:


I'd think new already is translated into a library call. Walter?


Yes, new is lowered to a couple different runtime functions. Here's a 
list:


http://wiki.dlang.org/Runtime_Hooks

--
/Jacob Carlborg


Re: D2 is really that stable as it is claimed to be?

2013-09-23 Thread Andrej Mitrovic
On 9/23/13, Andrej Mitrovic andrej.mitrov...@gmail.com wrote:
 I have a partial implementation of this in one of my branches

Also, I will not continue work on this unless Walter greenlights it.
I'm not going to put any work that's inevitably going to be thrown
away.


Re: std.allocator needs your help

2013-09-23 Thread Andrei Alexandrescu

On 9/23/13 11:24 AM, Walter Bright wrote:

On 9/23/2013 3:17 AM, Manu wrote:

Sure, true. But little things like separate it into its own lib, so
you can
easily link a different one, or not link one at all.


To link in a different one, put the different one on the link command
before libphobos2.a. The different one will override the one in the
library.


Also, what about language support?


How it's done is deliberately not part of the language.


How much language support is there currently?


Zero.


I think there's at least indirect support in e.g. generating typeinfo 
objects appropriately. Many of the components of those typeinfos are 
expressly defined for helping a tracing collector.


Andrei



Re: D2 is really that stable as it is claimed to be?

2013-09-23 Thread Andrej Mitrovic
On 9/23/13, bearophile bearophileh...@lycos.com wrote:
 1) One of them is the aka, that is showing both the name of
 aliases and the aliased types/values:
 http://d.puremagic.com/issues/show_bug.cgi?id=5004

I have a partial implementation of this in one of my branches, but
IIRC it was difficult do cover all cases since the compiler internally
inserts a bunch of aliases as well. Those could be marked that they're
internal, so that's fixable. Another issue I ran into is that
diagnostics are called after the retrieval of the aliased-to type,
which basically means by the time the compiler issues errors the alias
declaration is gone, the compiler only works on the target symbol. I
had a workaround for this, but it's going to take more work to get
done.


Re: D2 is really that stable as it is claimed to be?

2013-09-23 Thread Jacob Carlborg

On 2013-09-21 23:12, Andrei Alexandrescu wrote:


I'm ambivalent because the matter is fuzzy. It is factually true that
new releases will break code. On the other hand, that is the case with
most compiler releases even for mature languages (at Facebook upgrading
across minor gcc releases _always_ entails significant disruption). On
the third hand (sic), there are companies and projects using D in the
real world so stating that is unstable would do little else than either
shoo people away for no good reason.


Some of these companies still use D1.

About the code breakage. I think it's still an issue that bugfixes and 
language changes occur in the same release. No notation of major, minor 
and patch releases.


--
/Jacob Carlborg


Re: std.allocator needs your help

2013-09-23 Thread Andrei Alexandrescu

On 9/23/13 11:59 AM, Jacob Carlborg wrote:

On 2013-09-23 17:03, Andrei Alexandrescu wrote:


I'd think new already is translated into a library call. Walter?


Yes, new is lowered to a couple different runtime functions. Here's a
list:

http://wiki.dlang.org/Runtime_Hooks


Thanks, this is great.

Currently new is fail because it calls functions passing TypeInfo 
objects, instead of calling type-parameterized functions. We must change 
that to have new T(args) lower into .opNew!T(args). Then object.d 
defines that function.



Andrei



Re: std.allocator needs your help

2013-09-23 Thread Andrei Alexandrescu

On 9/23/13 11:55 AM, Robert Schadek wrote:

On 09/23/2013 07:16 PM, Andrei Alexandrescu wrote:

On 9/23/13 10:01 AM, deadalnix wrote:


Finally, we got to decide how these basics block are used to form typed
allocators, and interact with language constructs.


Sure. Again: I describe the Otto cycle and you discuss how to paint
the road.

IMO there is a problem with this metaphor. If the road is painted
metallic the Otto motor (cycle) needs cooling, otherwise ... boom. So I
think the overall picture has to be kept in sight.



Which makes the metaphor unintentionally better. Yes, we do need to 
worry about higher concerns because that's how layerd abstractions work.


Andrei



Re: Download page needs a tidy up

2013-09-23 Thread Flamaros
On Thursday, 22 August 2013 at 13:14:01 UTC, Ludovit Lucenic 
wrote:

On Thursday, 22 August 2013 at 03:23:57 UTC, Manu wrote:
I got the latest GDC from dlang.org/download, but it doesn't 
work.
libiconv-2.dll (and possibly others?) is not included in the 
package.


If this depends on another package being present, there is no 
text anywhere

along the download path to inform the user.


On 22 August 2013 13:07, Manu turkey...@gmail.com wrote:


So I'm trying to find windows binaries for GDC and LDC...

First place I look is dlang.org/download. Appears to be for 
DMD... keep

looking.

I look at the GDC/LDC wiki pages. No links to binaries 
anywhere.

GDC and LDC home pages... no links to binaries.
Github doesn't host binaries anymore...

Where are they?

Turns out there are links to the GDC binaries (hosted on 
bitbucket) on

dlang.org/download.
...I didn't previously notice they were there, never scrolled 
down far
enough. The impression you get from the top of the page is 
that dlang.orgis just DMD related, and I quickly dismissed it 
previously _


But there's still no LDC binary there... where is it?

This needs to be fixed. You can argue I'm retarded and 
ignorant, but as an
end user, it should take me no more than 5 seconds to find 
the download

button.

I suggest, on the front page of dlang.org, there should be a 
MASSIVE
button: DOWNLOAD D COMPILERS, and the download page should 
be tweaked to

be more obviously compiler agnostic.

D1 and DMC consume an unreasonable amount of realestate, 
hiding GDC/LDC
(surely basically nobody is looking for those?), perhaps they 
should be
reduced to small test links with the other links down the 
bottom of the

page?
This will allow room to present GDC and LDC without scrolling.

And why is there no LDC binary?


I am completely with you, Manu.
Same with me with GDC under Windows. Missing libiconv-2.dll...
The same happened to me when looking around for the other two D 
compilers. It took me a couple of days until I found the link 
on the dlang.org's download page.


Any suggestions on where to get a working copy of GDC to run on 
Windows, please?


Thanks,
Ludovit


I want to try gdc and I get the same error on libiconv-2.dll


Re: D2 is really that stable as it is claimed to be?

2013-09-23 Thread Timon Gehr

On 09/22/2013 09:27 PM, Walter Bright wrote:

On 9/22/2013 11:43 AM, Timon Gehr wrote:

Tracking line numbers is likely worth it. I don't believe that
providing column
numbers in error messages necessitates a slowdown though.


Please consider that:

  IT ISN'T JUST FOR ERROR MESSAGES

It would go in the symbolic debug info, too, where it will be required
everywhere and will be right there on the fast path through the
lexer/compiler.
...


There is no such thing as a law that obliges compiler writers to add 
column numbers in debug info when such information is available in 
frontend error messages. The trade-offs involved in both cases may be 
different and deserve separate consideration.



Now consider the lexer doing a fast skip over comment text (this ranks
fairly high in the profile). This operation gets a lot slower if you're
also keeping track of column number.


I am not keeping track of column number.


Please note that:

  COLUMN NUMBER ISN'T THE OFFSET FROM THE START OF THE LINE
...


Obviously. I compute the correct column number exactly in the case when 
an error message should actually be printed. It is not necessary to do 
any of this on the fast path. The additional memory word per location 
that I waste in comparison to DMD could be shaved off by using more 
computation in the error case (or by giving up support for exact 
underlining), but the project has not yet reached a stage where this is 
worth considering/measuring.


Excerpts from actual code I wrote roughly two years ago:

class Source{
// computes a slice of the entire first line
// where some given slice occurs in the source buffer.
// this allows to recover column information on the fly, and we
// will also be able to print the line where an error occurred
// without storing it explicitly.
// running time is linear in output length
string getLineOf(string rep)in{/*...*/}out{/*...*/}body{
string before=code[0..rep.ptr-code.ptr];
string after=code[rep.ptr-code.ptr..$];
immutable(char)* start=code.ptr, end=code.ptr+code.length;

// It is fine to skip decoding here, because we are just
// searching for ASCII characters.
// TODO: support unicode line breaks?
foreach_reverse(ref c; before)
if(c=='\n'||c=='\r'){start = c+1; break;}
foreach(ref c; after)
if(c=='\n'||c=='\r'){end = c; break;}
return start[0..end-start];
}
// ...
}

struct Location{
string rep;// slice of the code representing the Location
int line;  // line number at start of location

@property Source source()const{
auto src = Source.get(rep); // (currently just a linear search)
assert(src, source for '~rep~' not found!);
return src;
}
// ...
}

int getColumn(Location loc, int tabsize){
int res=1;
auto l=loc.source.getLineOf(loc.rep);
for(;!l.emptyl[0]l.ptrloc.rep.ptr; l.popFront()){
if(l.front=='\t') res=res-res%tabsize+tabsize;
else res++;
}
return res;
}





Re: std.allocator needs your help

2013-09-23 Thread Robert Schadek
On 09/23/2013 09:11 PM, Andrei Alexandrescu wrote:
 On 9/23/13 11:55 AM, Robert Schadek wrote:
 On 09/23/2013 07:16 PM, Andrei Alexandrescu wrote:
 On 9/23/13 10:01 AM, deadalnix wrote:

 Finally, we got to decide how these basics block are used to form
 typed
 allocators, and interact with language constructs.

 Sure. Again: I describe the Otto cycle and you discuss how to paint
 the road.
 IMO there is a problem with this metaphor. If the road is painted
 metallic the Otto motor (cycle) needs cooling, otherwise ... boom. So I
 think the overall picture has to be kept in sight.


 Which makes the metaphor unintentionally better. Yes, we do need to
 worry about higher concerns because that's how layerd abstractions work.

 Andrei

You're right! And I'm to tired to read properly.


Re: Debugging support for D - wiki

2013-09-23 Thread Michael

What about Win64 and VS Debugger?


Debugging support for D - wiki

2013-09-23 Thread Bruno Medeiros
I'm looking to begin adding integrated debugger support for the DDT IDE 
pretty soon. With this in mind it would be desirable to have a view of 
what level of D language debugger support is there for the various 
combinations of platform+compiler+debugger.


This information would be quite beneficial to regular D users as well, 
as Manu's recent thread on the importance of a debugger is any 
indication of. Yet there doesn't seem to be any info about this in the 
wiki. The debuggers wiki page ( http://wiki.dlang.org/Debuggers ) 
doesn't even list the main players in this scene (VisualD/Mago, GDB, 
WinDebugger?)



I might get started with this, but I would need to enlist the help of 
other people for the other platforms/debuggers I don't have proper acess to.


The only combinations I tried so far was DMD+Windows+GDB, which seems 
like it's not supported at all. And GDC+Windows32+GDB which does seem to 
be well supported (GDB understands D name mangling, breakpoints in 
source, D data structures layout, etc.). I'm guessing GDC+GDB on Linux 
works just as well. (what about Mac though?)


Several questions remain:
Is debugger support with DMD+Linux+GDB as good as it is with GDC?
For DMD+Windows, is there only good debugger support with VisualD? :-(
And how well does that work with 32/64 bit platform variations?

It would be great to have these answered, and going forward, keeping 
track of this info in the wiki.


--
Bruno Medeiros - Software Engineer


Re: Move VisualD to github/d-programming-language ?

2013-09-23 Thread Bruno Medeiros

On 18/09/2013 14:41, eles wrote:

On Wednesday, 18 September 2013 at 13:21:45 UTC, Bruno Medeiros
wrote:

On 18/09/2013 07:58, eles wrote:
Not yet.


How could I help?


Actually, check my thread Debugging support for D - wiki. You might be 
able to help with research and trying out debuggers for configurations I 
can't (or simply haven't) tried myself.


--
Bruno Medeiros - Software Engineer


Re: std.allocator needs your help

2013-09-23 Thread Walter Bright

On 9/23/2013 12:09 PM, Andrei Alexandrescu wrote:

I think there's at least indirect support in e.g. generating typeinfo objects
appropriately. Many of the components of those typeinfos are expressly defined
for helping a tracing collector.


Those are not language features.

Also, the latest support for that is done with a library-defined template.



Re: std.allocator needs your help

2013-09-23 Thread Dmitry Olshansky

23-Sep-2013 22:52, Jacob Carlborg пишет:

On 2013-09-23 17:47, Manu wrote:



Imagine if new was a template (it would have to be a template).
Allocating a template would require nested template syntax every time,
which is pretty ugly.

   X x = new!(X!arg(args...)); // ewoo, paren spam...


Why not:

X x = new!X(args);



+1 Or call it make for the time being so as to not collide with the keyword.

--
Dmitry Olshansky


Re: Download page needs a tidy up

2013-09-23 Thread Bruno Medeiros

On 22/08/2013 04:23, Manu wrote:

I got the latest GDC from dlang.org/download
http://dlang.org/download, but it doesn't work.
libiconv-2.dll (and possibly others?) is not included in the package.

If this depends on another package being present, there is no text
anywhere along the download path to inform the user.




I just had the same problem today. I opened a thread in the GDC 
newsgroup to see if this can be rectified ( 
news://news.digitalmars.com:119/l1q33o$2m6i$1...@digitalmars.com ) as even 
on the GDC website there is no such info.


But regardless, http://dlang.org/download should be updated as well. I 
agree on the point that is quite beneficial to D to have this 
information tidied up and better presented for new (and existing) D 
users. (even I took a while to figure out that I needed TDM-GCC in 
addition to the GDC packages in 
https://bitbucket.org/goshawk/gdc/downloads - and it's an installation 
procedure I've done in the past as well, but had forgotten).


--
Bruno Medeiros - Software Engineer


Re: std.allocator needs your help

2013-09-23 Thread Walter Bright

On 9/23/2013 9:47 AM, Benjamin Thaut wrote:

I always understood void[] as block of unkown data.


Untyped data, not unknown data.



Re: std.allocator needs your help

2013-09-23 Thread Walter Bright

On 9/23/2013 10:08 AM, Andrei Alexandrescu wrote:

I'm unclear on what void[] means starting from its semantics.


I agree that it should be void[], as that represents (in D) a block of untyped 
data. void[] should be ideal for a primitive allocator.




Re: Download page needs a tidy up

2013-09-23 Thread Bruno Medeiros

On 22/08/2013 14:13, Ludovit Lucenic wrote:

On Thursday, 22 August 2013 at 03:23:57 UTC, Manu wrote:

I got the latest GDC from dlang.org/download, but it doesn't work.
libiconv-2.dll (and possibly others?) is not included in the package.

If this depends on another package being present, there is no text
anywhere
along the download path to inform the user.


On 22 August 2013 13:07, Manu turkey...@gmail.com wrote:


So I'm trying to find windows binaries for GDC and LDC...

First place I look is dlang.org/download. Appears to be for DMD... keep
looking.

I look at the GDC/LDC wiki pages. No links to binaries anywhere.
GDC and LDC home pages... no links to binaries.
Github doesn't host binaries anymore...

Where are they?

Turns out there are links to the GDC binaries (hosted on bitbucket) on
dlang.org/download.
...I didn't previously notice they were there, never scrolled down far
enough. The impression you get from the top of the page is that
dlang.orgis just DMD related, and I quickly dismissed it previously _

But there's still no LDC binary there... where is it?

This needs to be fixed. You can argue I'm retarded and ignorant, but
as an
end user, it should take me no more than 5 seconds to find the download
button.

I suggest, on the front page of dlang.org, there should be a MASSIVE
button: DOWNLOAD D COMPILERS, and the download page should be
tweaked to
be more obviously compiler agnostic.

D1 and DMC consume an unreasonable amount of realestate, hiding GDC/LDC
(surely basically nobody is looking for those?), perhaps they should be
reduced to small test links with the other links down the bottom of the
page?
This will allow room to present GDC and LDC without scrolling.

And why is there no LDC binary?


I am completely with you, Manu.
Same with me with GDC under Windows. Missing libiconv-2.dll...
The same happened to me when looking around for the other two D
compilers. It took me a couple of days until I found the link on the
dlang.org's download page.

Any suggestions on where to get a working copy of GDC to run on Windows,
please?

Thanks,
Ludovit


Check out: http://forum.dlang.org/thread/l1q33o$2m6i$1...@digitalmars.com

I haven't tried the 64 bit alternative though (which has a more recent 
DMD frontend version: 2.060)


--
Bruno Medeiros - Software Engineer


Re: std.allocator needs your help

2013-09-23 Thread Andrei Alexandrescu

On 9/23/13 1:04 PM, Walter Bright wrote:

On 9/23/2013 10:08 AM, Andrei Alexandrescu wrote:

I'm unclear on what void[] means starting from its semantics.


I agree that it should be void[], as that represents (in D) a block of
untyped data. void[] should be ideal for a primitive allocator.


Great, made that change, it all works. Does void[] make any promise 
about alignment?


Andrei



Re: std.allocator needs your help

2013-09-23 Thread Timon Gehr

On 09/23/2013 01:49 AM, Andrei Alexandrescu wrote:

I am making good progress on the design of std.allocator, and I am
optimistic about the way it turns out. D's introspection capabilities
really shine through, and in places the design does feel really
archetypal - e.g. this is the essence of a freelist allocator. It's a
very good feeling. The overall inspiration comes from Berger's
HeapLayers, but D's introspection takes that pattern to a whole new level.
...


Seems neat.


Several details are still in flux, but at the top level it seems most
natural to divide things in two tiers:

1. Typed allocator, i.e. every request for allocation comes with the
exact type requested;

2. Untyped allocator - traffics exclusively in ubyte[].
...


Some general remarks:

One issue you will probably run into and maybe want to fix in some way 
during the typed allocator design is that private constructors cannot be 
called from templates parameterized on types.


E.g.:

module a;

auto New(T,Args...)(Args args){
return new T(args);
}

// ---

module b;

class A{
private this(){}
}

void main(){
auto a = New!A(); // error
}

Is there an intention to also support replacements of instance new 
allocations, i.e. object.new subobject(args)?


Re: std.allocator needs your help

2013-09-23 Thread Peter Alexander
On Sunday, 22 September 2013 at 23:49:56 UTC, Andrei Alexandrescu 
wrote:
1. Typed allocator, i.e. every request for allocation comes 
with the exact type requested;


2. Untyped allocator - traffics exclusively in ubyte[].


This is a good design.

Perhaps this is a later concern, but we should make sure that 
node-based containers (e.g. linked list, trees) have a way to 
access the allocation size needed for the node. STL did not do 
this.



* alignment is a compile-time constant yielding the alignment 
of allocated data. Many allocators offer the maximum alignment 
of the platform (for which I used real.alignof above). This 
constant is required for all allocators.


What if, for example, I wanted to allocate a 4096 byte aligned 
block from the GC allocator? Do I have to create a new allocator 
backed by the GC allocator?


What if the alignment is not known at compile time (e.g. hard 
disk page size or CPU cache line size)?


Might be better to pass the desired alignment in the allocate 
method.



* available is a property that returns how many total (not 
necessarily contiguous) bytes are available for allocation. The 
NullAllocator knows statically it has 0 bytes available so it 
implements it as an enum. Generally allocators will implement 
it as a @property. This property is optional.


It would be useful to know the maximum available contiguous block 
size too, so that you can find out if an allocation will succeed 
without calling allocate. It's also useful for diagnosing 
fragmentation issues e.g. allocation failed, free memory = X, 
max contiguous = Y. If X is high and Y is low then you are 
highly fragmented.


Of course, this should be optional.


* allocate(s) returns a ubyte[] with length at least s, or 
null. (It does not throw on out-of-memory because that would 
hurt composability; it turns out many elemental allocators do 
naturally run out of memory.) This method is required for all 
allocators. In most allocators this method should be @safe.


What are the semantics of allocate(0)? malloc(0) is 
implementation defined.


Re: std.allocator needs your help

2013-09-23 Thread Andrei Alexandrescu

On 9/23/13 1:32 PM, Timon Gehr wrote:

One issue you will probably run into and maybe want to fix in some way
during the typed allocator design is that private constructors cannot be
called from templates parameterized on types.


Hrm, that's a real problem. We've ran into it at work when we were 
trying to replace a macro with a template. The macro is automatically 
friend with everyone! :o)



Is there an intention to also support replacements of instance new
allocations, i.e. object.new subobject(args)?


It's a good point to keep in mind as we move further with this.


Andrei



Re: [OT] Which IDE / Editor do you use?

2013-09-23 Thread Nick Sabalausky
On Mon, 23 Sep 2013 07:50:43 -0700
H. S. Teoh hst...@quickfur.ath.cx wrote:

 On Mon, Sep 23, 2013 at 02:01:02PM +0200, Dicebot wrote:
  
  Ironically, this is exactly the reason I have never succeeded in
  using the Windows for daily work. Amount of manual configuration and
  subverting the defaults needed to make it actually usable for my
  programming flow is outstanding. In the same time on my Linux distro
  it is mostly `pacman -Sy gnome gnome-extra xorg-server nvidia dlang
  vim git` and I am ready to work on a fresh install.
 
 Ditto.

Similar here, at least these days. Last time I got a new system, it had
Win7 preinstalled. I'd already been using Windows as my primary
system (for ages), but it took me about *a week or two* of googling and
tweaking and third party hacks before I had finally got it to a point
that was more or less usable (but still frequently irritating and
impractical).

 
 I'm surprised at people talking about the amount of time spent
 configuring stuff on Linux, etc., because it's never happened to me! I
 mean, OK, in the early days you had to manually configure X11 and deal
 with all of the obscure problems, but that's no longer the case today.
 All I have to do is 'apt-get install package' and it Just Works(tm).
 

Yea, I find installing software is often (not always, but often)
*easier* on Linux these days, thanks to apt and such. It used to be a
nightmare of dependency issues in the days of dpkg/rpm[1]. But now,
most of the time it's just one trivial command. Done. Or if you prefer
GUIs, the...uhh...what's it called, Synaptec?, is just as easy, *and*
good for discoverability: It's basically a freeware app store, but
Linux had it even *before* iOS.

And when you install a GUI app it puts *one* item in the start menu,
not Company Name - Program Name - Tons of Junk including docs and an
uninstall link that's right next to the launch link

Of course, sometimes windows is still easier, too. I get so frustrated
when I discover some Posix program through the web and it gives *no*
indication how to download or install it because they just assume
it's already in everyone's distro repos and that everyone knows what
their distro named the package, and that you're installing it *on* the
same Posix distro you're already familiar with.

For example, last night I tried to install the cmdline 7z on an OSX
machine, and after nearly an hour of completely useless *official*
webpages, and screwing around with sources, etc, I gave up.

[1] Of course I know dpkg/rpm are still there under the hood.

 I do like to tweak stuff -- and this is where Windows falls flat for
 me, 'cos it forces you to work a certain way, and when you go outside
 of that, things just stop working or it becomes an uphill battle
 (disclaimer: I haven't touched Windows for over a decade, so this may
 no longer be true today)

That's actually *more* true now than it was with XP. MS used to be
pretty big on preferences, customization, etc (maybe not *AS* much as
Linux, but still). But lately they've been very noticeably trying to
become Apple/Mozilla, complete with forcing every change on everybody
and minimizing how much they'll allow you to revert any of their
endless stream of crazy UI flavor of the month ideas.



Re: std.allocator needs your help

2013-09-23 Thread Andrei Alexandrescu

On 9/23/13 1:37 PM, Peter Alexander wrote:

What if, for example, I wanted to allocate a 4096 byte aligned block
from the GC allocator? Do I have to create a new allocator backed by the
GC allocator?


I've been thinking a good library component would be AlignmentAllocator 
that would work like this:


struct AlignmentAllocator(Allocator, size_t desiredAlignment)
if (Allocator.alignment  desiredAlignment)
{
enum alignment = desiredAlignment;
...
}

That allocator would allocate more memory (I suspect there's a gcd 
calculation somewhere :o)) and then adjust the starting pointer of the 
allocated block to reach the requested alignment.


I'm just off the phone with Walter discussing this and related issue. 
It's an interesting problem space.



What if the alignment is not known at compile time (e.g. hard disk page
size or CPU cache line size)?


The proposed design assumes compile-time allocation sizes. A trick 
similar to the one above (overallocate and adjust pointer) should work.


I'd need a handful of good examples where the alignment must be known at 
runtime. Can you link to some?



Might be better to pass the desired alignment in the allocate method.


The thing is in 99%+ of the cases you don't need it. Then perhaps in 
99%+ of the remaining cases the alignment is known during compilation. 
Nevertheless it's a change worth investigating.



* available is a property that returns how many total (not necessarily
contiguous) bytes are available for allocation. The NullAllocator
knows statically it has 0 bytes available so it implements it as an
enum. Generally allocators will implement it as a @property. This
property is optional.


It would be useful to know the maximum available contiguous block size
too, so that you can find out if an allocation will succeed without
calling allocate.


I think the best way is to just go ahead and attempt an allocation, 
especially if the allocator is shared (races!). (There's some 
flexibility with expand() there, which has a minimum size and a desired 
size.) But clearly the information of the largest contiguous block is 
currently missing, and is reasonable to be considered for addition.



It's also useful for diagnosing fragmentation issues
e.g. allocation failed, free memory = X, max contiguous = Y. If X is
high and Y is low then you are highly fragmented.

Of course, this should be optional.


Makes sense.


* allocate(s) returns a ubyte[] with length at least s, or null. (It
does not throw on out-of-memory because that would hurt composability;
it turns out many elemental allocators do naturally run out of
memory.) This method is required for all allocators. In most
allocators this method should be @safe.


What are the semantics of allocate(0)? malloc(0) is implementation defined.


I defined Mallocator to return whatever malloc returns on allocate(0), 
but decided realloc() is too messed up and special-cased reallocate(0) 
to free memory and place null in the buffer. Probably I'll work the same 
logic in Mallocator.allocate(0) to eliminate platform dependencies.



Andrei



Re: std.allocator needs your help

2013-09-23 Thread Walter Bright

On 9/23/2013 1:18 PM, Andrei Alexandrescu wrote:

Does void[] make any promise about alignment?


No.



  1   2   >