Is it possible to define the ** operator in F# - f#

let (**) ls1 ls2 = List.intersect ls1 ls2
does not work because (**) is considered a comment. Is there any escape possibility?

You can add whitespace inside the parentheses, like this:
let ( ** ) ls1 ls2 = List.intersect ls1 ls2
Keep in mind, however, that ** is a standard F# operator for "power":
2 ** 3 = 8
So if you redefine it like this in the global context, you will not be able to use it in the "power" sense.

Related

Evaluating constant expressions in clang tools

I'm writing a Clang tool and I'm trying to figure out how to evaluate a string literal given access to the program's AST. Given the following program:
class DHolder {
public:
DHolder(std::string s) {}
};
DHolder x("foo");
I have the following code in the Clang tool:
const CXXConstructExpr *ctor = ... // constructs `x` above
const Expr *expr = ctor->getArg(0); // the "foo" expression
???
How can I get from the Expr representing the "foo" string literal to an actual C++ string in my tool? I've tried to do something like:
// From ExprConstant.cpp
Evaluate(result, info, expr);
but I don't know how to initialize the result and info parameters.
Any clues?
I realize this is an old question, but I ran into this a moment ago when I could not use stringLiteral() to bind to any arguments (the code is not C++11). For example, I have a CXXMMemberCallExpr:
addProperty(object, char*, char*, ...); // has 7 arguments, N=[0,6]
The AST dump shows that ahead of the StringLiteral is a CXXBindTemporaryExpr. So in order for my memberCallExpr query to bind using hasArgument(N,expr()), I wrapped my query with bindTemporaryExpr() (shown here on separate lines for readability):
memberCallExpr(
hasArgument(6, bindTemporaryExpr(
hasDescendant(stringLiteral().bind("argument"))
)
)
)
The proper way to do this is to use the AST matchers to match the string literal and bind a name to it so it can be later referenced, like this:
StatementMatcher m =
constructExpr(hasArgument(0, stringLiteral().bind("myLiteral"))).bind("myCtor");
and then in the match callback do this:
const CXXConstructExpr *ctor =
result.Nodes.getNodeAs<CXXConstructExpr("optionMatcher");
const StringLiteral *optNameLiteral =
result.Nodes.getNodeAs<StringLiteral>("optName");
The literal can then be accessed through
optNameLiteral->getString().str();

Why is using the base key word causing this error?

I am trying to do an example for Programming F# by O'Railey, Chris Smith page 53.
It is working with functions returning functions.
This line straight from the book in the VS2013 IDE Editor, FSI and LinqPad4 are giving an error:
Code:
let generatePowerOfFunc base = (fun exponent -> base ** exponent)
Error:
error FS0010: Unexpected keyword 'base' in pattern
What am I missing or is there something the author did not include that needs to be included.
I strongly suspect it's merely a matter of base not being a keyword when the book was written.
Try a different identifier:
let generatePowerOfFunc b = (fun exponent -> b ** exponent)
Assuming you've got the 2009 edition of Programming F#, that would be before F# 2.0 was released (although after 1.0). I'm trying to find out exactly when it was introduced as a keyword...
EDIT: Actually, looking at this version of the spec which was written in 2009, it looks like base was already a keyword at that point. I wonder whether the original code was written significantly before the book was published.
Either way, I think it's reasonable to treat it basically as an error, and using a valid identifier instead should be fine.
EDIT: It's actually listed in the book's errata:
Example 3-3 does not work as-is in VS 2010. "base" is apparently a keyword, so it should have been escaped or there is some voodoo to make it not a keyword that I've missed in the book. Line 2 of the example should look like this:
let generatePowerOfFunc ``base`` = (fun exponent -> ``base`` ** exponent);;
Alternatively, a different variable name should be chosen.
Note from the Author or Editor:
Thanks for the feedback, I must have missed the keyword being marked as reserved late in the product cycle.
In a future version of the book I'll have it read:
let generatePowerOfFunc baseValue = (fun exponent -> baseValue ** exponent);;
base in F# is a keyword, which refers to the parent class.
Either you can use double backticks as follows
let generatePowerOfFunc ``base`` = (fun exponent -> ``base`` ** exponent);;
or just change the name of the argument to something else.

Lua Semicolon Conventions

I was wondering if there is a general convention for the usage of semicolons in Lua, and if so, where/why should I use them? I come from a programming background, so ending statements with a semicolon seems intuitively correct. However I was concerned as to why they are "optional" when its generally accepted that semicolons end statements in other programming languages. Perhaps there is some benefit?
For example: From the lua programming guide, these are all acceptable, equivalent, and syntactically accurate:
a = 1
b = a*2
a = 1;
b = a*2;
a = 1 ; b = a*2
a = 1 b = a*2 -- ugly, but valid
The author also mentions: Usually, I use semicolons only to separate two or more statements written in the same line, but this is just a convention.
Is this generally accepted by the Lua community, or is there another way that is preferred by most? Or is it as simple as my personal preference?
Semi-colons in Lua are generally only required when writing multiple statements on a line.
So for example:
local a,b=1,2; print(a+b)
Alternatively written as:
local a,b=1,2
print(a+b)
Off the top of my head, I can't remember any other time in Lua where I had to use a semi-colon.
Edit: looking in the lua 5.2 reference I see one other common place where you'd need to use semi-colons to avoid ambiguity - where you have a simple statement followed by a function call or parens to group a compound statement. here is the manual example located here:
--[[ Function calls and assignments can start with an open parenthesis. This
possibility leads to an ambiguity in the Lua grammar. Consider the
following fragment: ]]
a = b + c
(print or io.write)('done')
-- The grammar could see it in two ways:
a = b + c(print or io.write)('done')
a = b + c; (print or io.write)('done')
in local variable and function definition. Here I compare two quite similar sample codes to illustrate my point of view.
local f; f = function() function-body end
local f = function() function-body end
These two functions can return different results when the function-body section contains reference to variable "f".
Many programming languages (including Lua) that do not require semicolons have a convention to not use them, except for separating multiple statements on the same line.
Javascript is an important exception, which generally uses semicolons by convention.
Kotlin is also technically an exception. The Kotlin Documentation say not only not to use semicolons on non-batched statements, but also to
Omit semicolons whenever possible.
In local variable definitions, we get ambiguous results from time to time:
local a, b = string.find("hello world", "hello") --> a = nil, b = nil
while sometimes a and b are assigned the right values 7 and 11.
So I found no choice but to follow one of these two approaches:
local a, b; a, b = string.find("hello world", "hello") --> a, b = 7, 11
local a, b
a, b = string.find("hello world", "hello") --> a, b = 7, 11
For having more than one thing on a line, for example:
c=5
a=1+c
print(a) -- 6
could be shortened to:
c=5; a=1+c; print(a) -- 6
also worth noting that if you're used to Javascript, or something like that, where you have to end a line in a semicolon, and you're especially used to writing that, then this means that you won't have to remove that semicolon, and trust me, i'm used to Javascript too, and I really, really forget that you don't need the semicolon, every time I write a new line!

What's with "Uppercase variable identifiers should not generally be used in patterns..."?

This compiler like:
let test Xf Yf = Xf + Yf
This compiler no like:
let test Xfd Yfd = Xfd + Yfd
Warning:
Uppercase variable identifiers should not generally be used in patterns, and may indicate a misspelt pattern name.
Maybe I'm not googling properly, but I haven't managed to track down anything which explains why this is the case for function parameters...
I agree that this error message looks a bit mysterious, but there is a good motivation for it. According to the F# naming guidelines, cases of discriminated unions should be named using PascalCase and the compiler is trying to make sure that you don't accidentally misspell name of a case in pattern matching.
For example, if you have the following union:
type Side =
| Left
| Right
You could write the following function that prints "ok" when the argument is Left and "wrong!" otherwise:
let foo a =
match a with
| Lef -> printfn "ok"
| _ -> printfn "wrong!"
There is a typo in the code - I wrote just Lef - but the code is still valid, because Lef can be interpreted as a new variable and so the matching assigns whatever side to Lef and always runs the first case. The warning about uppercase identifiers helps to avoid this.
F# tries to enforce case rules for active patterns - consider what does this code do
let f X =
match X with
|X -> 1
|_ -> 2
This is quite confusing. Also, function parameters are similar to patterns, you can do
let f (a,b,_) = a,b
for example. Not quite sure why the third letter triggers the warning though

Why is ";;" required in F# interactive?

Why is ";;" required in F# interactive at the end of a command? For instance, IronPython doesn't require it?
EDIT:
When do you put double semicolons in F#?
covers most of the historical background
I guess my point was if you are using mostly one-liners in interactive it's cumbersome; however I see the value of ';;' when building functions interactively.
Historically, I believe that this was inherited from OCaml - see https://stackoverflow.com/a/2669731/82959.
How does the compiler know when you want to end your function - both of these are valid
let func() =
System.Console.Read() |> ignore
and
let func() =
System.Console.Read() |> ignore
1
So we need ;; to know where the function ends

Resources