Following this post on perlgeek, it gives an example of currying:
my &add_two := * + 2;
say add_two(5); # 7
Makes sense. But if I swap the + infix operator for the min infix operator:
my &min_two := * min 2;
say min_two(5); # Type check failed in binding; expected 'Callable' but got 'Int'
Even trying to call + via the infix syntax fails:
>> my &curry := &infix:<+>(2, *);
Method 'Int' not found for invocant of class 'Whatever'
Do I need to qualify the Whatever as a numeric value, and if so how? Or am I missing the point entirely?
[Edited with responses from newer rakudo; Version string for above: perl6 version 2014.08 built on MoarVM version 2014.08]
Your Rakudo version is somewhat ancient. If you want to use a more recent cygwin version, you'll probably have to compile it yourself. If you're fine with the Windows version, you can get a binary from rakudo.org.
That said, the current version also does not transform * min 2 into a lambda, but from a cursory test, seems to treat the * like Inf. My Perl6-fu is too weak to know if this is per spec, or a bug.
As a workaround, use
my &min_two := { $_ min 2 };
Note that * only auto-curries (or rather 'auto-primes' in Perl6-speak - see S02) with operators, not function calls, ie your 3rd example should be written as
my &curry := &infix:<+>.assuming(2);
This is because the meaning of the Whatever-* depends on context: it is supposed to DWIM.
In case of function calls, it gets passed as an argument to let the callee decide what it wants to do with it. Even operators are free to handle Whatever explicitly (eg 1..*) - but if they don't, a Whatever operand transforms the operation into a 'primed' closure.
Related
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.
I am using Xilinx ISE 10.1 to run some verilog code. In the code I want to write the register values of 3 registers in a file, cipher.txt. The following is the code snippet:
if (clk_count==528) begin
f1 = $fopen("cipher.txt", "w");
$fwrite(f1, "clk: %d", clk_count[11:0]);
$fwrite(f1, "plain: %h", plain[31:0]);
$fwrite(f1, "cipher: %h", cipher[31:0]);
$fclose(f1);
end
At the end of execution, the contents of cipher.txt is found as:
clk: %dplain: %hcipher: %h
There is no other error encountered, but a warning comes up corresponding to the 3 fwrite's:
Parameter 3 is not constant in call of system task $fwrite.
Parameter 3 is not constant in call of system task $fwrite.
Parameter 3 is not constant in call of system task $fwrite.
The values of the registers clk_count and cipher change on every clock cycle (value of register plain remains constant throughout), and the values are written to cipher.txt when clk_count equals 528 (indicated by the if statement)
Can anybody provide some insight and/or help me get past this hurdle?
Thanks.
It appears that ISE expects the arguments to $fwrite to be constant. The warnings are referring to clk_count[11:0], plain[31:0], and cipher[31:0], which are not constant. By definition they are changing each cycle so they are not known at compile time. This also explains why they are not printing and you are seeing %d and %h in the output.
There is nothing to my knowledge in the Verilog spec that requires the arguments to $fwrite be constant. The same code works as expected with Cadence Incisive. My guess is that it's a limitation of ISE, so you may want to check with Xilinx.
Possible work-arounds:
1) Use $swrite to create a string with the proper formatting. Then write the string to the file.
2) Try using an intermediate variable in the calls to $fwrite. Maybe the part-selects are throwing it off. e.g.
integer foo;
foo = clk_count[11:0];
$fwrite(... , foo , ...);
Either of those might work, or not.
Out of curiosity, if you remove the part-selects, and try to print clk_count without the [11:0] , do you get the same warnings?
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.
This is my code:
x := 22 storeString.
y := x + x.
Transcript show: y.
Expected output: 2222
Actual output: 44.
I thought that the storeString message, sent to 22, assigned to x, would result in a string value being stored into x.
So I thought, I'm pretty new in smalltalk. Maybe it's order of operations? So I tried this:
x := (22 storeString).
y := x + x.
Transcript show: y.
Same result, and same, if I use printOn instead of storeOn. This is probably a day-one tutorial-following type question. But what is going on? Note that I know about the concatenation operator (,) but I am still wondering how it is that you can add two strings together like this? Is some implicit conversion from string back to integer happening as part of +?
Only a few things are implicit in Smalltalk. You can browse the implementation of #+ selector in String class and find out yourself what is going on. Or print String >> #+ definition.
You can also check out the internals of any running object instance, so you could have evaluated x inspect, to find out that x really is a String.
#+ is implemented on String and does a coercion to a Number before doing the addition.
Squeak has lot of eToys (a Smalltalk variation for kids) code spread throughout its core codebase. This is likely the reason why String implements all math operators. In Pharo the math operators have been mostly removed from String, so '1' + '2' raises an error like in any other Smalltalk.
Open a workspace. Enter:
'12' + '34'
Highlight and then use the right button menu to invoke "debug it". If ever there was a "killer app" for Smalltlak, it is the way the Smalltalk debugger interacts with the "all objects all the time" nature of Smalltalk. You can see what everything is and how it does. If you use "into", you'll be able to see exactly how it pulls off turning that into '46'.
Even cooler (I think), is that you can do
12 + '34'
(the first is no longer a string, rather a direct number). Again, you can use the debugger, and the whole double dispatch mechanism Smalltalk uses to do transcendental math will be opened up to you.
You can even do weirder examples like
4.0 + #('13' 2)
(here we're adding a number to an array, and the array contents are of mixed type)
Happy Smalltalking!
this behavior may appear puzzling to anyone not familiar with smalltalk, especially since in other languages the exact opposite tends to happen (numbers are coerced to strings).
the reason why this not a problem, is because string concatenation is done with ,. once aware of that, it becomes clear that '22' + 22 or even '22' + '22' can never be '2222'. it's either going to fail, or produce 44.
so if string concatenation is what you want, you need to send the right message:
x := 22 storeString.
y := x , x.
Transcript show: y.
i'm just about to learn inline assembly.the GCC inline assembly cookbook http://www.ethernut.de/en/documents/arm-inline-asm.html
says:
A strict rule is: Never ever write to an input operand.
can someone tell me whether - and if so why - this rule is true?
let's say i get the value of an input operand through some register. Am I not allowed to reuse this register within the same assembly block if i don't inted to declare it also as output operand?
example:
asm volatile("add %[value], %[value], %[value] \n\t"
"mov %[result], %[value] \n\t"
: [result]"=r" (y)
: [value]"r" (x)
: //no clober
);
I know the example doesn't make much sense - but is it invalid?
I ask because i'm writing some assembly function that takes many input operands, each taking a general purpose register. since there are only 12 GPR's available on my architecture, with each input operand i get less "free" registers to work with. so do I really have to declare the input registers also as output in order to use them to "work" with them inside the function (even though i don't need theyr value outside the inline-assembly body? If so - can someone explain why?
hope the question is clear
thanks!
The compiler doesn't know x is clobbered (and I think there is no way to clobber an input register in a valid way). So it might reuse the register holding x later in the code assuming it still holds an unaltered value which isn't true since you changed it.