🦋 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.
00:00 reportable6 left 00:01 reportable6 joined 01:01 statisfiable6 left, unicodable6 left, committable6 left, coverable6 left, releasable6 left, reportable6 left 01:02 releasable6 joined, statisfiable6 joined, committable6 joined, reportable6 joined, unicodable6 joined 01:03 coverable6 joined 01:04 xinming left 01:06 xinming joined 01:19 deoac joined 02:15 teatwo joined 02:19 teatime left
Voldenet ><Nemokosch> just imagine if it even was a well-designed language in addition… 03:00
I believe that perl5 is fast precisely because it was created with specific tasks in mind
in comparison languages like python, ruby or raku are too general to optimize for those specific tasks (and specific-task optimizations will end up as pure C) 03:04
03:19 evalable6 left, linkable6 left, evalable6 joined, linkable6 joined 03:58 rf left 03:59 gabiruh left 04:03 gabiruh joined 04:55 deoac left 05:01 derpydoo joined
avuserow tonight I released (yet another) module for making SQL called SQL::Builder - and wrote a small blogpost on why: dev.to/avuserow/sqlbuilder-making-...-raku-4mgn 05:01
Voldenet avuserow: that's cool, does it support some sort of `$sql.from('songs', 's').where("s.name = sandstorm")`?` 05:12
using aliases is fairly important
also, `["a", "=", 1]` for predicates is fairly awkward, you could accept something like `*.a == 1` by creating infix ops for basic operators and executing that WhateverCode using some operator that'd capture this state 05:14
avuserow yes, `from` can take a Pair to determine the alias: `$sql.from(:s<songs>).where(["s.name", "=", "sandstorm"])`
Voldenet iirc Red does something like that 05:15
avuserow The most likely path forward is to have a lightweight Table/Column type, then have methods/operators on the column 05:17
Voldenet yeah, something like that
I'd mention something about CTEs but I don't think I've ever seen a query builder supporting it 05:18
On mssql some queries can have their performance altered through the use of CTEs 05:19
avuserow though RakuAST may open other options. If I can know that I'm within a where clause, then I can possibly rewrite things into the three-tuple versions at compile time
Voldenet Possibly macros would add some cool features without that much pain 05:20
avuserow then I don't need to make a ton of runtime things, and it could look even more like SQL
Voldenet currently evaluating contents of WhateverCode is a thorny path
in fact, the only lib I've seen handling CTEs is linq2db for csharp (linq2db.github.io/articles/sql/CTE.html) 05:21
avuserow I don't have a particular use for CTEs but I don't think they'd be that hard to support 05:22
Voldenet Well, the only really important use is recursive CTEs 05:23
avuserow since the SelectBuilder object exists, you could have something like... `my $q = $sql.with($with-def, $inner-q).from(...).select(...)`
it would be kind of syntactically like the subquery support with FROM/JOIN clauses 05:24
Voldenet Mssql likes to build parallel queries when you use that, which allocate tons of memory
with CTE you could (not sure about current versions, so I'm using past tense) tell it to not do that 05:25
avuserow linq was a very very vague inspiration, mostly with `from` being the constructor for SelectBuilder
that's kind of interesting
I actually haven't used this with anything but postgres and sqlite. There's definitely some postgres bias in the syntax, especially casting. I may add some compatibility options there 05:27
is mssql generally available to test out and use? 05:28
Voldenet development edition is free as long as you're not using it in prod
which contains all the features 05:29
erm, developer edition 05:32
avuserow okay, good to know 05:33
I'm going to call it a night. thanks for reading! 05:34
Voldenet np, thanks for good library to use :) 05:36
06:00 reportable6 left 06:01 reportable6 joined 06:44 jpn joined 06:51 jpn left
Nemokosch Voldenet: I doubt Perl5 is fast because of the magic variables, the concept of different "contexts" that can mess up the return value you are trying to use, the lack of proper function signatures (weee, got added in 5.36 or something) and so on 06:56
06:56 jpn joined
Voldenet wantarray is definitely the killer performance feature 06:58
But honestly, I don't mean the language design at all, just what was the end goal 06:59
If you start with things to do and ignore things like syntax, you end up working only on performance while skipping crucial things 07:00
I know because I've built a few for-specific-purpose "languages" that were hideous to use outside of very specific task, but fast and easy for one thing 07:02
("languages" because they used json/tsv for commands) 07:04
Nemokosch well endless bikeshedding about mundane things like syntax does no good either, that's for sure 07:05
Voldenet that's how you end up without multiline lambdas (python) or no signatures (perl) 07:06
or generics (golang for a long while)
Nemokosch From what I know, the lack of multiline lambdas was a very deliberate choice in Python
Voldenet because "it would increase complexity of parsing" 07:07
Nemokosch not only that
On the other hand, I don't think there is any reason to protect the lack of function signatures in Perl
Voldenet you could say that no signatures for a long while was a deliberate choice for perl, because it would significantly increase complexity… ;)
Nemokosch yeah yeah, it's so complex that even C had them from the beginning and without explicit variable definition since like 1990 07:08
Voldenet it used to have some amazing syntax `int foo(bar, baz) char* bar; int baz; { … }` 07:10
Nemokosch yep, that's what I was referring to as "explicit variable definition"
Voldenet still, working on performance instead of the language isn't bad tradeoff 07:12
Nemokosch as long as it doesn't lead to decisions (or lack of decisions) like this, it's not
Voldenet perl has Keyword::Declare now, so it's fairly easy to add missing features
Nemokosch At the end of the day, I don't think you can revert trends just by the virtue of making good design decisions so there's also that 07:14
07:14 jpn left
However, that's not to say that the broader Perl community shouldn't think about what they keep getting constantly wrong, that even JS and PHP managed to fix themselves over time 07:15
Voldenet *cough*
Nemokosch PHP basically started off as "Perl, the bad parts" 07:16
and now it's a hundred times better language
Voldenet "was it strparse, parsestr, str_parse, or parse_str" 07:17
imo php keeps thinking about performance more than syntax 07:18
Nemokosch which should REALLY make everyone think who obsesses over eternal backwards compatibility
they managed to improve the language significantly, DESPITE not even focusing on that 07:19
Voldenet I do love seeing C++20 codebase with some ancient C++ headers ;)
Nemokosch you meant to say C headers 😼 07:20
Voldenet "good C headers (k&r style)" won't compile in C++ fortunately 07:21
Nemokosch well they don't have to compile 😛
07:21 sena_kun joined
Voldenet tbh. there's healthy balance between language features and performance and I consider perl to not strike that balance well, but it explains why it's fast :P 07:21
otoh you could argue that raku doesn't in the other direction, but while improving performance is measurable, improving syntax isn't 07:23
Nemokosch For Python - I do think that lack of fully blown lambdas was mostly a "social" decision, just like Guido forced reduce out of the core language
Voldenet so it's better to have better syntax first
Nemokosch Python is most definitely not a "design by committee" language. Whatever GvR set his mind on, had to be that way; in return it has always had a consistent vision 07:24
07:45 sena_kun left 08:00 xkr47 left, jpn joined 08:05 jpn left 08:09 jpn joined 08:14 xkr47 joined 08:15 jpn left 08:17 MoC joined 08:37 lizmat left 08:38 lizmat joined 09:08 jpn joined 09:13 jpn left 09:56 jpn joined 10:02 jpn left 10:09 Sgeo left 10:33 kurahaupo joined 10:35 kurahaupo left 10:36 kurahaupo joined 10:49 frost joined 10:58 kurahaupo left, kurahaupo joined 10:59 sftp left 11:02 sftp joined 11:26 kurahaupo left, kurahaupo joined 11:47 MoC left 12:00 reportable6 left, reportable6 joined 12:17 MoC joined 12:35 sena_kun joined
Anton Antonov Which produced a deceptively simplistic programming language. 13:14
13:14 derpydoo left
Nemokosch "A new BASIC", as some would say 13:36
14:14 linkable6 left, evalable6 left, teatwo left 14:15 evalable6 joined, teatwo joined 14:16 linkable6 joined
Anton Antonov My attitude is kind of reflected here: resources.wolframcloud.com/PacletR...alParsers/ 14:20
14:42 jpn joined
lucs gfldex: No luck when adding 'compose', but here are a few more interesting (I think) observations: gist.github.com/lucs/4d5fe5e3c6fbd...66da677df1 14:51
gfldex It is a well known fact that the REPL mostly works. Raku is less dynamic as it looks at first. 14:52
14:58 MoC left
lucs By "mostly works", do you mean "sometimes fails"? 15:01
gfldex yes
lucs Fair enough :)
Do you have an opinion on how safe or should-avoid using 'augment' is? 15:04
15:04 derpydoo joined
moritz you should avoid augment 15:08
lucs Yeah, a few people have mentioned that, but I'm not clear on when it can be thought of a legitimate thing to do. 15:09
*thought of as 15:10
15:11 jpn left
gfldex That the REPL doesn't always work is a bug that very difficult to stomp out. 15:11
lucs In my case, it's no big deal, because I was using the REPL just to try out stuff as I develop my module, but the 'augment' on Match is kind of important (avoidable, but would be nice). 15:12
gfldex In retrospective `use MONEY-*;` was the wrong term. `use YOU-WILL-BREAK-ASSUMPTIONS;` would have been better. 15:15
lucs :-) 15:16
gfldex But then, the word assumptions contains the word ass. And we don't want to be that either. It's the old dilemma of balancing freedom with predictability. 15:17
timo i have heard "when you assume you make an ass out of u and me" 15:27
Anton Antonov "When you presume, you make a press out of u and me." -- Does not work that well, but it is something ChatGPT can come up with. 15:43
@avuserow I am experimenting with "SQL::Builder" -- you might be hearing from me. 🙂 15:44
avuserow Sounds good. Looks like you found a rough edge already, sorry about that. I'll take a look soon 15:53
gfldex lolibloggedalittle: gfldex.wordpress.com/2023/05/07/ha...algorithm/ 16:00
m: say $*lizmat++ for Empty;
camelia ( no output )
gfldex This line of code is a trueism, because lizmat invented Empty but got very little praise for it. More prais for lizmat, please. tyvm 16:01
Voldenet using LAST in map is scary 16:07
16:10 derpydoo left
Voldenet but since map is described as gather - Empty is guaranteed to work, next will also work 16:11
Anton Antonov @Voldenet Good to know. 16:13
gfldex Voldenet: In the old days, `for` just called `.map`, `do for` still does. That's why LAST must work in `.map`. 16:14
Voldenet iirc for loop will be converted to map as well 16:15
m: (for ^3 { $_ * 42 }).say
camelia (0 42 84)
gfldex Not anymore, I believe lizmat added that optimisation. 16:16
Voldenet Oh, it behaves like map, but is not actually map
gfldex And I don't like it. If `for` would always call `.map` we would not need custom iterators for simple iteration. Providing `method grep` and `method map` would do. 16:17
Voldenet funny that most developers would use .map where they intended to use >>.
gfldex ». was meant to autothread but then we got hyper/race. It would be tricky to set degree and batch-size otherwise. 16:19
And I don't think loop phasers would work in `».&{ your-code-here() }`. 16:20
Nemokosch don't forget that >>. has deepmap semantics anyway 16:21
Voldenet well LAST is scary and also not impleemented 16:23
m: (^42).hyper.map({ LAST { say ":(" } })
camelia Phasers in hyper/race not yet implemented. Sorry.
in block <unit> at <tmp> line 1
Voldenet Empty and next are implemented though
I wouldn't use phasers outside pure for loops either way, it simply doesn't look right 16:25
Nemokosch there is problematically much non-structured behavior 16:26
have we talked about next actually skipping through the stack, looking for a loop to step? 16:27
Voldenet I do wonder how is `next` implemented in context of hypermap 16:28
gfldex Empty in map is not in Roast (or I can't find the spot). But it really is emergent behaviour, because how binding to a positional container works. And Empty is specced quite a lot.
I believe it does not work.
At least the last time I checked no control exceptions worked in a HyperSeq. In react blocks most of the bugs are fixed tho. 16:29
Voldenet m: (^40000).hyper(:10batch :10degree).map({ next unless $_ > 39980; $_ }).say 16:30
camelia (39981 39982 39983 39984 39985 39986 39987 39988 39989 39990 39991 39992 39993 39994 39995 39996 39997 39998 39999)
Voldenet but it does seem to work
Nemokosch of course documentation and specification could have improved; documentation has improved a lot, it has a quasi workflow. Specification doesn't.
sometimes I wonder how I picked up this language; ngl I think most people wouldn't have that amount of time and freedom 16:31
however, I believe that Empty in particular can be deduced solely from the documentation 16:32
Voldenet one could reason that Empty works differently than next 16:33
next "skips" the element during the loop 16:34
16:34 jpn joined
Voldenet Empty gets emplaced into the resulting data structure which flattens it 16:34
Nemokosch yep, that's quite sure 16:35
btw I think the use of Empty in map even appeared in the Rakudo weeklies, as an alternate implementation to grep 16:36
gfldex next acutally stops execution of the block, while Empty works its magic after the fact.
Voldenet In practice Empty seems faster 16:37
Nemokosch what really strikes me without syntax highlighting is that [before] .item is confusing 16:38
in theory, I did know about &infix:<before> but not enough to think that while reading the code
gfldex Aye, control exceptions are still pretty slow. One reason for RakuAST.
Voldenet either way, Empty seems like something what _should_ be returned from map conceptually 16:41
gfldex ofc it does. Empty is the Slip of (). 16:44
And a Slip is just a value, unless it is bound to a positional container.
Voldenet fortunately redo doesn't work in map 16:46
actually maybe it does, but there's no way to return a value 16:47
gfldex Indeed, for doesn't want to be gather/take . 16:48
Voldenet m: (^10).map({ redo if (state @x).push($_).elems < 2; |@x }).say 16:49
camelia (0 0 0 0 1 0 0 1 2 0 0 1 2 3 0 0 1 2 3 4 0 0 1 2 3 4 5 0 0 1 2 3 4 5 6 0 0 1 2 3 4 5 6 7 0 0 1 2 3 4 5 6 7 8 0 0 1 2 3 4 5 6 7 8 9)
Voldenet this example makes my head hurt
I don't know any sane use case for this 16:50
gfldex Hold my beer! :D
No wait, you where asking for "sane". :->
Voldenet when drunk coding, you may consider more things sane, so take your beer back ;) 16:51
16:52 rf joined 17:05 Altai-man joined 17:07 lizmat_ joined 17:09 vrurg left
Nemokosch how did you come up with this though 17:10
there are more serious problems with this than redo, to be honest xD
17:10 vrurg joined 17:14 sena_kun left, kurahaupo left, lizmat left 17:38 jpn left 17:48 abraxxa-home joined 17:49 jpn joined 17:53 abraxxa-home left 17:57 abraxxa-home joined 18:00 reportable6 left, reportable6 joined 18:18 deoac joined 18:35 jpn left 18:50 jpn joined 18:52 lizmat_ left, lizmat joined 19:14 xinming left 19:39 jpn left, jpn joined 19:44 Sgeo joined 20:07 euandreh left 20:13 derpydoo joined 21:09 sftp left 21:10 euandreh joined 21:22 abraxxa-home left
[Coke] m: dd 1..10; Range.new(:from(1), :to(10); 21:28
camelia ===SORRY!=== Error while compiling <tmp>
Unable to parse expression in argument list; couldn't find final ')' (corresponding starter was at line 1)
at <tmp>:1
------> dd 1..10; Range.new(:from(1), :to(10);⏏<EOL>
expecting an…
[Coke] m: dd 1..10; Range.new(:from(1), :to(10));
camelia 1..10
Cannot resolve caller new(Range:U: :to(Int), :from(Int)); none of these signatures matches:
(Range: Range $min, \max, :$excludes-min, :$excludes-max, *%_)
(Range: \min, Range $max, :$excludes-min, :$excludes-max, *%_)
[Coke] m: dd 1..10; Range.new(1, *); 21:29
camelia 1..10
[Coke] ok, that explains github.com/Raku/doc/issues/4301
someone used :from :to but it's positional
Anton Antonov @avuserow I am trying to include "SQL::Builder" as a target in my data wrangling DSL. Here is an example: 21:31
@avuserow I have implemented the where statements generation to be in accordance to "SQL::Builder" (documentation) yet. But where statements are also handled. (Currently Raku code is placed.) 21:33
21:33 Altai-man left
avuserow That's awesome 21:34
Anton Antonov @avuserow Now, I might have a bunch of implementation requests : distinct , count, semi-join, anti-join, long- and wide form transformations, etc. 21:35
@avuserow Should make issues at GitHub? Or you prefer to be emailed a list? Other ways? 21:36
avuserow GitHub Issues are great, preferably with some example output 21:37
Anton Antonov @avuserow BTW, you can try the code generation yourself here: antononcube.shinyapps.io/DSL-evaluations/ .
I understand you mean SQL code. But would you "accept" Raku code too / instead? 21:39
avuserow DISTINCT is on my list already. I've been treating COUNT as a function (via Fn.new('COUNT', 'column')), but maybe there's something else in mind? 21:40
PRs are welcome too 👍
Anton Antonov Agh, you are asking me to do the work.... 🙂 21:41
avuserow oh, I would accept Raku examples too
I have not heard of semi-joins or anti-joins, and I'm a very example driven learner, so that's the easiest way for me to wrap my head around the request 21:42
Anton Antonov If there is an existing "count feature" I will implemented the code generation for it. It seems I can easily include it in the constructed pipeline.
You can see Raku examples here : github.com/antononcube/Raku-Data-R...s.rakutest 21:44
avuserow I currently write count as: $sql.from("table").select(Fn.new("COUNT", "artists")) => SELECT COUNT(artists) FROM table . TBD whether this deserves a better syntax, since this is 0.0.1 and syntax is easier to add than remove 21:45
Anton Antonov That is probably good enough. I have to experiment with it. 21:47
21:48 n1to__ left
@avuserow So, you run the generated SQL code in Raku sessions, or you also use separate SQL sessions? 21:49
avuserow I run it in Raku. I have a Cro webapp that uses this to make the SQL for e.g. search queries 21:53
Anton Antonov I see. I use both Cro webapp (the service linked above) and a CLI script that copies the generated code in the clipboard. 21:54
avuserow I have an experimental wrapper class for my main project that adds methods like .one, .all to actually run the queries. I'll eventually release that. 21:56
Anton Antonov BTW, currently I "only" construct the Raku code for "SQL::Builder" (in "DSL::English::DataQueryWorkflows") -- I am not executing it order to get the SQL code itself. (I plan to do that later today.) I might suggest that your builder know how to deal with wrong arguments. 21:58
@avuserow For example, this DSL spec: DSL MODULE DataQuery; DSL TARGET Raku::SQL::Builder; load data "songs"; join with ratings by song-id; filter by title is like "Am"; sort by title; generates the Raku code: $sql.from('songs').join(:inner, ratings, :on(["song-id"])).where(title ~~ "Am").order-by("title") 21:59
@avuserow Idially, where can just dump the given argument, e.g. select * from songs join ... where <<title ~~ "Am">> order by title. Or something like that... 22:02
avuserow Hm. Maybe. I have a lot of thoughts on the where clause syntax. I need to write a blog article (or two) about it at some point 22:05
it seems like you would get what you want if you emitted .where(["title", "~~", "Am"]) . It's kind of like an abstract syntax tree way of writing SQL 22:08
but there's still some exploration and refinement to do. That's v0.0.1 for you 🙂 22:09
22:48 linkable6 left, evalable6 left 22:50 linkable6 joined, evalable6 joined 23:43 jpn left