Re: may gc free malloced memory?

2013-09-12 Thread monarch_dodra
On Thursday, 12 September 2013 at 05:36:31 UTC, Alexandr 
Druzhinin wrote:
Some C function malloc-ed memory. This memory should be freeed 
much later. I don't want to manually call C function to free 
this memory in some point later, so may I in some way ask gc to 
free this memory using something like addRoot(for instance) or 
else or the true way is to copy malloc-ed memory to 
gc-allocated memory and free malloc-ed memory at once? Like:


ubyte data* = cfunction_allocates_memory();
auto gcmemory = data[0..length(data)];
cfunction_frees_memory(data);
// work with gcmemory only

or

ubyte data* = cfunction_allocates_memory();
GC.someUnknownToMeFunction(data); // now gc will control this 
memory


No.

Only free can be used with malloc. The memory comes from distinct 
pools.


Another option could be to use GC.malloc, and memcpy your old 
mmory into your new memory, free the old memory, and use your new 
block. GC.malloc, as the name suggests, is a malloc, but done by 
the GC.


Re: Greedy memory handling

2013-09-12 Thread Jacob Carlborg

On 2013-09-11 10:06, monarch_dodra wrote:

I have a function that will *massively* benefit from having a persistent
internal buffer it can re-use (and grow) from call to call, instead of
re-allocating on every call.

What I don't want is either of:
1. To set a fixed limitation of size, if the user ends up making
repeated calls to something larger to my fixed size.
2. For a single big call which will allocate a HUGE internal buffer that
will consume all my memory.

What I need is some sort of lazy buffer. Basically, the allocation
holds, but I don't want the to prevent the GC from collecting it if it
deems it has gotten too big, or needs more memory.

Any idea on how to do something like that? Or literature?


How about keeping a stack or static buffer. If that gets too small use a 
new buffer. When you're done with the new buffer set it to null to allow 
the GC to collect it. Then repeat.


--
/Jacob Carlborg


Re: may gc free malloced memory?

2013-09-12 Thread Rene Zwanenburg

On Thursday, 12 September 2013 at 05:59:33 UTC, monarch_dodra
wrote:
On Thursday, 12 September 2013 at 05:36:31 UTC, Alexandr 
Druzhinin wrote:
Some C function malloc-ed memory. This memory should be freeed 
much later. I don't want to manually call C function to free 
this memory in some point later, so may I in some way ask gc 
to free this memory using something like addRoot(for instance) 
or else or the true way is to copy malloc-ed memory to 
gc-allocated memory and free malloc-ed memory at once? Like:


ubyte data* = cfunction_allocates_memory();
auto gcmemory = data[0..length(data)];
cfunction_frees_memory(data);
// work with gcmemory only

or

ubyte data* = cfunction_allocates_memory();
GC.someUnknownToMeFunction(data); // now gc will control this 
memory


No.

Only free can be used with malloc. The memory comes from 
distinct pools.


Another option could be to use GC.malloc, and memcpy your old 
mmory into your new memory, free the old memory, and use your 
new block. GC.malloc, as the name suggests, is a malloc, but 
done by the GC.


You could also use some kind of helper class. Perhaps Phobos has
a facility for this, but to illustrate the idea:
http://dpaste.dzfl.pl/805a61c0

However note that the memory isn't guaranteed to be freed this
way. Only if the GC heap gets full and the collector runs.


Re: may gc free malloced memory?

2013-09-12 Thread Alexandr Druzhinin

12.09.2013 14:45, Rene Zwanenburg пишет:

On Thursday, 12 September 2013 at 05:59:33 UTC, monarch_dodra
wrote:

On Thursday, 12 September 2013 at 05:36:31 UTC, Alexandr Druzhinin wrote:

Some C function malloc-ed memory. This memory should be freeed much
later. I don't want to manually call C function to free this memory
in some point later, so may I in some way ask gc to free this memory
using something like addRoot(for instance) or else or the true way is
to copy malloc-ed memory to gc-allocated memory and free malloc-ed
memory at once? Like:

ubyte data* = cfunction_allocates_memory();
auto gcmemory = data[0..length(data)];
cfunction_frees_memory(data);
// work with gcmemory only

or

ubyte data* = cfunction_allocates_memory();
GC.someUnknownToMeFunction(data); // now gc will control this memory


No.

Only free can be used with malloc. The memory comes from distinct pools.

Another option could be to use GC.malloc, and memcpy your old mmory
into your new memory, free the old memory, and use your new block.
GC.malloc, as the name suggests, is a malloc, but done by the GC.


You could also use some kind of helper class. Perhaps Phobos has
a facility for this, but to illustrate the idea:
http://dpaste.dzfl.pl/805a61c0

However note that the memory isn't guaranteed to be freed this
way. Only if the GC heap gets full and the collector runs.
Ok. I just think that copying from one pool to another is excessive and 
may be there is a some way to avoid it.

Thanks for the answers!


Re: VisualD import

2013-09-12 Thread QAston
On Wednesday, 11 September 2013 at 22:15:07 UTC, Rainer Schuetze 
wrote:



On 11.09.2013 23:42, Lemonfiend wrote:
On Wednesday, 11 September 2013 at 20:36:39 UTC, Rainer 
Schuetze wrote:



On 11.09.2013 18:13, Lemonfiend wrote:

Oops, I forgot to say what I actually did.

I added derelict to Compiler-General-Additional Imports.

The code is just this:

module main;

import std.stdio;
import derelict.opengl3.gl3;

void main()
{
   writeln(Hello D-World!);
}


And the build output is a symbol undefined linker issue:

-- Rebuild All started: Project: Test, Configuration: 
Debug Win32

--
Building Debug\Test.exe...
OPTLINK (R) for Win32  Release 8.00.12
Copyright (C) Digital Mars 1989-2010  All rights reserved.
http://www.digitalmars.com/ctg/optlink.html
Debug\Test.obj(Test)
Error 42: Symbol Undefined 
_D8derelict7opengl33gl312__ModuleInfoZ

Building Debug\Test.exe failed!
Details saved as 
file://C:\D\Test\Test\Debug\Test.buildlog.html

Build time: 3 s
Solution build stopped.
Build has been canceled.


Did you add the derelict library/libraries as linker inputs?


I haven't compiled derelict to a lib, I'm using the source 
directly.

With rdmd I can simply do -Ipath\to\derelict\source


The compilation model of rdmd is not supported by Visual D. You 
might be able to use rdmd as other compiler in the project 
options with additional options --build-only.


On the other hand, you can also create a library from the 
project templates, then drag the source folder into the project 
to add all files. Then set a project dependency of your 
application to the library.


You can also create a dub package and generate visuald project 
from dub.


override and package

2013-09-12 Thread Namespace

Code:

import std.stdio;

class T1 {
protected:
void _apply() {
writeln(Call T1);
}
}

class T2 : T1 {
public:
override void _apply() {
writeln(Call T2);
}
}

class T3 : T1 {
protected:
override void _apply() {
writeln(Call T3);
}
}

class T4 : T1 {
package:
void _apply() { /// -- [1]
writeln(Call T4);
}
}

void main()
{
T1 t1 = new T1();
T2 t2 = new T2();
T3 t3 = new T3();
T4 t4 = new T4();

t1._apply();
t2._apply();
t3._apply();
t4._apply();
}


Produce the correct output:
Call T1
Call T2
Call T3
Call T4

If I remove 'override' from T3 (or also T2) I get the correct 
deprecation message:
/d172/f194.d(19): Deprecation: overriding base class function 
without using override attribute is deprecated (f194.T3._apply 
overrides f194.T1._apply)


But if I try to write 'override' before [1], I get this error 
message:

Error: function T4._apply cannot override a non-virtual function

This seems inconsistent. I really overwrite the method, and then 
I put it in a package label.


Re: override and package

2013-09-12 Thread Namespace

Same with private, of course.


Re: Adding libraries to an executable

2013-09-12 Thread Anton Alexeev

On Thursday, 12 September 2013 at 01:16:28 UTC, Mike Parker wrote:

On 9/12/2013 6:20 AM, Anton Alexeev wrote:
On Tuesday, 10 September 2013 at 11:06:04 UTC, Jacob Carlborg 
wrote:

On 2013-09-10 11:04, Anton Alexeev wrote:


Can be but not libphobos2


Link statically with it, which is does by default. Just 
compile with:


dmd -L-lcurl test.d


The point is:
http://pastebin.com/0VkYgFix


Apparently you need to install the libcurl dev package. The 
linker can't find libcurl.a.


I've installed libcurl4-openssl-dev 7.29.0-1ubuntu3.1 before I 
asked for help here. Else I can't even compile with that command: 
dmd -L-lphobos2 -L-lcurl test.d


Re: override and package

2013-09-12 Thread Jacob Carlborg

On 2013-09-12 11:28, Namespace wrote:


But if I try to write 'override' before [1], I get this error message:
Error: function T4._apply cannot override a non-virtual function

This seems inconsistent. I really overwrite the method, and then I put
it in a package label.


I think the error message is pretty clear. You cannot override a 
function that isn't virtual. Private and package methods are not 
virtual. Example:


class Base
{
void foo ()
{
writeln(Base.foo);
}
}

class Sub : Base
{
package void foo ()
{
writeln(Sub.foo);
}
}

void main ()
{
auto sub = new Sub;
sub.foo(); // prints Sub.foo as expected

Base base = sub;
base.foo(); // prints Base.foo
}

--
/Jacob Carlborg


Re: Adding libraries to an executable

2013-09-12 Thread Jacob Carlborg

On 2013-09-12 12:14, Anton Alexeev wrote:


I've installed libcurl4-openssl-dev 7.29.0-1ubuntu3.1 before I asked for
help here. Else I can't even compile with that command: dmd -L-lphobos2
-L-lcurl test.d


How does your dmd.conf file look like?

--
/Jacob Carlborg


Re: override and package

2013-09-12 Thread Namespace
On Thursday, 12 September 2013 at 11:29:22 UTC, Jacob Carlborg 
wrote:

On 2013-09-12 11:28, Namespace wrote:

But if I try to write 'override' before [1], I get this error 
message:
Error: function T4._apply cannot override a non-virtual 
function


This seems inconsistent. I really overwrite the method, and 
then I put

it in a package label.


I think the error message is pretty clear. You cannot override 
a function that isn't virtual. Private and package methods are 
not virtual. Example:


class Base
{
void foo ()
{
writeln(Base.foo);
}
}

class Sub : Base
{
package void foo ()
{
writeln(Sub.foo);
}
}

void main ()
{
auto sub = new Sub;
sub.foo(); // prints Sub.foo as expected

Base base = sub;
base.foo(); // prints Base.foo
}


Obvious. But what happend? Is the original _apply hidden?


Re: override and package

2013-09-12 Thread Jacob Carlborg

On 2013-09-12 13:34, Namespace wrote:


Obvious. But what happend? Is the original _apply hidden?


If you call through an object of the same type, T4 in this case, the 
method in the base class is hidden. If you call through a base class 
reference, T1 in this case, the _apply method in the subclass is hidden.


--
/Jacob Carlborg


Re: override and package

2013-09-12 Thread Jacob Carlborg

On 2013-09-12 13:39, Jacob Carlborg wrote:


If you call through an object of the same type, T4 in this case, the
method in the base class is hidden. If you call through a base class
reference, T1 in this case, the _apply method in the subclass is hidden.


I'm guessing it's the same as overriding non-virtual methods in C++, if 
you're familiar with that.


--
/Jacob Carlborg


Re: __FILE__ and __LINE__ again...

2013-09-12 Thread Dicebot

On Tuesday, 10 September 2013 at 16:58:54 UTC, H. S. Teoh wrote:

On Tue, Sep 10, 2013 at 06:50:03PM +0200, Dicebot wrote:
On Tuesday, 10 September 2013 at 16:45:33 UTC, H. S. Teoh 
wrote:
but you can get rid of this with link-time optimization (on 
Posix,
you'd add -L-gc-sections to your dmd command-line: this will 
cause ld
to delete code sections that are never referenced, which 
includes the

log() instantiations if indeed they have been inlined).

Using `--gc-sections` requires each function and data item to 
be
placed into its own section (-fdata-sections and 
-ffunction-sections

in gcc). AFAIK dmd does not do it.


Hmm. Does that mean gdc supports that, then?


Actually I was wrong, looks like DMD does section differentiation 
by default. I am wondering if --gc-sections should be made 
default on Linux targets...


Re: Greedy memory handling

2013-09-12 Thread H. S. Teoh
On Thu, Sep 12, 2013 at 08:27:59AM +0200, Jacob Carlborg wrote:
 On 2013-09-11 10:06, monarch_dodra wrote:
 I have a function that will *massively* benefit from having a
 persistent internal buffer it can re-use (and grow) from call to
 call, instead of re-allocating on every call.
 
 What I don't want is either of:
 1. To set a fixed limitation of size, if the user ends up making
 repeated calls to something larger to my fixed size.
 2. For a single big call which will allocate a HUGE internal buffer
 that will consume all my memory.
 
 What I need is some sort of lazy buffer. Basically, the allocation
 holds, but I don't want the to prevent the GC from collecting it if
 it deems it has gotten too big, or needs more memory.
 
 Any idea on how to do something like that? Or literature?
 
 How about keeping a stack or static buffer. If that gets too small
 use a new buffer. When you're done with the new buffer set it to
 null to allow the GC to collect it. Then repeat.
[...]

The problem is, he wants to reuse the buffer next time if the GC hasn't
collected it yet.

Here's an idea, though. It doesn't completely solve the problem, but it
just occurred to me that weak pointers (i.e., ignored by the GC for
the purposes of marking) can be simulated by XOR'ing the pointer value
with some mask so that it's not recognized as a pointer by the GC. This
can be encapsulated by a weak pointer struct that automatically does the
translation:

struct WeakPointer(T) {
enum size_t mask = 0xdeadbeef;
union Impl {
T* ptr;
size_t uintVal;
}
Impl impl;
void set(T* ptr) @system {
impl.ptr = ptr;
impl.uintVal ^= mask;
}
T* get() @system {
Impl i = impl;
i.uintVal ^= mask;
return i.ptr;
}
}

WeakPointer!Buffer bufferRef;

void doWork(Args...) {
T* buffer;
if (bufferRef.get() is null) {
// Buffer hasn't been allocated yet
buffer = allocateNewBuffer();
bufferRef.set(buffer);
} else {
void *p;
core.memory.GC.getAttr(p);
if (p is null || p != bufferRef.get()) {
// GC has collected previous buffer
buffer = allocateNewBuffer();
bufferRef.set(buffer);
}
}
useBuffer(buffer);
...
}

Note that the inner if block is not 100% safe, because there's no
guarantee that even if the base pointer of the block hasn't changed, the
GC hasn't reallocated the block to somebody else. So this part is still
yet to be solved.


T

-- 
It is widely believed that reinventing the wheel is a waste of time; but
I disagree: without wheel reinventers, we would be still be stuck with
wooden horse-cart wheels.


Re: __FILE__ and __LINE__ again...

2013-09-12 Thread H. S. Teoh
On Thu, Sep 12, 2013 at 03:37:58PM +0200, Dicebot wrote:
 On Tuesday, 10 September 2013 at 16:58:54 UTC, H. S. Teoh wrote:
 On Tue, Sep 10, 2013 at 06:50:03PM +0200, Dicebot wrote:
 On Tuesday, 10 September 2013 at 16:45:33 UTC, H. S. Teoh wrote:
 but you can get rid of this with link-time optimization (on Posix,
 you'd add -L-gc-sections to your dmd command-line: this will cause
 ld to delete code sections that are never referenced, which
 includes the log() instantiations if indeed they have been
 inlined).
 
 Using `--gc-sections` requires each function and data item to be
 placed into its own section (-fdata-sections and -ffunction-sections
 in gcc). AFAIK dmd does not do it.
 
 Hmm. Does that mean gdc supports that, then?
 
 Actually I was wrong, looks like DMD does section differentiation by
 default. I am wondering if --gc-sections should be made default on
 Linux targets...

Interesting. However, I ran into some runtime segfaults caused by
--gc-sections yesterday. I didn't investigate further, but that makes me
hesitant to make --gc-sections the default. Something, somewhere, is
being broken by --gc-sections. It doesn't happen in all cases, though.
Only some of my programs are affected by it.

I should investigate this when I get some time.


T

-- 
Let's call it an accidental feature. -- Larry Wall


Re: __FILE__ and __LINE__ again...

2013-09-12 Thread Dicebot

On Thursday, 12 September 2013 at 13:58:03 UTC, H. S. Teoh wrote:
Interesting. However, I ran into some runtime segfaults caused 
by
--gc-sections yesterday. I didn't investigate further, but that 
makes me
hesitant to make --gc-sections the default. Something, 
somewhere, is
being broken by --gc-sections. It doesn't happen in all cases, 
though.

Only some of my programs are affected by it.

I should investigate this when I get some time.


Actually, nevermind, dmd only does it for small portion of the 
code :) However, I have tested -ffunction-sections + 
-fdata-sections + --gc-sections on gdc and have reduced binary 
size _twice_ for a simple `writeln(arr.map(a = a*2)())` snippet. 
Which is only partially cool because gdc binary is more than 
twice larger than dmd one for same code :D


Problem with --gc-sections is that it can't be used when building 
libraries and any with executable that expose parts of own code 
to shared libraries. It is essentially a whole program 
optimization and it can't be done without compiler support in 
cases where binary is _not_ the whole program.


Re: Adding libraries to an executable

2013-09-12 Thread Anton Alexeev
On Thursday, 12 September 2013 at 11:30:05 UTC, Jacob Carlborg 
wrote:

On 2013-09-12 12:14, Anton Alexeev wrote:

I've installed libcurl4-openssl-dev 7.29.0-1ubuntu3.1 before I 
asked for
help here. Else I can't even compile with that command: dmd 
-L-lphobos2

-L-lcurl test.d


How does your dmd.conf file look like?


;
; dmd.conf file for dmd
;
; dmd will look for dmd.conf in the following sequence of 
directories:

;   - current working directory
;   - directory specified by the HOME environment variable
;   - directory dmd resides in
;   - /etc directory
;
; Names enclosed by %% are searched for in the existing 
environment and inserted

;
; The special name %@P% is replaced with the path to this file
;

[Environment]

DFLAGS=-I/usr/include/dmd/phobos 
-I/usr/include/dmd/druntime/import -L-L/usr/lib/i386-linux-gnu 
-L-L/usr/lib/x86_64-linux-gnu -L--no-warn-search-mismatch 
-L--export-dynamic


Handling exceptions from Windows DLL

2013-09-12 Thread FreeSlave

Hello. There was an issue 2 years ago:
https://github.com/D-Programming-Language/druntime/pull/92

It seems that this bug is still here (I can't handle D Exception
from dll builded with dmd and dmc link).
Will this bug get fixed? Do other D compilers have the same issue?


Re: override and package

2013-09-12 Thread Maxim Fomin

On Thursday, 12 September 2013 at 11:29:22 UTC, Jacob Carlborg
wrote:

On 2013-09-12 11:28, Namespace wrote:

But if I try to write 'override' before [1], I get this error 
message:
Error: function T4._apply cannot override a non-virtual 
function


This seems inconsistent. I really overwrite the method, and 
then I put

it in a package label.


I think the error message is pretty clear. You cannot override 
a function that isn't virtual. Private and package methods are 
not virtual.


Actually error message is misleading - it complains as T1._apply
would be non-virtual function which is wrong, it is one. The
problem is not in case of overriding non-virtual function but in
attempt to override virtual function (private) by non-virtual one
(package). I think error mesage should be something like:

Error: function T4._apply is non-virtual function and cannot
ovverride virtual function T1._apply


Re: Greedy memory handling

2013-09-12 Thread Dmitry Olshansky

12-Sep-2013 17:51, H. S. Teoh пишет:

On Thu, Sep 12, 2013 at 08:27:59AM +0200, Jacob Carlborg wrote:

On 2013-09-11 10:06, monarch_dodra wrote:

I have a function that will *massively* benefit from having a
persistent internal buffer it can re-use (and grow) from call to
call, instead of re-allocating on every call.

What I don't want is either of:
1. To set a fixed limitation of size, if the user ends up making
repeated calls to something larger to my fixed size.
2. For a single big call which will allocate a HUGE internal buffer
that will consume all my memory.

What I need is some sort of lazy buffer. Basically, the allocation
holds, but I don't want the to prevent the GC from collecting it if
it deems it has gotten too big, or needs more memory.

Any idea on how to do something like that? Or literature?


How about keeping a stack or static buffer. If that gets too small
use a new buffer. When you're done with the new buffer set it to
null to allow the GC to collect it. Then repeat.

[...]

The problem is, he wants to reuse the buffer next time if the GC hasn't
collected it yet.

Here's an idea, though. It doesn't completely solve the problem, but it
just occurred to me that weak pointers (i.e., ignored by the GC for
the purposes of marking) can be simulated by XOR'ing the pointer value
with some mask so that it's not recognized as a pointer by the GC. This
can be encapsulated by a weak pointer struct that automatically does the
translation:

struct WeakPointer(T) {
enum size_t mask = 0xdeadbeef;
union Impl {
T* ptr;
size_t uintVal;
}
Impl impl;
void set(T* ptr) @system {
impl.ptr = ptr;
impl.uintVal ^= mask;
}
T* get() @system {
Impl i = impl;
i.uintVal ^= mask;
return i.ptr;
}
}

WeakPointer!Buffer bufferRef;

void doWork(Args...) {
T* buffer;
if (bufferRef.get() is null) {
// Buffer hasn't been allocated yet
buffer = allocateNewBuffer();
bufferRef.set(buffer);
} else {
void *p;
core.memory.GC.getAttr(p);


This line above is not 100% good idea .. at least with deadbeaf as mask.

If we do know what OS you compile for we may just flip the say upper bit 
and get a pointer into kernel space (and surely that isn't in GC pool). 
Even then your last paragraph pretty much destroys it.



Better option is to have finalizer hooked up to set some flag. Then 
_after_ restoring the pointer we consult that flag variable.



if (p is null || p != bufferRef.get()) {
// GC has collected previous buffer
buffer = allocateNewBuffer();
bufferRef.set(buffer);
}
}
useBuffer(buffer);
...
}

Note that the inner if block is not 100% safe, because there's no
guarantee that even if the base pointer of the block hasn't changed, the
GC hasn't reallocated the block to somebody else. So this part is still
yet to be solved.


T




--
Dmitry Olshansky


Re: Any idea for a solution to handle overloads when dynamically implementing methods?

2013-09-12 Thread Gary Willoughby

On Wednesday, 11 September 2013 at 18:24:31 UTC, H. S. Teoh wrote:

On Mon, Sep 09, 2013 at 10:16:42PM +0200, Gary Willoughby wrote:

Just wondered if i could pick you brains for a nice solution to
dynamically add methods to a class, paying particular 
attention to

overloads. I'm currently writing a mocking framework and
everything's coming along nicely and i'm wondering how to 
handle

replacing overloads of the mocked class.

To create a new mocked class this is the code:

auto mock = new Mock!Person();

Simple enough, mock now contains an extended class with all the
methods set to assert(false) because there are no 
implementations
yet. What i need to do is to add the implementations 
dynamically.

This is the code i propose.

mock.addMethod(getAge, int delegate(){
return 40;
});

assert(mock.getAge() == 40);

Which i guess would be easy to implement but it doesn't handle
overloads because the method string doesn't contain enough
information to define which overload it's implementing.

Any nice ideas what would be a nice way of supporting this? I
thought i'd ask while i have a think and get some tea. :)


One idea I have is to use the built-in typetuples as a way of
disambiguating between different overloads. For example, 
something like

this:

// This captures the function argument type list in a form that
// we can call .mangleof on.
template ArgTypesWrapper(ArgTypes...) { }

// This builds a unique string to identify a specific overload
// based on the function name and the .mangleof of its argument
// types. The key to this trick is that the .mangleof of a
// template encodes its argument types, so it is unique per
// combination of argument types.
template FuncSignature(string funcName, ArgTypes...) {
enum FuncSignature = funcName ~ ArgTypesWrapper.mangleof;
}

class Mock(... /* whatever you currently have here */) {
// This unfortunately has to be a template function in
// order to be able to capture the argument types of the
// delegate in the typetuple A. This may complicate the
// implementation of how you'd actually dispatch to the
// overload implementation at runtime.
void addMethod(R, A...)(string funcName, R delegate(A...) dg)
{
string overloadName = FuncSignature!(funcName, A);

// Now overloadName should be a unique string
// representing that particular combination of
// function name and argument types, i.e., it's
// a function signature. So you can use it to
// identify which overload is which.
}
}


T


Thanks for the idea, i have implemented something based on this 
and it seems to be working well.


What does __parameters return?

2013-09-12 Thread simendsjo
The documentation says the parameter tuple of a function, 
delegate, or function pointer. This includes the parameter types, 
names, and default values.


.. but what type is it?

Error: argument (int i, char c, string s, bool b = false) to 
typeof is not an expression


How am I supposed to get the parameter names using this?

It's possible to use .stringof, and then regular string handling 
to extract the names, but I guess there should be a simpler way 
if only I knew what it returned.


Re: Safety/purity and assert/enforce error messages

2013-09-12 Thread H. S. Teoh
On Thu, Sep 12, 2013 at 09:12:18PM +0200, bearophile wrote:
 H. S. Teoh:
 
 In phobos git HEAD, std.format has been made pure @safe nothrow (and
 CTFE-able), so you should be able to write your assert as:
 
  assert(condition, format(x = %s, blahblah, x));
 
 With the latest DMD from updated GIT head:
 
 
 import std.string: format;
 void main() pure nothrow {
 string x = hello;
 bool condition = true;
 assert(condition, format(x = %s, blahblah, x));
 }
 
 
 It gives:
 
 test.d(5): Error: 'std.string.format!(char, string).format' is not nothrow
 test.d(2): Error: function 'D main' is nothrow yet may throw
[...]

Oops. Apparently I wrote nothrow but forgot to test it. I did test pure
and @safe, though, so at least those two should work.


T

-- 
Food and laptops don't mix.


Re: cascade operator or nearest equivalent

2013-09-12 Thread bearophile

Daniel Davidson:

I am using Dart for code generation but would like to consider 
D if I can find a convenient replacement for the following 
declarative style:


Replacing Dart with D seems quite strange, such two languages 
have so much different usage niches.




var dateRange = struct('date_range')
  ..doc = 'Basic pair of start and end dates'
  ..unitTest = true
  ..publicSection = true
  ..members = [
member('start_date')
..type = 'Date',
member('end_date')
..type = 'Date',
  ];


A similar syntax is not allowed in D, but there are two things 
that help for this: the C-style initialization of structs, that 
support field names too, and the with(){} statement.


Bye,
bearophile


Re: Linking Trouble (Linux)

2013-09-12 Thread Craig Dillabaugh

On Thursday, 12 September 2013 at 19:46:21 UTC, Craig Dillabaugh
wrote:
I just upgraded my Linux distro (openSuse) and now when trying 
to

compile a project with dub I am getting linking errors.

Compilation goes OK until the linking stage, when I get the
following:

Linking...
dmd -of/home/craig/cloud/vibe-tiles/vibe
/home/craig/cloud/vibe-tiles/temp.o -L-levent_pthreads -L-levent
-L-lssl -L-lcrypto -g


clip


Strangely, libdl.so.2 and libz.so.1 are both there and libcrypto
is linked to them.


clip


Craig


OK, so I solved my compilation problem by passing the following
as the linker command (added -L-ldl and -L-lz):

dmd -of/home/craig/cloud/vibe-tiles/vibe
/home/craig/cloud/vibe-tiles/temp.o -L-levent_pthreads -L-levent
-L-lssl -L-ldl -L-lz -L-lcrypto -g

How the GCC linker decides which libraries I need to explicitly
specify is indeed a mystery to me.

Craig


Re: Safety/purity and assert/enforce error messages

2013-09-12 Thread Jonathan M Davis
On Thursday, September 12, 2013 13:21:26 H. S. Teoh wrote:
 On Thu, Sep 12, 2013 at 04:07:24PM -0400, Jonathan M Davis wrote:
  On Thursday, September 12, 2013 12:42:34 H. S. Teoh wrote:
   On Thu, Sep 12, 2013 at 09:12:18PM +0200, bearophile wrote:
H. S. Teoh:
In phobos git HEAD, std.format has been made pure @safe nothrow
(and CTFE-able), so you should be able to write your assert as:
assert(condition, format(x = %s, blahblah, x));

With the latest DMD from updated GIT head:


import std.string: format;
void main() pure nothrow {

string x = hello;
bool condition = true;
assert(condition, format(x = %s, blahblah, x));

}


It gives:

test.d(5): Error: 'std.string.format!(char, string).format' is not
nothrow
test.d(2): Error: function 'D main' is nothrow yet may throw
   
   [...]
   
   Oops. Apparently I wrote nothrow but forgot to test it. I did test
   pure and @safe, though, so at least those two should work.
  
  format can't be nothrow, because it throws when you screw up the
  format specifiers. You have to wrap it in a try-catch block and
  assert(0) in the catch block if you want to put it in a nothrow
  function. std.datetime does this in at least a few places.
 
 [...]
 
 Right. Makes me wanna suggest adding this template to std.exception:
 
 auto assumeWontThrow(alias fun, T...)(T args) nothrow {
 try {
 return fun(args);
 } catch(Exception) {
 // You broke your promise, I die.
 assert(0);
 }
 }
 
 Then you can write things like:
 
 int mayThrow(int arg) {
 if (arg  0) throw new Exception(...);
 return BBN(arg);
 }
 
 int iWontThrow() nothrow { // -- N.B. this function is nothrow
 static assert(123  0);
 return assumeWontThrow!mayThrow(123);
 }

Sounds like a good suggestion, though an actual implementation should have an 
error message in the assert(0). You could also implement it as a lazy 
parameter like enforce and assertNotThrown do (which I think is more user-
friendly), but that would likely be less efficient due to how lazy doesn't get 
optimized very well (or at least, it's my understanding that it doesn't).

- Jonathan M Davis


Re: Safety/purity and assert/enforce error messages

2013-09-12 Thread H. S. Teoh
On Thu, Sep 12, 2013 at 10:17:30PM +0200, Joseph Rushton Wakeling wrote:
 On 12/09/13 22:07, Jonathan M Davis wrote:
 format can't be nothrow, because it throws when you screw up the
 format specifiers. You have to wrap it in a try-catch block and
 assert(0) in the catch block if you want to put it in a nothrow
 function. std.datetime does this in at least a few places.
 
 The annoyance of this is that it means that any otherwise @safe pure
 nothrow function that has an assert() in it can be blocked from being
 nothrow if it needs a formatted string for the assert failure message.
 
 Note that this restriction still applies even if the code is being
 compiled with -release and the assertion therefore stripped out.
 
 Or am I missing a trick as to how to deal with assert() and enforce()
 ... ? :-)

Using assumeWontThrow, as defined in my previous post, you can write
this:

auto myFunc(int x) nothrow {
// Look, ma! This line doesn't violate nothrow!
assert(isValid(x), assumeWontThrow!format(
Invalid args (%s), dude!, x));

... // do work here
}

:-)


T

-- 
Uhh, I'm still not here. -- KD, while away on ICQ.


Cannot access frame of insert whatever here

2013-09-12 Thread simendsjo
I haven't done any D coding since May, but picked up my little 
toy code again now.
Last time I had a lot of hassle with not being able to 
store/access symbols through templates, and I got the same thing 
now.


Am I the only one hitting these all the time?

I'm basically playing around with UDAs:

@notNull class A {
  @matches([0-9]+) string s;
  @interval![)(0, 10) int i;
}
void f(A a) {
  mixin enforceValidParameters;
  enforceValidParameters();
}

f(null); // Throws because a is null
f(new A()); // Throws because a.s doesn't match and i isn't 
within [0,10)


I need a mixin there because I haven't found another way of 
getting the correct function without passing any parameters. And 
the second call because the mixin cannot call any code itself, 
only declare.


.. But the above doesn't work. I have to do this instead:
void f(A a, A b) {
  validate!(a, b)();
}

which doesn't scale. It's bad enough that I need to run a 
function after mixing in code.


.. Just a bit of a rant - unable to access frames sucks :/


Re: Greedy memory handling

2013-09-12 Thread Dmitry Olshansky

12-Sep-2013 20:51, H. S. Teoh пишет:

On Thu, Sep 12, 2013 at 07:50:25PM +0400, Dmitry Olshansky wrote:

12-Sep-2013 17:51, H. S. Teoh пишет:

[...]

struct WeakPointer(T) {
enum size_t mask = 0xdeadbeef;
union Impl {
T* ptr;
size_t uintVal;
}
Impl impl;
void set(T* ptr) @system {
impl.ptr = ptr;
impl.uintVal ^= mask;
}
T* get() @system {
Impl i = impl;
i.uintVal ^= mask;
return i.ptr;
}
}

WeakPointer!Buffer bufferRef;

void doWork(Args...) {
T* buffer;
if (bufferRef.get() is null) {
// Buffer hasn't been allocated yet
buffer = allocateNewBuffer();
bufferRef.set(buffer);
} else {
void *p;
core.memory.GC.getAttr(p);


This line above is not 100% good idea .. at least with deadbeaf as
mask.

If we do know what OS you compile for we may just flip the say upper
bit and get a pointer into kernel space (and surely that isn't in GC
pool). Even then your last paragraph pretty much destroys it.


Well, that was just an example value. :) If we know which OS it is and
how it assigns VM addresses, then we can adjust the mask appropriately.

But yeah, calling GC.getAttr is unreliable since you can't tell whether
the block is what you had before, or somebody else's new data.



It occured to me that there are modes where full address space is 
available, typically so on x86 app running on top of x64 kernel (e.g. in 
Windows Wow64 could do that, Linux also has so-called x32 ABI).




[...]

Better option is to have finalizer hooked up to set some flag. Then
_after_ restoring the pointer we consult that flag variable.


Good idea. The problem is, how to set a finalizer on a memory block that
can change in size? The OP's original situation was that the buffer can
be extended while in use, but I don't know of any D type that can
associate a dtor with a ubyte[] array (note that the GC collecting the
wrapper struct/class around the ubyte[] is not the same as collecting
the actual memory block storing the ubyte[] -- the former can happen
without the latter).



Double indirection? Allocate a class that has finalizer, hold that via 
weak-ref. The wrapper in turn contains a pointer to the buffer. The 
interesting point then is that one may allocate said buffer via C's realloc.


Then once helper struct is collected the finalizer is called and this is 
where we call free to cleanup C's heap.


I'm thinking this actually is going to work.

--
Dmitry Olshansky


Re: Safety/purity and assert/enforce error messages

2013-09-12 Thread bearophile

H. S. Teoh:

In phobos git HEAD, std.format has been made pure @safe nothrow 
(and

CTFE-able), so you should be able to write your assert as:

assert(condition, format(x = %s, blahblah, x));


With the latest DMD from updated GIT head:


import std.string: format;
void main() pure nothrow {
string x = hello;
bool condition = true;
assert(condition, format(x = %s, blahblah, x));
}


It gives:

test.d(5): Error: 'std.string.format!(char, string).format' is 
not nothrow

test.d(2): Error: function 'D main' is nothrow yet may throw

Bye,
bearophile


Re: Safety/purity and assert/enforce error messages

2013-09-12 Thread Jonathan M Davis
On Thursday, September 12, 2013 12:42:34 H. S. Teoh wrote:
 On Thu, Sep 12, 2013 at 09:12:18PM +0200, bearophile wrote:
  H. S. Teoh:
  In phobos git HEAD, std.format has been made pure @safe nothrow (and
  
  CTFE-able), so you should be able to write your assert as:
   assert(condition, format(x = %s, blahblah, x));
  
  With the latest DMD from updated GIT head:
  
  
  import std.string: format;
  void main() pure nothrow {
  
  string x = hello;
  bool condition = true;
  assert(condition, format(x = %s, blahblah, x));
  
  }
  
  
  It gives:
  
  test.d(5): Error: 'std.string.format!(char, string).format' is not nothrow
  test.d(2): Error: function 'D main' is nothrow yet may throw
 
 [...]
 
 Oops. Apparently I wrote nothrow but forgot to test it. I did test pure
 and @safe, though, so at least those two should work.

format can't be nothrow, because it throws when you screw up the format 
specifiers. You have to wrap it in a try-catch block and assert(0) in the catch 
block if you want to put it in a nothrow function. std.datetime does this in 
at least a few places.

- Jonathan M Davis


Re: Safety/purity and assert/enforce error messages

2013-09-12 Thread H. S. Teoh
On Thu, Sep 12, 2013 at 04:07:24PM -0400, Jonathan M Davis wrote:
 On Thursday, September 12, 2013 12:42:34 H. S. Teoh wrote:
  On Thu, Sep 12, 2013 at 09:12:18PM +0200, bearophile wrote:
   H. S. Teoh:
   In phobos git HEAD, std.format has been made pure @safe nothrow
   (and CTFE-able), so you should be able to write your assert as:
   assert(condition, format(x = %s, blahblah, x));
   
   With the latest DMD from updated GIT head:
   
   
   import std.string: format;
   void main() pure nothrow {
   
   string x = hello;
   bool condition = true;
   assert(condition, format(x = %s, blahblah, x));
   
   }
   
   
   It gives:
   
   test.d(5): Error: 'std.string.format!(char, string).format' is not nothrow
   test.d(2): Error: function 'D main' is nothrow yet may throw
  
  [...]
  
  Oops. Apparently I wrote nothrow but forgot to test it. I did test
  pure and @safe, though, so at least those two should work.
 
 format can't be nothrow, because it throws when you screw up the
 format specifiers. You have to wrap it in a try-catch block and
 assert(0) in the catch block if you want to put it in a nothrow
 function. std.datetime does this in at least a few places.
[...]

Right. Makes me wanna suggest adding this template to std.exception:

auto assumeWontThrow(alias fun, T...)(T args) nothrow {
try {
return fun(args);
} catch(Exception) {
// You broke your promise, I die.
assert(0);
}
}

Then you can write things like:

int mayThrow(int arg) {
if (arg  0) throw new Exception(...);
return BBN(arg);
}

int iWontThrow() nothrow { // -- N.B. this function is nothrow
static assert(123  0);
return assumeWontThrow!mayThrow(123);
}


T

-- 
It won't be covered in the book. The source code has to be useful for
something, after all. -- Larry Wall


Re: Greedy memory handling

2013-09-12 Thread monarch_dodra

On Thursday, 12 September 2013 at 19:13:40 UTC, Dmitry Olshansky
wrote:
Double indirection? Allocate a class that has finalizer, hold 
that via weak-ref. The wrapper in turn contains a pointer to 
the buffer. The interesting point then is that one may allocate 
said buffer via C's realloc.


Then once helper struct is collected the finalizer is called 
and this is where we call free to cleanup C's heap.


I'm thinking this actually is going to work.


Yum. I like this.

I was going to say: At the end of the day, if the GC doesn't
*tell* us the collection happened, then the problem is not
solve-able. We'd need a way that would allow the GC to tell us
the memory was *finalized*. And then I'd go on to say since our
GC is non-finalizing, there is simply no solution.

But then classes. Derp.

I'd be real interested in having a finalized solution. The
details of how memory addressing is not my strong suite, so I
wouldn't trust myself with all those union{ptr/size_t} things.

Thanks, I'll start toying around with this :)


Re: What does __parameters return?

2013-09-12 Thread H. S. Teoh
On Thu, Sep 12, 2013 at 08:44:29PM +0200, simendsjo wrote:
 The documentation says the parameter tuple of a function, delegate,
 or function pointer. This includes the parameter types, names, and
 default values.
 
 .. but what type is it?
 
 Error: argument (int i, char c, string s, bool b = false) to typeof
 is not an expression
 
 How am I supposed to get the parameter names using this?
 
 It's possible to use .stringof, and then regular string handling to
 extract the names, but I guess there should be a simpler way if only
 I knew what it returned.

You're not going to like the answer to this one... :)

Here's some example code that uses __parameters to inspect a function
and print out a list of its parameter types and names (my explanations
are in the comments):

-snip-
import std.stdio;

// Example function we want to examine parameters for
int func(string x, float y, int z=123) {
return 0;
}

void main() {
// __parameters appears to only work inside is(...), in a quirky
// special-cased syntax that ONLY works when written exactly in the
// form is(TypeOfFunc Ident == __parameters), in which case Ident gets
// aliased to a parameter tuple, an elusive compiler internal entity
// that is similar to, but not the same as, a type tuple.
static if (is(typeof(func) Params == __parameters)) {
// You already know what does one this, I believe.
pragma(msg, Params.stringof);

// foreach works on parameter tuples, but it acts very weird.
// If a single argument is given, it gets assigned to the
// *type* of the parameter in question. If two arguments are
// given, like here, the first is assigned the index into the
// parameter tuple, and the second to the *type* of the
// corresponding parameter.
foreach (i, T; Params) {
// This quirky behaviour of foreach on parameter tuples
// means T is *not* the parameter itself, merely the
// *type* of the parameter. To get the actual
// parameter's description, we need a 1-element slice
// of the parameter tuple. Thankfully, i has been
// conveniently assigned the index of the current
// parameter, so we can use that for the slicing:
alias Param = Params[i .. i+1];

// As I said, T is merely the type of the parameter,
// not the parameter itself.
alias ParamType = T;

// The 1-element slice Param behaves as if it's an
// independent entity with a name, so we can use
// __traits(identifer, ...) to get at the parameter
// name.
string ParamName = __traits(identifier, Param);

writeln(type=, T.stringof,  name=, ParamName);

// Not shown here is the default parameter value.
// Looking at std.traits.ParameterDefaultValueTuple,
// there appears to be no direct way to get at this.
// The only way seems to be to declare a function with
// Param as its single argument, and then call that
// function with no arguments so that the function can
// return the default value of the parameter. This is
// what Phobos actually does to build the default
// parameter tuple.

// Also not shown here is how to get at the
// storage class of the parameter; I didn't look
// into this, but your best reference would be
// std.traits.ParameterStorageClass' code.
}
}
}
-snip-

Given the non-intuitive quirkiness of the whole thing, you're probably
far better off using Phobos' std.traits.Parameter...Tuple templates to
get at the various bits of function parameters.

Or just parse the string returned by the .stringof value, as you
suggested.


T

-- 
Never wrestle a pig. You both get covered in mud, and the pig likes it.


Re: Safety/purity and assert/enforce error messages

2013-09-12 Thread Jonathan M Davis
On Thursday, September 12, 2013 22:17:30 Joseph Rushton Wakeling wrote:
 On 12/09/13 22:07, Jonathan M Davis wrote:
  format can't be nothrow, because it throws when you screw up the format
  specifiers. You have to wrap it in a try-catch block and assert(0) in the
  catch block if you want to put it in a nothrow function. std.datetime
  does this in at least a few places.
 
 The annoyance of this is that it means that any otherwise @safe pure nothrow
 function that has an assert() in it can be blocked from being nothrow if it
 needs a formatted string for the assert failure message.
 
 Note that this restriction still applies even if the code is being compiled
 with -release and the assertion therefore stripped out.
 
 Or am I missing a trick as to how to deal with assert() and enforce() ... ?
 :-)

You can put the try-catch in a version(assert) block to get around that 
problem, but it is true that it's not exactly ideal. However, there really 
isn't any way around that with a function that takes a format string unless 
you want it to ignore bad arguments. You'd need a function like text which 
just appends all of its arguments together in order to get around that 
problem.

- Jonathan M Davis


Re: Adding libraries to an executable

2013-09-12 Thread Jacob Carlborg

On 2013-09-12 18:25, Anton Alexeev wrote:


[Environment]

DFLAGS=-I/usr/include/dmd/phobos -I/usr/include/dmd/druntime/import
-L-L/usr/lib/i386-linux-gnu -L-L/usr/lib/x86_64-linux-gnu
-L--no-warn-search-mismatch -L--export-dynamic


I don't see way explicitly linking with Phobos would make a difference, 
since the compiler will link with Phobos implicitly. That assumes you 
have libphobos2.a in /usr/lib/i386-linux-gnu or /usr/lib/x86_64-linux-gnu.


--
/Jacob Carlborg


Re: Greedy memory handling

2013-09-12 Thread H. S. Teoh
On Thu, Sep 12, 2013 at 07:50:25PM +0400, Dmitry Olshansky wrote:
 12-Sep-2013 17:51, H. S. Teoh пишет:
[...]
  struct WeakPointer(T) {
  enum size_t mask = 0xdeadbeef;
  union Impl {
  T* ptr;
  size_t uintVal;
  }
  Impl impl;
  void set(T* ptr) @system {
  impl.ptr = ptr;
  impl.uintVal ^= mask;
  }
  T* get() @system {
  Impl i = impl;
  i.uintVal ^= mask;
  return i.ptr;
  }
  }
 
  WeakPointer!Buffer bufferRef;
 
  void doWork(Args...) {
  T* buffer;
  if (bufferRef.get() is null) {
  // Buffer hasn't been allocated yet
  buffer = allocateNewBuffer();
  bufferRef.set(buffer);
  } else {
  void *p;
  core.memory.GC.getAttr(p);
 
 This line above is not 100% good idea .. at least with deadbeaf as
 mask.
 
 If we do know what OS you compile for we may just flip the say upper
 bit and get a pointer into kernel space (and surely that isn't in GC
 pool). Even then your last paragraph pretty much destroys it.

Well, that was just an example value. :) If we know which OS it is and
how it assigns VM addresses, then we can adjust the mask appropriately.

But yeah, calling GC.getAttr is unreliable since you can't tell whether
the block is what you had before, or somebody else's new data.


[...]
 Better option is to have finalizer hooked up to set some flag. Then
 _after_ restoring the pointer we consult that flag variable.

Good idea. The problem is, how to set a finalizer on a memory block that
can change in size? The OP's original situation was that the buffer can
be extended while in use, but I don't know of any D type that can
associate a dtor with a ubyte[] array (note that the GC collecting the
wrapper struct/class around the ubyte[] is not the same as collecting
the actual memory block storing the ubyte[] -- the former can happen
without the latter).


T

-- 
People tell me that I'm skeptical, but I don't believe it.


Re: Greedy memory handling

2013-09-12 Thread Jacob Carlborg

On 2013-09-12 15:51, H. S. Teoh wrote:


The problem is, he wants to reuse the buffer next time if the GC hasn't
collected it yet.


I was thinking he could reuse the stack/static buffer. Basically using 
two buffers, one static and one dynamic.


--
/Jacob Carlborg


Re: Safety/purity and assert/enforce error messages

2013-09-12 Thread Joseph Rushton Wakeling

On 12/09/13 22:07, Jonathan M Davis wrote:

format can't be nothrow, because it throws when you screw up the format
specifiers. You have to wrap it in a try-catch block and assert(0) in the catch
block if you want to put it in a nothrow function. std.datetime does this in
at least a few places.


The annoyance of this is that it means that any otherwise @safe pure nothrow 
function that has an assert() in it can be blocked from being nothrow if it 
needs a formatted string for the assert failure message.


Note that this restriction still applies even if the code is being compiled with 
-release and the assertion therefore stripped out.


Or am I missing a trick as to how to deal with assert() and enforce() ... ? :-)



Re: Greedy memory handling

2013-09-12 Thread H. S. Teoh
On Thu, Sep 12, 2013 at 11:13:30PM +0400, Dmitry Olshansky wrote:
 12-Sep-2013 20:51, H. S. Teoh пишет:
 On Thu, Sep 12, 2013 at 07:50:25PM +0400, Dmitry Olshansky wrote:
[...]
 Better option is to have finalizer hooked up to set some flag. Then
 _after_ restoring the pointer we consult that flag variable.
 
 Good idea. The problem is, how to set a finalizer on a memory block
 that can change in size? The OP's original situation was that the
 buffer can be extended while in use, but I don't know of any D type
 that can associate a dtor with a ubyte[] array (note that the GC
 collecting the wrapper struct/class around the ubyte[] is not the
 same as collecting the actual memory block storing the ubyte[] -- the
 former can happen without the latter).
 
 
 Double indirection? Allocate a class that has finalizer, hold that
 via weak-ref. The wrapper in turn contains a pointer to the buffer.
 The interesting point then is that one may allocate said buffer via
 C's realloc.
 
 Then once helper struct is collected the finalizer is called and
 this is where we call free to cleanup C's heap.
 
 I'm thinking this actually is going to work.
[...]

Interesting idea, use C's malloc/realloc to hold the actual buffer. Only
possible catch is, will that cause the GC to collect when it runs out of
memory (which is the whole point of the OP's question)? I.e., does it
make a difference in GC behaviour to allocate, say, 10MB from the GC vs.
allocating 10MB from malloc/realloc?

Assuming we have that settled, something like this should work:

bool isValid;
final class BufWrapper {
void* ptrToMallocedBuf;
this(void* ptr) {
// We need this, 'cos otherwise we don't know if
// our weak ref to BufWrapper is still valid!
isValid = true;

ptrToMallocedBuf = ptr;
}
~this() {
// If we're being collected, free the real
// buffer too.
free(ptrToMallocedBuf);
isValid = false;
}
}

// WeakPointer masks the pointer to BufWrapper in some suitable
// way so that the GC will collect it when needed.
WeakPointer!BufWrapper wrappedBufRef;

void doWork(...) {
void* buf;
if (!isValid) {
buf = realloc(null, bufSize);
wrappedBufRef.set(buf);
} else {
buf = wrappedBufRef.get();
}

// use buf here.
}


T

-- 
Public parking: euphemism for paid parking. -- Flora


Linking Trouble (Linux)

2013-09-12 Thread Craig Dillabaugh

I just upgraded my Linux distro (openSuse) and now when trying to
compile a project with dub I am getting linking errors.

Compilation goes OK until the linking stage, when I get the
following:

Linking...
dmd -of/home/craig/cloud/vibe-tiles/vibe
/home/craig/cloud/vibe-tiles/temp.o -L-levent_pthreads -L-levent
-L-lssl -L-lcrypto -g
/usr/lib64/gcc/x86_64-suse-linux/4.7/../../../../x86_64-suse-linux/bin/ld:
warning: libdl.so.2, needed by /usr/lib64/libcrypto.so, not found
(try using -rpath or -rpath-link)
/usr/lib64/gcc/x86_64-suse-linux/4.7/../../../../x86_64-suse-linux/bin/ld:
warning: libz.so.1, needed by /usr/lib64/libcrypto.so, not found
(try using -rpath or -rpath-link)
/usr/lib64/libcrypto.so: undefined reference to
`dlopen@GLIBC_2.2.5'
/usr/lib64/libcrypto.so: undefined reference to
`dlerror@GLIBC_2.2.5'
/usr/lib64/libcrypto.so: undefined reference to
`dlclose@GLIBC_2.2.5'
/usr/lib64/libcrypto.so: undefined reference to
`dlsym@GLIBC_2.2.5'
/usr/lib64/libcrypto.so: undefined reference to
`dladdr@GLIBC_2.2.5'

Strangely, libdl.so.2 and libz.so.1 are both there and libcrypto
is linked to them.

$ ldd /usr/lib64/libcrypto.so
 linux-vdso.so.1 (0x7fff7d52)
 libdl.so.2 = /lib64/libdl.so.2 (0x7f3b2ef98000)
 libz.so.1 = /lib64/libz.so.1 (0x7f3b2ed8)
 libc.so.6 = /lib64/libc.so.6 (0x7f3b2e9d)
 /lib64/ld-linux-x86-64.so.2 (0x7f3b2f5a8000)

I've surfed around quite a bit and can't seem to find anything.
I solved a similar problem in the past by reinstalling glibc, but
that hasn't helped in this case. Any hints on where to look would
be appreciated.

Craig


Re: Safety/purity and assert/enforce error messages

2013-09-12 Thread Joseph Rushton Wakeling

On 12/09/13 20:49, H. S. Teoh wrote:

In phobos git HEAD, std.format has been made pure @safe nothrow (and
CTFE-able), so you should be able to write your assert as:

assert(condition, format(x = %s, blahblah, x));

Don't think it will work on 2.063.2, though, since it was a relatively
recent change. I suspect this will only work starting from 2.064.


Ahh, good to know, thanks.  I guess I'll withhold tweaking such things until 
after the next release ... :-)




Re: Greedy memory handling

2013-09-12 Thread Dmitry Olshansky

13-Sep-2013 00:11, H. S. Teoh пишет:

On Thu, Sep 12, 2013 at 11:13:30PM +0400, Dmitry Olshansky wrote:

12-Sep-2013 20:51, H. S. Teoh пишет:

On Thu, Sep 12, 2013 at 07:50:25PM +0400, Dmitry Olshansky wrote:

[...]

Better option is to have finalizer hooked up to set some flag. Then
_after_ restoring the pointer we consult that flag variable.


Good idea. The problem is, how to set a finalizer on a memory block
that can change in size? The OP's original situation was that the
buffer can be extended while in use, but I don't know of any D type
that can associate a dtor with a ubyte[] array (note that the GC
collecting the wrapper struct/class around the ubyte[] is not the
same as collecting the actual memory block storing the ubyte[] -- the
former can happen without the latter).



Double indirection? Allocate a class that has finalizer, hold that
via weak-ref. The wrapper in turn contains a pointer to the buffer.
The interesting point then is that one may allocate said buffer via
C's realloc.

Then once helper struct is collected the finalizer is called and
this is where we call free to cleanup C's heap.

I'm thinking this actually is going to work.

[...]

Interesting idea, use C's malloc/realloc to hold the actual buffer. Only
possible catch is, will that cause the GC to collect when it runs out of
memory (which is the whole point of the OP's question)? I.e., does it
make a difference in GC behaviour to allocate, say, 10MB from the GC vs.
allocating 10MB from malloc/realloc?


The only problem I can foresee is that when it runs the collection 
(*and* being tight on RAM) the C heap will not return said chunk back to 
OS. Then GC won't pick up that memory, and we'd get out of ram.


I would safely assume however that for big buffers a mmap/munmap is 
called (or its analogue) and hence memory is returned back to OS. That's 
what all allocators do for huge chunks by anyway.


Otherwise we are still in a good shape, the memory will eventually be 
freed, yet we get to reuse it quite cheaply in a tight loop.  I don't 
expect collections to run in these all that often ;)




Assuming we have that settled, something like this should work:

bool isValid;
final class BufWrapper {
void* ptrToMallocedBuf;
this(void* ptr) {
// We need this, 'cos otherwise we don't know if
// our weak ref to BufWrapper is still valid!
isValid = true;

ptrToMallocedBuf = ptr;
}
~this() {
// If we're being collected, free the real
// buffer too.
free(ptrToMallocedBuf);
isValid = false;
}
}

// WeakPointer masks the pointer to BufWrapper in some suitable
// way so that the GC will collect it when needed.
WeakPointer!BufWrapper wrappedBufRef;

void doWork(...) {
void* buf;


Careful here - you really have first to get a pointer ... THEN check if 
it's valid.



if (!isValid) {
buf = realloc(null, bufSize);
wrappedBufRef.set(buf);
} else {

//otherwise at this point GC.collect runs and presto, memory is freed
//too bad such a thing will never show up in unittests

buf = wrappedBufRef.get();
}

// use buf here.
}


Checking the flag should be somehow part of weak ref job.
I'd rather make it less error prone:

void* buf;
//unmask pointer, do the flag check - false means was freed
if(!weakRef.readTo(buf)){
//create  set new buf
buf = realloc(...);
}

... //use buf

weakRef.set(buf);

I think I'd code it up if nobody beats me to it as I need the same exact 
pattern for std.regex anyway.


--
Dmitry Olshansky


Re: What does __parameters return?

2013-09-12 Thread simendsjo

On Thursday, 12 September 2013 at 19:41:26 UTC, H. S. Teoh wrote:

On Thu, Sep 12, 2013 at 08:44:29PM +0200, simendsjo wrote:

(...)

.. but what type is it?

Error: argument (int i, char c, string s, bool b = false) to 
typeof

is not an expression

How am I supposed to get the parameter names using this?


(...)


You're not going to like the answer to this one... :)


(...)


Or just parse the string returned by the .stringof value, as you
suggested.



Thanks. I just ended up using both is(__parameters and 
is(function to fetch the parameter names. Sometimes it seems 
things are added to D without a very thorough design phase, but 
then again, it starts with __, so I guess I'm on my own :)


Re: override and package

2013-09-12 Thread Namespace

On Thursday, 12 September 2013 at 16:16:14 UTC, Maxim Fomin wrote:

On Thursday, 12 September 2013 at 11:29:22 UTC, Jacob Carlborg
wrote:

On 2013-09-12 11:28, Namespace wrote:

But if I try to write 'override' before [1], I get this error 
message:
Error: function T4._apply cannot override a non-virtual 
function


This seems inconsistent. I really overwrite the method, and 
then I put

it in a package label.


I think the error message is pretty clear. You cannot override 
a function that isn't virtual. Private and package methods are 
not virtual.


Actually error message is misleading - it complains as T1._apply
would be non-virtual function which is wrong, it is one. The
problem is not in case of overriding non-virtual function but in
attempt to override virtual function (private) by non-virtual 
one

(package). I think error mesage should be something like:

Error: function T4._apply is non-virtual function and cannot
ovverride virtual function T1._apply


Thank you, you understand my problem. ;)
I agree, the message should be changed.


Re: Safety/purity and assert/enforce error messages

2013-09-12 Thread H. S. Teoh
On Thu, Sep 12, 2013 at 08:13:37PM +0200, Joseph Rushton Wakeling wrote:
 Hi all,
 
 Suppose that I want to insert some variable values into an assert
 error message.  The easy way to do this is something like:
 
 assert(someCondition, text(x = , x, , cannot blah blah blah));
 
 However, the use of text() prevents me from applying @safe and other
 such attributes to the function containing this assert, even though
 text() will only be called in the event of an assertion failure.
 
 Is there any reliable way to include variable values in the error
 message that doesn't interfere with @safe, pure, etc.?  Using
 to!string has a similar problem.
[...]

In phobos git HEAD, std.format has been made pure @safe nothrow (and
CTFE-able), so you should be able to write your assert as:

assert(condition, format(x = %s, blahblah, x));

Don't think it will work on 2.063.2, though, since it was a relatively
recent change. I suspect this will only work starting from 2.064.


T

-- 
MASM = Mana Ada Sistem, Man!


Re: What does __parameters return?

2013-09-12 Thread Andrej Mitrovic
On 9/12/13, simendsjo simend...@gmail.com wrote:
 Thanks. I just ended up using both is(__parameters and
 is(function to fetch the parameter names. Sometimes it seems
 things are added to D without a very thorough design phase, but
 then again, it starts with __, so I guess I'm on my own :)

Have you tried using ParameterIdentifierTuple from std.traits?


Re: Linking Trouble (Linux)

2013-09-12 Thread Craig Dillabaugh

On Thursday, 12 September 2013 at 20:26:29 UTC, Craig Dillabaugh
wrote:

On Thursday, 12 September 2013 at 19:46:21 UTC, Craig Dillabaugh
wrote:
I just upgraded my Linux distro (openSuse) and now when trying 
to

compile a project with dub I am getting linking errors.

Compilation goes OK until the linking stage, when I get the
following:

Linking...
dmd -of/home/craig/cloud/vibe-tiles/vibe
/home/craig/cloud/vibe-tiles/temp.o -L-levent_pthreads 
-L-levent

-L-lssl -L-lcrypto -g


clip


Strangely, libdl.so.2 and libz.so.1 are both there and 
libcrypto

is linked to them.


clip


Craig


OK, so I solved my compilation problem by passing the following
as the linker command (added -L-ldl and -L-lz):

dmd -of/home/craig/cloud/vibe-tiles/vibe
/home/craig/cloud/vibe-tiles/temp.o -L-levent_pthreads -L-levent
-L-lssl -L-ldl -L-lz -L-lcrypto -g

How the GCC linker decides which libraries I need to explicitly
specify is indeed a mystery to me.

Craig


For anyone who runs into a similar problem using DUB the
following package.json files solves the problem:

{
name: vibe,
description: My first vibe project.,
homepage: http://example.org;,
copyright: Me,
authors: [
Craig Dillabaugh
],
dependencies: {
vibe-d: ~master
},
libs: [dl, z]
}


Re: What does __parameters return?

2013-09-12 Thread H. S. Teoh
On Thu, Sep 12, 2013 at 10:40:06PM +0200, simendsjo wrote:
 On Thursday, 12 September 2013 at 19:41:26 UTC, H. S. Teoh wrote:
 On Thu, Sep 12, 2013 at 08:44:29PM +0200, simendsjo wrote:
 (...)
 .. but what type is it?
 
 Error: argument (int i, char c, string s, bool b = false) to typeof
 is not an expression
 
 How am I supposed to get the parameter names using this?
 
 (...)
 
 You're not going to like the answer to this one... :)
 
 (...)
 
 Or just parse the string returned by the .stringof value, as you
 suggested.
 
 
 Thanks. I just ended up using both is(__parameters and is(function
 to fetch the parameter names. Sometimes it seems things are added to
 D without a very thorough design phase, but then again, it starts
 with __, so I guess I'm on my own :)

I think Walter's official statement on the matter is that __traits is
not intended to be used by user code, but to allow Phobos to access
compiler internals so that it can provide more user-friendly wrappers
around the raw functionality.


T

-- 
Nobody is perfect.  I am Nobody. -- pepoluan, GKC forum


Re: Safety/purity and assert/enforce error messages

2013-09-12 Thread Joseph Rushton Wakeling

On 12/09/13 22:23, Jonathan M Davis wrote:

You can put the try-catch in a version(assert) block to get around that
problem, but it is true that it's not exactly ideal. However, there really
isn't any way around that with a function that takes a format string unless
you want it to ignore bad arguments. You'd need a function like text which
just appends all of its arguments together in order to get around that
problem.


Well, I have been using text() to generate my assert error messages, but the 
trouble is that (at least in 2.063) it's not @safe, pure or nothrow ... :-(




Re: Safety/purity and assert/enforce error messages

2013-09-12 Thread H. S. Teoh
On Thu, Sep 12, 2013 at 11:37:10PM +0200, Joseph Rushton Wakeling wrote:
 On 12/09/13 22:23, Jonathan M Davis wrote:
 You can put the try-catch in a version(assert) block to get around
 that problem, but it is true that it's not exactly ideal. However,
 there really isn't any way around that with a function that takes a
 format string unless you want it to ignore bad arguments. You'd need
 a function like text which just appends all of its arguments together
 in order to get around that problem.
 
 Well, I have been using text() to generate my assert error messages,
 but the trouble is that (at least in 2.063) it's not @safe, pure or
 nothrow ... :-(

Even in git HEAD, text() may still throw.

So ultimately, you still need assumeWontThrow:

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

:)


T

-- 
Some days you win; most days you lose.


Re: isRandomAccessRange!(const(size_t[])) is false ... ?

2013-09-12 Thread Ali Çehreli

On 09/12/2013 02:53 PM, Joseph Rushton Wakeling wrote:

import std.range;

void main()
{
 assert(isRandomAccessRange!(const(size_t[])));
}

 results in an assertion error.  This is a bug, no ... ?


That one is fine. You probably want a slice of const(size_t):

import std.range;

void main()
{
assert(!isRandomAccessRange!(const(size_t[])));
assert( isRandomAccessRange!(const(size_t)[])); // --
}

Ali



isRandomAccessRange!(const(size_t[])) is false ... ?

2013-09-12 Thread Joseph Rushton Wakeling

import std.range;

void main()
{
assert(isRandomAccessRange!(const(size_t[])));
}

 results in an assertion error.  This is a bug, no ... ?


Re: Safety/purity and assert/enforce error messages

2013-09-12 Thread Meta
On Thursday, 12 September 2013 at 20:07:40 UTC, Jonathan M Davis 
wrote:

On Thursday, September 12, 2013 12:42:34 H. S. Teoh wrote:

On Thu, Sep 12, 2013 at 09:12:18PM +0200, bearophile wrote:
 H. S. Teoh:
 In phobos git HEAD, std.format has been made pure @safe 
 nothrow (and

 
 CTFE-able), so you should be able to write your assert as:
  assert(condition, format(x = %s, blahblah, x));
 
 With the latest DMD from updated GIT head:
 
 
 import std.string: format;

 void main() pure nothrow {
 
 string x = hello;

 bool condition = true;
 assert(condition, format(x = %s, blahblah, x));
 
 }
 
 
 It gives:
 
 test.d(5): Error: 'std.string.format!(char, string).format' 
 is not nothrow

 test.d(2): Error: function 'D main' is nothrow yet may throw

[...]

Oops. Apparently I wrote nothrow but forgot to test it. I did 
test pure

and @safe, though, so at least those two should work.


format can't be nothrow, because it throws when you screw up 
the format
specifiers. You have to wrap it in a try-catch block and 
assert(0) in the catch
block if you want to put it in a nothrow function. std.datetime 
does this in

at least a few places.

- Jonathan M Davis


Why don't we have a format function that is statically checked?


Re: isRandomAccessRange!(const(size_t[])) is false ... ?

2013-09-12 Thread Jonathan M Davis
On Thursday, September 12, 2013 23:53:15 Joseph Rushton Wakeling wrote:
 import std.range;
 
 void main()
 {
 assert(isRandomAccessRange!(const(size_t[])));
 }
 
  results in an assertion error. This is a bug, no ... ?

Nope. It's correct. Because it's const, you can't call popFront on it or any 
of the other mutating range operations. So, it's not a valid range.

- Jonathan M Davis


Re: isRandomAccessRange!(const(size_t[])) is false ... ?

2013-09-12 Thread H. S. Teoh
On Thu, Sep 12, 2013 at 03:12:48PM -0700, Ali Çehreli wrote:
 On 09/12/2013 02:53 PM, Joseph Rushton Wakeling wrote:
 import std.range;
 
 void main()
 {
  assert(isRandomAccessRange!(const(size_t[])));
 }
 
  results in an assertion error.  This is a bug, no ... ?
 
 That one is fine. You probably want a slice of const(size_t):
 
 import std.range;
 
 void main()
 {
 assert(!isRandomAccessRange!(const(size_t[])));
 assert( isRandomAccessRange!(const(size_t)[])); // --
 }
[...]

Explanation:

const(size_t)[] means the elements of the array can't be modified, but
the array itself can (necessary to implement popFront, popBack, etc.).

const(size_t[]) means the array itself can't be modified, so popFront,
popBack are invalid. So it cannot be a range.


T

-- 
Food and laptops don't mix.


Re: Safety/purity and assert/enforce error messages

2013-09-12 Thread H. S. Teoh
On Thu, Sep 12, 2013 at 11:45:07PM +0200, Meta wrote:
 On Thursday, 12 September 2013 at 20:07:40 UTC, Jonathan M Davis
 wrote:
[...]
 format can't be nothrow, because it throws when you screw up the
 format specifiers. You have to wrap it in a try-catch block and
 assert(0) in the catch block if you want to put it in a nothrow
 function. std.datetime does this in at least a few places.
 
 - Jonathan M Davis
 
 Why don't we have a format function that is statically checked?

Currently, this is not possible, because the format string may be a
runtime-computed value. For example:

void main(string[] args) {
// fmtString is only known at runtime.
auto fmtString = File(fmtstrings.cfg).byLine().front.idup;

// This will throw if command-line arguments don't match
// format string.
writefln(fmtString, args[1..$]);
}

It *is* true, however, that the vast majority of format usage uses a
static format string. In those cases, it *would* be nice to have a
nothrow variant of format(). Arguably, we could have this variant of
format:

string staticFormat(string fmt, T...)(T args) { ... }

which takes a compile-time format string. Then it can be statically
verified to be pure, @safe, nothrow, etc..

This is actually more tricky than it sounds, though. Specifiers like
%s are parsed into Format!char objects, which may be passed to a
user-defined type's toString method, so the nothrow-ness of
staticFormat() may change depending on whether the user-defined toString
throws.


T

-- 
Старый друг лучше новых двух.


Re: isRandomAccessRange!(const(size_t[])) is false ... ?

2013-09-12 Thread Andrej Mitrovic
On 9/12/13, Joseph Rushton Wakeling joseph.wakel...@webdrake.net wrote:
 import std.range;

 void main()
 {
  assert(isRandomAccessRange!(const(size_t[])));
 }

  results in an assertion error.  This is a bug, no ... ?

I think ranges have to be non-const. I mean how can you iterate over
one if e.g. popFront can't manipulate the inner state?

Maybe you meant:

const(size_t)[]

P.S. you can use a 'static assert' in your code.


Re: isRandomAccessRange!(const(size_t[])) is false ... ?

2013-09-12 Thread Joseph Rushton Wakeling

On 13/09/13 00:15, Jonathan M Davis wrote:

Nope. It's correct. Because it's const, you can't call popFront on it or any
of the other mutating range operations. So, it's not a valid range.


D'oh! :-P

I gave the assert as an example, but this one snuck up on me rather unexpectedly 
-- I'd got a class method that was something like this:


auto foo(in size_t n) @safe const nothrow pure
{
return buf[n];  // where buf is a size_t[][]
}

... and it turned out that foo was trying to return a const(size_t[]) rather 
than a size_t[].


Re: isRandomAccessRange!(const(size_t[])) is false ... ?

2013-09-12 Thread Jonathan M Davis
On Friday, September 13, 2013 00:46:20 Joseph Rushton Wakeling wrote:
 On 13/09/13 00:15, Jonathan M Davis wrote:
  Nope. It's correct. Because it's const, you can't call popFront on it or
  any of the other mutating range operations. So, it's not a valid range.
 D'oh! :-P
 
 I gave the assert as an example, but this one snuck up on me rather
 unexpectedly -- I'd got a class method that was something like this:
 
 auto foo(in size_t n) @safe const nothrow pure
 {
 return buf[n]; // where buf is a size_t[][]
 }
 
 ... and it turned out that foo was trying to return a const(size_t[]) rather
 than a size_t[].

At present, const and ranges basically don't mix. Slicing an array results in 
a tail-const slice, which allows you to get away with using const arrays and 
then slice them when you need to operate on a range which is const, but it's 
actually really, really hard to define opSlice in a way that that works for 
user-defined types. We really need to fix that, but for now, it generally means 
that you don't use const if you're using ranges (which of course is not what 
we want, but we're stuck for the moment).

- Jonathan M Davis


Re: Safety/purity and assert/enforce error messages

2013-09-12 Thread Meta

On Thursday, 12 September 2013 at 22:04:20 UTC, H. S. Teoh wrote:
Currently, this is not possible, because the format string may 
be a runtime-computed value. For example:


...



When you don't have a runtime computed format string, though 
(which is
generally the case for my code, at least), it would be extremely 
useful
for a literal format string to be statically verified and 
nothrow. One really nice thing I've seen with the Rust language 
is that they have a fmt macro that statically verifies that the 
types of its arguments match the format string.




It *is* true, however, that the vast majority of format usage 
uses a
static format string. In those cases, it *would* be nice to 
have a
nothrow variant of format(). Arguably, we could have this 
variant of

format:

string staticFormat(string fmt, T...)(T args) { ... }

which takes a compile-time format string. Then it can be 
statically

verified to be pure, @safe, nothrow, etc..

This is actually more tricky than it sounds, though. Specifiers 
like
%s are parsed into Format!char objects, which may be passed 
to a

user-defined type's toString method, so the nothrow-ness of
staticFormat() may change depending on whether the user-defined 
toString

throws.


Is it necessary to allow toString to throw? I can't think of any 
reason other than the object being in an invalid state, in which 
case maybe it should throw an Error.