3 ms·
> the function's argument is a tuple (this is the more common way, not only in SML, but also how it's done most commonly in maths); The Ceylon programming lang
by brabel 6y ago
> the function's argument is a tuple (this is the more common way, not only in SML, but also how it's done most commonly in maths);
The Ceylon programming language worked that way[1] and it was really cool to be able just what you wanted: `o.map(f)`.
It's a shame that other languages didn't seem to pick up this idea... I've no idea if this could be made to work in Rust though (given Rust has no GC and it would go against its philosophy to allocate parameters like this on the heap just to create tuples - maybe the compiler could get rid of the actual tuples altogether?).
[1] https://ceylon-lang.org/blog/2012/12/21/tuples-and-functions/ https://ceylon-lang.org/blog/2012/12/21/tuples-and-functions...
- estebank 6y agoRust tuples are on the stack, to have them on the heap you need to explicitly use Box. Funnily enough, internally this is how closures parameters are represented internally, as a single argument that is a tuple of all its parameters.
- _nalply 6y agoPerhaps you meant that variables which are closed over are in an anonymous struct or in a tuple. I am fuzzy about the details but as far as I know parameters are passed like as in other functions.
- estebank 6y agoRust represents closures in the following way: pub trait Fn<Args> { type Output; extern "rust-call" fn call(self, args: Args) -> Self::Output; } where Args is a tuple of all the actual arguments. You used to be able to cause an ICE on nightly if you used something other than the correct argument[1], but instead it now tells you that it should have been a tuple: error: functions with the "rust-call" ABI must take a single non-self argument that is a tuple --> src/main.rs:7:5 | 7 | extern "rust-call" fn call_once(self, args: i32) -> Self::Output {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0059]: cannot use call notation; the first type parameter for the function trait is neither a tuple nor unit --> src/main.rs:12:5 | 12 | x(42); | ^^^^^ [1]: https://play.rust-lang.org/?version=nightly&mode=debug&edition=2018&gist=9b66c97982c370bc865597301af2ae7e https://play.rust-lang.org/?version=nightly&mode=debug&editi...
- _nalply 6y agoHuh. That's really slick. I stand corrected.
- terhechte 6y agoSwift had this feature until version 2.3 it was removed in 3.0 because it added a lot of complexity and seemingly confused users. I’d search for a link but I’m on mobile
- anderskaseorg 6y agoEven though Ceylon uses tuple types to represent parameter lists, a function accepting multiple arguments (with the parameter list represented by a tuple: Callable<Void, [Integer, String]>) is still different from a function accepting a tuple of multiple fields (with the parameter list represented by a tuple of a tuple: Callable<Void, [[Integer, String]]>). You can’t just call one as if it were the other. Ceylon works the same way as Rust here, as far as I can tell. BTW, for Rust beginners who might be concerned that o.map(f) is somehow a difficult problem, the solution in Rust is simple: o.map(|(a, b)| f(a, b)).