I have been programming in f# for a few weeks now and decided that I would now try out some of the object oriented features. I am wondering though, how to reference a method in a class from within another method in that class. Here is an (admittedly contrived) but deliberately simple example of what I am talking about.
type MathsOperations =
static member addOne (a : int) : int =
a + 1
static member addTwo (a : int) : int =
1 + (addOne a)
Here in the addTwo method I get the error that addOne is not defined.
Related
I am currently learning D and struggling to understand how operator overloading could work for a class? Overriding opCmp makes sense and works correctly for a struct, but for a class it requires taking the right hand side as a Object instead of as my type.
This means I can't access any members to do a comparison. What's the point in the overload then? Am I missing something?
Sure you can access your members:
class MyClass {
int member;
override int opCmp(Object other) {
if (auto mcOther = cast(MyClass)other) {
// other, and thus mcOther, is an instance of MyClass.
// So we can access its members normally:
return member < mcOther.member ? -1
: member > mcOther.member ? 1
: 0;
} else {
// other is not a MyClass, so we give up:
assert(0, "Can't compare MyClass with just anything!");
}
}
}
The reason opCmp for classes takes Object as a parameter is it's being introduced in the Object class, from which every D class derives. Introducing opCmp there was a sensible choice back in the day, but less so now. However, since we don't want to break every piece of D code out there that uses opCmp (and opEquals, toHash and toString) with classes, we're kinda stuck with that choice.
What is 'Access specifier' in Object oriented programming ?
I have searched for it's definition several times but not get the satisfactory answer.
Can anyone please explain it to me with realistic example ?....
Thanks in advance
What are they?
This wikipedia article pretty much sums it up. But Let's elaborate on a few main points. It starts out saying:
Access modifiers (or access specifiers) are keywords in object-oriented languages that set the accessibility of classes, methods, and other members. Access modifiers are a specific part of programming language syntax used to facilitate the encapsulation of components.1
So an Access Specifier aka Access Modifier takes certain class, method, or variable and decides what other classes are allowed to use them. The most common Access Specifiers are Public, Protected, and Private. What these mean can vary depending on what language you are in, but I'm going to use C++ as an example since that's what the article uses.
Accessor Method | Who Can Call It
-----------------------------------------------------------------------
Private | Only the class who created it
Protected | The class who created it and derived classes that "inherit" from this class
Public | Everyone can call it
Why is this important?
A big part of OOP programming is Encapsulation. Access Specifiers allow Encapsulation. Encapsulation lets you choose and pick what classes get access to which parts of the program and a tool to help you modularize your program and separate out the functionality. Encapsulation can make debugging a lot easier. If a variable is returning an unexpected value and you know the variable is private, then you know that only the class that created it is affecting the values, so the issue is internal. Also, it stops other programmers from accidentally changing a variable that can unintentionally disrupt the whole class.
Simple Example
Looking at the example code from the article we see Struct B i added the public in there for clarity:
struct B { // default access modifier inside struct is public
public:
void set_n(int v) { n = v; }
void f() { cout << "B::f" << endl; }
protected:
int m, n; // B::m, B::n are protected
private:
int x;
};
This is what would happen if you created an inherited struct C that would try and use members from struct B
//struct C is going to inherit from struct B
struct C :: B {
public:
void set_m(int v) {m = v} // m is protected, but since C inherits from B
// it is allowed to access m.
void set_x(int v) (x = v) // Error X is a private member of B and
// therefore C can't change it.
};
This is what would happen if my main program where to try and access these members.
int main(){
//Create Struct
B structB;
C structC;
structB.set_n(0); // Good Since set_n is public
structB.f(); // Good Since f() is public
structB.m = 0; // Error because m is a protected member of Struct B
// and the main program does not "inherit" from struct B"
structB.x = 0; // Error because x is a private member of Struct B
structC.set_n() // Inheritied public function from C, Still Good
structC.set_m() // Still Good
structC.m = 0 // Error Main class can't access m because it's protected.
structC.x = 0; // Error still private.
return 0;
}
I could add another example using inheritance. Let me know if you need additional explanation.
The follow codes produces "prog.go:17: c.Test undefined (type Child has no field or method Test)". (http://play.golang.org/p/g3InujEX9W)
package main
import "fmt"
type Base struct {
X int
}
func (b Base) Test() int {
return b.X
}
type Child Base
func main() {
c := Child{4}
fmt.Println(c.Test())
}
I realize Test is technically defined on Base, but should Child inherit that method?
the way to go for inheritance in go is using struct embedding with anonymous struct members.
Here is an adaption of your example.
Read about struct embedding and go's approach to inheritance etc here
The behaviour you encountered is expected and in sync with the golang specification, which explicitly states that:
The method set of any type T consists of all methods with receiver type T. The method set of the corresponding pointer type *T is the set of all methods with receiver *T or T (that is, it also contains the method set of T). Further rules apply to structs containing anonymous fields, as described in the section on struct types. Any other type has an empty method set.
The object in the below code has been instantiated just once, right? So the single object that has been instantiated should contain a single integer i field whose value is 2. Why does p.i give 1 instead of 2? Is this specific to SystemVerilog? Or do all oop languages behave similarly?
class Packet;
integer i = 1;
function integer get();
get = i;
endfunction
endclass
class LinkedPacket extends Packet;
integer i = 2;
function integer get();
get = -i;
endfunction
endclass
LinkedPacket lp = new;
Packet p = lp;
j = p.i; // j = 1, not 2
j = p.get(); // j = 1, not -1 or –2
Thanks
This example is pasted from section 8.13 of the the 1800-2009 SystemVerilog specification, which explains the issue. My opinion is that overriding class members like this is a really bad idea. The example in the specification is simply there to illustrate how it works.
The class property integer i is defined in both the base class and child class. This declaration in LinkedPacket overrides and hides the declaration in Packet.
From the specification:
In this case, references to p access the methods and class properties of the Packet class. So, for example, if
class properties and methods in LinkedPacket are overridden, these overridden members referred to
through p get the original members in the Packet class. From p, new and all overridden members in
LinkedPacket are now hidden.
Since you are calling the function through a handle to Packet you get the values from Packet.
In addition, the get() function is not declared virtual. This is why you do not see the integer being negated. This is also noted in the example in the specification.
To call the overridden method via a base class object (p in the example), the method needs to be declared
virtual (see 8.19).
This behavior is not unique to SystemVerilog and is similar to what you would observe in other OO languages.
If you want to have a different value for i in LinkedPacket, the proper way to do this would be to only declare i in the base class, and initialize it differently in the constructor.
e.g.
class Packet;
integer i;
function new();
i = 1;
endfunction
virtual function integer get();
get = i;
endfunction
endclass
class LinkedPacket extends Packet;
function new();
i = 2;
endfunction
virtual function integer get();
get = -i;
endfunction
endclass
I'm no SystemVerilog expert, but I'd expect p.i to return 1 as that is what you initialise it to. p.get() is just another way to return the same value, so that will also be 1.
j=get(); will (I think) return -2 - without an object prefix, I'd expect it to call the second function which is outside of the class.
I am currently implementing a Spec framework in F# and I want to hide the Equals, GetHashCode etc. methods on my should type, so that the API is not cluttered with these.
I know in C# it is done by making the class implement an interface like this:
using System;
using System.ComponentModel;
public interface IFluentInterface
{
[EditorBrowsable(EditorBrowsableState.Never)]
bool Equals(object other);
[EditorBrowsable(EditorBrowsableState.Never)]
string ToString();
[EditorBrowsable(EditorBrowsableState.Never)]
int GetHashCode();
[EditorBrowsable(EditorBrowsableState.Never)]
Type GetType();
}
I tried doing the same in F#:
type IFluentInterface = interface
[<EditorBrowsable(EditorBrowsableState.Never)>]
abstract Equals : (obj) -> bool
[<EditorBrowsable(EditorBrowsableState.Never)>]
abstract ToString: unit -> string
[<EditorBrowsable(EditorBrowsableState.Never)>]
abstract GetHashCode: unit -> int
[<EditorBrowsable(EditorBrowsableState.Never)>]
abstract GetType : unit -> Type
end
Implemented it in my type:
interface IFluentInterface with
member x.Equals(other) = x.Equals(other)
member x.ToString() = x.ToString()
member x.GetHashCode() = x.GetHashCode()
member x.GetType() = x.GetType()
but without success.
I also tried to override the methods in my type and adding the attribute that way, but that didn't do the trick either.
So the question remains, how can I clean up my API ?
Edit:
Thanks to the help (see below) I was able to solve my problem.
In summary, .Equals and .GetHashCode can be hidden via [<NoEquality>] [<NoComparison>] but that will also change the semantics.
The hiding via EditorBrowsable attributes does not work.
The only way to have a clean API and still be able to overload methods is to make these method members static.
The resulting class can be found by browsing inside my project FSharpSpec.
The type in question can be found here.
Thanks to everyone who helped me solve this problem.
Cheers ...
Alternatively, you could design the library using an alternative style using functions enclosed in a module. This is the usual way for writing functional code in F# and then you won't need to hide any standard .NET methods. To complete the example given by 'kvb', here is an example of object-oriented solution:
type MyNum(n:int) =
member x.Add(m) = MyNum(n+m)
member x.Mul(m) = MyNum(n*m)
let n = new MyNum(1)
n.Add(2).Mul(10) // 'ToString' shows in the IntelliSense
The functional way of writing the code might look like this:
type Num = Num of int
module MyNum =
let create n = Num n
let add m (Num n) = Num (m + n)
let mul m (Num n) = Num (m * n)
MyNum.create 1 |> MyNum.add 2 |> MyNum.mul 10
If you type MyNum., the F# IntelliSense will show the functions defined in the module, so you won't see any noise in this case.
Repeating my answer from
http://cs.hubfs.net/forums/thread/13317.aspx
In F# you can disallow Equals & GetHashCode (and remove them from intellisense) by annotating the type with the NoEquality and NoComparison attributes, as shown below. User-defined methods can also be hidden from the intellisense list via the Obsolete attribute or the CompilerMessage attribute with IsHidden=true. There is no way to hide the System.Object methods GetType and ToString from the F# intellisense.
[<NoEquality; NoComparison>]
type Foo() =
member x.Bar() = ()
member x.Qux() = ()
[<System.Obsolete>]
member x.HideMe() = ()
[<CompilerMessage("A warning message",99999,IsError=false,IsHidden=true)>]
member x.WarnMe() = ()
let foo = new Foo()
foo. // see intellisense here
I don't think that there is any way to do that in F# in general. In the particular case of .Equals and .GetHashCode, you can make them unusable by putting a [<NoEquality>] attribute on your type, but this actually has a semantic effect in addition to hiding those methods.
EDIT
It might also be worth mentioning that fluent interfaces are rarely used in F#, since it's much more idiomatic to use combinators and pipelining instead. For instance, imagine that we want to create a way to create arithmetic expressions. Rather than
let x = Expressions.MakeExpr(1).Add(2).Mul(3).Add(4)
I think that most F# users would prefer to write
open Expressions
let x =
1
|> makeExpr
|> add 2
|> mul 3
|> add 4
With this style, there's no need to hide members because expressions get piped to combinators, rather than calling methods of an expression builder.