Re: Rant after trying Rust a bit

2015-07-23 Thread H. S. Teoh via Digitalmars-d
On Thu, Jul 23, 2015 at 01:40:17PM -0700, Walter Bright via Digitalmars-d wrote:
 On 7/23/2015 12:50 PM, H. S. Teoh via Digitalmars-d wrote:
 That assumes the template author is diligent (foolhardy?) enough to
 write unittests that cover all possible instantiations...
 
 No, only each branch of the template code must be instantiated, not
 every possible instantiation. And we have a tool to help with that:
 -cov
 
 Does anyone believe it is a good practice to ship template code that
 has never been instantiated?

OK, I jumped into the middle of this discussion so probably I'm speaking
totally out of context... but anyway, with regards to template code, I
agree that it ought to be thoroughly tested by at least instantiating
the most typical use cases (as well as some not-so-typical use cases).

An uninstantiated template path is worse than a branch that's never
taken, because the compiler can't help you find obvious problems before
you ship it to the customer.

A lot of Phobos bugs lurk in rarely-used template branches that are not
covered by the unittests.

Instantiating all branches is only part of the solution, though. A lot
of Phobos bugs also arise from undetected dependencies of the template
code on the specifics of the concrete types used to test it in the
unittests.  The template passes the unittest but when you instantiate it
with a type not used in the unittests, it breaks. For instance, a lot of
range-based templates are tested with arrays in the unittests. Some of
these templates wrongly depend on array behaviour (as opposed to being
confined only to range API operations) while their signature constraints
indicate only the generic range API. As a result, when non-array ranges
are used, it breaks. Sometimes bugs like this can lurk undetected for a
long time before somebody one day happens to instantiate it with a range
type that violates the hidden assumption in the template code.

If we had a Concepts-like construct in D, where template code is
statically constrained to only use, e.g., range API when manipulating an
incoming type, a lot of these bugs would've been caught.

In fact, I'd argue that this should be done for *all* templates -- for
example, a function like this ought to be statically rejected:

auto myFunc(T)(T t) { return t + 1; }

because it assumes the validity of the + operation on T, but T is not
constrained in any way, so it can be *any* type, most of which,
arguably, do not support the + operation.

Instead, templates ought to be required to explicitly declare up-front
all operations that it will perform on incoming types, so that (1) its
assumptions are obvious, and (2) the compiler will reject attempts to
instantiate it with an incompatible type.

auto myFunc(T)(T t)
if (is(typeof(T.init + 1)))
{
return t + 1;
}

The current syntax is ugly, of course, but that's easily remedied. The
more fundamental problem is that the compiler does not restrict
operations on T in any way, even when the sig constraint specifies how T
ought to be used. Someone could easily introduce a bug:

auto myFunc(T)(T t)
if (is(typeof(T.init + 1)))
{
/* Oops, we checked that +1 is a valid operation on T,
 * but here we're doing -1 instead, which may or may not
 * be valid: */
return t - 1;
}

The compiler still accepts this code as long as the unittests use types
that support both + and -. So this dependency on the incidental
characteristics of T remains as a latent bug.

If the compiler outright rejected any operation on T that hasn't been
explicitly tested for, *then* we will have eliminated a whole class of
template bugs. Wrong code like the last example above would be caught as
soon as the compiler compiles the body of myFunc.


T

-- 
Elegant or ugly code as well as fine or rude sentences have something in 
common: they don't depend on the language. -- Luca De Vitis


[Issue 14765] [Reg2.068.0] Rangified functions no longer accept types that implicitly cast to string

2015-07-23 Thread via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=14765

--- Comment #5 from github-bugzi...@puremagic.com ---
Commits pushed to stable at https://github.com/D-Programming-Language/phobos

https://github.com/D-Programming-Language/phobos/commit/31c963070245c2c89ae287283f49fc77425c45df
add std.traits.isAutodecodableString() to fix Issue 14765

https://github.com/D-Programming-Language/phobos/commit/39806a85f5cd0f3280519277a5943e3485abd797
Merge pull request #3512 from MartinNowak/fix14765

add std.traits.isAutodecodableString() to fix Issue 14765

--


[Issue 14765] [Reg2.068.0] Rangified functions no longer accept types that implicitly cast to string

2015-07-23 Thread via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=14765

github-bugzi...@puremagic.com changed:

   What|Removed |Added

 Status|NEW |RESOLVED
 Resolution|--- |FIXED

--


Re: dmd 2.068, 2.069, 2.0xx Evil Plan going forward

2015-07-23 Thread ketmar via Digitalmars-d
On Tue, 21 Jul 2015 01:54:44 -0700, Walter Bright wrote:

 On 7/20/2015 11:34 PM, Martin Nowak wrote:
 I got this number from Daniel, he didn't found a reason.
 Chances are it's uniformly slower because of dmd's backend, but of
 course profiling might help.
 
 Consider that the Win32 version of dmd is built with with the same
 backend as dmd. If there's a slowdown with that version, it isn't due to
 the backend.

DMC version of DMD is noticably slower on building phobos than MinGW 
version. i'm using HEAD built with MinGW with wine, and the difference 
can be noticed with my eyes. i didn't measure that with time, though.

so backend is surely plays a role here.

signature.asc
Description: PGP signature


Re: Rant after trying Rust a bit

2015-07-23 Thread Walter Bright via Digitalmars-d

On 7/23/2015 1:08 PM, Dicebot wrote:
 I am not sure how it applies.

D interfaces (defined with the 'interface' keyword) are simple dispatch types, 
they don't require an Object. Such interfaces can also have default implementations.



 My point was about the fact that `isInputRange`
 and `InputRangeObject` are the same entities in Rust, simply interpreted
 differently by compiler depending on usage context.

I understand.


 This is important because you normally want to design your application in 
terms
 of template constraints and structs to get most out of inlining and
 optimization. However, to define stable ABI for shared libraries, the very 
same
 interfaces need to be wrapped in runtime polymorphism.

 Closest thing in D would be to define traits as interfaces and use code like 
this:


 void foo(T)()
  if (  (is(T == struct) || is(T == class))
  Matches!(T, Interface)
  )
 { }

 where `Matches` is a template helper that statically iterates method list of
 interface and looks for matching methods in T.

I don't think the test for struct and class is necessary. It can be just:

void foo(T)() if (Matches!(T, Interface)) { ... }

as opposed to:

void foo(T : Interface)() { ... }


 However, making it built-in feels
 really convenient in Rust:

 - considerably less function declaration visual noise

It's less noise, sure, and perhaps we can do some syntactical sugar to improve 
that. But I don't think this is a fundamental shortcoming for D as it stands now 
(although nobody has written a Matches template, perhaps that should be a priority).



 - much better error messages: trying to use methods of T not defined by a 
trait
 will result in compile-time error even without instantiating the template

The error messages will occur at compile time and will be the same if you write 
a unit test to instantiate the template. As I wrote earlier, I don't really 
understand the need to ship template source code that has never been instantiated.




Re: Rant after trying Rust a bit

2015-07-23 Thread Dicebot via Digitalmars-d

On Thursday, 23 July 2015 at 20:52:46 UTC, Walter Bright wrote:

 My point was about the fact that `isInputRange`
 and `InputRangeObject` are the same entities in Rust, simply
interpreted
 differently by compiler depending on usage context.

I understand.


Ok, sorry, it wasn't clear from the response context :)

I don't think the test for struct and class is necessary. It 
can be just:


void foo(T)() if (Matches!(T, Interface)) { ... }

as opposed to:

void foo(T : Interface)() { ... }


Correct indeed, though I don't feel it is much of a difference 
considering how common such code is (remember that you endorse 
ranges as The Way for designing APIs!)



 - much better error messages: trying to use methods of T not
defined by a trait
 will result in compile-time error even without instantiating
the template

The error messages will occur at compile time and will be the 
same if you write a unit test to instantiate the template. As I 
wrote earlier, I don't really understand the need to ship 
template source code that has never been instantiated.


1)

It does not protect from errors in definition

void foo (R) (Range r)
if (isInputRange!Range)
{ r.save(); }

unittest
{
SomeForwardRange r;
foo(r);
}

This will compile and show 100% test coverage. Yet when user will 
try using it with real input range, it will fail.


2)

There is quite a notable difference in clarity between error 
message coming from some arcane part of function body and 
referring to wrong usage (or even totally misleading because of 
UFCS) and simple and straightforward Your type X does not 
implement method X necessary for trait Y


3)

Coverage does not work with conditional compilation:

void foo (T) ()
{
import std.stdio;
static if (is(T == int))
writeln(1);
else
writeln(2);
}

unittest
{
foo!int();
}

$ dmd -cov=100 -unittest -main ./sample.d


[Issue 14822] New: DMD crash with CTFE range code (v2.067.1)

2015-07-23 Thread via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=14822

  Issue ID: 14822
   Summary: DMD crash with CTFE range code (v2.067.1)
   Product: D
   Version: D2
  Hardware: x86_64
OS: Linux
Status: NEW
  Severity: normal
  Priority: P1
 Component: dmd
  Assignee: nob...@puremagic.com
  Reporter: initrd...@gmail.com

Created attachment 1531
  -- https://issues.dlang.org/attachment.cgi?id=1531action=edit
reduced source code

I've reduced this code with DustMite and attached it to the issue.

Compile using `dmd -main -unittest sqlite3.d`

Output:

 dmd -main -unittest sqlite3.d
MapResult(Result(0LU, 0LU))
dmd: struct.c:929: virtual void StructDeclaration::semantic(Scope*): Assertion
`type-ty != Tstruct || ((TypeStruct *)type)-sym == this' failed.
fish: “dmd -main -unittest sqlite3.d” terminated by signal SIGABRT (Abort)

--


Re: Bin2d (0.2.0) Rewrite

2015-07-23 Thread Taylor Hillegeist via Digitalmars-d-announce

On Thursday, 23 July 2015 at 12:07:21 UTC, Rikki Cattermole wrote:

On 23/07/2015 11:56 p.m., Suliman wrote:
On Thursday, 23 July 2015 at 10:15:17 UTC, Rikki Cattermole 
wrote:
So Bin2D[0] has been rewritten and adds a bunch of nice new 
features.


- Limit generated code by:
  - package modifier
  - ``version(unittest)``
- Use enum for usage at compile time, instead of 
``const(ubyte[])``

- Report with variable name to original filename

Only dependency is Phobos.
The rewrite adds most importantly usage of e.g. byChunk over 
the input

files to limit the amount of memory used.

[0] https://github.com/rikkimax/bin2d


Cool! Could you add example of usage in readme?


There is already a pretty basic example in it.
Anything specific in mind?


To be honest it took me a bit to realize what it was. A Command 
line application that produces a d modules which represent/store 
those files.


The example is great but it could also use a bit more generic 
outline


Bin2d MODULENAME.d=Resource_Reference FILE1_PATH [FILE2_PATH ...]

I'm not sure how its usually done. Also even though its not 
necessary its always nice to have an example that will compile. 
It also adds some context.


MAIN.d
---
import std.stdio;
import Resource_Reference;

void main() {
string[] FILE_LOCATIONS = outputFilesToFileSystem();
FILE_LOCATIONS.each!writeln();
}
---

compile With dmd MAIN.d MODULENAME.d

Actually this didn't work for me... maybe I'm misinterpreting 
something.




Re: Rant after trying Rust a bit

2015-07-23 Thread Walter Bright via Digitalmars-d

On 7/23/2015 2:08 PM, Dicebot wrote:

It does not protect from errors in definition

void foo (R) (Range r)
 if (isInputRange!Range)
{ r.save(); }

unittest
{
 SomeForwardRange r;
 foo(r);
}

This will compile and show 100% test coverage. Yet when user will try using it
with real input range, it will fail.


That is correct. Some care must be taken that the mock types used in the unit 
tests actually match what the constraint is, rather than being a superset of them.




There is quite a notable difference in clarity between error message coming from
some arcane part of function body and referring to wrong usage (or even totally
misleading because of UFCS) and simple and straightforward Your type X does not
implement method X necessary for trait Y


I believe they are the same. method X does not exist for type Y.



Coverage does not work with conditional compilation:

void foo (T) ()
{
 import std.stdio;
 static if (is(T == int))
 writeln(1);
 else
 writeln(2);
}

unittest
{
 foo!int();
}

$ dmd -cov=100 -unittest -main ./sample.d


Let's look at the actual coverage report:
===
   |void foo (T) ()
   |{
   |import std.stdio;
   |static if (is(T == int))
  1|writeln(1);
   |else
   |writeln(2);
   |}
   |
   |unittest
   |{
  1|foo!int();
   |}
   |
foo.d is 100% covered


I look at these all the time. It's pretty obvious that the second writeln is not 
being compiled in.


Now, if I make a mistake in the second writeln such that it is syntactically 
correct yet semantically wrong, and I ship it, and it blows up when the customer 
actually instantiates that line of code,


   -- where is the advantage to me? --

How am I, the developer, better off? How does well, it looks syntactically like 
D code, so ship it! pass any sort of professional quality assurance?




Re: dmd 2.068, 2.069, 2.0xx Evil Plan going forward

2015-07-23 Thread ketmar via Digitalmars-d
On Wed, 22 Jul 2015 12:17:21 +, Martin Nowak wrote:

 - The backend generates pretty bad code, we'll never be able to catch up
 with good optimizers. Why should we invest in an outdated backend?

the one reason is that it's small and doesn't require 3rd-party libraries 
to build. while it's not the best backend out here, change-compile-full-
rebuild cycle is very fast for DMD, and doesn't require to install gcc 
sources or llvm.

yet i'm not sure that this reason will outweigh the translation and 
maintenance burden.

signature.asc
Description: PGP signature


Re: Rant after trying Rust a bit

2015-07-23 Thread deadalnix via Digitalmars-d
On Thursday, 23 July 2015 at 14:08:23 UTC, Andrei Alexandrescu 
wrote:
Thanks for the link, good quick read to get the overview of 
Rust's traits feature. It's ingenious because it integrates 
static and dynamic dispatch.


For dynamic dispatch, traits are better than interfaces - more 
flexible, better informed. For static dispatch, they don't hold 
a candle to D's constraints. This is important because dynamic 
dispatch is more of a cut-and-dried matter, whereas static 
dispatch is where it's at.




On that note, I've mentioned scala's trait, which are kind of 
similar and worth looking at. The thing being based on java's 
object model, as D's object model, it is easier to think about 
how this could get into D.


For static dispatch I think D's template constraints are quite 
a lot better; they have a lot more power and offer a lot more 
to promise. They are an out-of-the-box solution that's a bit 
unwieldy because it's new enough to not yet have established 
idioms. In contrast, traits come from straight within the box.




Certainly, but they suffer from the LISP effect. You can do 
everything because the structure does not constrain you in any 
way, while at the same time it become quickly very hard to 
understand, for the very same reason.


I do think think the opposition between the 2, as seen in your 
post, or Stroustrup's allergy to static if is wrong headed.


May be one can be expressed via the other ?



Re: casting away const and then mutating

2015-07-23 Thread Jonathan M Davis via Digitalmars-d

On Thursday, 23 July 2015 at 18:43:03 UTC, anonymous wrote:
On a GitHub pull request, Steven Schveighoffer (schveiguy), 
Jonathan M Davis (jmdavis), and I (aG0aep6G) have been 
discussing if or when it's ok to cast away const and then 
mutate the data:


https://github.com/D-Programming-Language/phobos/pull/3501#issuecomment-124169544

I've been under the impression that it's never allowed, i.e. 
it's always undefined behaviour. I think Jonathan is of the 
same opinion.


It's come up time and time again with discussions for logical 
const. If you cast away const, it's up to you to guarantee that 
the data being referenced is not mutated, and if it is mutated, 
it's undefined behavior.


Now, if you know that the data being referenced is actually 
mutable and not immutable, and you know that the compiler isn't 
going to make any assumptions based on const which are then wrong 
if you mutate the variable after casting away const, then you can 
get away with it. But it's still undefined behavior, and if the 
compiler later starts doing more than it does now based on the 
knowledge that you can't mutate via a const reference, then your 
code might stop working correctly. So, if you're _really_ 
careful, you can get away with casting away const and mutating a 
variable, but you are depending on undefined behavior.


Steven disagrees and thinks that there are cases where it's ok. 
Namely, this simple case would be ok:



int x;
const int *y = x;
*(cast(int *)y) = 5;


As I understand him, he's arguing that since the data is 
mutable, and since no function boundaries are crossed, 
compilers should not be allowed to do anything but the obvious 
with that code.


Even if this were defined behavior, what would be the point? You 
have access to x. You could just mutate it directly. I don't see 
how it would make any sense to be attempting to mutate something 
via a const reference when you have access to it via a mutable 
reference. It's when you don't have access to it via a mutable 
reference that it becomes an issue - which means that you've 
crossed a function boundary.


As far as I can tell, making the above defined behavior buys you 
nothing. The times when you gain something from being able to 
cast away const and mutate are the times when you've crossed 
function boundaries and you have to assume that the calling code 
can't see that the cast is happening and thus can't see that the 
data it passed it might have been mutated even though it was 
const. The times where being able to cast away const and mutate 
would be valuable are exactly the times when that would be 
violating the purpose of const - that the data isn't changed via 
a const reference.


The only way to make casting away const and mutating defined 
behavior in general is to make it so that the compiler can't make 
assumptions based on const, which does tend to defeat the purpose 
of const on some level. And part of the whole deal with D's const 
is that it's actually physical const and not logical const or 
C++'s const or any other type of const, and if that's the case, 
then casting away const and mutating is _not_ something that 
should be defined behavior. If it were, then we wouldn't be 
dealing with physical const anymore. Instead we'd be in the same 
boat as C++ where const didn't actually mean that the object 
wasn't mutated, since you could cast away mutate - just with the 
caveat that you have to be sure that the data wasn't actually 
immutable, since mutating immutable data _definitely_ breaks 
immutable, and it could segfault, depending on where the data is 
stored.


So, I don't see how we say that it makes sense for const to ever 
be cast away and then mutated. That violates the guarantees that 
const is supposed to provide and puts us back in the C++ boat, 
only worse, since you still have to worry about immutable and not 
mutating const when it's actually immutable.


- Jonathan M Davis


Re: Rant after trying Rust a bit

2015-07-23 Thread Walter Bright via Digitalmars-d

On 7/23/2015 12:50 PM, H. S. Teoh via Digitalmars-d wrote:

That assumes the template author is diligent (foolhardy?) enough to
write unittests that cover all possible instantiations...


No, only each branch of the template code must be instantiated, not every 
possible instantiation. And we have a tool to help with that: -cov


Does anyone believe it is a good practice to ship template code that has never 
been instantiated?


Re: Rant after trying Rust a bit

2015-07-23 Thread Walter Bright via Digitalmars-d

On 7/23/2015 12:50 PM, Tobias Müller wrote:

TBH I'm very surprised about that argument, because boolean conditions with
version() were dimissed for exactly that reason.


I knew someone would bring that up :-)

No, I do not believe it is the same thing. For one thing, you cannot test the 
various versions on one system. On any one system, you have to take on faith 
that you didn't break the version blocks on other systems.


This is quite unlike D's template constraints, where all the combinations can be 
tested reliably with a unittest{} block.




Re: Rant after trying Rust a bit

2015-07-23 Thread Ziad Hatahet via Digitalmars-d
On Wed, Jul 22, 2015 at 4:25 PM, jmh530 via Digitalmars-d 
digitalmars-d@puremagic.com wrote:


 I feel like it's hard to separate borrowing from Rust's variety of
 pointers ( is borrowed pointer, ~ is for unique pointer, @ is for managed
 pointer).


Rust has ditched the ~ and @ syntax for pointers for a long time now. For
unique pointers they use BoxT, and for managed pointers it is either
RcT, ArcT, or GcT, depending on the desired behavior. The last one is
currently still under development I believe.


Re: Rant after trying Rust a bit

2015-07-23 Thread Vlad Levenfeld via Digitalmars-d

On Thursday, 23 July 2015 at 20:40:17 UTC, Walter Bright wrote:

On 7/23/2015 12:50 PM, H. S. Teoh via Digitalmars-d wrote:
That assumes the template author is diligent (foolhardy?) 
enough to

write unittests that cover all possible instantiations...


No, only each branch of the template code must be instantiated, 
not every possible instantiation. And we have a tool to help 
with that: -cov


Does anyone believe it is a good practice to ship template code 
that has never been instantiated?


I dunno about good practices but I have some use cases.

I write a bunch of zero-parameter template methods and then pass 
them into a Match template which attempts to instantiate each of 
them in turn, settling on the first one which does compile. So 
the methods basically form a list of preferred implementation of 
functionality X. All but one winds up uninstantiated.


I also use a pattern where I mix in a zero-parameter template 
methods into a struct - they don't necessarily work for that 
struct, but they won't stop compilation unless they are 
instantiated. A complete interface is generated but only the 
subset which the context actually supports can be successfully 
instantiated - and anything the caller doesn't need, doesn't get 
compiled.


Again, not sure if this is a bad or good thing. But I have found 
these patterns useful.


Re: Overloading Based on Constraints

2015-07-23 Thread Steven Schveighoffer via Digitalmars-d-learn

On 7/23/15 5:58 PM, jmh530 wrote:

I was looking at
http://dlang.org/concepts.html
where it discusses overloading templates based on constraints. I wanted
to try to overload a template function with another version that does
everything in place. So basically, one has a return and the other
doesn't. However, when I run the code, it only calls the first function.
The second one is ignored. I tried a number of adjustments, but the only
thing that worked is to re-name the function something else, remove the
U's, and just have it be a void function.


Just so you know, *every* template is tried for every call. So the if 
statements are not dependent on each other. Something I've wanted for a 
long time is an if-else mechanism for template constraints.


What ends up happening is you have to repeat your constraints on every 
overload, but negate the previous ones.


In any case, to your code:




import std.stdio : writeln;
import std.traits;

T test(T)(T x)
 if (isNumeric!(T))
{
 writeln(calling test without void);
 T y = x;
 y += 1;
 return y;
}

U test(T, U)(ref T x)
 if (isNumeric!(T)  is(U == void))


this will NEVER be called via IFTI, because U cannot be determined from 
the parameters. Return type (or how you use the result) does not play 
into IFTI at all.


This is likely why it's never used, because it fails to instantiate.

And note that regular overloading does not work like this. You can't 
overload on return type. Overloading on ref works, but only makes it so 
you can dictate how to handle rvalues vs. lvalues differently.


-Steve


Re: Bin2d (0.2.0) Rewrite

2015-07-23 Thread Suliman via Digitalmars-d-announce

On Thursday, 23 July 2015 at 10:15:17 UTC, Rikki Cattermole wrote:
So Bin2D[0] has been rewritten and adds a bunch of nice new 
features.


- Limit generated code by:
  - package modifier
  - ``version(unittest)``
- Use enum for usage at compile time, instead of 
``const(ubyte[])``

- Report with variable name to original filename

Only dependency is Phobos.
The rewrite adds most importantly usage of e.g. byChunk over 
the input files to limit the amount of memory used.


[0] https://github.com/rikkimax/bin2d


Cool! Could you add example of usage in readme?


Re: Converting uint[] slice to string for the purpose of hashing?

2015-07-23 Thread Enjoys Math via Digitalmars-d-learn

On Thursday, 23 July 2015 at 11:49:05 UTC, cym13 wrote:

On Thursday, 23 July 2015 at 11:15:46 UTC, Enjoys Math wrote:

1.  Is the best way to hash a uint[] slice

2.  How do you do it?


IIRC, std.digest functions take ubyte[] as input, so to hash a 
uint[] I would do the following:


void main(string[] args)
{
import std.conv;
import std.digest.md;

int[] a   = [1, 2, 3, 4, 5];
auto  md5 = new MD5Digest();

md5.put(a.to!(ubyte[]));

auto hash = md5.finish();
writeln(hash);
}


Thanks.  That worked.   Here's my code:

module hashtools;
import std.conv;
import std.digest.md;

string uintSliceToHash(const uint[] slice) {
auto  md5 = new MD5Digest();
md5.put(slice.to!(ubyte[]));
return md5.finish().to!(string);
}

unittest {
import std.stdio;
uint[] slice = [1,2,3,4];
writeln(uintSliceToHash(slice));
}



Re: Converting uint[] slice to string for the purpose of hashing?

2015-07-23 Thread Enjoys Math via Digitalmars-d-learn

On Thursday, 23 July 2015 at 12:10:04 UTC, Enjoys Math wrote:

On Thursday, 23 July 2015 at 11:49:05 UTC, cym13 wrote:

[...]


Thanks.  That worked.   Here's my code:

module hashtools;
import std.conv;
import std.digest.md;

string uintSliceToHash(const uint[] slice) {
auto  md5 = new MD5Digest();
md5.put(slice.to!(ubyte[]));
return md5.finish().to!(string);
}

unittest {
import std.stdio;
uint[] slice = [1,2,3,4];
writeln(uintSliceToHash(slice));
}


Actually, uint[] seems to be hashable:

import std.stdio;
int[uint[]] aa;
aa[[1,2,3]] = 5;
writeln(aa[[1,2,3]]);

WORKS


Converting uint[] slice to string for the purpose of hashing?

2015-07-23 Thread Enjoys Math via Digitalmars-d-learn

1.  Is the best way to hash a uint[] slice

2.  How do you do it?




Re: Rant after trying Rust a bit

2015-07-23 Thread Adam D. Ruppe via Digitalmars-d

On Wednesday, 22 July 2015 at 21:04:57 UTC, simendsjo wrote:
:) The example was written to save space. I recon you 
understand what I mean.


Yeah, but the if/else is one of the most useful examples of it, 
and is covered by ?:, so the whole thing becomes less compelling 
then.


The other places where I've used it in languages that support it 
are little blocks crammed into a line and sometimes exception 
grabbing... but still, the value isn't that great.


Re: Rant after trying Rust a bit

2015-07-23 Thread Andrei Alexandrescu via Digitalmars-d

On 7/22/15 7:47 PM, rsw0x wrote:

On Wednesday, 22 July 2015 at 18:47:33 UTC, simendsjo wrote:

...


I think rust makes the ugliness of D's push everything into phobos for
simplicity become very visible. D and Rust share many equal constructs,
but D's is almost always uglier.


Care for a list? Thanks! -- Andrei



Re: Converting uint[] slice to string for the purpose of hashing?

2015-07-23 Thread cym13 via Digitalmars-d-learn

On Thursday, 23 July 2015 at 11:15:46 UTC, Enjoys Math wrote:

1.  Is the best way to hash a uint[] slice

2.  How do you do it?


IIRC, std.digest functions take ubyte[] as input, so to hash a 
uint[] I would do the following:


void main(string[] args)
{
import std.conv;
import std.digest.md;

int[] a   = [1, 2, 3, 4, 5];
auto  md5 = new MD5Digest();

md5.put(a.to!(ubyte[]));

auto hash = md5.finish();
writeln(hash);
}



Re: Rant after trying Rust a bit

2015-07-23 Thread Andrei Alexandrescu via Digitalmars-d

On 7/22/15 5:36 PM, jmh530 wrote:

On Wednesday, 22 July 2015 at 20:43:04 UTC, simendsjo wrote:

When everything is an expressions, you can write things like
auto a = if(e) c else d;

In D you have to write
type a = invalid_value;
if(e) a = c;
else  a = d;
assert(a != invalid_value);




I prefer this example from one of the various Rust tutorials

let foo = if x == 5 {
 five
   }
   else if x == 6 {
 six
   }
   else {
 neither
   }

You're basically using a conditional expression as an rvalue. You can do
the same thing with a { } block.


I used to be quite jazzed about the everything-is-an-expression mantra, 
but it's not all great.


1. Inferring function return types when everything is an expression 
(i.e. last expression there is the return type) may yield WAT results.


2. Defining a result type for loops is awkward.

At the end of the day everything-is-an-expression is natural for 
functional languages, but doesn't seem it makes a large difference to an 
imperative language.


To OP: thanks for your rant! Instead of getting defensive we'd do good 
to derive action items from it.



Andrei



Silicon Valley D Meetup July 2015

2015-07-23 Thread Ali Çehreli via Digitalmars-d-announce
Thanks to Chris Jacobi, we may have a permanent venue: Hacker Dojo in 
Mountain View:


  http://www.meetup.com/D-Lang-Silicon-Valley/events/224003042/

This will be a social get together with an open agenda. Bring your 
lightning talk and any other topic with or without a slide deck.


Ali


Re: Converting uint[] slice to string for the purpose of hashing?

2015-07-23 Thread Temtaime via Digitalmars-d-learn
All types are hashable and for your own structs and classes you 
can redefine opHash


Re: Rant after trying Rust a bit

2015-07-23 Thread Tobias Müller via Digitalmars-d
Walter Bright newshou...@digitalmars.com wrote:
 On 7/23/2015 3:12 PM, Dicebot wrote:
 On Thursday, 23 July 2015 at 22:10:11 UTC, H. S. Teoh wrote:
 OK, I jumped into the middle of this discussion so probably I'm speaking
 totally out of context...
 
 This is exactly one major advantage of Rust traits I have been trying to
 explain, thanks for putting it up in much more understandable way :)
 
 Consider the following:
 
 int foo(T: hasPrefix)(T t) {
t.prefix();// ok
bar(t);// error, hasColor was not specified for T
 }
 
 void bar(T: hasColor)(T t) {
t.color();
 }
 
 Now consider a deeply nested chain of function calls like this. At the
 bottom, one adds a call to 'color', and now every function in the chain
 has to add 'hasColor' even though it has nothing to do with the logic in
 that function. This is the pit that Exception Specifications fell into.
 
 I can see these possibilities:
 
 1. Require adding the constraint annotations all the way up the call
 tree. I believe that this will not only become highly annoying, it might
 make generic code impractical to write (consider if bar was passed as an 
 alias).
 
 2. Do the checking only for 1 level, i.e. don't consider what bar()
 requires. This winds up just pulling the teeth of the point of the constraint 
 annotations.
 
 3. Do inference of the constraints. I think that is indistinguishable
 from not having annotations as being exclusive.
 
 
 Anyone know how Rust traits and C++ concepts deal with this?

You may aus well ask How do interfaces in OO programming deal with this?.
Frankly, I've never had an issue with that. Or it's a hint for design
problems.

Traits (and interfaces) are mostly not that fine grained, i.e. you don't
have a trait/interface for every method.
They should ideally define an abstraction/entity with a semantic meaning.
If your constraint hasColor(x) just means x has method color(), and
then implement it for every class that has this method, you can just as
well omit constraints and use duck typing.

Tobi


Re: Rant after trying Rust a bit

2015-07-23 Thread Tobias Müller via Digitalmars-d
Walter Bright newshou...@digitalmars.com wrote: 
 I know a lot of the programming community is sold on exclusive
 constraints (C++ concepts, Rust traits) rather than inclusive ones (D
 constraints). What I don't see is a lot of experience actually using them
 long term. They may not turn out so well, like ES.

Haskell has type classes since ~1990.

Tobi


Re: Rant after trying Rust a bit

2015-07-23 Thread Tofu Ninja via Digitalmars-d

On Thursday, 23 July 2015 at 20:09:34 UTC, Walter Bright wrote:

On 7/23/2015 7:49 AM, ixid wrote:
If we had a clean sheet wouldn't it be better to have if 
return a value and

ditch ternary?


Then we'd start seeing code like:

x = 45 + if (y == 10) { while (i--) z += call(i); z; } else 
{ switch (x) { case 6: foo(); y; } + tan(z);


I.e. the embedding of arbitrary statements within expressions. 
We already have some of this with embedded anonymous lambda 
support, and I've discovered one needs to be very careful in 
formatting it to not wind up with an awful unreadable mess.


So I'd be really reluctant to continue down that path.

Now, if you want to disallow { } within the embedded if 
statement, then the proposal becomes nothing more than:


? = if
: = else

which is a potayto potahto thing.

I agree that trivial syntax issues actually do matter, but 
having used ?: a lot, I have a hard time seeing embeddable 
if-else as a real improvement, in fact I find it more than a 
little jarring to see.


I think I agree on the if else issue, seems arbitrary as we 
already have ?:. Other statements as expressions have less 
obvious meanings. The only part is that I wish you could have 
blocks as expressions. The thing is with ufcs, it really should 
be possible.


For example the following does not compile:
int a = {return 4;};

but the following does:
int a = {return 4;}();

I know it's a really small difference, but with UFCS, I would 
expect you the be able to omit the () and have the function 
literal called automatically. Though I can see that this would 
have problems with auto and knowing if it should be a function 
pointer or to call the function.


I guess what I would expect is auto a = {return 4;}; to type a 
to a function pointer, but if you explicitly type a to int then 
the literal should be called.


Does UFCS even apply to function pointers? I guess it is a 
problem, it does not seem to be obvious when to call and when to 
copy the pointer. I don't really know what should happen. I think 
I read a dip a little while ago that might have addressed this, 
but I don't really remember. I dont know, now that I have written 
this, it seems to have more problems than I originally thought.




How do you make a copy TO and object when you're INSIDE of it?

2015-07-23 Thread Enjoys Math via Digitalmars-d-learn

Here's my code:

module grammar;

class Grammar(T : ulong) {
this(const T[] str) {
auto grammar = str in grammarCache;

if (grammar) {
this = grammar.dup;
} else {
this = approximateSmallestGrammar(str);
grammarCache[str] = this.dup;
}
}

static Grammar approximateSmallestGrammar(const T[] str) {
return new Grammar();
}

@property Grammar dup() {

}

private:
this() {}
static Grammar[T[]] grammarCache;
};


Compiler says 'this' is not an lvalue.  How would I accomplish 
what I want?




Re: Rant after trying Rust a bit

2015-07-23 Thread Tofu Ninja via Digitalmars-d

On Friday, 24 July 2015 at 00:55:35 UTC, Tofu Ninja wrote:

On Thursday, 23 July 2015 at 20:09:34 UTC, Walter Bright wrote:

On 7/23/2015 7:49 AM, ixid wrote:
If we had a clean sheet wouldn't it be better to have if 
return a value and

ditch ternary?


Then we'd start seeing code like:

x = 45 + if (y == 10) { while (i--) z += call(i); z; } 
else { switch (x) { case 6: foo(); y; } + tan(z);


I.e. the embedding of arbitrary statements within expressions. 
We already have some of this with embedded anonymous lambda 
support, and I've discovered one needs to be very careful in 
formatting it to not wind up with an awful unreadable mess.


So I'd be really reluctant to continue down that path.

Now, if you want to disallow { } within the embedded if 
statement, then the proposal becomes nothing more than:


? = if
: = else

which is a potayto potahto thing.

I agree that trivial syntax issues actually do matter, but 
having used ?: a lot, I have a hard time seeing embeddable 
if-else as a real improvement, in fact I find it more than a 
little jarring to see.


I think I agree on the if else issue, seems arbitrary as we 
already have ?:. Other statements as expressions have less 
obvious meanings. The only part is that I wish you could have 
blocks as expressions. The thing is with ufcs, it really should 
be possible.


For example the following does not compile:
int a = {return 4;};

but the following does:
int a = {return 4;}();

I know it's a really small difference, but with UFCS, I would 
expect you the be able to omit the () and have the function 
literal called automatically. Though I can see that this would 
have problems with auto and knowing if it should be a function 
pointer or to call the function.


I guess what I would expect is auto a = {return 4;}; to type 
a to a function pointer, but if you explicitly type a to int 
then the literal should be called.


Does UFCS even apply to function pointers? I guess it is a 
problem, it does not seem to be obvious when to call and when 
to copy the pointer. I don't really know what should happen. I 
think I read a dip a little while ago that might have addressed 
this, but I don't really remember. I dont know, now that I have 
written this, it seems to have more problems than I originally 
thought.


Actually now that I think about it, I think I would expect auto a 
= { return 4;}; to type a to an int and call the function 
literal, and auto a = { return 4;}; to type a to a function 
pointer. I think that makes sense. Then if a is a function 
pointer auto b = a; would type b to a function pointer as well. I 
suppose UFCS really does not make sense to function pointers, but 
does make sense for function literals.


I expect {return 4;} to just be an anonymous function, not a 
pointer to an anonymous function. That way you can write alias f 
= {return 4;}; which would just be an alias to a function, which 
makes sense. I haven't thought about how this would apply to 
delegates.





[Issue 14731] [REG2.068a] Error location insufficient when CTFE

2015-07-23 Thread via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=14731

--- Comment #4 from github-bugzi...@puremagic.com ---
Commit pushed to master at https://github.com/D-Programming-Language/dmd

https://github.com/D-Programming-Language/dmd/commit/f491e5604009e40ad96cc7ecad6979975776a200
Merge pull request #4771 from 9rnsr/fix14731

--


[Issue 13720] [REG2.067] Adding trivial destructor to std.datetime causes Internal error: ..\ztc\cgelem.c 2418

2015-07-23 Thread via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=13720

--- Comment #8 from github-bugzi...@puremagic.com ---
Commit pushed to master at https://github.com/D-Programming-Language/dmd

https://github.com/D-Programming-Language/dmd/commit/742f467c137c8dc6e42d0a4d0863d5bc6b0f
Merge pull request #4759 from 9rnsr/fix13720

--


[Issue 14430] [REG2.060] Null parameter is detected as non-null.

2015-07-23 Thread via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=14430

--- Comment #13 from github-bugzi...@puremagic.com ---
Commit pushed to master at https://github.com/D-Programming-Language/dmd

https://github.com/D-Programming-Language/dmd/commit/d6a13be63392ea2d6c2eac369a8b6e2c42b2492b
Merge pull request #4775 from WalterBright/fix14430

--


[Issue 14682] [REG2.037] Incorrect interpretation of ~ []

2015-07-23 Thread via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=14682

--- Comment #16 from github-bugzi...@puremagic.com ---
Commit pushed to master at https://github.com/D-Programming-Language/dmd

https://github.com/D-Programming-Language/dmd/commit/e23ff7c0e4f9de3f4dd6352e261ee430466d7ddb
Merge pull request #4742 from 9rnsr/fix14682

--


[Issue 14510] Bad tail call optimization with static arrays

2015-07-23 Thread via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=14510

--- Comment #4 from github-bugzi...@puremagic.com ---
Commit pushed to master at https://github.com/D-Programming-Language/dmd

https://github.com/D-Programming-Language/dmd/commit/86757a2f4efc5562d8621207676d2a187e91b33a
Merge pull request #4778 from WalterBright/fix14510

--


[Issue 14626] [REG2.066] byValue doesn't work with inout AA

2015-07-23 Thread via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=14626

--- Comment #7 from github-bugzi...@puremagic.com ---
Commits pushed to master at https://github.com/D-Programming-Language/druntime

https://github.com/D-Programming-Language/druntime/commit/6d57c68df1f72e9416548ad450e56a16bb1fdb90
fix Issue 14626 - byValue doesn't work with inout AA

https://github.com/D-Programming-Language/druntime/commit/ad900eb3cc38397c4fa3a0a805793f002d03abc7
Merge pull request #1326 from 9rnsr/fix14626

--


Re: casting away const and then mutating

2015-07-23 Thread Jonathan M Davis via Digitalmars-d
On Friday, 24 July 2015 at 03:02:30 UTC, Steven Schveighoffer 
wrote:

On 7/23/15 7:57 PM, Jonathan M Davis wrote:

If
you cast away const, it's up to you to guarantee that the data 
being
referenced is not mutated, and if it is mutated, it's 
undefined behavior.


Still need a reference to the spec that says that. Note that 
the spec specifically says it's undefined to cast away and 
modify immutable, and is careful not to include const/mutable 
in that discussion.


It's come up a number of times in discussions on logical const, 
including from Walter. For it to be otherwise would mean that 
const is not actually physical const. I'm quite certain that the 
spec is wrong in this case.


OK, but the point is you have run an algorithm that gets a 
*piece* of x (pretend x is not just a simple int), which you 
know to be mutable because x is mutable. But you don't want the 
algorithm to mutate x.


Basically, if we say this is undefined behavior, then inout is 
undefined behavior.


inout is done by the compiler. It knows that it's safe to cast 
the return type to mutable (or immutable), because it knows that 
the return value was either the argument that it passed in or 
something constructed within the function and thus safe to cast. 
The compiler knows what's going on, so it can ensure that it 
doesn't violate the type system and is well-defined.


An example of what the compiler can start doing more than it 
does now would be helpful. I can't see how it can do anything 
based on this.


Well, it could remove dead code. For instance, if you had

const(Foo) bar(T t)
{
const myFoo = getFoo(t);
auto value1 = pureFunc(myFoo);
auto value2 = pureFunc2(myFoo);
auto value3 = pureFunc3(value1, value2);
return myFoo;
}

All of the lines with pureFunc* could be removed outright, 
because they're all pure function calls, and they can't possibly 
have mutated myFoo. I wouldn't expect a lot of dead code like 
that, and maybe something like that would never be implemented in 
the compiler, but it could be as long as the compiler can 
actually rely on const not being mutated.


But part of the problem with start doing more than it does now 
is that that could easily depend on ideas that folks come up with 
later. At some point in the future, someone might figure out how 
const interacts with some other set of attributes and be able to 
optimize based on that. So, if you're casting away const and 
mutating, relying on no one coming up with new optimizations, 
then you could be in trouble later when they do. And maybe they 
won't, but we don't know.


Specifically, I would say you can cast away const on a 
reference that you have created within your own function on a 
mutable piece of data (in other words, you control the mutable 
data), then you can mutate via the cast reference. Otherwise, 
the inout feature is invalid, and we should remove it from the 
language, because that's EXACTLY what it does.


A simple example:

struct Node
{
   int val;
   Node *next;
}
const(Node) *find(const(Node)* n, int val)
{
   while(n  n.val != val) n = n.next;
   return n;
}
Node *find(Node *n, int val)
{
const cn = n;
return cast(Node *)find(cn, val);
}

Note that the mutable version of find doesn't mutate the node 
(checked by the compiler BTW), and it's signature doesn't allow 
any const optimizations -- it gets in a mutable and returns a 
mutable. This can be rewritten like this:


inout(Node) *find(inout(Node)* n, int val)
{
while(n  n.val != val) n = n.next;
return n;
}

But in the case of the PR in question, we can't do this, 
because we can't inout our range and have it continue to be a 
range. So we are mimicking the behavior of inout, and the 
compiler should be fine with this.


It sounds like what you really want is a tail-inout range or 
somesuch, though since we can't even sort out tail-const ranges 
properly at this point, I expect that tail-inout ranges are a bit 
of a pipe dream.


In any case, regardless of whether what you're proposing defined 
behavior or not, it'll work, because there's no way that the 
compiler could do any optimizations based on const after the cast 
is done, because it's only const within the function. It's when 
you cast away const on something that you were given as const 
that you have a real problem. e.g.


const(Foo) bar(const(Foo) foo)
{
auto f = cast(Foo)foo;
f.mutateMe();
return foo;
}

I agree that what you're asking for makes sense. If you pass in a 
mutable object to a function, and you know that the const object 
you get out is either the same object or a new one that is not 
immutable, and no references to that object escaped the function, 
then casting the return type to mutable should work, and I'm not 
against that being well-defined, but as I understand it, it 
technically isn't, because it involves casting away const and 
then mutating the result. And if it is well-defined, then we'd 
need clear way to describe the circumstances to 

Re: Where will D sit in the web service space?

2015-07-23 Thread Joakim via Digitalmars-d

On Thursday, 23 July 2015 at 17:44:59 UTC, Etienne wrote:

On Thursday, 23 July 2015 at 17:03:31 UTC, Laeeth Isharc wrote:
But some of us think general-purpose, native languages are 
coming back,


Yes.  Now why do you think this is the case?  I tried to 
articulate it as best I could for now, but Ola has all these 
_reasons_ why this isn't the case, which may mean he is right, 
but might not.


Native languages are more efficient, they use less power. This 
is increasingly important to reduce the greenhouse gas 
emissions, to improve battery duration on mobile devices or to 
reduce server costs in general.


Yep, I specifically mentioned the mobile and server domains as 
places where general-purpose native/AoT-compiled languages are 
having a resurgence, obviously for the efficiency reasons Etienne 
lists.  Being general-purpose simply means that you wouldn't be 
limited to one of those domains, and could quickly bridge over to 
even newer domains that spring up.


One big trend over the last decade and a half has been the rise 
of webapps, where native desktop apps, which are still 
predominantly written in native languages, have been 
de-emphasized as a result.  However, with the rise of mobile and 
webapps not doing as well there, for a variety of reasons, native 
development is coming back for many apps, at least on the client 
side for networked apps.


On the server, as long as you don't really need to scale out, you 
have a lot of choices for your tech.  But the moment you need to 
scale, you'll probably want to go native, at least for your 
backend.


Re: How do you make a copy TO and object when you're INSIDE of it?

2015-07-23 Thread Steven Schveighoffer via Digitalmars-d-learn

On 7/23/15 9:30 PM, Enjoys Math wrote:

Here's my code:

module grammar;

class Grammar(T : ulong) {
 this(const T[] str) {
 auto grammar = str in grammarCache;

 if (grammar) {
 this = grammar.dup;
 } else {
 this = approximateSmallestGrammar(str);
 grammarCache[str] = this.dup;
 }
 }

 static Grammar approximateSmallestGrammar(const T[] str) {
 return new Grammar();
 }

 @property Grammar dup() {

 }

private:
 this() {}
 static Grammar[T[]] grammarCache;
};


Compiler says 'this' is not an lvalue.  How would I accomplish what I want?



You're approaching this wrong. Do the lookup before deciding whether to 
instantiate a new object:


static Grammar getGrammar(const T[] str) {
 if(auto x = str in grammarCache)
 return *x;
 else
 {
 auto g = new Grammar;
 grammarCache[str] = g;
 return g;
 }
}

If you always want to dup, then do it outside the lookup. Don't do it in 
the constructor, you already have an object by then.


-Steve


[Issue 14822] DMD crash with CTFE range code (v2.067.1)

2015-07-23 Thread via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=14822

Kenji Hara k.hara...@gmail.com changed:

   What|Removed |Added

 Status|NEW |RESOLVED
 Resolution|--- |WORKSFORME

--- Comment #1 from Kenji Hara k.hara...@gmail.com ---
The issue does not happen with 2.068-beta1..

I guess the root issue had had a problem in error handling for the template
instantiation. I think it has been fixed by:

https://github.com/D-Programming-Language/dmd/pull/4464

--


Re: Rant after trying Rust a bit

2015-07-23 Thread Walter Bright via Digitalmars-d

On 7/23/2015 6:05 PM, H. S. Teoh via Digitalmars-d wrote:

It doesn't solve *all* the problems, but it does solve a
significant subset of them.


The worst case of not having this feature is a compile time error. Not a runtime 
error, undetectable error, or silent corruption. A compile time error.


I also believe that you underestimate the nuisance significance of requiring the 
constraints cover 100% of everything the template body does.


Experience with something similar is with exception specifications. Even 
advocates of ES found themselves writing obviously crap code to work around the 
issue, because ES was so damned annoying.


I know a lot of the programming community is sold on exclusive constraints (C++ 
concepts, Rust traits) rather than inclusive ones (D constraints). What I don't 
see is a lot of experience actually using them long term. They may not turn out 
so well, like ES.


Re: Rant after trying Rust a bit

2015-07-23 Thread Adam D. Ruppe via Digitalmars-d

On Thursday, 23 July 2015 at 21:27:17 UTC, Ziad Hatahet wrote:

I think it is actually kinda pretty:



What about:

int median(int a, int b, int c) {
return (ab) ? (bc) ? b : (ac) ? c : a : (ac) ? a : 
(bc) ? c : b;

}

vs.

def median(a: Int, b: Int, c: Int) =
  if (a  b) {
if (b  c) b
else if (a  c) c
else a
  }
  else if (a  c) a
  else if (b  c) c
  else b


Not really a spaces-to-spaces comparison...

to be honest, I'd probably just write that as:

int median(int a, int b, int c) {
   if (a  b) {
 if (b  c) return b;
 else if (a  c) return c;
 else return a;
   }
   else if (a  c) return a;
   else if (b  c) return c;
   else return b;
}

You don't need it to be an expression since it is a function, you 
can simply write return statements (which I kinda like since then 
it is obvious that that value is a terminating condition and not 
just the middle of some other calculation).


But if we were using a ternary, some newlines can help with it:

 return
   (a  b) ? (
 (b  c) ? b
 : (a  c) ? c
 : a
   )
   : (a  c) ? a
   : (b  c) ? c
   : b;

Indeed, there I just took your if/else thing and swapped out the 
else keyword for the : symbol, then replaced if(cond) with (cond) 
?, then changed out the {} for (). It still works the same way.




Is the compiler always able to always optimize out the function 
call by inlining it, as would be the case with

a scope?


It should be.


Re: casting away const and then mutating

2015-07-23 Thread Steven Schveighoffer via Digitalmars-d

On 7/23/15 7:57 PM, Jonathan M Davis wrote:

On Thursday, 23 July 2015 at 18:43:03 UTC, anonymous wrote:

On a GitHub pull request, Steven Schveighoffer (schveiguy), Jonathan M
Davis (jmdavis), and I (aG0aep6G) have been discussing if or when it's
ok to cast away const and then mutate the data:

https://github.com/D-Programming-Language/phobos/pull/3501#issuecomment-124169544


I've been under the impression that it's never allowed, i.e. it's
always undefined behaviour. I think Jonathan is of the same opinion.


It's come up time and time again with discussions for logical const.


This is not logical const. We are starting with mutable data, moving it 
through a function that we *don't* want to mutate the data, and then 
using it as mutable again in the function where you (and the compiler) 
know its mutable. But you aren't even mutating, just getting it back to 
the original constancy (though mutation should be OK, you still have a 
mutable reference).



If
you cast away const, it's up to you to guarantee that the data being
referenced is not mutated, and if it is mutated, it's undefined behavior.


Still need a reference to the spec that says that. Note that the spec 
specifically says it's undefined to cast away and modify immutable, and 
is careful not to include const/mutable in that discussion.



Now, if you know that the data being referenced is actually mutable and
not immutable, and you know that the compiler isn't going to make any
assumptions based on const which are then wrong if you mutate the
variable after casting away const, then you can get away with it.
But
it's still undefined behavior, and if the compiler later starts doing
more than it does now based on the knowledge that you can't mutate via a
const reference, then your code might stop working correctly. So, if
you're _really_ careful, you can get away with casting away const and
mutating a variable, but you are depending on undefined behavior.


An example of what the compiler can start doing more than it does now 
would be helpful. I can't see how it can do anything based on this.




int x;
const int *y = x;
*(cast(int *)y) = 5;



Even if this were defined behavior, what would be the point? You have
access to x. You could just mutate it directly.


OK, but the point is you have run an algorithm that gets a *piece* of x 
(pretend x is not just a simple int), which you know to be mutable 
because x is mutable. But you don't want the algorithm to mutate x.


Basically, if we say this is undefined behavior, then inout is undefined 
behavior.



I don't see how it would
make any sense to be attempting to mutate something via a const
reference when you have access to it via a mutable reference. It's when
you don't have access to it via a mutable reference that it becomes an
issue - which means that you've crossed a function boundary.


Exactly. You still have mutable access to it, and you know the const 
access is to the same object, just transformed via an algorithm.



The only way to make casting away const and mutating defined behavior in
general


This is NOT what is being asked. Not the general case of making it 
defined to cast away const on any item (which could turn out to be 
immutable).


I think it's pointless to argue over this. The behavior can't be defined 
any other way than what I'm asking. The question is if we want the 
*official* position to nonsensically call it undefined behavior.


Specifically, I would say you can cast away const on a reference that 
you have created within your own function on a mutable piece of data (in 
other words, you control the mutable data), then you can mutate via the 
cast reference. Otherwise, the inout feature is invalid, and we should 
remove it from the language, because that's EXACTLY what it does.


A simple example:

struct Node
{
   int val;
   Node *next;
}
const(Node) *find(const(Node)* n, int val)
{
   while(n  n.val != val) n = n.next;
   return n;
}
Node *find(Node *n, int val)
{
const cn = n;
return cast(Node *)find(cn, val);
}

Note that the mutable version of find doesn't mutate the node (checked 
by the compiler BTW), and it's signature doesn't allow any const 
optimizations -- it gets in a mutable and returns a mutable. This can be 
rewritten like this:


inout(Node) *find(inout(Node)* n, int val)
{
while(n  n.val != val) n = n.next;
return n;
}

But in the case of the PR in question, we can't do this, because we 
can't inout our range and have it continue to be a range. So we are 
mimicking the behavior of inout, and the compiler should be fine with this.


-Steve


[Issue 14806] [REG2.063] alias this doesn't force elaborate equality, but is followed during it

2015-07-23 Thread via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=14806

--- Comment #3 from github-bugzi...@puremagic.com ---
Commits pushed to master at https://github.com/D-Programming-Language/dmd

https://github.com/D-Programming-Language/dmd/commit/83fa6accb7b83f3a88898a675933319073e3497e
fix Issue 14806 - alias this doesn't force elaborate equality, but is followed
during it

https://github.com/D-Programming-Language/dmd/commit/9318101daf48fb24b335cb6177c509bfec390586
Merge pull request #4820 from 9rnsr/fix14806

--


[Issue 14753] pragma(inline) hides the alias string

2015-07-23 Thread via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=14753

--- Comment #4 from github-bugzi...@puremagic.com ---
Commit pushed to master at https://github.com/D-Programming-Language/dmd

https://github.com/D-Programming-Language/dmd/commit/cbab6d6303783a22ee65a5a1e777a50d038133fa
Merge pull request #4793 from 9rnsr/fix14753

--


[Issue 14737] [REG2.058] A concatenation of array literal and static array should make dynamic array

2015-07-23 Thread via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=14737

--- Comment #6 from github-bugzi...@puremagic.com ---
Commit pushed to master at https://github.com/D-Programming-Language/dmd

https://github.com/D-Programming-Language/dmd/commit/d68e8d61ccabd1ae7c2252b86cda56e13adef1c4
Merge pull request #4776 from 9rnsr/fix14737

--


[Issue 14572] cannot build dmd from source anymore: 'g++ -m64: No such file or directory'

2015-07-23 Thread via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=14572

--- Comment #9 from github-bugzi...@puremagic.com ---
Commit pushed to master at https://github.com/D-Programming-Language/dmd

https://github.com/D-Programming-Language/dmd/commit/65ce308abc30e0f31fa118326840da14043adf5f
Merge pull request #4772 from JinShil/fix14572

--


[Issue 14735] [REG2.068-b1] std.string.indexOf cannot deduce function for char argument

2015-07-23 Thread via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=14735

--- Comment #15 from github-bugzi...@puremagic.com ---
Commit pushed to master at https://github.com/D-Programming-Language/dmd

https://github.com/D-Programming-Language/dmd/commit/c2b84a0b24f680bfa3cd336af6c84b0ded2c4594
Merge pull request #4779 from 9rnsr/fix14735

--


Re: How do you make a copy TO and object when you're INSIDE of it?

2015-07-23 Thread Enjoys Math via Digitalmars-d-learn
On Friday, 24 July 2015 at 03:12:43 UTC, Steven Schveighoffer 
wrote:

On 7/23/15 9:30 PM, Enjoys Math wrote:

[...]


You're approaching this wrong. Do the lookup before deciding 
whether to instantiate a new object:


static Grammar getGrammar(const T[] str) {
 if(auto x = str in grammarCache)
 return *x;
 else
 {
 auto g = new Grammar;
 grammarCache[str] = g;
 return g;
 }
}

If you always want to dup, then do it outside the lookup. Don't 
do it in the constructor, you already have an object by then.


-Steve


Thanks.  That sounds like a good approach


Re: Rant after trying Rust a bit

2015-07-23 Thread Walter Bright via Digitalmars-d

On 7/23/2015 3:12 PM, Dicebot wrote:

On Thursday, 23 July 2015 at 22:10:11 UTC, H. S. Teoh wrote:

OK, I jumped into the middle of this discussion so probably I'm speaking
totally out of context...


This is exactly one major advantage of Rust traits I have been trying to
explain, thanks for putting it up in much more understandable way :)


Consider the following:

int foo(T: hasPrefix)(T t) {
   t.prefix();// ok
   bar(t);// error, hasColor was not specified for T
}

void bar(T: hasColor)(T t) {
   t.color();
}

Now consider a deeply nested chain of function calls like this. At the bottom, 
one adds a call to 'color', and now every function in the chain has to add 
'hasColor' even though it has nothing to do with the logic in that function. 
This is the pit that Exception Specifications fell into.


I can see these possibilities:

1. Require adding the constraint annotations all the way up the call tree. I 
believe that this will not only become highly annoying, it might make generic 
code impractical to write (consider if bar was passed as an alias).


2. Do the checking only for 1 level, i.e. don't consider what bar() requires. 
This winds up just pulling the teeth of the point of the constraint annotations.


3. Do inference of the constraints. I think that is indistinguishable from not 
having annotations as being exclusive.



Anyone know how Rust traits and C++ concepts deal with this?


Re: Rant after trying Rust a bit

2015-07-23 Thread Walter Bright via Digitalmars-d

On 7/23/2015 3:06 PM, H. S. Teoh via Digitalmars-d wrote:

OK, I jumped into the middle of this discussion so probably I'm speaking
totally out of context... but anyway, with regards to template code, I
agree that it ought to be thoroughly tested by at least instantiating
the most typical use cases (as well as some not-so-typical use cases).


I argue that every code line of the template must at least have been 
instantiated at some point by the test suite. Anything less is, frankly, 
unprofessional.




A lot of Phobos bugs lurk in rarely-used template branches that are not
covered by the unittests.


Generally when I work on a Phobos template, I upgrade it to 100% unit test 
coverage. This should be a minimum bar for all Phobos work. We ought to be 
ashamed of anything less.




Instantiating all branches is only part of the solution, though. A lot
of Phobos bugs also arise from undetected dependencies of the template
code on the specifics of the concrete types used to test it in the
unittests.  The template passes the unittest but when you instantiate it
with a type not used in the unittests, it breaks. For instance, a lot of
range-based templates are tested with arrays in the unittests. Some of
these templates wrongly depend on array behaviour (as opposed to being
confined only to range API operations) while their signature constraints
indicate only the generic range API. As a result, when non-array ranges
are used, it breaks. Sometimes bugs like this can lurk undetected for a
long time before somebody one day happens to instantiate it with a range
type that violates the hidden assumption in the template code.


I agree that the constraint system is not checked against the actual body of the 
template. Dicebot brought that up as well. Some attention should be paid in the 
unit tests to using types that are minimal implementations of the constraints.


That said, it is a pipe dream to believe that if something matches the function 
signatures, that it is correct and will work without ever having been tested.




If we had a Concepts-like construct in D, where template code is
statically constrained to only use, e.g., range API when manipulating an
incoming type, a lot of these bugs would've been caught.

In fact, I'd argue that this should be done for *all* templates -- for
example, a function like this ought to be statically rejected:

auto myFunc(T)(T t) { return t + 1; }

because it assumes the validity of the + operation on T, but T is not
constrained in any way, so it can be *any* type, most of which,
arguably, do not support the + operation.


It's a valid point, but I'd counter that it'd be pretty tedious and burdensome. 
D isn't meant to be a bondage  discipline language. The failed exception 
specifications (Java and C++) comes to mind.




If the compiler outright rejected any operation on T that hasn't been
explicitly tested for, *then* we will have eliminated a whole class of
template bugs. Wrong code like the last example above would be caught as
soon as the compiler compiles the body of myFunc.


Yeah, but few would like programming in such a nagging, annoying language. Note 
that if you do instantiate with a type that doesn't support those operations, it 
isn't the end of the world - you'll still get a compile time error message.




Re: Measuring Execution time

2015-07-23 Thread Jonathan M Davis via Digitalmars-d-learn
On Thursday, July 23, 2015 13:59:11 Steven Schveighoffer via 
Digitalmars-d-learn wrote:
 On 7/22/15 5:23 AM, Clayton wrote:
  How does one represent Duration in only Micro-seconds, or milliseconds.
  Trying to measure the execution time of an algorithm and I get 4 ms,
  619 μs, and 8 hnsecs , I want to sum all these and get total hnsecs or
  μs .
 
  I would also  appreciate advise on  whether this is the best way to
  measure the execution time of an algorithm.
 
 
 
  import std.datetime;
  import std.stdio;
 
  void algorithm( ){
   writeln(Hello!);
  }
  void main(){
 
   auto stattime = Clock.currTime();
   algorithm( );
   endttime = Clock.currTime();
 
   auto duration = endttime - stattime;
 
   writeln(Hello Duration == , duration);
 
  }

 I know John identified Stopwatch, but just an FYI, Duration has the
 method total: http://dlang.org/phobos/core_time.html#.Duration.total

 I think doing:

 writeln(Hello Duration == , duration.total!usecs);

 would also work.

Yes, you could do that, but doing timing with the realtime clock is
fundamentally wrong, because the clock can change on you while you're
timing. That's why using a monotonic clock is better, since it's guaranteed
to never move backwards. Unfortunately, while StopWatch does use a monotonic
clock, it currently does that by using TickDuration for that rather than
MonoTime, so its result is a TickDuration rather than a Duration, so it's a
bit harder to use than would be nice, but it is more correct to use
StopWatch than to subtract SysTimes. Alternatively, you could just use
MonoTime directly. e.g.

auto startTime = MonoTime.currTime;
// do stuff
auto endTime = MonoTime.currTime;

audo duration = endTime - startTime;
writeln(Hello Duration == , duration.total!usecs);

in which case you get a Duration just like with subtract SysTimes, and the
suggestion of using total works just fine.

I need to put together replacements for the benchmarking functions in
std.datetime (probably in std.benchmark) which use MonoTime and Duration
rather than TickDuration so that we can deprecate the ones in std.datetime
which use TickDuration (and deprecate TickDuration itself).

- Jonathan M Davis




Re: Rant after trying Rust a bit

2015-07-23 Thread H. S. Teoh via Digitalmars-d
On Thu, Jul 23, 2015 at 05:34:20PM -0700, Walter Bright via Digitalmars-d wrote:
 On 7/23/2015 3:06 PM, H. S. Teoh via Digitalmars-d wrote:
 OK, I jumped into the middle of this discussion so probably I'm
 speaking totally out of context... but anyway, with regards to
 template code, I agree that it ought to be thoroughly tested by at
 least instantiating the most typical use cases (as well as some
 not-so-typical use cases).
 
 I argue that every code line of the template must at least have been
 instantiated at some point by the test suite. Anything less is,
 frankly, unprofessional.

I agree, and I didn't claim otherwise.


 A lot of Phobos bugs lurk in rarely-used template branches that are
 not covered by the unittests.
 
 Generally when I work on a Phobos template, I upgrade it to 100% unit
 test coverage. This should be a minimum bar for all Phobos work. We
 ought to be ashamed of anything less.

Agreed.


 Instantiating all branches is only part of the solution, though. A
 lot of Phobos bugs also arise from undetected dependencies of the
 template code on the specifics of the concrete types used to test it
 in the unittests.  The template passes the unittest but when you
 instantiate it with a type not used in the unittests, it breaks. For
 instance, a lot of range-based templates are tested with arrays in
 the unittests. Some of these templates wrongly depend on array
 behaviour (as opposed to being confined only to range API operations)
 while their signature constraints indicate only the generic range
 API. As a result, when non-array ranges are used, it breaks.
 Sometimes bugs like this can lurk undetected for a long time before
 somebody one day happens to instantiate it with a range type that
 violates the hidden assumption in the template code.
 
 I agree that the constraint system is not checked against the actual
 body of the template. Dicebot brought that up as well. Some attention
 should be paid in the unit tests to using types that are minimal
 implementations of the constraints.
 
 That said, it is a pipe dream to believe that if something matches the
 function signatures, that it is correct and will work without ever
 having been tested.

I didn't say that this one thing alone will singlehandedly solve all of
our template testing woes. Obviously, it cannot catch semantic errors --
you use all the valid range API operations, but you use them in the
wrong order, say, or in a way that doesn't accomplish what the code is
supposed to do.  I think it's a given that you still need to adequately
unittest the code just like you would non-template code.

Nevertheless, this does help to eliminate an entire class of latent
template bugs -- hidden dependencies on the incoming type that are not
covered by the function's contract (i.e., signature constraints).
Relying on the programmer to always use types with minimal functionality
in the unittests is programming by convention, and you know very well
how effective that is. Without enforcement, we have no way of being sure
that our tests are actually adequate. An untested branch of template
code can be detected by using -cov, but performing an operation on an
incoming type without checking for it in the sig constraints cannot be
detected except by reading every line of code. The unittest may have
inadvertently used a type with a superset of functionality, but since
this is never enforced (and the current language provides no way to
actually enforce it) we can never be sure -- we're just taking it on
faith that the tests have covered all bases.

With actual language enforcement, we can actually provide some
guarantees. It doesn't solve *all* the problems, but it does solve a
significant subset of them.


 If we had a Concepts-like construct in D, where template code is
 statically constrained to only use, e.g., range API when manipulating
 an incoming type, a lot of these bugs would've been caught.
 
 In fact, I'd argue that this should be done for *all* templates --
 for example, a function like this ought to be statically rejected:
 
  auto myFunc(T)(T t) { return t + 1; }
 
 because it assumes the validity of the + operation on T, but T is not
 constrained in any way, so it can be *any* type, most of which,
 arguably, do not support the + operation.
 
 It's a valid point, but I'd counter that it'd be pretty tedious and
 burdensome. D isn't meant to be a bondage  discipline language. The
 failed exception specifications (Java and C++) comes to mind.
 
 
 If the compiler outright rejected any operation on T that hasn't been
 explicitly tested for, *then* we will have eliminated a whole class
 of template bugs. Wrong code like the last example above would be
 caught as soon as the compiler compiles the body of myFunc.
 
 Yeah, but few would like programming in such a nagging, annoying
 language.

I have trouble thinking of a template function that's actually *correct*
when its sig constraints doesn't specify what operations are valid on
the 

Re: How do you make a copy TO and object when you're INSIDE of it?

2015-07-23 Thread Jonathan M Davis via Digitalmars-d-learn
On Friday, July 24, 2015 01:30:55 Enjoys Math via Digitalmars-d-learn wrote:
 Here's my code:

 module grammar;

 class Grammar(T : ulong) {
  this(const T[] str) {
  auto grammar = str in grammarCache;

  if (grammar) {
  this = grammar.dup;
  } else {
  this = approximateSmallestGrammar(str);
  grammarCache[str] = this.dup;
  }
  }

  static Grammar approximateSmallestGrammar(const T[] str) {
  return new Grammar();
  }

  @property Grammar dup() {

  }

 private:
  this() {}
  static Grammar[T[]] grammarCache;
 };


 Compiler says 'this' is not an lvalue.  How would I accomplish
 what I want?

Assign to the members individually rather than the whole object at once.

- Jonathan M Davis



[Issue 14699] [REG2.062] ICE: segfaults on array with zero size

2015-07-23 Thread via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=14699

--- Comment #12 from github-bugzi...@puremagic.com ---
Commit pushed to master at https://github.com/D-Programming-Language/dmd

https://github.com/D-Programming-Language/dmd/commit/72f759961d08ed9a4e0da2e1d81608fed9a0d7b6
Merge pull request #4744 from 9rnsr/fix14699

--


[Issue 14805] [REG2.064] Unreasonably slow new Struct[large]

2015-07-23 Thread via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=14805

--- Comment #7 from github-bugzi...@puremagic.com ---
Commits pushed to master at https://github.com/D-Programming-Language/dmd

https://github.com/D-Programming-Language/dmd/commit/27dc11712eb4ddd4d45033654f7d8cb93d7745d4
fix Issue 14805 - Unreasonably slow new Struct[large]

https://github.com/D-Programming-Language/dmd/commit/35d35f1cf7c5e386f3c9c2f5ca76fc4f12f174e0
Merge pull request #4821 from 9rnsr/fix14805

--


[Issue 14754] [REG2.068b1] 64bit wrong code with -inline

2015-07-23 Thread via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=14754

--- Comment #6 from github-bugzi...@puremagic.com ---
Commit pushed to master at https://github.com/D-Programming-Language/dmd

https://github.com/D-Programming-Language/dmd/commit/22e27f5d84dc39d005106303986d91525e2834bf
Merge pull request #4795 from 9rnsr/fix14754

--


Re: Rant after trying Rust a bit

2015-07-23 Thread Walter Bright via Digitalmars-d

On 7/23/2015 7:15 AM, Andrei Alexandrescu wrote:

I am a bit puzzled by the notion of shipping template code that has
never been instantiated as being a positive thing. This has also turned
up in the C++ static_if discussions.


This is easy to understand. Weeding out uncovered code during compilation is a
central feature of C++ concepts. Admitting you actually never want to do that
would be a major blow.


But if a unit test fails at instantiating it, it fails at compile time.



Re: Rant after trying Rust a bit

2015-07-23 Thread H. S. Teoh via Digitalmars-d
On Thu, Jul 23, 2015 at 12:49:29PM -0700, Walter Bright via Digitalmars-d wrote:
 On 7/23/2015 7:15 AM, Andrei Alexandrescu wrote:
 I am a bit puzzled by the notion of shipping template code that has
 never been instantiated as being a positive thing. This has also
 turned up in the C++ static_if discussions.
 
 This is easy to understand. Weeding out uncovered code during
 compilation is a central feature of C++ concepts. Admitting you
 actually never want to do that would be a major blow.
 
 But if a unit test fails at instantiating it, it fails at compile
 time.

That assumes the template author is diligent (foolhardy?) enough to
write unittests that cover all possible instantiations...


T

-- 
People say I'm indecisive, but I'm not sure about that. -- YHL, CONLANG


Re: Rant after trying Rust a bit

2015-07-23 Thread Tobias Müller via Digitalmars-d
Andrei Alexandrescu seewebsiteforem...@erdani.org wrote:
 On 7/23/15 5:07 AM, Walter Bright wrote:
Turns out many constraints in Phobos are of the form (A || B),
 not just (A  B).
 
 Agreed. And that's just scratching the surface.
 
 Serious question: how do you express in Rust that a type implements one
 trait or another, then figure out statically which?

You define a new trait and implement it differently for A and B.
That leads to a cleaner design IMO because you have to think about the
right abstraction for that trait.

TBH I'm very surprised about that argument, because boolean conditions with
version() were dimissed for exactly that reason.

Tobi


Re: Rant after trying Rust a bit

2015-07-23 Thread Walter Bright via Digitalmars-d

On 7/23/2015 8:03 AM, Dicebot wrote:

At the same time one HUGE deal breaker with rust traits that rarely gets
mentioned is the fact that they are both constraints and interfaces at the same
time:

// this is template constraint, it will generate new `foo` symbol for each new T
fn foo T : InputRange (range : T)

// this use the very same trait definition but creates fat pointer on demand
with simplistic dispatch table
fn foo (range : InputRange)

It kills all the necessity for hacks like RangeObject and is quite a salvation
once you get to defining dynamic shared libraries with stable ABI.

This is probably my most loved feature of Rust.


D interface types also produce the simplistic dispatch table, and if you make 
them extern(C++) they don't need a RangeObject. I know it isn't as convenient as 
what you describe above, but it can be pressed into service.




Re: Rant after trying Rust a bit

2015-07-23 Thread Tobias Müller via Digitalmars-d
jmh530 john.michael.h...@gmail.com wrote: 
 I feel like it's hard to separate borrowing from Rust's variety of
 pointers ( is borrowed pointer, ~ is for unique pointer, @ is for managed 
 pointer).

That's actually very outdated information. Two of the four pointer types
(,@,~ and *) were ditched in favor of library solutions.

*T: Raw pointers are still the same
T: is now called reference, not borrowed pointer
~T: Is now BoxT
@T: Is now RcT (and possibly GcT although a GC was never implemented)
 Tobi


Re: Rant after trying Rust a bit

2015-07-23 Thread Dicebot via Digitalmars-d

On Thursday, 23 July 2015 at 19:55:30 UTC, Walter Bright wrote:

On 7/23/2015 8:03 AM, Dicebot wrote:
At the same time one HUGE deal breaker with rust traits that 
rarely gets
mentioned is the fact that they are both constraints and 
interfaces at the same

time:

// this is template constraint, it will generate new `foo` 
symbol for each new T

fn foo T : InputRange (range : T)

// this use the very same trait definition but creates fat 
pointer on demand

with simplistic dispatch table
fn foo (range : InputRange)

It kills all the necessity for hacks like RangeObject and is 
quite a salvation
once you get to defining dynamic shared libraries with stable 
ABI.


This is probably my most loved feature of Rust.


D interface types also produce the simplistic dispatch table, 
and if you make them extern(C++) they don't need a RangeObject. 
I know it isn't as convenient as what you describe above, but 
it can be pressed into service.


I am not sure how it applies. My point was about the fact that 
`isInputRange` and `InputRangeObject` are the same entities in 
Rust, simply interpreted differently by compiler depending on 
usage context.


This is important because you normally want to design your 
application in terms of template constraints and structs to get 
most out of inlining and optimization. However, to define stable 
ABI for shared libraries, the very same interfaces need to be 
wrapped in runtime polymorphism.


Closest thing in D would be to define traits as interfaces and 
use code like this:


void foo(T)()
if (  (is(T == struct) || is(T == class))
Matches!(T, Interface)
)
{ }

where `Matches` is a template helper that statically iterates 
method list of interface and looks for matching methods in T. 
However, making it built-in feels really convenient in Rust:


- considerably less function declaration visual noise
- much better error messages: trying to use methods of T not 
defined by a trait will result in compile-time error even without 
instantiating the template


Re: Rant after trying Rust a bit

2015-07-23 Thread Walter Bright via Digitalmars-d

On 7/23/2015 7:49 AM, ixid wrote:

If we had a clean sheet wouldn't it be better to have if return a value and
ditch ternary?


Then we'd start seeing code like:

x = 45 + if (y == 10) { while (i--) z += call(i); z; } else { switch (x) { 
case 6: foo(); y; } + tan(z);


I.e. the embedding of arbitrary statements within expressions. We already have 
some of this with embedded anonymous lambda support, and I've discovered one 
needs to be very careful in formatting it to not wind up with an awful 
unreadable mess.


So I'd be really reluctant to continue down that path.

Now, if you want to disallow { } within the embedded if statement, then the 
proposal becomes nothing more than:


? = if
: = else

which is a potayto potahto thing.

I agree that trivial syntax issues actually do matter, but having used ?: a lot, 
I have a hard time seeing embeddable if-else as a real improvement, in fact I 
find it more than a little jarring to see.


Re: Rant after trying Rust a bit

2015-07-23 Thread Ziad Hatahet via Digitalmars-d
On Thu, Jul 23, 2015 at 8:41 AM, Jonathan M Davis via Digitalmars-d 
digitalmars-d@puremagic.com wrote:

 Maybe, but the ternary operator is a lot less verbose


The ternary operator becomes much harder to read the moment you have more
than the simple if/else case. As it was mentioned elsewhere on this thread,
you can do the following in Scala:

val x = if (condition_1) 1
   else if (condition_2) 2
   else if (condition_3) 3
   else 4

Having expressions be built-in extends beyond the simple if/else case,
which can be emulated with the ternary operator as you said. You can assign
the result of match expressions for instance, or the result of scoped
blocks, .e.g.

val x = {
val ys = foo()
ys.map(...).filter(...).exists(...)
}

, and from some other comments in this thread, it sounds like the way they
 implemented it in Rust forces you to use braces for single line statements,
 which would be a _huge_ downside IMHO.


On the other hand, Rust does not require parenthesis around if conditions:

let x = if some_condition { 1 } else { 2 }


 I'm inclined to think that it would need a use case that's a lot more
 compelling than if-else chains to be worth it.


I provided examples above.



--
Ziad


Re: Rant after trying Rust a bit

2015-07-23 Thread H. S. Teoh via Digitalmars-d
On Thu, Jul 23, 2015 at 08:50:55PM +, Vlad Levenfeld via Digitalmars-d 
wrote:
 On Thursday, 23 July 2015 at 20:40:17 UTC, Walter Bright wrote:
 On 7/23/2015 12:50 PM, H. S. Teoh via Digitalmars-d wrote:
 That assumes the template author is diligent (foolhardy?) enough to
 write unittests that cover all possible instantiations...
 
 No, only each branch of the template code must be instantiated, not
 every possible instantiation. And we have a tool to help with that:
 -cov
 
 Does anyone believe it is a good practice to ship template code that
 has never been instantiated?
 
 I dunno about good practices but I have some use cases.
 
 I write a bunch of zero-parameter template methods and then pass them
 into a Match template which attempts to instantiate each of them in
 turn, settling on the first one which does compile. So the methods
 basically form a list of preferred implementation of functionality
 X. All but one winds up uninstantiated.
[...]

But don't you still have to test each template, to make sure they
compile when they're supposed to?


T

-- 
Without geometry, life would be pointless. -- VS


Overloading Based on Constraints

2015-07-23 Thread jmh530 via Digitalmars-d-learn

I was looking at
http://dlang.org/concepts.html
where it discusses overloading templates based on constraints. I 
wanted to try to overload a template function with another 
version that does everything in place. So basically, one has a 
return and the other doesn't. However, when I run the code, it 
only calls the first function. The second one is ignored. I tried 
a number of adjustments, but the only thing that worked is to 
re-name the function something else, remove the U's, and just 
have it be a void function.



import std.stdio : writeln;
import std.traits;

T test(T)(T x)
if (isNumeric!(T))
{
writeln(calling test without void);
T y = x;
y += 1;
return y;
}

U test(T, U)(ref T x)
if (isNumeric!(T)  is(U == void))
{
writeln(calling test with void);
x += 2;
}

void main()
{
int a = 1;
int b = test(a);
writeln(b);
int c = b;
test(c);
writeln(c);
}


Re: Rant after trying Rust a bit

2015-07-23 Thread Justin Whear via Digitalmars-d
On Thu, 23 Jul 2015 13:46:16 -0700, Walter Bright wrote:
 like implicit declaration of variables.

Trigger warning needed!


Re: Rant after trying Rust a bit

2015-07-23 Thread Dicebot via Digitalmars-d

On Thursday, 23 July 2015 at 22:10:11 UTC, H. S. Teoh wrote:
OK, I jumped into the middle of this discussion so probably I'm 
speaking totally out of context...


This is exactly one major advantage of Rust traits I have been 
trying to explain, thanks for putting it up in much more 
understandable way :)


Re: dmd 2.068, 2.069, 2.0xx Evil Plan going forward

2015-07-23 Thread ketmar via Digitalmars-d
On Mon, 20 Jul 2015 21:49:00 +, Martin Nowak wrote:

 We have a PR from Kenji, that fixes 313+314.
 https://github.com/D-Programming-Language/dmd/pull/3407
 
 It's a major change of the import system, so it needs a thorough review
 and we also need to mitigate the code breakage impact of this change.

at least for phobos, it breaks almost nothing. and where it does some 
breckage, it identifies invalid code that relies on import bugs anyway.

the same with some projects i tried to build, like deadcode, for example 
(which is fairly big): this PR breaks only invalid code, i.e. code that 
relies on current buggy import and should be fixed anyway.

yet, there is surprisingly small amount of such code, literally along 10 
or so patches for phobos (and that number constantly decreases), and not 
much more for deadcode (but for deadcode the fixes was a little more 
complicated, as i have to add some qualifiers in some modules).

i'm using DMD with that patch incorporated for more a year now, and got 
no problems with code that doesn't rely on import bugs.

signature.asc
Description: PGP signature


Re: casting away const and then mutating

2015-07-23 Thread Steven Schveighoffer via Digitalmars-d

On 7/23/15 2:43 PM, anonymous wrote:

Steven disagrees and thinks that there are cases where it's ok. Namely,
this simple case would be ok:


int x;
const int *y = x;
*(cast(int *)y) = 5;



Yes, IMO, this should simply work and be consistent. The compiler could 
use willful ignorance to assume x is still 0, but I find that to be 
counterproductive. It would have to implement flow analysis to determine 
that y must point at x, and then simply ignore the assignment during 
that analysis.


I'll note that the reason I want to allow this, is because we have a 
case where the same implementation must be used for the const and 
mutable version of the function, but the return value is a template that 
varies on constancy. Therefore, you necessarily need 2 function 
definitions -- the compiler isn't smart enough (or maybe it's too 
smart?) to use inout(T) as a template parameter to the Range struct, and 
auto convert that back on return.


The nice thing about inout, is the compiler guarantees one 
implementation of the function, and the implementation will guarantee 
const is preserved. But on returning, the function puts the data back to 
the way it was. That's exactly what we want.


In this case, we can't use inout. So we have to cast (or alternatively, 
copy-paste implementation) one result to the other.


My opinion is, we should execute the implementation as if the object 
were const, and then cast back to mutable if we are using the mutable 
entry point. This allows the compiler to check the function 
implementation for const-correctness, vs. the other suggestion: casting 
the const object to a mutable one and then hoping the mutable function 
implementation is const-correct without compiler help.


The proposed usage of casting also does not mutate the data in the 
function that casts. It receives in a mutable object, and it outputs a 
reference to the mutable object. The compiler would have to go through 
great lengths to see that the source of the mutable range it's receiving 
comes from a const range, and then ignore the type system in order to 
elide a reloading of something that is miniscule compared to the 
function call itself.




As I understand him, he's arguing that since the data is mutable, and
since no function boundaries are crossed, compilers should not be
allowed to do anything but the obvious with that code.

I think we've exchanged all arguments we have, yet no one has been
convinced by the other side.

We've found the language spec to be a bit sparse on this. All I could
find is essentially you can't mutate through a const reference [1],
but no mention of if/when it's ok to cast a const reference to a mutable
one (and then mutate).


Note that it does specifically mention immutable cannot be cast away and 
then modified (on that same page, see Removing Immutable With A Cast). 
It does not mention const, I assume that is on purpose.


-Steve


Re: Rant after trying Rust a bit

2015-07-23 Thread Walter Bright via Digitalmars-d

On 7/23/2015 2:22 AM, Chris wrote:

It's one thing to list nice features, and it's another thing to use these
features in production code. As a code base grows, the limitations become more
and more obvious. Thus, I would be wary of jumping to conclusions or hailing new
features as game changers, before having tested them thoroughly in the real
world. Only time will tell, if something really scales. I've learned to wait and
see what people with experience report after a year or two of using a given
language.


It is very true that many features look good on paper, and only time and 
experience reveals the truth. There are a lot of programming features that fail 
the second clause - like implicit declaration of variables.


Re: Rant after trying Rust a bit

2015-07-23 Thread Adam D. Ruppe via Digitalmars-d

On Thursday, 23 July 2015 at 20:48:34 UTC, Ziad Hatahet wrote:
The ternary operator becomes much harder to read the moment you 
have more than the simple if/else case.


I think it is actually kinda pretty:

auto x =   (condition_1) ? 1
 : (condition_2) ? 2
 : (condition_3) ? 3
 : 4;


val x = {
val ys = foo()
ys.map(...).filter(...).exists(...)
}


auto x = {
  auto ys = foo();
  return ys.map(...).filter(...).exists(...);
}();


Before you get too worried about the (), I'd point out that this 
is a very common pattern in Javascript (for like everything...) 
and while everybody hates JS, most every uses it too; this patten 
is good enough for usefulness.


(or for that you could prolly just write foo().map()... directly 
but i get your point)


Re: Silicon Valley D Meetup July 2015

2015-07-23 Thread Ali Çehreli via Digitalmars-d-announce

On 07/23/2015 04:52 AM, Ali Çehreli wrote:


   http://www.meetup.com/D-Lang-Silicon-Valley/events/224003042/


Bonus item for the meeting: The first proof copy of Programming in D, 
which arrived today. You can touch and smell it if you come to the 
meeting! :p


Ali



Re: Rant after trying Rust a bit

2015-07-23 Thread Ziad Hatahet via Digitalmars-d
On Thu, Jul 23, 2015 at 2:00 PM, Adam D. Ruppe via Digitalmars-d 
digitalmars-d@puremagic.com wrote:

 I think it is actually kinda pretty:


What about:

int median(int a, int b, int c) {
return (ab) ? (bc) ? b : (ac) ? c : a : (ac) ? a : (bc) ? c : b;
}

vs.

def median(a: Int, b: Int, c: Int) =
  if (a  b) {
if (b  c) b
else if (a  c) c
else a
  }
  else if (a  c) a
  else if (b  c) c
  else b


Before you get too worried about the (), I'd point out that this is a very
 common pattern in Javascript (for like everything...) and while everybody
 hates JS, most every uses it too; this patten is good enough for usefulness.


Is the compiler always able to always optimize out the function call by
inlining it, as would be the case with a scope?


Re: Rant after trying Rust a bit

2015-07-23 Thread Andrei Alexandrescu via Digitalmars-d

On 7/23/15 5:07 AM, Walter Bright wrote:

On 7/22/2015 11:47 PM, Jacob Carlborg wrote:

On 2015-07-22 20:47, simendsjo wrote:


Traits
--
I think the ability to express an interface without buying into
inheritance is the right move. The alternative in D is specifying the
behavior as a template


I completely agree and don't really like the approach D has
implemented template
constraints. Yeah I know, Andrei will destroy this :)


Consider that template constraints can be arbitrarily complex, and can
even check behavior, not just a list of function signatures ANDed
together. Turns out many constraints in Phobos are of the form (A || B),
not just (A  B).


Agreed. And that's just scratching the surface.

Serious question: how do you express in Rust that a type implements one 
trait or another, then figure out statically which?



  and verifying the contract in a unittest for the type.

I am a bit puzzled by the notion of shipping template code that has
never been instantiated as being a positive thing. This has also turned
up in the C++ static_if discussions.


This is easy to understand. Weeding out uncovered code during 
compilation is a central feature of C++ concepts. Admitting you actually 
never want to do that would be a major blow.



Andrei



Re: Rant after trying Rust a bit

2015-07-23 Thread Jacob Carlborg via Digitalmars-d

On 2015-07-23 09:45, Joakim wrote:


That's because it has its own top-level link in the sidebar, More
libraries.  You could argue that's not the best description of dub, but
it's certainly prominently placed.


Ah, right, I completely forgot about that. But one could expect the 
actual tool be available to download from dlang.org as well.


--
/Jacob Carlborg


Re: Rant after trying Rust a bit

2015-07-23 Thread Jacob Carlborg via Digitalmars-d
On 2015-07-23 12:56, Marc =?UTF-8?B?U2Now7x0eiI=?= schue...@gmx.net 
wrote:



Expressions
---
This probably also falls in the too late category, but
statements-as-expressions is really nice. `auto a = if ...` - why not?


Generally I find this an elegant concept. But in Rust, it leads to the
distinction between expressions terminated with `;` and those without,
which in turn makes it necessary to use braces even if you have only one
statement or expression. This is something that I dislike very much.


In Scala there's no problem. No semicolons are required a no braces.

--
/Jacob Carlborg


Re: Converting uint[] slice to string for the purpose of hashing?

2015-07-23 Thread Jonathan M Davis via Digitalmars-d-learn
On Thursday, July 23, 2015 12:56:13 Temtaime via Digitalmars-d-learn wrote:
 All types are hashable and for your own structs and classes you
 can redefine opHash

It's toHash, actually, but yeah.

- Jonathan M Davis



Re: How to get *32mscoff libraries for phobos?

2015-07-23 Thread Taylor Hillegeist via Digitalmars-d-learn

On Thursday, 23 July 2015 at 01:43:56 UTC, Mike Parker wrote:

On Thursday, 23 July 2015 at 01:39:05 UTC, Mike Parker wrote:


post at [1] where Rainer shared the relevant bits of a batch


Gah, hate it when I forget the links.

[1] http://forum.dlang.org/post/m456t5$2jc4$1...@digitalmars.com


IT worked! Placing this Batch file in the dmd2\src Folder.

-- BEGIN FILE: BUILD.bat
set dm_make=C:\D\dmd2\windows\bin\make.exe
set DMD=C:\D\dmd2\windows\bin\dmd.exe
set cl32=C:\Program Files (x86)\Microsoft Visual Studio 
12.0\VC\bin\cl.exe
set ar32=C:\Program Files (x86)\Microsoft Visual Studio 
12.0\VC\bin\lib.exe


cd druntime
del /q errno_c.obj complex.obj
%dm_make% -f win64.mak DMD=%DMD% MODEL=32mscoff CC=\%cl32%\
if errorlevel 1 goto xit
cd ..

cd phobos
cd etc\c\zlib
%dm_make% -f win64.mak clean
cd ..\..\..
%dm_make% -f win64.mak DMD=%DMD% MODEL=32mscoff CC=\%cl32%\ 
MAKE=%dm_make% AR=\%ar32%\

if errorlevel 1 goto xit
cd ..

-- END FILE

I had to reinstall dmd (I think I messed up my dmd2\src folder 
somehow)

I used visual studio 2013 community edition.

SO. Where do i put it now that its built? I placed it in the 
dmd2\windows\lib and i still got LINK : fatal error LNK1104: 
cannot open file 'phobos32mscoff.lib'


... perhaps i need to edit the sc.ini file...


Re: Rant after trying Rust a bit

2015-07-23 Thread Dicebot via Digitalmars-d
On Thursday, 23 July 2015 at 14:15:30 UTC, Andrei Alexandrescu 
wrote:

On 7/23/15 5:07 AM, Walter Bright wrote:

On 7/22/2015 11:47 PM, Jacob Carlborg wrote:

On 2015-07-22 20:47, simendsjo wrote:


Traits
--
I think the ability to express an interface without buying 
into
inheritance is the right move. The alternative in D is 
specifying the

behavior as a template


I completely agree and don't really like the approach D has
implemented template
constraints. Yeah I know, Andrei will destroy this :)


Consider that template constraints can be arbitrarily complex, 
and can
even check behavior, not just a list of function signatures 
ANDed
together. Turns out many constraints in Phobos are of the form 
(A || B),

not just (A  B).


Agreed. And that's just scratching the surface.


It is definitely a big issue for designing more advanced generic 
libraries and one of my major issues with Rust but you need to 
realize that vast majority of application domain usage of such 
constraints is simply ensuring list of methods. You may be biased 
by too much standard library development ;)


At the same time one HUGE deal breaker with rust traits that 
rarely gets mentioned is the fact that they are both constraints 
and interfaces at the same time:


// this is template constraint, it will generate new `foo` symbol 
for each new T

fn foo T : InputRange (range : T)

// this use the very same trait definition but creates fat 
pointer on demand with simplistic dispatch table

fn foo (range : InputRange)

It kills all the necessity for hacks like RangeObject and is 
quite a salvation once you get to defining dynamic shared 
libraries with stable ABI.


This is probably my most loved feature of Rust.

Serious question: how do you express in Rust that a type 
implements one trait or another, then figure out statically 
which?


As far as I understand current idiomatics, you don't. Code that 
tries to use functions that are not ensured by trait will simply 
not compile and for any complicated generic programming one is 
supposed to use macros. Rust does not have templates, only 
trait-restricted generics.


I find it terribly unproductive but it seems to appeal to certain 
developer mindset, primarily the ones that associate templates 
with C++ templates.


Re: Rant after trying Rust a bit

2015-07-23 Thread Andrei Alexandrescu via Digitalmars-d
On 7/23/15 6:56 AM, Marc =?UTF-8?B?U2Now7x0eiI=?= schue...@gmx.net 
wrote:

Traits
--
I think the ability to express an interface without buying into
inheritance is the right move. The alternative in D is specifying the
behavior as a template and verifying the contract in a unittest for
the type.


Not only that, but Rust does so much more with traits, e.g. closures.
They seem to be a simple, yet powerful concept, that a big part of the
language is built on.

http://blog.rust-lang.org/2015/05/11/traits.html

On the other hand, it is extremely restrictive in contrast to `static
if()` and template constraints. D's approach is a lot more expressive
and - at least for me - intuitive.


Thanks for the link, good quick read to get the overview of Rust's 
traits feature. It's ingenious because it integrates static and dynamic 
dispatch.


For dynamic dispatch, traits are better than interfaces - more flexible, 
better informed. For static dispatch, they don't hold a candle to D's 
constraints. This is important because dynamic dispatch is more of a 
cut-and-dried matter, whereas static dispatch is where it's at.


For static dispatch I think D's template constraints are quite a lot 
better; they have a lot more power and offer a lot more to promise. They 
are an out-of-the-box solution that's a bit unwieldy because it's new 
enough to not yet have established idioms. In contrast, traits come from 
straight within the box.


From a language perspective, it is my belief that Design by 
Introspection (enabled collectively by template constraints, 
introspection, compile-time function evaluation, and static if) is the 
one crushing advantage that D has over any competitor. Things like 
range-based algorithms are good but easy to copy and adapt.


The faster we manage to get creative with Design by Introspection and 
describe it, systematize it, create compelling designs with it, the 
quicker will D win the minds and hearts of people.


There's a lot at stake here. An question often asked by would-be users 
is What does D offer that's special? or What does D offer over 
language Xyz? As we all know there are many answers to that. Maybe too 
many. Now I know what the answer is: Design by Introspection.



Andrei



Re: Rant after trying Rust a bit

2015-07-23 Thread Jacob Carlborg via Digitalmars-d

On 2015-07-23 11:07, Walter Bright wrote:


Consider that template constraints can be arbitrarily complex, and can
even check behavior, not just a list of function signatures ANDed
together. Turns out many constraints in Phobos are of the form (A || B),
not just (A  B).


I know that is possible, but in most cases it's only a list of function 
signatures that is needed.


--
/Jacob Carlborg


Re: Wait, what? What is AliasSeq?

2015-07-23 Thread Timon Gehr via Digitalmars-d

On 07/23/2015 10:42 AM, deadalnix wrote:

On Wednesday, 22 July 2015 at 04:44:48 UTC, Timon Gehr wrote:

On 07/22/2015 12:53 AM, deadalnix wrote:

On Tuesday, 21 July 2015 at 21:26:24 UTC, Daniel N wrote:

On Tuesday, 21 July 2015 at 16:54:54 UTC, H. S. Teoh wrote:


Because, among other things, it auto-expands.


T


1) .tupleof auto-expands and changing it at this point would cause
epic breakage.(I also see no reason to.)



This is actually a very good point. First of, tupleof does not return a
TypeTuple, but they have something similar in nature.


What's the difference? There shouldn't be any.


You can't put runtime values into the first one, you can into the second
one.


It should be just a bunch of aliases to the field members, which have 
runtime values.


Anyway, I figured out the difference:

alias Seq(T...)=T;

void main(){
struct S{ int x,y,z; }
S s;
alias a=s.tupleof; // error
alias b=Seq!(s.x,s.y,s.z); // ok
alias c=Seq!(s.tupleof); // ok
typeof(s.tupleof) x;
alias d=x; // ok
}


Wtf.


Re: Rant after trying Rust a bit

2015-07-23 Thread jmh530 via Digitalmars-d
On Thursday, 23 July 2015 at 13:30:49 UTC, Andrei Alexandrescu 
wrote:
At the end of the day everything-is-an-expression is natural 
for functional languages, but doesn't seem it makes a large 
difference to an imperative language.




Good points.




Re: Experience upgrading template code from 2.065 to 2.067

2015-07-23 Thread simendsjo via Digitalmars-d

On Thursday, 23 July 2015 at 13:20:32 UTC, Nicholas Wilson wrote:

On Wednesday, 22 July 2015 at 15:50:13 UTC, simendsjo wrote:


// 1
template Tmlp(T) {}
// 2
template Tmpl(alias T) {}


I'm assuming thats a typo


Yes. I just wrote the code in the post without trying to compile 
it. I'm not as good at caching typos as the compiler.


Re: Sending an immutable object to a thread

2015-07-23 Thread Frank Pagliughi via Digitalmars-d-learn

On Thursday, 23 July 2015 at 09:05:12 UTC, Marc Schütz wrote:


It is not safe, but for a different reason: `mt` is already a 
_reference_ to the actual object (that's how classes behave in 
D). This reference is located in a register or on the stack, 
and `mt` is therefore a pointer into the stack.


It's illegal to return that pointer from the function, because 
it will become invalid once the function is left. Fortunately, 
the compiler can detect simple cases like this one, and will 
refuse to compile it:


Object* foo() {
Object o;
return o;
}

xx.d(3): Error: escaping reference to local o


Very interesting. You see, I am trying to resolve the distinction 
be a value type and a reference type in D.


If Object were declared as a struct, this would make sense to 
me. The object would be created on the stack as a temporary, and 
it would disappear when the function exited. So returning a 
pointer to it would be a very, very bad thing.


But a class object is allocated in the GC heap. I would have 
guessed that, since a class reference is just essentially a 
hidden pointer, that the address-of operator '' for a class 
object would return the address into the heap... not the address 
of the reference itself! Just a little syntactic sugar.


But that's not the case. I thought this was true:
  class MyThing { ... };

  MyThing a = new MyThing,
  b = a;
  assert(a == b);  // Fails

In a weird way, that makes total sense to me, and no sense at all.

So, passing a pointer to a stack-based reference from one thread 
is another is not necessarily a good thing to do, as the original 
reference might disappear while the thread is using it.


Is there a way to get the address of the actual heap object from 
a class reference? Or am I drifting to far into the realm of 
unsafe.


This all goes back to my original question of passing an 
immutable object from one thread to another. It is simple with 
arrays, since there is a clear distinction between the array 
reference and its contents. You can easily create a mutable 
reference to immutable contents with an array.


But it seems rather convoluted with class objects.

So, in the end, it seems best to send a rebindable reference to 
the other thread, and perhaps hide the mild ugliness behind a 
library API that takes an immutable object and then sends the 
rebindable version, like:


  void send_message(Tid tid, immutable(Message) msg) {
send(tid, thisTid(), rebindable(msg));
  }

That seems easy enough.

Thanks much for all the help.



Re: Rant after trying Rust a bit

2015-07-23 Thread ixid via Digitalmars-d

On Thursday, 23 July 2015 at 13:33:43 UTC, Adam D. Ruppe wrote:

On Wednesday, 22 July 2015 at 21:04:57 UTC, simendsjo wrote:
:) The example was written to save space. I recon you 
understand what I mean.


Yeah, but the if/else is one of the most useful examples of it, 
and is covered by ?:, so the whole thing becomes less 
compelling then.


The other places where I've used it in languages that support 
it are little blocks crammed into a line and sometimes 
exception grabbing... but still, the value isn't that great.


If we had a clean sheet wouldn't it be better to have if return a 
value and ditch ternary?


Re: C bindings: typedef struct conflicts with method

2015-07-23 Thread Jacob Carlborg via Digitalmars-d-learn

On 2015-07-23 03:57, Mike Parker wrote:


In your case, rd_kafka_metadata is the name of the struct, but in C
instances would need to be declared like so:

struct rd_kafka_metadata instance;


Since the struct is declared directly in the typedef, is the struct name 
actually available?


--
/Jacob Carlborg


Re: New D book available for pre-order: D Web Development

2015-07-23 Thread Kai Nacke via Digitalmars-d-announce

On Wednesday, 22 July 2015 at 21:43:09 UTC, notna wrote:

On Wednesday, 22 July 2015 at 21:19:20 UTC, notna wrote:

On Wednesday, 22 July 2015 at 15:29:20 UTC, Kai Nacke wrote:


As I have all the books/hardcopies from 
http://wiki.dlang.org/Books,


Added you book to the Wiki. Hope you and your publisher don't 
mind ;)


Thank you very much!

Regards,
Kai


Re: Learning D Available for Pre-Order

2015-07-23 Thread Kai Nacke via Digitalmars-d-announce

On Tuesday, 23 June 2015 at 14:47:03 UTC, Mike Parker wrote:
The project that has taken me away from Derelict since the end 
of February is now available for pre-order at [1]. I'm


[1] https://www.packtpub.com/application-development/learning-d


Great work, for sure I'll buy a copy!

I missed your book on http://wiki.dlang.org/Books and added it.

Regards,
Kai


Re: New D book available for pre-order: D Web Development

2015-07-23 Thread Kai Nacke via Digitalmars-d-announce

On Wednesday, 22 July 2015 at 15:46:09 UTC, Sönke Ludwig wrote:
Nice! I had heard of the plans for this book, but didn't have 
time to actively contribute. But give me a ping if you need 
some additional review. I can't promise that I'll be fast, but 
I'll do my best!


Great offer! I'll contact you. Thanks!

Regards,
Kai


Re: Rant after trying Rust a bit

2015-07-23 Thread jmh530 via Digitalmars-d

On Wednesday, 22 July 2015 at 23:25:56 UTC, jmh530 wrote:


If traits were deemed important enough to add to D, I would 
suggest just extending interfaces so that they have inheritance 
and can be easily used in template constraints.




I think I had a few misconception about D interfaces. The 
documentation does not say anything about interface inheritance, 
but it seems to work when I tried it. It definitely seems weird 
that this behavior isn't mentioned anywhere.


Also, the use of static* or final methods in the interface can 
allow default implementations of methods. This is something that 
can be done with Scala traits. I feel like this isn't 
documentated as well as it could be. A weirder thing is that when 
I tried to test that static and final methods could not 
overridden (which is allowed in Scala), it seemed like they were 
getting overridden. The tricky part is that I had been using 
something like final foo() { } instead of final void foo() { }. 
For some reason you can override the first, but not the second.


So really, I guess the D interfaces are more powerful than I had 
thought. Only downside is that they only work for classes.


* I feel like these also aren't particularly described well in 
the documentation either.


Re: Silicon Valley D Meetup July 2015

2015-07-23 Thread Andrei Alexandrescu via Digitalmars-d-announce

On 7/23/15 7:52 AM, Ali Çehreli wrote:

Thanks to Chris Jacobi, we may have a permanent venue: Hacker Dojo in
Mountain View:

   http://www.meetup.com/D-Lang-Silicon-Valley/events/224003042/

This will be a social get together with an open agenda. Bring your
lightning talk and any other topic with or without a slide deck.

Ali


https://twitter.com/D_Programming/status/624229374603169792

https://www.facebook.com/dlang.org/posts/1107571949256485

I encourage everyone in the community to boost such announcements to 
social outlets like Twitter and Facebook.



Andrei



Re: Rant after trying Rust a bit

2015-07-23 Thread via Digitalmars-d
On Thursday, 23 July 2015 at 13:30:49 UTC, Andrei Alexandrescu 
wrote:
I used to be quite jazzed about the everything-is-an-expression 
mantra, but it's not all great.


1. Inferring function return types when everything is an 
expression (i.e. last expression there is the return type) may 
yield WAT results.


2. Defining a result type for loops is awkward.

At the end of the day everything-is-an-expression is natural 
for functional languages, but doesn't seem it makes a large 
difference to an imperative language.


It also works well for Ruby with its dynamic typing. Function 
return types don't matter, of course, and for loops you just use 
whatever the last executed expression happens to be.


Anyway, in D we have delegate literals, for the rare cases where 
it's useful.


Re: Rant after trying Rust a bit

2015-07-23 Thread shannon mackey via Digitalmars-d

On Thursday, 23 July 2015 at 15:37:24 UTC, shannon mackey wrote:
 On Wednesday, 22 July 2015 at 19:41:16 UTC, Jack Stouffer 
wrote:

On Wednesday, 22 July 2015 at 20:43:04 UTC, simendsjo wrote:

On Wednesday, 22 July 2015 at 18:47:33 UTC, simendsjo wrote:

[...]


Don't quite know what you mean here.


When everything is an expressions, you can write things like
auto a = if(e) c else d;

In D you have to write
type a = invalid_value;
if(e) a = c;
else  a = d;
assert(a != invalid_value);



I frequently do things like this in D:

auto good = ( true == true ) ? true : false;

which looks a lot like your Rust example?  Is that not what you 
were looking for?


Sorry, I didn't read to the end of the thread, and this has been 
covered many times.


Re: Rant after trying Rust a bit

2015-07-23 Thread Jonathan M Davis via Digitalmars-d

On Thursday, 23 July 2015 at 14:49:55 UTC, ixid wrote:

On Thursday, 23 July 2015 at 13:33:43 UTC, Adam D. Ruppe wrote:

On Wednesday, 22 July 2015 at 21:04:57 UTC, simendsjo wrote:
:) The example was written to save space. I recon you 
understand what I mean.


Yeah, but the if/else is one of the most useful examples of 
it, and is covered by ?:, so the whole thing becomes less 
compelling then.


The other places where I've used it in languages that support 
it are little blocks crammed into a line and sometimes 
exception grabbing... but still, the value isn't that great.


If we had a clean sheet wouldn't it be better to have if return 
a value and ditch ternary?


Maybe, but the ternary operator is a lot less verbose, and from 
some other comments in this thread, it sounds like the way they 
implemented it in Rust forces you to use braces for single line 
statements, which would be a _huge_ downside IMHO. I'm inclined 
to think that it would need a use case that's a lot more 
compelling than if-else chains to be worth it.


- Jonathan M Davis


Re: Wait, what? What is AliasSeq?

2015-07-23 Thread Jonathan M Davis via Digitalmars-d

On Thursday, 23 July 2015 at 15:03:24 UTC, Timon Gehr wrote:

On 07/23/2015 10:42 AM, deadalnix wrote:

On Wednesday, 22 July 2015 at 04:44:48 UTC, Timon Gehr wrote:

On 07/22/2015 12:53 AM, deadalnix wrote:

On Tuesday, 21 July 2015 at 21:26:24 UTC, Daniel N wrote:

On Tuesday, 21 July 2015 at 16:54:54 UTC, H. S. Teoh wrote:


Because, among other things, it auto-expands.


T


1) .tupleof auto-expands and changing it at this point 
would cause

epic breakage.(I also see no reason to.)



This is actually a very good point. First of, tupleof does 
not return a

TypeTuple, but they have something similar in nature.


What's the difference? There shouldn't be any.


You can't put runtime values into the first one, you can into 
the second

one.


It should be just a bunch of aliases to the field members, 
which have runtime values.


Anyway, I figured out the difference:

alias Seq(T...)=T;

void main(){
struct S{ int x,y,z; }
S s;
alias a=s.tupleof; // error
alias b=Seq!(s.x,s.y,s.z); // ok
alias c=Seq!(s.tupleof); // ok
typeof(s.tupleof) x;
alias d=x; // ok
}


Wtf.


That definitely makes it seem like they _should_ be the same, 
though they clearly aren't. That may just be part of the issues 
related to alias not being consistent that David was bringing up 
before though. Regardless, I'm inclined to agree that what 
tupleof gives you should just be a TypeTuple/AliasSeq/whatever, 
though it would be nice to rename it once we actually settle on a 
name for the library construct.


- Jonathan M Davis


  1   2   >