This channel is intended for people just starting with the Raku Programming Language (raku.org). Logs are available at irclogs.raku.org/raku-beginner/live.html 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: docs.raku.org/type/Stash | 02:44 | ||
For lexical tables: docs.raku.org/type/PseudoStash | |||
:(**@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 glot.io 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 | docs.raku.org/type/Associative | 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 := Whatever.new; 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 = Whatever.new | |||
:(**@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 | ||
glot.io/snippets/ghroe4i139 | |||
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 glot.io/snippets/ghroe4i139 | 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 | ||
cdn.discordapp.com/attachments/768.../image.png | |||
issue with -n is that it splits newlines | |||
I want the whole string | |||
Nemokosch | well just do it in code | ||
slurp() | |||
Zephyr | hmm, true | 14:20 | |
raku -e '"package.json".IO.slurp.say' works fine | |||
thanks | |||
Nemokosch | probably slurp().say would also work | 14:21 | |
and sending the file into it | |||
:(**@rest, *%rest) | i introduced them back glot.io/snippets/ghroe4i139 | 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 | |||
<-[blabla]> | |||
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 glot.io/snippets/ghroe4i139 | 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 | |
cdn.discordapp.com/attachments/768.../image.png | |||
:(**@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 "zepsregex.md"; my @oldLines = $old.lines; my @oldItems = @oldLines.map({($_ ~~ &pattern)<item>.Str}); my $new = slurp "zepcat.md"; my @newLines = $new.lines; my @newItems = @newLines.map({($_ ~~ &pattern)<item>.Str}); for @newItems.kv -> $idx, $val { if @oldLines[$idx] != $val { say "$idx: | ||
$val"; } } | |||
cdn.discordapp.com/attachments/768.../image.png | |||
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 | |||
stevied | docs.raku.org/type/Mu#method_new | ||
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 | ||
huh | |||
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: docs.raku.org/language/objects#Cla...ce_methods | 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 | ||
cdn.discordapp.com/attachments/768.../image.png | |||
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 | |
github.com/rakudo/rakudo/blob/2022...u.pm6#L121 | |||
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 "zepsregex.md"; my @oldLines = $old.lines; my @oldItems = @oldLines.map(&cb); my $new = slurp "zepcat.md"; my @newLines = $new.lines; my @newItems = @newLines.map(&cb); 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 | zepcat.md and zepsregex.md both have text that match that pattern | ||
but zepcat.md has some lines missing here and there | |||
and I need to insert them | |||
however, the raw string in zepsregex.md 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 | |
github.com/rakudo/rakudo/blob/main...Object.pm6 | 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 | ||
til | |||
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 | |||
github.com/rakudo/rakudo/blob/d5a8...t.pm6#L761 | 17:46 | ||
code that I hoped would be simpler, lol | |||
github.com/rakudo/rakudo/blob/d5a8...t.pm6#L812 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 | ||
Nemokosch | indices looks solid at least | ||
Nahita | what is solid meaning | ||
raschip | He doesn't like idiomatic Raku code. | ||
Nemokosch | like idk if it's deterministically faster | 18:07 | |
Nahita | yeah not sure as well | ||
Nemokosch | but it performed reliably well | ||
Nahita | hence the 100 trials but | ||
raschip | A Bag is implemented as a Hash, it's fast. | ||
Nahita | well it was the slowest in my unstatistically backed timings | ||
3_000 length string, 100 trials | 18:08 | ||
although not sure if optimizations are going on | |||
raschip | Well, the question is: is it fast enough or not? | ||
Nahita | yeah only curious | ||
raschip | Better: is it fast enough for you? | 18:09 | |
Nahita | it is, was only curious | ||
a .count method would make it the most readable | |||
raschip | Yep, it's always good to have benchmarks. | ||
Nahita | but amongst the options, i'm between indices and Bag | 18:10 | |
will select one and move on | |||
raschip | I can't see the bot output, btw, discord bot doesn't forward it. | ||
Nahita | oh sorry | ||
raschip | No problem, just making sure you're aware. | 18:11 | |
Bag would make it clear, since that's what Bag is for. If you need to send it, then go for the more cryptic implementation, I would say. | |||
Nemokosch | more cryptic implementation š you're really making a point here | 18:12 | |
raschip | Don't go for premature optimization. | ||
Nemokosch | I don't know the use case but indeed, there can be overlapping matches as well, in theory | 18:14 | |
raschip | Nahita, do you know the quote about premature optimization? | 18:15 | |
Nahita | if you need to send it send to where? | ||
yes yes | |||
raschip | send it is an idiom about racing something, or about rockets | ||
They talk about 'sending it' meaning racing or launching. | 18:16 | ||
Nahita | i didn2t know that | ||
i'm actually counting a single character " | 18:17 | ||
i'm going to attempt to write a specific counting function for strings, and probably fail and see it's even slower than current alternatives | 18:20 | ||
actually i could copy the .indices code and count instead of gather indices š | 18:21 | ||
Nemokosch | I wonder if there is a significant potential gain opportunity | 18:24 | |
Nahita | well memory-wise, there is, as expected | 19:02 | |
time-wise... if you have thousands of characters large strings... maybe | |||
raschip | What about programmer time? | ||
Nahita | m: use nqp; sub count(str $big, str $small, int $overlap) { my int $len = $overlap ?? 1 !! nqp::chars($small) || 1; my int ($pos, $count) = 0, 0; my int $index; nqp::while( nqp::isne_i(($index = nqp::index($big, $small, $pos)), -1), nqp::stmts( ++$count, ($pos = nqp::add_i($index, $len)) ) ); $count } sub timid($inp, \n) { my $start | ||
= now; $inp.EVAL for ^n; printf "%33s%.3f\n", "$inp ==> ", "{ (now - $start) / n }"; } my $big = "wow" x 33_333; my $small = "w"; my \n = 10; timid q|count $big, $small, 0|, n; timid q|$big.indices($small).elems|, n; timid q|$big.comb.Bag{$small}|, n; timid q|$big.comb.grep($small).elems|, n; | |||
raschip | And code clarity? | ||
Nahita | a dedicatedly named .count function is the clearest, no? | 19:03 | |
raschip | right | ||
Nahita | for IRC, if anyone cares, output is count $big, $small, 0 ==> 0.025 $big.indices($small).elems ==> 0.032 $big.comb.Bag{$small} ==> 0.146 $big.comb.grep($small).elems ==> 0.112 | ||
Nemokosch | oh, this code is fairly straightforward | 19:16 | |
something like this could be added to a new language version tbh, no? | 19:17 | ||
raschip | it could, but sometimes they do refuse these things just because there is a way to do it in the language already. If you do submit it as a method in Str depending on use v6.e, it's more likely to be accepted. | 19:20 | |
Nemokosch | yes... it seems there was a time around 6.d when some methods (like flatmap in particular) were labelled deprecated with the motive of "it's simple enough already" - but the core community has changed a bit again, and I'd say the language is more in an expanding phase again | 19:22 | |
19:27
p6steve joined
|
|||
p6steve | m: +("wow" x 6).indices: <w> | 19:29 | |
camelia | WARNINGS for <tmp>: Useless use of "+" in expression "+(\"wow\" x 6).indices: <w>" in sink context (line 1) |
||
p6steve | hmmm - works in the repl ... anyway I'm just pointing out that using '+' to coerce the result to a Numeric is an idiomatic way to replace .elems | 19:30 | |
p6steve | m: my $big = "wow" x 6; say +$big.indices: <w>; | 19:31 | |
camelia | 12 | ||
Nahita | hmm... that + is too "small" in some sense and might hurt readability maybe compared to elems | 19:33 | |
like | |||
+$code.substr($idx.succ).indices('"') versus $code.substr($idx.succ).indices('"').elems | |||
idk | |||
actually i'm already using it in numeric context with %% so i don't even need to do elems or + huehuehue | 19:34 | ||
p6steve | yes - I notice that many rakoons prefer to use more 'word-like' approach | ||
... personally I prefer a more maths-y style ... but I respect that choice and find it easy on the brain (so I would be happy with a count method too ;-) | 19:36 | ||
and conversely, you are saying 'q|$big.indices($small).elems|' which is putting the elems Int into a Str ;-) | 19:39 | ||
Nahita | oh, that's for EVAL | ||
the %% stuff is in my actual code | 19:40 | ||
p6steve | no critique intended ... just that raku is a very good mirror and helps us to see and to tune the context of our code | 19:41 | |
gfldex | @:(**@rest, *%rest) please note: github.com/rakudo/rakudo/issues/5175 | 19:45 | |
Looks like you where the first to ask for a type with a signature constraint. | |||
20:57
raschip left
23:59
jgaz left
|