We can use reduce with a sub with two arguments, putting it in double brackets:
> sub mysum { $^a + $^b }
> [[&mysum]] 1,3,5
9
But what if we want to use an anonymous function instead?
Both following variants produce a compile error:
> [[&{ $^a + $^b }]] 1,3,5
> [[{ $^a + $^b }]] 1,3,5
You are not allowed to have any spaces in that form of reduce.
> [[&({$^a+$^b})]] 1, 3, 5
9
This is so that it is more obvious that it is a reduce, and not an array declaration.
> [ { $^a + $^b }, { $^a * $^b } ].pick.(3,5)
8 | 15
The double [[…]] is just an extension of allowing any function to be used as an infix operator.
Note that you must use &(…) in this feature, when not talking about a named function &foo, or an already existing infix operator.
> 3 [&( { $^a + $^b } )] 5
8
This is sort-of an extension of using […] for bracketing meta operators like Z and =
> #a [Z[[+]=]] 1..5
> #a Z[[+]=] 1..5
> #a Z[+=] 1..5
> #a Z+= 1..5
Not sure why that doesn't work. But there's always:
say reduce { $^a + $^b }, 1,3,5 # 9
I'm guessing you knew that but it's all I've got for tonight. :)
I've now moved my comment here and expanded it a bit before I go to sleep.
The TTIAR error means it fails to parse the reduce as a reduce. So I decided to take a quick gander at the Perl 6 grammar.
I searched for "reduce" and quickly deduced that it must be failing to match this regex.
While that regex might be only 20 or so lines long, and I recognize most of the constructs, it's clearly not trivial. I imagine there's a way to use Grammar::Debugger and/or some other grammar debugging tool with the Perl 6 grammar but I don't know it. In the meantime, you must be a bit of a regex whiz by now, so you tell me: why doesn't it match? :)
Update
With Brad's answer to your question as our guide, the answer to my question is instantly obvious. The first line of the regex proper (after the two variable declarations) directly corresponds to the "no spaces" rule that Brad revealed:
<?before '['\S+']'>
This is an assertion that the regex engine is positioned immediately before a string that's of the form [...] where the ... is one or more non-space characters. (\s means space, \S means non-space.)
(Of course, I'd have been utterly baffled why this non-space rule was there without Brad's answer.)
Related
I got a task on code wars.
The task is
In this simple Kata your task is to create a function that turns a string into a Mexican Wave. You will be passed a string and you must return that string in an array where an uppercase letter is a person standing up.
Rules are
The input string will always be lower case but maybe empty.
If the character in the string is whitespace then pass over it as if it was an empty seat
Example
wave("hello") => []string{"Hello", "hEllo", "heLlo", "helLo", "hellO"}
So I have found the solution but I want to understand the logic of it. Since its so minimalistic and looks cool but I don't understand what happens there. So the solution is
fun wave(str: String) = str.indices.map { str.take(it) + str.drop(it).capitalize() }.filter { it != str }
Could you please explain?
str.indices just returns the valid indices of the string. This means the numbers from 0 to and including str.length - 1 - a total of str.length numbers.
Then, these numbers are mapped (in other words, transformed) into strings. We will now refer to each of these numbers as "it", as that is what it refers to in the map lambda.
Here's how we do the transformation: we first take the first it characters of str, then combine that with the last str.length - it characters of str, but with the first of those characters capitalized. How do we get the last str.length - it characters? We drop the first it characters.
Here's an example for when str is "hello", illustrated in a table:
it
str.take(it)
str.drop(it)
str.drop(it).capitalize()
Combined
0
hello
Hello
Hello
1
h
ello
Ello
hEllo
2
he
llo
Llo
heLLo
3
hel
lo
Lo
helLo
4
hell
o
O
hellO
Lastly, the solution also filters out transformed strings that are the same as str. This is to handle Rule #2. Transformed strings can only be the same as str if the capitalised character is a whitespace (because capitalising a whitespace character doesn't change it).
Side note: capitalize is deprecated. For other ways to capitalise the first character, see Is there a shorter replacement for Kotlin's deprecated String.capitalize() function?
Here's another way you could do it:
fun wave2(str: String) = str.mapIndexed { i, c -> str.replaceRange(i, i + 1, c.uppercase()) }
.filter { it.any(Char::isUpperCase) }
The filter on the original is way more elegant IMO, this is just as an example of how else you might check for a condition. replaceRange is a way to make a copy of a string with some of the characters changed, in this case we're just replacing the one at the current index by uppercasing what's already there. Not as clever as the original, but good to know!
This error occurs on line 3 of my code and I don't know why.
I'm trying to create multiple variables with x..q, but it doesn't work.
for i=1,3 do
for q=1,3 do
x..q=i+1
print(x..q)
end
end
The output should be:
2
2
2
3
3
3
4
4
4
But instead it returns the error in the title.
If you want to create multiple global variables, use code like this:
for i=1,3 do
for q=1,3 do
_G["x"..q]=i+1
print(_G["x"..q])
end
end
This code will create globals x1, x2, and x3.
But I think you'd be better off using a table:
x={}
for i=1,3 do
for q=1,3 do
x[q]=i+1
print(x[q])
end
end
I believe you are using the operator .. unintentionally.
When accessing a value of a table, the syntax is x.q. Programming in Lua: 2.5 – Tables
To represent records, you use the field name as an index. Lua supports this representation by providing a.name as syntactic sugar for a["name"]. So, we could write the last lines of the previous example in a cleanlier manner as
a.x = 10 -- same as a["x"] = 10
print(a.x) -- same as print(a["x"])
print(a.y) -- same as print(a["y"])
When concatenating a string the syntax is x .. q.
Programming in Lua: 3.4 – Concatenation
Lua denotes the string concatenation operator by ".." (two dots). If any of its operands is a number, Lua converts that number to a string.
print("Hello " .. "World") --> Hello World
print(0 .. 1) --> 01
In the Perl doc, there is a section about .postfix/.postcircumfix, it says that
In most cases, a dot may be placed before a postfix or postcircumfix:
my #a;
#a[1, 2, 3];
#a.[1, 2, 3]; # Same
Technically, not a real operator; it's syntax special-cased in the compiler.
I tried myself:
> my #a = 1,2,3,4,5
> #a[1] # 2
> #a.[1] # 2
> my %a = Perl => 6, Python => 3, PHP => 7
> %a<Perl> #6
> %a.<Perl> #6
> my #weekdays = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'];
> #weekdays.antipairs.hash{'Sunday'} # 6, I expected it to be syntax wrong, but it did work!
> #weekdays.antipairs.hash.{'Sunday'} # 6, seems visual clarity or brevity
So, what does the dot before a postfix or postcircumfix in Perl 6 mean? How on earth did it do that? I'm curious about that. Thanks.
An expression in Perl 6 is parsed as termish things with infixish things between them. A termish is in turn defined as zero or more prefixish things, followed by the term itself, followed by zero or more postfixish things. The postfixish takes in all of:
Method calls ( like .foo)
Postfix operators (like ++)
Postcircumfix operators (like the [42] in #a[42])
Doing hyper (>>) on these to distribute them across a data structure
Since it just looks for zero or more of them, then you can freely interleave method calls and hash and array indexes. This explains why #weekdays.antipairs.hash{'Sunday'} parses fine (and why #weekdays.antipairs.hash<Sunday> would also work, and even #weekdays.antipairs.hash<Sunday>.say is fine too).
As for the ., the grammar simply accepts and ignores a . before a postfix or a postcircumfix. Here's a slightly cut-down version of the parser, that I've annotated a bit to explain what the pieces are.
token postfixish {
<!stdstopper>
# If we're not in a string interpolation, allow unspace (that's
# where you write `\ ++`, for example, allowing spreading
# postfixish things over multiple lines).
[ <!{ $*QSIGIL }> [ <.unsp> | '\\' ] ]?
# Here we match the >> for doing a hyper. Note that it accepts
# but disregards a '.' before it. It's not captured at all and
# doesn't affect the code that is compiled.
[ ['.' <.unsp>?]? <postfix_prefix_meta_operator> <.unsp>?]**0..1
[
| <OPER=postfix>
# When there'd be no confusion with a method call, a '.' is
# also accepted and disregarded before a postfix operator
| '.' <?before \W> <OPER=postfix> ## dotted form of postfix operator (non-wordy only)
| <OPER=postcircumfix>
# Ditto here for recognized postcircumfixes
| '.' <?[ [ { < ]> <OPER=postcircumfix>
| <OPER=dotty>
| <OPER=privop>
]
}
Thus the . means nothing at all in this context. The parser simply accepts it and then moves on to look for the thing it actually cares about at that point.
One other thing worth noting is that postfix and postcircumfix operators all work after a dotty term too, operating on $_. Thus:
my #xs = 1..10;
.++ for #xs;
say #xs;
Will produce:
[2 3 4 5 6 7 8 9 10 11]
Here's a postcircumfix example:
my %h = a => 1, b => 2, c => 3;
say .<a> + .<c> given %h;
Which produces 4.
Perl 6 syntax is generally designed to make it easy to shift code from one form to another, and accepting the . in places even where it's not strictly needed eases that a little (so one could refactor to say %h1.<a> + %h2.<b>; and the parser will be fine with it). It may also be helpful for learning purposes to consider %h<a> short for %h.<a>, which would in turn make .<a> given %h a little less of a surprise.
The extra space afforded by the . may also aid clarity, especially if one was to stack multiple postfixes, and could even - should a language extension for some reason decide to define some "interesting" terms or postfix operators - serve as a means to disambiguate.
It actually does matter when you have a sub that returns a Callable.
sub foo { 'hello' }
sub bar { &foo; }
bar.WHAT # (Sub)
bar().WHAT # (Sub)
bar.().WHAT # (Str)
bar()().WHAT # (Str)
bar().().WHAT # (Str)
bar.().().WHAT # No such method 'CALL-ME' for invocant of type 'Str'
i am working on the problem of Number shuffle https://rubymonk.com/learning/books/1-ruby-primer/problems/154-permutations#solution4802. exercises asks to:
return a sorted array of all the unique numbers that can be formed
with 3 or 4 digits.
there is a solution (See the Solution) below the exercise, that looks like this:
def number_shuffle(number)
no_of_combinations = number.to_s.size == 3 ? 6 : 24
digits = number.to_s.split(//)
combinations = []
combinations << digits.shuffle.join.to_i while
combinations.uniq.size!=no_of_combinations
combinations.uniq.sort
end
I have a few questions, can anyone explain me:
1) in 'no_of_combinations' variable what does it mean '3 ? 6 : 24'? i think 3 is amount of digits in the number. question mark ( ? ) is symbol of 'if'- if number digits are 3, the amount of numbers will be 6 in the array of combinations. colon (punctuation) is symbol sign, but i do not know why 24, there are 23 symbols considering white space in the array of combinations.
2) what does it mean << symbol after combinations? i know that it is addition sign, but what does it do here? and also, what it means exclamation mark after 'size' in the following string?
1) in 'no_of_combinations' variable what does it mean '3 ? 6 : 24'?
The expression needs to include the comparison to make sense . . .
number.to_s.size == 3 ? 6 : 24
This is the ternary if. If the comparison before the ? is true, it evaluates to the first value (6 here), if it is false it evaluates to the second value (24 here). It has nothing to do with literal Symbol values . . . in fact Ruby parser will always treat the colon as a value separator here, however you space it.
The syntax of this operator is originally from C, and you will find it copied to many other languages.
2) what does it mean << symbol after combinations? i know that it is addition sign, but what does it do here?
It is not an addition sign. This operator does different things depending on the class of the object (on the left). In this example, that is an Array, and << pushes the object on the right onto the end of the array. It is almost identical to push
and also, what it means exclamation mark after 'size' in the following string?
In this case it is part of !=, or "not equals" comparison operator. The original author could have made this clearer with a bit of whitespace.
I need to be able to match a certain string ('[' then any number of equals signs or none then '['), then i need to match a matching close bracket (']' then the same number of equals signs then ']') after some other match rules. ((options{greedy=false;}:.)* if you must know). I have no clue how to do this in ANTLR, how can i do it?
An example: I need to match [===[whatever arbitrary text ]===] but not [===[whatever arbitrary text ]==].
I need to do it for an arbitrary number of equals signs as well, so therein lies the problem: how do i get it to match an equal number of equals signs in the open as in the close? The supplied parser rules so far dont seem to make sense as far as helping.
You can't easely write a lexer for it, you need parsing rules. Two rules should be sufficient. One is responsible for matching the braces, one for matching the equal signs.
Something like this:
braces : '[' ']'
| '[' equals ']'
;
equals : '=' equals '='
| '=' braces '='
;
This should cover the use case you described. Not absolute shure but maybe you have to use a predicate in the first rule of 'equals' to avoid ambiguous interpretations.
Edit:
It is hard to integrate your greedy rule and at the same time avoid a lexer context switch or something similar (hard in ANTLR). But if you are willing to integrate a little bit of java in your grammer you can write an lexer rule.
The following example grammar shows how:
grammar TestLexer;
SPECIAL : '[' { int counter = 0; } ('=' { counter++; } )+ '[' (options{greedy=false;}:.)* ']' ('=' { counter--; } )+ { if(counter != 0) throw new RecognitionException(input); } ']';
ID : ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_')*
;
WS : ( ' '
| '\t'
| '\r'
| '\n'
) {$channel=HIDDEN;}
;
rule : ID
| SPECIAL
;
Your tags mention lexing, but your question itself doesn't. What you're trying to do is non-regular, so I don't think it can be done as part of lexing (though I don't remember if ANTLR's lexer is strictly regular -- it's been a couple of years since I last used ANTLR).
What you describe should be possible in parsing, however. Here's the grammar for what you described:
thingy : LBRACKET middle RBRACKET;
middle : EQUAL middle EQUAL
| LBRACKET RBRACKET;