Re: Getting a range over a const Container

2012-07-18 Thread Jonathan M Davis
On Thursday, July 19, 2012 04:39:26 Francisco Soulignac wrote:
> So, my question is how can I (correctly) traverse a const SList,
> const DList, etc?

Right now? I'm pretty sure that that's impossible. Hopefully that will change, 
but getting const and ranges to work together can be rather difficult, and 
std.container needs more work in that regard.

- Jonathan M Davis


Re: Getting a range over a const Container

2012-07-18 Thread Francisco Soulignac
Hi all,

it's been a while since this question, and I don't know how to solve
it either.  The following code passes all the test using the last
version of dmd (2.059).

import std.container, std.algorithm;

//non const case
void assertequal(T)(SList!(T) l, int[] r) {
assert(equal(l[], r));
}

//const case
void const_assertequal(T)(const SList!(T) l, int[] r) {
assert(equal(l[], r));
}

unittest{
SList!(int) l;
l.insertFront(2);
l.insertFront(1);
assertequal (l,   [1,2]);
assert(!__traits(compiles, const_assertequal(l, [1,2])));
}

The conflict with the last assertion is that opSplice can't be
applied to const.  So, I looked at the container module, and made a
minimal example of a list myself (emulating SList).

struct List {
struct Node {
Node* next;
int val;
}

private Node* first;

struct Range {
//sorry about "actual", it should have been current
private Node* actual;
this(Node* first) {actual = first;}
@property front() {return actual.val;}
@property empty() const {return !actual;}
void popFront() {assert(!empty); actual = actual.next;}
Range save() {return this;}
}
unittest{static assert(isForwardRange!(Range));}

void add(int v) {
Node * next = first;
first = new Node;
first.val = v;
first.next = next;
}

Range opSlice() {
return Range(first);
}

}

void assertequal(L : List)(L l, int[] r) {
assert(equal(l[], r));
}

void assertequal_const(L : List)(L l, int[] r) {
assert(equal(l[], r));
}

unittest{
List l;
l.add(2);
l.add(1);
assert(equal(l[], [1,2]));
assertequal (l,   [1,2]);
assert(!__traits(compiles, const_assertequal(l, [1,2])));
}

As far as I know, the problem comes with the transitivity of const.
In assertequal_const, l.first has type const(Node*), thus it can't
be converted to Node* in Range's constructor.  I can't manage to
find a workaround here, because l.first will always have type
const(Node*), but for traversing the list I require to copy l.first
into some node, say actual, whose type is Node* so that I can move
it doing actual = actual.next.  I would be happy to do

actual = cast(Node*)(l.first)
actual = actual.next;

but that code is suppose to be undefined, isn't it?
(http://dlang.org/const3.html : Removing Immutable With A Cast).

So, my question is how can I (correctly) traverse a const SList,
const DList, etc?

Best,
Francisco.
PS: sorry for the long mail.


Re: ufcs and integer params

2012-07-18 Thread Adam D. Ruppe

On Thursday, 19 July 2012 at 02:57:05 UTC, Brad Roberts wrote:
The clear argument for me is that it must be trivial to take an 
existing member variable and change it to a property

function pair _and vice versa_.


I can see some value in that.


The other bits about non-@property
functions is significantly less important as far as I'm 
concerned.



Question to everybody: how would you feel about this
compromise: the strictness is opt in.

So, if you don't use @property, you get the status quo.
These functions can be called either way, but if there's
ambiguity, it tends toward treating them as a function.

If you do use @property, it becomes strict.


This would cover your concerns while keeping the
dual-syntax benefits, and it minimizes code breakage
of existing stuff.


It'd also discourage a lot of the questions of to @property
or not to @property, since you can just ask "is it a real
property" without falsely marking stuff for UFCS chaining or
whatever. It'd save me a lot of headaches on my range.empty's
too.




If we switch to this compromise position, I'm about 98%
sure I'd vote yes (would have to actually try it to be certain).


Re: ufcs and integer params

2012-07-18 Thread Brad Roberts
On 7/18/2012 5:30 AM, Adam D. Ruppe wrote:
> On Wednesday, 18 July 2012 at 11:37:43 UTC, David Nadlinger wrote:
>> Arguments! Yay!
> 
> I've gone over this a dozen times on the group and on
> bugzilla, and I'm kinda sick of repeating it.
> 
> -property breaks craploads of code. That's a huge negative,
> and nobody has even come close to countering that.
> 
> "-property will be the standard" is utterly worthless, yet
> that's really the only thing I see brought up again.

The clear argument for me is that it must be trivial to take an existing member 
variable and change it to a property
function pair _and vice versa_.  If someone has @property int foo() and 
@property void foo(int) as members of a class
and call sites add (), then yanking those back to just int foo; will fail, 
badly.  So that must be explicitly disallowed.

THAT is the argument for enforcing the lack of parens after properties, imho.  
The other bits about non-@property
functions is significantly less important as far as I'm concerned.

My 2 cents,
Brad


Re: Compilation failure

2012-07-18 Thread Timon Gehr

On 07/19/2012 12:42 AM, bearophile wrote:

Timon Gehr:


You are right; this is a bug.


This discussion is not about an obscure language detail, it's a common
situation.


FWIW, I have never run across it before.


So if you think this is a bug, then please Timon file it in
Bugzilla.



Usually bugs are reported by the guy who finds them, but here you go:
http://d.puremagic.com/issues/show_bug.cgi?id=8400


Re: Object Pointer

2012-07-18 Thread Jonathan M Davis
On Wednesday, July 18, 2012 20:37:50 Namespace wrote:
> Only for correctness:
> If i allocate memory on the GC Heap in e.g. a struct and don't
> free the memory in the DTor, then the GC free the memory
> automatically?

You don't normally _ever_ free memory from the GC heap. That's the GC's job. 
That's what garbage collectors _do_. There are cases where it may be valuable 
to explicitly free GC memory for performance reasons, but it's risky and opens 
yourself up to the possibility of accessing freed memory and the like. That's 
one of the reasons why delete is being deprecated.

So, no, you don't have to free GC allocated memory in a struct's destructor. 
The GC takes care of it.

- Jonathan M Davis


Re: Compilation failure

2012-07-18 Thread bearophile

Timon Gehr:


You are right; this is a bug.


This discussion is not about an obscure language detail, it's a 
common situation. So if you think this is a bug, then please 
Timon file it in Bugzilla.


Bye,
bearophile


Re: Is this actually supposed to be legal?

2012-07-18 Thread Timon Gehr

On 07/18/2012 01:37 AM, Jonathan M Davis wrote:

On Tuesday, July 17, 2012 23:11:43 Timon Gehr wrote:

This issue is unrelated to CRTP. (also, you probably want to negate
that static if condition, otherwise the code is valid and poses no
challenge to a compiler.)


It's not that it makes the compiler's life hard. It's the fact that
conditional compilation relies on state that doesn't exist yet. It's messed up
to be checking whether an object defines something when you're in the middle of
defining that object.
...


Declarations in D are declarative. There is no notion of state.



Re: Is this actually supposed to be legal?

2012-07-18 Thread Timon Gehr

On 07/18/2012 11:08 PM, monarch_dodra wrote:

On Tuesday, 17 July 2012 at 23:38:04 UTC, Jonathan M Davis wrote:

It's not that it makes the compiler's life hard. It's the fact that
conditional compilation relies on state that doesn't exist yet. It's
messed up
to be checking whether an object defines something when you're in the
middle of
defining that object.

[snip]

- Jonathan M Davis


Well, while you "can" do it in C++ as the "Curiously Recursive Template
Pattern" (particularly popular way of implementing the singleton pattern
BTW), you can't just do anything you feel like doing with it.

If I remember correctly, in C++, you can't access any of T's members, or
create any (stack) instances of T, or (I think) call T's any of T's
static members, because "T is not correctly formed yet".

Did you try anything more advanced? For example, this outright _crashes_
my (r)dmd:


class MyBase(T)
{
int a = T.hello();
}

class MySubA : MyBase!MySubA
{
static int hello(){return 0;}
}



Well, that is a bug.


I'm not entirely sure how valid the comparison with C++'s CRTP is,
because D's classes are actually pointer to implementation,  but I think
it is a safe bet that what C++ can't do, neither can D.


Careful there. D allows forward references. This is all supposed to work 
in D. (but DMD is poor when it comes to tricky symbol lookup tasks.)


Re: Is this actually supposed to be legal?

2012-07-18 Thread monarch_dodra

On Tuesday, 17 July 2012 at 23:38:04 UTC, Jonathan M Davis wrote:
It's not that it makes the compiler's life hard. It's the fact 
that
conditional compilation relies on state that doesn't exist yet. 
It's messed up
to be checking whether an object defines something when you're 
in the middle of

defining that object.

[snip]

- Jonathan M Davis


Well, while you "can" do it in C++ as the "Curiously Recursive 
Template Pattern" (particularly popular way of implementing the 
singleton pattern BTW), you can't just do anything you feel like 
doing with it.


If I remember correctly, in C++, you can't access any of T's 
members, or create any (stack) instances of T, or (I think) call 
T's any of T's static members, because "T is not correctly formed 
yet".


Did you try anything more advanced? For example, this outright 
_crashes_ my (r)dmd:



class MyBase(T)
{
  int a = T.hello();
}

class MySubA : MyBase!MySubA
{
static int hello(){return 0;}
}

I'm not entirely sure how valid the comparison with C++'s CRTP 
is, because D's classes are actually pointer to implementation, 
but I think it is a safe bet that what C++ can't do, neither can 
D.


Re: opDot == alias this?

2012-07-18 Thread Namespace

Understand.
Many thanks to you both.


Re: Object Pointer

2012-07-18 Thread Namespace

Only for correctness:
If i allocate memory on the GC Heap in e.g. a struct and don't 
free the memory in the DTor, then the GC free the memory 
automatically?


Re: opDot == alias this?

2012-07-18 Thread Jonathan M Davis
On Wednesday, July 18, 2012 16:58:34 Namespace wrote:
> First:
> Why is opDot not listed here:
> http://dlang.org/operatoroverloading.html ?
> How much other operators exists which are not listed there?
> 
> And:
> Is opDot the same as alias this? I think so.

opDot is going to be deprecated and really should have been already ( 
http://d.puremagic.com/issues/show_bug.cgi?id=2327 ). Don't use it. alias this 
and opDispatch give you the same thing, only better.

http://stackoverflow.com/questions/9880064/d2-what-are-semantics-of-opdot

- Jonathan M Davis


Re: foreach for ranges?

2012-07-18 Thread Ali Çehreli

On 07/18/2012 08:21 AM, Mike L. wrote:
>> Also, UFCS makes no sense on overloaded operators, because they 
don't get

>> called with ".", and all UFCS is is changing obj.func(params) to
>> func(obj,
>> params).
>>
>> - Jonathan M Davis
>
> Ok, that's basically what I was wondering. I had assumed foreach(e;
> someThing) {} could possibly have been converted to someThing.opApply()
> . Thanks for clarifying.

But that is still true and opApply receives the body of the foreach loop 
as a delegate:


someThing.opApply(delegate int(/* loop variables */) {
// ... the body of foreach ...
return terminationCode; // whether the user did 'break;'
});

Also, the following bug (that is already fixed) is somewhat related to 
this discussion:


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

Ali



Re: Segmentation fault while creating a class object by dlsym-ed function

2012-07-18 Thread Alexandr Druzhinin
Probably you mean the same problem that is described in the thread 
avobe, see "using GC needs particular skills?"


Every time after execution my code I got very frustating access 
violation and the problem was misunderstanding garbage collector because 
I've never used it before.





Re: opDot == alias this?

2012-07-18 Thread Simen Kjaeraas
On Wed, 18 Jul 2012 16:58:34 +0200, Namespace   
wrote:



First:
Why is opDot not listed here: http://dlang.org/operatoroverloading.html ?
How much other operators exists which are not listed there?


I believe it's being deprecated. As far as I know, no other operators are
unmentioned.



Is opDot the same as alias this? I think so.


They are related, but not the same. opDot allows access to the returned  
type's

members and functions, but not the type itself.



What are the advantages and disadvantages of both?


alias this allows implicit type conversions, opDot does not. That's about  
it,

I think.



Which of them should i use?


Depends. Look above. If you want a type to be usable as if another type,  
use
alias this. If you just want to be able to access members of the other  
type,

use opDot.



Will one of them disappear in the future?


As stated above, I believe opDot is scheduled for deprecation, but I'm  
unsure if

(not to mention when) it will happen.

I think opDot is more flexible as alias this. You can have one alias  
this for one class/struct, but various opDot's, as this example shows:


TDPL states that multiple alias this should be supported, but it has not  
yet

been implemented in the compiler.

--
Simen


Re: Magic type return

2012-07-18 Thread Regan Heath
On Tue, 17 Jul 2012 15:23:05 +0100, bearophile   
wrote:



Andrea Fontana:


class Known
{
 void* data; // external data by c api
 int type;  // 0 for int, 1 for string, etc. ..
}

How can I implement a method like this?

Known  known;  // <-- suppose known.type == 1;
string s  = known.value(); // <-- automatic


To do this Known.value() needs to return different types according to  
the run-time value of Known.type. This is not possible in a statically  
typed language... You need to find other solutions.


Unless we had overload based on return type, right?

e.g.

class Known
{
  string value()
  {
if (type != 1)
  throw..;
return cast(string)data;
  }

  int value()
  {
if (type != 0)
  throw ..;
return cast(int)data;
  }
}

The compiler could produce the correct code/call for the line

string s = known.value();

then, but it's not a feature we're likely to see any time soon.

R

--
Using Opera's revolutionary email client: http://www.opera.com/mail/


Re: foreach for ranges?

2012-07-18 Thread Mike L.
Also, UFCS makes no sense on overloaded operators, because they 
don't get
called with ".", and all UFCS is is changing obj.func(params) 
to func(obj,

params).

- Jonathan M Davis


Ok, that's basically what I was wondering. I had assumed 
foreach(e; someThing) {} could possibly have been converted to 
someThing.opApply() . Thanks for clarifying.


opDot == alias this?

2012-07-18 Thread Namespace

First:
Why is opDot not listed here: 
http://dlang.org/operatoroverloading.html ?

How much other operators exists which are not listed there?

And:
Is opDot the same as alias this? I think so.

This code

[code]
class Foo {
public:
void echo() const {
writeln("Foo");
}
}

class Test {
private:
Foo _f;

public:
this(ref Foo f) {
this._f = f;
}

@property
ref Foo opDot() {
return this._f;
}
}
[/code]

Works exactly as these:

[code]
class Test2 {
private:
Foo _f;

public:
this(ref Foo f) {
this._f = f;
}

@property
ref Foo Get() {
return this._f;
}

alias Get this;
}
[/code]

But with opDot it is shorter. What are the advantages and 
disadvantages of both?


Which of them should i use? Will one of them disappear in the 
future?
I think opDot is more flexible as alias this. You can have one 
alias this for one class/struct, but various opDot's, as this 
example shows:


[code]
class Foo {
public:
void echo() const {
writeln("Foo");
}
}

class Bar {
public:
void echo() const {
writeln("Bar");
}
}

class Test3 {
private:
Foo _f;
Bar _b;

public:
this(ref Foo f, ref Bar b) {
this._f = f;
this._b = b;
}

@property
ref Foo opDot() {
return this._f;
}

@property
const(Bar) opDot() const {
return this._b;
}
}
[/code]

If Test3 is unconst, it prints with Foo, otherwise with Bar.


Re: Magic type return

2012-07-18 Thread Andrea Fontana
Yes I did it using Variant and it works fine

Il giorno mer, 18/07/2012 alle 16.42 +0200, Philippe Sigaud ha scritto:

> > class Known
> > {
> >  void* data; // external data by c api
> >  int type;  // 0 for int, 1 for string, etc. ..
> > }
> >
> > How can I implement a method like this?
> >
> > Known  known;  // <-- suppose known.type == 1;
> > string s  = known.value(); // <-- automatic 
> >
> > I just know how to do this:
> >
> > string s = know.value!string(); 
> 
> As bearophile said, you cannot change a value's type (which is a
> compile-time construct) with a runtime value, as is Known.type. 
> 
> Second point, in D, the rhs is fully evaluated before being assigned
> to the lhs, I think. So, known.value() must evaluate to *something*,
> without knowing it will be assigned to a string.
> In your example, what happens if known.type != 1? 
> 
> You can use Phobos Variant, (or Algebraic if the range of types you
> plan to use is known beforehand). Then, you should test typeid before
> using it.
> 




Re: Is this actually supposed to be legal?

2012-07-18 Thread Philippe Sigaud
> That being said, I have never used CRTP in D so far, since template
mixins seem to be the better choice in almost all situations.

FWIW, CRTP is the main reason I used classes in Pegged, to allow grammar
rules to refer to themselves. My earlier attempts with structs did not work.

So, given a grammar rule like:

Expr <- '(' Expr ')' / ...

I use:

class Expr : Or! (Sequence!(Literal!("("), Expr, Literal!(")")) , ...)
{ ... }

As you can see, class Expr refer to itself while it's not defined yet. It's
the main use I've found for this idiom. Many C++ parsers use the same trick
and I was particularly glad to see it worked in D too.

Most of the times I use mixins, but could not find a way to do the same
recursive rule definition with them.

IIRC, I talk a bit about the CRTP in my tutorial on D templates , on Github.

Philippe


Re: Magic type return

2012-07-18 Thread Philippe Sigaud
> class Known
> {
>  void* data; // external data by c api
>  int type;  // 0 for int, 1 for string, etc. ..
> }
>
> How can I implement a method like this?
>
> Known  known;  // <-- suppose known.type == 1;
> string s  = known.value(); // <-- automatic
>
> I just know how to do this:
>
> string s = know.value!string();

As bearophile said, you cannot change a value's type (which is a
compile-time construct) with a runtime value, as is Known.type.

Second point, in D, the rhs is fully evaluated before being assigned to the
lhs, I think. So, known.value() must evaluate to *something*, without
knowing it will be assigned to a string.
In your example, what happens if known.type != 1?

You can use Phobos Variant, (or Algebraic if the range of types you plan to
use is known beforehand). Then, you should test typeid before using it.


Re: using GC needs particular skills?

2012-07-18 Thread Alexandr Druzhinin

18.07.2012 8:00, Mike Parker пишет:


Destructors are unreliable. There is no guarantee that a destructor will
be called before the garbage collector is terminated. When the program
exits, the runtime will call gc_term which will then call destructors on
any objects that haven't yet been cleaned up. But the order in which
those destructors are called is unpredictable. This is a recipe for all
sorts of problems.

Static class destructors and module destructors are more reliable in
that you know they will be called in a particular order. But, they are
called before the gc is terminated.

Your particular problem is this. Derelict-style bindings load shared
libraries dynamically via system calls. That means that every bound
function is actually a function pointer. The shared library is then
unloaded in a static module destructor. When DRuntime exits, it calls
all the module destructors *before* calling gc_term. So what's happening
is:

1. The module destructors are run
2. Derelict unloads the shared library, thereby causing all of the
function pointers into that library to become invalid.
3. gc_term is run
4. The destructor of one of your objects is called and it tries to call
a function from the Derelict binding, but since that function pointer is
no longer valid, you get a segfault.

When cleaning up resources in D, you should generally not rely on class
destructors to do so. You'll want to include some sort of process to
clean up everything yourself. What I tend to do is something like this:


void term()
{
 // initiate cleanup here
}

void main()
{
 scope(exit) term();
 init();
 run();
}


The scope(exit) will ensure that the cleanup is run regardless of how
the program exits. Every subsystem in my program will have term()
function or method that substitutes for a destructor. This works fine
and I have no problems with it.

Of course, you can still use destructors for scoped object instances in
cases where you want RAII inside a particular scope.


Thank you very much for your help! Now I undestand it - I've never used 
gc before.


Re: Compilation failure

2012-07-18 Thread Lemonfiend

On Wednesday, 18 July 2012 at 12:15:52 UTC, Lemonfiend wrote:

On Wednesday, 11 July 2012 at 02:30:47 UTC, Timon Gehr wrote:

On 07/11/2012 04:25 AM, ixid wrote:

in some way it sees global immutables almost as enums


This seems like a bad idea. Consistency of behaviour would 
seem to be a

good principle to expect of a language.


You are right; this is a bug.


Has someone reported this bug? I can't seem to find it in the 
tracker.


If not, how should I go about reporting it?


Also, I don't think I'm clear enough about the differences 
between immutables, consts and enums to write a bug report about 
this.


Re: ufcs and integer params

2012-07-18 Thread David Nadlinger

On Wednesday, 18 July 2012 at 12:30:46 UTC, Adam D. Ruppe wrote:

2) -property doesn't even get that right anyway. Not kidding,
try it. -property might as well be renamed -break-my-code-and-
give-me-ABSOLUTELY-NOTHING-in-return.

Why, why would we ever consent to having that standard?


I actually tend to agree with this part – I see -property more 
like an experiment help determining the behavior we want to make 
the default with real-world testing. We should definitely try to 
fix/improve the implementation of -property before we consider to 
make it the default. But without it, the discussion might have 
never gotten to the point where we are now, so I still consider 
it a success.


David


Re: ufcs and integer params

2012-07-18 Thread Adam D. Ruppe

On Wednesday, 18 July 2012 at 11:37:43 UTC, David Nadlinger wrote:

Arguments! Yay!


I've gone over this a dozen times on the group and on
bugzilla, and I'm kinda sick of repeating it.

-property breaks craploads of code. That's a huge negative,
and nobody has even come close to countering that.

"-property will be the standard" is utterly worthless, yet
that's really the only thing I see brought up again.

The other most common thing is "I don't like how writeln = 10
looks". Easy response: then don't write that.

If you're going to break code because someone might write
something you find ugly - note this is different than the 
arguments
people like Crockford make about, say, Javascript's ==, which he 
argues
is a bug 95% of the time you see it, this is just "I don't like 
how

that looks".

But if we're going to let the possibility for subjective ugliness
be justification for BREAKING CODE, I can't stress that enough,
we might as well just nuke the whole language.



BTW, a common fallacy I also here is bringing up the edge cases
like returning a delegate in a property. Two points:

1) That has *nothing* to do with syntax. The @property decoration
takes care of that, regardless of syntax. Why do we have to
break a common case to fix an edge case especially when
we /can/ have our cake and eat it too?

2) -property doesn't even get that right anyway. Not kidding,
try it. -property might as well be renamed -break-my-code-and-
give-me-ABSOLUTELY-NOTHING-in-return.

Why, why would we ever consent to having that standard?


Re: Compilation failure

2012-07-18 Thread Lemonfiend

On Wednesday, 11 July 2012 at 02:30:47 UTC, Timon Gehr wrote:

On 07/11/2012 04:25 AM, ixid wrote:

in some way it sees global immutables almost as enums


This seems like a bad idea. Consistency of behaviour would 
seem to be a

good principle to expect of a language.


You are right; this is a bug.


Has someone reported this bug? I can't seem to find it in the 
tracker.


If not, how should I go about reporting it?


Re: ufcs and integer params

2012-07-18 Thread David Nadlinger

On Wednesday, 18 July 2012 at 07:30:10 UTC, Marco Leise wrote:

Am Sun, 15 Jul 2012 19:17:11 +0200
schrieb Philippe Sigaud :

[…]
auto distance = 100.km;
auto speed = 120.km/hour;

auto timeToDestination = distance/speed; // timeToDest is a 
time (seconds)


The version on Github is grossly limited (it's just a sketch), 
but it gives
an idea of what's possible. My goal is to code a generic unit 
system
generator, given user inputs such as a list of units and 
sub-units.


[…]


Sounds fun. I mean, it makes me happy to see code written like 
this instead of

Distance distance = new Kilometers(100);
Speed speed = Speed.fromDistanceByTime(new Kilometers(120), new 
Hours(1));


I find multiplication to read much more natural:
---
enum km = kilo * meter;

auto distance = 100.0 * km;
auto speed = 100.0 * km / hour;

auto timeToDest = distance / speed;
---

See http://klickverbot.at/code/units/ for a slightly neglected 
implementation of this scheme. It supports stuff like defining 
new units with arbitrary (potentially runtime) conversion 
factors, properly typechecked affine units (think degrees 
celsius), etc. – but any error messages and symbol names will 
probably look like if the compiler had a seizure.


David


Re: ufcs and integer params

2012-07-18 Thread David Nadlinger

On Monday, 16 July 2012 at 23:18:10 UTC, Adam D. Ruppe wrote:

I'm another who is /vehemently/ against the utter
idiocy that is the -property switch.


Arguments! Yay!


Re: Segmentation fault while creating a class object by dlsym-ed function

2012-07-18 Thread Konstantin J. Chernov

Thank you for your replies!

I've found a working solution - all I needed is to change wstring 
to const wstring, and pass it not as func("something"), but as


  wstring tmp = "something"; func(tmp);

That's really odd, because I don't understand, how those changes 
made segfault disappear.


Here's the working code:

test.d:

import std.c.linux.linux;
import std.stdio;
import testclass;

int main(string[] args)
{
void* handle = dlopen("./testclass.so", RTLD_LAZY | 
RTLD_LOCAL);

testclass function(const wstring) a;
a = cast(testclass function(const wstring))dlsym(handle, 
"loadClass");

wstring tmp = "Test";
testclass b = a(tmp);
return 0;
}

testclass.di:

class testclass
{
this(const wstring loadmsg);
~this();
wstring foo();
};

testclass.d:

import std.stdio;

class testclass
{
private wstring msg;
this(const wstring loadmsg)
{
writeln("Class constructor");
this.msg = loadmsg;
}
~this()
{
}
wstring foo()
{
return msg;
}
};

extern(C) testclass loadClass(const wstring loadmsg)
{
return new testclass(loadmsg);
}


dmd test.d -L-ldl
dmd testclass.d -fPIC -shared


Re: Segmentation fault while creating a class object by dlsym-ed function

2012-07-18 Thread Alex Rønne Petersen

On 18-07-2012 06:51, Konstantin J. Chernov wrote:

Hello. When I'm trying to create a class object by using a dlsym-ed
function, I'm getting a segmentation fault after execution of program.

However, if I'm deleting that object before 'return 0' in main (by using
'delete b'), everything is going fine.

I'm just started to learn D after using C++ for more than 5 years, so
some things look really strange for me (especially that 'new
className()' doesn't return a pointer).

What am I doing wrong here? Is there any way to do what I'm trying to do
right way?

Thanks.

test.d:

import std.c.linux.linux;
import std.stdio;
import testclass;

int main(string[] args)
{
 void* handle = dlopen("./testclass.so", RTLD_LAZY | RTLD_LOCAL);
 testclass function(wstring) a;
 a = cast(testclass function(wstring))dlsym(handle, "loadClass");
 testclass b = a("test");
 return 0;
}

testclass.di:

class testclass
{
 this(const wstring loadmsg);
 ~this();
 wstring foo();
};

testclass.d:

import std.stdio;

class testclass
{
 private wstring msg;
 this(const wstring loadmsg)
 {
 writeln("Class constructor");
 this.msg = loadmsg;
 }
 ~this()
 {
 }
 wstring foo()
 {
 return msg;
 }
};

extern(C) testclass loadClass(const wstring loadmsg)
{
 return new testclass(loadmsg);
}



As Jacob said, the D runtime isn't quite ready for shared libraries yet.

What you can do, however, is provide a bit of inversion of control to 
make the allocation happen from the runtime linked statically to your 
application:


import std.conv;

alias extern (C) void* function(size_t) Allocator;

extern (C) testclass loadClass(Allocator allocator, const wstring loadmsg)
{
auto size = __traits(classInstanceSize, testclass);
auto mem = allocator(size);

return emplace!testclass(mem[0 .. size], loadmsg);
}

Then in the application:

import core.memory;
import core.sys.posix.dlfcn;
import std.stdio;
import testclass;

void* allocate(size_t size)
{
return GC.malloc(size);
}

int main(string[] args)
{
auto h = dlopen("./testclass.so", RTLD_LAZY | RTLD_LOCAL);
auto a = cast(testclass function(Allocator, wstring))dlsym(h, 
"loadClass");

auto b = a(&allocate, "test");

return 0;
}

This should make allocation work, but I haven't actually tested it. Note 
also that even if it does work, things get more complicated when the 
class you're allocating has a finalizer, for example (see 
http://dlang.org/phobos/core_memory.html#FINALIZE).


--
Alex Rønne Petersen
a...@lycus.org
http://lycus.org




Re: is() and const

2012-07-18 Thread Jonathan M Davis
On Wednesday, July 18, 2012 10:43:23 Andrea Fontana wrote:
> So:
> const(int) : int  <-- true

const int is implicitly convertible to int, because it's a value type, and 
assigning a const int to an int (or vice versa) makes a copy.

> const(PP) : PP  <-- false

const PP is not implicitly convertible to PP, because it's a reference type. 
So, assigning a PP to a PP doesn't make a copy. It just copies the reference. 
And a const PP can't be converted to a mutable PP, because that would be 
dropping the const, invalidating const's guarantees.

If PP were a struct with no pointers, arrays, or reference types (or it had a 
postblit constructor), then it would be a value type, and const PP _would_ 
implicitly convert to PP.

> Is this behaviour correct?

Yes.

> And how can I check if T is of a certain class ignoring consts (and
> avoiding double checks)?

is(Unqual!T == T)

Unqual is in std.traits.

- Jonathan M Davis


Re: is() and const

2012-07-18 Thread Andrea Fontana
It seems to works (but i use Unqual!T directly)

Thank you :)

Il giorno mer, 18/07/2012 alle 11.13 +0200, bearophile ha scritto:

> Andrea Fontana:
> 
> > const(int) : int  <-- true
> > const(PP) : PP  <-- false
> >
> > Is this behaviour correct?
> 
> I think it's correct, and it's caused by the difference between 
> value types and reference types.
> 
> 
> > And how can I check if T is of a certain class ignoring consts 
> > (and avoiding double checks)?
> 
> There are some different ways to do it, one of them is to use 
> something like (untested):
> 
> is(Unqual!typeof(x) == PP)
> 
> Where Unqual is in Phobos, std.traits.Unqual.
> 
> Bye,
> bearophile




Re: Segmentation fault while creating a class object by dlsym-ed function

2012-07-18 Thread Jacob Carlborg

On 2012-07-18 10:17, Konstantin J. Chernov wrote:

What am I doing wrong here? Is there any way to do what I'm trying to do
right way?


Dynamic libraries aren't properly supported by the runtime.


That's terrible:(

It's so nice to make an interface, and create classes that inherit this
interface dynamically, without linking...

Maybe there's another way?



No, not that I can think of for now. But it's a known problem that is 
being worked on: https://github.com/dawgfoto/druntime/tree/SharedRuntime


--
/Jacob Carlborg




Re: Segmentation fault while creating a class object by dlsym-ed function

2012-07-18 Thread bearophile

Konstantin J. Chernov:


testclass.di:

class testclass
{
this(const wstring loadmsg);
~this();
wstring foo();
};


And usually you don't need to write .di files in D.

Bye,
bearophile


Re: is() and const

2012-07-18 Thread bearophile

Andrea Fontana:


const(int) : int  <-- true
const(PP) : PP  <-- false

Is this behaviour correct?


I think it's correct, and it's caused by the difference between 
value types and reference types.



And how can I check if T is of a certain class ignoring consts 
(and avoiding double checks)?


There are some different ways to do it, one of them is to use 
something like (untested):


is(Unqual!typeof(x) == PP)

Where Unqual is in Phobos, std.traits.Unqual.

Bye,
bearophile


is() and const

2012-07-18 Thread Andrea Fontana
Run this code:

class PP {}

void what(T)(T val)
{
static if (is(T == int)) writeln ("T == int");
static if (is(T == const(int))) writeln ("T == const(int)");
static if (is(T : int)) writeln ("T : int");
static if (is(T == PP)) writeln ("T == PP");
static if (is(T == const(PP))) writeln ("T == const(PP)");
static if (is(T : PP)) writeln ("T : PP");
}

void main(string[] args)
{

const int aa = 10;
int ab;

const PP ba = new PP;
PP bb = new PP;

writeln("- Testing const(int)");
what(aa);
writeln();

writeln("- Testing int");
what(ab);
writeln();

writeln("- Testing const(PP)");
what(ba);
writeln();

writeln("- Testing PP");
what(bb);
writeln();

return;
}

It says:

- Testing const(int)
T == const(int)
T : int

- Testing int
T == int
T : int

- Testing const(PP)
T == const(PP)

- Testing PP
T == PP
T : PP


So:
const(int) : int  <-- true
const(PP) : PP  <-- false

Is this behaviour correct?

And how can I check if T is of a certain class ignoring consts (and
avoiding double checks)?






Re: Segmentation fault while creating a class object by dlsym-ed function

2012-07-18 Thread Konstantin J. Chernov
What am I doing wrong here? Is there any way to do what I'm 
trying to do

right way?


Dynamic libraries aren't properly supported by the runtime.


That's terrible:(

It's so nice to make an interface, and create classes that 
inherit this interface dynamically, without linking...


Maybe there's another way?



Re: ufcs and integer params

2012-07-18 Thread Marco Leise
Am Sun, 15 Jul 2012 19:17:11 +0200
schrieb Philippe Sigaud :

> > On Sunday, July 15, 2012 05:30:55 Jay Norwood wrote:
> > > I see from this other discussions that it looks like 2.059 ( or
> > > maybe 2.060) does support something like 3.cm().   Not sure from
> > > the discussion if it would also accept 3.cm as in the xtext/xtend
> > > example.
> 
> Hi Jay,
> 
> I had a little fun with coding a units (SI units) system in D and pushed an
> incomplete version on Github a few weeks ago:
> 
> https://github.com/PhilippeSigaud/Units
> 
> It allows things like:
> 
> auto distance = 100.km;
> auto speed = 120.km/hour;
> 
> auto timeToDestination = distance/speed; // timeToDest is a time (seconds)
> 
> The version on Github is grossly limited (it's just a sketch), but it gives
> an idea of what's possible. My goal is to code a generic unit system
> generator, given user inputs such as a list of units and sub-units.
> 
> cheers,
> 
> Philippe

Sounds fun. I mean, it makes me happy to see code written like this instead of
Distance distance = new Kilometers(100);
Speed speed = Speed.fromDistanceByTime(new Kilometers(120), new Hours(1));

:D

-- 
Marco