I'm trying to become comfortable in Perl 6. One of the things I found handy in Python when I was at a REPL prompt was that I could do a dir(object) and find out the attributes of an object, which in Python includes the object's methods.
This often served as a helpful reminder of what I wanted to do; 'Oh, that's right, trim in Python is called strip', that sort of thing.
In Perl 6, I know about the introspection methods .WHO, .WHAT, .WHICH, .HOW and .WHY, but these are at a class or object level. How do I find out what's inside an object, and what I can do to it?
How do I find out what's inside an object, and what I can do to it?
You mentioned that you already know about the introspection methods - but are you aware of what you can find out by querying an objects metaobject (available from .HOW)?
$ perl6
>
> class Article {
* has Str $.title;
* has Str $.content;
* has Int $.view-count;
* }
>
> my Str $greeting = "Hello World"
Hello World
>
> say Article.^methods
(title content view-count)
>
> say Article.^attributes
(Str $!title Str $!content Int $!view-count)
>
> say $greeting.^methods
(BUILD Int Num chomp chop pred succ simplematch match ords samecase samemark
samespace word-by-word trim-leading trim-trailing trim encode NFC NFD NFKC NFKD
wordcase trans indent codes chars uc lc tc fc tclc flip ord WHY WHICH Bool Str
Stringy DUMP ACCEPTS Numeric gist perl comb subst-mutate subst lines split words)
>
> say $greeting.^attributes
Method 'gist' not found for invocant of class 'BOOTSTRAPATTR'
>
There is a shortcut for querying an object's metaobject;
a.^b translates to a.HOW.b(a). The methods and attributes for Article are themselves objects - instances of Method and Attribute. Whenever you call .say on an object, you implicitly call its .gist method which is meant to give you a summarized string representation of the object - i.e. the 'gist' of it.
The attributes of the builtin Str type appear to be of type BOOTSTRAPATTR type - which doesn't implement the .gist method. As an alternative, we can just ask for the attributes to spit out their names instead;
> say sort $greeting.^methods.map: *.name ;
(ACCEPTS BUILD Bool DUMP Int NFC NFD NFKC NFKD Num Numeric Str Stringy WHICH WHY
chars chomp chop codes comb encode fc flip gist indent lc lines match ord ords perl
pred samecase samemark samespace simplematch split subst subst-mutate succ tc tclc
trans trim trim-leading trim-trailing uc word-by-word wordcase words)
>
> say sort $greeting.^attributes.map: *.name
($!value)
>
You can find our more here (which is where just about everything for this answer came from).
Related
I am attempting to use lgamma from C's math.h in Perl6.
How can I incorporate this into Perl6?
I have tried
use NativeCall;
sub lgamma(num64 --> num64) is native(Str) {};
say lgamma(3e0);
my $x = 3.14;
say lgamma($x);
This works for the first number (a Str) but fails for the second, $x, giving the error:
This type cannot unbox to a native number: P6opaque, Rat
in block <unit> at pvalue.p6 line 8
I want to do this very simply, like in Perl5: use POSIX 'lgamma'; and then lgamma($x) but I don't see how to do that in Perl6.
The errors with native values isn't always clear.
Basically it is saying that a Rat isn't a Num.
3.14 is a Rat. (Rational)
say 3.14.^name; # Rat
say 3.14.nude.join('/'); # 157/50
You could just always coerce the value to Num everytime you call it.
lgamma( $x.Num )
That doesn't seem so great.
I would just wrap the native sub in another one that coerces all Real numbers to Num.
(Real is all Numeric except Complex)
sub lgamma ( Num(Real) \n --> Num ){
use NativeCall;
sub lgamma (num64 --> num64) is native {}
lgamma( n )
}
say lgamma(3); # 0.6931471805599453
say lgamma(3.14); # 0.8261387047770286
Your $x has no type. If you use any type for it, say num64, it will say:
Cannot assign a literal of type Rat (3.14) to a native variable of type num. You can declare the variable to be of type Real, or try to coerce the value with 3.14.Num or Num(3.14)
So you do exactly that:
my num64 $x = 3.14.Num;
This converts the number exactly to the representation that is required by lgamma
I am testing a random generator generating instances of my own type. For that I have a custom instance of Arbitrary:
complexGenerator :: (RandomGen g) => g -> (MyType, g)
instance Arbitrary MyType where
arbitrary = liftM (fst . complexGenerator . mkStdGen) arbitrary
This works well with Test.QuickCheck (actually, Test.Framework) for testing that the generated values hold certain properties. However, there are quite a few properties I want to check, and the more I add, the more time it takes to verify them all.
Is there a way to use the same generated values for testing every property, instead of generating them anew each time? I obviously still want to see, on failures, which property did not hold, so making one giant property with and is not optimal.
I obviously still want to see, on failures, which property did not hold, so making one giant property with and is not optimal.
You could label each property using printTestCase before making a giant property with conjoin.
e.g. you were thinking this would be a bad idea:
prop_giant :: MyType -> Bool
prop_giant x = and [prop_one x, prop_two x, prop_three x]
this would be as efficient yet give you better output:
prop_giant :: MyType -> Property
prop_giant x = conjoin [printTestCase "one" $ prop_one x,
printTestCase "two" $ prop_two x,
printTestCase "three" $ prop_three x]
(Having said that, I've never used this method myself and am only assuming it will work; conjoin is probably marked as experimental in the documentation for a reason.)
In combination with the voted answer, what I've found helpful is using a Reader transformer with the Writer monad:
type Predicate r = ReaderT r (Writer String) Bool
The Reader "shared environment" is the tested input in this case. Then you can compose properties like this:
inv_even :: Predicate Int
inv_even = do
lift . tell $ "this is the even invariant"
(==) 0 . flip mod 2 <$> ask
toLabeledProp :: r -> Predicate r -> Property
toLabeledProp cause r =
let (effect, msg) = runWriter . (runReaderT r) $ cause in
printTestCase ("inv: " ++ msg) . property $ effect
and combining:
fromPredicates :: [Predicate r] -> r -> Property
fromPredicates predicates cause =
conjoin . map (toLabeledProp cause) $ predicates
I suspect there is another approach involving something similar to Either or a WriterT here- which would concisely compose predicates on different types into one result. But at the least, this allows for documenting properties which impose different post-conditions dependent on the the value of the input.
Edit: This idea spawned a library:
http://github.com/jfeltz/quickcheck-property-comb
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.
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.
I'm working on an online judge for algorithm contests. I want to include support for many programming languages, but i don't know all of them. I have to make test sources, but i don't know all of these languages.
I want the equivalent of this code:
#include <stdio.h>
int main () {
int a, b;
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
scanf("%d%d", &a, &b);
printf("%d", a + b);
return 0;
}
In this programming languages.
I want to read from file input.txt two numbers, each on a line, and write the sum of them to the output file output.txt
Thank you.
EDIT Please don't tell me that Visual Basic .NET is not a functional language. I know it.
Haskell:
main = do
[astr, bstr] <- fmap lines (readFile "input.txt")
writeFile "output.txt" $ show (read astr + read bstr)
Or to sum all lines:
main = writeFile "output.txt" . show . sum . map read . lines =<< readFile "input.txt"
In F#:
System.IO.File.ReadAllLines "input.txt" |> Seq.sumBy int |> string
|> fun s -> System.IO.File.WriteAllText("output.txt", s)
An F# version that assumes that the input file contains just two lines (with numbers):
open System.IO
let [| astr; bstr |] = File.ReadAllLines "input.txt"
File.WriteAllText("output.txt", string (int astr + int bstr))
This is a bit simpler than Jon's version, but it is a more direct solution (and behaves the same as Haskell solution posted by others).
There are a ton of ways of doing this in Scala.
val f = (as : Array[String]) => as(0).toInt + as(1).toInt
io.Source.fromFile("C:/myfile.xtx").getLines().toStream match {
case line1 #:: _ => println(f(line1.split(","))
}
You could also do...
val splitLine = (_ : String).split(",")
val printSum = (as : Array[String]) => println(as(0).toInt + as(1).toInt)
val sums = io.Source.fromFile("C:/f.xtx").getLines() map (splitLine andThen printSum)
sums.head //start printing as Iterator is lazy
But then since side-effects should generally be avoided, you would probably want to make your functions pure
val sumLine = (as : Array[String]) => as(0).toInt + as(1).toInt
val sums = io.Source.fromFile("C:/f.xtx").getLines() map (splitLine andThen sumLine)
println(sums.head)
Some answers here seem confused about what the C code does. The C code is not particularly useful. It takes a file like
42
1776
this is any sort of random junk
because the program never reads this far
and produces a file containing
1818
and that is it. IMO, this is a lousy example for showing the power of functional languages because it does so little--one instance of one operation, basically. Yawn. With about the same amount of work, you could take a file with two columns of numbers and produce a file that had their sum in one column as an output. With a tiny bit more work, you could handle any conceivable error in the input.
But, fair enough, if this is the job at hand, one way to accomplish this in Scala is:
val pw = new java.io.PrintWriter("output.txt")
val num = scala.io.Source.fromFile("input.txt").getLines().map(_.toInt)
pw.print(num.next+num.next)
pw.close // Only use this line if execution continues (e.g. in REPL)
Racket Scheme:
(define (simpleSum)
(let* ((input (map string->number (file->lines "input.txt")))
(a (first input)) (b (second input)))
(write-to-file (number->string (+ a b)) "output.txt")))
I don't think scala has its advantage in such simple scenario, including all its fancy features and its api. It's better to use java library. java.util.Scanner has provided the useful nextInt() which can work in many cases and PrintWriter is the fastest output mechniasm in java.
val in = new Scanner(new FileInputStream("input.txt"))
val out = new PrintWriter("output.txt")
out.println((in.nextInt + in.nextInt))
out.close
in.close
And also, I'm curious about which online judge you're working on :)
Here is the VB.NET implementation:
Dim FileLines() as string = system.io.file.readalllines("input.txt")
system.io.file.WriteAllText("output.txt", ctype(FileLines(0), integer) + ctype(FileLines(1), integer))
Visual Basic is not a functional language, unless you use some of the LINQ features.