How do I use parameter overloading or optional parameters in rust? - optional-parameters

I am trying to write a print function for a binary tree and here is what I have so far:
impl TreeNode {
fn print(&self) {
self.print(0);
}
fn print(&self, level: u8) {
for _i in range(0,level) {
print!("\t");
}
match self.data {
Some(x) => println!("{}",x),
None => ()
};
match self.left {
Some(ref x) => x.print(level+1),
None => ()
};
match self.right {
Some(ref x) => x.print(level+1),
None => ()
};
}
}
I am getting the error: duplicate definition of value print. So I was wondering if there is a way to create functions with the same name but different arguments. Alternatively optional parameters would solve this problem, but I don't think that is possible at the moment (at least I couldn't find it via a Google search).
So, what is the best way to do this? Renaming the second print function works but looks ugly and requires you to remember more than one function name if I want to (for this example) print starting from the middle of the tree.

Rust does not have overloading, so it is impossible to have two functions or methods with the same name and with different sets of parameters.
However, it is sometimes possible to emulate overload with traits. This approach is likely inappropriate for your use case, but you can see how it is done in the standard library, where Path::new() constructor can be called with something resembling a vector of bytes:
Path::new("/a/b/c/d") // argument is &str
Path::new(b"/a/b/c/d") // argument is &[u8]
Path::new(Path::new("/a/b/c/d")) // argument is another Path
This is done via BytesContainer trait, and new() method is defined like this:
fn new<T: BytesContainer>(bytes: T) -> Path { ... }
Then this trait is implemented for all the types you want:
impl<'a> BytesContainer for &'a str { ... }
impl<'a> BytesContainer for &'a [u8] { ... }
impl BytesContainer for Path { ... }
// and more
This resembles overloading precisely because new() does exactly the same thing regardless of what kind of input it is provided; it is just a convenience thing which makes Path constructor more flexible. In the end new() just converts its argument to a byte slice. However, this does not allow you to have completely different functions with the same name.

Related

Scala: how to access variables in a method defined in some other block of code

I have following code:
.hof((key, value) => {
Some(..some processing result on key,value)
.filterNot(_.isEmpty)
.map(x: X => {....my code processing x using key,value with output y})
}
)
I want to abstract out the function I passed to map into a method defined in class.
def myMethod(x: X) = {
y = ....some computation....
return y
}
But I need to have access to key,value in myMethod.
Is there a way to have that?
You can define myMethod in curried form:
def myMethod(key: Key, value: Value)(x: X) = {
... uses key and value ...
}
Then you can partially apply it in the map, passing it the key/value pair that you have at that point:
.map(myMethod(key, value))
Note that adding key/value pair to myMethod signature isn't some kind of "cheating"; if the method needs to use key and value, then it should have them passed as parameters.
This is the great thing about FP; once every function declares all the parameters it operates on, you can compose them easily.
Of course, you could simply place myMethod somewhere within the scope where key and value are going to be accessible (=closure), but by declaring them as parameters you are more flexible and you can place the method anywhere you want.
You can define the method locally like this:
.hof((key, value) => {
def myMethod(x: X) = {
???
}
Some(..some processing result on key,value)
.filterNot(_.isEmpty)
.map(myMethod)
}
)
Otherwise you are going to have to pass (key, value) to the function as arguments.
(See answer from #slouc for tips on how to use currying to make this cleaner)

Is it possible to write a Rust macro "has_trait!(<type>,<ident>|<expr>)"?

I want to match, e.g. an ident's type to implement a certain trait, how would I do that?
Here the basic idea in (incomplete) code:
macro_rules! has_trait {
($ ($t : ty), ($x : ident),) => {
}
}
fn trait_test() {
let a = vec![1, 2, 3];
let b = 42;
let a_iteratable = has_trait!(IntoIterator, a);
let b_iteratable = has_trait!(IntoIterator, b);
println!("{:?} iterable? {}", a, a_iteratable);
println!("{:?} iterable? {}", b, b_iteratable);
}
I cannot wrap my head around how to say "any type which has trait Foo".
I see 2 options how to tackle the problem:
Find a match expression which matches any type with trait $t and simply return true on match, else (how works else?) false.
In the body of the match of any type, use some code to determine if trait $t is implemented by the type of $x.
I cannot see how to do either of both options.
Can this even be done?
I am afraid there is here a serious misconception about what macros can and cannot do.
In Rust, a macro acts on the AST, short for Abstract Syntax Tree. This means that it has access to syntactic information (only).
It means that anything that a macro does, you can also do without a macro. A macro is just syntactic sugar to avoid writing boilerplate over and over.
And conversely, if you cannot do something without a macro, you cannot do it with a macro either.
It is not immediately clear to me whether this information is available or not (proving a negative is always so difficult), however it is certain that the usage of macros has no influence on this availability.
As the other answers have already made clear, there is nothing a macro can do. And indeed, in current (stable) Rust, that's it. However, if you are willing to either use nightly or wait until specialization is stable, you can write and implement a trait to make that distinction, e.g.
#[feature(specialization)] // nightly only for now
trait HasMyTrait {
fn has_trait() -> bool;
}
impl<T> HasMyTrait for T {
default fn has_trait() -> bool { false }
}
impl<T: MyTrait> HasMyTrait for T {
fn has_trait() -> bool { true }
}
This is just a simple example, but you can switch out multiple implementations of whatever functionality you want based on if the type in question implements a trait or not.
This code requires Rust 1.11.0 nightly as of 2016-06-02 or newer.
What you basically want is static (or compile-time) reflection:
Assigning values at compile-time, depending on the type system, to use at run-time.
This is possible in for example D or even C++, but not in Rust.
Rust does not allow template specialisation or compile-time values as generic parameters, nor does it have static reflection capabilities like D.

Scala no argument string function vs typed String parameter

I ran across a function that looks like this:
def doSomethingQuestionable(config: someConfig, value: String)(default: => String) : String
What is interesting is the parameterless function that gets passed in as second argument group. In the code base, the method is only ever called with a config and two strings, the latter being some default value, but as a String, not a function. Within the code body of the method, default is passed on to a method that takes 3 string arguments. So the function "default" only resolves down to a string within the body of this method.
Is there any benefit, apart from a currying usage which does not happen with this method in the code base I am going through, of defining the method this way? Why not just define it with 3 string arguments in a single argument group?
What am I missing? Some compiler advantage here? Keep in mind, I am assuming that no currying will ever be done with this, since it is a large code base, and it is not currently done with this method.
The point is to have a potentially expensive default string that is only created when you need it. You write the code as if you're creating the string to pass in, but because it's a by-name parameter ('=> String') it will actually be turned into a function that will be transparently called whenever default is referenced in the doSomethingQuestionable method.
The reason to keep it separate is in case you do want a big block of code to create that string. If you never do and never will, it may as well be
def doSomethingQuestionable(config: someConfig, value: String, default: => String): String
If you do, however,
def doSomethingQuestionable(cfg, v){
// Oh boy, something went wrong
// First we need to check if we have a database accessible
...
// (Much pain ensues)
result
}
is way better than embedding the code block as one argument in a multi-argument parameter list.
This is a parameterless function returning a String:
() => String
Which is not what you have. This,
=> <WHATEVER>
is a parameter being passed by-name instead of by-value. For example:
=> String // A string being passed by-name
=> () => String // A parameterless function returning string being passed by-name
The difference between these modes is that, on by-value, the parameter is evaluated and the resulting value is passed, whereas on by-name, the parameter is passed "as is", and evaluated each time it is used.
For example:
var x = 0
def printValue(y: Int) = println(s"I got $y. Repeating: $y.")
def printName(y: => Int) = println(s"I got $y. Repeating: $y.")
printValue { x += 1; x } // I got 1. Repeating: 1.
printName { x += 1; x } // I got 2. Repeating: 3.
Now, as to why the method splits that into a second parameter, it's just a matter of syntactic pleasantness. Take the method foldLeft, for example, which is similarly defined. You can write something like this:
(1 to 10).foldLeft(0) { (acc, x) =>
println(s"Accumulator: $acc\tx: $x\tacc+x: ${acc+x}")
acc+x
}
If foldLeft was defined as a single parameter list, it would look like this:
(1 to 10).foldLeft(0, { (acc, x) =>
println(s"Accumulator: $acc\tx: $x\tacc+x: ${acc+x}")
acc+x
})
Not much different, granted, but worse looking. I mean, you don't write this thing below, do you?
if (x == y, {
println("Same thing")
}, {
println("Different thing"
})

Rust: Is there a way to call a static function on a macro type argument?

This code:
#![feature(macro_rules)]
macro_rules! new(
($my_type:ty) => ( $my_type::new() );
)
struct Foo {
blah: int
}
impl Foo {
fn new() -> Foo {
return Foo { blah: 0 }
}
}
fn main() {
let my_foo = new!(Foo);
println!("Foo's value: {}", my_foo.blah);
}
Looks good enough, but it fails with this error:
test.rs:4:25: 4:32 error: unexpected token: `Foo`
test.rs:4 ($my_type:ty) => ( $my_type::new() );
^~~~~~~
If I go into the macro and replace $my_type with Foo it compiles and runs just fine, so Foo is clearly valid in that position. Unless Foo comes from macro substitution, apparently.
If I run rustc test.rs --pretty expanded, it doesn't show me the expanded macro. It just gives me the same error message. I suspect this means it's generating the message before it expands the macro, but it might just be that it doesn't show me anything unless the compile succeeds. Though that would severely limit the usefulness of --pretty expanded.
Based on other experiments, I can use the macro type arguments in basically every other place one would expect a type to work. You just can't call static functions on them. This seems like a rather arbitrary restriction, and the error message is certainly not helpful.
Why does this restriction exist? And is there a way around it?
The Foo::bar() syntax is creating the path Foo::bar and then calling that function, and only works with valid paths, it doesn't work with arbitrary types, e.g. (u8, i8)::bar() doesn't work. You can use the ident macro non-terminal, which takes a single identifier and can be used whereever an identifier is valid, including inside a path
#![feature(macro_rules)]
macro_rules! new(
($my_type: ident) => ( $my_type::new() );
)
struct Foo {
blah: int
}
impl Foo {
fn new() -> Foo {
return Foo { blah: 0 }
}
}
fn main() {
let my_foo = new!(Foo);
println!("Foo's value: {}", my_foo.blah);
}
UFCS offers calling such methods on arbitrary types, via the syntax <Type>::new() and so, when that is implemented, replacing your current macro with
macro_rules! new(
($my_type: ty) => ( <$my_type>::new() );
)
should work too.

Scala Returning a void function with 0 parameters, ugly syntax?

Given a method defined as follows
def descendEach(times:Int)(f:()=>Unit) {
for (i <- 1 to times) {
// other code
f()
}
}
when I use this method I want to be able to write
gd.descendEach(20){
println(gd.cost)
}
but the scala compiler only lets me get away with
gd.descendEach(20){ () =>
println(gd.cost)
}
which is kind of ugly. Am I missing something here? Is it possible to write it in the first way I presented?
Use the following syntax:
def descendEach[T](times:Int)(f: => T)
This way you can not only pass function without extra () => (this is called pass by name), but also use functions returning any type (not necessarily Unit). It is sometimes convenient when you have an existing function you want to pass but don't really care about its return value:
def g() = 42
descendEach(20)(g)
Note that with this syntax you are simply using f, not f().