How can Raku mixins work with operator overloading? - raku

I could use some help to work out if overloading math operators can be made to work with mixin via does (or but) in a way that avoids the ambiguity error below... this module:
unit module Physics::Error;
role Error is export {
has Real $.abs-error;
method negate {
...
}
}
multi prefix:<-> ( Error:D $right) is export {
...
}
used like by this script...
use Physics::Error;
my $x = 12.5 does Error(0.5);
my $z = -$x;
Ambiguous call to 'prefix:<->(Rat+{Physics::Error::Error})'; these signatures all match:
(Rat:D \a)
(Physics::Error::Error:D $right)
I want my custom operator to always win unambiguously, then for it to implement the core operation and the Error calcs and then return a (Rat+{Physics::Error::Error}).
Big picture is to do math operations that also perform simple error calculations.

Add an is default trait to your multis:
multi prefix:<-> ( Error:D $right) is export is default {
That said, note jnthn's comment here:
is default is really a last resort, and even if you can get it to work using the mixin approach, you'll find the result is terribly slow, in no small part because mixins trigger deoptimization (falling out of specialized and JIT-compiled code back to the interpreter).

Related

Separating operator definitions for a class to other files and using them

I have 4 files all in the same directory: main.rakumod, infix_ops.rakumod, prefix_ops.rakumod and script.raku:
main module has a class definition (class A)
*_ops modules have some operator routine definitions to write, e.g., $a1 + $a2 in an overloaded way.
script.raku tries to instantaniate A object(s) and use those user-defined operators.
Why 3 files not 1? Since class definition might be long and separating overloaded operator definitions in files seemed like a good idea for writing tidier code (easier to manage).
e.g.,
# main.rakumod
class A {
has $.x is rw;
}
# prefix_ops.rakumod
use lib ".";
use main;
multi prefix:<++>(A:D $obj) {
++$obj.x;
$obj;
}
and similar routines in infix_ops.rakumod. Now, in script.raku, my aim is to import main module only and see the overloaded operators also available:
# script.raku
use lib ".";
use main;
my $a = A.new(x => -1);
++$a;
but it naturally doesn't see ++ multi for A objects because main.rakumod doesn't know the *_ops.rakumod files as it stands. Is there a way I can achieve this? If I use prefix_ops in main.rakumod, it says 'use lib' may not be pre-compiled perhaps because of circular dependentness
it says 'use lib' may not be pre-compiled
The word "may" is ambiguous. Actually it cannot be precompiled.
The message would be better if it said something to the effect of "Don't put use lib in a module."
This has now been fixed per #codesections++'s comment below.
perhaps because of circular dependentness
No. use lib can only be used by the main program file, the one directly run by Rakudo.
Is there a way I can achieve this?
Here's one way.
We introduce a new file that's used by the other packages to eliminate the circularity. So now we have four files (I've rationalized the naming to stick to A or variants of it for the packages that contribute to the type A):
A-sawn.rakumod that's a role or class or similar:
unit role A-sawn;
Other packages that are to be separated out into their own files use the new "sawn" package and does or is it as appropriate:
use A-sawn;
unit class A-Ops does A-sawn;
multi prefix:<++>(A-sawn:D $obj) is export { ++($obj.x) }
multi postfix:<++>(A-sawn:D $obj) is export { ($obj.x)++ }
The A.rakumod file for the A type does the same thing. It also uses whatever other packages are to be pulled into the same A namespace; this will import symbols from it according to Raku's standard importing rules. And then relevant symbols are explicitly exported:
use A-sawn;
use A-Ops;
sub EXPORT { Map.new: OUTER:: .grep: /'fix:<'/ }
unit class A does A-sawn;
has $.x is rw;
Finally, with this setup in place, the main program can just use A;:
use lib '.';
use A;
my $a = A.new(x => -1);
say $a++; # A.new(x => -1)
say ++$a; # A.new(x => 1)
say ++$a; # A.new(x => 2)
The two main things here are:
Introducing an (empty) A-sawn package
This type eliminates circularity using the technique shown in #codesection's answer to Best Way to Resolve Circular Module Loading.
Raku culture has a fun generic term/meme for techniques that cut through circular problems: "circular saws". So I've used a -sawn suffix of the "sawn" typename as a convention when using this technique.[1]
Importing symbols into a package and then re-exporting them
This is done via sub EXPORT { Map.new: ... }.[2] See the doc for sub EXPORT.
The Map must contain a list of symbols (Pairs). For this case I've grepped through keys from the OUTER:: pseudopackage that refers to the symbol table of the lexical scope immediately outside the sub EXPORT the OUTER:: appears in. This is of course the lexical scope into which some symbols (for operators) have just been imported by the use Ops; statement. I then grep that symbol table for keys containing fix:<; this will catch all symbol keys with that string in their name (so infix:<..., prefix:<... etc.). Alter this code as needed to suit your needs.[3]
Footnotes
[1] As things stands this technique means coming up with a new name that's different from the one used by the consumer of the new type, one that won't conflict with any other packages. This suggests a suffix. I think -sawn is a reasonable choice for an unusual and distinctive and mnemonic suffix. That said, I imagine someone will eventually package this process up into a new language construct that does the work behind the scenes, generating the name and automating away the manual changes one has to make to packages with the shown technique.
[2] A critically important point is that, if a sub EXPORT is to do what you want, it must be placed outside the package definition to which it applies. And that in turn means it must be before a unit package declaration. And that in turn means any use statement relied on by that sub EXPORT must appear within the same or outer lexical scope. (This is explained in the doc but I think it bears summarizing here to try head off much head scratching because there's no error message if it's in the wrong place.)
[3] As with the circularity saw aspect discussed in footnote 1, I imagine someone will also eventually package up this import-and-export mechanism into a new construct, or, perhaps even better, an enhancement of Raku's built in use statement.
Hi #hanselmann here is how I would write this (in 3 files / same dir):
Define my class(es):
# MyClass.rakumod
unit module MyClass;
class A is export {
has $.x is rw;
}
Define my operators:
# Prefix_Ops.rakumod
unit module Prefix_Ops;
use MyClass;
multi prefix:<++>(A:D $obj) is export {
++$obj.x;
$obj;
}
Run my code:
# script.raku
use lib ".";
use MyClass;
use Prefix_Ops;
my $a = A.new(x => -1);
++$a;
say $a.x; #0
Taking my cue from the Module docs there are a couple of things I am doing different:
Avoiding the use of main (or Main, or MAIN) --- I am wary that MAIN is a reserved name and just want to keep clear of engaging any of that (cool) machinery
Bringing in the unit module declaration at the top of each 'rakumod' file ... it may be possible to use bare files in Raku ... but I have never tried this and would say that it is not obvious from the docs that it is even possible, or supported
Now since I wanted this to work first time you will note that I use the same file name and module name ... again it may be possible to do that differently (multiple modules in one file and so on) ... but I have not tried that either
Using the 'is export' trait where I want my script to be able to use these definitions ... as you will know from close study of the docs ;-) is that each module has it's own namespace (the "stash") and we need export to shove the exported definitions into the namespace of the script
As #raiph mentions you only need the script to define the module library location
Since you want your prefix multi to "know" about class A then you also need to use MyClass in the Prefix_Ops module
Anyway, all-in-all, I think that the raku module system exemplifies the unique combination of "easy things easy and hard thinks doable" ... all I had to do with your code (which was very close) was tweak a few filenames and sprinkle in some concise concepts like 'unit module' and 'is export' and it really does not look much different since raku keeps all the import/export machinery under the surface like the swan gliding over the river...

Kotlin: Difference between {} and () while using map transform?

I'm new to kotlin. Ive always used the map transform with curly braces. Then -
Why does this work ->
val x = someList.map(::SomeConstructor)
and this doesn't?
val x = someList.map{ ::SomeConstructor }
I didn't find usage of map with circular brackets anywhere on the online tutorials.
Please try to explain in detail, or provide suitable reference article.
What you ask is explained in this official documentation.
If and only if the last argument of a function is a lambda, you can extract it from the call paranthesis, to put it inline on the right of the function. It allows a nicer DSL syntax.
EDIT: Let's make an example :
One of the good use-case is context programming. Imagine you've got a closeable object. You want to delimit its usage to ensure it's properly closed once not needed anymore. In Java, you've got the try-with-resources:
try (final AutoCloseable myResource = aquireStuff()) {
// use your resource here.
}
Kotlin provide the use function. Now, you can do either :
acquireStuff().use( { doStuff1(it) ; doStuff2(it) } )
or write :
acquireStuff().use {
doStuff1(it)
doStuff2(it)
}
It looks like a Java try-w-resource, but is extensible to any of your API. Allowing you to design libraries giving advanced constructs to end-users.

Jinq in Kotlin - how to convert lambda into java SerializedLambda?

Can I have serializable lambda in Kotlin? I am trying to use Jinq library from Kotlin, but it requires serializable lambdas. Is there any syntax that makes it possible?
Update:
My code:
var temp=anyDao.streamAll(Task::class.java)
.where<Exception,Task> { t->t.taskStatus== TaskStatus.accepted }
.collect(Collectors.toList<Task>());
I am getting this error:
Caused by: java.lang.IllegalArgumentException:
Could not extract code from lambda.
This error sometimes occurs because your lambda references objects that aren't Serializable.
All objects referenced in lambda are serializable (code results in no errors in java).
Update 2
After debugging it seems that kotlin lambda isn't translated into java.lang.invoke.SerializedLambda which is required by Jinq to get information from. So the problem is how to convert it to SerializedLambda.
I'm the maker of Jinq. I haven't had the time to look at Kotlin-support, but based on your description, I'm assuming that Kotlin compiles its lambdas into actual classes or something else. As such, Jinq would probably need some special code for cracking open Kotlin lambdas, and it may also need special code for handling any unusual Kotlin-isms in the generated code. Jinq should be capable of handling it because it was previously retrofitted to handle Scala lambdas.
If you file an issue in the Jinq github about it, along with a small Kotlin example (in both source and .class file form), then I can take a quick peek at what might be involved. If it's small, I can make those changes. Unfortunately, if it looks like a lot of work, I don't think I can really justify putting a lot of resources into adding Kotlin support to Jinq.
I have no experience on Jinq, but according to the implementation in GitHub and my experience of using Java Library in Kotlin.
ref: https://github.com/my2iu/Jinq/blob/master/api/src/org/jinq/orm/stream/JinqStream.java
You can always fall back to use the native Java Interface in Kotlin.
var temp = anyDao.streamAll(Task::class.java)
.where( JinqStream.Where<Task,Exception> { t -> t.taskStatus == TaskStatus.accepted } )
.collect(Collectors.toList<Task>());
// Alternatively, You you can import the interface first
import org.jinq.orm.stream.JinqStream.*
...
// then you can use Where instead of JinqStream.Where
var temp = anyDao.streamAll(Task::class.java)
.where(Where<Task,Exception> { t -> t.taskStatus == TaskStatus.accepted } )
.collect(Collectors.toList<Task>());
Or make a custom extension to wrap the implementation
fun JinqStream<T>.where(f: (T) -> Boolean): JinqStream<T> {
return this.where(JinqStream.Where<T,Exception> { f(it) })
}
Disclaimer: The above codes have not been tested.

MicrosoftAjaxMinifier doesn't seem to remove "unreachable code"

I'm using this with BundleTransformer from nuget and System.Web.Optimisation in an ASP.Net app. According to various docs this minifier is supposed to "remove unreachable code". I know it's not as aggressive as google closure (which I can't use presently) but I can't get even the simplest cases to work, eg;
function foo() {
}
where foo isn't called from anywhere. I can appreciate the argument that says this might be an exported function but I can't see a way to differentiate that. All my JS code is concatenated so it would be able to say for sure whether that function was needed or not if I can find the right switches.
The only way I've found to omit unnecessary code is to use the debugLookupList property in the web.config for BundleTransformer but that seems like a sledgehammer to crack a nut. It's not very granular.
Does anyone have an example of how to write so-called 'unreachable code' that this minifier will recognise?
Here's a place to test online
I doubt the minifier has any way of knowing if a globally defined function can be removed safely (as it doesn't know the full scope). On the other hand it might not remove any unused functions and might only be interested in unreachable code (i.e. code after a return).
Using the JavaScript Module Pattern, your unused private functions would most likely get hoovered up correctly (although I've not tested this). In the example below, the minifier should only be confident about removing the function called privateFunction. Whether it considers unused functions as unreachable code is another matter.
var AmazingModule = (function() {
var module = {};
function privateFunction() {
// ..
}
module.otherFunction = function() {
// ..
};
return module;
}());
function anotherFunction() {
// ..
}

What's the naming convention for a function that returns a function?

function getPerformActionFunction(someParameter) {
return function() {
performAction(someParameter);
}
}
What would you call getPerformActionFunction to indicate that it doesn't perform the action, but rather returns a function which performs the action?
Example is Javascript, and if there's a Javascript convention that's preferred, but also interested in other languages if the answer differs.
Not sure if it's in any style guides, but I quite like the -er suffix to suggest something that is able to do an action.
e.g. getActionPerformer or fooHandler or XMLTransformer
I've used this sort of style in C#, Java and Clojure an it seems to work OK.