What does plus mean in method declarations in Perl6?
Here is an example from spec
submethod BUILD (+$tail, +#legs, *%extraargs) {
$.tail = $tail;
#:legs = #legs;
}
2019 Update See the section Variadic positionals destructuring; +#foo and *#foo in my answer to the SO question "variable number of arguments to function/subroutine".
In 2015 Larry Wall introduced the + parameter prefix, one of four parameter prefixes (*, **, +, |) that signify slurpy (variadic) parameters. He added it to the Rakudo compiler, added some tests, gave a brief informal description of it on the irc channel, and added a section on it to the relevant language design doc.
The example quoted in the original question is taken from an archive of an informal document written and frozen in time over a decade ago. At that time a + parameter prefix signified a named parameter as contrasted with a positional one. Nowadays we use : for that, thus:
submethod BUILD (:$tail, :#legs, *%extraargs) {
$.tail = $tail;
#.legs = #legs;
}
Your "spec" links goes to a historical document, and the syntax has long gone from Perl 6. I'm not sure what it used to do, maybe "at least one argument", in analogy to the + quantifier in regexes.
For an up-to-date specification, please read http://perlcabal.org/syn/S06.html which contains all the information on signatures and subroutines.
Related
I know that by using 0:3 in this code in Pascal will put 3 decimal places to the result
var a,b:real;
begin
a:=23;
b:=7;
writeln(a/b:0:3);
readln;
end.
What I would like to know is if anyone has a source to learn what this : will do with other variables or if adding for example 0:3:4 will make a difference. Basically what : can do to a variable
For the exact definition of write parameters take a look at ISO standards 7185 and 10206, “Standard Pascal” and “Extended Pascal” respectively. These references are useless though if your compiler’s documentation does not make a statement regarding compliance with them. Other compilers have their own non-standard extensions, so the only reliable source of reference is your compiler’s documentation or even its source code if available.
[…] what this : will do with other variables […] Basically what : can do to a variable
As MartynA already noted this language is imprecise: The variables’ values are only read by write/writeLn/writeStr, thus leaving them unmodified.
[…] if adding for example 0:3:4 will make a difference.
To my knowledge a third write parameter is/was only allowed in PXSC, Pascal eXtensions for Scientific Computing. In this case the third parameter would indicate for the rounding mode (nonexistent or 0: closest printable number; greater than zero: round up; less than zero: round down).
This code works:
(3,6...66).contains( 9|21 ).say # OUTPUT: «any(True, True)»
And returns a Junction. It's also tested, but not documented.
The problem is I can't find its implementation anywhere. The Str code, which is also called from Cool, never returns a Junction (it does not take a Junction, either). There are no other methods contain in source.
Since it's autothreaded, it's probably specially defined somewhere. I have no idea where, though. Any help?
TL;DR Junction autothreading is handled by a single central mechanism. I have a go at explaining it below.
(The body of your question starts with you falling into a trap, one I think you documented a year or two back. It seems pretty irrelevant to what you're really asking but I cover that too.)
How junctions get handled
Where is contains( Junction) defined? ... The problem is I can't find [the Junctional] implementation anywhere. ... Since it's autothreaded, it's probably specially defined somewhere.
Yes. There's a generic mechanism that automatically applies autothreading to all P6 routines (methods, operators etc.) that don't have signatures that explicitly control what happens with Junction arguments.
Only a tiny handful of built in routines have these explicit Junction handling signatures -- print is perhaps the most notable. The same is true of user defined routines.
.contains does not have any special handling. So it is handled automatically by the generic mechanism.
Perhaps the section The magic of Junctions of my answer to an earlier SO Filtering elements matching two regexes will be helpful as a high level description of the low level details that follow below. Just substitute your 9|21 for the foo & bar in that SO, and your .contains for the grep, and it hopefully makes sense.
Spelunking the code
I'll focus on methods. Other routines are handled in a similar fashion.
method AUTOTHREAD does the work for full P6 methods.
This is setup in this code that sets up handling for both nqp and full P6 code.
The above linked P6 setup code in turn calls setup_junction_fallback.
When a method call occurs in a user's program, it involves calling find_method (modulo cache hits as explained in the comment above that code; note that the use of the word "fallback" in that comment is about a cache miss -- which is technically unrelated to the other fallback mechanisms evident in this code we're spelunking thru).
The bit of code near the end of this find_method handles (non-cache-miss) fallbacks.
Which arrives at find_method_fallback which starts off with the actual junction handling stuff.
A trap
This code works:
(3,6...66).contains( 9|21 ).say # OUTPUT: «any(True, True)»
It "works" to the degree this does too:
(3,6...66).contains( 2 | '9 1' ).say # OUTPUT: «any(True, True)»
See Lists become strings, so beware .contains() and/or discussion of the underlying issues such as pmichaud's comment.
Routines like print, put, infix ~, and .contains are string routines. That means they coerce their arguments to Str. By default the .Str coercion of a listy value is its elements separated by spaces:
put 3,6...18; # 3 6 9 12 15 18
put (3,6...18).contains: '9 1'; # True
It's also tested
Presumably you mean the two tests with a *.contains argument passed to classify:
my $m := #l.classify: *.contains: any 'a'..'f';
my $s := classify *.contains( any 'a'..'f'), #l;
Routines like classify are list routines. While some list routines do a single operation on their list argument/invocant, eg push, most of them, including classify, iterate over their list doing something with/to each element within the list.
Given a sequence invocant/argument, classify will iterate it and pass each element to the test, in this case a *.contains.
The latter will then coerce individual elements to Str. This is a fundamental difference compared to your example which coerces a sequence to Str in one go.
I saw this question and it got me wondering.
Ignoring the fact that pretty much all languages have to be backwards compatible, is there any reason we cannot use operators as both keywords and functions, depending on if it's immediately followed by a parenthesis? Would it make the grammar harder?
I'm thinking mostly of python, but also C-like languages.
Perl does something very similar to this, and the results are sometimes surprising. You'll find warnings about this in many Perl texts; for example, this one comes from the standard distributed Perl documentation (man perlfunc):
Any function in the list below may be used either with or without parentheses around its arguments. (The syntax descriptions omit the parentheses.) If you use parentheses, the simple but occasionally surprising rule is this: It looks like a function, therefore it is a function, and precedence doesn't matter. Otherwise it's a list operator or unary operator, and precedence does matter. Whitespace between the function and left parenthesis doesn't count, so sometimes you need to be careful:
print 1+2+4; # Prints 7.
print(1+2) + 4; # Prints 3.
print (1+2)+4; # Also prints 3!
print +(1+2)+4; # Prints 7.
print ((1+2)+4); # Prints 7.
An even more surprising case, which often bites newcomers:
print
(a % 7 == 0 || a % 7 == 1) ? "good" : "bad";
will print 0 or 1.
In short, it depends on your theory of parsing. Many people believe that parsing should be precise and predictable, even when that results in surprising parses (as in the Python example in the linked question, or even more famously, C++'s most vexing parse). Others lean towards Perl's "Do What I Mean" philosophy, even though the result -- as above -- is sometimes rather different from what the programmer actually meant.
C, C++ and Python all tend towards the "precise and predictable" philosophy, and they are unlikely to change now.
Depending on the language, not() is not defined. If not() is not defined in some language, you can not use it. Why not() is not defined in some language? Because creator of that language probably had not need this type of language construction. Because it is better to let things be simpler.
(Question by John Williams, from a Coursera forum, which I decided to share with the community, since I haven't been able to find this answered anywhere.)
The following code runs without error:
int _j = 1;
//int 2var = 2;
int var2 = 2;
int Kvar = 3; // first letter can be uppercase
int spec$var = 4;
int com_pound_var = 5; // compounding without camel case
int com$pound$two = 6;
int $var = 199;
println(_j);
println(var2);
println(Kvar);
println(spec$var);
println(com_pound_var);
println(com$pound$two);
println($var); //first character can be special
Since the compiler accepts _j, Kvar, and $var as valid variable names, it is clear that variable names do not need to start with a lowercase letter.
I was unable to locate the variable naming rules anywhere in the reference.
What are the variable naming rules for the Processing language?
Quick answer: can start with any letter, underscore and dollar signs, continue with letters, numbers, underscore and dollar signs. Details below.
I could also not find anything in the reference or the documentation at all. However, inspecting the source code, I found that Processing is not a language of its own, but rather a framework in which you run some commands. The difference is that you're actually writing a different language, and Processing just gives you some basic scaffolding where you build on top of.
For some technical details: Processing compiles a Java Build with some flags, spins up a virtual machine (Java VM, not same thing as a full fledged virtual machine) and connects to it to get input and output streams (this is why you can interact with the mouse or get the console output of your own program in a separate window). (Source.)
This language, which you may have guessed already, is Java.
With that said, the actual docs that answer this question is the Java Language Specification, which, to simplify things, is as close as you can get to an answer. (But if you really want to know, it's a mess.)
Specifically, the section on Identifiers, which I'll sum up below:
Can start with any letter (A-Z, a-z), underscore (_), dollar sign ($), or any unicode "letter" (accented, chinese, etc. Details.)
Can continue with any of the above, and can also continue with digits (0-9). Can also contain other unicode "letters" (Details.)
Can have unlimited length
Cannot be any Java keyword (list here)
Cannot be false, true, null
They can look the same and still be different if their codes are different (some Unicode letters look just like letters but are different ones)
I hope this helps! Investigating was fun.
I am very new to Flex/Bison, So it is very navie question.
Pardon me if so. May look like homework question - but I need to implement project based on below concept.
My question is related to two parts,
Question 1
In Bison parser, How do I provide rules for optional input.
Like, I need to parse the statment
Example :
-country='USA' -state='INDIANA' -population='100' -ratio='0.5' -comment='Census study for Indiana'
Here the ratio token can be optional. Similarly, If I have many tokens optional, then How do I provide the grammar in the parser for the same?
My code looks like,
%start program
program : TK_COUNTRY TK_IDENTIFIER TK_STATE TK_IDENTIFIER TK_POPULATION TK_IDENTIFIER ...
where all the tokens are defined in the lexer. Since there are many tokens which are optional, If I use "|" then there will be many different ways of input combination possible.
Question 2
There are good chance that the comment might have quotes as part of the input, so I have added a token -tag which user can provide to interpret the same,
Example :
-country='USA' -state='INDIANA' -population='100' -ratio='0.5' -comment='Census study for Indiana$'s population' -tag=$
Now, I need to reinterpret Indiana$'s as Indiana's since -tag=$.
Please provide any input or related material for to understand these topic.
Q1: I am assuming we have 4 possible tokens: NAME , '-', '=' and VALUE
Then the grammar could look like this:
attrs:
attr attrs
| attr
;
attr:
'-' NAME '=' VALUE
;
Note that, unlike you make specific attribute names distinguished tokens, there is no way to say "We must have country, state and population, but ratio is optional."
This would be the task of that part of the program that analyses the data produced by the parser.
Q2: I understand this so, that you think of changing the way lexical analysis works while the parser is running. This is not a good idea, at least not for a beginner. Have you even started to think about lexical analysis, as opposed to parsing?