2023-06-09 05:20:46 KipIngram: Hope she's doing alright 2023-06-09 05:22:53 She is; thanks. Her vision isn't quite as good as it used to be, but she's still able to manage things pretty well. 2023-06-09 05:23:24 It's funny when we say 40 is middle-aged, because she's already shown her middle age was at least 44, so at 40 she wasn't even middle-aged 2023-06-09 05:24:05 Yeah. Well, when I was a kid I heard that average life span was around 72 years. I think it's well up from that now. 2023-06-09 05:24:12 And we see people live to 119 occasionally, so they were middle-aged at 59 2023-06-09 05:24:37 We've learned an awful lot about how our bodies tick these last few decades - makes since that would likely translate into longer life span, at least for people who pay attention to such things. 2023-06-09 05:25:19 There's a guy at Harvard named David Sinclair who's done some pretty remakrable research into longevity. 2023-06-09 05:25:32 He has a package of ideas on boosting one's longevity. 2023-06-09 05:25:48 https://www.youtube.com/watch?v=n9IxomBusuw 2023-06-09 05:26:36 He advocates certain supplements, but the primary "pole in his tent" is how you schedule your eating. Apparently confining your eating to a few hours a day and fasting the rest of the time promotes longevity. 2023-06-09 05:26:42 So much for the "many small meals a day" idea. 2023-06-09 05:26:58 I think to live a long life you need a combination of good environment, healthy attitude, and good genes. 2023-06-09 05:27:17 My wife tends to eat once a day because she is so busy at work in a kitchen all day 2023-06-09 05:27:26 According to him, triggering your body's survival mechanism (like giving it the impression you may be hurting for food) causes it to do a number of things that are good for you. 2023-06-09 05:27:56 I think she has relatively better health than me from standing up and doing an active job 2023-06-09 05:28:07 That would have to help - yes. 2023-06-09 05:28:21 We've beocme a fairly sedentary people. 2023-06-09 05:28:51 When things get back to normal (or close enough) I plan to go jogging with her again, that helps me a lot 2023-06-09 05:29:03 Although apparently jogging is not good for you, you can't win 2023-06-09 05:29:16 I think it's better than nothing 2023-06-09 05:29:35 Cool. I've been trying to jog, or at least walk, several times a week recently, but I'm not as reliable about it as I need to be. Try to move some weights around a couuple or three times a week as well. 2023-06-09 05:29:51 Better than nothing 2023-06-09 05:29:52 Nothiing terribly hard core. 2023-06-09 05:30:14 A brisk walk at lunch is good, I should do that again. I worked somewhere where everyone did this every day and I could tell it was good for me 2023-06-09 05:30:16 I've got an incline bench, some dumbells, and a curling bar. 2023-06-09 05:31:08 We have an Aldi that's maybe half a mile away - recently I've been walking over there for light grocery shopping. So that also lets me carry back whatever a buy, and somethimes that's a moderate weight. 2023-06-09 05:31:21 s/a/I/ 2023-06-09 05:31:24 KipIngram: just wait until the MIG welders come into stock there 2023-06-09 05:31:35 :-) 2023-06-09 05:32:12 There's an AutoZone on the other side of the parking lot there, but I doubt I'll be walking for my next car battery. 2023-06-09 05:38:52 unjust: Yesterday you suggested giving a BNF sort of description for what input of a complicated item might look like. I think that's at least in the zone I'm talking about. In some languages we provide struct specifications, which defines how items sit in memory. A BNF description describes what they look like in i/o form, and that would tell it how to read it when you provide it. When it writes it back 2023-06-09 05:38:53 to you, there might be "compact" form, which would just be linear without regard for layout, and you might also provide a "pretty print" specification that would describe your desired layout. 2023-06-09 05:39:04 That ought to be everything the system needed to interact with you around such things. 2023-06-09 05:42:29 It's been a long time since I've read anything about BNF related ideas. 2023-06-09 05:43:34 This is all pretty different from Forth's "one word at a time" philosophy, but I kind of see it as something that would get invoked only if treating the input one word at a time was going to produce an error. 2023-06-09 05:43:56 Exactly the same way checking whether something is a number is done only if we'd otherwise get an error. 2023-06-09 05:46:00 Also, in Chuck's earliest work, before he even had compiled definitions, his "definitions" were like macro text substitutions. That's still kind of an interesting idea. Those have kind of faded from Forth, but they still could be interesting for certain purposes. 2023-06-09 06:11:48 So, let's say we've input some complex object, had it parsed into RAM for us, and placed in something like this ring system. Now there's an item on top of the stack that points to this thing. 2023-06-09 06:12:23 There's all sorts of stuff we could do with that. For one thing, we could attach a vocabulary to that type of object, and when such a thing is on top of the stack that vocabulary could get searched first. 2023-06-09 06:13:05 Doing that in a definition would involve some cute tricks, but is at least feasible. 2023-06-09 06:13:29 That pushes it a step closer to some of the stuff I've talked about at other times. 2023-06-09 06:14:21 To get it in a definition you'd need to do something to notify the compiler than a fancy thing was going to be on the stack. 2023-06-09 06:14:37 Which you could do with a stack comment that had some smarts behind it. 2023-06-09 06:15:41 : split ( string -- ?? ) ... ; 2023-06-09 06:16:40 Maybe : string ( string -- [string]) ... ; 2023-06-09 06:17:10 Just spitballing here now. 2023-06-09 06:18:10 I've always thought having the compiler track that kind of thing would be fairly straightforward except for when paths through code that had variant results were encountered. 2023-06-09 06:18:34 Which might be as simple as IF DROP THEN. 2023-06-09 06:22:41 If the compiler came to a case it couldn't suss out, you'd have options. You could just throw an error and force the programmer to resolve that some way. Or, if you wanted to get fancy, you could create code to do something at runtime. I don't really find such things appealing, but it's a possibility. 2023-06-09 06:22:51 Because at runtime the system will know what things look like. 2023-06-09 06:25:57 KipIngram: I think Chuck accepted compilation was an outright improvement to Forth though 2023-06-09 06:26:08 Oh, it clearly is. 2023-06-09 06:26:36 A performance boost like that - kind of no way that wouldn't be "accepted." 2023-06-09 06:27:16 I think machine code macros could be faster, but they use so much more space and are so much slower to compile 2023-06-09 06:27:43 Yes - I'm not advocating them as superior to definitions in any way - just "different." 2023-06-09 06:27:56 I don't think it's just two ways of doing the same thing. 2023-06-09 06:30:02 I sort of get the impression that compilation wasn't done originally because Chuck just hadn't thought of a nice, east way to do it 2023-06-09 06:30:23 I feel sure. It was a set of ideas in progress. 2023-06-09 06:31:31 It's also interesting to see how he "tipped his hat" toward other ideas more than he did later. His confidence and certainty about things clearly grew over the years. 2023-06-09 06:32:15 Prime example, in that book he went to a fair bit of length to show how his system could be used to process infix expressions, because "lots of people wanted that." 2023-06-09 06:32:24 Later he more or less said "stop wanting that." 2023-06-09 06:33:25 It's like we kind of got to watch him grow up. 2023-06-09 06:33:52 I think his aims changed over time as well. I think it's clear that he didn't design colorForth for general appeal 2023-06-09 06:34:00 And any later stuff 2023-06-09 06:34:13 Right - he was focused on his own personal productivity by then. 2023-06-09 06:34:21 He had goals. 2023-06-09 06:34:25 I'm not sure he was interested in that 2023-06-09 06:34:52 Well, I guess he had other motivations as well. 2023-06-09 06:35:01 A craving for maximum simplicity, and so on. 2023-06-09 06:35:06 I think it's a creative outlet for him 2023-06-09 06:35:12 I don't think he's trying to be 'productive' 2023-06-09 06:35:16 I definitely understand that. 2023-06-09 06:35:23 Creating is like a drug. 2023-06-09 06:36:44 I think he is more interested in the artistic side of electric engineering and programming 2023-06-09 06:36:51 Or the aesthetic side maybe 2023-06-09 06:36:56 I buy that. 2023-06-09 06:37:15 And there's a philosophical side to it as well 2023-06-09 06:38:26 I think he also saw a lot of things he thought was wrong with mainstream development, and wanted to figure out how to do better. 2023-06-09 06:38:59 I saw that GreenArrays have dumped definitions like - to mean INVERT 2023-06-09 06:39:09 Because they decided it was too confusing 2023-06-09 06:39:19 And push/pop to mean >R and R> 2023-06-09 06:40:20 I like >r and r> better there, better than push/pop. 2023-06-09 06:40:28 More visibly descriptive. 2023-06-09 06:40:34 And shorter. 2023-06-09 06:40:44 Their rationale is that people got confused about which stack was being 'pushed' to 2023-06-09 06:40:50 Right. 2023-06-09 06:49:23 KipIngram: https://i.imgur.com/vQbAjQt.png 2023-06-09 06:49:55 Formatted output function examples, but also this demonstrates the 'fixed point' features 2023-06-09 06:50:41 Because it's typeless I don't have floats at all. You can put separators like '._ in numbers and they are just visual, they don't do anything 2023-06-09 06:51:40 This is straight out of Forth obviously 2023-06-09 06:52:03 Yeah, I've seen that kind of thing used for formatting dates, times, etc. 2023-06-09 06:52:27 And so I have format specs like "%~3f" to mean a fixed point number with 3 digits after point, and "%~5.3f" to mean one with 5 digits where I only display 3 in output 2023-06-09 06:52:32 And round the result 2023-06-09 06:53:16 I had a setup for doing that. An alternative to TYPE that would detect format fields, and for each one would convert a stack item into the string it was printing per that field's spec. 2023-06-09 06:53:18 And there are 'custom' ones which perform the same sort of features as <# #S '.' HOLD # # # #> 2023-06-09 06:53:31 It was neat - it was a little byte code interpreter that "executed" the format field. 2023-06-09 06:53:43 It used a stack cell as a "stack of bytes." 2023-06-09 06:54:00 One byte being sufficient for everything it needed to deal with. 2023-06-09 06:54:18 One byte was plenty to specify a base, or a field width, or whatever. 2023-06-09 06:54:50 I could do quite a large amount of what printf() can do, and the whole thing cost about 1300 bytes. 2023-06-09 06:55:18 Haven't put anything like that in this latest system yet. 2023-06-09 06:55:24 Also notice that %c can print more than one character 2023-06-09 07:30:37 We were talking about multi-line strings yesterday. Having some kind of support for that would give a pretty nice way to get initial content into blocks. Pre-editor. 2023-06-09 07:31:05 Very easy to add to most Forths 2023-06-09 07:31:36 I decided against using EDITOR commands for my serialisation format 2023-06-09 07:31:39 It just complicates it 2023-06-09 07:31:59 My current setup is a bit cumbersome when it comes to moving content from a vim file into blocks. My editor works on one line at a time, so at the moment I have to copy and paste it one line at a time. 2023-06-09 07:32:07 Instead I do e.g. 200 BLOCK--- and end on a single --- 2023-06-09 07:32:17 A bit painful, but it gets me there, and more and more I'm just writing it with the editor in the first place. 2023-06-09 07:32:20 And it complains if the block is too many lines or lines are too long 2023-06-09 07:32:30 Oh, that's nice. 2023-06-09 07:32:50 I write short lines these days. 2023-06-09 07:33:05 i.e. I stop when SOURCE S" ---" COMPARE 0= 2023-06-09 07:33:16 So the whole line, not just one word, must be --- 2023-06-09 07:34:06 Yeah, I ought to add something like that, that would let me copy/paste a block. 2023-06-09 07:34:19 You really should 2023-06-09 07:34:26 When just testing code I can copy/paste a block. That works fine. 2023-06-09 07:34:30 And have something to spit it out as well, and you can version-control your blocks 2023-06-09 07:34:41 I only have to do the one-line-at-a-time thing to get it into a block. 2023-06-09 07:34:44 Automate that s*** 2023-06-09 07:34:54 Yep. 2023-06-09 07:35:04 That can be my little project today. 2023-06-09 07:35:04 This is Forth, no toil allowed 2023-06-09 07:35:16 It is quite a neat tidy little utility 2023-06-09 07:35:19 Should be achievable 2023-06-09 07:35:19 :-) 2023-06-09 07:36:58 Make sure you WIPE the floor before putting the furniture in 2023-06-09 07:37:09 KipIngram: BNF came to mind because i remembered skimming over Brad Rodriguez's A BNF parser in FORTH @ https://dl.acm.org/doi/pdf/10.1145/122094.122095 2023-06-09 07:37:36 Yeah. And it is kind of standard technology in how compilers handle this sort of thing. 2023-06-09 07:37:38 unjust: Do you have github? 2023-06-09 07:38:05 veltas: yes, i starred your demo repo. my username is jhswartz there 2023-06-09 07:39:24 veltas: The way my stuff works right now, the source in a block is null-terminated, and it doesn't matter what's after that. 2023-06-09 07:39:42 That null terminates interpretation of the block. 2023-06-09 07:39:52 WORD will not advance past a null. 2023-06-09 07:40:00 unjust: I'm giving you access to what I've doodled so far for NewB, but it's obviously inconsistent and I haven't gotten anywhere with the compiler yet 2023-06-09 07:40:09 It's mostly the design I've worked on so far 2023-06-09 07:40:16 It actually gets processed twice if it's immediately following a word. 2023-06-09 07:40:24 First as the end of that word, and then as "the null word." 2023-06-09 07:40:42 But at the moment the last line of my blocks are terminated in a newline. 2023-06-09 07:40:47 veltas: thanks! 2023-06-09 07:41:42 ACTION is going for lunch 2023-06-09 07:41:57 I've considered the idea, though, of just incrementing to the next block and continuing in that situation, and using an explicit "end of source" indication. 2023-06-09 07:42:15 Possibly even allowing words to straddle a block boundary. 2023-06-09 07:42:45 In that case (straddle words) the block end would be count-based. 2023-06-09 07:43:10 I.e., >IN -> >IN 4096 mod. 2023-06-09 07:43:42 >IN 4096 / BLK +! >IN 4096 mod >IN ! 2023-06-09 07:44:12 I think that's all it would take, and it would "just work." 2023-06-09 07:45:30 Or >IN 4096 /mod >IN ! BLK +! perhaps. 2023-06-09 07:46:35 Since my block buffers are adjacent to one another, then in most cases I could just edit a range of blocks in one shot with that. 2023-06-09 07:46:46 Except for where the whole buffer array "wrapped." 2023-06-09 07:47:11 I ought to be careful, though - that would "bind me in" to adjacent buffers, and I might not want to be restricted to that. 2023-06-09 07:47:23 Plus there is that wrap case, so it's not a solution that works universally. 2023-06-09 07:48:43 BTW, I've kind of left fixed line lengths behind me now, so I no longer have any "line too long" or "too many lines" issues. Just byte count. 2023-06-09 07:49:11 In my little suite of editor words I have a word bb that tells me how many bytes are being used in a block. 2023-06-09 07:49:41 All of my editor commands are two-letter words, and all of them are one letter repeated twice. 2023-06-09 08:20:43 BTW, I would need to check this, but I think the way my line editing works, and the way I've implemented this block editor, it wouldn't let me lengthen a line past where it would push the null out of the block. 2023-06-09 08:20:56 There's logic in there for that - if it's working right then it would prevent that. 2023-06-09 08:21:09 It would just refuse to accept any more keystrokes. 2023-06-09 08:21:16 Well, any that made the line longer. 2023-06-09 08:21:30 And that's not just on the last line - it's on any line. 2023-06-09 08:22:03 Because when I edit a line, I'm really editing the "whole rest of the block." It only prints out the one line, but the rest of the stuff is shifted around as the line length changes. 2023-06-09 08:22:33 The edit buffer is the entire remainder of the block - the "printout" is up to the first newline. 2023-06-09 08:23:15 I didn't really design it with this particular application in mind, but at some point it occurred to me that it could work that way. 2023-06-09 08:23:30 If I defined the parameters to the line edit call properly. 2023-06-09 11:21:37 Ok, just wrote my own quick and dirty system for pasting into blocks: 2023-06-09 11:21:43 : newline 13 .!=; drop 10 ; ok 2023-06-09 11:21:45 : >block key 27 .=; newline over c! 1+ me ; ok 2023-06-09 11:21:47 50 block >block ok 2023-06-09 11:21:49 50 200 type ok 2023-06-09 11:21:51 50 block 200 type Operations: 2023-06-09 11:21:53 o insert(name, voc) 2023-06-09 11:21:55 o .insert(name, voc) 2023-06-09 11:21:57 o find(name, voc) 2023-06-09 11:21:59 o .wipe() 2023-06-09 11:22:01 o forget(name, voc) 2023-06-09 11:22:15 I run it, paste, then hit escape to exit. 2023-06-09 11:22:59 I should be able to do multiple pastes and it would just "carry on." 2023-06-09 11:24:09 I'll probably refine it just a bit to have it put a null termination, drop the escape and the address, and so on. 2023-06-09 11:26:42 Good. This is final: 2023-06-09 11:26:44 : newline 13 .!=; 3 - ; 2023-06-09 11:26:46 : (>block) key 27 .=; newline over c! 1+ me ; 2023-06-09 11:26:48 : >block block (>block) drop off ; 2023-06-09 11:27:18 That's a keeper. As you said, veltas, no toil allowed. 2023-06-09 11:27:37 I can then immediately say 50 ed to open it in my editor. 2023-06-09 11:28:41 what do .=; and .!=; do? 2023-06-09 11:30:31 So, =; returns if the two stack items are equal; !=; returns if they're not. The . prefix tells it to retain one otherwise dropped argument. 2023-06-09 11:30:54 So .=; tests a data value against something, returns if they match, but only drops the compare value - keeps the original data. 2023-06-09 11:31:08 I still want that keystroke if the return fails. 2023-06-09 11:31:22 Those are just two of my whole flock of conditional return words. 2023-06-09 11:31:39 That's the stuff I generated the nasm source for with Python. 2023-06-09 11:32:20 There's over a hundred of them - with and without 0 implicit argument, all comparison cases, signed and unsigned, return, double return, recurse, etc. 2023-06-09 11:32:38 Nice 2023-06-09 11:32:41 Glad it worked out 2023-06-09 11:32:47 That stuff is the heart of my control flow methodology. 2023-06-09 11:33:24 I want to write a little word now that will replace a block buffer address with the address of the terminating null. 2023-06-09 11:33:33 Then I'll be able to use this to "add to" blocks. 2023-06-09 11:35:21 : >null .c@ 0=; 1+ me ; 2023-06-09 11:36:40 So I guess that means I don't want the call to block in >block. So maybe it's >ram rather than >block. 2023-06-09 11:45:31 No - I settled on block< (overwrites from start of block) and block<< (appends). 2023-06-09 11:46:23 Now we'll see how long it is before I overwrite instead of appending. 2023-06-09 11:46:48 but, if I said bye without flushing, it wouldn't get written out. 2023-06-09 11:47:36 Might make more sense to have the more aggressive action take the longer name, but I liked mirroring Linux redirection nomenclature. 2023-06-09 11:49:12 hmm, dave gauer's forth post has finally gone through its first pass 2023-06-09 11:51:29 https://ratfactor.com/forth/the_programming_language_that_writes_itself.html 2023-06-09 12:07:45 KipIngram: so .=; is something like a macro that could (if your implementation had IF/THEN) expand to OVER = IF EXIT THEN ? 2023-06-09 12:15:39 Yes, more or less. You could implement it like that if you wanted to play with it. 2023-06-09 12:16:10 They're all primitives in my system. 2023-06-09 12:17:25 You saw that word "me" at the end of one of those definitions - that's tail recursion. It's implemented as a jump back to the most recently defined entry point. 2023-06-09 12:17:43 I can do those conditionally as well; 0=me or .!=me etc. 2023-06-09 12:18:08 And to do an extra level of return (double return) I just put two ; characters instead of one. 2023-06-09 12:18:40 .=; works for me with that definition (i have a MACRO: word that generates macros) thanks for sharing that concept 2023-06-09 12:19:28 Oh gosh. I've harped on those things endlessly. It's a wonder you guys don't roll your eyes and say "there he goes again." 2023-06-09 12:19:56 I love them - I am 100% convinced that my code is more terse and tight as a result of using them. They've changed my whole coding style. 2023-06-09 12:20:11 sometimes you've got to hear the same thing a few times before the potential benefits register 2023-06-09 12:21:15 So, really : foo ... me ; isn't any different from what you'd get with : foo ... foo ; in a more typical system. 2023-06-09 12:21:36 But... you can't then say : foo ... 0=foo ; in a typical system. 2023-06-09 12:22:05 Adopting the "me" nomenclature (which I intended to be invocative of "self" in other languages) allowed the addition of the condition cases. 2023-06-09 12:22:15 how do you keep track of the current evaluated word's entry point that's referenced by ME? 2023-06-09 12:22:20 evocative 2023-06-09 12:22:28 current @ @ 2023-06-09 12:22:45 Well, current @ @ pfa h@ ... 2023-06-09 12:23:03 There's a little diddling I have to do, but basically the same way the dictionary remembers which name is at the head of the linked list. 2023-06-09 12:23:15 So if I say 2023-06-09 12:23:25 : foo ... : bar ... me ; 2023-06-09 12:23:31 That will jump back to bar, not foo. 2023-06-09 12:24:07 So the first ... would be "loop initialization." 2023-06-09 12:24:14 I'd be more likely to write it like this, though: 2023-06-09 12:24:18 : foo ... 2023-06-09 12:24:23 : bar ... me ; 2023-06-09 12:24:56 And that ; at the end really should be [ because I don't need to compile a return there. I would need to if it were conditional, though. 2023-06-09 12:25:21 At some point I'll probably make ; smart enough to catch that for me. 2023-06-09 12:27:01 how does your : behaviour change between calls from interpret and compile modes? 2023-06-09 12:30:10 also, maybe unrelated, have you (or anyone else here) experimented with replacing parsing words with words that eat the token-on-TOS instead? ie. : FORTH-WORD ... ; vs. STOIC-WORD : ... ; ? 2023-06-09 12:38:27 Not at all - it's just immediate, that's all. 2023-06-09 12:39:00 I place the header stuff in a separate region from the definition cells, so in that foo/bar double def the two bits of ... code butt right up against one another. 2023-06-09 12:39:33 foo points at the first ... and bar points at the second. 2023-06-09 12:40:03 So when I do a whole bunch of definitions I get one big slab of code, with headers pointing into it at various places. 2023-06-09 12:40:30 No, I haven't experimented in that fashion. 2023-06-09 12:40:58 I have "reflected" a little on the notion of, if you have literal string support, something like this: 2023-06-09 12:41:08 "...code... ;" : foo 2023-06-09 12:41:28 Then you could compile "algorithmically constructed" definitions. 2023-06-09 12:41:58 That would be a rather different compiler structure, though. 2023-06-09 12:42:20 Just as easy to "algorithmically create block content" and then just compile it in the usual way. 2023-06-09 12:59:33 unjust: Putting a second : in an ongoing definition doesn't require me to "jump around" anything. 2023-06-09 12:59:44 The way it would in, say, a FIG system. 2023-06-09 13:00:20 But, the price I pay for that is that I have two HERE values to keep track of, have to use the right one for things, etc. 2023-06-09 13:01:47 In this upcoming system I'm going to have four regions. Name/header, bodies, cfa's, and pfa's. 2023-06-09 13:02:31 And on top of that I'm looking at using a hash-based approach for the name/header stuff, and it will involve two regions itself - a "string table" and the hash table. 2023-06-09 13:03:28 So when I start up I'll need to allocate five regions, copy content into them, and do an adjustment pass on the cfa and pfa tables based on where I load the bodies. 2023-06-09 13:11:52 That relocation will be simple though - on disk the tables will just have offsets - I'll just need to add the base address of the bodies to every cell of each table. 2023-06-09 13:12:05 And registers will specify where the tables are. 2023-06-09 13:12:48 And those three constitute the "runtime stuff" - the names and hash tables will get their location put into variables. 2023-06-09 13:13:03 As will the address of the disk buffers. 2023-06-09 14:44:06 drakonis: good read 2023-06-09 14:46:46 aye 2023-06-09 15:03:47 Yes it is. 2023-06-09 15:03:50 I like this: 2023-06-09 15:03:52 [1 2 3 4] [1 +] map 2023-06-09 15:03:58 That's... intuitive. 2023-06-09 15:04:04 yes. 2023-06-09 15:04:10 combinators are a boon. 2023-06-09 15:04:14 And by the way, those lists could live in this ring storage I've been talking about. 2023-06-09 15:04:24 So I could readily see working in this sort of thing. 2023-06-09 15:04:45 In fact, it's the MOST intuitive map example I've yet seen. 2023-06-09 15:06:30 Also, the point-free style seems to benefit greatly from short (even very short) definitions... 2023-06-09 15:06:32 Amen. 2023-06-09 15:06:59 map { $_ + 1 } qw[1 2 3 4] # Perl 2023-06-09 15:15:38 I like the Joy better. 2023-06-09 15:17:27 the joy of programming. 2023-06-09 15:23:16 Ok, I'm starting to think that Joy needs to go on my "list" with APL as "influence material." 2023-06-09 15:23:24 hard to beat joy's syntax in forth, considering [ and ] are already devoted to mode changes 2023-06-09 15:24:38 I'm willing to change such things if I feel like it. 2023-06-09 15:24:51 I feel no "entrapment" from the standard. 2023-06-09 15:25:08 That said, I'm certainly using [ and ] in the normal way today. 2023-06-09 15:25:24 But... they're the first thing anyone (including me) thinks about for lists. 2023-06-09 15:25:45 But, this is one reason I want to broaden my ability to handle more complex input. 2023-06-09 15:26:19 [ 1 2 3 ] might confuse Forth, but I could leave [ and ] just as they are (when they're space delimited) and still have [1, 2, 3] define a list. 2023-06-09 15:26:29 or [1 2 3] 2023-06-09 15:26:40 Or for that matter [1 2 3 ] 2023-06-09 15:26:59 It's just that opening [ that needs to be interpreted differently - it will pick up the whole structure. 2023-06-09 15:27:03 i currently use <[ and ]> as shorthand for arrays, and <{ and }> for objects. i tried a few other representations but nothing comes close to [ ] and { } - so the closest i get to the joy syntax is: <[ 1 2 3 4 ]> "1 +" MAP 2023-06-09 15:27:21 That's fine too. 2023-06-09 15:27:32 And is directly "handle-able" by Forth. 2023-06-09 15:27:37 Without any extensions. 2023-06-09 15:27:40 So, yeah. 2023-06-09 15:28:06 I'm actually ALSO using { and } in my Forth. 2023-06-09 15:28:18 And ( 2023-06-09 15:28:30 my { and } are used for locals, ie. : MAP { input process -- output } ARRAY { output } BEGIN input COUNT WHILE input POP process EVALUATE output PUSH REPEAT output REVERSE ; 2023-06-09 15:28:31 ) is looked for by ( but isn't actually a word. 2023-06-09 15:28:47 My { and } are for opening and closing stack frames. 2023-06-09 15:29:03 Which is the extent to which I approach "locals." 2023-06-09 15:29:20 They let me treat cells in the stack in a "local variable ish" kind of way. 2023-06-09 15:29:39 Though more often they'd qualify as parameters rather than locals. 2023-06-09 15:30:19 I started out referencing deeper levels of the stack by offsetting from the stack pointer. 2023-06-09 15:30:35 But that means references to the same cell change as the stack pointer moves around. 2023-06-09 15:30:37 so it allows you to reserve N cells on the stack in the same way C does for automatic variables? 2023-06-09 15:30:59 All in the world { does is copy the stack pointer into a "frame pointer" and I then use IT as my index base. 2023-06-09 15:31:08 So references stay put, even as the stack pointer moves around. 2023-06-09 15:31:39 And it has a profound fringe benefit - } restores the stack pointer exactly where it was on {, though I can change that by the parameter I pass }. 2023-06-09 15:32:04 is the source for your forth system ever getting published? 2023-06-09 15:32:05 So if the code I call inside { ... } can wind up leaving different amounts of stuff on the stack, it doesn't matter - } will still clean everything up perfectly. 2023-06-09 15:32:17 Sometimes I open a frame just for that benefit and don't even use the cell refernce words. 2023-06-09 15:32:45 Yes, I intend to, but I'm still not ready yet. 2023-06-09 15:33:05 I want to feel like I've "finished it" - I'd be annoyed to publish it and have someone else finish it before I did. 2023-06-09 15:33:32 unjust: No, it doesn't reserve anything. 2023-06-09 15:33:37 Just saves a copy of the stack pointer. 2023-06-09 15:33:45 Then } can DROP some extra if I want to. 2023-06-09 15:33:56 Normally that would be used to remove parameters from the stack. 2023-06-09 15:34:23 Example - this is stupid, but illustrative. 2023-06-09 15:35:02 : my_+ ( a b -- a+b) { s1 @ s0 @ + s1 ! 1 } ; 2023-06-09 15:35:19 We've put the result in the a cell - the 1 } drops the b cell. 2023-06-09 15:35:42 Or 2023-06-09 15:36:04 : my_+ { s0 @ s1 +! 1 } ; 2023-06-09 15:36:48 I could have left out the s0 @ - that value is already right there for the +!. 2023-06-09 15:36:58 : my_+ { s1 +! 1 } ; 2023-06-09 15:37:20 Like I said, not code anyone would ever write. 2023-06-09 15:37:27 It's more useful when there are more parameters. 2023-06-09 15:37:59 My existing implementation of EXPECT is eventually intended to support command history, and first thing you know you have five or six active values on the stack. 2023-06-09 15:38:31 I support s0 through s5 currently. 2023-06-09 15:38:53 I didn't want the inefficiency of a generic word that took a numeric parameter. 2023-06-09 15:39:17 Such a word would be like PICK, except it returns the address of the cell instead of the content. 2023-06-09 15:54:59 Oh, I didn't know Chuck worked at SLAC. 2023-06-09 16:44:54 You know, this ring structure for transient items could also store a definition. 2023-06-09 16:45:05 That starts to make something like that map example closer to real. 2023-06-09 16:45:29 In the design I'm planning you couldn't execute it with the standard EXECUTE, because it wouldn't have an index in the CFA and PFA tables. 2023-06-09 16:45:49 But you could still have a word that would execute such a thing. It would just have to get to it in a different way. 2023-06-09 16:46:43 So something like this (to adopt notation close to unjust's): 2023-06-09 16:47:02 <[ 1 2 3 4 5 ]> <{ 1 + }> map 2023-06-09 16:47:07 could certainly work. 2023-06-09 16:48:15 And wouldn't alter the dictionary in any way. 2023-06-09 16:48:58 The code inside <{ }> would only be able to CALL dictionary words, though. 2023-06-09 16:49:37 MAP could do something special to get us to that code, but once it handed control to it, thinks would have to work in a standard way. 2023-06-09 16:54:16 interesting to see <{ }> used in that way, i've been using that notation to create an object (as in a bunch of attributes (key: value pairs)) 2023-06-09 16:56:32 so <{ "a" 1 "b" 2 "c" 3 }> is a roundabout way of doing saying: "a" 1 "b" 2 "c" 3 6 :OBJECT ( :OBJECT expects an even numbered cell count on the top of the stack to build the OBJECT with ) 2023-06-09 16:57:35 I just needed a way to differentiate code from a string. 2023-06-09 16:57:52 " ..." would just put a string item handle on the stack. 2023-06-09 16:58:11 TCL just goes "everything is a string" 2023-06-09 16:58:12 But in my example <{ would cause compilation. 2023-06-09 16:58:32 But in Forth there's a difference between interpreting and compiling. 2023-06-09 16:59:14 }> would add the return. 2023-06-09 17:00:12 I think <{ would just set STATE, save the compilation pointer on the return stack, and aim it at the temporary item space. Then }> would pop the compile pointer back from the return stack. 2023-06-09 17:00:14 i guess you could also make MAP take an input list/array/sequence and an execution token ... <[ 1 2 3 4 ]> ' 1+ MAP 2023-06-09 17:01:28 Well, it's a bit tricky. That whole idea's probably no good. 2023-06-09 17:02:46 That unnamed definition is really LIKE a string payload and would actually need to go inline, just like string data, wouldn't it? 2023-06-09 17:03:19 So it wouldn't actually be stored in the ring. 2023-06-09 17:06:25 Yes. I think you'd want that to work as well. 2023-06-09 17:06:51 Just a matter of whether you want to give the code a name or not. 2023-06-09 17:07:04 I.e., do you factor that code out. 2023-06-09 17:07:45 What does ' do if you use it in a definition, in the standard? 2023-06-09 17:07:57 Does it do its thing at compile time or runtime? 2023-06-09 17:08:11 Do we also have ['] ? 2023-06-09 17:08:50 ans has both ' and ['] 2023-06-09 17:09:00 Ok, then I think here we'd want ['] 2023-06-09 17:09:09 In your example right there. 2023-06-09 17:09:23 We want to ' the word that's next in the definition. 2023-06-09 17:09:32 Not whatever happens to come along next at runtime.