Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Perl6 String Concatenation Hangs

I'm trying to concatenate a string with Perl6 thus:

my $cmd = "databricks jobs --job-id 37 --notebook-params '\{";
put $cmd;
$cmd ,= "\"directory\": \"$s3-dir\",";
put $cmd;

However, the output hangs after the ,= operator. I'm assuming that this works the same way from the Perl .= operator.

https://docs.perl6.org/language/operators

Why is this job hanging? how can I properly concatenate the string?

like image 618
con Avatar asked Jan 28 '19 18:01

con


2 Answers

There is no ,= or ~= operators in Perl6.

Those are instances of the = meta operator combined with another infix operator.

# these are all functionally equivalent:
$a = $a ~ 'a';
$a ~= 'a';
$a [~]= 'a';
$a [&[~]]= 'a';
$a [&infix:<~>]= 'a';

$a = infix:<~> $a, 'a'; # use an operator as a subroutine

There is a history of C-like languages having operators like +=.
It would get a little tiring having to define new operators like that for every infix operator.
In Perl6 you can also easily define new operators.
So it has = as a meta-operator that will automatically work with all infix operators.

sub infix:<foo> (\l,\r){…}

$a = $a foo 3;
$a foo= 3;
$a [foo]= 3;

If you want to use an operator like +=, just look for the base operator that matches what you want and add =.

If you want to do string concatenation, the base operator is the infix ~ operator.
(Which looks a lot like the string coercion prefix operator ~.)

$a = $a ~ 'a';
$a ~= 'a';

If you want to do Set difference, the base operator is (-).

$a = $a (-) 3;
$a (-)= 3;

You can add any number of [] surrounding an infix operator.
(It needs space before it so that it isn't confused with postcircumfix [])

$a     -     3;
$a    [-]    3;
$a   [[-]]   3;
$a  [[[-]]]  3;

Which can be useful to make sure that meta operators combine the way you want them too.

$a -=         3;
$a [-]=       3;
3  R-=       $a; # $a = $a - 3;
$a [R-]=      3; # $a = 3 - $a;
3  R[-=]     $a; # $a = $a - 3;
3  R[[R-]=]  $a; # $a = 3 - $a;

This was extended so that [&…] where &… is the name of a function works as an infix operator.

sub bar (\l,\r){…}

# these are functionally identical.
$a = bar( $a, 3 );
$a = $a [&bar] 3;
$a [&bar]= 3;

When you used ,= you created a self-referential data structure.
(Note that say calls .gist, I added an extra .gist to be extra clear that I'm not printing a Str.)

my $c = 0;
# $c ,= 1;
$c = ($c,1);

say $c.gist;
# (\List_94195670785568 = (List_94195670785568 1))

say $c.WHICH;
# List|94195670785568

When you do something that coerces a List or Array into a Str, it follows the structure turning each part into a Str.

$c = ($c,…);

~$c;
# $c.Str
# |     \___________________
# |                         \
# $c[0].Str ~ ' ' ~ $c[1].Str
# |        \        \        \__________ 
# |    |    \        \__________________ 1.Str
# |    |     \
# |    V      \_____________
# |                         \
# $c[0].Str ~ ' ' ~ $c[1].Str
# |        \        \        \__________ 
# |    |    \        \__________________ 1.Str
# |    |     \
# |    V      \_____________
# |                         \
# $c[0].Str ~ ' ' ~ $c[1].Str
# |        \        \        \__________ 
# |    |    \        \__________________ 1.Str
# |    |     \
# |    V      \_____________
# |                         \
# …

It of course never finishes turning the first part into a Str.


The combination of , and = works safely with a Hash though.
(Which is what the docs show.)

my %c = a => 0;
%c ,= b => 1;
# %c = (%c, b => 1)

say %c.gist;
# {a => 0, b => 1}
like image 89
Brad Gilbert Avatar answered Oct 15 '22 23:10

Brad Gilbert


There was some confusion in the manual.

my $cmd = "databricks jobs --job-id 37 --notebook-params '\{";
put $cmd;
$cmd ,= "\"directory\": \"$s3-dir\",";
put $cmd;

should be

my $cmd = "databricks jobs --job-id 37 --notebook-params '\{";
put $cmd;
$cmd ~= "\"directory\": \"$s3-dir\",";
put $cmd;

the proper way to concatenate an already declared variable in Perl6 is with ~=

like image 41
con Avatar answered Oct 16 '22 01:10

con