Perché tu vai su #perl6 e dici “ma subst non è implementata? Va bene se ne metto una versione scema in Prelude.pm?” e larry wall ti risponde “si va bene” (log).

Dopo di che passi ad implementarla, usando una quantità di tempo incredibilmente superiore alle aspettative, navigando in haskell, pseudo haskell, meta haskell, perl5 e perl6, sotto la guida di gaal, moritz & fglock. Ed avendo cura di infilarci una discussione su italiano, ebraico e ungherese, tanto per soddisfare il linguista che è in te.

E finisci per definire un pezzettino delle specifiche di perl6, in modo che assomigli di più a ruby (log) ;)

UPDATE:

ripensandoci, forse è simpatico se vi faccio vedere il codice di subst :)

 1     method subst($rule, $replacement) is primitive is safe {
	
 2         my ($rgx,$adv,$dup = self);
 3 
 4         if $rule.isa(Str) {
	
 5           $rgx =  "<’$rule‘>";
 6         }
 7         else {
	
 8           $rgx = Pugs::Internals::rule_pattern($rule);
 9           $adv = Pugs::Internals::rule_adverbs($rule);
10         }
	
11 
12         my $advstr = $adv.map: { ":$_[0]"~"($_[1])"}.join if $adv;
	
13         my $apply = () if $replacement ~~ Code;
14         my $op="s$advstr/$rgx/\$replacement$apply/";
	
15 
16         eval($dup ~~ ~$op);
17         $dup
18     }
	

le dichiarazioni “is primitive is safe” sono per pugs, e sono una delle cose che mi poiace in perl6. Concettualmente si possono attaccare un sacco di metadati a una funzione, in questo caso ci limitiamo a dire che è una funzione di basso livello e che può essere usata all’interno di eval(), quindi ad esempio attraverso run.pugscode.org o lambdabot.

I puristi della OO e dei linguaggi dinamici dovrebbero arrabbiarsi per quei blocchi condizionali che fanno un check sul tipo, ma purtroppo è l’unica soluzione a cui sono arrivato.

Ora: in perl6 è possibile usare una espressione regolare all’interno di un’altra in questo modo: /< $regex>/ ma questo non è implementato in pugs, motivo per cui devo ricostruire la cosa a colpi di string interpolation & eval.

Altra cosa curiosa è che in pugs non si può risalire facilmente ad una rappresentazione di una regex per cui valga eval($regex.qualcosa())==$regex. In ruby ad esempio, Regexp#to_s restituisce una rappresentazione eval’abile, perché le Regexp sono essenzialmente solo delle stringhe.

In Perl6 invece una Rule (non le chiamiamo più regex perché sono molto di più) è più simile ad un programma che a una stringa, con tanto di regole di scope, argomenti, ereditarietà etc.

IMHO questo non significa che non si possa avere una rappresentazione in forma di stringa, ma per ora dalla regia dicono di no.

Questo per quanto riguarda il secondo ramo dell’if.

Il primo ramo sfrutta invece un’altra nuova caratteristica di Perl6, ovvero una sintassi speciale per effettuare il match di una stringa letterale, per cui
“hello” matcha /he..o/, matcha /< 'hello'>/ ma non matcha /< 'he..o'>/.

Ovviamente anche questo lo impacchettiamo nell’eval.

Infine facciamo la porcata di aggiungere un “()” per forzare l’applicazione di $replacement in caso questo sia un blocco di codice invece che una string.

Confusionario, lo so, ma pensate che quando l’interpolazione di una rule in un’altra sarà possibile tutto si ridurrà a una riga :)

Per concludere, il testcase