F# instance syntax - f#

What indicator do you use for member declaration in F#? I prefer
member a.MethodName
this is to many letters and x is used otherwise.

I do almost always use x as the name of this instance. There is no logic behind that, aside from the fact that it is shorter than other options.
The options that I've seen are:
member x.Foo // Simply use (short) 'x' everywhere
member ls.Foo // Based on type name as Benjol explains
member this.Foo // Probably comfortable for C# developers
member self.Foo // I'm not quite sure where this comes from!
member __.Foo // Double underscore to resemble 'ignore pattern'
// (patterns are not allowed here, but '__' is identifier)
The option based on the type name makes some sense (and is good when you're nesting object expressions inside a type), but I think it could be quite difficult to find reasonable two/three abbreviation for every type name.

Don't have a system. Wonder if I should have one, and I am sure there will be a paradigm with its own book some day soon. I tend to use first letter(s) of the type name, like Benjol.
This is a degree of freedom in F# we could clearly do without. :)

I tend to use some kind of initials which represent the type so:
type LaserSimulator =
member ls.Fire() =

I largely tend to use self.MethodName, for the single reason that self represents the current instance by convention in the other language I use most: Python. Come to think of it, I used Delphi for some time and they have self as well instead of this.
I have been trying to convert to a x.MethodName style, similar to the two books I am learning from: Real World Functional Programming and Expert F#. So far I am not succeeding, mainly because referring to x rather than self (or this) in the body of the method still confuses me.
I guess what I am saying is that there should be a meaningful convention. Using this or self has already been standardised by other languages. And I personally don't find the three letter economy to be that useful.

Since I work in the .NET world, I tend to use "this" on the assumption that most of the .NET people who encounter F# will understand its meaning. Of course, the other edge of that sword is that they might get the idea that "this" is the required form.
.NET self-documentation concerns aside, I think I would prefer either: "x" in general, or -- like Benjol -- some abbreviation of the class name (e.g. "st" for SuffixTrie, etc.).

The logic I use is this: if I'm not using the instance reference inside the member definition, I use a double underscore ('__'), a la let-binding expressions. If I am referencing the instance inside the definition (which I don't do often), I tend to use 'x'.

Related

Elixir: rationale behind allowing rebinding of variables

What is the rationale behind allowing rebinding of variables in Elixir, when Erlang doesn't allow that?
Most functional languages don't allow rebinding of variables in the same scope. So Elixir allowing this does definitely give it an non-functional, imperative feel. Erlang's problem is rather lack of scope, or to be more precise that there is only one scope in a whole function clause. We did have serious discussions whether to introduce scope but in the end we decided against it as it was backwards incompatible with the existing system. And developers hate backwards inconsistent changes.
The Erlang way has one serious benefit: when you get it wrong you generally get an error so you can SEE the mistake. This compared just getting strange behaviour when a variable doesn't have the value you expect it to have which is MUCH harder to detect and correct.
Personally I think that the problem of new variable names, for example using the number scheme, is greatly overblown. Compared to the time it takes me to work out WHAT I am going to do changing variable names is trivial. And after a while you just see it without reflecting about it. Honestly.
EDIT:
Also when chaining data through a sequence of functions the actual meaning of the data changes so reusing the same variable name can be very misleading. It can end up just meaning a generic "data I am passing from one function to another".
Here's the rationale straight from the horse's mouth:
http://blog.plataformatec.com.br/2016/01/comparing-elixir-and-erlang-variables/
Because it's simpler.
Take a look at this question posted to the Erlang mailing list in 2009. Specifically this part:
I like pattern matching in the majority of cases, but I find I write
enough code where I need to incrementally update a data structure, and
maintaining that code is a pain when I have code like:
X = foo(),
X1 = bar(X),
X2 = xyzzy(X1),
blah(X2).
and later want to change it to:
X = foo(),
X1 = whee(X),
X2 = bar(X1),
X3 = xyzzy(X2),
blah(X3).
Editor's note--this is the reply to that question.
This goes through IRC a lot. This is a result of poor variable naming
practice, and there is no need to introduce rebinding to "fix" it;
just stop using single letters and counters as variable names.
If for example that was written
FooStateX = foo(),
PostBarX = bar(FooStateX),
OnceXyzziedX = xyzzy(PostBarX),
blah(OnceXyzziedX).
The code demonstrated there isn't all that uncommon in Erlang (note the remark "this goes through IRC a lot"). Elixir's ability to simply rebind names saves us from having to generate new dummy names for things all the time. That's all. It's wise to bear in mind that the original creators of Erlang weren't trying to build a functional language. They were simply pragmatic developers who had a problem to solve. Elixir's approach is simple pragmatism.

No F# generics with constant "template arguments"?

It just occurred to me, that F# generics do not seem to accept constant values as "template parameters".
Suppose one wanted to create a type RangedInt such, that it behaves like an int but is guaranteed to only contain a sub-range of integer values.
A possible approach could be a discriminated union, similar to:
type RangedInt = | Valid of int | Invalid
But this is not working either, as there is no "type specific storage of the range information". And 2 RangedInt instances should be of different type, if the range differs, too.
Being still a bit C++ infested it would look similar to:
template<int low,int high>
class RangedInteger { ... };
Now the question, arising is two fold:
Did I miss something and constant values for F# generics exist?
If I did not miss that, what would be the idiomatic way to accomplish such a RangedInt<int,int> in F#?
Having found Tomas Petricek's blog about custom numeric types, the equivalent to my question for that blog article would be: What if he did not an IntegerZ5 but an IntegerZn<int> custom type family?
The language feature you're requesting is called Dependent Types, and F# doesn't have that feature.
It's not a particularly common language feature, and even Haskell (which most other Functional programming languages 'look up to') doesn't really have it.
There are languages with Dependent Types out there, but none of them I would consider mainstream. Probably the one I hear about the most is Idris.
Did I miss something and constant values for F# generics exist?
While F# has much strong type inference than other .NET languages, at its heart it is built on .NET.
And .NET generics only support a small subset of what is possible with C++ templates. All type arguments to generic types must be types, and there is no defaulting of type arguments either.
If I did not miss that, what would be the idiomatic way to accomplish such a RangedInt in F#?
It would depend on the details. Setting the limits at runtime is one possibility – this would be the usual approach in .NET. Another would be units of measure (this seems less likely to be a fit).
What if he did not an IntegerZ5 but an IntegerZn<int> custom type family?
I see two reasons:
It is an example, and avoiding generics keeps things simpler allowing focus on the point of the example.
What other underlying type would one use anyway? On contemporary systems smaller types (byte, Int16 etc.) are less efficient (unless space at runtime is the overwhelming concern); long would add size without benefit (it is only going to hold 5 possible values).

Is there a standard naming convention for self-identifiers in F#? [duplicate]

This question already has answers here:
Should I use, this, self or something else for self identifiers in type definitions?
(2 answers)
Closed 9 years ago.
Regarding F# self-identifier's as in:
type MyClass2 =
let data = 123
member whateverYouWant.PrintMessage() =
printf "MyClass2 with Data %d" data
The F# class documentation says:
Unlike in other .NET languages, you can name the self identifier
however you want; you are not restricted to names such as self, Me, or
this.
(The answer to the question What are the benefits of such flexible "self-identifiers" in F#? explains the possible usefulness of this.)
My question is, is there perhaps an unofficial standard of what to name the self-identifier? That is, while there may not be a prescriptive convention, is there a descriptive convention of what are F# programmers doing in the wild? this? x? self?
Update
Well looks like this may get closed, but the answer to the other question is hardly an answer as it's just showing multiple options which I'm already aware of. I'm looking for a consensus. Also, that question was asked in 2009 and there might not have been a consensus at that time, while there may be one now.
Also interesting is the book Expert F# 3.0 authored by Don Syme does not use a consistent self-identifier in the examples. Rather it seems to favor single letter self identifiers especially the letter x.
type MyClass2 as self =
let data = 123
let privatePrintMessage() = self.PrintMessage()
member this.PrintMessage() =
printf "MyClass2 with Data %d" data
Some people use member x.Name, but that is faulty because x does not explain what it is, and for one of the most used names in F# - the self identifier should be self-explanatory!
Some people also choose to write member __.Name when the self identifier is unnecessary. Those are usually the same people who make sure there are no unused identifiers (easy to do with --warnon:1182). Other people say that this is weird or that it leads to inconsistency - choose what you like.
There is a couple of options - people often write this or self or x. I think x is probably the least descriptive one, but it is used quite often - perhaps that is a wrong thing! Another good option is to use an identifier that refers to the name of the class (e.g. person or point), because that is quite informative.
type Point(x:float, y:float) =
member point.X = x
member point.Y = y
But I agree that it feels a bit redundant when you're not actually using the self-reference. So using __ would make sense. I think it is a bit unfortunate that you cannot use just ordinary (single) _.
So, in summary, there is probably no single recommended standard - but there is a few common patterns.
A different answer (if you prefer it):
No, there is no standard naming convention for self identifiers. You should choose one for each project, and enforce it.

ObjectPascal identifier naming style on other languages

I learned to program with delphi, and i always liked the object pascal code style, looks very intuitive and clean.
When you look at the variable declaration, you know what are you dealing with..
A fast summary:
Exception E EMyError
Classes and Types T TMyClass
Fields in classes f fVisible
Events On OnMouseDown
Pointer types P PMyRecord
Property Get Something Set SetSomething
It's too bad to use this identifier naming style in C++ C# Java, or any other language code?
Aside from taste and cultural issues (as already pointed by Mason)
There might be reasons why a convention is tied to a certain language, and the other languages might also have reasons for theirs.
I can only quickly think of a few examples though:
On languages that don't require a pointer type to be defined before use (like most non-Borland Pascals, C etc), the "P" one is usually rarely necessary.
Other languages might also have additional means of disambiguating (like in C where often types are upper cased, and the variables or fields get the lowercase identifier), and does not need "T". (strictly speaking Delphi doesn't neither at least for fields, since identifiers are somewhat context dependantly looked up (likeseparate namespaces for fields and types), but the convention is older than that feature)
BTW, you forget "I" for interface, and enum names being prefixed with some prefix derived from the base type name (e.g.
TStringsDefined = set of (sdDelimiter, sdQuoteChar, sdNameValueSeparator,
sdLineBreak, sdStrictDelimiter)
)
etc.
Hmm, this is another language specific bit, since Object Pascal always adds enum names to the global space (instead of requiring enumtype.enumname). With a prefix there is less polution of the global space.
That is one of my pet peeves with Delphi btw, the lack of import control (Modula2 style IMPORT QUALIFIED , FROM xxx IMPORT. Extended Pascal also has some of this)
As far as I know, the T, E, F, and P prefixes are only commonly used in Delphi programming. They're a standard part of the idiom here, but in C# or Java they'd look out of place.
Get and Set are pretty standard across object-oriented programming. Not sure about the On prefix, but it wouldn't surprise me to find that that's common in any event-driven framework.

F#: In real terms, what is the difference between a "string" and a "string option"?

In real terms, what is the difference between a "string" and a "string option"?
Aside from minor sytnax issues, the only difference I have seen is that you can pass a "null" to string while a string option expects a "none".
I don't particularly like the answer I've typed up below, because I think the reader will either see it as 'preaching to the choir' or as 'some complex nonsense', but I've decided to post it anyway, in case it invites fruitful comment-discussion.
First off, it may be noteworthy to understand that
let x : string option = Some(null)
is a valid value, that indicates the presence (rather than absence) of a value (Some rather than None), but the value itself is null. (The meaning of such a value would depend on context.)
If you're looking for what I see as the 'right' mental model, it goes something like this...
The whole notion that "all reference types admit a 'null' value" is one of the biggest and most costly mistakes of .Net and the CLR. If the platform were resdesigned from scratch today, I think most folks agree that references would be non-nullable by default, and you would need an explicit mechanism to opt-in to null. As it stands today, there are hundreds, if not thousands of APIs that take e.g. "string foo" and do not want a null (e.g. would throw ArgumentNullException if you passed null). Clearly this is something better handled by a type system. Ideally, 'string' would mean 'non-null', and for the minority of APIs that do want null, you spell that out, e.g. "Nullable<string> foo" or "Option<string> foo" or whatever. So it's the existing .Net platform that's the 'oddball' here.
Many functional languages (such as ML, one of the main influences of F#) have known this forever, and so designed their type systems 'right', where if you want to admit a 'null' value, you use a generic type constructor to explicitly signal data that intentionally can have 'asbence of a value' as a legal value. In ML, this is done with the "'t option" type - 'option' is a fine, general-purpose solution to this issue. F#'s core is compatible (cross-compiles) with OCaml, an ML dialect, and thus F# inherits this type from its ML ancestry.
But F# also needs to integrate with the CLR, and in the CLR, all references can be null. F# attempts to walk a somewhat fine line, in that you can define new class types in F#, and for those types, F# will behave ML-like (and not easily admit null as a value):
type MyClass() = class end
let mc : MyClass = null // does not compile
however the same type defined in a C# assembly will admit null as a proper value in F#. (And F# still allows a back-door:
let mc : MyClass = Unchecked.defaultof<_> // mc is null
to effectively get around the normal F# type system and access the CLR directly.)
This is all starting to sound complicated, but basically the F# system lets you pretty much program lots of F# in the 'ML' style, where you never need to worry about null/NullReferenceExceptions, because the type system prevents you from doing the wrong things here. But F# has to integrate nicely with .Net, so all types that originate from non-F# code (like 'string') still admit null values, and so when programming with those types you still have to program as defensively as you normally do on the CLR. With regards to null, effectively F# provides a haven where it is easy to do 'programming without null, the way God intended', but at the same time interoperate with the rest of .Net.
I haven't really answered your question, but if you follow my logic, then you would not ask the question (or would unask it, a la Joshu's MU from "Godel, Escher, Bach").
I think you could reclassify this as a more general question
What is the difference between option random ref type and just a random ref type
The difference is with an option, you are providing an explicit empty value case. It's a declarative way of saying "I might not provide a value". A option of value None unambiguously represents a lack of a value.
Often times people use null to represent a lack of a value. Unfortunately this is ambiguous to the casual reader because it's unknown if null represents a valid value or the lack of a value. Option removes this ambiguity.

Resources