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.
00:06 Manifest0 left
el gatito (** advocate) why do you hate using exceptions as iteration sentinels tho 00:15
Nemokosch they don't describe the intent well, they are wordy 00:24
multiple disadvantages for no advantages
el gatito (** advocate) raku does almost the same thing just returning IterationEnd instead of raising an exception 00:25
Nemokosch yes, and that's already slightly better 00:28
el gatito (** advocate) how? 00:33
Nemokosch it doesn't get mixed with actual exceptions 00:38
el gatito (** advocate) you can make an exception subclass that represent fail exceptions and StopIteration wouldn't subclass it 00:42
Nemokosch why would you want to drill on the type system, though, in order to indicate the normal behavior of iterators? 00:45
el gatito (** advocate) actually python doesn't do that 😭 00:46
why not 00:50
Nemokosch because it's inconvenient and error-prone
what is the offer in return?
el gatito (** advocate) actually ruby does the same thing ruby-doc.org/core-2.6/Enumerator.html 00:51
Nemokosch that's sad if anything 00:52
el gatito (** advocate) its more convenient if you are iterating multiple times? py with suppress(StopIteration): seq.append(next(it)) other |= next(it) vs py temp = next(it) if not isinstance(temp, StopIteration): seq.append(temp) temp2 = next(it) if not isinstance(temp, StopIteration): other |= temp2 00:55
Nemokosch this rather seems like a hack
even if we ignore that this supressor is some magic function - what value do you get when you were supposed to get an exception? 01:00
and if you do get a value that you can recognize - what was the whole exception mumbo jumbo about? we are back to a sentinel value 01:01
el gatito (** advocate) no value also yielding a value and ending the iteration should be different to the consumer, so they do different things (give a value vs raising an exception) 01:08
Nemokosch how does "no value" manifest when you are clearly storing something into a variable? 01:09
also: why would an end user even want to consume an iterator 01:10
rather than something iterable
with the proper handling of an iterable
like a foreach loop
el gatito (** advocate) you don't want to store an "end of iteration" marker to a variable?
by consumer i mean code that consumes iterators bruh 01:11
Nemokosch yes - what would that even be?
that's low-level code
and as such, it clearly never wants to escalate a control exception
and idk how that follows. I just wanted to get an answer 01:12
el gatito (** advocate) also what happens when someone wants to yield StopIteration or IterationEnd you don't want to make assumptions about the data being yielded 01:15
Nemokosch yes, you do, if the value happens to be the dedicated sentinel value 01:17
sorry but that's not some coincidental data, that's part of the interface
you know, this argument is like
el gatito (** advocate) the exception is raised before something is assigned to the variable so nothing is assigned period
Nemokosch "what if the processor of the iterator wants to raise StopIteration cause why not?"
"you wouldn't want to make assumptions about the exceptions that can happen..." 01:18
yet it's being assigned to something so something just must happen 01:19
the universe can't just disappear on this contradiction, lol
el gatito (** advocate) generators will cause a RuntimeError if they raise that and if class-based iterators raise that it obviously means they want to end 01:21
Nemokosch similarly, if you define an iterator that gives you IterationEnd on pulling, that means it's over 01:23
Actually, IterationEnd isn't even Any; it's really just a unique reference reserved for this purpose 01:24
there is literally no other reason to return it than to indicate the exhaustion of the iterator 01:25
el gatito (** advocate) the rhs next(it) raises an exception while evaluating so the assignment doesn't happen same thing when you do a = 1 / 0 there is an exception in 1 / 0, so a is untouched 01:26
should be pretty easy to reason 01:27
Nemokosch then what did you win with suppress?
el gatito (** advocate) ignore the exception and exit the block 01:28
Nemokosch or you could just do something like
until (my \next := $iterator.pull-next) =:= IterationEnd { ... } 01:29
and be in the safe
it didn't need sugar on top of sugar
actually, := is superfluous there, terms always bind on initialization 01:30
el gatito (** advocate) fair 😤 01:32
Nemokosch these wrappers are more or less convertible anyway, if the iterator interface itself achieves the same thing 01:34
the question is what you'd make the normal way
el gatito (** advocate) then whats your ideal of an iterator interface you want separate done() method to indicate the end of iterator? 01:35
01:36 frost joined
Nemokosch Tbh the Java way is not so bad 01:42
with bare hasNext and next
the C#/Object Pascal way is somewhat more readable to the user imo
a function for moving the cursor (which can return False on "failure"), and another one for reading the current item 01:43
the JS interface is fairly interesting and not necessarily in a bad way 01:44
that one is more like Python (you can pass a value to next)
however, it doesn't throw an error but returns an object with the value and the completion 01:45
if the completion is marked, a final value still might be obtained, which in that case would be the return value of the iterator 01:46
el gatito (** advocate) then there is php php <?php interface Iterator extends Traversable { /* Methods */ public current(): mixed public key(): mixed public next(): void public rewind(): void public valid(): bool }
Nemokosch well this is a bit harder to actually implement I guess 01:48
with the rewind
still, I have to say, given the core of the Javascript language, the extensions from ES6 onwards are really gems of shining genius 01:50
also unorthodox af 01:51
but it seems kinda justified when it comes to a language that has not seen any serious revisions for almost 20 years
and was deliberately designed to be banal
one example that illustrates the desperation, though, is 'use strict' 01:53
el gatito (** advocate) didn't fix the type system tho 😭 01:57
which is why typescript is a godsend 02:05
Nemokosch what was wrong with the type system? 02:08
ngl I also admire TS, mostly because of laziness
el gatito (** advocate) weak typing 😩
Nemokosch Without TS, I basically don't know the API of a random Node module 02:09
but that's really the biggest use I see for it
el gatito (** advocate) typescript complains when you give the wrong type so no more weak typing 02:11
unless you want
Nemokosch I tend to use == and fortunately the linter won't complain by default
but yeah all of a sudden it's statically known what types can hit that comparison 02:12
el gatito (** advocate) the same with raku too typing will allow me to write strongly typed codebase 02:14
Nemokosch I wonder how much static analysis will be possible, and how much it will be just runtime checks, PHP style 02:21
Also, be warned that the type system demands quite some care to get solid
02:41 rf joined 03:03 rf left
el gatito (** advocate) m:perl my @a = <a b c>; say "this is @a"; 03:58
Raku eval this is @a
el gatito (** advocate) what
m:perl my @a = <a b c>; say "this is @a[]";
Raku eval this is a b c
el gatito (** advocate) why
m:perl my @a = <a b c>; say "this is $@a"; 03:59
Raku eval this is a b c
MasterDuke because `@` is now a common character to appear in strings where you don't want them to interpolate, i.e., email addresses 04:08
el gatito (** advocate) $ is also common? 04:10
and you can just escape them or use ' strings? 04:13
05:23 Heptite left
Nemokosch @ is more common than $ 08:30
having said that, this is inconsistent, no point in trying to explain it away xD
however, it's also insignificant 08:31
09:03 Manifest0 joined 09:10 dakkar joined
el gatito (** advocate) actually {} interpolation most goated 09:23
m:perl say "1 + 1 = {1 + 1}"
Raku eval 1 + 1 = 2
Nemokosch because it actually creates a block 09:51
10:09 ab5tract joined
el gatito (** advocate) then invokes it immediately 10:15
hmm
Nemokosch m: say "1 + 1 = &{1 + $_}(2)" 10:33
Raku eval 1 + 1 = 3
Nemokosch needed the ampersand
11:03 frost left 11:16 frost joined, ab5tract left 11:29 ab5tract joined 11:42 ab5tract left 11:53 ab5tract joined 12:13 frost left
Nahita m: sub f(\n?) { } 12:28
Raku eval Exit code: 1 ===SORRY!=== Error while compiling /home/glot/main.raku Malformed parameter at /home/glot/main.raku:1 ------> sub f(\n⏏?) { } expecting any of: constraint
Nahita m: sub f($n? is raw) { }
Raku eval
13:17 Heptite joined 13:28 saint- left 14:09 QhpAptyj9hj0RQwM joined 14:33 jgaz joined 14:40 habere-et-disper joined
habere-et-disper Hello rakoons o/ :D 14:44
Is it reasonable that
m: <a b>.join
camelia ( no output )
habere-et-disper m: join <a b>
camelia ( no output )
habere-et-disper give different results? I realize that with the prefix form you have to do:
m: join '', <a b>
camelia ( no output )
habere-et-disper But it seems somewhat irregular that a default value appears supplied in postfix form but not in prefix form. Am I missing something? Thanks!
m: say <a b>.join
camelia ab
habere-et-disper m: say join <a b>
camelia
14:53 habere-et-disper left
Nemokosch m: say join (1, 2) 15:00
Raku eval
Nemokosch weeeell
oh right 15:01
the argument order is different
m: say join '', (1, 2)
Raku eval 12
Nemokosch I think this is regular, in the sense that all array-ish subs have this argument layout 15:02
map, grep, and so on
the question is rather: why a one-argument call succeeds with whatever result 15:03
ab5tract m: say join |<a b> 15:52
camelia b
15:54 habere-et-disper joined
ab5tract seems weird 15:54
15:54 rf joined 15:55 QhpAptyj9hj0RQwM left
Nemokosch I mean... that's one b, separated by a's 16:00
😄
habere-et-disper The documentation is correct, reading "The method form also allows you to omit the separator", but I'd be interested as to why the prefix form is not afforded it. 16:54
The join documentation also gives an example of:
m: say join ', ', <a b c>;
camelia a, b, c
habere-et-disper Which appears to currently fail !?
I get the following on the REPL (v2022-12): 16:55
say join ', ', <a b c>;
===SORRY!=== Error while compiling:
Two terms in a row
------> say join<HERE> ', ', <a b c>;
Nemokosch can't reproduce on the same version 17:35
maybe you have actually missed a space between join and ', '? 17:36
17:37 dakkar left
habere-et-disper No, and even weirder it appears to work fine again !? 17:38
17:53 habere-et-disper left 18:02 Heptite left 18:07 Heptite joined 18:16 ab5tract left 18:30 ab5tract joined
Nahita if I have a .rakumod file for common use, what can I do so that use Module from anywhere uses it 18:57
tried moving the file to some places where it reports it couldn't find it, it still didn't find it 18:58
it's a single .rakumod file
i faked a meta6.json and zef installed it but that's perhaps not the way 19:00
p6steve why not zef install https:://github.com/path-to/Module.git ? 19:03
Nahita it's a single file locally
p6steve does zef install /local-path/Module.rakumod work (I never tried it)? 19:04
Nahita thanks but that searched for the internet so it did not work 19:05
by internet i mean it updated mirrors fez, cpan etc. and says No candidates found matching identity 19:07
i can make an alias for "raku -Ipath/to/module" i guess... 19:08
but there is a better way probably
p6steve according to the zef README 19:09
# PATH zef install ./Raku-Net--HTTP
should work ... need to start the local path with / or .
github.com/ugexe/zef#more-cli 19:10
Nahita well i first tried "zef install ." in the folder the module resides in
then i got "Type check failed for return value; expected IO::Path but got Any (Any)" message
then i faked a meta6.json
then "zef install ." worked
now i tried "zef install ./folder" 19:11
same message as above
which is not super helpful message but i guess it wants to say it couldn't fine meta6.json or something idk 19:12
Nemokosch I guess you could just copy it to a folder in RAKULIB?
p6steve yeah I have tried locally on my machine and have the same issue 19:13
making a mini module (ie spoof the META6.json locally) and then zef install . works for me 19:14
as @Nemokosch mentions perhaps you can symlink or append the Module path to RAKULIB 19:15
Nahita in Perl, i put a .pm file in a place mentioned in @INC, it works. in Python, i put a .py file in a place mentioned in sys.path, it works. in Raku, i put a .rakumod file to such place, it doesn't work 19:22
should i precompile the module or something?
Nemokosch it should work without 19:23
Nahita let me try that maybe
Nemokosch it definitely works locally by setting -I to the sufficient location
It would only make sense that it works the other way around as well
Nahita moving the precompiled thing didn't work too 19:28
19:30 ab5tract left
asking in the other place. 19:35
19:53 ab5tract joined
elcaro You could to a copy it to a folder, eg. $HOME/.local/lib/raku/Module.rakumod Then export the path to the env var RAKULIB For example, I have a line in my .profile file export RAKULIB=$HOME/.local/lib/raku And now any modules I throw in there are always available to use 23:09
If you're on windows, replace $HOME with %USERPROFILE%, but really, it doesn't matter where you put them, so long as RAKULIB points to it. Exporting env vars is also annoying in Windows (last I checked). 23:10
23:56 Heptite left