Does Vala have some capability to do something similar to typedef in C or alias in D? I've checked its sporadic documentation, and couldn't find anything related to this.
Not a typedef as such, but you can extend most types, including the primitives:
public struct foo : int8 { }
This will generate a typedef in the generated C, but, strictly speaking, it isn't one in Vala because it isn't a type alias (i.e., int8 and foo are not automatically interconvertible).
This doesn't work for delegates.
Related
I see multiple forms of typedef throughout dart and flutter libraries, but I can't quite make sense of it. There's this example in framework.dart:
typedef ElementVisitor = void Function(Element element);
And there's this example (https://medium.com/#castellano.mariano/typedef-in-dart-40e96d3941f9):
typedef String Join(String a, String b);
I don't quite understand the difference of their uses. Maybe this has something to do with why I can't find the definition of "Function" anywhere in the Dart or Flutter libraries. But then again I can find other typedef's just fine in the framework.dart file.
As docs refers
There is an old and new way of typedef
in general: the new way is a bit clearer and more readable.
in details:
typedef G = List<int> Function(int); // New form.
typedef List<int> H(int i); // Old form.
Note that the name of the parameter is required in the old form, but the type may be omitted. In contrast, the type is required in the new form, but the name may be omitted.
As well as
The reason for having two ways to express the same thing is that the new form seamlessly covers non-generic functions as well as generic ones, and developers might prefer to use the new form everywhere, for improved readability.
There is a difference between declaring a generic function type and declaring a typedef which takes a type argument. The former is a declaration of a single type which describes a certain class of runtime entities: Functions that are capable of accepting some type arguments as well as some value arguments, both at runtime. The latter is a compile-time mapping from types to types: It accepts a type argument at compile time and returns a type, which may be used, say, as a type annotation. We use the phrase parameterized typedef to refer to the latter. Dart has had support for parameterized typedefs for a while, and the new syntax supports parameterized typedefs as well. Here is an example of a parameterized typedef, and a usage thereof:
typedef I<T> = List<T> Function(T); // New form.
typedef List<T> J<T>(T t); // Old form.
I<int> myFunction(J<int> f) => f;
For more info
A typedef can be used to specify a function signature that we want specific functions to match. A function signature is defined by a function’s parameters (including their types). The return type is not a part of the function signature.
typedef function_name(parameters)
A variable of typedef can point to any function having the same signature as typedef.
typedef var_name = function_name
One declared a type while other assigns it to a typedef variable
https://dart.dev/guides/language/language-tour#typedefs
Imagine a silly class like this:
class ConditionalWorker{
var validityChecker= (inputs)=>true;
ConditionalWorker(this.validityChecker)
...
Now my question is, what is the proper way of declaring the validityChecker field?
This tutorial suggests using typedefs. But that's not very practical. Firstly it's a chore to write a lot of typedefs that would only be used once. And secondly these typedefs show up and pollute the autocompletion of my IDE.
The var works best, with custom setters/constructor arguments to keep it always of a specific kind, but I know it's discouraged by the style guide.
I could do Function<bool> but that just a more glorified var and the amount of work is the same.
It's a shame because it's perfectly legal to have a function like this:
bool every(bool test(E element));
where the parameter is a very well defined function, but I can't have a field declared the same way:
bool test(E element);
But hopefully there is something just as good that I didn't figure out. Right?d
If you want a function type more specific than Function, you need a typedef.
If you don't like to have named typedefs for every return type, you can define generic function types yourself.
typedef R function0<R>();
typedef R function1<S,R>(S arg1);
typedef R function2<S,T,R>(S arg1. T arg2);
typedef R function3<S,T,U,R>(S arg1, T arg2, U arg3);
Then you can write:
function1<int,int> curryAdd(int x) => (int y) => x + y;
Or if function0 looks bad to you, you can name them NullaryFunction, UnaryFuncytion, BinaryFunction, TernaryFunction, or any other name that you like.
If Function<bool> is not specific enough (you also want to specify the number and type of the arguments you have to use typedefs. There are no other ways.
I'm not sure why you think it is not practical. If you want to specify the type for a field that references a value you have to use one of the existing classes or create a new one. It's the same for fields referencing functions.
With Dart 2 we can use inline function types and we need to use it instead of typedefs where possible.
With inline function types we now can define a function as a field or a property as simple as this:
final bool Function(E) test;
Bear with me if this is a dumb question as I've recently started learning C++/CX. I was going through MSDN documentation on value classes and ref classes and I came across these exceprts:
Because all members of a value class or value struct are public and are emitted into metadata, standard C++ types are not allowed.
and
[A ref class] may contain as members C++/CX constructs or scalar types such as enum class, ref class, float64, and so on. It may also contain standard C++ types. C++/CX constructs may have public, protected, internal, private, or protected private accessibility. Public or protected members are emitted to metadata. Standard C++ types must have private, internal, or protected private accessibility, which prevents them from being emitted to metadata.
My question is: what are the definitions of "C++/CX constructs" and "standard C++ types"?
If my guess is correct, C++/CX constructs include ref classes and structs and enum classes and structs, and standard C++ types include int, bool, float, double, etc. Is that right?
When the documentation says "C++/CX constructs," it means Windows Runtime types. When programming using C++/CX, there are two categories of types:
C++ Types: The set of C++ types includes all of the types that you can use in ordinary C++ code: fundamental types (like int or double), enumerations, pointers, references, class types, etc.
Windows Runtime Types: These are types that can be used across the Windows Runtime ABI boundary. These include reference types (ref class), Windows Runtime value types (value class, numeric types, Windows Runtime enumerations, etc.) and delegates.
Note that there is a bit of overlap between these categories: numeric types are in both.
You can use C++ types anywhere in your code except in the public surface of any public components that you write. Only Windows Runtime types can be used across the Windows Runtime ABI boundary. For example:
public ref class C sealed
{
public:
// Ok: int is a fundamental WinRT type
void F(int x) { }
// Not ok: std::string is not a WinRT type
void G(std::string s) { }
private:
// Ok: _s is private; private members are implementation details, so you
// may use ordinary C++ types for private members.
std::string _s;
};
These two categories of types are not unique to building Windows Runtime components in C++: if you build a component in .NET, you can use .NET-specific types (e.g., concrete generic types) and .NET-specific constructs (e.g. generic methods), which are not valid Windows Runtime types.
I have an Objective-C protocol:
typedef enum {
ViewStateNone
} ViewState;
#protocol ViewStateable
- (void)initViewState:(ViewState)viewState;
- (void)setViewState:(ViewState)viewState;
#end
I'm using this protocol in the following class:
#import "ViewStateable.h"
typedef enum {
ViewStateNone,
ViewStateSummary,
ViewStateContact,
ViewStateLocation
} ViewState;
#interface ViewController : UIViewController <ViewStateable> {
}
#end
I won't go too far into the specifics of my application, but what I'm doing here is typedefing an enumeration in a protocol so that the protocol's methods can take an input value of that type.
I'm then hoping to redeclare or extend that typedef in the classes that conform to that protocol, so that each class can have their own view states. However, I'm running into the following two errors:
Redeclaration of enumerator 'ViewStateNone'
Conflicting types for 'ViewState'
I'm ashamed to admit that my knowledge of C (namely typedefs) is not extensive, so is what I'm trying to do here, firstly, possible and, secondly, sensible?
Cheers friends.
It is neither possible nor sensible. This comes from the fact that typedefs and enums are basically just defines. (Well, not really, but for this purpose, they are.) If you need to do things like this, you might want to review your design (see below).
More info
typedef type newtype;
is (almost) equivalent to
#define newtype type;
and
enum {
ViewStateNone
};
is basically the same as
#define ViewStateNone 1
There are a few finer points withe regards to differences between the two, and the most compelling argument for using enums and typedefs is of course compile time checking of integer constants.
However; once an typedef enum {} type; has been seen, it cannot be unseen, and once it has been seen, its name is reserved for it, and it alone.
There are ways around all of this; but those are paths rarely traveled, and generally for good reason. It quickly becomes incredibly unmanageable.
As a solution, you might want to create a new class, MyViewState, which represents a view state and associated information, which could easily just be a wrapper around an NSInteger.
In closing: Review your design. I fear you might be doing something overly convoluted.
It's certainly not possible in the form you have it, for reasons that the errors fairly succinctly explain. An enum constant can only be declared once in any scope, and similarly a typedef.
Moreover, there's a bit of a conceptual difficulty with defining a type in a protocol that implementors can then redefine. The implementors should be conforming to the type, not adding to it. If the class needs to be able to determine its own set of values, the protocol must use a type that is general enough to hold all those that might be wanted. In this case you could use int or, probably more sensibly, something readable like NSString. You might also add another method to the protocol that will report back the values supported by the implementing class.
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.