4

A continuation of this question, and probably an even more weird one.

Can I e.g. concatenate two regexes using a sub? (Of course, I understand, how to do it with a regex)

The following code is totally wrong, but I hope it can explain what I want to do:

my Regex sub s12 ( $c, $v) {
   return / <{$c}> <{$v}> /
}

my regex consonant { <[a .. z] -[aeiou]>  }
my regex vowel { <[aeiou]> }

my regex open_syllable { &s12( &consonant, &vowel ) }

"bac" ~~ m:g/ <open_syllable> /;
say $/; # should be 'ba'
Eugene Barsky
  • 5,780
  • 3
  • 17
  • 40
  • 1
    Have you tried: `my regex open_syllable { $(s12( &consonant, &vowel )) }`? – Håkon Hægland Nov 10 '17 at 15:10
  • 1
    Are you just having trouble with syntax, or are you trying to make this work without rakudo being slow as it interprets the regex? Because you can do this exactly the way you showed, with very slightly different syntax. – piojo Nov 10 '17 at 15:57
  • Do you mean you want to write a function that uses core compiler methods to interpret what each regex is, and concatenate them at a lower level? (That's interesting, but I have no idea how.) Also, that sounds like an acceptable use case for `EVAL`. Either write code that is doing a type of compilation, or invoke the compiler explicitly. – piojo Nov 10 '17 at 16:03
  • I'm still struggling with syntax. As soon as I'll reach my p6, I'll test the suggestion. – Eugene Barsky Nov 10 '17 at 16:35

1 Answers1

5

What you wrote is basically right, but you need to tweak the syntax a little. First, you should declare your combining function like any other sub. Next, it seems like to interpolate a regex into another, <$r> is the right syntax, and to interpolate a function call into a regex, <{my-sub(args)}> is the right syntax. (No need to prefix the sub with an ampersand when calling it—& is mostly for when you want to refer to a Callable without calling it.) Combine these little fixes and your code works:

sub combine(Regex $a, Regex $b --> Regex) {
    / <$a> <$b> /
}

my regex consonant { <[a .. z] -[aeiou]>  }
my regex vowel { <[aeiou]> }

my regex open_syllable { <{combine(&consonant, &vowel)}> }

"bac" ~~ m:g/ <open_syllable> /;
say ~$/; # output: ba
piojo
  • 6,351
  • 1
  • 26
  • 36
  • Wow! That will save me from typing manually lots of alternative cases! (Though I suppose there will be additional questions) – Eugene Barsky Nov 10 '17 at 19:29
  • 1
    @piojo Nit: I think `returns` is scheduled to be deprecated -- ["This form is planned for future removal."](https://docs.perl6.org/type/Signature#index-entry---%3E-returns-Constraining_Return_Types). – raiph Nov 10 '17 at 19:56
  • 1
    @raiph Great! I never liked that there were two syntaxes for specifying the return type. I updated the code. – piojo Nov 11 '17 at 08:10
  • 1
    @piojo :) I hope you don't mind me piling up little nits... "were two syntaxes" **s/were/are/** `returns` is still accepted syntax, without a deprecation warning, and there's no mention of its removal in [6.d prep](https://github.com/perl6/6.d-prep). I apologize for writing "scheduled". **s/two/four/** The page my prior comment links to lists *four* current syntax options for controlling the returned value. (`-->` is the most general -- it supports specifying a *type constraint* (eg `--> Int`), just like the other three forms, but it also supports specifying a *constant value* (eg `--> 42`). – raiph Nov 11 '17 at 18:51
  • @raiph Oh, that's right, thanks. I disliked having multiple syntaxes so much I managed to forget two of them immediately upon reading the documentation. Now let me try forgetting those other two again... – piojo Nov 12 '17 at 02:06