This channel is intended for people just starting with the Raku Programming Language ( Logs are available at
Set by lizmat on 8 June 2022.
:(**@rest, *%rest) m: my \x = 1; sub x { 2 } say x; say x(); 02:29
sigiless vars take precedence over 0 arg calls not surprising 02:30
m: sub x { 2 } say x; say x();
is this ambiguity resolved by keeping a symbol table 02:32
raschip In Raku there's a symbol table for every scope, lexical or package 02:33
:(**@rest, *%rest) can you delete a variable in raku 02:37
raschip Never heard anything about it. The symbol tables are read-only for the program. 02:41
You access them directly, though. 02:43
For package tables: 02:44
For lexical tables:
:(**@rest, *%rest) m: # generic + lmao use MONKEY-TYPING; multi sub infix:<+>(Any \a, Any \b --> Any) { a.ADD(b) } augment class Str { method ADD(\other) { self ~ other } } say 'hello ' + 'world'; 03:06
how doesn't this work 03:07
raschip Can you write it on and share? discord bot mangles the code, I can't even try it. 03:11
:(**@rest, *%rest) oh wait thats because the old signature is (Any(Numeric) \a, Any(Numeric) \b) 03:13
mine conflicts with it
i think make a role named Addable 03:14
raschip Sleep now, g'night. 03:25
03:26 raschip left
:(**@rest, *%rest) m: # generic + lmao use MONKEY-TYPING; role Addable { method ADD(\, \) { ... } } multi sub infix:<+>(Addable \a, Addable \b --> Any) { a.ADD(b) } augment class Str { method ADD(\other) { self ~ other } } say 'hello ' + 'world'; 03:52
m: # generic + lmao use MONKEY-TYPING; role Addable { method ADD(\, \) { ... } } multi sub infix:<+>(Addable \a, Addable \b --> Any) { a.ADD(b) } augment class Str does Addable { method ADD(\other) { self ~ other } } say 'hello ' + 'world'; 03:53
yes it worked
does raku have protocols like interfaces but you don't have to does it explicitly like roles 04:38
jaguart do you mean like virtual roles? 06:08
hmm - but your example already shows that - so something else 06:10
:(**@rest, *%rest) i still have to does it in that case 06:30
07:18 guifa left 07:19 guifa joined 07:32 snonux joined 07:42 snonux_ joined
m: use monkey-typing; supersede class Cool {} say '-1'.abs 08:32
m: pragma monkey-typing; supersede class Cool {} say '-1'.abs
08:51 snonux_ left, snonux left 08:55 dakkar joined
does raku have array like or hash like objects yk objects that can be safely put in @ and % vars respectively without coercing to Array 09:17
dakkar IIRC, %vars take objects that do the Associative role, @vars take objects that do the Positional role 09:20
:(**@rest, *%rest) and if they does those roles are they safely assigned or are they coerced to an Array 09:25
Nemokosch what does that mean? 09:27
:(**@rest, *%rest) safely assigned as in assigned without getting coerced to an Array or Hash
Nemokosch 09:28
that's what an Associative needs to provide
it clearly provides STORE so that it will be used, not to drop the whole thing and use a Hash instead...
:(**@rest, *%rest) oh >>> Please note that we are using binding := here, since by default % assignments expect a Hash in the right-hand side, and thus assignment would try and convert it to a hash (also failing). However, with the Associative role: class Whatever is Associative {}; my %whatever :=; will be syntactically correct. 09:29
Nemokosch it doesn't have to be like that 09:30
:(**@rest, *%rest) = coerces to Hash := keep it
Nemokosch you could specify %whatever to be a different type
my %whatever is Whatever =
:(**@rest, *%rest) hmm 09:31
Nemokosch btw I think there is some discrepancy between your original question and the answer to it
like, you don't need the % sigil to make something act like a Hash or something
actually, you don't even need does Associative 09:32
it could be duck typed, like in Python
if you provide the magic, you are good to go
:(**@rest, *%rest) m: my %num := 1; say %num;
so i just need to specify the methods 09:33
Nemokosch yes, simplest case
but then of course % won't accept your stuff 09:34
(without Associative)
anyway, to provide STORE is pointless without a % var, mainly
:(**@rest, *%rest) i imagine the same with Positional
Nemokosch yes 09:35
because a $ var will be wrapped into a Scalar and therefore the Scalar STORE will win
but the BLABLABLA-KEY methods are fully sensible to provide, even without Associative 09:36
11:53 raschip joined 12:03 sivoais joined 12:52 raschip left 13:03 raschip joined
:(**@rest, *%rest) are there common tokens that i can use in grammar in the stdlib? 13:37
why does my grammar return Nil 14:00
Nemokosch why can't you start with something simpler 😩 14:05
:(**@rest, *%rest) what is simpler than that? 14:07
Nemokosch something that uses 1 or 2 tokens, not like 8 14:08
the STRING token itself doesn't work, that's for sure 14:13
:(**@rest, *%rest) ok i updated it 14:14
Nemokosch <[- " \\]> what would this do?
:(**@rest, *%rest) seems like the problem is % 14:15
match everything except " and \
Nemokosch doesn't seem like that tbh
and is it what it really does? πŸ€”
looks kinda weird
:(**@rest, *%rest) after i remove % it no longer has the problem 14:16
and actually matched
Nemokosch then it probably works for the wrong reason
m: say 'a' ~~ / <[- " \]> /
so you are saying that this would match 14:17
not even a string worked with that grammar
no % involved
:(**@rest, *%rest) and after string was gone lmao
Nemokosch it's not the fault of %, rather the loose use of whitespace 14:18
Zephyr is there a simple way to make a CLI one-liner that processes an entire file rather than line-by-line?
what I've tried: 14:19
issue with -n is that it splits newlines
I want the whole string
Nemokosch well just do it in code
Zephyr hmm, true 14:20
raku -e '"package.json".IO.slurp.say' works fine
Nemokosch probably slurp().say would also work 14:21
and sending the file into it
:(**@rest, *%rest) i introduced them back 14:22
doesn't match
Nemokosch @:(**@rest, *%rest) rule is sensitive to whitespace - that's why I don't like it actually
your grammar kind of depends on the right amount of spaces here and there 14:23
:(**@rest, *%rest) i have to rewrite all of them into tokens?
Nemokosch you don't "have to" but I think it's a good idea to never rely on "implicit" whitespaces, I'd rather add \s* where it's appropriate 14:24
:(**@rest, *%rest) aren't rule whitespace-ignoring? like isn't rule R { 'foo' 'bar' }equivalent to token R { 'foo' <.ws> 'bar' } 14:25
Nemokosch that's not "whitespace-ignoring" in my lingo for sure 14:27
anyway, the syntax was faulty
not <[-blabla]>
and this does fix your last snippet immediately
Zephyr right, forgot, thanks 14:28
:(**@rest, *%rest) oh nice 14:29
Nemokosch tbh whitespace in regexes is a thing that I fear 14:31
I'd say Raku regexes are more explicit by default and therefore feel safer
as long as you follow a couple of simple rules of thumb, it's fairly straightforward 14:32
for example, I quote everything I can, unless I mean the special syntactic meaning
regardless if I have to or not
Nahita is <.ws> equivalent to \s or \s* or not? 14:33
didn't understand the documentation
:(**@rest, *%rest) now its still Nil 14:34
Nahita uuu JSON parser
:(**@rest, *%rest) why doesn't it give good errors instead of Nil 😭
Nahita there's Grammar::Debugger or something for that ig 14:35
:(**@rest, *%rest) if i change [<pair>* % ','] to [<pair> [',' <pair>]*]? it will work 14:36
Nemokosch because you have a whitespace inside I guess
this was a rule
it would turn the other way around if your input had not space there
:(**@rest, *%rest) % operator is space-dependent ig 14:37
Nemokosch like i don't even know how to read this inside a rule: [<pair>* % ','] 14:38
where is the space?
is there any?
see, this is the kind of guessing game I hate
[<pair> [',' <pair>]*] - this on the other hand is just incomprehensive 14:39
it does assume the space, perhaps one space exactly
:(**@rest, *%rest) ok if i span my input more than one line 14:40
it doesn't match again
i hate Grammars
Nemokosch yeah it needs to be more solid with the whitespace
:(**@rest, *%rest) quits 😀 14:41
according to the regex page its <!ww>\s* 14:44
Nahita thanks so it checks boundaries too then
:(**@rest, *%rest) still
Zephyr what's the difference between m/stuff/ and rx/stuff/? 14:47
Nemokosch that m is evil and shouldn't be ever used with smartmatches
:(**@rest, *%rest) m/stuff/ is like $_.match(rx/stuff/)
or $_ ~~ /stuff/ 14:48
Zephyr so no m/ in smartmatches, thanks
Nemokosch I mean, it works... but at what cost
Zephyr wonder if the syntax highlighter of vscode is buggy or my code is wrong 14:50
:(**@rest, *%rest) i think its buggy tbh
Nemokosch m: my $match1 = 'asdfgh' ~~ /df/; my $match2 = 'trololo' ~~ /lol/; say $match1 ~~ $match2;
every time I think of this, it makes me wanna cry
smartmatching on two Match objects is implemented as "just take the right side, duh" 14:51
very smart indeed πŸ₯΄
and THIS is why something ~~ m// can work
that's the sole reason for this hell
:(**@rest, *%rest) imagine the pain of putting <.ws> everywhere on the grammar 😭
Nemokosch I don't even know this <.ws> magic, I only know good old \s 14:52
:(**@rest, *%rest) <.ws> is just like that 14:53
Nemokosch then I don't see any problems
yes, if you want to support whitespace between certain structures of the grammar, you're gonna indicate that 14:54
quite normal if you ask me
:(**@rest, *%rest) still explicitly writing \w* or <.WS> between grammar parts are tedious and considered bad form in parser generator grammars (in those you can just tell the lexer to not feed whitespace to the parser) 14:56
Zephyr am I missing something obvious perl my regex pattern { ^^ \s* '- ' $<item> = ( \S+ ) } my $old = slurp ""; my @oldLines = $old.lines; my @oldItems ={($_ ~~ &pattern)<item>.Str}); my $new = slurp ""; my @newLines = $new.lines; my @newItems ={($_ ~~ &pattern)<item>.Str}); for @newItems.kv -> $idx, $val { if @oldLines[$idx] != $val { say "$idx:
$val"; } }
Nemokosch I wouldn't call that tedious, it's a part of the design of the grammar
like anything else
stevied There is this: multi method new($, *@) in the Mu class. So what does this throw an error: class A {}.new('blah');
Nemokosch ^is this even valid syntax?
Zephyr excuse the extra variables, I made them for using later
stevied yes, it's valid syntax 14:57
error is: Default constructor for 'A' only takes named arguments
Nemokosch I think the candidate you found is misleading
:(**@rest, *%rest) thats obvious
no pos args
Nemokosch normally, you indeed cannot pass positional arguments to the default constructor
raschip Can't use positional arguments by default. 14:58
stevied I passed in 'blah' as an arg
Zephyr oh wait, I typed oldLines instead of oldItems
Nemokosch not sure what you found but tbh not sure if there is point in debugging a wrong assumption
the error message is right here
stevied I know you can't, but why not, given that Mu has a new contructor that looks like: multi method new($, *@)
Nemokosch again, is there any point in trying to trace down this wrong assumption?
:(**@rest, *%rest) you didn't declare it in A 14:59
its just class A {}
Nemokosch did that fix your problem?
stevied but this is allowed: class A {}.new(blah => 1);
Zephyr doesn't look like it unfortunately
Nemokosch but like... it gave the right error 15:00
"you cannot use positionals in the default constructor"
stevied there is no error
Nemokosch this is what we all learn and experience
isn't this just enough?
:(**@rest, *%rest) again, implicit *%_
all named args is eaten by it 15:01
Nahita "assumption"? wtf
stevied i'll ask the question a different way. How do I use this method in Mu: multi method new($, *@)
Nahita that's from the documentation
stevied and if I can't, why bother putting it in the docs?
Nahita fix the documentation, is the "point"
Nemokosch I'm sure the documentation also says that the default constructor cannot use positionals...
Zephyr oh, maybe it's because there isn't always a match
Nahita it does, so what, so what 15:02
Nemokosch the documentation doesn't say that the default constructor is some multi method new($, *@)
so like there's nothing to see here
it does say it's multi
Nemokosch > This method expects only named arguments which are then used to initialize attributes with accessors of the same name.
:(**@rest, *%rest) is there a way to get a specialization of a multi as a sub
stevied right, so what the hell is the new($, *@) method for? 15:03
why is it there?
Nemokosch I have no idea
:(**@rest, *%rest) my or @stevied's question?
raschip To give the correct error if try to use it. 15:04
Zephyr is there an alternative to optional chaining in Raku?
Nemokosch hm, raschip has a great point actually xD
Zephyr sorry for all the dumb questions, just messing around a bit with it after a long time
:(**@rest, *%rest) $a?.b?
Nemokosch that can very well be a candidate dedicated to producing the error
uh oh, no 15:05
Zephyr didn't know that works in it, thanks
Nemokosch first, there is no ?., there is .?
second, it doesn't quite do what ?. does in other languages
Zephyr then?
Nemokosch it says "call the method if you find it, return Nil otherwise`
Zephyr perl sub cb($str) { ($str ~~ &pattern)<item>.Str }how'd you write this function to only return .Str if there's a match or return $str if there isn't 15:06
Nemokosch andthen can be used for optional chaining, if you mean "execute it for defined lhs"
Zephyr yup
stevied hmm, maybe this is why there's a positional method: 15:07
Nemokosch andthen checks if the lhs is defined and if it does, it sets the topic variable to the lhs and executes the rhs with it, as a kind of block
Zephyr perl sub cb($str) { ($str ~~ &pattern)<item> andthen .Str or $str }is that valid
:(**@rest, *%rest) perl if $str ~~ &pattern -> $match { $match<item>.Str } else { $str } 15:08
Nemokosch yes, although I'd rather use orelse
instead of or
stevied so it seems tthe ($, *@) for is for passing objects to new()
Nahita ($str ~~ &pattern)<item>.Str orelse $str
Nemokosch as kind of the rightful counterpart of andthen
Zephyr shouldn't that error trying to convert Nil to Str?
Nemokosch it will throw a warning probably
Nahita m: Nil.Str.say 15:09
:(**@rest, *%rest) this should work too?perl if $str ~~ &pattern { $/<item>.Str } else { $str }
raschip It's a failure, only produces an exception if you don't check for definedness, which is happening in this case.
Zephyr I was trying to go for a one-liner
Nemokosch yes
also, $<item> is enough
Zephyr somehow my error remains
Nemokosch (not sure if $<item> was a good idea from syntax pov but it does work this way) 15:10
!= on a string
should be ne
Zephyr oh
thanks, guess I should review the basics sometime
stevied oh, wait, I think new($, *@) is so you can pass in pairs. each pair is a single value 15:14
Nemokosch raschip already spoiled what it's for 15:15
to produce the error πŸ˜†
raschip There should be a way to hide it from appearing in the docs... 15:16
Nemokosch yep, that's what I'm thinking about, too... can a candidate be marked as an implementation-detail?
stevied ah, ok 15:17
Nemokosch that would come kinda handy; after all, this really is a candidate for internal workings
stevied thanks!
15:23 Air4x joined
Zephyr is a Hash guaranteed to keep insertion order? 15:23
Nemokosch no 15:24
Zephyr not nice
is there any ordered key-value pair?
Nemokosch a Hash is actually a hash...
well, what is your use case? 15:25
:(**@rest, *%rest) to preserve order when converting from arrays of pairs i think 15:26
Nemokosch there are two orthogonal things here imo 15:27
a) hash-style lookup
b) ordered pairs
both are easy in themselves
the combination needs a module I think
Zephyr basically: I have 2 lists, one is a list of keys another is a list of values. now, I wanna be able to get the value from the key inside a loop without hurting the order
or idk if I made any sense 15:28
a picture speaks a thousand words so here's the code perl my regex pattern { ^^ \s* '- ' $<item> = ( \S+ ) } sub cb($str) { ($str ~~ &pattern)<item> andthen .Str orelse $str } my $old = slurp ""; my @oldLines = $old.lines; my @oldItems =; my $new = slurp ""; my @newLines = $new.lines; my @newItems =; I'm trying to merge the 2 files together by the
matched keys without hurting the order
:(**@rest, *%rest) then im afraid you have to use pair lists 15:29
Zephyr and both have text that match that pattern
but has some lines missing here and there
and I need to insert them
however, the raw string in is outdated
the key isn't the only data, so yeah 15:30
raschip Hash is in fact guaranteed to give you a different order every time you run the program.
Zephyr welp, quite the opposite of what I need here
raschip The hash function has random order enforced, to guarantee peo0ple don't rely on it
:(**@rest, *%rest) that causes problems with reproducibility hmm
Nemokosch lol, now I didn't know that
:(**@rest, *%rest) and make hash loops unpredictable
Nemokosch checks raschip in the list of Rakudo contributors
Zephyr trying to rephrase: merge 2 files, for each conflict, prefer the newer file's data. for lines that don't exist in the new file, insert the older file's data 15:31
conflict is determined by the regex match there
and must maintain the order
raschip I would have a map from the key into lists of 2 elements, the contents and the order. After using the hash, it's easy to construct the original list in order 15:32
:(**@rest, *%rest) i can do that without hash
stevied should I file an issue about the new() method in the docs?
might as well 15:33
Zephyr hmm, having the order as a value makes sense indeed, lemme try. thanks btw
Nemokosch yep, you can - just please check if there are already issues of that sort 15:35
sounds essential enough, related to how these signatures are collected
15:37 NemokoschKiwi joined 15:38 NemokoschKiwi left 15:40 Air4x left
:(**@rest, *%rest) are there a "callable with signature" type like Callable[(...), ...] in python or (...) => ... in typescript 15:47
Nemokosch the pointy block?
there are anonymous subs and pointy blocks 15:48
:(**@rest, *%rest) a type that matches callables with specific signatures
15:48 Air4x joined
Nemokosch hmm 15:49
:(**@rest, *%rest) it would be useful for callbacks 15:50
Nemokosch the Callable role can have parameters, not sure if they can cover the signature as well 15:51
I can only see the returns argument 16:00
actually if I think about it, Callable in itself doesn't know signatures
:(**@rest, *%rest) raku conveniently ignored specialized callback type 😭 while almost all langs with typing support it 16:07
Nemokosch you know, sometimes I wonder what was first: the chicken or the egg 16:18
power users/devs not really using types, or types being kind of lacky 16:19
the thing is, Raku's type system is a bit different from Python's or especially Typescript's
Typescript is basically a preprocessor language, nothing was expensive because at the end of the day, 95% of its code is going to get discarded in favor of plain old untyped Javascript 16:22
iirc Python types are also for the linter, basically 16:23
also, as far as I can remember, Python types are quite messy and inconvenient, both regarding how to obtain them and how the syntax needed to be adopted
in Raku, types naturally evolve with the language 16:24
just slower than the content or the syntax itself
16:26 Air4x left
:(**@rest, *%rest) yea but doesn't that say anything about the lack of specialized callback types 16:35
Nemokosch In those languages, this is just a formality 16:38
in Raku, it kind of needs to evolve with the actual data structures
khm, khm, Hash
did you know that the "typed" hash is in fact a different data structure from a banal default Hash? 16:39
more accurately, it mixes in roles that add code to handle certain behavior
:(**@rest, *%rest) raku's is more like php in terms of gradual typing or the other way around coincidentally php also doesn't support signatures on functions
real 16:40
Nemokosch iirc PHP also tries to do runtime checks and stuff
rather than linting
:(**@rest, *%rest) something like Hash[Str, Int]? 16:41
16:41 jgaz joined
Nemokosch yes 16:56 16:58
> my role Hash::Object[::TValue, ::TKey]
:(**@rest, *%rest) Hash[Str, Int] is different from Hash hmm
Nemokosch well, it's a Hash that has this role mixed in 16:59
hence overriding certain behavior
:(**@rest, *%rest) omg generic types
Nemokosch "generic types"
"weak typing"
when do these terms ever end? 😭
let's give them funny Raku-ish names instead
:(**@rest, *%rest) type-capturing types 😳 17:00
i hope signatured callbacks get added in next version tho 17:08
though i don’t know how to represent it 17:09
Callable[:(Int, Str, Bool)]?
m: my ($first, **@rest) = 1, 2, 3, 4; say @rest; 17:18
destructuring uses a signature 17:19
m: my ($first, @rest) = 1, 2, 3, 4; say @rest; 17:20
why is this behavior πŸ€” 17:22
weve talked about it before but it is not how it should work
oh wait i found it out &c:(Int, Str, Bool) 17:25
Nemokosch how to read this? 17:26
the answer lies within the STORE methon of a List 17:27
or you mean why this is useful/sensible?
:(**@rest, *%rest) a callable &c with signature :(Int, Str, Bool) 17:28
yeah why it doesn’t match a list of a scalar and an array
actually both at the same time 17:30
how is it done, and why is it desirable
17:36 dakkar left
why is WhateverCode not a subclass of blocks 17:38
Nemokosch pff good question, one at a time 17:41
for the latter: I think this has its roots in the Perl era where multiple things were arrays and single things were scalars. Most stuff would flatten either way. Then this simple quirk persisted, I think simply because 1. code out there 2. it basically came for free from list assignment, no new syntax required... 17:44
which gets us to 17:46
code that I hoped would be simpler, lol look here 17:47
"if we're pulling something on the left handside that has no containers: STORE all the rest into that 17:48
:(**@rest, *%rest) how about this 17:49
Nemokosch I suspect it doesn't really have a scope 17:52
I've had issues with that kinda stuff
Nahita should i do $str.indices($another).elems to count $another in $str both strings?
:(**@rest, *%rest) it should have one? because how else are they gonna store their args
Nahita or should i do comb & grep andthen elems 17:53
idk why there is no .count
or is there?
Nemokosch doesn't seem like that, at least :c 17:55
come to think of it 17:57
there are barely any core routines that do counting of any sort
raschip The idiomatic way to do it in Raku is to cast it into a Bag, then the answer will be evident 18:03
Nahita m: sub t($inp, \n) { my $start = now; $inp.EVAL for ^n; say "$inp ==> { (now - $start) / n }"; } t q|("wow" x 1_000).comb.Bag<w>|, 100; t q|("wow" x 1_000).comb.grep("w").elems|, 100; t q|("wow" x 1_000).indices("w").elems|, 100;
m: sub t($inp, \n) { my $start = now; $inp.EVAL for ^n; say "$inp ==> { (now - $start) / n }"; } t q|("wow" x 1_000).indices("w").elems|, 100; t q|("wow" x 1_000).comb.grep("w").elems|, 100; t q|("wow" x 1_000).comb.Bag<w>|, 100; 18:04
raschip It's also possible to .grep and then .elems 18:05
Nahita yeah tried the three
raschip I like the way they do it i R, they map the list Any --> Bool and them sum it up. 18:06
Nahita indices seems faster here and locally, but Bag reads better ig idk