How does one define a super class in Haskell? My situation is that I have defined a class StringHashed that maps members to their names as a String. I wish to implement, en mass, all t from Show t by making the string name simply return show t. Am I right in saying that StringHashed is now a superclass of Show? Here is what I would like to be able to write:
class StringHashed t where
stringHash :: t -> String
instance Show t => StringHashed t where
stringHash = show
But Haskell complains about an invalid instance declaration. I have also tried instance StringHashed (Show t) and other syntactical dribble; none have worked for me. I have also read a proposal on the GHC wiki that provides no solution. This is the one. I have concern about using -XFlexibleInstances simply because it is not default. Is there a proper way to achieve a general instance declaration? Or am I being too demanding of Haskell's type system?
Haskell superclasses cannot be added after the fact - they need to be mentioned in the subclass's declaration. And defining an instance like you do in the question, while possible with extensions, can create subtle overlap problems.
FlexibleInstances itself is not the problem - it's one of GHC's most innocuous extensions. The problem is that GHC's instance lookup method means that
instance Show t => StringHashed t where ...
defines this instance to hold for all types t - the Show t restriction is only an afterthought checked after lookup. So it will overlap with all other instances you can make, and while there is an extension OverlappingInstances to allow this, it is considered somewhat dubious to use.
However GHC has a feature DefaultSignatures, which is designed for use cases similar to yours:
{-# LANGUAGE DefaultSignatures #-}
class StringHashed t where
stringHash :: t -> String
default stringHash :: Show t => t -> String
stringHash = show
instance StringHashed Int
This allows you to write a default for the method which only works for some instance types. Note however, that you still need to write an actual instance declaration for each type - but its body can be empty.
Related
I'm trying to write class types and having an issue expressing what I want.
I have
class type event_emitter = object
method on : string -> unit
end
and then I want to do this:
class type socket = object
inherit event_emitter
method on : int -> unit
end
But I get a compiler error about a type signature mismatch between the two. I've also tried using the virtual keyword, doing class type virtual event_emitter = method virtual on : string -> unit but this also doesn't work as I guess these are class type definitions, not implementations anyway.
I really want this method override to work and this seemed straightforward, not sure why its not allowed.
What you are trying to do is overloading, not overriding. You are trying to create a new method in socket with the same name as in event_emitter, but with a different type. Overriding would be creating a new method with the same name and type. This description would hold for other languages like Java and C++, as well. The difference is that I don't believe OCaml allows this kind of overloading – the same as for regular functions.
Note that if you entered the analogous declarations for Java, it would work, but socket would have two on methods, not one. OCaml doesn't allow this.
This doesn't contradict antron's answer, but you can do this:
class type ['a] event_emitter = object
method on : 'a -> unit
end
class type socket = object
inherit [int] event_emitter
end
Is there any technical reason I am missing for which e doesn't have static fields/methods?
I've looked up the LRM and there is no mention of anything like this. There are workaround (like this one: http://www.specman-verification.com/index.php?entry=entry060612-105347), but I don't find it a particularly clean approach as it's not nicely encapsulated.
Good question. There should be no such technical reasons to not have it, and it might be a good idea to add static members to e structs. Its semantics would just need to be carefully considered, because of the aspect-oriented features of e, which are irrelevant to some other languages that have static members (for example, one question that would need to be answered is whether static methods can be extended, e.g., with is also or not).
However, it doesn't seem very critical to me, because a static field is, effectively, no more than a global field (or method, or any other kind of struct member) that belongs to a given struct's namespace. So, even without having static members, an easy workaround is to add such a member to global (or to sys), and make sure that its name has a prefix that makes it clear to "belong" to a given struct.
There is an important point, though, which does make static members more than just a member of global. In e, like in C++, there are template types. A static member of a template would be something that, on the one hand, is shared by all instance objects of a given template instance type, but on the other hand, would exist separately for each template instance (each one of which being a separate struct).
Not sure if the port-based workaround suggested at the above link is any better. I see it as an overkill.
Actually, in my previous answer I am missing an important point, which does make static members more than just a member of global.
In e, like in C++, there are template types. A static member of a template would be something that, on the one hand, is shared by all instance objects of a given template instance type, but on the other hand, would exist separately for each template instance (each one of which being a separate struct).
By the way static struct members were added to the language in Specman v15.2. They are handy especially in configuration structs that are well, static:
extend packet_s {
static max_address : uint = 0x1000;
};
-- Change max_address for all instances
on xxx { packet_s::max_address = 0x2000; };
A static field can't be generated, physical(%) or used in when subtypes. Here's some comments from the teamspecman blog : Static members in e
I think the main reason why e doesn't have static struct members yet is the fact that you always have global and sys singletons as well as top unit of your specific module (which means better encapsulation), where the 'static' information can be placed. There is no special technical reason for that, besides some complexity in defining exact semantics.
As a syntactic sugar for the unit access, you can always wrap it with very basic single-word macro - it will not be completely seamless, because this magic word will always be required vs. natively visible static struct members of 'me', but still very easy to use.
When I compile:
object Test extends App {
implicit def pimp[V](xs: Seq[V]) = new {
def dummy(x: V) = x
}
}
I get:
$ fsc -d aoeu go.scala
go.scala:3: error: Parameter type in structural refinement may not refer to an abstract type defined outside that refinement
def dummy(x: V) = x
^
one error found
Why?
(Scala: "Parameter type in structural refinement may not refer to an abstract type defined outside that refinement" doesn't really answer this.)
It's disallowed by the spec. See 3.2.7 Compound Types.
Within a method declaration in a structural refinement, the type of any value parameter may only refer to type parameters or abstract types that are contained inside the refinement. That is, it must refer either to a type parameter of the method
itself, or to a type definition within the refinement. This restriction does not apply
to the function’s result type.
Before Bug 1906 was fixed, the compiler would have compiled this and you'd have gotten a method not found at runtime. This was fixed in revision 19442 and this is why you get this wonderful message.
The question is then, why is this not allowed?
Here is very detailed explanation from Gilles Dubochet from the scala mailing list back in 2007. It roughly boils down to the fact that structural types use reflection and the compiler does not know how to look up the method to call if it uses a type defined outside the refinement (the compiler does not know ahead of time how to fill the second parameter of getMethod in p.getClass.getMethod("pimp", Array(?))
But go look at the post, it will answer your question and some more.
Edit:
Hello list.
I try to define structural types with abstract datatype in function
parameter. ... Any reason?
I have heard about two questions concerning the structural typing
extension of Scala 2.6 lately, and I would like to answer them here.
Why did we change Scala's native values (“int”, etc.) boxing scheme
to Java's (“java.lang.Integer”).
Why is the restriction on parameters for structurally defined
methods (“Parameter type in structural refinement may not refer
to abstract type defined outside that same refinement”) required.
Before I can answer these two questions, I need to speak about the
implementation of structural types.
The JVM's type system is very basic (and corresponds to Java 1.4). That
means that many types that can be represented in Scala cannot be
represented in the VM. Path dependant types (“x.y.A”), singleton types
(“a.type”), compound types (“A with B”) or abstract types are all types
that cannot be represented in the JVM's type system.
To be able to compile to JVM bytecode, the Scala compilers changes the
Scala types of the program to their “erasure” (see section 3.6 of the
reference). Erased types can be represented in the VM's type system and
define a type discipline on the program that is equivalent to that of
the program typed with Scala types (saving some casts), although less
precise. As a side note, the fact that types are erased in the VM
explains why operations on the dynamic representation of types (pattern
matching on types) are very restricted with respect to Scala's type
system.
Until now all type constructs in Scala could be erased in some way.
This isn't true for structural types. The simple structural type “{ def
x: Int }” can't be erased to “Object” as the VM would not allow
accessing the “x” field. Using an interface “interface X { int x{}; }”
as the erased type won't work either because any instance bound by a
value of this type would have to implement that interface which cannot
be done in presence of separate compilation. Indeed (bear with me) any
class that contains a member of the same name than a member defined in
a structural type anywhere would have to implement the corresponding
interface. Unfortunately this class may be defined even before the
structural type is known to exist.
Instead, any reference to a structurally defined member is implemented
as a reflective call, completely bypassing the VM's type system. For
example def f(p: { def x(q: Int): Int }) = p.x(4) will be rewritten
to something like:
def f(p: Object) = p.getClass.getMethod("x", Array(Int)).invoke(p, Array(4))
And now the answers.
“invoke” will use boxed (“java.lang.Integer”) values whenever the
invoked method uses native values (“int”). That means that the above
call must really look like “...invoke(p, Array(new
java.lang.Integer(4))).intValue”.
Integer values in a Scala program are already often boxed (to allow the
“Any” type) and it would be wasteful to unbox them from Scala's own
boxing scheme to rebox them immediately as java.lang.Integer.
Worst still, when a reflective call has the “Any” return type,
what should be done when a java.lang.Integer is returned? The called
method may either be returning an “int” (in which case it should be
unboxed and reboxed as a Scala box) or it may be returning a
java.lang.Integer that should be left untouched.
Instead we decided to change Scala's own boxing scheme to Java's. The
two previous problems then simply disappear. Some performance-related
optimisations we had with Scala's boxing scheme (pre-calculate the
boxed form of the most common numbers) were easy to use with Java
boxing too. In the end, using Java boxing was even a bit faster than
our own scheme.
“getMethod”'s second parameter is an array with the types of the
parameters of the (structurally defined) method to lookup — for
selecting which method to get when the name is overloaded. This is the
one place where exact, static types are needed in the process of
translating a structural member call. Usually, exploitable static types
for a method's parameter are provided with the structural type
definition. In the example above, the parameter type of “x” is known to
be “Int”, which allows looking it up.
Parameter types defined as abstract types where the abstract type is
defined inside the scope of the structural refinement are no problem
either:
def f(p: { def x[T](t: T): Int }) = p.xInt
In this example we know that any instance passed to “f” as “p” will
define “x[T](t: T)” which is necessarily erased to “x(t: Object)”. The
lookup is then correctly done on the erased type:
def f(p: Object) = p.getClass.getMethod("x", Array(Object)).invoke(p,
Array(new java.lang.Integer(4)))
But if an abstract type from outside the structural refinement's scope
is used to define a parameter of a structural method, everything breaks:
def f[T](p: { def x(t: T): Int }, t: T) = p.x(t)
When “f” is called, “T” can be instantiated to any type, for example:
f[Int]({ def x(t: Int) = t }, 4)
f[Any]({ def x(t: Any) = 5 }, 4)
The lookup for the first case would have to be “getMethod("x",
Array(int))” and for the second “getMethod("x", Array(Object))”, and
there is no way to know which one to generate in the body of
“f”: “p.x(t)”.
To allow defining a unique “getMethod” call inside “f”'s body for
any instantiation of “T” would require any object passed to “f” as the
“p” parameter to have the type of “t” erased to “Any”. This would be a
transformation where the type of a class' members depend on how
instances of this class are used in the program. And this is something
we definitely don't want to do (and can't be done with separate
compilation).
Alternatively, if Scala supported run-time types one could use them to
solve this problem. Maybe one day ...
But for now, using abstract types for structural method's parameter
types is simply forbidden.
Sincerely,
Gilles.
Discovered the problem shortly after posting this: I have to define a named class instead of using an anonymous class. (Still would love to hear a better explanation of the reasoning though.)
object Test extends App {
case class G[V](xs: Seq[V]) {
def dummy(x: V) = x
}
implicit def pimp[V](xs: Seq[V]) = G(xs)
}
works.
this works:
scala> class foo[T] {
| var t: T = _
| }
defined class foo
but this doesn't:
scala> def foo[T] = {
| var t: T = _
| }
<console>:5: error: local variables must be initialized
var t: T = _
why?
(one can use:
var t: T = null.asInstanceOf[T]
)
There is a mailing list thread where Martin answered:
It corresponds to the JVM. You can omit a field initialization but not a local variable initialization. Omitting local variable initializations means that the compiler has to be able to synthesize a default value for every type. That's not so easy in the face of type parameters, specialization, and so on.
When pressed about how there is or should be any distinction between fields and locals in the matter of Scala synthesizing default values, he went on to say:
In terms of bytecodes there IS a clear difference. The JVM will initialize object fields by default and require that local variables are initialized explicitly. […] I am not sure whether we should break a useful principle of Java (locals have to be initialized before being used), or whether we should rather go the full length and introduce flow-based initialization checking as in Java. That would be the better solution, IMO, but would require significant work in terms of spec and implementation. Faced with these choices my natural instinct is to do nothing for now :-)
So if I understand correctly, the Scala compiler does not actually synthesize default values for object fields, it produces bytecode that leaves the JVM to handle this.
According to SI-4437 there was agreement from Martin on actually endorsing the null.asInstanceOf[T] pattern in the language spec, seemingly for lack of being able to feasibly support a better alternative within existing constraints.
This is defined in section 4.2 of the Scala Language Specification (my italics)
A variable definition var x: T = _ can appear only as a member of a template. It
introduces a mutable field with type T and a default initial value
This, of course, does not answer the why this should be so!
Here is at least one use case that I just uncovered. When then superclass initializes member variables via reflection it can actually initialize a subclasses member variables. However, if a subclass also initializes the member variable with a value, then this will have the effect of overwriting the value that the superclass gave it. This can be avoided by initializing the subclasses member variable with the underscore. This is why the language spec talks about giving the variable a getter function that returns the current value a little further down from the quoted sentence in oxbow_lake's sentence.
Can I specify interfaces when I declare a member?
After thinking about this question for a while, it occurred to me that a static-duck-typed language might actually work. Why can't predefined classes be bound to an interface at compile time? Example:
public interface IMyInterface
{
public void MyMethod();
}
public class MyClass //Does not explicitly implement IMyInterface
{
public void MyMethod() //But contains a compatible method definition
{
Console.WriteLine("Hello, world!");
}
}
...
public void CallMyMethod(IMyInterface m)
{
m.MyMethod();
}
...
MyClass obj = new MyClass();
CallMyMethod(obj); // Automatically recognize that MyClass "fits"
// MyInterface, and force a type-cast.
Do you know of any languages that support such a feature? Would it be helpful in Java or C#? Is it fundamentally flawed in some way? I understand you could subclass MyClass and implement the interface or use the Adapter design pattern to accomplish the same thing, but those approaches just seem like unnecessary boilerplate code.
A brand new answer to this question, Go has exactly this feature. I think it's really cool & clever (though I'll be interested to see how it plays out in real life) and kudos on thinking of it.
As documented in the official documentation (as part of the Tour of Go, with example code):
Interfaces are implemented implicitly
A type implements an interface by implementing its methods. There is
no explicit declaration of intent, no "implements" keyword.
Implicit interfaces decouple the definition of an interface from its
implementation, which could then appear in any package without
prearrangement.
How about using templates in C++?
class IMyInterface // Inheritance from this is optional
{
public:
virtual void MyMethod() = 0;
}
class MyClass // Does not explicitly implement IMyInterface
{
public:
void MyMethod() // But contains a compatible method definition
{
std::cout << "Hello, world!" "\n";
}
}
template<typename MyInterface>
void CallMyMethod(MyInterface& m)
{
m.MyMethod(); // instantiation succeeds iff MyInterface has MyMethod
}
MyClass obj;
CallMyMethod(obj); // Automatically generate code with MyClass as
// MyInterface
I haven't actually compiled this code, but I believe it's workable and a pretty trivial C++-ization of the original proposed (but nonworking) code.
Statically-typed languages, by definition, check types at compile time, not run time. One of the obvious problems with the system described above is that the compiler is going to check types when the program is compiled, not at run time.
Now, you could build more intelligence into the compiler so it could derive types, rather than having the programmer explicitly declare types; the compiler might be able to see that MyClass implements a MyMethod() method, and handle this case accordingly, without the need to explicitly declare interfaces (as you suggest). Such a compiler could utilize type inference, such as Hindley-Milner.
Of course, some statically typed languages like Haskell already do something similar to what you suggest; the Haskell compiler is able to infer types (most of the time) without the need to explicitly declare them. But obviously, Java/C# don't have this ability.
I don't see the point. Why not be explicit that the class implements the interface and have done with it? Implementing the interface is what tells other programmers that this class is supposed to behave in the way that interface defines. Simply having the same name and signature on a method conveys no guarantees that the intent of the designer was to perform similar actions with the method. That may be, but why leave it up for interpretation (and misuse)?
The reason you can "get away" with this successfully in dynamic languages has more to do with TDD than with the language itself. In my opinion, if the language offers the facility to give these sorts of guidance to others who use/view the code, you should use it. It actually improves clarity and is worth the few extra characters. In the case where you don't have access to do this, then an Adapter serves the same purpose of explicitly declaring how the interface relates to the other class.
F# supports static duck typing, though with a catch: you have to use member constraints. Details are available in this blog entry.
Example from the cited blog:
let inline speak (a: ^a) =
let x = (^a : (member speak: unit -> string) (a))
printfn "It said: %s" x
let y = (^a : (member talk: unit -> string) (a))
printfn "Then it said %s" y
type duck() =
member x.speak() = "quack"
member x.talk() = "quackity quack"
type dog() =
member x.speak() = "woof"
member x.talk() = "arrrr"
let x = new duck()
let y = new dog()
speak x
speak y
TypeScript!
Well, ok... So it's a javascript superset and maybe does not constitute a "language", but this kind of static duck-typing is vital in TypeScript.
Most of the languages in the ML family support structural types with inference and constrained type schemes, which is the geeky language-designer terminology that seems most likely what you mean by the phrase "static duck-typing" in the original question.
The more popular languages in this family that spring to mind include: Haskell, Objective Caml, F# and Scala. The one that most closely matches your example, of course, would be Objective Caml. Here's a translation of your example:
open Printf
class type iMyInterface = object
method myMethod: unit
end
class myClass = object
method myMethod = printf "Hello, world!"
end
let callMyMethod: #iMyInterface -> unit = fun m -> m#myMethod
let myClass = new myClass
callMyMethod myClass
Note: some of the names you used have to be changed to comply with OCaml's notion of identifier case semantics, but otherwise, this is a pretty straightforward translation.
Also, worth noting, neither the type annotation in the callMyMethod function nor the definition of the iMyInterface class type is strictly necessary. Objective Caml can infer everything in your example without any type declarations at all.
Crystal is a statically duck-typed language. Example:
def add(x, y)
x + y
end
add(true, false)
The call to add causes this compilation error:
Error in foo.cr:6: instantiating 'add(Bool, Bool)'
add(true, false)
^~~
in foo.cr:2: undefined method '+' for Bool
x + y
^
A pre-release design for Visual Basic 9 had support for static duck typing using dynamic interfaces but they cut the feature* in order to ship on time.
Boo definitely is a static duck-typed language: http://boo.codehaus.org/Duck+Typing
An excerpt:
Boo is a statically typed language,
like Java or C#. This means your boo
applications will run about as fast as
those coded in other statically typed
languages for .NET or Mono. But using
a statically typed language sometimes
constrains you to an inflexible and
verbose coding style, with the
sometimes necessary type declarations
(like "x as int", but this is not
often necessary due to boo's Type
Inference) and sometimes necessary
type casts (see Casting Types). Boo's
support for Type Inference and
eventually generics help here, but...
Sometimes it is appropriate to give up
the safety net provided by static
typing. Maybe you just want to explore
an API without worrying too much about
method signatures or maybe you're
creating code that talks to external
components such as COM objects. Either
way the choice should be yours not
mine.
Along with the normal types like
object, int, string...boo has a
special type called "duck". The term
is inspired by the ruby programming
language's duck typing feature ("If it
walks like a duck and quacks like a
duck, it must be a duck").
New versions of C++ move in the direction of static duck typing. You can some day (today?) write something like this:
auto plus(auto x, auto y){
return x+y;
}
and it would fail to compile if there's no matching function call for x+y.
As for your criticism:
A new "CallMyMethod" is created for each different type you pass to it, so it's not really type inference.
But it IS type inference (you can say foo(bar) where foo is a templated function), and has the same effect, except it's more time-efficient and takes more space in the compiled code.
Otherwise, you would have to look up the method during runtime. You'd have to find a name, then check that the name has a method with the right parameters.
Or you would have to store all that information about matching interfaces, and look into every class that matches an interface, then automatically add that interface.
In either case, that allows you to implicitly and accidentally break the class hierarchy, which is bad for a new feature because it goes against the habits of what programmers of C#/Java are used to. With C++ templates, you already know you're in a minefield (and they're also adding features ("concepts") to allow restrictions on template parameters).
Structural types in Scala does something like this.
See Statically Checked “Duck Typing” in Scala
D (http://dlang.org) is a statically compiled language and provides duck-typing via wrap() and unwrap() (http://dlang.org/phobos-prerelease/std_typecons.html#.unwrap).
Sounds like Mixins or Traits:
http://en.wikipedia.org/wiki/Mixin
http://www.iam.unibe.ch/~scg/Archive/Papers/Scha03aTraits.pdf
In the latest version of my programming language Heron it supports something similar through a structural-subtyping coercion operator called as. So instead of:
MyClass obj = new MyClass();
CallMyMethod(obj);
You would write:
MyClass obj = new MyClass();
CallMyMethod(obj as IMyInterface);
Just like in your example, in this case MyClass does not have to explicitly implement IMyInterface, but if it did the cast could happen implicitly and the as operator could be omitted.
I wrote a bit more about the technique which I call explicit structural sub-typing in this article.