Re: D vs Rust: function signatures

2014-04-30 Thread Paulo Pinto via Digitalmars-d
On Wednesday, 30 April 2014 at 01:49:01 UTC, Nick Sabalausky 
wrote:

On 4/29/2014 9:38 PM, Narrator wrote:


fn map'r, B(self, f: |A|: 'r - B) - Map'r, A, B, Self



That looks like line noise.


Not if one is used to ML languages. Beauty is in the eyes of the 
beholder. :)


Re: D vs Rust: function signatures

2014-04-30 Thread John Colvin via Digitalmars-d

On Wednesday, 30 April 2014 at 01:38:46 UTC, Narrator wrote:
The unbelievable amount of time and energy that's been spent 
discussing the smallest syntax, you would think that D would, 
at the very least, have better looking function signatures, but 
it doesn't.


auto zip(Ranges...)(Ranges ranges) if (Ranges.length  
allSatisfy!(isInputRange, Ranges));
auto zip(Ranges...)(StoppingPolicy sp, Ranges ranges) if 
(Ranges.length  allSatisfy!(isInputRange, Ranges));


fn zipB, U: IteratorB(self, other: U) - ZipSelf, U


auto chain(Ranges...)(Ranges rs) if (Ranges.length  0  
allSatisfy!(isInputRange, staticMap!(Unqual, Ranges))  
!is(CommonType!(staticMap!(ElementType, staticMap!(Unqual, 
Ranges))) == void));


fn chainU: IteratorA(self, other: U) - ChainSelf, U


template map(fun...) if (fun.length = 1)
auto map(Range)(Range r) if (isInputRange!(Unqual!Range));

fn map'r, B(self, f: |A|: 'r - B) - Map'r, A, B, Self


template filter(alias pred) if (is(typeof(unaryFun!pred)))
auto filter(Range)(Range rs) if (isInputRange!(Unqual!Range));

fn filter'r(self, predicate: |A|: 'r - bool) - Filter'r, 
A, Self



MaxType!(T1, T2, T) max(T1, T2, T...)(T1 a, T2 b, T xs) if 
(is(typeof(a  b)));


pub fn maxT: TotalOrd(v1: T, v2: T) - T


I don't think a single one of those signatures are equivalent.

Also, bear in mind that those if() constraints contain arbitrary 
code (as long as it can be evaluated at compile-time), so they 
are very flexible.


Re: D vs Rust: function signatures

2014-04-30 Thread bearophile via Digitalmars-d

Nick Sabalausky:

On 4/29/2014 9:38 PM, Narrator wrote:


fn map'r, B(self, f: |A|: 'r - B) - Map'r, A, B, Self



That looks like line noise.


In D there is a lambda syntax:

auto F = (in int x) = x ^^ 2;
void main() {
int y;
auto G = (in int x) = x + y;
pragma(msg, typeof(F));
pragma(msg, typeof(G));
}


That code contains the types (the pragma output is a little 
different):


int function(in int) pure nothrow @nogc @safe
int delegate(in int) nothrow @nogc @safe


An alternative syntax can be similar to the way you write D 
lamdas:


(in int) pure nothrow @nogc @safe = int
(in int) nothrow @nogc @safe == int

(I am not suggesting to introduce this syntax to D because its an 
useless duplication, but I find it a bit better.)


Bye,
bearophile


Re: D vs Rust: function signatures

2014-04-30 Thread Nick Sabalausky via Digitalmars-d

On 4/30/2014 3:26 AM, Paulo Pinto wrote:

On Wednesday, 30 April 2014 at 01:49:01 UTC, Nick Sabalausky wrote:

On 4/29/2014 9:38 PM, Narrator wrote:


fn map'r, B(self, f: |A|: 'r - B) - Map'r, A, B, Self



That looks like line noise.


Not if one is used to ML languages. Beauty is in the eyes of the
beholder. :)


FWIW, I do agree (Not that I know much about ML-family). The ...to me 
was carelessly left as implied. ;)




Re: D vs Rust: function signatures

2014-04-30 Thread Timon Gehr via Digitalmars-d

On 04/30/2014 04:04 AM, Vladimir Panteleev wrote:


fn map'r, B(self, f: |A|: 'r - B) - Map'r, A, B, Self


Same as points 1 and 3 above (D's version allows specifying multiple
functions).

Not sure what 'r or |A| means in Rust syntax, but I guess this would be
the equivalent D syntax:

auto map(R)(R delegate(T))


|A| - B is the type of a closure mapping an A to a B. 'r is a lifetime 
parameter (there is another one in Self):


I.e. that signature is roughly saying: The returned iterator lives at 
most as long as the closure context of f and the underlying iterator.


This way you can eg. get an iterator over some mutable data structure, 
map it without allocations using a stack closure, and the type system 
verifies that the data structure is not changed while the mapped 
iterator is in use, and that there are no dangling references to stack 
memory left behind.


D vs Rust: function signatures

2014-04-29 Thread Narrator via Digitalmars-d
The unbelievable amount of time and energy that's been spent 
discussing the smallest syntax, you would think that D would, at 
the very least, have better looking function signatures, but it 
doesn't.


auto zip(Ranges...)(Ranges ranges) if (Ranges.length  
allSatisfy!(isInputRange, Ranges));
auto zip(Ranges...)(StoppingPolicy sp, Ranges ranges) if 
(Ranges.length  allSatisfy!(isInputRange, Ranges));


fn zipB, U: IteratorB(self, other: U) - ZipSelf, U


auto chain(Ranges...)(Ranges rs) if (Ranges.length  0  
allSatisfy!(isInputRange, staticMap!(Unqual, Ranges))  
!is(CommonType!(staticMap!(ElementType, staticMap!(Unqual, 
Ranges))) == void));


fn chainU: IteratorA(self, other: U) - ChainSelf, U


template map(fun...) if (fun.length = 1)
auto map(Range)(Range r) if (isInputRange!(Unqual!Range));

fn map'r, B(self, f: |A|: 'r - B) - Map'r, A, B, Self


template filter(alias pred) if (is(typeof(unaryFun!pred)))
auto filter(Range)(Range rs) if (isInputRange!(Unqual!Range));

fn filter'r(self, predicate: |A|: 'r - bool) - Filter'r, A, 
Self



MaxType!(T1, T2, T) max(T1, T2, T...)(T1 a, T2 b, T xs) if 
(is(typeof(a  b)));


pub fn maxT: TotalOrd(v1: T, v2: T) - T


Re: D vs Rust: function signatures

2014-04-29 Thread Nick Sabalausky via Digitalmars-d

On 4/29/2014 9:38 PM, Narrator wrote:


fn map'r, B(self, f: |A|: 'r - B) - Map'r, A, B, Self



That looks like line noise.



Re: D vs Rust: function signatures

2014-04-29 Thread Vladimir Panteleev via Digitalmars-d

On Wednesday, 30 April 2014 at 01:38:46 UTC, Narrator wrote:
The unbelievable amount of time and energy that's been spent 
discussing the smallest syntax, you would think that D would, 
at the very least, have better looking function signatures, but 
it doesn't.


auto zip(Ranges...)(Ranges ranges) if (Ranges.length  
allSatisfy!(isInputRange, Ranges));
auto zip(Ranges...)(StoppingPolicy sp, Ranges ranges) if 
(Ranges.length  allSatisfy!(isInputRange, Ranges));


fn zipB, U: IteratorB(self, other: U) - ZipSelf, U


IIUC:

1. The Rust function is non-variadic
2. The Rust function has no StoppingPolicy equivalent
3. The Rust function is a method of some type, such as Zip or 
Chain, which must be declared explicitly in every such type.


Here is the equivalent D syntax:

auto zip(R)(R other) if (isInputRange!R)

It is shorter than the Rust version.

auto chain(Ranges...)(Ranges rs) if (Ranges.length  0  
allSatisfy!(isInputRange, staticMap!(Unqual, Ranges))  
!is(CommonType!(staticMap!(ElementType, staticMap!(Unqual, 
Ranges))) == void));


fn chainU: IteratorA(self, other: U) - ChainSelf, U


Same as points 1 and 3 above. Most of that boilerplate comes from 
validating the variadic parameter types.



template map(fun...) if (fun.length = 1)
auto map(Range)(Range r) if (isInputRange!(Unqual!Range));

fn map'r, B(self, f: |A|: 'r - B) - Map'r, A, B, Self


Same as points 1 and 3 above (D's version allows specifying 
multiple functions).


Not sure what 'r or |A| means in Rust syntax, but I guess this 
would be the equivalent D syntax:


auto map(R)(R delegate(T))

Note that D's real version has the function alias as a template 
parameter, and not as a runtime parameter, meaning that you will 
have a guarantee of a separate template instantiation for every 
different map predicate. This allows you to make assumptions 
about the performance of the generated code which don't rely as 
much on expected compiler optimizations (although I don't know 
what guarantees Rust makes about this).



template filter(alias pred) if (is(typeof(unaryFun!pred)))
auto filter(Range)(Range rs) if (isInputRange!(Unqual!Range));

fn filter'r(self, predicate: |A|: 'r - bool) - Filter'r, 
A, Self


As above, though D's filter also accepts only one predicate.

MaxType!(T1, T2, T) max(T1, T2, T...)(T1 a, T2 b, T xs) if 
(is(typeof(a  b)));


pub fn maxT: TotalOrd(v1: T, v2: T) - T


Same as point 1 above. Also, the Rust version requires that the 
two values have exactly the same type.