7
say "1 10".split(" ") 

returns (1,10)

When I use those 1 and 10 as arguments to the sequence operator [...]

say [...] "1 10".split(" ")

returns just (1) while it's supposed to return (1 2 3 4 5 6 7 8 9 10) I guess it's because the output of the split function is interpreted as string.

How to solve that problem? Thank you.

Elizabeth Mattijsen
  • 25,654
  • 3
  • 75
  • 105
Terry
  • 1,206
  • 1
  • 10
  • 26
  • Where to put the 3rd number? Btw, `say [...] "1 10".split(" ").Seq` doesn't cut it. It returns just `(1)` whereas it's expected to return `(1 2 3 4 5 6 7 8 9 10)` – Terry Aug 07 '19 at 14:35
  • `"1 10".split(" ")` returns a sequence -- I used `(1,10).Seq` to make it equivalent. As for where to put the third number: this doesn't work like I suggested, please ignore. – ugexe Aug 07 '19 at 15:26
  • 1
    "the range operator `[...]`" Your code *is* using the op you're showing (an ellipsis or **3** dots, `…` or `...`) but that's *not* the `Range` op. Infix `...` is [the *sequence* operator](https://docs.perl6.org/language/operators#index-entry-..._operators). It takes one *or more* initial values *and an optional generator* on its left, a *smart matched* end value on its right, and constructs a [`Seq`](https://docs.perl6.org/type/Seq). There's *also* an infix **2** dot [*range* operator](https://docs.perl6.org/routine/...html), which constructs a [`Range`](https://docs.perl6.org/type/Range). – raiph Aug 07 '19 at 18:31
  • It was three dots, I mean not a special character containing 3 dots. But I've just tried with the special character `…` now and it did have no effect on the outcome, i.e. I still needed to put +<< hyperop in between to get the target sequence `(1 2 3 4 5 6 7 8 9 10)` – Terry Aug 07 '19 at 18:51
  • 1
    Right. Three dots means exactly the same thing as the special ellipsis character. They're aliased ops. My point was that you were calling it a "range" operator, but a range is a specific thing in P6 that's distinct from a sequence and there's a range operator which is *two* dots, not three. Anyhoo, I see you've edited your question to call it the sequence op so now it's all squared away. :) – raiph Aug 07 '19 at 22:22

2 Answers2

7

If you want numeric behavior then coerce to numerics:

say [...] +<< "1 10".split(" "); # (1 2 3 4 5 6 7 8 9 10)

This uses a << hyperop to apply a numeric coercion (prefix +) to each element of the sequence generated by the split.


Regarding sequence and range behavior with string endpoints:


What you've written is equivalent to:

put gist "1"..."10";

(say is equivalent to put gist.)

A gist of "1"..."10" is (1).

That's because the gist of List.new("1") is (1) just like the gist of List.new("a") is (a).

And "1"..."10" evaluates to a List.new("1").

Why? I'm not sure yet but I'm exploring the available info.

Let's start with the doc. The doc for the infix ... op says:

The default generator is *.succ or *.pred, depending on how the end points compare

Well:

say "1" cmp "10"; # Less

which presumably means the sequence starts calling *.succ.

And then:

say "1".succ;     # 2

and:

say "2" cmp "10"; # More

It seems this results in the sequence immediately terminating after the "1" rather than including the "2" and continuing.


I'm continuing to search the bug queues and examine the code around the area that @wamba++ linked in their answer to the above linked SO "Why does the Perl 6 sequence 'A' … 'AA' have only one element?".

Elizabeth Mattijsen
  • 25,654
  • 3
  • 75
  • 105
raiph
  • 31,607
  • 3
  • 62
  • 111
  • Thank you for the answer. It worked. So, the hyperop did the trick and that's fine. And I was wondering how it interpreted the "1 10" output of split into a just (1) and now I've got the idea. – Terry Aug 07 '19 at 17:56
  • Ops. I had forgotten to tick the answer there. Håkon's answer came first and it more or less solved the issue but still I didn't tick it as an answer, somehow. Then came your comprensive answer and I applied it to my code. I guess because I was busy fine tuning my code so I must have forgotten to tick an answer. Because your answer both solves the issue and meanwhile explains the way Perl 6 works, it's a better answer so I ticked it as the answer :) – Terry Aug 07 '19 at 18:41
4

As usual, raiph is giving the correct answer, but I find something missing about why it really does not work. Main thing is that [] is a reduce operator, it's not applying whatever is inside it as an infix operator except as a side effect. For instance, this works:

say [+] <4 8>.words; # OUTPUT: «12␤»

But only because there are two components, and the reduce [] is applied to them, having the same effect. Ditto for ...

say [...] <4 8>.words; # OUTPUT: «(4 5 6 7 8)␤»

However that's not what you are looking for. You have two operands, a single operator, you want to call the operator itself. Which you can of course do by using its fully qualified name

say infix:<...>( | <3 5>.words ); # OUTPUT: «(3 4 5)␤»

as long as, of course, you flatten (with | ) its arguments to make it match the signature of an infix operator.

As usual, TIMTOWTDI. So do whatever suits you the best.

jjmerelo
  • 22,578
  • 8
  • 40
  • 86
  • 1
    The real reason it doesn't work isn't what you're thinking. `say infix:<...>( | <1 10>.words ); # OUTPUT: «(1)␤»` demonstrates the problem remains in your reformulation of the syntax. It's the same as the `'A' ... 'AA'` SO I linked to. But my answer so far has ended up kinda rushed and cryptic. I plan to improve it in the next day or so once I feel I've gathered the related bug reports, issues, irc and design doc discussion especially by Larry, and Rakudo code lines, and can distill it all to explain it as coherently as I can manage. – raiph Aug 07 '19 at 22:41