🦋 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:07 jpn joined
timo that's correct, it's currently a pull request in the moarvm repo 00:10
CI is green, i'll wait for someone to give it a quick look, then it can be merged to main 00:11
grondilu noted, thanks
timo you can try to work-around it in your code by getting rid of the LEAVE block in DELETE-KEY i think 00:12
00:12 jpn left
grondilu I think this is a schema I use quite a bit, though it's only yesterday that it seemed to cause issues 00:13
timo indeed, the magic trick seems to be the combination with something else in the program 00:15
grondilu oh it seemed so far I was using it only for graphics stuff. They are much less intensive than when I parse a game.
As I use LEAV &undo almost at every move 00:16
(well, not quite but almost)
(the point of the hybrid representation was precisely to avoid having to mutate the object every time) 00:17
( 🤔 but that hybrid representation is not fully implemented, so... not sure) 00:18
timo did you know about "temp"? i haven't used it yet, but it could be relevant 00:19
grondilu actuall no, I don't know about ut
*it
timo the exact mechanism of the issue is tricky to describe in a way that is helpful to non-internals-divers 00:20
so, my current understanding is that entering the block with the LEAVE phaser installs a "special unwind" on the stack frame which causes a bit of code to run when it's left, plus a bit of important housekeeping. one bit of that housekeeping is storing the current "thrown payload" so it can be restored after the code is ran 00:21
the cause of the bug was that the pointer to the "thrown payload" was not being sent to the GC to be updated when the object it points to is moved 00:22
for the explosion to actually then happen, a piece of code that runs after the leave phaser must grab the "thrown payload" that was restored but not put its own payload in that slot in the mean time, and a GC run must have happened between installing that special unwind and the payload getting restored from it 00:23
the "thrown payload" is kind of an optimization in moarvm that we can use when we throw some kind of exception where the Exception object doesn't actually matter, only its category but also one value that belongs to it 00:24
grondilu well that sounds out of my league
timo there's a GC_DEBUG define that one can set inside moarvm's source code that makes code a little bit slower (at 1) or a lot slower (at 2) that can catch the explosion a bit earlier than having to wait for the next GC run, but it's still not trivial to make a reproducing case 00:30
in any case, props for stumbling upon this 00:31
grondilu I have a nack for finding obscure bugs here lol 00:32
it's fortunately getting more rare with time, but I used to stumble upon weird bugs everytime I was starting a new project in raku 00:33
timo straight-up GC bugs have become quite rare I think 00:45
00:47 lichtkind left
timo it's merged into moarvm's main branch now, so if you grab the very latest blead, you won't see the crash any more (but users of your module that remain on the latest released version will still get them) 01:08
grondilu proceeds to pull rakudo/moar 01:09
so now I have to merge moarvm-error to master? 01:12
01:12 hulk joined
grondilu well after I clean it up, that is 01:13
01:13 kylese left
timo no, using moar's main branch should be good enough 01:14
wait
moarvm-error was in your repo, not moar's repo
grondilu yes
timo right, you have a few different options what exactly to do with the moarvm-error branch, and the commit on it 01:15
you can switch to your master branch and use the "git merge" command to pull the commit from the other branch into the main branch. since they haven't diverged yet, there won't be a noticeable effect from the perspective of the main branch - it will by default be a "fast-forward merge", but there's a "--no-ff" flag to "git merge" that allows you to create a merge commit regardless if you like 01:16
you can also do the cleanup while you're on the moarvm-error branch with additional commits, then afterwards to the merge in the same way i just described 01:17
grondilu gotcha 01:18
the important point I guess is not to commit in the master branch before I do the merge, otherwise merging will be tricky, right?
timo if you prefer for the intermediate commits to not go down in your commit history, that's what "squashing" is for. usually i use "git rebase -i" + editor to do that, but i see now that "git merge" also has a "--squash" flag that i have never tried that is probably a bunch easier than my way
that's right. git will automatically merge your files if the edits from each branch are far away enough from each other to not overlap (with some safety margin), but it's not guaranteed that the automatic merge result is actually semantically correct 01:19
if the edits are too close, it will tell you that there's been a merge conflict and will ask you to resolve it by hand 01:20
do you use some IDE for your work usually?
grondilu I just use neovim
timo OK, I've been using vscode mostly for a while, and it has a decent "merge editor" 01:21
grondilu I think as long as I remember not to commit anything in the master branch for a while, I'll be fine.
timo i used to use Splice.vim from steve losh, but it appears to have bitrotted maybe 01:22
grondilu hell, I guess I'll just do the merge now and clean everything in master.
timo it'll be totally fine to keep it in the branch and not commit to master until that's done 01:23
but it's really a matter of taste 01:24
do you want your master branch to always be "clean" / "working" / "releasable", then you'd be developing a lot in "feature branches" 01:25
for raku modules that upload to the fez ecosystem, it's not so important to keep master clean since a "zef install YourModule" won't just pull the latest commit from your main or master branch
grondilu I'm not sure moar was updated when I pulled rakudo 01:28
the bug just occurred
and I did not see any message regarding moar when rebuilding rakudo. only about nqp 01:29
timo how exactly do you build rakudo? unless we commit a "requires at least this commit" thingie to nqp and then to rakudo, it won't pull the newer commit
we call this "bumping" and lizmat does this quite regularly
i could do it right now
grondilu I do `./Configure.pl --gen-{moar,nqp} --prefix=...` 01:30
timo ok, that respects the NQP_REVISION in rakudo and the MOAR_REVISION in nqp
grondilu looks at options for Configure.pl 01:31
timo there we go 01:33
grondilu well I don't see anything forcing the update of moar 01:36
timo but the latest rakudo commit should pull in the new stuff 01:37
grondilu I see
"Unrecognized revision specifier '<<<<<<<'" 01:38
timo nnnnoooooo
grondilu lol
you did a oopsie?
timo now should be better
'tis a sign that i should be going to sleep 01:39
grondilu ah now I see the message about moar needing update
01:41 jpn joined
grondilu ouch 01:45
Missing or wrong version of dependency 'gen/moar/stage2/NQPHLL.nqp' (from '/var/home/grondilu/.local/src/chess/lib/Chess/Colors.rakumod (Chess::Colors)')
01:45 jpn left
grondilu did I forget to make install? 01:47
grondilu checks 01:48
no, I didn't.
oh, maybe I should remove the .precomp files? 01:49
yes, that worked
02:15 hulk left 02:16 kylese joined 02:23 discord-raku-bot left 02:44 jpn joined 02:50 jpn left 03:14 simcop2387 left, simcop2387_ joined 03:15 simcop2387_ is now known as simcop2387 03:25 xkr47 left, xkr47 joined 03:50 Aedil joined 04:22 jpn joined 04:27 jpn left 04:30 kylese left 04:33 kylese joined 04:48 maylay left 04:50 maylay joined 05:04 discord-raku-bot joined 05:06 landyacht joined
.landyacht. testing bridge 05:06
05:06 landyacht left 05:30 kylese left 05:32 kylese joined 05:35 Sgeo left 05:55 jpn joined 05:59 stanrifkin joined 06:00 jpn left 06:51 jpn joined 06:56 jpn left 07:08 jpn joined 07:13 jpn left 07:58 dakkar joined 08:02 jpn joined 08:20 vrurg left, vrurg joined 09:00 lichtkind joined 09:57 Aedil left 10:01 Aedil joined
grondilu Hello 12:12
m: role Foo { method WHICH { rand } }; role Foo[$x] { method x { $x } }; say Foo[pi].new.WHICH
camelia Foo[Num]|6313063968064
grondilu m: role Foo { method WHICH { rand } }; role Foo[$x] { method x { $x } }; say Foo[pi] ~~ Foo
camelia True
grondilu so why does Foo[pi] inherits WHICH from Foo? 12:13
*doesn't
m: role Foo { method WHICH { rand } }; role Foo[$x] { method x { $x } }; say (class :: does Foo).new.WHICH
camelia ===SORRY!=== Error while compiling <tmp>
Unable to parse class definition
at <tmp>:1
------> ethod x { $x } }; say (class :: does Foo<HERE>).new.WHICH
grondilu m: role Foo { method WHICH { rand } }; role Foo[$x] { method x { $x } }; say (class :: does Foo {}).new.WHICH 12:14
camelia 0.3279472895416208
grondilu m: role Foo { method WHICH { rand } }; role Foo[$x] { method x { $x } }; say (class :: does Foo[pi] {}).new.WHICH
camelia <anon|1>|2767065099968
grondilu see the problem?
dakkar I think Foo[1] should not match Foo at all… they're unrelated roles 12:29
m: role Foo {}; role Foo[$x] {}; say Foo ~~ Foo[1]
camelia False
dakkar m: role Foo {}; role Foo[$x] {}; say Foo[1] ~~ Foo
camelia True
dakkar m: role Foo {}; role Foo[$x] {}; say Foo; say Foo[1]
camelia (Foo)
(Foo[Int])
dakkar also that last string looks wrong
(it should be `Foo[1]`, right? not `Foo[Int]`, I did not pass a type object as the role argument) 12:30
grondilu might be just the gist 12:35
m: role Foo {}; role Foo[$x] {}; say Foo; dd Foo[1]
camelia (Foo)
Foo[Int]
grondilu 🤔
dakkar the gist is supposed to be `eval`-uable back to something pretty close to the original value
(right?) 12:36
grondilu well maybe the compiler forgot what $x is since it's not used
dakkar m: role Foo[$x] { method x { $x } }; say Foo[1]
camelia (Foo[Int])
dakkar no
(it would be wrong anyway!)
grondilu then maybe it's a form of encapsulation policy not to show the value 12:37
dakkar m: role Foo[$x] { method x { $x } }; say Foo[1].HOW.role_arguments 12:38
camelia (1)
dakkar no
I'm pretty sure you stumbled on a small pile on interlocking bugs
grondilu m: role Foo { method talk { say "hi" } }; role Foo[$x] { method x { $x } }; (class :: does Foo[pi] {}).new.talk 12:40
camelia No such method 'talk' for invocant of type '<anon|1>'
in block <unit> at <tmp> line 1
grondilu seems like this had nothing to do with WHICH
dakkar correct, the two roles have no relation to each other
grondilu yet Foo[pi] ~~ Foo
dakkar which is (I suspect) one of the bugs 12:41
that `~~` should not be true
grondilu it's also a bit confusing that they are not related
(if they really aren't)
dakkar it might be nice to have some "proto" parametric role like we have for multi subs, maybe 12:42
grondilu any user would assume that is what the parameterless version is 12:43
dakkar `multi sub foo() { say "empty" }; multi sub($x) { say "with $x" }; foo(1)` do you assume the first one gets called? 12:44
grondilu fair point
dakkar we have an explicit `proto` for the multi-sub case 12:45
grondilu I see. In fact maybe Foo really means Foo[]
in which case that makes sense 12:46
dakkar it… doesn't (their metaclasses are different), but it's probably a close enough approximation
grondilu hang on. Does that mean I can use a parameter in a parametric role in order to merely distinguish between several versions of that role? 13:00
lizmat yes: the body of a multi role is internally treated as a multi sub, with the parametric role's arguments as its signature 13:01
grondilu Like : I have a Chess::Piece role with a `color` attribute. Instead of an attribute I could make it a parametric role. And then I won't have to face the issues I get from using WHICH 13:02
lizmat m: role A[Str] { dd }; role A[Int] { dd }; class B is A[42] { } 13:03
camelia sub (::$?CLASS ::::?CLASS Mu, Int)
grondilu I thought I had tried this approach before but sadly I can't remember why I gave up on it.
m: enum color <black white>; role piece[color $color] {}; say piece[white].WHICH; say piece[black].WHICH 13:05
camelia piece[color]|U5045034485856
piece[color]|U5045034485832
grondilu m: enum color <black white>; role piece[color $color] {}; say piece[white].WHICH; say piece[white].WHICH
camelia piece[color]|U2373530947608
piece[color]|U2373530947608
grondilu that seems like exactly how I should have done it. Never instanciating pieces. 13:06
as they need to be indistinguishable
I've considered using enums but pieces do have behaviors and properties. 13:07
m: enum color <black white>; class Piece {}; role Pawn[color $color] is Piece {}; say Pawn[white]; 13:11
camelia (Pawn[color])
grondilu that's so much cleaner. Except maybe having a parametric role inheriting from a class is a bit unusual. 13:12
lizmat why can't Piece be a role as well ? 13:13
roles auto-pun into classes when instantiated
grondilu it can indeed
lizmat m: role A { $.foo =42 }; dd A.new
camelia ===SORRY!=== Error while compiling <tmp>
Variable $.foo used where no 'self' is available
at <tmp>:1
------> role A { $.foo<HERE> =42 }; dd A.new
expecting any of:
term
lizmat m: role A { has $.foo =42 }; dd A.new
camelia A.new(foo => 42)
grondilu but then if should I use inheritance or mixin? 13:14
lizmat whatever feels more convenient for you ?
grondilu like `role Pawn[color $color] is Piece` or `role Pawn[color $color] does Piece`? I'm not sure what the difference entails. 13:15
lizmat with classes you run the risk of: 13:16
m: class A { }; role B is A { }; class C does B is A { }
camelia ===SORRY!=== Error while compiling <tmp>
Package 'C' already has parent 'A'
at <tmp>:1
lizmat whereas with roles, this would just work: 13:17
m: role A { }; role B does A { }; class C does B does A { }
camelia ( no output )
grondilu I see. Now, is there any chance I could make Piece the parametrized role? Pawn will not inherit the parametrization, right? 13:18
Meaning I have to repeat [color $color] for each piece type (pawn, bishop, knights...)
lizmat lemme think about that... need to go afk for 20 mins or so 13:19
back 13:47
something like: role Piece[$type, $color] { } maybe ?
where $color could be an enum ? and possibly $type as well ? 13:48
14:36 japhb left 14:48 japhb joined
grondilu I went afk too and on the road I thought : why not make colors as roles instead? 14:50
the problem with role Piece[$type, $color] { } is that I can't have one role for each type of piece, regardless of color, can I? 14:51
maybe just: role white {}; role black {}; role Piece[$symbol] {}; class Pawn does Piece['p'] {...}; 14:53
and then `Pawn but white` whenever I need a white pawn. 14:54
also role Piece[$symbol] { multi method new {!!!} } to forbid instanciation. 14:56
m: role white {}; role black {}; role Piece[$symbol] { multi method symbol(white:) { $symbol.uc } }; class Pawn does Piece['p'] {}; symbol Pawn but white : 14:58
camelia ( no output )
grondilu m: role white {}; role black {}; role Piece[$symbol] { multi method symbol(white:) { $symbol.uc } }; class Pawn does Piece['p'] {}; print symbol Pawn but white :
camelia P
grondilu unfortunately that would require a big rewrite of my modules.
honestly that seems better. The concept of color very much matches what a role is, after all : it can be applied to any object. Mixed-in, so to say. 15:00
grondilu goes for it 15:01
Voldenet maybe a bit boring approach, but isn't color an attribute of a piece 15:16
melezhik. If someone wants to play with Raku/alpine images testing here is the link to my project - github.com/melezhik/sparky-qemu-ex...ree/alpine 15:17
Voldenet what could be simply done is `my WhiteRook = Piece.new(white, rook)` 15:20
erm
grondilu Voldenet: the problem with this is that I dealing with instances, and thus issues with WHICH
Voldenet: the problem with this is that I am *then* dealing with instances, and thus issues with WHICH 15:21
Voldenet `my \WhiteRook = Piece.new(white, rook)`
grondilu 🤨 15:22
Voldenet it'd require binding everywhere
so maybe it's a bit annoying
grondilu m: enum color <white black>; enum piece-type <pawn rook knight>; role Piece[color, piece-type] {}; my \a = Piece.new(white, rook); my \b = Piece.new(white, rook); print a.WHICH; print b.WHICH 15:24
camelia No appropriate parametric role variant available for 'Piece':
Cannot resolve caller (Piece); none of these signatures matches:
(::$?CLASS ::::?CLASS Mu, color, piece-type)
in block <unit> at <tmp> line 1
grondilu m: enum color <white black>; enum piece-type <pawn rook knight>; role Piece[color $, piece-type $] {}; my \a = Piece.new(white, rook); my \b = Piece.new(white, rook); print a.WHICH; print b.WHICH
camelia No appropriate parametric role variant available for 'Piece':
Cannot resolve caller (Piece); none of these signatures matches:
(::$?CLASS ::::?CLASS Mu, color, piece-type)
in block <unit> at <tmp> line 1
grondilu wth am I doing
m: enum color <white black>; enum piece-type <pawn rook knight>; role Piece { has color $.color; has piece-type $.type }; my \a = Piece.new(white, rook); my \b = Piece.new(white, rook); print a.WHICH; print b.WHICH 15:25
camelia Default constructor for 'Piece' only takes named arguments
in block <unit> at <tmp> line 1
grondilu m: enum color <white black>; enum piece-type <pawn rook knight>; role Piece { has color $.color; has piece-type $.type }; my \a = Piece.new(:color(white), :piece(rook)); my \b = Piece.new(:color(white), :piece(rook)); print a.WHICH; print b.WHICH
camelia Piece|6282958131648Piece|6282958133088
Voldenet well, that wouldn't work 15:26
m: enum color <white black>; enum piece-type <pawn rook knight>; role Piece { has color $.color; has piece-type $.type }; my \WhiteRook = Piece.new(:color(white), :piece(rook)); my \a = WhiteRook; my \b = WhiteRook; print a.WHICH; print b.WHICH
camelia Piece|3036901757568Piece|3036901757568
Voldenet that would
maybe it's feasible to have "new" being a bit smarter 15:27
grondilu like caching? 15:28
multi method new(|) { ...; (state %){$color}{$type} //= self.bless: ... }
Voldenet yeah, something like that 15:29
m: my enum Color <white black>; my enum PieceType <rook>; role Piece { my %I; has Color $.c; has PieceType $.t; method new($c, $t) { %I{$c}{$t} //= self.bless(:$c, :$t); } }; my $x = Piece.new(white, rook); my $y = Piece.new(white, rook); say $x.WHICH; say $y.WHICH;
camelia Piece|4421230257504
Piece|4421230257504
Voldenet no binding needed
grondilu 🤔 15:30
Voldenet It's unromantic and lacks intellectual challenge built into it, exactly how I like :>
grondilu and then I can define Pawn, Rook (with upper-case first), as subsets... I guess. 15:31
Voldenet perhaps the other possibility would be roles, still non-generic 15:46
role Color { method color {…}; }; role White does Color { method color { "w" }}; role PieceType { }; role Rook does PieceType {}; role Piece does PieceType does Color { }; class WhiteRook does Rook does White does Piece {}; say WhiteRook.color
evalable6 w
Voldenet role Color { method color {…}; }; role White does Color { method color { "w" }}; role PieceType { }; role Rook does PieceType {}; role Piece does PieceType does Color { }; class WhiteRook does Rook does Piece {}; say WhiteRook.color
m: role Color { method color {…}; }; role White does Color { method color { "w" }}; role PieceType { }; role Rook does PieceType {}; role Piece does PieceType does Color { }; class WhiteRook does Rook does Piece {}; say WhiteRook.color
camelia ===SORRY!=== Error while compiling <tmp>
Method 'color' must be implemented by WhiteRook because it is required by roles: Piece.
at <tmp>:1
Voldenet it feels a bit hacky though 15:47
su.sh hey guys, i'm new to raku. this marks my first interaction with the raku community! 15:58
scullucs Welcome, and have the appropriate amount of fun! 16:00
su.sh nice 16:01
antononcube Disproportionate is fine too. 16:17
scullucs Once in a while too, sure 🙂 16:33
16:36 dakkar left
lucs Question about reformatting output of ⟨something⟩.raku : [1] > say ('baz 42 k9 foo' ~~ m:g/ \d+ /).raku 17:11
(Match.new(:orig("baz 42 k9 foo"), :from(4), :pos(6)), Match.new(:orig("baz 42 k9 foo"), :from(8), :pos(9)))
JHC, sorry
gist.github.com/lucs/b24b30cf0eb3e...9ebd260946
[Coke] lucs: I don't think so - we have modules for JSON and a few other formats, but not for pretty printing an object/array of objects. 17:22
Seems like a straightforward module, though. (I don't know how much of that logic is already in rakudo's dd) 17:23
lucs Hmm... I'll have a look at dd. 17:24
Not sure how far I'll get, but I'll try to write up something that works. 17:25
Thanks.
[Coke] dd is more about dumping than pretty printing
lucs Yeah, oh well :)
[Coke] oh, maybe raku.land/zef:raku-community-modules/PrettyDump ? 17:26
ah, yes, there you go 17:27
lucs Oho! Great, thanks. 17:28
[Coke] added a comment to your gist
and that's a community module if you have any issues we can get a new versin out
17:58 drakonis left
grondilu so what characters can I use with `term:<>` ? î­¬ given in the docs as an example works, but not chess pieces apparently. 18:51
m: constant term:<î­¬> = Mu
camelia ( no output )
grondilu m: constant term:<â™”> = Mu
camelia ( no output )
grondilu 🤨 18:52
m: constant term:<â™”> = Mu; print â™”
camelia Use of uninitialized value of type Mu in string context.
Methods .^name, .raku, .gist, or .say can be used to stringify it to something meaningful.
in block <unit> at <tmp> line 1
grondilu m: constant term:<â™”> = Mu; dd â™”
camelia Mu
grondilu I swear I had tried it on my machine and it failed
m: package Foo { constant term:<â™”> is export = Mu; }; import Foo; dd â™” 18:54
camelia ===SORRY!=== Error while compiling <tmp>
Bogus term
at <tmp>:1
------> m:<â™”> is export = Mu; }; import Foo; dd <HERE>â™”
expecting any of:
argument list
infix
infix stopper
postfix
prefix…
grondilu m: package Foo { constant term:<î­¬> is export = Mu; }; import Foo; dd î­¬
camelia ===SORRY!=== Error while compiling <tmp>
Bogus term
at <tmp>:1
------> m:<î­¬> is export = Mu; }; import Foo; dd <HERE>î­¬
expecting any of:
argument list
infix
infix stopper
postfix
prefix…
grondilu nevermind I'll go for the verbose versions white-pawn, white-knight... 18:58
19:01 oodani left 19:07 oodani joined 19:48 jpn left 19:51 eseyman left 20:27 jpn joined 20:50 manu_ joined 20:52 bisectable6 left, bloatable6 left, linkable6 left, benchable6 left, greppable6 left, committable6 left, releasable6 left, nativecallable6 left, unicodable6 left, quotable6 left, evalable6 left, notable6 left, shareable6 left, tellable6 left, coverable6 left, sourceable6 left 20:53 Aedil left 20:55 greppable6 joined, shareable6 joined, nativecallable6 joined, bloatable6 joined, linkable6 joined, committable6 joined 20:56 releasable6 joined, evalable6 joined, benchable6 joined, bisectable6 joined, tellable6 joined, quotable6 joined, unicodable6 joined 20:57 notable6 joined, coverable6 joined, sourceable6 joined 20:59 manu_ is now known as eseyman 21:24 jpn left 21:47 jpn joined 21:57 Sgeo joined 21:59 Sgeo_ joined 22:02 Sgeo left
lizmat grondilu: perhaps you meant Mu.new ? 22:19
22:23 jpn left
grondilu not at all. I moved on anyway. 23:11
Just wanted to say it's quite amazing how much faster my code is for processing games if I edit the Chess::Position object in place instead of treating it as immutable. 23:12
Now I can parse all Morphy's games in less than ten seconds against nearly a minute before.
grondilu tries with Kasparov's games 23:13
done. about a minute. Against about ten minutes before. 23:14
mutability FTW, I guess.
timo maybe there's some stuff we can do in terms of optimizations to make it faster with immutable objects 23:26
but yes, there is a cost to copying for every change you want to make
grondilu well, in fact I was parsing the FEN (string description of a position) everytime I made a move. That sure could not be cheap. 23:27
timo right, sounds like a good place to put a cache 23:28
grondilu 🤔 maybe, I had not thought about putting one here
the main cache I'm using is for move generation, but I'm not using it to parse games. 23:29
in any case now the speed is very decent. Usable, dare I say. 23:32
23:45 bdju left 23:46 derpydoo joined 23:48 bdju joined
timo > raku -Ilib -MChess{,::Games} -e 'say .moves>>.LAN for Chess::Games::load slurp' < resources/masters/Morphy.pgn 23:52
is this still a good snippet to check on the performance?
oh, `-I .` is better than `-I lib` 23:53
23:55 jpn joined
grondilu well, for the performance of that aspect of the library, yes. But again, this is not using moves generation, nor checking the correctness of the moves. 23:55
Just parsing moves written in so-called short-algebraic-notation. 23:56
timo OK
i'm always interested to run a quick profile on anything i can find
grondilu though I should use an other term than "parse" because there is some semantics analysis involved. 23:57
basically the point was not to check that the moves are correct, but to infer exactly what they meant.
timo the term "parse" can be used for that as well, depending on how deep the analysis gets
grondilu is gonna try to get some sleep now. 23:59
timo have a good one!