I have an universal iOS app targeting iOS SDK 6.1, and the compiler is set to Apple LLVM compiler 4.2. When I place a breakpoint in my code and run the following I get weird results for sin(int).
For reference, sin(70) = 0.7739 (70 is in radians).
(lldb) p (double)sin(70)
(double) $0 = -0.912706376367676 // initial value
(lldb) p (double)sin(1.0)
(double) $1 = 0.841470984807897 // reset the value sin(int) will return
(lldb) p (double)sin(70)
(double) $2 = 0.841470984807905 // returned same as sin(1.0)
(lldb) p (double)sin(70.0)
(double) $3 = 0.773890681557889 // reset the value sin(int) will return
(lldb) p (double)sin(70)
(double) $4 = 0.773890681558519
(lldb) p (double)sin((float)60)
(double) $5 = -0.304810621102217 // casting works the same as appending a ".0"
(lldb) p (double)sin(70)
(double) $6 = -0.30481062110269
(lldb) p (double)sin(1)
(double) $7 = -0.304810621102223 // every sin(int) behaves the same way
Observations:
The first value for sin(int) in a debug session is always -0.912706376367676.
sin(int) will always return the same value that was returned from the last executed sin(float).
If I replace p with po, or expr (e.g. expr (double)sin(70)), I get the same exact results.
Why is the debugger behaving like this?
Does this mean that I should type cast every single parameter each time I call a function?
Some more interesting behavior with NSLog:
(lldb) expr (void)NSLog(#"%f", (float)sin(70))
0.000000 // new initial value
(lldb) expr (void)NSLog(#"%f", (float)sin(70.0))
0.773891
(lldb) expr (void)NSLog(#"%f", (float)sin(70))
0.000000 // does not return the previous sin(float) value
(lldb) p (double)sin(70)
(double) $0 = 1.48539705402154e-312 // sin(int) affected by sin(float) differently
(lldb) p (double)sin(70.0)
(double) $1 = 0.773890681557889
(lldb) expr (void)NSLog(#"%f", (float)sin(70))
0.000000 // not affected by sin(float)
You're walking into the wonderful world of default argument promotions in C. Remember, lldb doesn't know what the argument types or return type of sin() is. The correct prototype is double sin (double). When you write
(lldb) p (float) sin(70)
there are two problems with this. First, you're providing an integer argument and the C default promotion rules are going to pass this as an int, a 4-byte value on the architectures in question. double, besides being 8-bytes, is an entirely different encoding. So sin is getting garbage input. Second, sin() returns a double, or 8-byte on these architectures, value but you're telling lldb to grab 4 bytes of it and do something meaningful. If you'd called p (float)sin((double)70) (so only the return type was incorrect) lldb would print a nonsensical value like 9.40965e+21 instead of 0.773891.
When you wrote
(lldb) p (double) sin(70.0)
you fixed these mistakes. The default C promotion for a floating point type is to pass it as a double. If you were calling sinf(), you'd have problems because the function expected only a float.
If you want to provide lldb with a proper prototype for sin() and not worry about these issues, it is easy. Add this to your ~/.lldbinit file,
settings set target.expr-prefix ~/lldb/prefix.h
(I have a ~/lldb directory where I store useful python files and things like this) and ~/lldb/prefix.h will read
extern "C" {
int strcmp (const char *, const char *);
void printf (const char *, ...);
double sin(double);
}
(you can see that I also have prototypes for strcmp() and printf() in my prefix file so I don't need to cast these.) You don't want to put too many things in here - this file is prepended to every expression you evaluate in lldb and it will slow your expression evaluations down if you put all the prototypes in /usr/include in there.
With that prototype added to my target.expr-prefix setting:
(lldb) p sin(70)
(double) $0 = 0.773890681557889
Related
So I have this function that calculates the frequency percentage of each letter given a string. this function is called "frequency" and utilizes other helper functions that I've wrote ("count", "lowerCases", and "percent"). But when I try to return my result, I keep getting a mismatch error. Here is my code below:
let frequency(str:string) : float =
let myList = ['a'..'z']
for i=0 to 25 do
printf "%f" (percent ((count myList.[i] str) (lowerCases str)))
System.Console.WriteLine(frequency"hello world")
I keep getting this error:
This expression was expected to have type float but here has type unit
How can I fix this type mismatch error? I've already tried setting my result to a different variable and calling that variable, but that didn't work.
You've declared the function as returning a float:
let frequency(str:string) : float =
However, your function doesn't return a float, it just prints one out:
printf "%f" (percent ((count myList.[i] str) (lowerCases str)))
The printf function returns unit, meaning that it effectively has no return value (it has a constant return value of the singleton type unit).
There are two things that I see you needing to fix here. You need to return a value from the function (by having it be the value of the last line), and I think you will want your return type to be a list or a map instead of a single value (else, how would you know two which letter the frequency applies)?
You can achieve this result by just calling your percent function from List.map, and then making Map of the list:
let frequency(str:string) : Map<char, float> =
['a'..'z']
|> List.map (fun letter -> letter, (percent ((count letter str) (lowerCases str))))
|> Map.ofList
An F# function binds a single value of the single expression in its body (the one which comes last after all let-bindings, simply speaking. In your case, this expression is
for i=0 to 25 do
printf "%f" (percent ((count myList.[i] str) (lowerCases str)))
It has the type unit, meaning it does not return anything useful but a special value (), while the let frequency ... : float = binding says that it returns a float. Hence the error.
printf already prints to console. What you want is probably
let frequency(str:string) : unit =
let myList = ['a'..'z']
for i=0 to 25 do
printf "%f" (percent ((count myList.[i] str) (lowerCases str)))
do frequency "hello world"
It is idiomatic to omit the : unit annotation in such a function, and let the compiler infer the return type. This code does not shine the F# glory, naturally, but does the job.
As it appears you are learning the language, here's an exercise, maybe for the future. Your function lumps together computing the letter frequencies and printing them, and functional programming is all about composition. What if you want to display the result in a window instead of printing it to console, or format it differently? Try to write two functions, one returning a data structure with the letter frequencies, and another printing it.
typedef (void (^blockType)());
I need cast blocks with different argument types into a same type blockType, and invoke it as the original type later. But there is a issue while casting block type.
The following code works well with any argument type, ...
((blockType)^(BOOL b) {
NSLog(#"BOOL: %d", b);
})(YES); // >> BOOL: 1
((blockType)^(int i) {
NSLog(#"int: %d", i);
})(1); // >> int: 1
((blockType)^(double f) {
NSLog(#"double: %f", f);
})(1.0 / 3); // >> double: 0.333333
((blockType)^(NSString *s) {
NSLog(#"NSString *: %#", #"string");
})(1.0 / 3); // >> NSString *: string
except float:
((blockType)^(float f) {
NSLog(#"float: %f", f);
})(1.0f); // >> float: 0.000000
((blockType)^(float f) {
NSLog(#"float: %f", f);
})(1.0f / 3); // >> float: 36893488147419103232.000000
but it is ok without casting:
(^(float f) {
NSLog(#"float without casting: %f", f);
})(1.0 / 3); // >> float without casting: 0.333333
how to explain and resolve it?
It appears to be a taint of the good old C language. Consider the following code (we can say it is kind of 'translation' of your Obj-C block with issues to C as far as blocks are related to function pointers (see here)):
void test()
{
void (*pEmpty)();
pEmpty = functionFloat;
pEmpty(1.0f / 3);
}
void functionFloat(float f)
{
printf("float: %f", f);
}
If you call test you will see the same result as when you invoke your 'sick' block. Compiler will provide just a warning about incompatible pointers and will let you run. But if you change
void (*pEmpty)();
to
void (*pEmpty)(void);
there will be a compile-time error. Same will happen if you add void explicitly to your void-blocks, e.g. (void (^)(void) instead of (void (^)().
The reason for such behavior explained in the C Standard:
The empty list in a function declarator that is not part of a
definition of that function specifies that no information about the number or types of the
parameters is supplied.§6.7.6.3-14 (p.134)
Thus, as it doesn't mean that there are no parameters but rather no info about them, cast passes fine.
The problem with unexpected output is the following:
A pointer to a function of one type may be converted to a pointer to a function of another
type and back again; the result shall compare equal to the original pointer. If a converted
pointer is used to call a function whose type is not compatible with the referenced type,
the behavior is undefined.§6.3.2.3-8 (p.56)
and
If the function is defined with a type that is not compatible with the type (of the
expression) pointed to by the expression that denotes the called function, the behavior is
undefined.§6.5.2.2-9 (p.82)
So, it seems that the solution here is just like #jtbandes said: don't mess block types and re-design this part of code to avoid such casts.
Explain: Calling the block as blockType- (void (^)()), the block is treated as (void (^)(double)).
Resolve: Must cast the block back to (void (^)(float)) when invoking.
I am a bit confused by the Literal keyword and why it is necessary in F#.
Reading the docs, it sounds to me that [<Literal>] is used to define a constant, however I am a bit confused how this constant differs from all other constants in F#..
Values that are intended to be constants can be marked with the
Literal attribute. This attribute has the effect of causing a value to
be compiled as a constant.
When I think of a constant, I think of something which is immutable....
let x = "a" + "b" //this is a immutable value, its value is constant
[<Literal>]
let y = "a" + "b" //this is also a immutable value, but why is this a special constant?
Is it because the 'normal' F# values are evaluated lazily and the [<Literal>] is not evaluated lazily..? is that what they mean with 'compiled as constant'..? or is there something else to it?
In your example, x is an immutable value that is assigned during runtime (but NOT evaluated lazily), whereas y is assigned during compiletime. As an example,
let myDLL = "foo.dll"
[<DllImport(myDLL, CallingConvention = CallingConvention.Cdecl)>]
extern void HelloWorld()
will not work, because DllImport is an attribute and needs to know the value of myDLL during compilation. However, this will work:
[<Literal>]
let myDLL = "foo.dll"
[<DllImport(myDLL, CallingConvention = CallingConvention.Cdecl)>]
extern void HelloWorld()
If you come from C# background, you can think of Literal values as const fields, and non-literal ones as readonly fields. The same differences apply.
I think a better example is what happens in a match.
This doesn't do what you expect:
let t = 3
match q with
|t -> printfn "this always happens"
|_ -> printfn "this never happens" //and produces a compiler warning
on the other hand:
[<Literal>]
let t = 3
match q with
|t -> printfn "q is 3"
|_ -> printfn "q isn't 3"
So here as the Literal is a compile time constant we can use it for pattern matching.
The docs with that paragraph (Literals) briefly refer to "pattern matching", the when clause, and the use of PascalCase identifiers, but need an example for clarity. Unfortunately, the above example of pattern matching is incorrect (by using lowercase t for the literal).
[<Literal>]
let X = 3 // PascalCase by convention for a literal
match 3 with
| X -> "Pattern Matched with X" // PascalCase REQUIRED for pattern matching with a constant.
| x when x = X -> "Matched with X, via 'when'" // lower case is always a local identifier
| _ -> "false"
// RESULT 'val it : string = "Pattern Matched with X"'
Is it possible to somehow create a pow function for measure types?
The pow function in f# only takes int as parameter, and then pow function in the Math class takes a float - but dosent allow float<cm>.
I first thought that:
let rec myPow(x:float<cm>,y:int) =
if y = 0 then x
else myPow(x*x, y - 1)
might work out, but its obvious that each time it come across the else line it will change the return type.
Any suggestions?
I don't think that is possible. You are asking the function to return <cm^2> in case the power is by 2 and <cm^3> in case of 3 and so on. Which makes the function to return different "types" based on the calculation which obviously not possible in a static type and type safe language. Unfortunately, I don't think units of measure can be made "generics" to try that to reach any further.
Your function can have only one static return type.
Ankur is correct - you cannot do this (without resorting to hacks that would break units).
Maybe a clearer description of the problem is that the type of pow function would depend on the value of the argument and F# doesn't allow you to do this. You could imagine this would work if were using just literals as the second argument, but it would become tricky if you used expressions:
pow a 3 // Assuming a = 1.0<cm>, the return type is float<cm ^ 3>
pow a n // Assuming a = 1.0<cm>, the return type is float<cm ^ n>
In the second case the value n would have to appear in the type!
You can use some nasty tricks (inspired by this Haskell article), but it becomes a bit crazy. Instead of using numeric literals, you'd use something like S(S(S(N))) to represent the number 3. This way, you can bring the number into the type. You probably don't want to do this, but here is an example:
[<Measure>] type cm
// Represents a number with units of measure powered to the
// number's value (e.g "(S (S O))" has type Num<cm, cm^3>)
type Num<[<Measure>] 'M, [<Measure>] 'N> =
| O_ of int * float<'N>
| S_ of int * Num<'M, 'N / 'M>
// Constructors that hide that simplify the creation
let O : Num<'M, 'M> = O_ (1, 0.0<_>)
let S n = match n with O_(i, _) | S_(i, _) -> S_(i + 1, n)
// Type-safe power function with units of measure
let pow (x:float<'M>) ((O_(i, _) | S_(i, _)):Num<'M, 'M 'N>) : float<'M 'N> =
// Unsafe hacky implementation, which is hidden
// from the user (for simplicity)
unbox ((float x) ** float i)
let res = pow 2.0<cm> (S (S O))
EDIT: I posted the source code to F# snippets, so that you can see the inferred types: http://fssnip.net/4H
As said, you cannot. If y is not known at compile-time, it's not possible to type check the expression in F# type system.
I suspect you'll use myPow only with a few small and known constants. In this case, you could use the following functions instead and keep static typing:
let inline pow2 (x: float<'a>) : float<'a^2> = pown (float x) 2 * 1.<_>
let inline pow3 (x: float<'a>) : float<'a^3> = pown (float x) 3 * 1.<_>
let inline pow4 (x: float<'a>) : float<'a^4> = pown (float x) 4 * 1.<_>
let inline pow5 (x: float<'a>) : float<'a^5> = pown (float x) 5 * 1.<_>
I am creating Linq expression trees from F# that operates on a custom datatype I have. The type is a very simple discriminated union that has the usual arithmetic operators overloaded. But for some reason I cannot create arithmetic linq expression nodes due to the fact that it can't find the correct overload. Thing is, I swear I had this working some time ago but I can't figure out what I changed to make it break.
I'll attach a small code sample showing the problem. The datatype below has the Addition operator overloaded. Using the overloaded operator works like a charm, but when I try to create an addition expression tree node using Expression.Add(lhs, rhs) the system throws an exception complaining that it can't find the overload for the Add operation.
Does anyone have an idea of what I am doing wrong?
Thank you,
Rickard
open System.Linq.Expressions
module DataType =
exception NotImplementedYet of string
type DataCarrier =
| ScalarCarrier of float
| VectorCarrier of float array
member this.Add(other) =
match (this, other) with
| ScalarCarrier(x), ScalarCarrier(y) -> ScalarCarrier(x + y)
| VectorCarrier(u), VectorCarrier(v) ->
VectorCarrier(Array.map2 (fun x y -> x + y) u v)
| _,_ -> raise (NotImplementedYet("No go!"))
static member (+) (lhs:DataCarrier, rhs) =
lhs.Add(rhs)
module Main =
let createAddOp (lhs:DataType.DataCarrier) (rhs:DataType.DataCarrier) =
let clhs = Expression.Constant(lhs)
let crhs = Expression.Constant(rhs)
Expression.Add(clhs, crhs)
(* no problems with this one *)
printf "Testing operator overloading: %A" (DataType.ScalarCarrier(1.0)
+ DataType.ScalarCarrier(2.0))
(* this throws an exception *)
printf "Testing expr construction %A" (Main.createAddOp
(DataType.ScalarCarrier(1.0))
(DataType.ScalarCarrier(2.0)))
One solution is to explicitly type the Expression operands (giving them the static type DataType.DataCarrier instead of their runtime type DataType.DataCarrier.ScalarCarrier):
module Main =
let createAddOp (lhs:DataType.DataCarrier) (rhs:DataType.DataCarrier) =
let clhs = Expression.Constant(lhs, typeof<DataType.DataCarrier>)
let crhs = Expression.Constant(rhs, typeof<DataType.DataCarrier>)
Expression.Add(clhs, crhs)
Another option would be to explicitly pass the addition operator to use:
module Main =
let createAddOp (lhs:DataType.DataCarrier) (rhs:DataType.DataCarrier) =
let clhs = Expression.Constant(lhs)
let crhs = Expression.Constant(rhs)
Expression.Add(clhs, crhs, typeof<DataType.DataCarrier>.GetMethod("op_Addition"))
I am surprised that your original code doesn't work, though. It appears to be a limitation in how expression trees find relevant add operators (that is, it appears that Linq only looks for add operators on the runtime types of operands).