Operators for classes imported from .net dlls - haxe

I am trying to use Haxe to write scripts for game engines like Unity or Godot.
In both cases I am unable to write a line like
Translate(dir * 100.0);
where dir is a Vector2 imported from the .net dll of Godot resp. Unity.
The working alternatives I found so far would be
Translate(Vector2.op_Multiply(dir, 100.0));
which on first sight seems like a bug in the hxcs module, but after some research it seems like a limitation of Haxe's type system.
The other alternative would be to use an abstract type to overload the operator resulting in code like this:
Translate(new Vector2WithOps(dir) * 100.0);
So my question is: is there a way to get around the explicit cast to the abstract type?
Intuitively it seems like Haxe should be able to apply the operators automatically when importing from C#, and it should be able to infer the type needed for the multiplication and perform the cast to the abstract type implicitly. I understand that there are technical reasons why both is at least difficult, but I am still hoping that there's a way I haven't seen yet.

So my question is: is there a way to get around the explicit cast to the abstract type?
Yes, abstracts allow defining implicit casts. You can simply add from Vector2 to Vector2 to the declaration:
abstract Vector2WithOps(Vector2) from Vector2 to Vector2 {}
That doesn't magically make something like dir * 100.0 work, however - you still need a way to trigger the cast of dir to a Vector2WithOps, for instance by assigning it to a variable typed that:
var dirWithOps:Vector2WithOps = dir;
There's also a special syntax called type check to trigger the cast:
(dir : Vector2WithOps)
Ultimately, the most convenient option would be to make sure that you're already working with a Vector2WithOps to begin with. That would work as long as you're creating new instances in your own code, but works less well when one is returned from a native API. This reminds me of a Haxe issue that considered allowing operator overloading through static extensions, which would be quite useful here: #2803

Related

Linear types in hacklang: Statically forcing an order of function calls

So Hacklang is out with a new, fancy type system, where a nullable variable has to be checked before it can be used. What I wonder is, can you achieve something like linear types, statically forcing an order of function calls, the common example being open a file before reading it? In pseudo-code:
$file_handler = get_file_handler("myfile");
$file_handler->open();
$string = $file_handler->read();
Now, $file_handler->read() without open() would rather than throwing a runtime exception, just not compile:
$file_handler = get_file_handler("myfile");
$string = $file_handler->read(); /* Won't compile, must run open() first */
Doable?
(OK, maybe bad example for PHP/Hacklang, since it is not this lowlevel, but you get the idea.)
Hack does not currently have any native support for linear types. For the particular case you're asking about, an opaque type alias might be useful in a wrapper class: (danger, code typed directly into browser, may have minor errors but should illustrate idea)
<?hh
newtype closedfile = resource;
newtype openfile = resource;
function get_file_handler(string $filename): closedfile {
return some_wrapped_function($filename);
}
function open_file_handler(closedfile $file): openfile {
$file->open();
return $file;
}
function read(openfile $file): string {
return $file->read();
}
Depending on your application, doing this may not be possible or even a good idea, but it's the closest to what we have right now.
That said, if you're designing the API as opposed to using something existing, it might be a good idea to just design it such that there isn't such a thing as a not-yet-opened file, eliminating this sort of error from the start without any type system acrobatics necessary. (Basically, in my opinion at least, this is an API design problem, not a type system problem! Even if you could use the type system to make invalid code an error statically, the fact that the consumer of the API could even write that code and think it's potentially meaningful is a deficiency in the API.)

Watch window not working for F#

I had noticed some time ago that the "Watch" window in VS2012 for Web doesn't work for default functions in FSharp. For example, cos someValue doesn't work, neither does the workaround where let _cos = cos or let _cos x = cos x is inserted in the beginning of the function and _cos(someValue) is used. The error is something like "cos doesn't exist in the current context" or "_cos isn't valid in the current scope", among others.
Should I change some settings or is this an unexpected bug? Of course I can declare all the results I need to watch, but that's a bit of overhead and it is quite impractical. What can I do to fix this?
As mentioned in the referneced answer, the watches and immediate windows only support C#, so they are not able to evaluate F# expressions and they are not aware of the F# context (such as opened namespaces).
In summary storing the result in a local variable (which is compiled to an ordinary local variable) is the best way to see the result.
More details:
In some cases, you can write C# code that corresponds to what you want to do in F#. This is probably only worth for simple situations, when the corresponding C# is not too hard to write, but it can often be done.
For example to call cos 3.14, you need to write something like:
Microsoft.FSharp.Core.Operators.Cos(3.14)
If you find the cos function in the F# source code (it righ here, in prim-types.fsi), then you can see that it comes with CompiledName attribute that tells the compiler to compile it as a method named Cos (to follow .NET naming guidelines). It is defined in module named Operators (see it here), which is annotated with AutoOpen so you do not need to explicitly write open in the F# code, but it is actually the name of the class that the F# compiler generates when compiling the code.

Why must overloaded operators be declared public?

I wanted to overload an operator in a class , and have it private so that it could only be used from within the class.
However, when I tried to compile I got the error message "User-defined operator ... must be declared static and public:
Why do they have to be public?
To answer half part of your question you may see the blog post by Eric Lippert.
Why are overloaded operators always static in C#?
Rather, the question we should be asking ourselves when faced with a
potential language feature is "does the compelling benefit of the
feature justify all the costs?" And costs are considerably more than
just the mundane dollar costs of designing, developing, testing,
documenting and maintaining a feature. There are more subtle costs,
like, will this feature make it more difficult to change the type
inferencing algorithm in the future? Does this lead us into a world
where we will be unable to make changes without introducing backwards
compatibility breaks? And so on.
In this specific case, the compelling benefit is small. If you want to
have a virtual dispatched overloaded operator in C# you can build one
out of static parts very easily. For example:
public class B {
public static B operator+(B b1, B b2) { return b1.Add(b2); }
protected virtual B Add(B b2) { // ...
And there you have it. So, the benefits are small. But the costs are
large. C++-style instance operators are weird. For example, they break
symmetry. If you define an operator+ that takes a C and an int, then
c+2 is legal but 2+c is not, and that badly breaks our intuition about
how the addition operator should behave.
For your question's other part: Why they should be public.
I was not able to find any authentic source, but IMO, if they are not going to be public, and may be used inside a class only, then this can be done using a simple private method, rather than an overloaded operator.
You may see the blog post by RB Whitaker
Operator Overloading
All operator overloads must be public and static, which should make
sense, since we want to have access to the operator throughout the
program, and since it belongs to the class as a whole, rather than any
specific instance of the class.

What's the benefit of defining Go methods away from struct definitions?

Go allows one to define methods separately from the struct/datatype they work on. Does it mean just flexibility in placing the method definitions or something more?
I've heard Go's struct/methods system being compared to monkey patching, but if I understand correctly, then you really can't add methods to any existing type (struct), as methods must reside in same package as the type. Ie. you can monkey patch only the types which are under your control anyway. Or am I missing something?
In which cases would you define a type and its methods in separate source files (or in different parts of the same source file)?
This is an advantage of Go over type based languages : you can organize your files as you like :
you can put all the similar functions together, even if there are many receiver types
you can split a file which would otherwise be too big
As frequently, Go didn't add a constraint which was useless. So the answer could also be "why not" ?
you really can't add methods to any existing type (struct), as methods must reside in same package as the type
If you could, you might not be able to determine which function to call in case of the same function name used on the same struct in two different packages. Or that would make certain packages incompatible.
This is (partly, probably) because in Go, you can have methods on any type, not just struct:
type Age uint
func (a Age) Add(n Age) Age {
return a + n
}
This is also how you can add methods to an existing type. What you do is define a new type based on that existing type, and add methods as you like.
Monkey Patching is not possible in go. The type you define methods on must reside in the same package.
What you can do is to define functions and methods wherever you like inside the package. It doesn't really matter if the type definition is in the same file as the method definition for the type.
This makes it possible to group all type definitions in one file and have the method implementation in another. Possibly with other helper which are needed by the methods.

Importing modules as a function, with string as input

I want to make a function called 'load' which imports definitions of functions from another file. I know how to import modules, but in my program I want the definitions of the functions to change depending on which module is 'loaded' with this new function. Is there a way to do this? Is there a better way to write my program so that this is not necessary?
I think it's type signature would look something like:
load :: String -> IO ()
where the string is the name of the module to be loaded (and the module is in the same directory).
Edit: Thanks for all the replies. Most people agree that this is not the best way to do what I want. Instead, is there a way to declare a global variable from within an I/O program. That is, I want it so that if I type (function "thing") into a function of type String -> IO(), I can still type 'thing' into GHCi to get the value assigned to it... Any suggestions?
There is almost certainly a better way to write your program so that this is not necessary. It's hard to say what without knowing more details about your situation, though. You could, for instance, represent the generic interface each module implements as a data-type, and have each module export a value of that type with the implementation.
Basically, the set of loaded modules is a static, compile-time property, so it makes no sense to want your program's behaviour to change based on its contents. Are you trying to write a library? Your users probably won't appreciate it doing such evil magic to their import lists :) (And it probably isn't possible without Template Haskell in that case, anyway.)
The exception is if you're trying to implement a Haskell tool (e.g. REPL, IDE, etc.) or trying to do plugins; i.e. dynamically-loaded modules of Haskell source code to integrate into your Haskell program. The first thing to try for those should be hint, but you may find you need something more advanced; in that case, the GHC API is probably your best bet. plugins used to be the de-facto standard in this area, but it doesn't seem to compile with GHC 7; you might want to check out direct-plugins, a simplified implementation of a similar interface that does.
mueval might be relevant; it's designed for executing short (one-line) snippets of Haskell code in a safe sandbox, as used by lambdabot.
Unless you're building a Haskell IDE or something like that, you most likely don't need this (^1).
But, in the case you do, there is always the hint-package, which allows you to embed a haskell interpreter into your program. This allows you to both load haskell modules and to convert strings into haskell values at runtime. There is a nice example of how to use it here
^1: If you're looking for a way to make things polymorphic, i.e. changing some, but not all definitions of in your code, you're probably looking for typeclasses.
With regards to your edit, perhaps you might be interested in IORef.

Resources