Can subsets be exported in Raku? - module

I'd like to define a few subsets to which I am also adding a few constrains and some die statements for some useful error messages. I don't want to define them at the top of the module that uses those subsets and instead want to place them in another module while also doing away with using their fully qualified names (FQNs). For instance, I have
unit module Long::Module::Subsets;
subset PosInt
where ($_ ~~ Int || "The value must be an integer")
&& ($_ > 0 || "The value must be greater than 0")
is export
;
# other subsets ...
but got
===SORRY!=== Error while compiling /tmp/637321813/main.pl6
Two terms in a row ...
That not working I figured I could instead do something as follows but I'm wondering If I could avoid doing it:
use Long::Module::Subsets;
unit Long::Module;
my constant PosInt = Long::Module::Subsets::PosInt;
my constant Byte = Long::Module::Subsets::Byte;
# ... more subsets here
# ... some code here
my PosInt $age;

Subsets can indeed be exported. The problem here is that the is export trait isn't properly applied to the PosInt subset (and any other subset you might've also wished to export); the trait must be applied immediately after the new type being defined and right before any constrains introduced with where. By applying the trait correctly:
unit module Long::Module::Subsets;
subset PosInt is export
where ($_ ~~ Int || "The value must be an integer")
&& ($_ > 0 || "The value must be greater than 0")
;
# other subsets ...
the following should work fine:
use Long::Module::Subsets;
unit Long::Module;
# ... some code here
my PosInt $age;

Related

How to generate a lazy division?

I want to generate the sequence of
1, 1/2, 1/3, 1/4 ... *
using functional programming approach in raku, in my head it's should be look like:
(1,{1/$_} ...*)[0..5]
but the the output is: 1,1,1,1,1
The idea is simple, but seems enough powerful for me to using to generate for other complex list and work with it.
Others things that i tried are using a lazy list to call inside other lazy list, it doesn't work either, because the output is a repetitive sequence: 1, 0.5, 1, 0.5 ...
my list = 0 ... *;
(1, {1/#list[$_]} ...*)[0..5]
See #wamba's wonderful answer for solutions to the question in your title. They showcase a wide range of applicable Raku constructs.
This answer focuses on Raku's sequence operator (...), and the details in the body of your question, explaining what went wrong in your attempts, and explaining some working sequences.
TL;DR
The value of the Nth term is 1 / N.
# Generator ignoring prior terms, incrementing an N stored in the generator:
{ 1 / ++$ } ... * # idiomatic
{ state $N; $N++; 1 / $N } ... * # longhand
# Generator extracting denominator from prior term and adding 1 to get N:
1/1, 1/2, 1/3, 1/(*.denominator+1) ... * # idiomatic (#jjmerelo++)
1/1, 1/2, 1/3, {1/(.denominator+1)} ... * # longhand (#user0721090601++)
What's wrong with {1/$_}?
1, 1/2, 1/3, 1/4 ... *
What is the value of the Nth term? It's 1/N.
1, {1/$_} ...*
What is the value of the Nth term? It's 1/$_.
$_ is a generic parameter/argument/operand analogous to the English pronoun "it".
Is it set to N?
No.
So your generator (lambda/function) doesn't encode the sequence you're trying to reproduce.
What is $_ set to?
Within a function, $_ is bound either to (Any), or to an argument passed to the function.
If a function explicitly specifies its parameters (a "parameter" specifies an argument that a function expects to receive; this is distinct from the argument that a function actually ends up getting for any given call), then $_ is bound, or not bound, per that specification.
If a function does not explicitly specify its parameters -- and yours doesn't -- then $_ is bound to the argument, if any, that is passed as part of the call of the function.
For a generator function, any value(s) passed as arguments are values of preceding terms in the sequence.
Given that your generator doesn't explicitly specify its parameters, the immediately prior term, if any, is passed and bound to $_.
In the first call of your generator, when 1/$_ gets evaluated, the $_ is bound to the 1 from the first term. So the second term is 1/1, i.e. 1.
Thus the second call, producing the third term, has the same result. So you get an infinite sequence of 1s.
What's wrong with {1/#list[$_+1]}?
For your last example you presumably meant:
my #list = 0 ... *;
(1, {1/#list[$_+1]} ...*)[0..5]
In this case the first call of the generator returns 1/#list[1+1] which is 1/2 (0.5).
So the second call is 1/#list[0.5+1]. This specifies a fractional index into #list, asking for the 1.5th element. Indexes into standard Positionals are rounded down to the nearest integer. So 1.5 is rounded down to 1. And #list[1] evaluates to 1. So the value returned by the second call of the generator is back to 1.
Thus the sequence alternates between 1 and 0.5.
What arguments are passed to a generator?
Raku passes the value of zero or more prior terms in the sequence as the arguments to the generator.
How many? Well, a generator is an ordinary Raku lambda/function. Raku uses the implicit or explicit declaration of parameters to determine how many arguments to pass.
For example, in:
{42} ... * # 42 42 42 ...
the lambda doesn't declare what parameters it has. For such functions Raku presumes a signature including $_?, and thus passes the prior term, if any. (The above lambda ignores it.)
Which arguments do you need/want your generator to be passed?
One could argue that, for the sequence you're aiming to generate, you don't need/want to pass any of the prior terms. Because, arguably, none of them really matter.
From this perspective all that matters is that the Nth term computes 1/N. That is, its value is independent of the values of prior terms and just dependent on counting the number of calls.
State solutions such as {1/++$}
One way to compute this is something like:
{ state $N; $N++; 1/$N } ... *
The lambda ignores the previous term. The net result is just the desired 1 1/2 1/3 ....
(Except that you'll have to fiddle with the stringification because by default it'll use gist which will turn the 1/3 into 0.333333 or similar.)
Or, more succinctly/idiomatically:
{ 1 / ++$ } ... *
(An anonymous $ in a statement/expression is a simultaneous declaration and use of an anonymous state scalar variable.)
Solutions using the prior term
As #user0721090601++ notes in a comment below, one can write a generator that makes use of the prior value:
1/1, 1/2, 1/3, {1/(.denominator+1)} ... *
For a generator that doesn't explicitly specify its parameters, Raku passes the value of the prior term in the sequence as the argument, binding it to the "it" argument $_.
And given that there's no explicit invocant for .denominator, Raku presumes you mean to call the method on $_.
As #jjmerelo++ notes, an idiomatic way to express many lambdas is to use the explicit pronoun "whatever" instead of "it" (implicit or explicit) to form a WhateverCode lambda:
1/1, 1/2, 1/3, 1/(*.denominator+1) ... *
You drop the braces for this form, which is one of its advantages. (You can also use multiple "whatevers" in a single expression rather than just one "it", another part of this construct's charm.)
This construct typically takes some getting used to; perhaps the biggest hurdle is that a * must be combined with a "WhateverCodeable" operator/function for it to form a WhateverCode lambda.
TIMTOWTDI
routine map
(1..*).map: 1/*
List repetition operator xx
1/++$ xx *
The cross metaoperator, X or the zip metaoperator Z
1 X/ 1..*
1 xx * Z/ 1..*
(Control flow) control flow gather take
gather for 1..* { take 1/$_ }
(Seq) method from-loop
Seq.from-loop: { 1/++$ }
(Operators) infix ...
1, 1/(1+1/*) ... *
{1/++$} ... *

Does Perl 6 have an infinite Int?

I had a task where I wanted to find the closest string to a target (so, edit distance) without generating them all at the same time. I figured I'd use the high water mark technique (low, I guess) while initializing the closest edit distance to Inf so that any edit distance is closer:
use Text::Levenshtein;
my #strings = < Amelia Fred Barney Gilligan >;
for #strings {
put "$_ is closest so far: { longest( 'Camelia', $_ ) }";
}
sub longest ( Str:D $target, Str:D $string ) {
state Int $closest-so-far = Inf;
state Str:D $closest-string = '';
if distance( $target, $string ) < $closest-so-far {
$closest-so-far = $string.chars;
$closest-string = $string;
return True;
}
return False;
}
However, Inf is a Num so I can't do that:
Type check failed in assignment to $closest-so-far; expected Int but got Num (Inf)
I could make the constraint a Num and coerce to that:
state Num $closest-so-far = Inf;
...
$closest-so-far = $string.chars.Num;
However, this seems quite unnatural. And, since Num and Int aren't related, I can't have a constraint like Int(Num). I only really care about this for the first value. It's easy to set that to something sufficiently high (such as the length of the longest string), but I wanted something more pure.
Is there something I'm missing? I would have thought that any numbery thing could have a special value that was greater (or less than) all the other values. Polymorphism and all that.
{new intro that's hopefully better than the unhelpful/misleading original one}
#CarlMäsak, in a comment he wrote below this answer after my first version of it:
Last time I talked to Larry about this {in 2014}, his rationale seemed to be that ... Inf should work for all of Int, Num and Str
(The first version of my answer began with a "recollection" that I've concluded was at least unhelpful and plausibly an entirely false memory.)
In my research in response to Carl's comment, I did find one related gem in #perl6-dev in 2016 when Larry wrote:
then our policy could be, if you want an Int that supports ±Inf and NaN, use Rat instead
in other words, don't make Rat consistent with Int, make it consistent with Num
Larry wrote this post 6.c. I don't recall seeing anything like it discussed for 6.d.
{and now back to the rest of my first answer}
Num in P6 implements the IEEE 754 floating point number type. Per the IEEE spec this type must support several concrete values that are reserved to stand in for abstract concepts, including the concept of positive infinity. P6 binds the corresponding concrete value to the term Inf.
Given that this concrete value denoting infinity already existed, it became a language wide general purpose concrete value denoting infinity for cases that don't involve floating point numbers such as conveying infinity in string and list functions.
The solution to your problem that I propose below is to use a where clause via a subset.
A where clause allows one to specify run-time assignment/binding "typechecks". I quote "typecheck" because it's the most powerful form of check possible -- it's computationally universal and literally checks the actual run-time value (rather than a statically typed view of what that value can be). This means they're slower and run-time, not compile-time, but it also makes them way more powerful (not to mention way easier to express) than even dependent types which are a relatively cutting edge feature that those who are into advanced statically type-checked languages tend to claim as only available in their own world1 and which are intended to "prevent bugs by allowing extremely expressive types" (but good luck with figuring out how to express them... ;)).
A subset declaration can include a where clause. This allows you to name the check and use it as a named type constraint.
So, you can use these two features to get what you want:
subset Int-or-Inf where Int:D | Inf;
Now just use that subset as a type:
my Int-or-Inf $foo; # ($foo contains `Int-or-Inf` type object)
$foo = 99999999999; # works
$foo = Inf; # works
$foo = Int-or-Inf; # works
$foo = Int; # typecheck failure
$foo = 'a'; # typecheck failure
1. See Does Perl 6 support dependent types? and it seems the rough consensus is no.

matlab subsref: {} with string argument fails, why?

There are a few implementations of a hash or dictionary class in the Mathworks File Exchange repository. All that I have looked at use parentheses overloading for key referencing, e.g.
d = Dict;
d('foo') = 'bar';
y = d('foo');
which seems a reasonable interface. It would be preferable, though, if you want to easily have dictionaries which contain other dictionaries, to use braces {} instead of parentheses, as this allows you to get around MATLAB's (arbitrary, it seems) syntax limitation that multiple parentheses are not allowed but multiple braces are allowed, i.e.
t{1}{2}{3} % is legal MATLAB
t(1)(2)(3) % is not legal MATLAB
So if you want to easily be able to nest dictionaries within dictionaries,
dict{'key1'}{'key2'}{'key3'}
as is a common idiom in Perl and is possible and frequently useful in other languages including Python, then unless you want to use n-1 intermediate variables to extract a dictionary entry n layers deep, this seems a good choice. And it would seem easy to rewrite the class's subsref and subsasgn operations to do the same thing for {} as they previously did for (), and everything should work.
Except it doesn't when I try it.
Here's my code. (I've reduced it to a minimal case. No actual dictionary is implemented here, each object has one key and one value, but this is enough to demonstrate the problem.)
classdef TestBraces < handle
properties
% not a full hash table implementation, obviously
key
value
end
methods(Access = public)
function val = subsref(obj, ref)
% Re-implement dot referencing for methods.
if strcmp(ref(1).type, '.')
% User trying to access a method
% Methods access
if ismember(ref(1).subs, methods(obj))
if length(ref) > 1
% Call with args
val = obj.(ref(1).subs)(ref(2).subs{:});
else
% No args
val = obj.(ref.subs);
end
return;
end
% User trying to access something else.
error(['Reference to non-existant property or method ''' ref.subs '''']);
end
switch ref.type
case '()'
error('() indexing not supported.');
case '{}'
theKey = ref.subs{1};
if isequal(obj.key, theKey)
val = obj.value;
else
error('key %s not found', theKey);
end
otherwise
error('Should never happen')
end
end
function obj = subsasgn(obj, ref, value)
%Dict/SUBSASGN Subscript assignment for Dict objects.
%
% See also: Dict
%
if ~strcmp(ref.type,'{}')
error('() and dot indexing for assignment not supported.');
end
% Vectorized calls not supported
if length(ref.subs) > 1
error('Dict only supports storing key/value pairs one at a time.');
end
theKey = ref.subs{1};
obj.key = theKey;
obj.value = value;
end % subsasgn
end
end
Using this code, I can assign as expected:
t = TestBraces;
t{'foo'} = 'bar'
(And it is clear that the assignment work from the default display output for t.) So subsasgn appears to work correctly.
But I can't retrieve the value (subsref doesn't work):
t{'foo'}
??? Error using ==> subsref
Too many output arguments.
The error message makes no sense to me, and a breakpoint at the first executable line of my subsref handler is never hit, so at least superficially this looks like a MATLAB issue, not a bug in my code.
Clearly string arguments to () parenthesis subscripts are allowed, since this works fine if you change the code to work with () instead of {}. (Except then you can't nest subscript operations, which is the object of the exercise.)
Either insight into what I'm doing wrong in my code, any limitations that make what I'm doing unfeasible, or alternative implementations of nested dictionaries would be appreciated.
Short answer, add this method to your class:
function n = numel(obj, varargin)
n = 1;
end
EDIT: The long answer.
Despite the way that subsref's function signature appears in the documentation, it's actually a varargout function - it can produce a variable number of output arguments. Both brace and dot indexing can produce multiple outputs, as shown here:
>> c = {1,2,3,4,5};
>> [a,b,c] = c{[1 3 5]}
a =
1
b =
3
c =
5
The number of outputs expected from subsref is determined based on the size of the indexing array. In this case, the indexing array is size 3, so there's three outputs.
Now, look again at:
t{'foo'}
What's the size of the indexing array? Also 3. MATLAB doesn't care that you intend to interpret this as a string instead of an array. It just sees that the input is size 3 and your subsref can only output 1 thing at a time. So, the arguments mismatch. Fortunately, we can correct things by changing the way that MATLAB determines how many outputs are expected by overloading numel. Quoted from the doc link:
It is important to note the significance of numel with regards to the
overloaded subsref and subsasgn functions. In the case of the
overloaded subsref function for brace and dot indexing (as described
in the last paragraph), numel is used to compute the number of
expected outputs (nargout) returned from subsref. For the overloaded
subsasgn function, numel is used to compute the number of expected
inputs (nargin) to be assigned using subsasgn. The nargin value for
the overloaded subsasgn function is the value returned by numel plus 2
(one for the variable being assigned to, and one for the structure
array of subscripts).
As a class designer, you must ensure that the value of n returned by
the built-in numel function is consistent with the class design for
that object. If n is different from either the nargout for the
overloaded subsref function or the nargin for the overloaded subsasgn
function, then you need to overload numel to return a value of n that
is consistent with the class' subsref and subsasgn functions.
Otherwise, MATLAB produces errors when calling these functions.
And there you have it.

Optional named arguments without wrapping them all in "OptionValue"

Suppose I have a function with optional named arguments but I insist on referring to the arguments by their unadorned names.
Consider this function that adds its two named arguments, a and b:
Options[f] = {a->0, b->0}; (* The default values. *)
f[OptionsPattern[]] :=
OptionValue[a] + OptionValue[b]
How can I write a version of that function where that last line is replaced with simply a+b?
(Imagine that that a+b is a whole slew of code.)
The answers to the following question show how to abbreviate OptionValue (easier said than done) but not how to get rid of it altogether: Optional named arguments in Mathematica
Philosophical Addendum: It seems like if Mathematica is going to have this magic with OptionsPattern and OptionValue it might as well go all the way and have a language construct for doing named arguments properly where you can just refer to them by, you know, their names. Like every other language with named arguments does. (And in the meantime, I'm curious what workarounds are possible...)
Why not just use something like:
Options[f] = {a->0, b->0};
f[args___] := (a+b) /. Flatten[{args, Options[f]}]
For more complicated code I'd probably use something like:
Options[f] = {a->0, b->0};
f[OptionsPattern[]] := Block[{a,b}, {a,b} = OptionValue[{a,b}]; a+b]
and use a single call to OptionValue to get all the values at once. (Main reason is that this cuts down on messages if there are unknown options present.)
Update, to programmatically generate the variables from the options list:
Options[f] = {a -> 0, b -> 0};
f[OptionsPattern[]] :=
With[{names = Options[f][[All, 1]]},
Block[names, names = OptionValue[names]; a + b]]
Here is the final version of my answer, containing the contributions from the answer by Brett Champion.
ClearAll[def];
SetAttributes[def, HoldAll];
def[lhs : f_[args___] :> rhs_] /; !FreeQ[Unevaluated[lhs], OptionsPattern] :=
With[{optionNames = Options[f][[All, 1]]},
lhs := Block[optionNames, optionNames = OptionValue[optionNames]; rhs]];
def[lhs : f_[args___] :> rhs_] := lhs := rhs;
The reason why the definition is given as a delayed rule in the argument is that this way we can
benefit from the syntax highlighting. Block trick is used because it fits the problem: it does not interfere with possible nested lexical scoping constructs inside your function, and therefore there is no danger of inadvertent variable capture. We check for presence of OptionsPattern since this code wil not be correct for definitions without it, and we want def to also work in that case.
Example of use:
Clear[f, a, b, c, d];
Options[f] = {a -> c, b -> d};
(*The default values.*)
def[f[n_, OptionsPattern[]] :> (a + b)^n]
You can look now at the definition:
Global`f
f[n$_,OptionsPattern[]]:=Block[{a,b},{a,b}=OptionValue[{a,b}];(a+b)^n$]
f[n_,m_]:=m+n
Options[f]={a->c,b->d}
We can test it now:
In[10]:= f[2]
Out[10]= (c+d)^2
In[11]:= f[2,a->e,b->q]
Out[11]= (e+q)^2
The modifications are done at "compile - time" and are pretty transparent. While this solution saves
some typing w.r.t. Brett's, it determines the set of option names at "compile-time", while Brett's - at "run-time". Therefore, it is a bit more fragile than Brett's: if you add some new option to the function after it has been defined with def, you must Clear it and rerun def. In practice, however, it is customary to start with ClearAll and put all definitions in one piece (cell), so this does not seem to be a real problem. Also, it can not work with string option names, but your original concept also assumes they are Symbols. Also, they should not have global values, at least not at the time when def executes.
Here's a kind of horrific solution:
Options[f] = {a->0, b->0};
f[OptionsPattern[]] := Module[{vars, tmp, ret},
vars = Options[f][[All,1]];
tmp = cat[vars];
each[{var_, val_}, Transpose[{vars, OptionValue[Automatic,#]& /# vars}],
var = val];
ret =
a + b; (* finally! *)
eval["ClearAll[", StringTake[tmp, {2,-2}], "]"];
ret]
It uses the following convenience functions:
cat = StringJoin##(ToString/#{##})&; (* Like sprintf/strout in C/C++. *)
eval = ToExpression[cat[##]]&; (* Like eval in every other lang. *)
SetAttributes[each, HoldAll]; (* each[pattern, list, body] *)
each[pat_, lst_, bod_] := ReleaseHold[ (* converts pattern to body for *)
Hold[Cases[Evaluate#lst, pat:>bod];]]; (* each element of list. *)
Note that this doesn't work if a or b has a global value when the function is called. But that was always the case for named arguments in Mathematica anyway.

Generating a list of lists of Int with QuickCheck

I'm working through Real World
Haskell one of the
exercises of chapter 4 is to implement an foldr based version of
concat. I thought this would be a great candidate for testing with
QuickCheck since there is an existing implementation to validate my
results. This however requires me to define an instance of the
Arbitrary typeclass that can generate arbitrary [[Int]]. So far I have
been unable to figure out how to do this. My first attempt was:
module FoldExcercises_Test
where
import Test.QuickCheck
import Test.QuickCheck.Batch
import FoldExcercises
prop_concat xs =
concat xs == fconcat xs
where types = xs ::[[Int]]
options = TestOptions { no_of_tests = 200
, length_of_tests = 1
, debug_tests = True }
allChecks = [
run (prop_concat)
]
main = do
runTests "simple" options allChecks
This results in no tests being performed. Looking at various bits and
pieces I guessed that an Arbitrary instance declaration was needed and
added
instance Arbitrary a => Arbitrary [[a]] where
arbitrary = sized arb'
where arb' n = vector n (arbitrary :: Gen a)
This resulted in ghci complaining that my instance declaration was
invalid and that adding -XFlexibleInstances might solve my problem.
Adding the {-# OPTIONS_GHC -XFlexibleInstances #-} directive
results in a type mismatch and an overlapping instances warning.
So my question is what's needed to make this work? I'm obviously new
to Haskell and am not finding any resources that help me out.
Any pointers are much appreciated.
Edit
It appears I was misguided by QuickCheck's output when in a test first manner fconcat is defined as
fconcat = undefined
Actually implementing the function correctly indeed gives the expected result. DOOP!
[[Int]] is already an Arbitrary instance (because Int is an Arbitrary instance, so is [a] for all as that are themselves instances of Arbitrary). So that is not the problem.
I ran your code myself (replacing import FoldExcercises with fconcat = concat) and it ran 200 tests as I would have expected, so I am mystified as to why it doesn't do it for you. But you do NOT need to add an Arbitrary instance.