Why does Rust not allow slice as a value? [duplicate] - pointers

This question already has answers here:
What does "Sized is not implemented" mean?
(2 answers)
What is a "fat pointer"?
(1 answer)
Closed 2 years ago.
Why does Rust does not allow creating a slice sa as a value {ptr, len} on the stack and only allows to create rsa as a references to some (anonymous?) value called a fat pointer?
// a is five i32 values on the stack
let a = [1, 2, 3, 4, 5];
// rsa is a reference to (anonymous?) {ptr,len} on the stack
let rsa = &a[..];
// sa would be an explicit struct {ptr,len} on the stack
let sa = a[..];
error[E0277]: the size for values of type `[{integer}]` cannot be known at compilation time
--> src/main.rs:9:9
|
9 | let sa = a[..];
| ^^ ----- help: consider borrowing here: `&a[..]`
| |
| doesn't have a size known at compile-time
|
= help: the trait `std::marker::Sized` is not implemented for `[{integer}]`
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
= note: all local variables must have a statically known size
= help: unsized locals are gated as an unstable feature

Related

Go Pointers pointing to different memory locations but updating same variable [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 3 years ago.
Improve this question
Summary: a is pointing to a memory address of 0x40e020 which is assigned to b. c, is then assigned to b's memory location (or so I thought). When I print out the address of c &c it points to a different spot in memory 0x40c138.
package main
import (
"fmt"
)
func main() {
var a int = 42
b := &a
c := b
*c = 4
fmt.Println(a, b, &c) // output --> 4 0x40e020 0x40c138
}
Question: How is the pointer c updating a's value? I would expect a to print out 42, but the compiler spits out 4.
A picture might help. Here is (some of) the memory in your computer, around 0x40c138 through 0x40e020 or so:
+---------+ +---------+
????????: | * | (variable "b") 0x40c138: | * | (variable "c")
+----|----+ +----|----+
v ________________________________/
+---------+'
0x40e020: | 4 | (variable "a")
+---------+
Variables b and c both point to variable a. You print the value of variable b, which is 0x40e020, which is how we know where a itself lives in memory. You print the address of variable c, which is how we know where c itself lives in memory. You do not print the address of variable b so we are not sure where it lives, but we do know that b and c both point to a, so we can draw the arrow coming out of each one.
Since the arrow coming out of c points to a, writing through *c writes to a.
Let's break down exactly what's happening here:
var a int = 42
b := &a
c := b
You now have three variables, each with its own location in memory. a is an integer with the value 42. b and c each have the same value, which is the memory address of a.
*c = 4
This dereferences the pointer c and writes the value 4 to the memory location it points to, which is the memory location of a. This is why when printing a you see the value 4 - this line overwrites the value in a's memory location. That's the primary purpose of pointers - to allow multiple references to the same value in memory.
fmt.Println(a, b, &c) // output --> 4 0x40e020 0x40c138
This prints the value of a, the value of b (which is the address of a), and the address of c.
c prints the memory address of a. b is a variable that holds a's memory address and c is b (these variables hold the same value).
When you print &c, you print the memory address of the variable c which holds a's memory address.
The reason you can update a's value with c is because the * operator lets you access or follow the memory address c holds and update the value it is holding.

Why is the size of a pointer to something on the heap larger than the size of a stack variable?

I have the following stack- and heap-allocated variables:
let var1 = 10;
let var2 = Box::new(10);
Printing these outputs the same value, 10:
println!("var1 ={} var2 ={}", var1, * var2);
When I check the size using mem::size_of_val(), var1 is 4 and var2 is 8.
Isn't var2 a pointer to the heap? Why would a pointer be larger than the stack variable (var1)?
Also, is the use of "*" (i.e., *var2) in the println!() supposed to do anything different? I get 10 either way.
You didn't show your code for how you are invoking mem::size_of_val but I guess from the results that you are doing this:
println!("var1 size = {}", mem::size_of_val(&var1)); // 4
println!("var2 size = {}", mem::size_of_val(&var2)); // 8
The size of var1 is the size of an i32 (4 bytes), while the size of var2 is the size of a Box, which is just a pointer (it would be two pointers if it was a trait object). A pointer is always a usize (8 bytes on a 64bit system).
If you dereference the box first, then the size will be that of the box's contents and you'll get the result you expect:
println!("var2 size = {}", mem::size_of_val(&*var2)); // 4
Also, is the use of "*" (i.e., *var2) in the println!() supposed to do anything different? I get 10 either way.
The println! macro, along with format! and a few others, will always prepend a & to a value to make sure that it's borrowed, not moved or copied. When the value is needed it will be automatically dereferenced as many times as is necessary. See this answer for more detail.

Using max_by_key on a vector of floats [duplicate]

This question already has answers here:
How do I get the minimum or maximum value of an iterator containing floating point numbers?
(4 answers)
Closed last year.
I want to use max_by_key to get the maximum value from a vector of f64s based on a certain key. This is a simple example, with a small vector and abs as the key:
let a: Vec<f64> = vec![-3.0, 0.2, 1.4];
*a.iter().max_by_key(|n| n.abs()).unwrap()
However, since f64 does not implement Ord, I get
error[E0277]: the trait bound `f64: std::cmp::Ord` is not satisfied
--> src/main.rs:3:15
|
3 | *a.iter().max_by_key(|n| n.abs()).unwrap();
| ^^^^^^^^^^ the trait `std::cmp::Ord` is not implemented for `f64`
Similarly, sort_by_key fails with the same error:
a.sort_by_key(|n| n.abs())
I know I can get around the partial ordering restriction to sort a vector of floats with sort_by
b.sort_by(|m, n| m.partial_cmp(n).unwrap_or(Less))
but that would have to be called on a vector b for which I've computed the key (in this case abs) for each element of a, and then I would have to go back and find the corresponding element of a, which seems complicated and slow. As the number of items in the list grows, I'd like to minimize passes through the data.
Are there any workarounds?
If you do not want to create a wrapper type you can use the ordered_float or ord_subset crate. For example
extern crate ordered_float;
extern crate ord_subset;
#[test]
fn test_example_() {
use ordered_float::OrderedFloat;
// OrderedFloat -> NaN is greater than all other values and equal to itself.
// NotNaN -> NotNaN::new panics if called with NaN.
let mut a: Vec<f64> = vec![-3.0, 0.2, 1.4];
let max = *a.iter().max_by_key(|n| OrderedFloat(n.abs())).unwrap();
assert_eq!(-3.0, max);
a.sort_by_key(|n| OrderedFloat(n.abs()));
assert_eq!(vec![0.2, 1.4, -3.0], a);
}
#[test]
fn test_example_ord_subset() {
use ord_subset::OrdSubsetIterExt;
let a: Vec<f64> = vec![-3.0, 0.2, 1.4];
// For f64, NaN is ignored.
let max = *a.iter().ord_subset_max_by_key(|n| n.abs()).unwrap();
assert_eq!(-3.0, max);
// ord_subset does not help with the sorting problem in the question
}

How to prove that "Total" is not recursive (decidable) [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 9 years ago.
Improve this question
Halt = { f,x | f(x)↓ } is re (semi-decidable) but undecidable
Total = { f | ∀x f(x)↓ } is non-re (not even semi-decidable)
I need some help in proving that the Total problem is not recursive (decidable).
I know the diagonalization proof for the Halting problem, I just need the same kind of proof for the Total problem. I'm posting the Halting Problem Proof for reference:
Halting Problem Proof
Assume we can decide the halting problem. Then there exists some total function Halt such
that
1 if [x] (y) is defined
Halt(x,y) =
0 if [x] (y) is not defined
Here, we have numbered all programs and [x] refers to the x-th program in this ordering. We
can view Halt as a mapping from ℵ into ℵ by treating its input as a single number
representing the pairing of two numbers via the one-one onto function
pair(x,y) = <x,y> = 2^x (2y + 1) – 1
with inverses
<z>1 = exp(z+1,1)
<z>2 = ((( z + 1 ) // 2^<z>1) – 1 ) // 2
Now if Halt exist, then so does Disagree, where
0 if Halt(x,x) = 0, i.e, if Φx (x) is not defined
Disagree(x) =
µy (y == y+1) if Halt(x,x) = 1, i.e, if Φx (x) is defined
Since Disagree is a program from ℵ into ℵ , Disagree can be reasoned about by Halt. Let d
be such that Disagree = Φd, then
Disagree(d) is defined ⇔ Halt(d,d) = 0 ⇔ Φd (d) is undefined ⇔ Disagree(d) is undefined
But this means that Disagree contradicts its own existence. Since every step we took was
constructive, except for the original assumption, we must presume that the original assumption was in error. Thus, the Halting Problem is not solvable.

Match Comparison OCaml

I have come to love this syntax in OCaml
match myCompare x y with
|Greater->
|Less->
|Equal->
However, it needs 2 things, a custom type, and a myCompare function that returns my custom type.
Would there be anyway to do this without doing the steps above?
The pervasives module seems to have 'compare' which returns 0 if equal, pos int when greater and neg int when less. Is it possible to match those? Conceptually like so (which does not compile):
match myCompare x y with
| (>0) ->
| (0) ->
| (<0) ->
I know I could just use if statements, but pattern matching is more elegant to me. Is there an easy (if not maybe standard) way of doing this?
Is there an easy … way of doing this?
No!
The advantage of match over what switch does in another language is that OCaml's match tells you if you have thought of covering all the cases (and it allows to match in-depth and is compiled more efficiently, but this could also be considered an advantage of types). You would lose the advantage of being warned if you do something stupid, if you started using arbitrary conditions instead of patterns. You would just end up with a construct with the same drawbacks as a switch.
This said, actually, Yes!
You can write:
match myCompare x y with
| z when (z > 0) -> 0
| 0 -> 0
| z when (z < 0) -> 0
But using when makes you lose the advantage of being warned if you do something stupid.
The custom type type comparison = Greater | Less | Equal and pattern-matching over the three only constructors is the right way. It documents what myCompare does instead of letting it return an int that could also, in another language, represent a file descriptor. Type definitions do not have any run-time cost. There is no reason not to use one in this example.
You can use a library that already provide those variant-returning compare functions. This is the case of the BatOrd module of Batteries, for example.
Otherwise your best bet is to define the type and create a conversion function from integers to comparisons.
type comparison = Lt | Eq | Gt
let comp n =
if n < 0 then Lt
else if n > 0 then Gt
else Eq
(* ... *)
match comp (Pervasives.compare foo bar) with
| Lt -> ...
| Gt -> ...
| Eq -> ...

Resources