Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I emulate Lisp (apply) or (curry) in Rust?

I'm porting QuickCheck to Rust, and I've written everything except for_all as I'm not sure what the type signature should be.

I know that in general, for_all will accept a property lambda and a collection of generator lambdas. It will evaluate the generators in order to create a random test case to give the property as input.

It should print +++ OK, passed 100 tests. if the property returns true, otherwise, it should print *** Failed! and print the offending test case values.

like image 281
mcandre Avatar asked Feb 14 '12 04:02

mcandre


People also ask

Does rust have currying?

Rust cannot do currying cleanly for numerous reasons: It's C-like function application foo(x,y) instead of ML-style function application foo x y . It's simplistic self focused trait design, as opposed to type classes, modules, etc. As a result, Rust DSLs work via proc macros.

How do you return a function in Rust?

The return keyword can be used to return a value inside a function's body. When this keyword isn't used, the last expression is implicitly considered to be the return value. If a function returns a value, its return type is specified in the signature using -> after the parentheses () .


1 Answers

In Rust, all functions take a fixed number of parameters, so there's no such thing as an equivalent to Lisp's apply in the general case, but macros can provide you with the abstraction you desire. You can write:

macro_rules! for_all {
    ( $tester:expr, $( $generator:expr ),* ) => {
        $tester( $($generator() ),* )
    }
}

Then, for_all!(|a, b| a + b, || 4, || 7) produces 11.

Good luck with your project!

like image 140
Paul Stansifer Avatar answered Oct 01 '22 07:10

Paul Stansifer