Beefy Boxes and Bandwidth Generously Provided by pair Networks
The stupid question is the question not asked
 
PerlMonks  

Re: Generate the perl sequence 1, 11, 111, ....

by moritz (Cardinal)
on Oct 10, 2008 at 07:41 UTC ( #716372=note: print w/ replies, xml ) Need Help??


in reply to Generate the perl sequence 1, 11, 111, ....

my @ones = map { 1 x $_ } 1..100;


Comment on Re: Generate the perl sequence 1, 11, 111, ....
Download Code
Re^2: Generate the perl sequence 1, 11, 111, ....
by jeanluca (Deacon) on Oct 10, 2008 at 07:54 UTC
    I wanted to post something similar
    @ones =map("1" x $_, 0..10) ;
    What I don't understood is how it is possible that map can accept different syntax. For example, is it possible to write a perl subroutine that does the same thing, myPerlSub BLOCK LIST
    Thnx
    LuCa

    UPDATE: thnx for the explanation!!
      ... is it possible to write a perl subroutine that does the same thing, myPerlSub BLOCK LIST
      Absolutely. See perlsub and in particular Prototypes.
      >perl -wMstrict -le "sub mysub (&@) { my $coderef = shift; map $coderef->($_), @_; } my @out = mysub { $_ += 33 } 0 .. 5; print qq{@out}; " 33 34 35 36 37 38
      The odd-looking syntax
      mysubroutine {block} @list;
      is mentioned in perlsub. Look in the section on prototypes where it describes the "&" prototype character, particularly the sentence "An & requires an anonymous subroutine, which, if passed as the first argument, does not require the sub keyword or a subsequent comma" and also the examples "try", "catch", and "mygrep".
       
      On the other hand, it looks to me that map is somewhat more magical than the examples in perlsub; if you call
      map (sub { "1" x $_ }, (1..10));
      it returns an array of coderefs (references to subroutines) which is not at all what is needed here.
       
      Also, not all builtin functions have regular enough syntax to be expressed with a prototype at all. map is one of them:
      perl -wle 'print prototype("CORE::map")'
      prints
      Use of uninitialized value in print at -e line 1.
        On the other hand, it looks to me that map is somewhat more magical than the examples in perlsub; if you call
        map (sub { "1" x $_ }, (1..10));
        it returns an array of coderefs (references to subroutines) which is not at all what is needed here.

        I personally believe that indeed map and its sibling grep are more magical: precisely because as I wrote in my reply to the OP they accept an expression to be evaluated for each of the other parameters. But I don't understand what you mean with "which is not at all what is needed here" because your example does exaclty what I mean: I do expect it to return a list (not an array!) of coderefs. Only, it probably does not do what you expect in that those coderefs are... all the same coderef:

        C:\temp>perl -E "say for map sub {1 x $_} => 1..3" CODE(0x182a944) CODE(0x182a944) CODE(0x182a944)

        This is because $_ is a package variable and those anonymous subs are not closures: when you will use one of them, its $_ will be that in scope at the moment, not the one passed to map() when it was created. To obtain that you have to close over a lexical:

        C:\temp>perl -E "say for map { my $x=$_; sub {1 x $x} } 1..3" CODE(0x23aa7c) CODE(0x182aef4) CODE(0x182ad74)

        Alternatively, and this is the interesting point to be noted here, Perl 5.10 and highter support lexical $_:

        C:\temp>perl -E "my $_; say for map sub {1 x $_} => 1..3" CODE(0x23a97c) CODE(0x182a9bc) CODE(0x183bbbc)
        --
        If you can't understand the incipit, then please check the IPB Campaign.
      What I don't understood is how it is possible that map can accept different syntax. For example, is it possible to write a perl subroutine that does the same thing, myPerlSub BLOCK LIST
      Thnx
      LuCa

      UPDATE: thnx for the explanation!!

      I personally believe that you shouldn't be too surprised. Quite a lot of builtin functions accept different kinds of arguments. Just see the first one that springs to mind, e.g. perldoc -f split:

      split /PATTERN/,EXPR,LIMIT split /PATTERN/,EXPR split /PATTERN/ split Splits the string EXPR into a list of strings and returns +that list. By default, empty leading fields are preserved, and +empty trailing ones are deleted. (If all fields are empty, they +are considered to be trailing.)

      Ok, the case of map is somewhat more surprising: actually, not only is it possible, as others explained to you, to implement the syntax above with Prototypes (which indeed are there much to the objective of letting you write subs that behave like builtins) but it is currently impossible to implement the alternate syntax of map() i.e. namely that with an expression since that would be more akin to to a macro, but there's not provision for such a beast under Perl 5. Of course you can write a sub that accepts a generic argument as the first one and when you use it, then the argument can be an expression, but that would be evaluated and passed to the sub as a scalar, not as an expression to be evaluated by your sub itself.

      HTH.

      --
      If you can't understand the incipit, then please check the IPB Campaign.
Re^2: Generate the perl sequence 1, 11, 111, ....
by dHarry (Abbot) on Oct 10, 2008 at 08:00 UTC

    Is there some name for this kind of sequence

    1 liner :-)

      Hello all, This is my very first post/reply to perlmonks.org :)
      my $one_literal = "1"; my $counter = 1; while ( 1 ) { for ( my $i = 1; $i <= $counter; $i++ ) { printf "$one_literal"; } printf "\n"; $counter++; }
        Do you mind if I offer a critique? There are a few minor points that could be improved.
        • If all that $one_literal can contain is "1", then the variable isn't needed.
          If $one_literal can contain something other than "1", then it's misnamed.

        • Speaking of being misnamed, $one_literal doesn't contain a literal. It contains a string. String literals are pieces of source code that get compiled into strings. They don't exist anywhere but in source code.

        • The first argument of printf is a formatting string. Using it to print arbitrary string is a trap waiting to be sprung. Instead, use print or printf('%s', ...).

        • The C syntax for "for" loops (for ( my $i = 1; $i <= $counter; $i++ )) is much more complex than alternative syntax Perl provides (for my $i ( 1..$counter )). That makes it more error-prone and harder to parse mentally (small variations will be obscured).

        Hello all, This is my very first post/reply to perlmonks.org :)

        I personally believe, then, in addition to the Perl-specific points addressed by ikegami (which I was about to point out myself...) that as a behavioural rule you should have posted your reply not as a comment to a more or less random entry of this thread, but as one to the root node because it anwers the latter not the former.

        --
        If you can't understand the incipit, then please check the IPB Campaign.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://716372]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others contemplating the Monastery: (3)
As of 2014-10-24 21:44 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    For retirement, I am banking on:










    Results (138 votes), past polls