2024-09-08 00:11:03 That's a good point xentrac, re 32-bit global reg on AMD64 2024-09-08 01:31:43 ACTION reran the benchmarks under his FreeBSD box, results at http://forth.works/share/JMKoa1uTC.txt 2024-09-08 09:20:06 crc: And there's people who think you shouldn't hand-write assembly ever now because compilers are so good 2024-09-08 09:24:16 Was this using GCC 14? 2024-09-08 09:25:06 Might be worth trying clang too 2024-09-08 09:26:24 Or profile-guided optimisation 2024-09-08 09:26:59 But I think it's clear the asm is king for now 2024-09-08 17:30:57 It's the only way I'll ever write a Forth system again. It's the only way I see to guarantee that the registers are being used exactly the way I want them to be. 2024-09-08 17:31:39 I think the "compilers are so good" argument makes sense for many many applications, but in the case of crafting a Forth system you've got a very specific target, and I don't think any compiler could beat careful hand optimization of those lowest layers of the architecture. 2024-09-08 17:33:21 That core architecture is simple enough that you can hold it in your mind completely - it's not like a general application with more moving parts than you can keep up with. 2024-09-08 18:10:45 people always say that, if its true, then remove the assembly from V8 and see how fast the web goes now 2024-09-08 18:10:56 or any JIT 2024-09-08 18:11:20 most of luajit is in assembly as well 2024-09-08 18:39:07 well, what compilers are so good at is not writing the software in the first place, but rather allowing you to change it 2024-09-08 18:42:57 the LuaJIT assembly is pretty interesting. it looks like this: 2024-09-08 18:43:11 static void build_subroutines(BuildCtx *ctx) 2024-09-08 18:43:11 { 2024-09-08 18:43:11 |.code_sub 2024-09-08 18:43:22 |->vm_returnp: 2024-09-08 18:43:23 | test PC, FRAME_P 2024-09-08 18:43:39 | mov GL:RB, L:RB->glref 2024-09-08 18:44:09 that's from src/vm_x86.dasc 2024-09-08 18:45:22 the *.dasc files add up to 36552 lines. sloccount says there are 71991 lines of C, not counting the comments 2024-09-08 18:45:44 this is in luajit-2.1.0~beta3+git20220320+dfsg 2024-09-08 18:46:41 so a fair amount of LuaJIT is in assembly, but only like a third of it 2024-09-08 18:51:34 there's also a fair bit of LuaJIT that's actually in Lua, like 13101 lines of code 2024-09-08 18:53:18 and I think if you're considering the code LuaJIT is running for some platform in particular, the proportions favor C more heavily. ./src/vm_x64.dasc is 4936 lines, and all the other *.dasc files are for other platforms. but only 10528 of those 71991 lines of C are in src/*_mips* src/*_ppc* src/*_arm* (at C level, the amd64 code is unified with the i386 code in *_x86*) 2024-09-08 18:54:02 so on this amd64 laptop, the LuaJIT I'm running is something like 60000 lines of C, 13000 lines of Lua, and 5000 lines of assembly 2024-09-08 18:54:55 you could maybe make a reasonable argument that *this* C is really assembly in disguise: 2024-09-08 18:55:04 *mxp++ = XI_MOVmi; 2024-09-08 18:55:04 *mxp++ = MODRM(XM_OFS8, 0, RID_ESP); 2024-09-08 18:55:54 but that's only lj_asm_x86.h, which is still under 3kloc. 2024-09-08 19:09:34 so I think that, of the LuaJIT VM code on a given platform like my laptop, about 90% is written in C or Lua (a lot of the Lua is platform-specific too), and only about 10% is assembly 2024-09-08 19:09:38 not most of it 2024-09-08 19:10:31 on the other hand, in some sense, all of the JIT-compiled code is "in assembly" because LuaJIT compiled it from Lua to assembly before running it 2024-09-08 19:17:51 compilers are great for probably 95% of software 2024-09-08 19:17:54 maybe more 2024-09-08 19:58:01 super interesting xentrac 2024-09-08 19:58:16 you could've just gone to github though 2024-09-08 20:00:55 there's also the dynasm aspect of it 2024-09-08 20:52:23 When should interpreter emit spaces? GForth seems to add one space after your input, and another before 'ok' 2024-09-08 20:52:54 Which when there's no output means 'ok' has two spaces in front of it 2024-09-08 20:53:15 And I'm okay with this, it seems sensible, any other conventions? 2024-09-08 20:54:28 I've also seen people put ok on the next line, like a normal prompt 2024-09-08 20:56:23 Like Open Firmware https://www.youtube.com/watch?v=KVSHNGv_Kzs 2024-09-08 21:10:54 nmz: github thinks luajit is 0% assembly though 2024-09-08 21:11:28 because it doesn't recognize .dasc 2024-09-08 21:11:35 the dynasm directory is only 2095 lines of C 2024-09-08 21:14:00 veltas: GForth's convention seems good, PFE seems to conditionally emit a space before . if it hasn't emitted anything 2024-09-08 21:15:29 PForth puts four spaces before "ok" and then prints the stack and base on another line 2024-09-08 21:17:58 F83 seems to do the same thing as GForth 2024-09-08 21:18:34 The GForth development snapshots now print the stack at the bottom of the terminal in a status bar by default 2024-09-08 21:18:42 oh nice 2024-09-08 21:19:03 a thing I didn't realize at first was that the Forth convention is to print a newline at the *beginning* of each line rather than the *end* 2024-09-08 21:19:06 Ah, that is nice. 2024-09-08 21:19:12 I'm not really a fan, I prefer more minimal UI, but you can disable it easily 2024-09-08 21:19:22 I'd like a dev environment that had that info somewhere. 2024-09-08 21:19:34 Along with selected memory locations, etc. 2024-09-08 21:19:37 does it display base too? 2024-09-08 21:19:38 Call stack. 2024-09-08 21:19:48 That would be a good one to monitor. 2024-09-08 21:19:49 xentrac: It displays search order and current wordlist 2024-09-08 21:19:54 Maybe base I don't know 2024-09-08 21:20:05 KipIngram: maybe the results of calling some selected arbitrary functions? 2024-09-08 21:20:10 Try it out if you're interested, it's very different to 0.7.3 2024-09-08 21:20:35 I somehow had the impression GForth had gone dormant 2024-09-08 21:20:49 Yeah that will happen when you don't do releases for over a decade 2024-09-08 21:20:58 But it's actively worked on 2024-09-08 21:21:25 I think the GForth/F83 convention is the simplest one that gives you an understandable display 2024-09-08 21:22:36 you could omit one space or the other and get either 65 emit Aok or 65 emitA ok 2024-09-08 21:22:57 actually probably bolding the input or the output would be helpful now that I think about it 2024-09-08 21:23:41 I agree, about F83 2024-09-08 21:24:17 somewhere PFE is conditionally emitting a space so you get: 2024-09-08 21:24:31 KipIngram: I'd probably write a .I word e.g. print info, with all that stuff 2024-09-08 21:24:41 3 4 + . 7 ok 2024-09-08 21:24:42 Just dump a load of useful shit 2024-09-08 21:24:43 but 2024-09-08 21:24:52 3 4 + ok 2024-09-08 21:25:48 I feel like that conditional space could probably lead to confusion somewhere about what your code actually output, but I haven't found a case yet 2024-09-08 21:26:28 I have to guess it's possible via some complexity that I wouldn't want in a Forth 2024-09-08 21:26:55 what, the conditional space? 2024-09-08 21:26:59 Yeah 2024-09-08 21:27:09 If I had to implement this I would have TYPE write TRUE to a var to track if output occurs, and clear it after receiving each line 2024-09-08 21:27:21 yeah. or emit 2024-09-08 21:27:35 But it already is just adding complexity for little value 2024-09-08 21:27:36 depending on which one is implemented in terms of the other 2024-09-08 21:28:30 I tend to prefer 10% of code with 90% of the functionality 2024-09-08 21:29:12 Emacs does something like that for deactivating the "region" (selection). there's a variable "deactivate-mark" which is set to false (nil) before every command and true by anything that modifies the buffer, and the command loop checks it after the command 2024-09-08 21:35:40 In general I think it's clear that a lot of our programming interfaces are designed under constraints that make sense for teletypes, 1200-baud connections, or 80×24 screens, and that no longer having those constraints opens up many possibilities we didn't have before. Many of those possibilities are of course worse, adding distraction rather than focus and power. But it would be an impossibly strange 2024-09-08 21:35:46 coincidence if the optimal computer interface happened to be one within the small space of possibilities you can manage at 1200 baud 2024-09-08 21:36:52 either for some kind of average over people in general, or for one particular person 2024-09-08 21:38:41 (maybe minimax is a better aggregate function than average over people) 2024-09-08 21:42:40 newspapers typically wrap well below 80 columns 2024-09-08 21:45:17 yeah; usually in code our columns are much narrower than 80 or 64 columns for readability 2024-09-08 21:45:33 because we put indentation on the left 2024-09-08 22:08:37 No it actually turns out 64x16 is the perfect source screen size, proven by scientists and everything ;) 2024-09-08 22:09:02 source: I discovered this in a dream 2024-09-08 22:16:28 :-) 2024-09-08 22:20:43 In konilo, I have a `sys:info` word that displays some system status information (free/used memory, stack depth, block number currently loaded in the editor) 2024-09-08 22:22:15 for retroforth I have a version of the repl that shows this information as well as the top few stack items (including strings, where the addresses map to pointers in the temporary string buffers), and a few user selectable variables to watch 2024-09-08 22:22:27 that sounds useful. where do you show it? 2024-09-08 22:26:04 in konilo, it's shown in the editor (optionally); in the advanced repl for retro, it's shown on the left (this requires a terminal with at least 100 columns) 2024-09-08 22:27:55 zsh users seem to like to put parts of their prompt in the right margin 2024-09-08 22:29:07 GhostScript doesn't by default display the stack, but it does display the number of items on the stack if nonempty: GS> if empty, GS<39> if nonempty 2024-09-08 22:30:41 and inside {} (the PostScript version of RetroForth's quotation) it doesn't display a prompt at all 2024-09-08 22:30:41 https://asciinema.org/a/kn7mgi29GrXI7pwAmCMLYuVX7 shows retro's in action 2024-09-08 22:32:30 that's a pretty nice interface. I especially like 'Base watch 2024-09-08 22:32:40 how do you like asciinema? 2024-09-08 22:32:58 I find it very useful for things like this 2024-09-08 22:34:57 with respect to the screen repaints, I was thinking about doing a curses-like thing in Forth for wmaze, keeping in memory the previous and new screen contents and using that to compute the necessary updates 2024-09-08 22:35:34 because when I tried to upload the first versions of https://asciinema.org/a/672405 the asciinema was too large! 2024-09-08 22:36:46 particularly since I already had the desired screen contents in memory 2024-09-08 22:37:29 but I ended up just using a special-purpose hack of both updating the desired screen contents and spitting out escape sequences and drawn characters in draw-dude and erase-dude 2024-09-08 22:38:21 also I kept track of the current color to avoid emitting redundant escape sequences for that 2024-09-08 22:39:25 I've run into that with longer things. Most of my stuff is fairly short demonstrations. 2024-09-08 22:40:08 that's what it's best for. I think often asciinema would benefit from a voiceover 2024-09-08 22:41:17 for bigger things, I can self-host the asciimena recording 2024-09-08 22:43:18 one of my son's projects is a tool to convert asciinema recordings into a video format (mp4 I think?) so we can add voiceover 2024-09-08 22:44:14 you could probably just add LPC-21 or even Opus voice packets to the asciinema format without expanding it much 2024-09-08 22:46:07 try arecord foo.wav; sox foo.wav foo.lpc; ls -l foo.{wav,lpc}; play foo.wav foo.lpc 2024-09-08 22:47:02 sorry, "LPC-10" 2024-09-08 22:47:07 LPC-10 is 300 bytes per second 2024-09-08 22:47:23 gzip eliminates the bandwidth of the redundant screen updates 2024-09-08 22:47:42 300B/s is very impressive for audio 2024-09-08 22:48:43 im seeing 2.4kbit here 2024-09-08 22:49:01 yeah that adds up 2024-09-08 22:49:03 impressive 2024-09-08 22:50:32 ACTION will look into this (openbsd doesn't have an `arecord` package) 2024-09-08 22:51:09 aucat probably 2024-09-08 22:51:30 it makes sense because you can get away with absolutely horrendous audio quality for speech 2024-09-08 22:51:35 aucat -o foo.wav 2024-09-08 22:51:37 and people can still tell what you're saying 2024-09-08 23:12:38 yeah, sorry for my thick Linux accent 2024-09-08 23:13:09 LPC-10 is definitely not optimally comprehensible, and sounds noticeably robotic 2024-09-08 23:15:53 I tried 2ffmpeg -i tmp.wav -c:a libopus -b:a 2400 tmp.opus, but the output file was actually 5600 bits per second and therefore 700 bytes per second, and it sounded noticeably worse 2024-09-08 23:15:57 oops 2024-09-08 23:16:17 I tried 2ffmpeg -i tmp.wav -c:a libopus -b:a 2400 tmp.opus0, but the output file was actually 5600 bits per second and therefore 700 bytes per second, and it sounded noticeably worse 2024-09-08 23:16:21 ugh 2024-09-08 23:18:19 opus has to get to 1200 bytes per second before reaching the same quality 2024-09-08 23:18:30 codec2 might be another good option 2024-09-08 23:35:29 here's a command line to test with codec2 (using only sox and codec2 programs, no ALSA): 2024-09-08 23:35:35 sox foo.wav -t raw -r 8000 -c 1 -e signed-integer -b 16 - | c2enc 1200 - - | c2dec 1200 - - | play -t raw -r 8000 -c 1 -e signed-integer -b 16 - 2024-09-08 23:36:01 it seems to have sound quality roughly as good as LPC-10, but at half the size (150 bytes per second) 2024-09-08 23:37:01 it has modes that go down to 450 bits per second but the quality is unsurprisingly much worse 2024-09-08 23:39:18 hmm, no, actually that's *not* half the size. maybe I'm using it wrong 2024-09-08 23:44:52 oh, yes it is. I was just confused. But in my test it was closer to 191 bytes per second 2024-09-08 23:46:26 oh, no, exactly 150. I'll just stop talking until I figure things out