I'm getting stymied by the way "dot notation" works with objects and records when trying to program in a point-free functional style (which I think is a great, concise way to use a functional language that curries by default).
Is there an operator or function I'm missing that lets me do something like:
(.) object method instead of object.method?
(From what I was reading about the new ? operator, I think it works like this. Except it requires definition and gets into the whole dynamic binding thing, which I don't think I need.)
In other words, can I apply a method to its object as an argument like I would apply a normal function to its argument?
Short answer: no.
Longer answer: you can of course create let-bound functions in a module that call a method on a given type... For example in the code
let l = [1;2;3]
let h1 = l.Head
let h2 = List.hd l
there is a sense in which "List.hd" is the version of what you want for ".Head on a list". Or locally, you can always do e.g.
let AnotherWay = (fun (l:list<_>) -> l.Head)
let h3 = AnotherWay l
But there is nothing general, since there is no good way to 'name' an arbitrary instance method on a given type; 'AnotherWay' shows a way to "make a function out of the 'Head' property on a 'list<_>' object", but you need such boilerplate for every instance method you want to treat as a first-class function value.
I have suggested creating a language construct to generalize this:
With regards to language design
suggestions, what if
SomeType..Foo optArgs // note *two* dots
meant
fun (x : SomeType) -> x.Foo optArgs
?
In which case you could write
list<_>..Head
as a way to 'functionize' this instance property, but if we ever do anything in that arena in F#, it would be post-VS2010.
If I understand your question correctly, the answer is: no you can't. Dot (.) is not an operator in F#, it is built into the language, so can't be used as function.
Related
According the F# specification for operator overloading
<# #> op_Quotation
<## ##> op_QuotationUntyped
is given as with many other operators. Unless I'm missing something I don't believe that I can use this for custom types, so why is it listed?
I think you are right that there is no way of actually using those as custom operators. I suspect those are treated as operators in case this was useful, at some point in the future of the language, for some clever new feature.
The documentation really merely explains how the names of the operators get encoded. For non-special operator names, F# encodes those in a systematic way. For the ones listed in the page, it has a special nicer name. Consider this type:
type X() =
static member (<^><>) (a:int,b:int) = a + b
static member (<# #>) (a:int,b:int) = a + b
If you look at the names of those members:
[ for m in typeof<X>.GetMembers() -> m.Name ]
You see that the first operator got compiled as op_LessHatGreaterLessGreater, while the second one as op_Quotation. So this is where the name memntioned in the table comes in - it is probably good this is documented somewhere, but I think you're right, that this is not particularly useful!
4> abs(1).
1
5> X = abs.
abs
6> X(1).
** exception error: bad function abs
7> erlang:X(1).
1
8>
Is there any particular reason why I have to use the module name when I invoke a function with a variable? This isn't going to work for me because, well, for one thing it is just way too much syntactic garbage and makes my eyes bleed. For another thing, I plan on invoking functions out of a list, something like (off the top of my head):
[X(1) || X <- [abs, f1, f2, f3...]].
Attempting to tack on various module names here is going to make the verbosity go through the roof, when the whole point of what I am doing is to reduce verbosity.
EDIT: Look here: http://www.erlangpatterns.org/chain.html The guy has made some pipe-forward function. He is invoking functions the same way I want to above, but his code doesn't work when I try to use it. But from what I know, the guy is an experienced Erlang programmer - I saw him give some keynote or whatever at a conference (well I saw it online).
Did this kind of thing used to work but not anymore? Surely there is a way I can do what I want - invoke these functions without all the verbosity and boilerplate.
EDIT: If I am reading the documentation right, it seems to imply that my example at the top should work (section 8.6) http://erlang.org/doc/reference_manual/expressions.html
I know abs is an atom, not a function. [...] Why does it work when the module name is used?
The documentation explains that (slightly reorganized):
ExprM:ExprF(Expr1,...,ExprN)
each of ExprM and ExprF must be an atom or an expression that
evaluates to an atom. The function is said to be called by using the
fully qualified function name.
ExprF(Expr1,...,ExprN)
ExprF
must be an atom or evaluate to a fun.
If ExprF is an atom the function is said to be called by using the implicitly qualified function name.
When using fully qualified function names, Erlang expects atoms or expression that evaluates to atoms. In other words, you have to bind X to an atom: X = atom. That's exactly what you provide.
But in the second form, Erlang expects either an atom or an expression that evaluates to a function. Notice that last word. In other words, if you do not use fully qualified function name, you have to bind X to a function: X = fun module:function/arity.
In the expression X=abs, abs is not a function but an atom. If you want thus to define a function,you can do so:
D = fun erlang:abs/1.
or so:
X = fun(X)->abs(X) end.
Try:
X = fun(Number) -> abs(Number) end.
Updated:
After looking at the discussion more, it seems like you're wanting to apply multiple functions to some input.
There are two projects that I haven't used personally, but I've starred on Github that may be what you're looking for.
Both of these projects use parse transforms:
fun_chain https://github.com/sasa1977/fun_chain
pipeline https://github.com/stolen/pipeline
Pipeline is unique because it uses a special syntax:
Result = [fun1, mod2:fun2, fun3] (Arg1, Arg2).
Of course, it could also be possible to write your own function to do this using a list of {module, function} tuples and applying the function to the previous output until you get the result.
I would like to use the .NET CLR version of String.Split in F#. Specifically I would like to use this code:
let main argv =
let s = "Now is the time for FOO good men to come to the aide of their country"
let sepAry = [|"FOO"; "BAR"|]
let z1 = s.Split sepAry
0 // return an integer exit code
This fails to compile however, due to the fact (I believe) that the version of Split in F# is implemented differently than the one in .Net 4.5.
The version from .NET that I would like is:
Split(String[], StringSplitOptions) Returns a string array that contains the substrings in this string that are delimited by elements of a specified string array. A parameter specifies whether to return empty array elements.
I understand that I am getting the F# version of Split, which formerly resided in the PowerPack and that is why the implementation differs from the CLR version.
What is the best way to get what I want? Is it possible to override the F# version of Split and use the .Net version? Is it possible to extend the F# version and if so, how?
The overload you want to use expects a second argument.
let z1 = s.Split (sepAry, System.StringSplitOptions.None)
It's not an “F# version of Split”, it's exactly that Split you see in C#.
2 things are the problem here:
For .NET BCL you need to specify (), because the parameters are declared in different way using tuples (See http://msdn.microsoft.com/en-us/library/dd483468.aspx)
Only the char[] overload exists without StringSplitOptions. If you want to use a string array, you also need to specify StringSplitOptions.
You could create your own F# overload method, that provides a default for the stringsplitoptions.
Kirelagin is right, the Split method on String your trying to use doesn't exist, it's only available for char arrays with no secondary argument. You have to resort to this version: http://msdn.microsoft.com/en-us/library/tabh47cf.aspx. Also you have to use parentheses around your arguments when calling none-f# .NET apis because the arguments in C# are defined as a tuple.
You could of cause define your own extension-method on String, this way you don't have to specify None all the time if that is your expected default behavior
type System.String with
member x.Split(separator : (string [])) = x.Split(separator, System.StringSplitOptions.None)
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).
I'm trying to understand what identifiers represent and what they don't represent.
As I understand it, an identifier is a name for a method, a constant, a variable, a class, a package/module. It covers a lot. But what can you not use it for?
Every language differs in terms of what entities/abstractions can or cannot be named and reused in that language.
In most languages, you can't use an identifier for infix arithmetic operations.
For example, plus is an identifier and you can make a function named plus. But write you can write a = b + c;, there's no way to define an operator named plus to make a = b plus c; work because the language grammar simply does not allow an identifier there.
An identifier allows you to assign a name to some data, so that you can reference it later. That is the limit of what identifiers do; you cannot "use" it for anything other than a reference to some data.
That said, there are a lot of implications that come from this, some subtle. For example, in most languages functions are, to some degree or another, considered to be data, and so a function name is an identifier. In languages where functions are values, but not "first-class" values, you can't use an identifier for a function in an place you could use an identifier for something else. In some languages, there will even be separate namespaces for functions and other data, and so what is textually the same identifier might refer to two different things, and they would be distinguished by the context in which they are used.
An example of what you usually (i.e., in most languages) cannot use an identifier for is as a reference to a language keyword. For example, this sort of thing generally can't be done:
let during = while;
during (true) { print("Hello, world."); }
You could say it's used for everything that you'll want to refer to multiple times, or maybe even once (but use it to clarify the referent's purpose).
What can/can't be named differs per language, it's often quite intuitive, IMHO.
An "Anonymous" entity is something which is not named, although referred to somehow.
#!/usr/bin/perl
$subroutine = sub { return "Anonymous subroutine returning this text"; }
In Perl-speak, this is anonymous - the subroutine is not named, but it is referred to by the reference variable $subroutine.
PS: In Perl, the subroutine would be named like this:
sub NAME_HERE {
# some code...
}
Say, in Java your cannot write something like:
Object myIf = if;
myIf (a == b) {
System.out.println("True!");
}
So, you cannot name some code statement, giving it an alias. While in REBOL it is perfectly possible:
myIf: if
myIf a = b [print "True!"]
What can and what can't be named depends on language, as you see.
as its name implifies, an identifier is used to identify something. so for everything that can be identified uniquely, you can use an identifier. But for example a literal (e.g. string literal) is not unique so you can't use an identifier for it. However you can create a variable and assign a string literal to it.
Making soup out them is rather foul.
In languages such as Lisp, an identifier exists in its own right as an symbol, whereas in languages which are not introspective identifiers don't exist in the runtime.
You write a literal identifier/symbol by putting a single quote in front of it:
[1]> 'a
A
You can create a variable and assign a symbol literal to it:
[2]> (setf a 'Hello)
HELLO
[3]> a
HELLO
[4]> (print a)
HELLO
HELLO
You can set two variables to the same symbol
[10]> (setf b a)
HELLO
[11]> b
HELLO
[12]> a
HELLO
[13]> (eq b a)
T
[14]> (eq b 'Hello)
T
Note that the values bound to b and a are the same, and the value is the literal symbol 'Hello
You can bind a function to the symbol
[15]> (defun hello () (print 'hello))
HELLO
and call it:
[16]> (hello)
HELLO
HELLO
In common lisp, the variable binding and the function binding are distinct
[19]> (setf hello 'goodbye)
GOODBYE
[20]> hello
GOODBYE
[21]> (hello)
HELLO
HELLO
but in Scheme or JavaScript the bindings are in the same namespace.
There are many other things you can do with identifiers, if they are reified as symbols. I suspect that someone more knowledgable than me in Lisp will be able to demonstrate any of the things that you 'can't do with identifiers' exist.
But even Lisp can not make identifier soup.
Sort of a left-field thought, but JSON has all those quotations in it to eliminate the danger of a JavaScript keyword messing up the parsing.