Can you define an operator (***) in F#? - f#

I'm working on Arrows in F# and I wanted to create a *** operator. I note, however, that (***), the necessary way to express an operator in a function definition, overlaps with the F# block comment syntax. So how could you actually express this?
I thought of maybe .***. but I think that will actually treat the dots as part of the operator, which I'd rather avoid.

Yes, but you need to add spaces between the parentheses and the asterisks:
let ( *** ) x y = x * y
let z = 4 *** 5

Related

Evaluate a symbolic expression inside a MathematicalProgram constraint

I want to use a symbolic expression as a MathematicalProgram constraint but am unsure how to achieve this. My best go so far is the following (simplified example):
x = Variable("x")
expression = x**2
prog = MathematicalProgram()
v = prog.NewContinuousVariables(1)
prog.AddConstraint(
lambda a: Evaluate(np.array([expression]), {x: a[0].value()}),
lb=np.array([0.0]),
ub=np.array([0.0]),
vars=v,
)
result = Solve(prog)
I'm getting the error PyFunctionConstraint: Output must be of scalar type AutoDiffXd. Got float instead.. Using lambda a: Evaluate(np.array([expression]), {x: a[0]}) does not work due to incompatible function arguments.
I'd highly appreciate any help with this.
I don't think we currently support adding symbolic::Expression as constraint in pydrake yet. On the other hand, we do support ExpressionConstraint in C++ version of Drake.
May I ask why you would like to impose the constraint using symbolic Expression? It is generally much faster to evaluate the constraint, if pass a function directly, something like this
def foo(x):
return np.array([x[0] **2])
prog.AddConstraint(foo, np.array([0.]), np.array([0.]), vars=v)
#Hongkai Dai's answer with the ExpressionConstraint in C++ led me in the right direction. There is such a constraint in pydrake (see here). However, it currently does not support array inputs. The second required insight was that it is possible to use prog.NewContinuousVariables in symbolic expression operations (e.g. Jacobian).
Using these insights, I solved my problem with something similar to the following:
prog = MathematicalProgram()
x = prog.NewContinuousVariables(2)
expression = x[0]**2
J = expression.Jacobian([x[0]])
for i in range(2):
prog.AddConstraint(J[i], 0.0, 0.0)
result = Solve(prog)

Why should successive arguments involving method application be parenthesized?

Suppose the following F# function:
let f (x:int) (y:int) = 42
I suspect that the reason I need to parenthesize the arguments in example z2 below is because of type inference; my example might not be great, but it's easy to imagine how things could get very hairy:
let z1 = f 2 3
let z2 = f 2 (f 3 5)
However, the following case is less clear to me:
let rng = System.Random()
let z3 = f 1 rng.Next(5)
z3 doesn't work, with a clear error message:
error FS0597: Successive arguments should be separated by spaces or
tupled, and arguments involving function or method applications should
be parenthesized.
Fixing it is trivial (parenthesize all the things), but what I am not clear about is why such an expression is a problem. I assume this has to do with type inference again, but naively, it seems to me that here, methods having a list of arguments surrounded by a parenthesis would actually make things less potentially ambiguous. Does this have to do with the fact that rng.Next(5) is equivalent to rng.Next 5?
Can someone hint, give an example or explain why this rule is needed, or what type of problems would arise if it were not there?
I think that the problem here is that the code could be treated as:
let z3 = f 1 rng.Next (5)
This would be equivalent to omitting the parentheses and so it would be calling f with 3 arguments (the second being a function value). This sounds a bit silly, but the compiler actually does not strictly insist on having a space between parameters. For example:
let second a b = b
add 5(1) // This works fine and calls 'add 5 1'
add id(1) // error FS0597
add rng.Next(5) // error FS0597
add (rng.Next(5)) // This works fine (partial application)
I think the problem is that if you look at the sequence of the 4 examples in the above snippet, it is not clear which behavior should you get in the second and the third case.
The call rng.Next(5) is still treated in a special way, because F# allows you to chain calls if they are formed by single-parameter application without space. For example rng.Next(5).ToString(). But, for example, writing second(1)(2) is allowed, but second(1)(2).ToString() will not work.

Was point free functions able to inline?

let inline myfunction x y = ...
let inline mycurried = myfunction x // error, only functions may be marked inline
It seems impossible to explicitly inline curried functions.
So whenever mycurried is called, it won't get inlined even if myfunction is inlined properly, is it correct?
So can this be regarded as one of the drawback of curried function?
I think your question is whether a point-free function can be inlined or not.
The limitation you found is not because of the curried function.
Note that in your example the curried function is on the right side, on the left side you have a point-free function.
F# only allows functions to be inline, not constants.
I principle you may think this could be considered as a bug given that type inference is smart enough to find out that is a (point-free) function, but read the notes from Tomas regarding side-effects.
Apparently when the compiler finds on the left side only an identifier it fails with this error:
let inline myfunction x y = x + y
let inline mycurried = myfunction 1
--> Only functions may be marked 'inline'
As Brian said a workaround is adding an explicit parameter on both sides:
let inline mycurried x = (myfunction 1) x
but then your function is no longer point-free, it's the same as:
let inline mycurried x = myfunction 1 x
Another way might be to add an explicit generic parameter:
let inline mycurried<'a> = myfunction 1
when generic parameters are present explicitly on the left side it compiles.
I wish they remove the error message and turn it a warning, something like:
Since only functions can be 'inline' this value will be compiled as a function.
UPDATE
Thanks Tomas for your answer (and your downvote).
My personal opinion is this should be a warning, so you are aware that the semantic of your code will eventually change, but then it's up to you to decide what to do.
You say that inline is "just an optimization" but that's not entirely true:
. Simply turning all your functions inline does not guarantee optimal code.
. You may want to use static constraints and then you have to use inline.
I would like to be able to define my (kind-of) generic constants, as F# library already does (ie: GenericZero and GenericOne). I know my code will be pure, so I don't care if it is executed each time.
I think you just need to add an explicit parameter to both sides (though I have not tried):
let inline myfunction x y = ...
let inline mycurried y = myfunction 42 y // or whatever value (42)
The compiler only allows inline on let bindings that define a function. This is essentially the same thing as what is happening with F# value restriction (and see also here). As Brian says, you can easily workaround this by adding a parameter to your function.
Why does this restriction exist? If it was not there, then adding inline would change the meaning of your programs and that would be bad!
For example, say you have a function like this (which creates mutable state and returns a counter function):
let createCounter n =
let state = ref n
(fun () -> incr state; !state)
Now, the following code:
let counter = createCounter 0
... creates a single global function that you can use multiple times (call counter()) and it will give you unique integers starting from 1. If you could mark it as inline:
let inline counter = createCounter 0
... then every time you use counter(), the compiler should replace that with createCounter 0 () and so you would get 1 every time you call the counter!

Implementing post / pre increment / decrement when translating to Lua

I'm writing a LSL to Lua translator, and I'm having all sorts of trouble implementing incrementing and decrementing operators. LSL has such things using the usual C like syntax (x++, x--, ++x, --x), but Lua does not. Just to avoid massive amounts of typing, I refer to these sorts of operators as "crements". In the below code, I'll use "..." to represent other parts of the expression.
... x += 1 ...
Wont work, coz Lua only has simple assignment.
... x = x + 1 ...
Wont work coz that's a statement, and Lua can't use statements in expressions. LSL can use crements in expressions.
function preIncrement(x) x = x + 1; return x; end
... preIncrement(x) ...
While it does provide the correct value in the expression, Lua is pass by value for numbers, so the original variable is not changed. If I could get this to actually change the variable, then all is good. Messing with the environment might not be such a good idea, dunno what scope x is. I think I'll investigate that next. The translator could output scope details.
Assuming the above function exists -
... x = preIncrement(x) ...
Wont work for the "it's a statement" reason.
Other solutions start to get really messy.
x = preIncrement(x)
... x ...
Works fine, except when the original LSL code is something like this -
while (doOneThing(x++))
{
doOtherThing(x);
}
Which becomes a whole can of worms. Using tables in the function -
function preIncrement(x) x[1] = x[1] + 1; return x[1]; end
temp = {x}
... preincrement(temp) ...
x = temp[1]
Is even messier, and has the same problems.
Starting to look like I might have to actually analyse the surrounding code instead of just doing simple translations to sort out what the correct way to implement any given crement will be. Anybody got any simple ideas?
I think to really do this properly you're going to have to do some more detailed analysis, and splitting of some expressions into multiple statements, although many can probably be translated pretty straight-forwardly.
Note that at least in C, you can delay post-increments/decrements to the next "sequence point", and put pre-increments/decrements before the previous sequence point; sequence points are only located in a few places: between statements, at "short-circuit operators" (&& and ||), etc. (more info here)
So it's fine to replace x = *y++ + z * f (); with { x = *y + z * f(); y = y + 1; }—the user isn't allowed to assume that y will be incremented before anything else in the statement, only that the value used in *y will be y before it's incremented. Similarly, x = *--y + z * f(); can be replaced with { y = y - 1; x = *y + z * f (); }
Lua is designed to be pretty much impervious to implementations of this sort of thing. It may be done as kind of a compiler/interpreter issue, since the interpreter can know that variables only change when a statement is executed.
There's no way to implement this kind of thing in Lua. Not in the general case. You could do it for global variables by passing a string to the increment function. But obviously it wouldn't work for locals, or for variables that are in a table that is itself global.
Lua doesn't want you to do it; it's best to find a way to work within the restriction. And that means code analysis.
Your proposed solution only will work when your Lua variables are all global. Unless this is something LSL also does, you will get trouble translating LSL programs that use variables called the same way in different places.
Lua is only able of modifying one lvalue per statement - tables being passed to functions are the only exception to this rule. You could use a local table to store all locals, and that would help you out with the pre-...-crements; they can be evaluated before the expression they are contained in is evauated. But the post-...-crements have to be evaluated later on, which is simply not possible in lua - at least not without some ugly code involving anonymous functions.
So you have one options: you must accept that some LSL statements will get translated to several Lua statements.
Say you have a LSL statement with increments like this:
f(integer x) {
integer y = x + x++;
return (y + ++y)
}
You can translate this to a Lua statement like this:
function f(x) {
local post_incremented_x = x + 1 -- extra statement 1 for post increment
local y = x + post_incremented_x
x = post_incremented_x -- extra statement 2 for post increment
local pre_incremented_y = y + 1
return y + pre_incremented_y
y = pre_incremented_y -- this line will never be executed
}
So you basically will have to add two statements per ..-crement used in your statements. For complex structures, that will mean calculating the order in which the expressions are evaluated.
For what is worth, I like with having post decrements and predecrements as individual statements in languages. But I consider it a flaw of the language when they can also be used as expressions. The syntactic sugar quickly becomes semantic diabetes.
After some research and thinking I've come up with an idea that might work.
For globals -
function preIncrement(x)
_G[x] = _G[x] + 1
return _G[x]
end
... preIncrement("x") ...
For locals and function parameters (which are locals to) I know at the time I'm parsing the crement that it is local, I can store four flags to tell me which of the four crements is being used in the variables AST structure. Then when it comes time to output the variables definition, I can output something like this -
local x;
function preIncrement_x() x = x + 1; return x; end
function postDecrement_x() local y = x; x = x - 1; return y; end
... preIncrement_x() ...
In most of your assessment of configurability to the code. You are trying to hard pass data types from one into another. And call it a 'translator'. And in all of this you miss regex and other pattern match capacities. Which are far more present in LUA than LSL. And since the LSL code is being passed into LUA. Try using them, along with other functions. Which would define the work more as a translator, than a hard pass.
Yes I know this was asked a while ago. Though, for other viewers of this topic. Never forget the environments you are working in. EVER. Use what they give you to the best ability you can.

Writing F# code to parse "2 + 2" into code

Extremely just-started-yesterday new to F#.
What I want: To write code that parses the string "2 + 2" into (using as an example code from the tutorial project) Expr.Add(Expr.Num 2, Expr.Num 2) for evaluation. Some help to at least point me in the right direction or tell me it's too complex for my first F# project. (This is how I learn things: By bashing my head against stuff that's hard)
What I have: My best guess at code to extract the numbers. Probably horribly off base. Also, a lack of clue.
let script = "2 + 2";
let rec scriptParse xs =
match xs with
| [] -> (double)0
| y::ys -> (double)y
let split = (script.Split([|' '|]))
let f x = (split[x]) // "This code is not a function and cannot be applied."
let list = [ for x in 0..script.Length -> f x ]
let result = scriptParse
Thanks.
The immediate issue that you're running into is that split is an array of strings. To access an element of this array, the syntax is split.[x], not split[x] (which would apply split to the singleton list [x], assuming it were a function).
Here are a few other issues:
Your definition of list is probably wrong: x ranges up to the length of script, not the length of the array split. If you want to convert an array or other sequence to a list you can just use List.ofSeq or Seq.toList instead of an explicit list comprehension [...].
Your "casts" to double are a bit odd - that's not the right syntax for performing conversions in F#, although it will work in this case. double is a function, so the parentheses are unnecessary and what you are doing is really calling double 0 and double y. You should just use 0.0 for the first case, and in the second case, it's unclear what you are converting from.
In general, it would probably be better to do a bit more design up front to decide what your overall strategy will be, since it's not clear to me that you'll be able to piece together a working parser based on your current approach. There are several well known techniques for writing a parser - are you trying to use a particular approach?

Resources