Re: How do you get comfortable with Dlang.org's Forum?

2018-02-26 Thread Basile B. via Digitalmars-d
On Saturday, 24 February 2018 at 19:30:52 UTC, Patrick Schluter 
wrote:
On Saturday, 24 February 2018 at 18:46:50 UTC, Steven 
Schveighoffer wrote:

On 2/24/18 7:00 AM, Patrick Schluter wrote:
On Saturday, 24 February 2018 at 04:41:44 UTC, H. S. Teoh 
wrote:

[...]


Last week I saw a video showing how a forum was shutdown 
because it was alledgedly full of racists. The thread where 
there were "racist comments" was in fact one where the 
initial question was ok, the answers absolutely nice but then 
the troll changed the initial post to something sinister and 
all the positive answers looked like agreement to the racist 
slur of the first comment. It was then demonstrated that the 
troll was a journalist from a big mainstream media. If I find 
the article again I will give a link (it's in french though, 
might not interest that much).





Wow, that's insane. I would be interested in seeing it.

It's in the history of my work PC, may be I will find it on 
monday.


I'm french, i'm interested to know what the hell you talked 
about. Google search gave nothing. Do you referred to the 
journalist who was harassed by people on a gamer forum ?


Re: implicit construction operator

2018-02-26 Thread aliak via Digitalmars-d

On Monday, 26 February 2018 at 21:36:49 UTC, ketmar wrote:

aliak wrote:

It makes libraries *much* more intuitive and expressive (C++ 
just got it wrong by choosing the wrong default). If you allow 
library authors to opt in instead of opt out then it becomes a 
conscious decision for one.


library authors can create overloads for various argument 
types. with `foo(T...) (T args)` it is possible to generate 
conversions with CTFE. so we *already* have such feature.


Touche.


Re: implicit construction operator

2018-02-26 Thread aliak via Digitalmars-d

On Monday, 26 February 2018 at 21:34:21 UTC, ketmar wrote:

aliak wrote:

And if that's also a no no, how about char -> int. Or int -> 
float? Is ok?


no, it is not ok. it was a mistake. it is now too late to fix 
it, but we can avoid doing more of the same kind.


Oops, yeah, ok, D char ...  char -> int yeah mistake.

int -> long even?


I have a patch to let lldb demangle D symbols ; help welcome to improve it

2018-02-26 Thread Timothee Cour via Digitalmars-d
https://github.com/llvm-mirror/lldb/pull/3
+
https://github.com/timotheecour/dtools/blob/master/dtools/lldbdplugin.d


on OSX, it works great except when encountering large symbols which
cause segfault when GC does a collection (triggered inside
core.demangle.demangle);
Help is welcome to improve that (or more generally to improve D
support in lldb, which I started in
https://github.com/llvm-mirror/lldb/pull/3)
NOTE: lldb doesn't accept github PR's but easier to work with PR's for
whoever wants to help on tha in the meantime


Re: implicit construction operator

2018-02-26 Thread H. S. Teoh via Digitalmars-d
On Mon, Feb 26, 2018 at 09:45:03PM +, TheFlyingFiddle via Digitalmars-d 
wrote:
> On Monday, 26 February 2018 at 21:30:09 UTC, aliak wrote:
> > On Monday, 26 February 2018 at 19:32:44 UTC, ketmar wrote:
> > > WebFreak001 wrote:
> > And if that's also a no no, how about char -> int. Or int -> float?
> > Is ok?
> > 
> > Maybe there're some valid arguments, to disallow it *completely*
> > though?
> > 
> > Cheers
> 
> I would be very happy if char -> int and int -> float was not implicit.

Yeah, implicit char -> int is totally evil, and should never have gotten
into the language in the first place. To wit:

void foo(dchar ch) {
backup_files();
}
void foo(byte b) {
format_disk();
}
foo('a');   // guess which one gets called.


> This has happened to me enough times that i remember it:
> 
> float a = some_int / some_other_int; //ops i don't think this was what I 
> wanted.
> constrast
> float a = some_int.to!float / some_other_int.to!float; //ugly but at-least 
> its clear.

Actually, since operations involving float are "infectious", all you
need is:

float a = some_int.to!float / some_other_int;


> Not really a big deal (and auto kind of ruins it) but it would make
> stuff consistent between user types and built in ones.

Not sure what you mean here.  In a user type, if opBinary!"/" returns an
int, then you still have the same problem.


T

-- 
He who laughs last thinks slowest.


Re: Go 2017 Survey Results

2018-02-26 Thread jmh530 via Digitalmars-d

On Monday, 26 February 2018 at 21:04:20 UTC, Ali wrote:

This link was posted today on hacker news (ycombinator)
https://blog.golang.org/survey2017-results
https://news.ycombinator.com/item?id=16468358

My biggest takes from this are
1) people are looking for python alternatives, probably more so 
than c alternatives

2) generic programming is important


Or why I learned D.


Re: implicit construction operator

2018-02-26 Thread TheFlyingFiddle via Digitalmars-d

On Monday, 26 February 2018 at 21:30:09 UTC, aliak wrote:

On Monday, 26 February 2018 at 19:32:44 UTC, ketmar wrote:

WebFreak001 wrote:
And if that's also a no no, how about char -> int. Or int -> 
float? Is ok?


Maybe there're some valid arguments, to disallow it 
*completely* though?


Cheers


I would be very happy if char -> int and int -> float was not 
implicit.


This has happened to me enough times that i remember it:

float a = some_int / some_other_int; //ops i don't think this was 
what I wanted.

constrast
float a = some_int.to!float / some_other_int.to!float; //ugly but 
at-least its clear.


Not really a big deal (and auto kind of ruins it) but it would 
make stuff consistent between user types and built in ones.


Re: Slow code, slow

2018-02-26 Thread ketmar via Digitalmars-d

H. S. Teoh wrote:


On Mon, Feb 26, 2018 at 10:12:25PM +0200, ketmar via Digitalmars-d wrote:
[...]

but until that brave new world materializes, we have a smart/fast
dilemma.  alas.


I'd like to contribute to the materialization of that brave new world.
Rather than sit around and wait for it to happen.  :-P


i'd like to do it too, but dmd code to process templates knocks me out of 
my consciousness. alas.


Re: implicit construction operator

2018-02-26 Thread ketmar via Digitalmars-d

aliak wrote:

It makes libraries *much* more intuitive and expressive (C++ just got it 
wrong by choosing the wrong default). If you allow library authors to opt 
in instead of opt out then it becomes a conscious decision for one.


library authors can create overloads for various argument types. with 
`foo(T...) (T args)` it is possible to generate conversions with CTFE. so 
we *already* have such feature.


Re: Go 2017 Survey Results

2018-02-26 Thread H. S. Teoh via Digitalmars-d
On Mon, Feb 26, 2018 at 09:04:20PM +, Ali via Digitalmars-d wrote:
[...]
> 2) generic programming is important
[...]

It's something sorely lacking in Go, so it's not unsurprising it's a big
item on the list.


T

-- 
BREAKFAST.COM halted...Cereal Port Not Responding. -- YHL


Re: Slow code, slow

2018-02-26 Thread H. S. Teoh via Digitalmars-d
On Mon, Feb 26, 2018 at 10:12:25PM +0200, ketmar via Digitalmars-d wrote:
[...]
> but until that brave new world materializes, we have a smart/fast
> dilemma.  alas.

I'd like to contribute to the materialization of that brave new world.
Rather than sit around and wait for it to happen.  :-P


T

-- 
Your inconsistency is the only consistent thing about you! -- KD


Re: implicit construction operator

2018-02-26 Thread aliak via Digitalmars-d

On Monday, 26 February 2018 at 19:32:44 UTC, ketmar wrote:

WebFreak001 wrote:


Now before you would have only been able to do this:

---
Nullable!Foo a;
foo(a, Nullable!int(5));
---

but now you should also be able to do:

---
Nullable!Foo x = null;
Nullable!Foo y = 5;

foo(null, 5);


please no. such unobvious type conversions goes out of control 
really fast. there is a reason why D doesn't have such thing, 
this is not an oversight, but a design decision.


How if you don't mind me asking? Seems like many features can go 
out of control if used incorrectly, but that doesn't mean they're 
a bad idea. I can understand they're a slippery slope, but it 
seems some people think it's a completely bad idea.


It makes libraries *much* more intuitive and expressive (C++ just 
got it wrong by choosing the wrong default). If you allow library 
authors to opt in instead of opt out then it becomes a conscious 
decision for one.


But at the very least, shouldn't we put some thought in to 
allowing it for inherent sub-type relationships. Where an alias 
this is used, there's probably such a relationship. BigInt to int 
is another one. Algebraic types as mentioned falls under that 
category as well.


And if that's also a no no, how about char -> int. Or int -> 
float? Is ok?


Maybe there're some valid arguments, to disallow it *completely* 
though?


Cheers




Re: implicit construction operator

2018-02-26 Thread ketmar via Digitalmars-d

aliak wrote:


And if that's also a no no, how about char -> int. Or int -> float? Is ok?


no, it is not ok. it was a mistake. it is now too late to fix it, but we 
can avoid doing more of the same kind.


Re: Go 2017 Survey Results

2018-02-26 Thread Russel Winder via Digitalmars-d
On Mon, 2018-02-26 at 21:04 +, Ali via Digitalmars-d wrote:
> This link was posted today on hacker news (ycombinator)
> https://blog.golang.org/survey2017-results
> https://news.ycombinator.com/item?id=16468358
> 
> My biggest takes from this are
> 1) people are looking for python alternatives, probably more so 
> than c alternatives

People choosing to complete a Go-oriented survey are…
 
> 2) generic programming is important
> 
> As I understand the results of this survey, will be use to guide 
> Go's development
> this is in my opinion very inclusive and transparent

I can't imagine Go getting templates anytime soon.

-- 
Russel.
===
Dr Russel Winder  t: +44 20 7585 2200
41 Buckmaster Roadm: +44 7770 465 077
London SW11 1EN, UK   w: www.russel.org.uk


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


Re: implicit construction operator

2018-02-26 Thread Meta via Digitalmars-d

On Monday, 26 February 2018 at 19:25:06 UTC, WebFreak001 wrote:

Now this would be really useful for Variant:

---
struct Variant {
this(U)(U value) @implicit { ... }
}

void bar(Variant x, Variant y) {}

Variant[] myObjects = [1, 2, "abc", new Node()];
Variant a = 4;
bar(4, "asdf");
---


This is possible in the language today using the implicit class 
construction feature of runtime variadic arrays:


class VArray
{
Variant[] va;

this(T...)(T ts) { foreach(t; ts) { va ~= Variant(t); } }
}

void test(VArray ta...)
{
foreach (v; ta.va)
{
writeln(v.type);
}
}

void main()
{
test(1, "asdf", false);
}




What's your opinion on this?


This is a very slippery slope to fall down. Even `alias this` is 
pushing the limit of what I think we should allow.


That said, there is exactly 1 case where I really, really want 
some kind of implicit conversion:


struct Success {}
struct Error { string msg; }

alias Result = Algebraic!(Success, Error);

Result connectToHost(IPAddress host)
{
//do some stuff
if (operationSucceeded)
{
return Success();
}
else
{
return Error(statusMessage);
}
}

This currently doesn't work, and you instead have to return 
Result(Success()) and
Result(Error(statusMessage)). I would love to have some way of 
implicitly constructing an Algebraic from any of the possible 
underlying types. It would bring us very close (if not all the 
way) to having Algebraic work identically to sum types in other 
languages such as Rust, Swift, Haskell, etc. Having to explicitly 
wrapping the values in an Algebraic doesn't seem like a big deal, 
but it makes it really annoying to use it in everyday code.


Go 2017 Survey Results

2018-02-26 Thread Ali via Digitalmars-d

This link was posted today on hacker news (ycombinator)
https://blog.golang.org/survey2017-results
https://news.ycombinator.com/item?id=16468358

My biggest takes from this are
1) people are looking for python alternatives, probably more so 
than c alternatives

2) generic programming is important

As I understand the results of this survey, will be use to guide 
Go's development

this is in my opinion very inclusive and transparent






Re: Slow code, slow

2018-02-26 Thread ketmar via Digitalmars-d

H. S. Teoh wrote:


The problem is not the Phobos implementation.  The problem is that the
compiler's way of handling templates and CTFE needs to be improved.  We
seriously need to muster some manpower to help Stefan finish newCTFE,
and then we need to take a serious look at improving the current
implementation of templates.


yeah, i'm not saying that phobos code is wrong. but being "not wrong" and 
being fast is not always the same. ;-)



still, we can be either smart, or have fast compile times, but not
both. T_T

[...]

I'll like to disagree. :-D  There's got to be a way to do this that
doesn't have to compromise either way.  I mean, this is not like we're
doing rocket science here, or solving an NP complete problem.  It's a
straightforward way of recognizing a particular code pattern and
applying 1-to-1 mappings.  The general case of completely arbitrary
templates can still fallback to the current implementation.  The point
is to optimize for specific template usage patterns that are common and
yields big speedups, but still leave the door open for weirder, but less
common, template code.


but until that brave new world materializes, we have a smart/fast dilemma. 
alas.


Re: Slow code, slow

2018-02-26 Thread H. S. Teoh via Digitalmars-d
On Mon, Feb 26, 2018 at 09:03:14PM +0200, ketmar via Digitalmars-d wrote:
> H. S. Teoh wrote:
[...]
> > In my mind, even C's printf API is sucky, because it involves runtime
> > parsing of what's usually a static string, over and over again. What we
> > *really* want is for something like:
> > 
> > writeln("blah %d bluh %s", i, s);
> > 
> > to be translated into something like:
> > 
> > stdout.putString("blah ");
> > stdout.putInt(i);
> > stdout.putString(" bluh ");
> > stdout.putString(s);
[...]
> i once wrote such thing (for fun, using "Functional Programming With
> Templates"). it was fun to do, and freakin' slow due to template
> bloat. ;-)
> but yes, it generates a string mixin, and in runtime there was no
> format string parsing.

The problem is not the Phobos implementation.  The problem is that the
compiler's way of handling templates and CTFE needs to be improved.  We
seriously need to muster some manpower to help Stefan finish newCTFE,
and then we need to take a serious look at improving the current
implementation of templates.


> still, we can be either smart, or have fast compile times, but not
> both. T_T
[...]

I'll like to disagree. :-D  There's got to be a way to do this that
doesn't have to compromise either way.  I mean, this is not like we're
doing rocket science here, or solving an NP complete problem.  It's a
straightforward way of recognizing a particular code pattern and
applying 1-to-1 mappings.  The general case of completely arbitrary
templates can still fallback to the current implementation.  The point
is to optimize for specific template usage patterns that are common and
yields big speedups, but still leave the door open for weirder, but less
common, template code.


T

-- 
Fact is stranger than fiction.


Re: Can this be done? Defining type as in this Scala sample code

2018-02-26 Thread Simen Kjærås via Digitalmars-d

On Monday, 26 February 2018 at 15:43:54 UTC, Bienlein wrote:

object Scratch extends App {

  // compiles:

  val list = List(1, 2.4, 5)
  val sum = list.sum
  println(sum)


  // does not compile:

  val list2 = List(1, 2.4, 5, "123")
  val sum2 = list2.sum
  println(sum2)

}


There's nothing in the language or standard library that supports 
this. However, it's perfectly possible to make something with 
those semantics:


import std.variant;
import std.stdio;

struct List(T) {
T[] values;

alias values this;
}

auto list(T...)(T args)
{
import std.traits : CommonType;

static if (is(CommonType!T == void))
List!Variant result;
else
List!(CommonType!T) result;

result.length = T.length;
foreach (i, e; args) {
result[i] = e;
}
return result;
}

auto sum(T)(List!T lst)
if (is(typeof(lst[0] + lst[0])) && !is(T == Variant))
{
T result = 0;
foreach (e; lst) {
result += e;
}
return result;
}

unittest {
auto list1 = list(1, 2.4, 5);
auto sum1 = list1.sum;
writeln(sum1);

auto list2 = list(1, 2.4, 5, "123");
auto sum2 = list2.sum;
writeln(sum2);
}


Since std.variant.Variant does operator overloads, we have to 
explicitly check if T == Variant in the sum function. For 
Variant, that's probably the correct choice. We could use 
Algebraic instead, but it also does operator overloads, even when 
no type in its arguments support them. Again, we could create our 
own - Algebraic and Variant are library types, after all.


--
  Simen


Re: implicit construction operator

2018-02-26 Thread ketmar via Digitalmars-d

WebFreak001 wrote:


Now before you would have only been able to do this:

---
Nullable!Foo a;
foo(a, Nullable!int(5));
---

but now you should also be able to do:

---
Nullable!Foo x = null;
Nullable!Foo y = 5;

foo(null, 5);


please no. such unobvious type conversions goes out of control really fast. 
there is a reason why D doesn't have such thing, this is not an oversight, 
but a design decision.


implicit construction operator

2018-02-26 Thread WebFreak001 via Digitalmars-d
hi, I had an idea from using some C# which I think would be 
really cool in D. Basically allow modifying implicit construction 
of a type. Right now we only have struct opAssign/constructor 
implicit conversion, but this addition would also add it to 
classes and make it even more convenient.


Changes in code (example Nullable):

---
struct Nullable(T) {
this(typeof(null)) @implicit {} // <-- @implicit is new
}

void foo(Nullable!int a, Nullable!int b) {}
---

Now before you would have only been able to do this:

---
Nullable!Foo a;
foo(a, Nullable!int(5));
---

but now you should also be able to do:

---
Nullable!Foo x = null;
Nullable!Foo y = 5;

foo(null, 5);

// while this would be nice, I am not sure how well this is 
possible right now:

Nullable!int[] foo = [1, 2, 3, null, 5];
---
The array syntax might not be possible if it looks at consistency 
inside the array before attempting to cast it, but for function 
arguments and quicker


This is especially making this case less of a pain to deal with:
---
void sendMessage(string content, Nullable!Snowflake nonce = 
Nullable!Snowflake.init, Nullable!Embed embed = 
Nullable!Embed.init);

Nullable!Embed embed = Embed.init;
sendMessage("a", Nullable!Snowflake.init, embed)

// ->

void sendMessage(string content, Nullable!Snowflake nonce = null, 
Nullable!Embed embed = null);

sendMessage("a", null, Embed.init);
---

Now this would be really useful for Variant:

---
struct Variant {
this(U)(U value) @implicit { ... }
}

void bar(Variant x, Variant y) {}

Variant[] myObjects = [1, 2, "abc", new Node()];
Variant a = 4;
bar(4, "asdf");
---

Just a few examples where it could be used in phobos, especially 
when passing them function arguments: Variant, JSONValue, 
eventual XML node, Nullable, BigInt, Unique, scoped, NullableRef, 
Rebindable, AsciiString, Latin1String, etc and many more. Plus 
also many libraries will be able to make use of this like vibe.d 
Json, Bson or msgpack or dyaml etc etc etc. Additionally this 
will make many duplicate functions which are just there for 
emulating this behaviour disappear, std.regex could accept just 
regex as argument and strings will be implicitly cast to it, 
reducing template/overload usage and possibly also making it 
faster to import.


What's your opinion on this? I think it is really useful to have 
when interoping with scripting languages or doing 
(de)serialization or for these attribute wrappers which are there 
because of no function attribute UDAs. I was looking into 
implementing this to dmd myself but the code on the implicit cast 
checks looks a bit hardcoded for the types that are in right now 
and not really suitable to implement this, but maybe someone with 
more knowledge about dmd internals can do this with ease.


This is only a single direction T -> Wrapper and I think this 
would actually be enough, but it would maybe be possible to add 
@implicit to opCast in the future.


Re: Slow code, slow

2018-02-26 Thread ketmar via Digitalmars-d

H. S. Teoh wrote:


On Mon, Feb 26, 2018 at 08:38:39PM +0200, ketmar via Digitalmars-d wrote:

H. S. Teoh wrote:


On Sat, Feb 24, 2018 at 09:43:35AM +, Stefan Koch via Digitalmars-d
wrote:
[...]

This particular slowdown happens because there are somehow
depdencies on std.format.format which is instantiated.  Which has
a ton of dependencies itself.

Aha!  That explains it.  Thanks, Stefan, for the accurate diagnosis. :-)
Now the next problem is: how to trim the fat off std.format ...

p.s.: and ditch type safety. 'cause `foo(T...) (T args)` is a major
slowdown -- it is a template. ;-)


Actually, I think this is the classic example of why the compiler should
improve the way it implements templates.

In my mind, even C's printf API is sucky, because it involves runtime
parsing of what's usually a static string, over and over again. What we
*really* want is for something like:

writeln("blah %d bluh %s", i, s);

to be translated into something like:

stdout.putString("blah ");
stdout.putInt(i);
stdout.putString(" bluh ");
stdout.putString(s);

I.e., there should not be Yet Another Template with Yet Another
Ridiculously Long Argument List Type Encoded In The Mangled Name, along
with needless marshalling of function arguments on the stack, branching
to some other part of the code (potentially causing an instruction cache
miss), tons of copy-pasta for calling the same old functions for
outputting strings and formatting integers, and incurring Yet Another
Branch Hazard when the function finally returns.

And there should definitely be no silly runtime parsing of format
strings and all of that useless dance.


i once wrote such thing (for fun, using "Functional Programming With 
Templates"). it was fun to do, and freakin' slow due to template bloat. ;-) 
but yes, it generates a string mixin, and in runtime there was no format 
string parsing.


still, we can be either smart, or have fast compile times, but not both. T_T

p.s.: oops. just found that i cannot pass structs with dtors to `(...)` 
functions. not fun at all.


Re: Slow code, slow

2018-02-26 Thread H. S. Teoh via Digitalmars-d
On Mon, Feb 26, 2018 at 08:42:22PM +0200, ketmar via Digitalmars-d wrote:
[...]
> p.p.s.: or replace it with `void fmtlite (...) {}` thingy. this way we
> can still have type safety, but get rid of templates.

Given the huge amount of templates in your typical, average D code, I
think it's a much more worthwhile effort to improve the way the compiler
implements templates instead. :-D


T

-- 
Leather is waterproof.  Ever see a cow with an umbrella?


Re: Slow code, slow

2018-02-26 Thread H. S. Teoh via Digitalmars-d
On Mon, Feb 26, 2018 at 08:38:39PM +0200, ketmar via Digitalmars-d wrote:
> H. S. Teoh wrote:
> 
> > On Sat, Feb 24, 2018 at 09:43:35AM +, Stefan Koch via Digitalmars-d
> > wrote:
> > [...]
> > > This particular slowdown happens because there are somehow
> > > depdencies on std.format.format which is instantiated.  Which has
> > > a ton of dependencies itself.
> > 
> > Aha!  That explains it.  Thanks, Stefan, for the accurate diagnosis. :-)
> > 
> > Now the next problem is: how to trim the fat off std.format ...
> 
> p.s.: and ditch type safety. 'cause `foo(T...) (T args)` is a major
> slowdown -- it is a template. ;-)

Actually, I think this is the classic example of why the compiler should
improve the way it implements templates.

In my mind, even C's printf API is sucky, because it involves runtime
parsing of what's usually a static string, over and over again. What we
*really* want is for something like:

writeln("blah %d bluh %s", i, s);

to be translated into something like:

stdout.putString("blah ");
stdout.putInt(i);
stdout.putString(" bluh ");
stdout.putString(s);

I.e., there should not be Yet Another Template with Yet Another
Ridiculously Long Argument List Type Encoded In The Mangled Name, along
with needless marshalling of function arguments on the stack, branching
to some other part of the code (potentially causing an instruction cache
miss), tons of copy-pasta for calling the same old functions for
outputting strings and formatting integers, and incurring Yet Another
Branch Hazard when the function finally returns.

And there should definitely be no silly runtime parsing of format
strings and all of that useless dance.

The latest Phobos does support compile-time format strings, but all that
does currently is to forward to the silly runtime parsing code (not to
mention coming with its own baggage of additional templates to do the
compile-time format string checking).

Basically, the whole stupid function call should just be completely
inlined and any external template function bodies thrown out the window,
because chances are you'll never call format() again with exactly the
same parameters somewhere else in the code.

I haven't checked if ldc will actually do this level of inlining, but
dmd certainly won't with its overly-conservative inliner.  And besides,
it's a stupid waste of compiler resources to have to generate all of
that template code every single time format() is called, only to have
the optimizer basically undo half of the work.  There should be some way
in the language to express format() in a way that doesn't involve tons
of template bloat and wasted function body copy-pasta.


T

-- 
Meat: euphemism for dead animal. -- Flora


Re: Slow code, slow

2018-02-26 Thread ketmar via Digitalmars-d

H. S. Teoh wrote:

On Sat, Feb 24, 2018 at 09:43:35AM +, Stefan Koch via Digitalmars-d 
wrote:

[...]

This particular slowdown happens because there are somehow depdencies
on std.format.format which is instantiated.
Which has a ton of dependencies itself.


Aha!  That explains it.  Thanks, Stefan, for the accurate diagnosis. :-)

Now the next problem is: how to trim the fat off std.format ...


p.p.s.: or replace it with `void fmtlite (...) {}` thingy. this way we can 
still have type safety, but get rid of templates.


Re: Translating C "static arrays" into D?

2018-02-26 Thread H. S. Teoh via Digitalmars-d
On Mon, Feb 26, 2018 at 06:25:42PM +, Atila Neves via Digitalmars-d wrote:
[...]
> There's a common misconception in C that arrays and pointers are the
> same thing - they're not. This comes about because of the dubious C
> feature whereby arrays decay into pointers in function calls. Somewhat
> related to this, a little known feature of C is pointers to arrays. In
> your example, that's what y and z are. They have funky syntax and look
> like function pointers, unless they're obscured with a typedef as in
> your example.
> 
> You can pass a double array of any size to x, or a pointer to double,
> but y and z are constrained to be pointers to arrays of size 1.
> Exemplified:
> 
> typedef double mytype[1];
> void func1(mytype x);
> void func2(mytype* x);
> 
> int main() {
> double arr1[1];
> double arr2[2];
> double* ptr;
> 
> func1(arr1); // fine
> func1(arr2); // fine
> func1(ptr);  // fine
> 
> func2(&arr1); // fine
> func2(&arr2); // oops - won't compile
> }

Ouch.  After working with C for more than 20 years, this one still
escaped me. :-(  How I hate C array semantics...


On Mon, Feb 26, 2018 at 01:33:58PM -0500, Steven Schveighoffer via 
Digitalmars-d wrote:
[...]
> If you declare mytype as:
> 
> alias mytype = double[1];
> 
> Then you can use it pretty much anywhere. The only exception is when
> it's the exact type of a parameter. In that case, use ref:
> 
> extern(C) void someFunc(ref mytype x, mytype *y, mytype **z);
[...]

Nice, that's also the solution I eventually converged on.


T

-- 
Let's eat some disquits while we format the biskettes.


Re: Slow code, slow

2018-02-26 Thread ketmar via Digitalmars-d

H. S. Teoh wrote:

On Sat, Feb 24, 2018 at 09:43:35AM +, Stefan Koch via Digitalmars-d 
wrote:

[...]

This particular slowdown happens because there are somehow depdencies
on std.format.format which is instantiated.
Which has a ton of dependencies itself.


Aha!  That explains it.  Thanks, Stefan, for the accurate diagnosis. :-)

Now the next problem is: how to trim the fat off std.format ...


no wai. it is just Too General to be slim. what can be done, though, is 
`std.format.lite` module (or something), that supports only a very small 
subset of "big format" features, like simply printing numbers, arrays, and 
unconditionally calling `.toString` on structs/classes, and a very 
restricted set of formatting options. that should cover alot of use cases. 
'cause most of the time people only need something like `%3d %s` and such.


Re: Slow code, slow

2018-02-26 Thread ketmar via Digitalmars-d

H. S. Teoh wrote:

On Sat, Feb 24, 2018 at 09:43:35AM +, Stefan Koch via Digitalmars-d 
wrote:

[...]

This particular slowdown happens because there are somehow depdencies
on std.format.format which is instantiated.
Which has a ton of dependencies itself.


Aha!  That explains it.  Thanks, Stefan, for the accurate diagnosis. :-)

Now the next problem is: how to trim the fat off std.format ...


p.s.: and ditch type safety. 'cause `foo(T...) (T args)` is a major 
slowdown -- it is a template. ;-)


Re: Translating C "static arrays" into D?

2018-02-26 Thread Steven Schveighoffer via Digitalmars-d

On 2/26/18 12:54 PM, H. S. Teoh wrote:

What's the correct translation of the following C declarations into D?

typedef double[1] mytype;

void someFunc(mytype x, mytype *y, mytype **z);

struct SomeStruct {
mytype x;
mytype *y;
mytype **z;
}

I need this to interface with an external C library.  Currently, I just
wrapped the above as-is inside an extern(C) block.  But I suspect it may
be wrong, because:

1) In C, declaring a function parameter of type double[1] is, IIRC, the
same thing as declaring it as double*.  But in D, double[1] passes one
double by value as a static array. So there may be an API mismatch here.


If you declare mytype as:

alias mytype = double[1];

Then you can use it pretty much anywhere. The only exception is when 
it's the exact type of a parameter. In that case, use ref:


extern(C) void someFunc(ref mytype x, mytype *y, mytype **z);

-Steve


Re: Translating C "static arrays" into D?

2018-02-26 Thread ketmar via Digitalmars-d

H. S. Teoh wrote:


On Mon, Feb 26, 2018 at 08:07:11PM +0200, ketmar via Digitalmars-d wrote:
[...]

in C, arrays are *always* decaying to pointers. so
void foo (int x[2])
is the same as
void foo (int* x)
`[2]` is purely informational.
that is, in D it will be:
alias mytype = double*;


Actually, that doesn't work, because in the struct declaration it will
be wrong:

// C
struct S {
double[5] x; // actually occupies the space of 5 doubles
}

// D
struct S {
double* x; // occupies the space of 1 pointer (wrong)
}


yeah, sorry. somehow i completely missed structs.


Re: Translating C "static arrays" into D?

2018-02-26 Thread Atila Neves via Digitalmars-d

On Monday, 26 February 2018 at 17:54:12 UTC, H. S. Teoh wrote:
What's the correct translation of the following C declarations 
into D?


typedef double[1] mytype;


This isn't valid C, but `typedef double mytype[1];` is.



void someFunc(mytype x, mytype *y, mytype **z);

struct SomeStruct {
mytype x;
mytype *y;
mytype **z;
}

I need this to interface with an external C library.  
Currently, I just wrapped the above as-is inside an extern(C) 
block.  But I suspect it may be wrong, because:


1) In C, declaring a function parameter of type double[1] is, 
IIRC, the same thing as declaring it as double*.  But in D, 
double[1] passes one double by value as a static array. So 
there may be an API mismatch here.


Yes, a `double[1]` parameter in C and `double*` are the same 
thing. However, that's not valid for the other two parameters (y 
and z).


There's a common misconception in C that arrays and pointers are 
the same thing - they're not. This comes about because of the 
dubious C feature whereby arrays decay into pointers in function 
calls. Somewhat related to this, a little known feature of C is 
pointers to arrays. In your example, that's what y and z are. 
They have funky syntax and look like function pointers, unless 
they're obscured with a typedef as in your example.


You can pass a double array of any size to x, or a pointer to 
double, but y and z are constrained to be pointers to arrays of 
size 1. Exemplified:


typedef double mytype[1];
void func1(mytype x);
void func2(mytype* x);

int main() {
double arr1[1];
double arr2[2];
double* ptr;

func1(arr1); // fine
func1(arr2); // fine
func1(ptr);  // fine

func2(&arr1); // fine
func2(&arr2); // oops - won't compile
}





2) In C, declaring a *variable* or struct field as double[1] 
has essentially the same semantics as D's static arrrays.  
Meaning that I cannot just change the declaration of mytype in 
order to get the correct behaviour of function parameters.


3) I'm getting a segfault at runtime of some C++ code into D, 
that calls
the library via this C API, and I suspect it's probably due to 
(1).


The correct translation is:

extern(C) void someFunc(double* x, double[1]* y, double[1]** z);


Atila


Re: Slow code, slow

2018-02-26 Thread H. S. Teoh via Digitalmars-d
On Sat, Feb 24, 2018 at 09:43:35AM +, Stefan Koch via Digitalmars-d wrote:
[...]
> This particular slowdown happens because there are somehow depdencies
> on std.format.format which is instantiated.
> Which has a ton of dependencies itself.

Aha!  That explains it.  Thanks, Stefan, for the accurate diagnosis. :-)

Now the next problem is: how to trim the fat off std.format ...


T

-- 
What is Matter, what is Mind? Never Mind, it doesn't Matter.


Re: Translating C "static arrays" into D?

2018-02-26 Thread H. S. Teoh via Digitalmars-d
On Mon, Feb 26, 2018 at 08:07:11PM +0200, ketmar via Digitalmars-d wrote:
[...]
> in C, arrays are *always* decaying to pointers. so
> 
>   void foo (int x[2])
> 
> is the same as
> 
>   void foo (int* x)
> 
> `[2]` is purely informational.
> 
> that is, in D it will be:
> 
>   alias mytype = double*;

Actually, that doesn't work, because in the struct declaration it will
be wrong:

// C
struct S {
double[5] x; // actually occupies the space of 5 doubles
}

// D
struct S {
double* x; // occupies the space of 1 pointer (wrong)
}

Furthermore, declaring it as `double*` breaks existing code ported from
C:

// Original C code:
void foo(mytype x);
mytype z;
foo(z);

// D code:
void foo(double* x);// OK
mytype z;   // NG
foo(z); // NG: passes uninitialized pointer

// alternatively:
double[1] z;
foo(z); // NG: need to insert `&` to compile

Eventually I figured out a (hackish) solution to make it work without
silently breaking transliterated C code: declare all function parameters
that take `mytype` as ref.  This causes the D compiler to simulate the
array -> pointer degradation semantics but still retain "static array"
semantics in structs and variable declarations, without requiring a
change in syntax.


T

-- 
Food and laptops don't mix.


Re: Translating C "static arrays" into D?

2018-02-26 Thread ketmar via Digitalmars-d

H. S. Teoh wrote:


What's the correct translation of the following C declarations into D?

typedef double[1] mytype;

void someFunc(mytype x, mytype *y, mytype **z);

struct SomeStruct {
mytype x;
mytype *y;
mytype **z;
}

I need this to interface with an external C library.  Currently, I just
wrapped the above as-is inside an extern(C) block.  But I suspect it may
be wrong, because:

1) In C, declaring a function parameter of type double[1] is, IIRC, the
same thing as declaring it as double*.  But in D, double[1] passes one
double by value as a static array. So there may be an API mismatch here.

2) In C, declaring a *variable* or struct field as double[1] has
essentially the same semantics as D's static arrrays.  Meaning that I
cannot just change the declaration of mytype in order to get the correct
behaviour of function parameters.

3) I'm getting a segfault at runtime of some C++ code into D, that calls
the library via this C API, and I suspect it's probably due to (1).


T


in C, arrays are *always* decaying to pointers. so

void foo (int x[2])

is the same as

void foo (int* x)

`[2]` is purely informational.

that is, in D it will be:

alias mytype = double*;


Re: Translating C "static arrays" into D?

2018-02-26 Thread H. S. Teoh via Digitalmars-d
On Mon, Feb 26, 2018 at 09:54:12AM -0800, H. S. Teoh via Digitalmars-d wrote:
> What's the correct translation of the following C declarations into D?
> 
>   typedef double[1] mytype;

Sorry, typo, should be:

typedef double mytype[1];


>   void someFunc(mytype x, mytype *y, mytype **z);
> 
>   struct SomeStruct {
>   mytype x;
>   mytype *y;
>   mytype **z;
>   }
[...]


T

-- 
Real men don't take backups. They put their source on a public
FTP-server and let the world mirror it. -- Linus Torvalds


Translating C "static arrays" into D?

2018-02-26 Thread H. S. Teoh via Digitalmars-d
What's the correct translation of the following C declarations into D?

typedef double[1] mytype;

void someFunc(mytype x, mytype *y, mytype **z);

struct SomeStruct {
mytype x;
mytype *y;
mytype **z;
}

I need this to interface with an external C library.  Currently, I just
wrapped the above as-is inside an extern(C) block.  But I suspect it may
be wrong, because:

1) In C, declaring a function parameter of type double[1] is, IIRC, the
same thing as declaring it as double*.  But in D, double[1] passes one
double by value as a static array. So there may be an API mismatch here.

2) In C, declaring a *variable* or struct field as double[1] has
essentially the same semantics as D's static arrrays.  Meaning that I
cannot just change the declaration of mytype in order to get the correct
behaviour of function parameters.

3) I'm getting a segfault at runtime of some C++ code into D, that calls
the library via this C API, and I suspect it's probably due to (1).


T

-- 
Amateurs built the Ark; professionals built the Titanic.


Re: Can this be done? Defining type as in this Scala sample code

2018-02-26 Thread drug via Digitalmars-d

you can do something like this (https://run.dlang.io/is/RYR5Dm):
```
import std.algorithm : sum;
import std.range : only;
import std.stdio : writeln;
import std.typecons : tuple;

void main()
{
{
auto list = tuple(1, 2.4, 5);
auto sum = list.expand.only.sum;
writeln(sum);
}

{
// do not compile
/*
auto list = tuple(1, 2.4, 5, "123");
auto sum = list.expand.only.sum;
writeln(sum);
*/
}
}
```


Re: Can this be done? Defining type as in this Scala sample code

2018-02-26 Thread jmh530 via Digitalmars-d

On Monday, 26 February 2018 at 15:43:54 UTC, Bienlein wrote:

Hello,

just curious whether this is a Scala speciality or whether it 
could also be done in D. Here is some Scala code:


object Scratch extends App {

  // compiles:

  val list = List(1, 2.4, 5)
  val sum = list.sum
  println(sum)


  // does not compile:

  val list2 = List(1, 2.4, 5, "123")
  val sum2 = list2.sum
  println(sum2)

}

In the code above list.sum compiles, because list only contains 
values that are of type Numeric. The sum method looks like this:


def sum[B >: A](implicit num: Numeric[B]): B = 
foldLeft(num.zero)(num.plus)


So sum compiles if all values can be converted to Numeric which 
the compiler checks at compile time.


For list2 this is not the case as "123" is a string and 
therefore not of type Numeric. Calling functions on list2 ist 
fine as long as no function is called that requires a 
conversion to Numeric for each element in the list such as in 
the case of sum.


My question is now whether that kind of logic can also be 
defined in D. My knowledge of D is too limited to find out in 
reasonable time myself. Reason for my curiosity is that the 
Scala solution relies on implicit conversion at compile time 
which has its drawbacks (compilation times, colliding implicit 
conversions the compiler cannot detect, etc.). So I just wanted 
to see whether D does this in a clean way and I know that D 
allows for some type parameter constraints to be set.


Thansk for any answers,
Bienlein


Probably more appropriate in the Learn forum.

I don't really know much Scala, but it seems like

  val list2 = List(1, 2.4, 5, "123")
would fail to compile because List requires the values to be of a 
common type and "123" is a string. By contrast, a tuple could 
hold all those elements, but then it might fail when calculating 
the sum. Even in D, it's a little tricky to take the sum of a 
Tuple. You may as well just do a for loop.


So I suppose the question is can D do

  val list = List(1, 2.4, 5)
  val sum = list.sum
Phobos has list containers in std.container. However, usually you 
would use an array for something like this unless you have a 
reason to use a list. The 1 and 5 ints are implicitly casted to 
doubles in both versions.


//array version

import std.algorithm : sum;
import std.stdio : writeln;

void main()
{
auto x = [1, 2.4, 5];
writeln(x.sum);
}

//list version

import std.algorithm : sum;
import std.stdio : writeln;
import std.container : SList;

void main()
{
auto x = SList!double(1, 2.4, 5);
writeln(x[].sum);
}


Can this be done? Defining type as in this Scala sample code

2018-02-26 Thread Bienlein via Digitalmars-d

Hello,

just curious whether this is a Scala speciality or whether it 
could also be done in D. Here is some Scala code:


object Scratch extends App {

  // compiles:

  val list = List(1, 2.4, 5)
  val sum = list.sum
  println(sum)


  // does not compile:

  val list2 = List(1, 2.4, 5, "123")
  val sum2 = list2.sum
  println(sum2)

}

In the code above list.sum compiles, because list only contains 
values that are of type Numeric. The sum method looks like this:


def sum[B >: A](implicit num: Numeric[B]): B = 
foldLeft(num.zero)(num.plus)


So sum compiles if all values can be converted to Numeric which 
the compiler checks at compile time.


For list2 this is not the case as "123" is a string and therefore 
not of type Numeric. Calling functions on list2 ist fine as long 
as no function is called that requires a conversion to Numeric 
for each element in the list such as in the case of sum.


My question is now whether that kind of logic can also be defined 
in D. My knowledge of D is too limited to find out in reasonable 
time myself. Reason for my curiosity is that the Scala solution 
relies on implicit conversion at compile time which has its 
drawbacks (compilation times, colliding implicit conversions the 
compiler cannot detect, etc.). So I just wanted to see whether D 
does this in a clean way and I know that D allows for some type 
parameter constraints to be set.


Thansk for any answers,
Bienlein


Re: PackedAliasSeq?

2018-02-26 Thread Simen Kjærås via Digitalmars-d
On Thursday, 22 February 2018 at 19:26:54 UTC, Andrei 
Alexandrescu wrote:

template PackedAliasSeq!(T...)
{
alias expand = AliasSeq!T;
}


I started playing around with this a few days ago, and came up 
with another interesting abstraction - NamedPack:


alias foo = NamedPack!("Type", int, "name", "foo");
assert(is(foo.Type == int));
assert(foo.name == "foo");
assert(foo.equals!(NamedPack!("Type", int, "name", "foo")));

And for good measure, a helper to define your own 'compile-time 
structs', for want of a better word:


alias Field = DefinePack!("Type", Type, "name", string, 
"offset", int);

alias field1 = Field!(int, "a", 0);
assert(is(field1.Type == int));
assert(field1.name == "a");
assert(field1.offset == 0);
assert(field1.equals!(NamedPack!("Type", int, "name", "a", 
"offset", 0)));


One benefit over regular structs being of course that these will 
never end up in the binary.



The more structured nature of this construct over the simple Pack 
template makes it useful where information would otherwise be 
encoded in the order of elements, as e.g. in pull #6192.


Implementation and some more documentation:
https://gist.github.com/Biotronic/8a2664c050f01aed5e0c45950509022b

--
  Simen