D vs Rust: function signatures

Vladimir Panteleev via Digitalmars-d digitalmars-d at puremagic.com
Tue Apr 29 19:04:58 PDT 2014


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 zip<B, U: Iterator<B>>(self, other: U) -> Zip<Self, 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 chain<U: Iterator<A>>(self, other: U) -> Chain<Self, 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 max<T: 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.


More information about the Digitalmars-d mailing list