🦋 Welcome to the MAIN() IRC channel of the Raku Programming Language (raku.org). Log available at irclogs.raku.org/raku/live.html . If you're a beginner, you can also check out the #raku-beginner channel!
Set by lizmat on 6 September 2022.
tonyo hah, thanks. `is factory` would be an interesting way to set defaults to things 00:04
Xliff Has anyone tried Google's Bard? 05:55
tellable6 2023-05-22T00:45:18Z #raku <Voldenet> Xliff: you can easily trigger malformed utf-8 sequence by using `255` as first byte with no following bytes – it's fatal because such sequence is not valid utf8 and probably some different encoding
Xliff .tell Voldenet: Thanks. That might help me write a golf so I can determine how to properly detect and handle such occurrences. 06:02
tellable6 Xliff, I'll pass your message to Voldenet
Voldenet Xliff: there was the later part, `Buf.new(255).decode("utf8-c8").say` 06:12
it's pretty sane way to handle invalid unicode variants
Xliff gist.github.com/Xliff/4c39e2e85ab7...27414ae82c 06:13
m: Buf.new(255).decode("utf8-c8").say 06:14
camelia 􏿽xFF
Xliff Voldenet: Humm... no error.
m: Buf.new(255).decode("utf8").say
camelia Malformed UTF-8 at line 1 col 1
in block <unit> at <tmp> line 1
Xliff There it is.
Voldenet `Second, you can use the is-valid-utf8 method to check if a string is in a valid UTF-8 format.` :D 06:15
i really love things chatbots invent
"just use the non-existing-library, here's the snippet…"
Xliff m: use warnings qw(warn-on-malformed-utf8); Buf.new(255).decode("utf8-c8").say; 42.say
camelia ===SORRY!=== Error while compiling <tmp>
Undeclared routines:
qw used at line 1
warn-on-malformed-utf8 used at line 1
Voldenet obviously :D 06:16
Xliff m: use warnings <warn-on-malformed-utf8>; Buf.new(255).decode("utf8-c8").say; 42.say
camelia ===SORRY!=== Error while compiling <tmp>
Could not find warnings in:
/home/camelia/.raku
/home/camelia/rakudo-m-inst-2/share/perl6/site
/home/camelia/rakudo-m-inst-2/share/perl6/vendor
/home/camelia/rakudo-m-inst-2/shar…
Xliff Oh you are kidding me! A hallucination?
m: use warnings 'warn-on-malformed-utf8'; Buf.new(255).decode("utf8").say; 42.say
camelia ===SORRY!=== Error while compiling <tmp>
Could not find warnings in:
/home/camelia/.raku
/home/camelia/rakudo-m-inst-2/share/perl6/site
/home/camelia/rakudo-m-inst-2/share/perl6/vendor
/home/camelia/rakudo-m-inst-2/shar…
Xliff Must have confused "Raku" with "Perl"
Wow! 06:17
Will have to update my gist.
Voldenet except `warn-on-malformed-utf8` doesn't exist anywhere
Xliff m: { CATCH { default { when .contains('malformed') { .message.say; .resume }; }; }; }; Buf.new(255).decode("utf8").say 06:18
camelia Malformed UTF-8 at line 1 col 1
in block <unit> at <tmp> line 1
Xliff m: { CATCH { default { when .contains('Malformed') { .message.say; .resume }; }; }; }; Buf.new(255).decode("utf8").say; 42.say
camelia Malformed UTF-8 at line 1 col 1
in block <unit> at <tmp> line 1
Xliff m: { CATCH { default { when .message.contains('Malformed') { .message.say; .resume }; }; }; }; Buf.new(255).decode("utf8").say; 42.say
camelia Malformed UTF-8 at line 1 col 1
in block <unit> at <tmp> line 1
Xliff m: { CATCH { default { when .message.contains('Malformed') { .message.say; .resume }; }; }; Buf.new(255).decode("utf8").say; 42.say } 06:19
camelia Malformed UTF-8 at line 1 col 1
This exception is not resumable
in block at <tmp> line 1
in any at <tmp> line 1
in block <unit> at <tmp> line 1
Xliff WTF!?
Voldenet it's not resumable
Xliff Why not
m: { CATCH { default { when .message.contains('Malformed') { .message.say; .resume }; }; }; Buf.new(255).decode("utf8").say; 42.say }; 42.say
camelia Malformed UTF-8 at line 1 col 1
This exception is not resumable
in block at <tmp> line 1
in any at <tmp> line 1
in block <unit> at <tmp> line 1
Xliff So there's no way I can prevent that from being fatal?
Voldenet utf8 decoder won't decode invalid utf8
utf-c8 can
Xliff But I have no control over how Cro chooses to print strings. 06:20
And that's where that exception comes from.
And I need my code to be _stable_ and you're telling me a malformed request can crash what I write at any time!?
Voldenet hmm, it should crash only for one specific client, not the whole server 06:21
Xliff No. Whole server.
m: { CATCH { default { when .message.contains('Malformed') { .message.say; .resume }; }; Buf.new(255).decode("utf8").say; 42.say }; 42.say
camelia ===SORRY!=== Error while compiling <tmp>
Missing block
at <tmp>:1
------> 355).decode("utf8").say; 42.say }; 42.say⏏<EOL>
expecting any of:
statement end
statement modifier
statement modifier lo…
Xliff m: { CATCH { default { when .message.contains('Malformed') { .message.say; }; }; }; Buf.new(255).decode("utf8").say; 42.say }; 42.say
camelia Malformed UTF-8 at line 1 col 1
42
Xliff OK. That at least solves that problem.
Voldenet m: { CATCH { default { .resume } }; Buf.new(255).decode("utf8").say; } 06:22
camelia This exception is not resumable
in block at <tmp> line 1
in any at <tmp> line 1
in block <unit> at <tmp> line 1
Xliff So without .resume, it will terminate the block, but not the server.
IF you make sure to surround the problematic code with curlies.
So... none of that last bit was true? LOL! 06:23
I will have to rewrite.
Voldenet in C# you can do something like `app.Use((next) => async (ctx) => { try { await next(ctx); } catch { ctx.Response.Write("error"); } });` 06:25
maybe in cro it's possible to write middleware that'd handle known errors
and you can do that stackoverflow.com/questions/693863...pplication 06:27
Xliff I think I have something like that in the server code, but not in the sentinel code. 06:28
sentinel code runs the server code but echos the output. 06:29
So anything bad that comes from cro gets sent to the sentinel via react/whenever.
So I have something like the above CATCH in the react block now, where there is an extra scope surrounding the whenever blocks that emit what comes from the server. 06:30
So I will have to test on that to see if it works.
Nemokosch m: 1 + 2 :add - 4 09:54
Raku eval Exit code: 1 ===SORRY!=== MVMArray: Can't pop from an empty array
Nemokosch did I drill a hole in the parsing? 09:55
lizmat looks like: the RakuAST grammar also fails, but differently: No such method 'add-colonpair' for invocant of type 'RakuAST::ApplyInfix' 09:56
which actually describes the issue better :-)
infixes are actually allowed to have nameds: 09:58
m: sub infix:<foo>($a, $b, :$add) { dd $a, $b, $add }; 1 foo 2 :add
camelia 1
2
Bool::True
lizmat so I guess this will sort itself out in RakUAST 09:59
Nemokosch yes, that's kind of where I was going 10:01
it works okay with parens until the subtraction 10:02
lizmat clickbaits rakudoweekly.blog/2023/05/22/2023-...xcinating/ 12:22
tonyo . 15:09
librasteve hey / ... what is :add:? 18:00
lizmat :add is a named argument to &infix:<+> in the above example ? 18:03
Voldenet m: sub infix:<foo>($a, $b, |c) { dd $a, $b, c }; (1 foo 2 :fun:stuff) foo 3 :this<is> 18:21
camelia 1
2
\(:fun, :stuff)
Nil
3
\(:this("is"))
librasteve m: sub infix:<+>($a, $b, |c) { $a - $b - c<add> }; say 1 + 2 :add<7>; 19:59
Raku eval -8
librasteve oooh
what is the best way to recast a Str or Int to an IntStr? 21:08
guifa IntStr.new(Int,Str) 21:09
librasteve guifa: tx! but that is quite heavy ... is there an idioamtic way like '+' for .Numeric or '~' for .Stringy? 21:11
guifa No, I don't think so. IntStr was created for a pretty particular purpose (qw strings) 21:12
librasteve or even a methodic way like .Allomorph?
seems like it is easy to make one with eg <1> literal 21:13
guifa sub prefix:<+̃>($x) { IntStr.new: $x.Numeric, $x.Str } 21:14
librasteve ^^ ++ 21:15
guifa oh wait 21:16
there's already a unicode character for it
⨤ U+2A24 and ⨦ U+2A26
I actually use a the allomorph for DateTime::Timezones to return the name of the timezone AND its offset for .timezone 21:17
Nemokosch allomorph of what types? 21:19
librasteve yeah - I had a lightbulb moment when I realised that it is used to keep the original string and the parsed number together
guifa string (name) and number (offset) 21:20
librasteve I would vote for this to be in core 21:29
using .Stringy
guifa we already haev Stringish, which is the equiavlent of Numeric but for strings 21:38
I think the ideal would be for IntStr to define some COERCE methods 21:50
lizmat PRs welcome :-) 21:51
librasteve docs.raku.org/type/Stringy 21:52
yeah - that would probably be more sensible
guifa err I guess it is Stringy oops I always forget which ones are -ive, -y, or -ish 21:53
librasteve and +̃ would need to be a multi to cover all the allomorphs
which could be a fiddle since you want to accept the Str form and you don't know what kind of Numeric that is 21:55
only a top programmer could do such a thing 21:56
tonyo haha 21:57
Nemokosch sounds like nightmare fuel 22:12
guifa random q: could I potentially use Proc::Async to launch a script but have it stay alive after the launcher has exited? 22:30
ugexe yes 22:31
guifa what would be the command? I've been thinking about trying to toy with the idea of having Intl::CLDR (which has an unfortunate init time even in the native ICU libraries) exist as a daemon of sorts to improve response times and then just exiting after some preset timeout period 22:36
(that's basically what all OSs do after all to save resources) 22:37
leont That sounds like you want ⨤ to by a synonym for val()? 22:41
Nemokosch val cannot take an Int, for sure 22:44
I would be quite curious how one uses these allomorphs in a way that they seem like a decent tradeoff 22:47
guifa The primary (and really only intended use) is for qw stuff so I can say @foo = <1 2 3 4 5> or <a b c d e> and not have to worry about whether I want string or int. I don't think it was really anticipated that people would make them manually, but it worked well for me since DateTime by default returns an offset for both, well, .offset and .timezone, but in my rewrite, a string like 'Europe/Madrid' makes sense for timezone but doesn't 22:49
break anything that uses it expecting an offset
ugexe i mean you can run `raku -e 'start { shell q|echo $$ && sleep 30|; }; sleep 1'` and then see that pid still exists after the raku command stops 22:51
guifa ah nice! 22:57
thanks. now to figure out the best way to detect if such a process is currently ongoing (and launch if not) within the module context
ugexe in the process you spawn you can check for the parent pid, and if its zero assume its now a zombie process 23:03
not sure about the other way around other than keeping track of the pid
which even then it might get reused
i guess you could have the daemon launch a child process that monitors its own parent pid, and if it changes to 0 to relaunch the parent process 23:05
leont guifa: yeah, .timezone returning something that isn't a timezone is a PITA
Nemokosch for operators, you don't need IntStr, a mere Int or Str will just work fine, "you don't have to worry" whether it's an int or a string 23:16
and the cost is rather big, not only because now you start making random combinations in an n squared fashion but because of the trap I said a couple of days ago even more 23:17
namely that you can have something that passes all Int type constraints, it acts like, say, 5 in all situations where it needs to be a number, and then it suddenly turns out not to be an element of a set that does contain 5 the integer 23:18
it also challenges the concept of type conversions. If an IntStr value is an Int value, then one could expect the conversion to Int to be an identity, and if you do Int(<5>), that is indeed <5> 23:21
however, if you do <5>.Int, that's suddenly 5
all in all, it seems to me that one has a lot more to worry about if they need to be prepared to deal with values that seem the same but in fact aren't the same. Also it introduces a kind of diamond problem: if you coerce Str to Bool, that's an empty check - unless that Str happens to be an allomorph with a number, in which case all character sequences that describe the number 0 some way, can give an unexpected 23:30
False.
I would say this is definitely "something to worry about", especially if you just didn't expect a number to show up there at all. Eventually, you might end up writing .Int and .Str that you have sworn to avoid. 23:31