Cairo: let vs tempvar what is the difference? - cairo-lang

I'm new to Cairo and I want to know what is the difference when I write let x = 1; and tempvar x = 1;. Is there any difference in Cairo Lang between let and tempvar?

Yes, there's a difference. The keyword let creates a reference that's resolved by the compiler while tempvar actually stores the variable in the stack using a specialized register called the ap pointer. You can find more information about it here

Related

Converting a immutable variable to mutable by taking ownership

I was going through the Rust book from the official rust website and came across the following paragraph:
Note that we needed to make v1_iter mutable: calling the next method on an iterator changes internal state that the iterator uses to keep track of where it is in the sequence. In other words, this code consumes, or uses up, the iterator. Each call to next eats up an item from the iterator. We didn’t need to make v1_iter mutable when we used a for loop because the loop took ownership of v1_iter and made it mutable behind the scenes.
If you notice the last line. It says the for loop makes a mutable variable immutable behind the scenes. If that's possible, then is it possible for us as a programmer to do the same?
Like I know it's not safe and we're not supposed to do that and stuff, but just wondering if that would be possible.
It is completely fine to rebind an immutable variable to a mutable, e.g. the following code works:
let x = 5;
let mut x = x;
After the last statement we can mutate x variable. In fact, thought, there are two variables, the first is moved into the latest. The same can be done with the function as well:
fn f(mut x: i32) {
x += 1;
}
let y = 5;
f(y);
The thing prohibited in Rust is changing immutable references to a mutable ones. That is an important difference because owned value is always safe to change comparing to a borrowed one.

Return Ruby's Fiddle::Pointer from C function

I am currently working on a high-performance Vector/Matrix Ruby gem C extension, as I find the built-in implementation cumbersome and not ideal for most cases that I have personally encountered, as well as lacking in other areas.
My first approach was implementing in Ruby as a subclass of Fiddle::CStructEntity, as a goal is to make them optimized for interop without need for conversion (such as passing to native OpenGL functions). Implementing in C offers a great benefit for the math, but I ran into a roadblock when trying to implement a minor function.
I wished to have a method return a Fiddle::Pointer to the struct (basically a pointer to Rdata->data. I wished to return an actual Fiddle::Pointer object. Returning an integer address, packed string, etc. is trivial, and using that could easily be extended in a Ruby method to convert to a Fiddle::Pointer like this:
def ptr
# Assume address is an integer address returned from C
Fiddle::Pointer.new(self.address, self.size)
end
This kind of opened up a question to me, and that is it possible to to even do such from C? Fiddle is not part of the core, library, it is part of the standard lib, and as such, is really just an extension itself.
The problem is trivial, and can be easily overcome with a couple lines of Ruby code as demonstrated above, but was more curious if returning a Fiddle object was even possible from a C extension without hacks? I was unable to find any examples of this being done, and as always when it comes to the documentation involving Fiddle, it is quite basic and does not explain much.
The solution for this is actually rather simple, though admittedly not as elegant or clean of a solution I was hoping to discover.
There are possibly more elaborate ways to go about this by including the headers for Fiddle, and building against it, but this was not really a viable solution, as I didn't want to restrict my C extension to only work with Ruby 2.0+, and would be perfectly acceptable to simply omit the method in the event Ruby version was less than 2.0.
First I include version.h, which gives access defines the macro RUBY_API_VERSION_MAJOR, which is all I really need to know in regards to whether or not Fiddle will be present or not.
This will be an abbreviated version to simply show how to get the Fiddle::Pointer class as a VALUE, and to create an instance.
#if RUBY_API_VERSION_MAJOR >= 2
rb_require("fiddle");
VALUE fiddle = rb_const_get(rb_cObject, rb_intern("Fiddle"));
rb_cFiddlePointer = rb_const_get(fiddle, rb_intern("Pointer"));
#endif
In this example, the class is stored in rb_cFiddlePointer, which can then be used to create and return a Fiddle::Pointer object from C.
// Get basic data about the struct
struct RData *rdata = RDATA(self);
VALUE *args = xmalloc(sizeof(VALUE) * 2);
// Set the platform pointer-size address (could just use size_t here...)
#if SIZEOF_INTPTR_T == 4
args[0] = LONG2NUM((long) rdata->data);
#elif SIZEOF_INTPTR_T == 8
args[0] = LL2NUM((long long) rdata->data);
#else
args[0] = INT2NUM(0);
#endif
// Get size of structure
args[1] = INT2NUM(SIZE_OF_YOUR_STRUCTURE);
VALUE ptr = rb_class_new_instance(2, args, rb_cFiddlePointer);
xfree(args);
return ptr;
After linking the function to an actual Ruby method, you can then call it to get a sized pointer to the internal structure in memory.

What Rust construct uses nearbyint from libsystem_m?

I've profiled my program with Valgrind and Callgrind and found that most of the time is spent in the nearbyint$fenv_access_off function.
I've found that it's a LLVM intrinsic, but which Rust language construct uses it? How can I avoid it?
Doing a search for nearbyint finds the related symbols nearbyintf32 and nearbyintf64. These are documented as returning the nearest integer to a floating point value. However, there appears to be no calls to that specific function.
fenv_access_off appears to be an OS X specific aspect of the math library.
The other thing in your trace is round. I can believe that round could use nearbyint. I also don't see any cases of round in the standard library that seem like they would occur in a tight loop.
Beyond this, anything is pure guessing.
I've reproduced it with:
fn main() {
let data:Vec<_> = (0..999999).map(|x|{
(x as f64).powf(2.2).round() as u8
}).collect();
}
so it seems as u8 is implemented using nearbyint.
It's the same speed as C uchar = round(pow(i, 2.2)), so I'll have to replace it with a good'ol lookup table…

Ruby - passing by value or by reference

I've searched on this, and everyone seems to say Ruby always passes by value, but this simple little example is a subset of a much larger program, and I'm a little confused.
a = "J123"
b = a
a.slice!(0)
puts a
puts b
This displays
123
123
And I don't understand why the value of "b" is changing.
Because both a and b are pointers that refer to the same object. They aren't the object itself. You can only pass pointers as arguments in Ruby, and pointers are passed by value.
This is similar to Java, JavaScript and Python, and unlike C++, C#, Haskell and Scala.
The difference is of interest in the following example:
def f(y)
y = 2
end
x = 1
f(x)
puts x # 1, not 2
If x were passed by reference, it would print 2.
It is pass by value. Everything in ruby is an object. Meaning all variables are actually references(pointers) to that item somewhere in memory.
x = 5 # (5 is stored as object in mem location 0x0001)
y = x # (now y also points to mem location 0x0001)
When you pass your variable into a function and it copies that variable by value - it is copying the memory location address, not the actual object at that memory location.
In your example, both a and b's values (memory locations) were copied by value. However they point to the same memory location, so modifying that location in memory through one variable still modifies the value of the other.
EDIT:
There is a great write-up here (for Java which is also pass-by-value), about how to test whether a language truly supports pass-by-reference.

long double initialization on Mac

I'm quite new to Mac and XCode and now I have a trivial but weird problem.
I'm calling Izero(2.12), you can see the value of the input argument here, while b contains a random value from memory since it has not been initialized yet.
after x*x is executed and a value is assigned to b, b is corrupted!
Please also notice that there's
long double xsqr = 0;
xsqr = x * x;
if I set 0 to xsqr first and then assign x*x to it, xsqr will get the correct value.
I'm running on Mac OS X 10.7.5 and Xcode 3.2.5, could anyone help to have it solved?
Should you have optimization enabled, the compiler possibly doesn't care to generate code that puts something sensible in b, since b isn't used in the rest of function Izero().

Resources