00:00:00 --- log: started forth/18.10.27 01:32:11 --- join: pierpal (~pierpal@95.234.60.245) joined #forth 02:11:59 --- quit: pierpal (Read error: Connection reset by peer) 02:15:25 --- join: pierpal (~pierpal@95.234.60.245) joined #forth 02:23:51 --- quit: pierpal (Read error: Connection reset by peer) 02:24:01 --- join: pierpal (~pierpal@95.234.60.245) joined #forth 02:27:12 --- quit: pierpal (Read error: Connection reset by peer) 02:30:45 --- join: pierpal (~pierpal@95.234.60.245) joined #forth 02:38:20 --- quit: pierpal (Read error: Connection reset by peer) 02:41:06 --- join: pierpal (~pierpal@95.234.60.245) joined #forth 03:29:30 KipIngram: I can't decipher your syntax. what the hell is a .<=; supposed to do, emit the value if <= and exit? is a hardcoded? 03:32:13 No. I've talked about that a few times here before. I have numerous words that look like other words with a . prefixed to the start. 03:32:19 I don't use stack comments and I've lost the code I used but it's probably something like ( N L H -- F) (the code doing `L N <= N H <= AND`) 03:32:43 When the . is used in that way it has nothing to do with output - instead it indicates that the deepest stack parameter that would normally be consumed by the word is retained. 03:33:12 So < expects two parameters a b and leavs a flag. 03:33:32 ...sounds convoluted 03:33:36 <; expects and consumes the same two parameters, but doesn't leave a flag - instead it conditionally returns. 03:33:55 .<; expects the two parameters but leaves one of them on the stack - leaves a. 03:34:17 So .< would leave the flag and only consume one of the arguments. 03:34:35 It's good when you need to make multiple comparisons with the same data - eliminates a lot of DUP calls from the code. 03:34:56 I've found it shortens and tightens my code quite a bit. 03:35:01 And this is a primitive? 03:35:06 Yes. 03:35:18 My Forth is fairly primitive heavy. 03:35:27 it kind of makes sense, but you must have a huge number of primitives 03:35:30 But I find them easy to remember because they fall into "families." 03:35:36 I would just do OVER SWAP lol 03:36:17 Sure - if I'd been gunning for the fewest primitives possible I'd have done it very differently. 03:36:33 I just wanted to wind up with very very efficient code, that's all. 03:36:36 so it's functionall equivalent to `: .<; OVER SWAP < IF RDROP THEN ;`? 03:36:53 Let me look at that for a minute. 03:36:57 I guess it does seem reasonable if you're going for a lot of primitives 03:37:11 Yes, I think so. 03:37:39 Well, I wasn't "going for a lot of primitives" so much as "tolerating a lot of primitives, as long as they're well-organized." 03:38:22 I want to be able to write short, good performance code. 03:38:34 I just found that the . prefix helped me do that in quite a few places. 03:39:41 For example if I need to compare a value to several different values for equality, it removes all the DUPs. And also .= is a shorter, faster primitive than = is, since it doesn't have to adjust the stack pointer. 03:40:10 .= just replaces b (the TOS) with a flag. 03:40:29 And the conditional returns have HUGELY shortened a lot of my definitions. 03:40:52 I tend to have reltively few IF ... THENs, and NO IF ... ELSE ... THEN 03:42:01 I still prefer quotations/anonymous functions so `if` can be postfix 03:42:27 `[ function-here ] if` 03:43:03 I think that's an interesting idea. I haven't really played with it. 03:43:21 But I see why you might like it - it sort of brings a "consistency" to the language. 03:43:45 I think reading ahead in the input stream is a little weird. 03:44:16 I mean it kind of makes sense as the input is in a buffer and all, but it's not very forth-like 03:44:23 Well, nothing actually DOES that (reads ahead). 03:44:38 But it's sort of logically there. 03:45:28 I assume your anonymous function gets compiled at comppile time, and at execution time its xt gets pushed to the stack? 03:46:32 * WilhelmVonWeiner shrugs 03:47:20 it's crc's language retro if you want to know, ask him or check the source 03:47:30 I just think of IF as compiling a conditional forward jump, with THEN defining the target. 03:47:32 Never really thought about it, long as it works i'm good 03:47:40 That's something I can wrap my brain around just fine. 03:48:07 postfix `if` just executes an XT on top of the stack if true, else it drops it 03:48:33 I think that seems less run-time efficient. 03:48:47 You have to push an xt to the stack, then decide to execute or drop it. 03:49:05 With the conventional approach you just either jump or not. 03:49:18 Less stack activity - faster code. 03:50:16 I don't know what the assembler for a conditional forward jump would look like. 03:51:06 I mean don't you have to know where the THEN continues from? 03:51:07 In mine it's just and rcx, rcx; jz 03:51:49 how do you know that without compiling everything between IF and THEN 03:51:56 Yes, at compile time IF compiles the call to (if), the runtime, and leaves space for a jump distance. 03:52:07 It leaves the address of that distance slot on the stack, along with a flag. 03:52:32 THEN confirms that flag, grabs that address, firgures out how far it is from that address to HERE, and sticks the distance in the right place. 03:52:52 THEN doesn't actually compile anything new - it just fixes up the jump IF compiled. 03:54:51 For IF ... ELSE ... THEN it's similar - IF compiles the jump and a target slot; ELSE sets that target slot but also compiles an unconditional jump and a new target slot, and THEN fixes up that second target slot. 03:55:06 A lot of the control structures in traditional FORTH get made that way. 03:55:27 BEGIN AGAIN - BEGIN just notes an address on the stack, for the start of the loop. AGAIN compiles a jump back to that address. 03:56:39 from your description I don't think a compiled word containing a quotation ( [] ) would be slower than traditional if, you're just pushing the address of an xt to the top of the stack 03:56:40 I spoke wrong above - I don't actually use and rcx, rcx; jz in my code. I do, but not across the span of IF ... THEN. 03:57:04 My (if) primitive checks toe top of stack, and if it's FALSE it adds the contents of the following instruction cell to the IP. 03:57:10 Otherwise it just steps IP over that cell. 03:57:57 I think it would be a LITTLE slower. Not so much so to rule it out if you like it - I think it's a totally acceptable approach. But you at least have to move that xt to the stack, and then remove it from the stack. 03:58:02 That's extra work. 03:59:01 Both approaches are the same up through calculating the flag. 03:59:29 Then the traditional approach calls the next instruction cell, which either increments IP or adds to IP, and the decision is all done. 04:00:54 The postfix approach has to 1) move the xt to the stack, then it executes the if primmitive which either drops the stack or executes it. Now that I'm looking at it in detail I suspect that would be similar in complexity to my (if). So maybe it's only pushing the xt to the stack that is extra - that's a very modest cost. 04:01:11 I think if you find the code easier to understand and write this way, then it's totally ok. 04:04:57 My (if) runtime primitive looks like this: and rcx, rcx; jz