Typed integer constant in OCaml - type-conversion

Lets say you had some code like this
type foo_t = int64
let do_something_with_foo (f : foo_t) = (* left to your imagination *)
And you wanted to call it with a constant "foo", like this:
do_something_with_foo 99
How do you convince the compiler/interpreter that your constant 99 is actually a foo_t?

Use do_something_with_foo 99L.
The constant 99 has type int, 99L has type int64.
This has nothing to do with the type alias foo_t = int64. As long as the definition of foo_t is visible (i.e. not masked by the signature of a containing module), any value of type int64 also has type foo_t and vice-versa.

L letter matters.
# 99L;;
- : int64 = 99L
# 99l;;
- : int32 = 99l
# 99;;
- : int = 99

Related

Function generation with arbitrary signature - revisited

I am resubmitting a question asked almost a decade ago on this site link - but which is not as generic as I would like.
What I am hoping for is a way to construct a function from a list of types, where the final output type can have an arbitrary/default value (such as 0.0 for a float, or "" for a string). So, from
[float; int; float;]
I would get something that amounts to
fun(f: float) ->
fun(i: int) ->
0.0
I am hopeful of achieving this, but am so far unable to. It would be helping me out a lot if I could see a sample that does the above.
The answer in the above link goes some of the way, but the example seems to know its function signature at compile time, which I won't, and also generates a compiler warning.
The scenario I have, for those that find context helpful, is that I want to be able to open a dll and one way or another identify a method which will have a given signature with argument-types limited to a known set of types (i.e. float, int). For each input parameter in this function signature I will run code to generate a 'buffer' object, which will have
a buffer of data items of the given type, i.e. [1.2; 3.2; 4.5]
a supplier of that data type (supplies may be intermittent so the receiving buffer may be empty at any one time)
a generator function that transforms data items before being dispatched. This function can be updated at any time.
a dispatch function. The dispatch target of bufferA will be bufferB, and for bufferB it will be a pub-sub thing where subscribers can subscribe to the end result of the calculation, in this case a stream of floats. Data accumulates in applicative style down the chain of buffers, until the final result is published as a new stream.
a regulator that turns the stream of data heading out to the consumer on or off. This ensures orderly function application.
The function from the dll will eventually be given to BufferA to apply to a float and pass the result on to buffer B (to pick up an int). However, while setting up the buffer infrastructure I only need a function with the correct signature, so a dummy value, such as 0.0, is fine.
For a function of a known signature I can handcraft the code that creates the necessary infrastructure, but I would like to be able to automate this, and ideally register dlls and have new calculated streams available plugin-style without rebuilding the application.
If you're willing to throw type safety out the window, you could do this:
let rec makeFunction = function
| ["int"] -> box 0
| ["float"] -> box 0.0
| ["string"] -> box ""
| "int" :: types ->
box (fun (_ : int) -> makeFunction types)
| "float" :: types ->
box (fun (_ : float) -> makeFunction types)
| "string" :: types ->
box (fun (_ : string) -> makeFunction types)
| _ -> failwith "Unexpected"
Here's a helper function for invoking one of these monstrosities:
let rec invokeFunction types (values : List<obj>) (f : obj) =
match types, values with
| [_], [] -> f
| ("int" :: types'), (value :: values') ->
let f' = f :?> (int -> obj)
let value' = value :?> int
invokeFunction types' values' (f' value')
| ("float" :: types'), (value :: values') ->
let f' = f :?> (float -> obj)
let value' = value :?> float
invokeFunction types' values' (f' value')
| ("string" :: types'), (value :: values') ->
let f' = f :?> (string -> obj)
let value' = value :?> string
invokeFunction types' values' (f' value')
| _ -> failwith "Unexpected"
And here it is in action:
let types = ["int"; "float"; "string"] // int -> float -> string
let f = makeFunction types
let values = [box 1; box 2.0]
let result = invokeFunction types values f
printfn "%A" result // output: ""
Caveat: This is not something I would ever recommend in a million years, but it works.
I got 90% of what I needed from this blog by James Randall, entitled compiling and executing fsharp dynamically at runtime. I was unable to avoid concretely specifying the top level function signature, but a work-around was to generate an fsx script file containing that signature (determined from the relevant MethodInfo contained in the inspected dll), then load and run that script. James' blog/ github repository also describes loading and running functions contained in script files. Having obtained the curried function from the dll, I then apply it to default arguments to get representative functions of n-1 arity using
let p1: 'p1 = Activator.CreateInstance(typeof<'p1>) :?> 'p1
let fArity2 = fArity3 p1
Creating and running a script file is slow, of course, but I only need to perform this once when setting up the calculation stream

Chisel UInt negative value error

I have recently started work in scala, and am required to create an implementation of MD5. It is my understanding that MD5 requires unsigned types, which scala does not come with. As I will soon begin Chisel, which does have unsigned types, I decided to implement its library. Everything appears good so far, except when doing the below bitwise operations, my F value becomes -271733879, which causes an error "Caused by: java.lang.IllegalArgumentException: requirement failed: UInt literal -271733879 is negative" as UInts can't be negative.
if(i<16){
F = ((B & C) | ((~B) & D))
g = i
}
There is more to the error message, but it is just the trace list of different libraries and classes that had an error because of this error, and thus I did not post it because I didn't think it was important. If it was, I can edit this and post it all.
My B, C, and D values are equal to the lower case equivalents listed below, and it is the first time through the for loop so they have not yet updated.
var a0 : UInt = UInt(0x67452301)
var b0 : UInt = UInt(0xefcdab89)
var c0 : UInt = UInt(0x98badcfe)
var d0 : UInt = UInt(0x10325476)
Any Help would be greatly appreciated.
For the sake of my answer, I am using the Chisel 3 preferred 123.U style for specifying literals rather than the Chisel 2 UInt(123) style, but this answer works for either.
There are several ways you could do this:
Use Scala Long (put L at end of literal)
val myUInt = 0x98badcfeL.U
This obviously won't work for larger than 64-bit
Use Scala BigInt
val myUInt = BigInt("98badcfe", 16).U
Use Chisel's shorthand for constructing BigInts from Strings
val myUInt = "x98badcfe".U
hex = x | h, dec = d, oct = o, bin = b

How does dereference work C++

I have trouble understanding what happens when calling &*pointer
int j=8;
int* p = &j;
When I print in my compiler I get the following
j = 8 , &j = 00EBFEAC p = 00EBFEAC , *p = 8 , &p = 00EBFEA0
&*p= 00EBFEAC
cout << &*p gives &*p = 00EBFEAC which is p itself
& and * have same operator precedence.I thought &*p would translate to &(*p)--> &(8) and expected compiler error.
How does compiler deduce this result?
You are stumbling over something interesting: Variables, strictly spoken, are not values, but refer to values. 8 is an integer value. After int i=8, i refers to an integer value. The difference is that it could refer to a different value.
In order to obtain the value, i must be dereferenced, i.e. the value stored in the memory location which i stands for must be obtained. This dereferencing is performed implicitly in C whenever a value of the type which the variable references is requested: i=8; printf("%d", i) results in the same output as printf("%d", 8). That is funny because variables are essentially aliases for addresses, while numeric literals are aliases for immediate values. In C these very different things are syntactically treated identically. A variable can stand in for a literal in an expression and will be automatically dereferenced. The resulting machine code makes that very clear. Consider the two functions below. Both have the same return type, int. But f has a variable in the return statement which must be dereferenced so that its value can be returned (in this case, it is returned in a register):
int i = 1;
int g(){ return 1; } // literal
int f(){ return i; } // variable
If we ignore the housekeeping code, the functions each translate into a sigle machine instruction. The corresponding assembler (from icc) is for g:
movl $1, %eax #5.17
That's pretty starightforward: Put 1 in the register eax.
By contrast, f translates to
movl i(%rip), %eax #4.17
This puts the value at the address in register rip plus offset i in the register eax. It's refreshing to see how a variable name is just an address (offset) alias to the compiler.
The necessary dereferencing should now be obvious. It would be more logical to write return *i in order to return 1, and write return i only for functions which return references — or pointers.
In your example it is indeed illogical to a degree that
int j=8;
int* p = &j;
printf("%d\n", *p);
prints 8 (i.e, p is actually dereferenced twice); but that &(*p) yields the address of the object pointed to by p (which is the address value stored in p), and is not interpreted as &(8). The reason is that in the context of the address operator a variable (or, in this case, the L-value obtained by dereferencing p) is not implicitly dereferenced the way it is in other contexts.
When the attempt was made to create a logical, orthogonal language — Algol68 —, int i=8 indeed declared an alias for 8. In order to declare a variable the long form would have been refint m = loc int := 3. Consequently what we call a pointer or reference would have had the type ref ref int because actually two dereferences are needed to obtain an integer value.
j is an int with value 8 and is stored in memory at address 00EBFEAC.
&j gives the memory address of variable j (00EBFEAC).
int* p = &j Here you define a variable p which you define being of type int *, namely a value of an address in memory where it can find an int. You assign it &j, namely an address of an int -> which makes sense.
*p gives you the value associated with the address stored in p.
The address stored in p points to an int, so *p gives you the value of that int, namely 8.
& p is the address of where the variable p itself is stored
&*p gives you the address of the value the memory address stored in p points to, which is indeed p again. &(*p) -> &(j) -> 00EBFEAC
Think about &j itself (or even &(j)). According to your logic, shouldn't j evaluate to 8 and result in &8, as well? Dereferencing a pointer or evaluating a variable results in an lvalue, which is a value that you can assign to or take the address of.
The L in "lvalue" refers to the left in "left hand side of the assignment", such as j = 10 or *p = 12. There are also rvalues, such as j + 10, or 8, which obviously cannot be assigned to.
That's just a basic explanation. In C++ there's a lot more to it, with various classes of values (but that thread might be too advanced for your current needs).

Swift type casting and parenthesis

Both of this type casting works
Edit
(as written by Nate Cook this is not a real Type Casting, in Swift type casting is done with the as keyword. With the following call I'm initializing an Int64 with a Float parameter.)
anInt = Int64(aFloat)
anInt = (Int64)(aFloat)
First
var anInt : Int64 = 0
var aFloat : Float = 11.5
anInt = Int64(aFloat)
println(anInt) // this prints 11
Second
var anInt : Int64 = 0
var aFloat : Float = 11.5
anInt = (Int64)(aFloat)
println(anInt) // this prints 11
In the second example the main difference is that there are parenthesis around the type Int64, but I don't find any information about this syntax in the docs.
The statement Int64(aFloat) is a typical initializer call that creates an Int64 passing a Float as the initialization parameters. Is this correct?
What is the meaning of the parenthesis in (Int64)(aFloat)? Is for better readability or there is another meaning?
Thanks
It looks like you can add an arbitrary number of parentheses (e.g. (((Int64)))). The main reason for the parentheses is to make a cast like (object as SomeClass).method()
See the duplicate question, but the short answer is that (Int) declares a tuple containing a single Int, which is semantically identical, per language specification, to a single Int Int.

Get letter corresponding to number in e (IEEE 1646)

I want to convert from integer values to string characters as follows:
0 to "a"
1 to "b"
and so forth up to
26 to "z"
Is there a way to do this in e without a big case statement?
Note: e is strongly typed and it isn't possible to do any type of arithmetic on string values. There also isn't any char-like type.
Another node: To all you C/C++ hotshots who keep down-voting my question, this isn't as easy a problem as you might think.
You can do something like this:
{0c"a"+my_num}.as_a(string)
0c"a" denotes the ASCII value of the letter 'a'. And an as_a() conversion of a list of numbers (actually, bytes) into a string creates a string where each character has the ASCII value of the corresponding list element.
You can define a new enum type to correspond to the alphabet, and use the fact that enum values are backed by int values to transform a list of ints to a list of enums, or to a string.
Consider the following example:
<'
type chars : [a, b, c, d, e, f, g];
extend sys {
run() is also {
var l : list of int[0..6];
var s: string = "";
gen l keeping {it.size() == 5};
print l;
for each in l { print it.as_a(chars); };
for each in l { s = append(s, it.as_a(chars)); };
print s;
};
};
'>
The output of this example will be:
l =
0. 4
1. 0
2. 6
3. 4
4. 5
it.as_a(chars) = e
it.as_a(chars) = a
it.as_a(chars) = g
it.as_a(chars) = e
it.as_a(chars) = f
s = "eagef"
Note that you can assign custom values to elements in the enum. In that way, you can assign standard ASCII values to enum elements.
type chars : [a=10, b=11, c=12, d=13, e=14, f=15, g=16];