My iPhone crashlog (and not my Simulator) shows me that I have the following issue:
Dyld Error Message:
Symbol not found: __TFE12CoreGraphicsVSC6CGRectCfMS0_FT1xSi1ySi5widthSi6heightSi_S0_
Referenced from: /private/var/mobile/Containers/Bundle/Application/8F97818E-F019-42E8-883C-6FB1994C24B7/Ekalipi.app/PlugIns/EkalipiKeyboard.appex/EkalipiKeyboard
Expected in: /private/var/mobile/Containers/Bundle/Application/8F97818E-F019-42E8-883C-6FB1994C24B7/Ekalipi.app/PlugIns/EkalipiKeyboard.appex/../../Frameworks/libswiftCoreGraphics.dylib
Dyld Version: 353.5
Is this a Unicode symbol that can't be loaded?
Last meaningful stack entry is this:
6 EkalipiKeyboard 0x0010ad88 0xf5000 + 89480
7 UIKit 0x2acbe4f0 -[_UIViewServiceViewControllerOperator __createViewController:withContextToken:fbsDisplays:appearanceSerializedRepresentations:legacyAppearance:hostAccessibilityServerPort:canShowTextServices:replyHandler:] + 1152
What is the pattern for understanding the above resource string?
Many thanks in advance!
Klaus
That is a mangled label that the compiler generated for that function (the CGRect initializer)
You can break down the full label like this (I think)
__TFE12CoreGraphicsVSC6CGRectCfMS0_FT1xSi1ySi5widthSi6heightSi_S0_
_ is a common beginning of a symbol
_T is the marker for a Swift global symbol
F says that it's a function
I don't know what E means (but looking at the detangled symbol it seems to correspond to ext)
12CoreGraphics is the name of the module (prefixes with the length of the name)
V marks the start of a struct
I don't know what S or what C means
6CGRect is the name of the function (I think it's the function)
I don't know what C means (see M below)
f marks this symbol as an "uncurried function"
I don't know what M means (CfM together seem to mean an init function but I don't know what the individual letters mean)
S0_ is a substitution. I think it's a substitution for "self" which is passed to curry the function
F here marks the beginning of the function's parameter list
T marks the beginning of a "tuple" (for the arguments)
1x is the name of the first parameter (prefixed with the length of the name)
Si says that it is of the Swift.Int type
1y is the name of the second parameter (prefixed with the length of the name)
Si says that it is of the Swift.Int type
5width is the name of the third parameter (prefixed with the length of the name)
Si says that it is of the Swift.Int type
6height is the name of the fourth parameter (prefixed with the length of the name)
Si says that it is of the Swift.Int type
_ marks the end of the uncurried function's arguments tuple
S0_ is the same substitution again (which I think means that it returns "self")
Additionally, running it through xcrun swift-demangle gives the official demangling:
ext.CoreGraphics.C.CGRect.init (C.CGRect.Type)(x : Swift.Int, y : Swift.Int, width : Swift.Int, height : Swift.Int) -> C.CGRect
Gwynne Raskind wrote a very detailed article about Swift Name Mangling where you can read more about this name mangling
Related
I've come across the following code and can not understand what operation the double exclamation marks provide. This code-snipet is from a FAKE script used in a CICD system. Microsoft's Symbol and Operator Reference does not list this operator, nor can I find it in FAKE's API Reference.
!! (projectPackagePath + "/*.zip")
|> Seq.iter(fun path ->
trace ("Removing " + path)
ShellExec tfCommand ("delete " + path + " /noprompt")
Another example of usage
let buildLabelFiles =
!!(labelPath ## "*.txt")
The !! operator takes a file pattern and returns a collection of files matching the pattern.
For example, if you want to print all text files in the current folder, you can write:
for file in !! "*.txt" do
printfn "%s" file
If you look at the operator definition in the source code, you can see that it is just an alias for creating a IGlobbingPattern value (see the type definition) that includes files given by the specified pattern. The IGlobbingPattern type implements IEnumerable, so you can iterate over the files, but you can do a couple of other things with IGlobbingPattern such as combining two file sets using ++ or removing some files from a file set using --.
This question is about characters in identifiers, not keywords as identifiers.
I found this question on C# names, but couldn't readily find the same on F#. Normally this is hardly relevant, but in my tests naming I often use the dot . and was surprised it wasn't supported in a module name, but is supported in a let-binding:
// fails:
module ``Run Test.Me functions`` =
[<Test>]
let ``X.Add should add``() = test <# X.Add 2 2 = 4 #>
// Succeeds
module ``Run Test-Me functions``
[<Test>]
let ``X.Add should add``() = test <# X.Add 2 2 = 4 #>
Outside of naming tests I don't see much use for this, but it made me wonder: what characters are supported by type and module names, and what characters for member names and let bindings?
Some tests:
module ``Weird.name`` = () // fails
module ``Weird-name`` = () // succeeds
module ``Weird()name`` = () // succeeds (?)
module ``Weird*name`` = () // fails
module ``Weird+name`` = () // fails
module ``Weird%name`` = () // succeeds (?)
module ``Weird/name`` = () // fails
module ``Weird\\name`` = () // fails
All of these name succeed in a let-binding or member name, but not as a type name or module name. At least that is consistent. But I can't find any line or logic in what is allowed and what not
Perhaps the limitation is imposed by the CLR / MSIL and not by F# itself?
Take a look at the F# Language Specification 4.0 - In section 3.4 Identifiers and Keywords.
Note that when an identifier is used for the name of a types, union
type case, module, or namespace, the following characters are not
allowed even inside double-backtick marks:
., +, $, &, [, ], /, \\, *, \", `
In addition to this list, the # (at-sign) is allowed in any name, but will raise a warning:
warning FS1104: Identifiers containing '#' are reserved for use in F# code generation
As near as I can find:
The list of characters can be found in the F# compiler with the name IllegalCharactersInTypeAndNamespaceNames.
As this is used for generating IL, that leads to ECMA-335 - Common Language Infrastructure (CLI) Partitions I to VI which reads:
II.5.3 Identifiers - Identifiers are used to name entities. Simple
identifiers are equivalent to an ID. However, the ILAsm syntax allows
the use of any identifier that can be formed using the Unicode
character set (see Partition I). To achieve this, an identifier shall
be placed within single quotation marks.
ID is a contiguous string of characters which starts with either an
alphabetic character (A–Z, a–z)
or one of _, $, #, ` (grave accent), or ?,
and is followed by any number of
alphanumeric characters (A–Z, a–z, 0–9)
or the characters _, $, #, ` (grave accent), and ?
For
subs
|> Array.map (fun x ->
let t, s, _ = x
getAuditEventsAsync s t (now - TimeSpan.FromDays(7.0)) now)
the compiler says for t when applying getAuditEventsAsync:
The type 'string' does not match the type 'string * string'
getAuditEventsAsync is a string -> string -> DateTime -> DateTime -> Async<string> and t and s are strings.
Any hints on why the compiler think I'm attempting to bind a string to a tuple of strings?
Update:
The root cause was actually in getAuditEventsAsync which does
async {
return! Http.AsyncRequestString
( url, httpMethod="GET",
headers = [ Accept HttpContentTypes.Json;
Authorization "Bearer " + t ])
}
for some url and token t where both are strings.
Operator precedence means that Authorization "Bearer " + t is interpreted as (Authorization "Bearer ") + t. Authorization returns string * string, (a non-overloaded) + is thus applied to a string * string and string which confuses the compiler.
The solution was to change Authorization "Bearer " + t to Authorization ("Bearer " + t).
So the question is now: why is the compiler error thrown at the application of getAuditEventsAsync rather than Authorization? :)
Here is a minimal example giving the same error message:
let Accept a = "Accept", a
let foo x = Accept "hoo" + x
foo "z"
The compiler and editor report two error messages, but (for some reason unclear to me) F# Interactive reports only the one you were getting. One of the errors is for + inside foo and the other is when calling foo.
If you comment out the last line, you get just one error on +:
error FS0071: Type constraint mismatch when applying the default type '(string * string)' for a type inference variable. Expecting a type supporting the operator '+' but given a tuple type Consider adding further type constraints
This makes sense and it says that + cannot be applied to tuples. Now, the compiler uses some defaulting mechanism so that it can continue type-checking and it decides that the argument of foo is also string * string. This then gives you the later error message when calling foo:
error FS0001: The type 'string' does not match the type 'string * string'
The confusing thing is that when you uncomment the last line again, the error message for the body of foo also changes to:
error FS0001: The type 'string' does not match the type 'string * string'
This is happening because the compiler now sees that foo is called with string as an argument and so the default guess x : string * string is replaced with x : string. I think this only affects the first error message though and so the second one still uses the default guess that foo takes string * string.
This is not entirely sensible behavior, but I guess that's the best the compiler can do given code with multiple errors - it has to use some default resolution for the error.
What's (in simple terms) the difference between setting a binding (LET) and symbols (=variables) in common lisp?
Symbols and variables are two very different kinds of entities. Symbol is a name of something; variable is a container for a value. Variable can be named by a symbol.
Binding is an association between a symbol and a variable; when binding is in effect, you can refer to a variable by its name. let form creates such a binding.
(let ((a 1))) sets the value of a to 1 until the point where the closing bracket which matches the opening bracket before the let is reached, at which point a reverts to whatever it's previous value was (or becomes undefined). You often see a let in the body of a function where you require local variables which need to go out of scope at the end of the function, so you would use a let there.
(setf a 1) sets a to 1 and assumes that either a has been previously defined (whether by defparameter, defvariable or let) or that a is a new special variable that needs a value.
It's a bit more complicated than that but I'm not sure i have the lisp chops to explain it.
On line 5633 in prim-types.fs (v1.9.7.8) there is the following type abbreviation:
type 'T ``lazy`` = Lazy<'T>
I have a few questions about it.
What do the double backticks mean?
Is this definition equivalent to type lazy<'T> = Lazy<'T>? (If not, how is it different?)
The double back ticks are a way of allowing an F# keyword to be used as an identifier. Another example would be
let ``let`` = 42
To answer the second half of your question, generic types in F# can be specified using either the O'Caml-style syntax where the generic parameter precedes the type (e.g 'a list, int array, etc.), or the .NET-style with angle brackets (e.g. list<'a>, array<int>, etc.), so the two definitions are indeed basically equivalent (except that your version as written is syntactically invalid because lazy is a keyword). For multi-parameter generic types, the O'Caml style is deprecated and will generate a warning (e.g. let (m:(int,string) Map) = Map.empty should be rewritten as let (m:Map<int,string>) = Map.empty).