Absolute value function in Rust - function

In this elementary Rust program a function calculates the absolute value of an integer, and main() helps in completing a statement with the result:
fn main() {
let value = abs(-4);
println!("{}.", value);
}
fn abs(x: i32) -> i32 {
print!("The abs value of {} is ", x);
if x > 0 {
return x;
} else {
-x
}
}
Is there a way to print correctly the whole statement "The abs value of... is..." into the abs() function? I tried unsuccessfully with
println!("The abs value of {} is {} ", x, x);
This always prints the value of the x parameter (e.g. -4, -4) so it's not correct.
And with
println!("The abs value of {} is {} ", x, abs(x));
But here, for some reason, Rust is not happy with recursion, gives a warning at compilation and then doesn't run the program.

The absolute value method is already defined; you do not need to implement it yourself
fn main() {
let value = abs(-4);
println!("{}.", value);
}
fn abs(x: i32) -> i32 {
let val = x.abs();
println!("The abs value of {} is {}", x, val);
val
}

Try this to avoid recursion:
fn main() {
let value = abs(-4);
println!("{}.", value);
}
fn abs(x: i32) -> i32 {
let y = if x >= 0 { x } else { -x };
println!("The abs value of {} is {} ", x, y);
y
}
Output:
The abs value of -4 is 4
4.
There are built-in .abs() method for primitive types e.g.
i8,
i16,
i32,
i64,
i128,
f32,
and f64:
assert_eq!(10i32.abs(), 10);
assert_eq!((-10i32).abs(), 10);
Overflow behavior
The absolute value of i32::min_value() cannot be represented as an
i32, and attempting to calculate it will cause an overflow. This
means that code in debug mode will trigger a panic on this case and
optimized code will return i32::min_value() without a panic.
The following code, will panic in debug mode (and returns -128 in release mode):
fn main() {
let a = -128_i8;
println!("{}", a); // -128
let b = a.abs();
println!("{}", b); // -128
}
Since abs(-2_147_483_648_i32) is 2_147_483_648_u32, you may return u32 instead of i32:
fn abs(x: i32) -> u32 {
if x >= 0 {
x as u32
} else if x == std::i32::MIN {
2_147_483_648_u32
} else {
-x as u32
}
}
fn main() {
let value = abs(std::i32::MIN); // i32::min_value() // -2_147_483_648i32
println!("{}.", value); // 2147483648
}
Output:
2147483648

Related

Is there any way to pass a callback to a function in WGSL?

I can't seem to figure out how or if it is acually possible to pass acallback to a function in WGSL. I would like to make something along these lines.
fn foo(x: f32, bar: ?callback?) {
bar(x);
}
fn baz(y: f32) -> f32 {
return y + 1;
}
#compute
fn main() {
foo(5, baz) // => 6
}
My intelisense hinted me
bar: Fn
but compiler doesn't like that.
WGSL does not have function pointers, so you can't pass a function as a parameter.

Programatically creating an iterator from mapping functions in Rust

I'm trying to write code like the following, but where I apply f1 and f2 some variable number of times:
#![feature(impl_trait_in_bindings)]
fn f1(c: char) -> impl IntoIterator<Item = char> {
vec!['A', c]
}
fn f2(c: char) -> impl IntoIterator<Item = char> {
vec!['C', 'D', c]
}
fn main() {
let x = vec!['X', 'X', 'X'];
let v: impl Iterator<Item = char> = x.into_iter();
let v = v.flat_map(f1);
let v = v.flat_map(f2);
println!("Force evaluation of five elements: {:?}", v.take(5).collect::<Vec<_>>());
}
I'd like to replace the let v = ... lines with a loop that iteratively reassigns v, like
let mut v: impl Iterator<Item = char> = x.into_iter();
for i in 0..f1Times {
v = v.flat_map(f1);
}
for i in 0..f2Times {
v = v.flat_map(f2);
}
... e.g. for my use case I may have several functions and I won't know which ones (or how many times) to apply ahead of time. I'd like the result to be an iterator that I can take only a limited number of items from, and I'd like to avoid invoking any functions that aren't needed to generate those items.
I can't get the types to work. For instance with the let mut block I proposed above I get:
mismatched types
expected opaque type `impl Iterator`
found struct `FlatMap<impl Iterator, impl IntoIterator, fn(char) -> impl IntoIterator {f1}>`
Is there a good way to build up this sort of iterator programatically?
I've found this pattern works, but still don't know if it's idiomatic or recommended...
#![feature(impl_trait_in_bindings)]
fn f1(c: char) -> impl Iterator<Item = char> {
Box::new(vec!['A', c].into_iter())
}
fn f2(c: char) -> impl Iterator<Item = char> {
Box::new(vec!['C', 'D', c].into_iter())
}
fn main() {
let x = vec!['X', 'X', 'X'];
let mut v: Box<dyn Iterator<Item = char>> = Box::new(x.into_iter());
let f1_ntimes = 2;
for _i in 0..f1NTimes {
v = Box::new(v.into_iter().flat_map(f1));
}
let f2_ntimes = 2;
for _i in 0..f2_ntimes {
v = Box::new(v.into_iter().flat_map(f2));
}
println!("Force evaluation of five elements: {:?}", v.take(5).collect::<Vec<_>>());
}

How do I write a function that returns itself?

What I want to make is a function, that returns itself, so I can call it like this:
foo()()...()
In C# it would be done via delegates:
delegate SelfFunc SelfFunc();
static void Main() {
SelfFunc foo = null;
foo = () => {
return foo;
};
foo()()...();
}
Anticipating questions like "why implement such silly behavior?": I want to sum numbers in a very strange way using single function continues calls: foo(1)(2)(3)() = 6, but in this question I just want to know how to return function itself. Example realization of this method that I made in C#. This is all just for fun and to learn Rust:
static int sum = 0;
delegate dynamic InfFunc(int i = int.MaxValue);
static void InfFuncTest() {
InfFunc f = null;
f = (int i) => {
if(i == int.MaxValue) {
return sum;
}
sum += i;
return f;
};
var g = f;
var value = g(1)(2)(3)();
Console.WriteLine(value);
}
A function that returns itself is possible on nightly.
First you need to enable the features unboxed_closures and fn_traits.
Then you can define a struct which, when called, returns self. The full code looks something like this:
#![feature(unboxed_closures, fn_traits)]
struct SelfFunc;
impl FnOnce<()> for SelfFunc {
type Output = SelfFunc;
extern "rust-call" fn call_once(self, _args: ()) -> Self::Output {
self
}
}
Then you can call the function as many times as you want:
fn main() {
let f = SelfFunc;
f()()()()()();
}
Based on #cameron1024's answer, you can "overload" using traits, but you will need 2 structs to handle the empty case properly of foo() (here called Add) without any arguments returning 0.
#![feature(unboxed_closures, fn_traits)]
struct Add;
impl FnOnce<(u32,)> for Add {
type Output = AddImpl;
extern "rust-call" fn call_once(self, args: (u32,)) -> Self::Output {
AddImpl(args.0)
}
}
impl FnOnce<()> for Add {
type Output = u32;
extern "rust-call" fn call_once(self, _args: ()) -> Self::Output {
0
}
}
struct AddImpl(u32);
impl FnOnce<()> for AddImpl {
type Output = u32;
extern "rust-call" fn call_once(self, _args: ()) -> Self::Output {
self.0
}
}
impl FnOnce<(u32,)> for AddImpl {
type Output = AddImpl;
extern "rust-call" fn call_once(self, args: (u32,)) -> Self::Output {
Self(self.0 + args.0)
}
}
fn main() {
dbg!( Add(1)(2)(3)() );
dbg!( Add() );
}
Playground
If you do not care about the no-args foo() requirement, you can make Add a tuple struct instead and remove AddImpl:
#![feature(unboxed_closures, fn_traits)]
struct Add(u32);
impl FnOnce<(u32,)> for Add {
type Output = Add;
extern "rust-call" fn call_once(self, args: (u32,)) -> Self::Output {
Add(self.0 + args.0)
}
}
impl FnOnce<()> for Add {
type Output = u32;
extern "rust-call" fn call_once(self, _args: ()) -> Self::Output {
self.0
}
}
fn main() {
dbg!( Add(1)(2)(3)() );
//dbg!( Add() ); // doesn't compile
}
Playground
Although I should note that this likely isn't such a great idea, using an slice/iterator would likely result in cleaner code:
fn main() {
dbg!([1, 2, 3].iter().copied().sum::<u32>());
}
Playground

Why does function pointer behaviour differ in Rust depending on the mutability of the function pointer?

When storing raw pointers to functions in structs in Rust, the behaviour of the program can change in unexpected ways depending on the mutability of the raw pointer.
Using const pointers gives the expected result.
The following code can also be viewed on the playground:
type ExternFn = unsafe extern "C" fn() -> ();
unsafe extern "C" fn test_fn() {
println!("Hello!");
}
mod mut_ptr {
use super::{ExternFn, test_fn};
#[derive(Debug, Eq, PartialEq)]
pub struct FunctionHolder {
function: *mut ExternFn,
}
impl FunctionHolder {
pub fn new() -> Self {
FunctionHolder {
function: (&mut (test_fn as ExternFn) as *mut _),
}
}
pub fn call(&self) {
if !self.function.is_null() {
unsafe { (&*self.function)(); }
}
}
}
}
mod const_ptr {
use super::{ExternFn, test_fn};
#[derive(Debug, Eq, PartialEq)]
pub struct FunctionHolder {
function: *const ExternFn,
}
impl FunctionHolder {
pub fn new() -> Self {
FunctionHolder {
function: (&(test_fn as ExternFn) as *const _),
}
}
pub fn call(&self) {
if !self.function.is_null() {
unsafe { (&*self.function)(); }
}
}
}
}
// use const_ptr::FunctionHolder;
use mut_ptr::FunctionHolder;
fn check_holder(holder: &FunctionHolder) -> bool {
let good = FunctionHolder::new();
println!("parameter = {:#?}", holder);
println!("expected = {:#?}", good);
holder == &good
}
fn main() {
let f0 = FunctionHolder::new();
println!("{:?}", f0);
let f1 = FunctionHolder::new();
println!("{:?}", f1);
// uncomment this line to cause a segfault if using the
// mut_ptr version :-(
// f1.call();
assert!(check_holder(&f1));
}
In the const_ptr module, the code behaves as expected: The pointer value stored in the FunctionHolder struct is the same regardless of where the function is called, and using the FunctionHolder::call method calls the function as required.
In the mut_ptr module, there are some unexpected differences:
The FunctionHolder::new method returns a struct holding a different value depending on the function in which it is called,
The FunctionHolder::call method causes a segfault.
fn() -> () is a function pointer. *const fn() -> () and *mut fn() -> () are function pointer pointers.
You want to use much simpler code, which also means there's no difference between the two implementations:
#[derive(Debug, Eq, PartialEq)]
pub struct FunctionHolder {
function: Option<ExternFn>,
}
impl FunctionHolder {
pub fn new() -> Self {
FunctionHolder {
function: Some(test_fn as ExternFn),
}
}
pub fn call(&self) {
if let Some(f) = self.function {
unsafe { f(); }
}
}
}
As mentioned in the comments, taking a mutable reference to a literal value constructs a new value each time:
fn main() {
println!("{:p}", &42);
println!("{:p}", &42);
println!("{:p}", &42);
println!("{:p}", &mut 42);
println!("{:p}", &mut 42);
println!("{:p}", &mut 42);
}
0x55a551c03a34
0x55a551c03a34
0x55a551c03a34
0x7ffd40dbb95c
0x7ffd40dbb9bc
0x7ffd40dbba1c
Immutable references to literals have implicit static promotion:
let a = &42;
// More-or-less
static HIDDEN: i32 = 42;
let a = &HIDDEN;
Mutable references to literals desugar to effectively:
let mut hidden: i32 = 42;
let a = &mut hidden;
By using raw pointers, you lose the support of the borrow checker to point out that your references don't live long enough for the mutable case.
See also:
Why is it legal to borrow a temporary?
Why can I return a reference to a local literal but not a variable?
What are the semantics of mutably borrowing a literal in Rust?

How to pass a function as argument in Rust

Given the following rust program:
fn call_twice<A>(val: A, f: fn(A) -> A) -> A {
f(f(val))
}
fn main() {
fn double(x: int) -> int {x + x};
println!("Res is {}", call_twice(10i, double));
// println!("Res is {}", call_twice(10i, (x: int) -> int {x + x}));
// ^ this line will fail
}
Why can I pass double as the function, but not inlined? What is a good way to achieve the same behaviour without defining the function somewhere?
2016-04-01 Update:
As of Rust 1.0, the code should look like this:
fn call_twice<A, F>(val: A, mut f: F) -> A
where F: FnMut(A) -> A {
let tmp = f(val);
f(tmp)
}
fn main() {
fn double(x: i32) -> i32 {x + x};
println!("Res is {}", call_twice(10, double));
println!("Res is {}", call_twice(10, |x| x + x));
}
The change to the closure parameter is because closure are now unboxed.
Original:
Insofar as I know, you can't define functions inline like that.
What you want is a closure. The following works:
fn call_twice<A>(val: A, f: |A| -> A) -> A {
let tmp = f(val);
f(tmp)
}
fn main() {
fn double(x: int) -> int {x + x};
println!("Res is {}", call_twice(10i, double));
println!("Res is {}", call_twice(10i, |x| x + x));
}
There are a few things to note:
Functions coerce to closures, but the opposite isn't true.
You need to store the result of f(val) in a temporary due to borrowing rules. Short version: you need unique access to a closure to call it, and the borrow checker isn't quite clever enough to realise the two calls are independent in their original positions.
Closures are in the process of being replaced by unboxed closures, so this will change in the future, but we're not quite there yet.