00:00:00 --- log: started forth/20.02.23 01:57:15 --- join: proteus-guy joined #forth 02:45:08 This is going to sound really stupid but how do I subscribe to comp.lang.forth with just an email address, no google account or usenet subscription? 02:45:12 Is that possible? 02:45:39 I'm assuming that would require some kind of mailing list being set up somewhere which doesn't exist but I thought I'd just ask first 02:47:26 veltas, you'd have to find some usenet email service. It's been years since I had such a thing. I expect they're out there however. 02:49:48 I think I'll wait for Google to refresh my recovery phone number 02:50:31 This whole issue is I don't want to use my gmail email (which nobody knows) for the group, but it won't let me add an alternative email to subscribe with without my recovery number first 02:50:44 And I just started beating my head against the desk and wishing it was the 90s again 02:51:05 veltas, do you find useful content on comp.lang.forth? 02:51:26 I don't know I was going to subscribe and then read content and see if it was useful/interesting 02:51:32 And then unsubscribe if not 02:52:19 It shouldn't be a huge commitment to subscribe to a newsgroup but unfortunately it is. There should be a mailing list but I suppose the transition was never prescient enough 02:52:40 it has earned a rather poor reputation I'm afraid. but, again, it's been years since I was on it. could be better. this channel was dead for a number of years but has really been quite useful for the last 2-3. wonder if it means a resurgence for forth as a technology? 02:53:28 Maybe, I can't remember where I learned about Forth but I literally learned it over the last few weeks and am trying to understand it well enough to write an 8-bit Forth ROM for the ZX Spectrum 02:53:46 That is what I am up to, pretty useless I know 02:54:30 I want to make it a 'Forth-2012 System' though, I wonder if anyone even cares about the standard 02:54:31 writing your own forth is the single most useful useless thing I think a person can do. ;-) 02:54:56 Especially for dead hardware 02:54:59 got two stacks, talk in RPN? you're a forth. that's my standard. ;-) 02:55:24 * proteus-guy isn't even aware of a Forth-2012 System. 02:55:27 I only care about it because I don't know the culture, so the standard probably understands Forth culture better than I do 02:55:38 Maybe it doesn't 02:56:02 er.... standards and good forth seem to anathema to each other in my experience. 02:56:06 They have got a locals syntax: {: :} which I think nobody actually uses and doesn't highlight correctly in my text editor 02:56:41 yeah... so locals and forth... er... hahaha generally a red flag. 02:57:10 I have had an easier time understanding the intention of words for extending the compiler in the original "Starting FORTH" PDF that's available online 02:57:14 than I have had from reading anything else 02:57:28 yep it's good. 02:58:01 It hurt my head a bit at first which is always a strong sign of a language that I need to mentally strain myself to grok it 02:58:14 The last time my head hurt learning the language it was Haskell 02:58:33 Anyway - I think making a forth for ZX Spectrum is a great way to get into forth. 02:58:51 Thanks I don't think it's a terrible way to learn it, even if the output is not really useful 02:59:26 There are already multiple FORTHs for the Spectrum, mostly from the 80s, some are actually quite good 02:59:38 the skill of getting real work out of a tiny limited system is one that will always be valuable. don't underappreciate that ability. 03:01:00 Do you think that locals are an anti-pattern in forth? 03:01:02 if you're a haskell fan then you might appreciate a forth for a TI calculator (Z-80 processor) written in scheme that a colleague did recently. 03:01:28 veltas, locals are a red flag but not always wrong. in forth you're expected to know the difference. 03:02:08 My experience so far is if I have a very short function I don't even want locals, it seems 'nicer' to just do stack operations 03:02:26 So I can imagine locals being a red flag that factorisation is needed maybe 03:02:44 check out his ti84-forth and his little z80 assembler. https://github.com/siraben 03:03:02 I have written some longer functions with loops that there weren't obvious candidates for factoring in, and where I had to work with enough variables to fancy using a couple locals 03:03:05 Okay I will check that out 03:03:27 he's a haskell/functional guy so you might appreciate his coding style. smart guy. 03:04:21 veltas, there are certainly common situations when you need more placeholders than what is convenient for two stacks. what the correct solution is in those cases is quite context sensitive. 03:07:36 Hmm 03:08:54 I think that is one thing that I noticed about Forth, that its syntax reminded me of a functional programming language's 03:09:22 Also its syntax extension ability is similar to that in other languages 03:10:10 But it's for totally different reasons, the fact that Forth is so small is really impressive in a mathematical sense because it's like we're talking in a better factored language for the computer 03:10:41 veltas, being concatenative it is actually cleaner than the prefix notation for functional style, imho. it's syntax extension ability is superior to any other I've yet encountered. that's why all good forth programs are creations of a DSL first and foremost. 03:11:29 Hmm I can't wait to apply this more seriously and create such a DSL, really see how powerful it is 03:13:21 Once you figure out how to implement your compiler words and extension words you'll be a proper forth-er and able to build all kinds of dsls quickly. enjoy. 04:01:31 --- quit: iyzsong-x (Quit: ZNC 1.7.1 - https://znc.in) 05:07:29 --- quit: X-Scale (Ping timeout: 260 seconds) 05:15:09 --- join: X-Scale` joined #forth 05:20:08 --- nick: X-Scale` -> X-Scale 05:21:00 --- join: dddddd joined #forth 05:21:35 --- join: Keshl_ joined #forth 05:22:02 --- quit: Keshl (Read error: Connection reset by peer) 05:34:52 --- quit: jsoft (Ping timeout: 258 seconds) 05:53:15 --- join: gravicappa joined #forth 06:00:24 --- join: frumbleme joined #forth 06:21:18 --- quit: frumbleme (Ping timeout: 260 seconds) 06:41:10 --- quit: X-Scale (Ping timeout: 258 seconds) 06:41:51 --- join: X-Scale` joined #forth 06:44:20 --- nick: X-Scale` -> X-Scale 07:39:23 --- quit: cp- (Quit: Disappeared in a puff of smoke) 07:39:50 --- join: cp- joined #forth 07:51:47 --- quit: cp- (Quit: Disappeared in a puff of smoke) 07:53:06 --- join: cp- joined #forth 09:15:50 --- quit: gravicappa (Read error: Connection reset by peer) 09:20:49 --- join: gravicappa joined #forth 10:23:01 --- quit: gravicappa (Ping timeout: 265 seconds) 13:36:45 --- nick: Keshl_ -> Keshl 14:07:43 --- join: KipIngram joined #forth 14:07:43 --- mode: ChanServ set +v KipIngram 14:13:57 --- quit: KipIngram (Quit: WeeChat 1.4) 14:23:43 --- join: kipingram joined #forth 14:23:43 --- mode: ChanServ set +v kipingram 14:26:22 --- quit: kipingram (Client Quit) 14:27:49 --- join: KipIngram joined #forth 14:27:49 --- mode: ChanServ set +v KipIngram 14:35:42 are there any competing exception mechanisms to ANS's throw+catch? 14:36:26 I don't love the idea of every error sharing the same handler, but I don't have a particularly better approach 14:57:30 --- join: rdrop-exit joined #forth 15:08:44 remexre, a simpler mechanism is to use addresses of fallback handlers instead of ANS style throw codes 15:13:17 hm, like separate errors into three or four categories, and e.g. jump to one on programmer errors (e.g. stack underflow), another on platform errors (e.g. SIGBUS), a third on program-specific error, etc? 15:14:01 No categories, just handlers 15:15:26 er, I meant specifying a single handler handles all the errors of a certain category 15:17:03 there are no categories, the fallback handler is the exception itself 15:17:49 if some code wants to intercept it and replace it with another handler it can 15:18:22 isn't that how ANS's works? 15:18:43 ANS uses throw codes 15:19:08 here's an example: 15:19:38 : xabort " Abort..." alert ; 15:19:58 : abort ( -- ) raise xabort ; 15:21:35 I'm possibly reading the wrong document, then? 15:21:41 http://www.forth.org/svfig/Win32Forth/DPANS94.txt 15:23:02 that's the ANS document, ANS uses throw codes, e.g. -1 for ABORT 15:23:33 okay, yeah; I'm just unfamiliar with the RAISE word 15:25:52 In ANS the "throw code" for ABORT is -1, in my example the "throw code" for ABORT is ' XABORT 15:26:28 Another example: 15:26:36 ohhhh I thought your example was an example of what was meant by throw codes 15:27:34 I'm using the address of the fallback handler for an exception, as the "throw code" of the exception 15:28:07 isn't raise foo just equivalent to ['] foo execute, though? or, how is control flow affected? 15:28:09 So if no one intercepts that exception, it will eventually execute XABORT 15:29:02 For ANS it would be equivalent to ['] xfoo throw 15:29:33 (if ANS used XTs instead of throw codes) 15:30:04 here's another example: 15:30:44 : x/0 ( -- ) " Divide by 0" alert ; 15:31:27 : example ... 0= triggers x/0 .... ; 15:31:56 : example2 ... 0<> averts x/0 .... ; 15:32:54 In the above the xt of x/0 is the "throw code" for division by zero 15:33:26 ok, I think I get that 15:33:28 what happens control-flow-wise when a fallback handler gets called? 15:34:34 If no one "catches" x/0, it eventually gets executed by the outer interpreter 15:35:34 as in after the x/0 word executes, it hits QUIT? 15:36:05 I don't have QUIT 15:36:15 : outer ( -- ? ) 15:36:28 begin token try dispatch intercept again ; compile-only 15:37:00 that... sounds like QUIT to me :P 15:37:13 close enough :) 15:38:09 The word TRY is the closest thing I have to CATCH 15:39:32 does that mark the after-x/0-return-point to be at intercept ? 15:40:28 When TRY returns it will have either 0 or an XT, intercept deals with it 15:40:36 ah 15:41:13 TRY is similar to CATCH execpt my "throw codes" are XT's 15:41:18 or 0 15:41:45 * XTs or 0 15:42:05 you can just execute it 15:42:13 ok, makes sense 15:43:09 When I need a new "throw code" I just make a new fallback exception handler definition, usually I name it x 15:43:44 xoverflow xbus xnan etc... 15:44:01 It's just a naming convention 15:44:15 okay, makes sense 15:44:54 --- join: dave0 joined #forth 15:44:54 ANS style throw codes are unecessary overhead IMHO 15:47:52 We have names and XTs, that's enough 15:48:34 Instead of saying -1 is the "throw code of abort", the XT of XABORT is the "throw code of abort" 15:49:10 though wait, how do you intercept execptions then 15:50:07 Same as ANS 15:50:34 so you'd have a CATCH, and you do a test on the XT it returns after? 15:51:25 or, a TRY I guess 15:51:33 In ANS if your intercepting an division by 0 you compare the throw code to -10, in my approach you compare the throw code to the XT of X/) 15:51:43 * X/0 15:51:52 okay, that's the part I thought was kinda gross 15:52:16 because in ANS I'll just do -10 CONSTANT exn-x/0 15:52:36 does X/ just print a "division by 0 erorr" ? 15:54:21 remexre, in my system the throw code for division by zero is ' X/0 15:54:31 (or ['] X/0) 15:55:32 dave0, you define X/0 to do whatever best suits your system 15:56:04 rdrop-exit: nice 15:56:22 recovery is something you never see in C code 15:56:28 after a fault 15:56:34 dave0, it's a fallback handler for when no one deals with the exception 15:57:13 rdrop-exit: yeah, XTs instead of magic numbers is definitely nicer, but the thing I was hoping to improve was the dance one needs to do to handle only one error 15:58:10 and to some degree, it'd be nice if there were more flexiblity, like in CL conditions 15:58:27 where your handler can say where control flow should resume at 15:59:25 that's just sugar over the basic mechanism 16:02:07 the basic mechanism boils down to unwinding the return stack to a previous point 16:02:51 and having a "register" that holds that point 16:02:53 er, for CL conditions, the interesting case is being able to say "after the condition was thrown" 16:03:09 what is CL? 16:03:27 common lisp 16:03:34 ick 16:03:46 ? 16:06:43 I haven't looked at lisp in 30 years, it's not fresh in my memory 16:09:20 The core mechanism of exception handling in Forth is very simple due to Forth having two stacks, ANS adds a little overhead with their throw codes, but it's still very basic 16:10:52 Anything more sophisticated just requires storing extra stuff in the exception frame 16:11:14 and having code that knows what to do with that extra stuff 16:13:33 Whether a more sophisticated mechanism would be worth the trouble, I'm not sure 16:14:34 CL's are mainly more useful when you want to express things like "if opening this file fails, create it and retry," or "if a divide by zero occurs, make the result 0" 16:14:42 CL's condition mechanism is* 16:15:34 None of that requires an extension of the basic mechanism 16:18:37 try / div/0 cancel 16:19:07 oops 16:19:10 where cancel moves control flow back to the place where the exception was thrown? 16:19:36 try / ['] div/0 cancel 16:19:43 doesn't have to 16:20:17 what's cancel do, then? 16:20:38 : cancel ( x1 x2 -- x1|0 ) lift <> and ;inline 16:21:04 lift? 16:21:25 lift ( x1 x2 -- x1 x1 x2 ) 16:22:20 hm, ok 16:22:33 so what I mean is more like 16:23:03 : print-file open-file dup read-file type close-file ; 16:23:21 : example-handler ." file didn't exist" restart retry ; 16:24:20 : foo ['] file-not-found ['] example-handler ['] print-file call-with-handler ; 16:24:38 where call-with-handler ( throw-code handler xt -- ) 16:24:40 that's not a fallback handler 16:25:07 correct 16:25:22 a fallback handler is what happens when no one has handled the exception and control returns to your system 16:25:49 er, yeah, this was me showcasing something you can do w/ conditions that can't be done with ANS-like exceptions (as far as I can tell) 16:26:18 sorry if I was unclear 16:26:48 --- quit: tabemann (Ping timeout: 240 seconds) 16:27:23 but you can make a normal handler as sophisticated as you want 16:28:09 sure, but it can't jump back to where the exception was thrown, unless I'm misunderstanding how it works 16:28:42 you end up at the next instruction 16:28:55 try foo zorba 16:29:04 always ends up at zorba 16:29:33 where you go from there doesn't require the exception mechanism 16:30:09 begin try foo ... again 16:30:10 yeah, I'm saying in some cases you want to continue where you threw from 16:31:54 you mean in foo ? 16:31:56 yeah 16:32:27 if somewhere deep in foo there's a recoverable error, it's nice to be able to recover from it and keep executing 16:32:44 that's what the normal mechanism does 16:32:59 keep executing as if the throw were a no-op* 16:33:48 some code had to handle the throw 16:34:23 you handle it then you move on 16:35:01 sure, but handling it unwinds the stack, no? 16:35:41 yes, you're always catching something that was thrown from a deeper level in the code 16:36:21 whereas conditions can choose to, uh, re-wind? (I guess in practice, they're probably implemented by not unwinding until after the handler runs) 16:36:32 condition handlers*, that is 16:37:29 you unwind until someone deals with it (and doesn't throw it upstairs) 16:38:18 the level dealing with it is the level that has the required context knowledge to deal with it presumably 16:38:18 but that makes the case where e.g. you want to describe how to recover from file-not-found somewhat more annoying 16:39:08 how to recover depends on higher up context knowledge 16:39:22 yeah 16:39:23 if it doesn't there's no need to throw 16:39:55 but after the higher-up code chooses how to recover (choosing a different path to open, creating the file, etc, etc) it wants to tell the lower code "now continue" 16:41:53 it still needs to open the file, so it would call open again with the new path 16:42:13 yeah, that's what the "restart retry" was about in my example 16:42:30 a loop is all that's needed 16:42:37 code that knows an exception is potentially about to be thrown can set up (named) restart points, for various actions you want to do 16:43:26 huge overhead, bigger exception frame 16:43:30 change my print-file to 16:43:44 sounds unecessary to me 16:43:45 : print-file ." this should only be printed once" open-file dup read-file type close-file ; 16:43:52 and then a loop no longer suffices 16:44:37 there are only two situations IMO 16:45:16 the code has enough context to deal with the situation, then it doesn't need to throw, or the code doesn't then it throws/ 16:45:20 . 16:47:09 exceptions are only for when the code throws up its hands 16:47:22 they are not for normal control flow 16:47:41 that's why conditions aren't called exceptions :P 16:47:50 I mean, would you make file-not-found an exception? 16:48:26 only if the file is always expected to be there 16:48:33 (as a side note, CL has warnings implemented as conditions, since the default handler just continues) 16:49:56 Lisp has a lot of constly abstractions, you can layer those on Forth's more basic mechanism's but then you get the abstraction overhead in Forth as well 16:50:05 you want the banana you get the gorilla 16:50:39 no disagreement, though as far as I know, conditions aren't significantly more expensive than normal exceptions would be 16:50:57 mainly because CL has stack unwinding implemented separately from either 16:52:10 you could do the same in Forth, not use exceptions for these "conditions" 16:52:13 like, in the implementation I've seen, the only difference is that exceptions unwind then run the handler, while conditions run the handler, which itself does the unwind 16:52:53 the main reason I haven't implemented them in forth is because any code I write is so dang ugly :P 16:53:30 because I'm passing two XTs in, and either a numeric code or another XT as well 16:53:55 down the rabbit hole of complexity 16:55:04 Forth isn't about surface simplicity 16:55:34 unlike other systems 16:56:49 Forth doesn't buy surface simplicity at the expense of more complexity under the hood 17:01:32 Forth is simple all the way down 17:03:03 sure, but conditions are very little additional code over exceptions 17:03:20 But exceptions are already expensive 17:03:41 yeah, i've avoided implementing them in the past because of that 17:05:54 I've never felt a need for anything more sophisticated 17:06:10 (or more costly) 17:07:10 the definition that throws an exception is basically saying I give up, caller(s) you deal with it 17:07:35 that's all that's needed as far I can tell 17:08:14 yeah, and conditions are letting the caller say "I'm done handling it, keep going / retry the last syscall / etc" 17:08:17 /shrug 17:09:00 That's definitely going to add complexity 17:09:47 since condition handlers run before you unwind, it's minimal 17:10:09 If a division throws a divide by zero, it's done 17:10:29 The caller can do what he wants 17:11:28 there's no need for a predefined menu of options 17:11:41 it's defined by the code that calls THROW 17:12:18 I don't want my division primitive to have that overhead 17:13:47 isn't it already having the overhead of a branch and potential call to throw, if you're not relying on some hardware exception/interrupt/etc? 17:15:17 how it does it isn't the point, the callee should be as simple as possible, since the caller is the one with the context to best know what to do 17:17:06 my point is, you're not adding much more code, you're mostly moving it from CATCH to the handler and THROW 17:18:45 It doesn't make sense to me to burden the lower level with the overhead 17:19:31 Context increases naturally as you go up 17:19:57 like, from an aesthetic or a performance perspective? because in the "simple exception" case, it'd be surprising to me if you had >10 extra instructions running 17:21:16 10 instructions is a lot in low level code, but not much in high level code 17:21:47 10 extra instructions in the throwing case*; should be 0 in the non-throwing case 17:24:27 they're still there all the time even if you only exceptionally use them 17:24:56 like in code size? sure, but they're in the THROW word? 17:30:39 People are always claiming that their pet complication has very little overhead, even if the complication isn't needed. 17:32:27 /shrug it's not *needed*, but it generalizes exceptions in a very nice way, and it makes some things a lot nicer to express 17:36:54 Exceptions are already a very general mechanism, this seems to impose a menu of predefined options on the lower level code. 17:37:17 er, no, the "menu" is presented to the handler, not the thrower 17:38:14 The situation now is that a throw just punts. 17:38:21 Sorry 17:38:33 The situation now is that a thrower just punts. 17:40:46 The smarts on what to do about it are all at a higher level. 17:42:29 Can't get a more general mechanism than that. 17:43:41 conditions have a superset of the functionality of exceptions 17:44:42 for example, in lisp, you have warnings, which are conditions, where the fallback handler does nothing (or perhaps logs it, I believe it's implementation-specific) 17:48:21 That's not a problem, the fallback is handled at the system-wide context by the outer interpreter. 17:48:56 sure, but how does the outer interpreter get control flow back to the code that signalled the warning? 17:49:05 No need 17:49:26 For example 17:50:21 If you're loading source from a file and you get a word not defined exception, you stop the load and print a message. 17:50:52 If you're typing the name interactively, you might just emit a BEEP. 17:51:51 The exception percolates to the level that knows what to do about it because it has the contextual knowledge. 17:52:58 for an example of warnings, which I don't believe you can easily do with exceptions: 17:53:16 --- join: tabemann joined #forth 17:53:57 I'm writing control code in a loop (e.g. a PID controller), and the sensor I'm reading from gets a value out of the expected range 17:55:11 ok 17:55:24 hey 17:55:29 hey 17:55:37 depending on what the sensor is, I might want to clamp it, might want to terminate execution, might want to use the last value; or (let's pretend this is the case), just ignore it 17:55:43 hiya 17:56:09 er, just ignore it == let the out-of-expected-range value be used 17:56:13 the "just ignore it" case can't be done in an exception handler 17:56:36 nor should it 17:57:20 it should be done via a defered word 17:57:45 that you set to how you want to handle it 17:58:47 no one's giving up, therefore no exception 17:59:05 exceptions are a way to punt 18:00:11 I guess... 18:00:32 though then once I have two sensors, I need two deferred words 18:00:40 (if you always deal with it the same way, you don't even need the deffered word) 18:01:11 yeah, the assumption I'm making here is that I'm controlling multiple sensors with a DO-PID-CONTROLLER word or smth 18:01:28 you only need one per sensor, if you want different behaviors vs a global behavior 18:02:04 None of that has to do with exceptions 18:02:58 like this is an example of where you can't make the code use exceptions, because they're not general enough 18:03:28 signalling a condition (instead of calling the deferred word) would be sufficient, though 18:04:01 No, it's an example where exceptions aren't needed 18:05:02 Exceptions are a heavyweight mechanism that should be avoided in most cases 18:07:12 idk, I agree in Java / C++, but ANS Forth exceptions are relatively cheap, and Lisp conditions that are handled w/out unwinding are similarly cheap 18:10:08 the major disadvantage I see in Forth and Lisp are that exception-involving control flow is more difficult to read 18:11:36 Relatively cheap is not a reason to use them inappropriately 18:12:08 I don't see this case being particularly inappropriate 18:12:58 The only reason to use an exception in real time loop is to bail out completely from the real-time loop 18:13:33 It's not a replacement for run of the mill control flow, it's a punt 18:14:04 it's panic 18:14:18 not all uses of conditions are exceptions 18:15:12 but you said they had more overhead than exceptions 18:15:28 when you're unwinding 18:16:03 so what are you doing instead of unwinding? 18:17:18 you're not just simply returning to the caller 18:17:22 from the PID controller example, I might be clamping the top-of-stack value, I might be doing a no-op, I might be logging and one of the above 18:18:26 and then I'd be returning to the caller, yeah 18:20:08 So either a regular word, or a defered word would do the job, how does a condition mechanism differ from the normal solution? 18:21:00 I don't need to copy the DO-PID-CONTROLLER code and add an extra deferred word for each sensor (or at least each case) 18:21:59 I don't get it 18:22:39 so I've got three sensors, I'd need three deferred words, right? 18:22:51 and 3 versions of DO-PID-CONTROLLER, one per deferred word 18:25:41 are you dealing with the out-of-range condition differently depending on the sensor? 18:26:18 or is it a global setting? 18:26:46 If it's global then one defered word, if it depends 18:27:02 then a jump table 18:28:23 per sensor; wdym a jump table? like "what a switch() {} statement compiles to" ? 18:28:25 --- join: boru` joined #forth 18:28:29 --- quit: boru (Disconnected by services) 18:28:31 --- nick: boru` -> boru 18:28:57 an array of XTs 18:31:23 one per sensor? 18:31:32 one XT per sensor 18:32:12 assuming you have a setting per sensor, if its a global setting you just need one XT (or a defered word) 18:32:31 I guess? seems less elegant than just signalling out of range, though 18:33:34 for example if its sensor #5 that is out of range 18:34:16 5 extreme-handler perform 18:34:39 the 5 would probably be already on the stack 18:34:44 where perform == ANS's execute? yeah 18:35:10 perform is equivalent to a @ EXECUTE 18:36:00 : extreme-handler ( sensor# -- xt ) extreme-handlers cells + ; 18:36:15 oh, yeah, forgot the @; yeah 18:36:17 sorry 18:36:31 I did mentally I mean 18:36:39 : extreme-handler ( sensor# -- xt ) cells extreme-handlers + ; 18:36:45 corrected 18:37:41 yeah, I've got an ARRAY defining word that does that automatically; but sure, makes sense 18:37:52 that's one way of dealing with it, but there are tons of other common ways 18:38:53 PERFORM used to be a common Forth primitive, not sure why they didn't standardize it 18:39:05 (maybe they did, I can't recall) 18:39:15 huh, okay 18:39:19 some Forths use the name @EXECUTE 18:39:34 I only started using Forth a year ago, and mainly learned it from the 2012 standard 18:39:41 I've always prefered the name PERFORM 18:39:53 so I don't know most things that are "used to be", heh 18:40:08 sure :) 18:41:04 I find that most of the baggage that new Forthers try to graft onto Forth from other languages unecessary pure overhead 18:41:35 There's usually a simpler Forth idiom 18:42:18 which doesn't require a new mechanism to be implemented 18:46:27 The problem with the standard is that it's complicating Forth by grafting on a lot of the cruft people are used to from other systems 18:48:08 yeah, I kinda feel like the "core" section should be a lot smaller and "core extension" should be larger 18:49:37 but for other sections, it's kinda nice that they've already got a solved, well-explored design 18:49:57 for if you want that cruft 18:51:49 It's less and less representative of what a Forth should be 18:55:10 eh, I'd be fine with these extensions, if they could be ./configure'd out (or equivalent) 18:56:23 'cause for e.g. exceptions or dynamic memory allocation, sometimes they're worth the overhead, and there's basically no reason to implement them yourself 19:01:36 exceptions are simple to implement, much of other stuff is C-oriented, there's some really ugly stuff like recognizers 19:03:04 I've no need for structs, objects, dynamic memory allocation, and the like. 19:03:15 oh, huh, yeah, I wouldn't want those... I don't think they're in the 2012 standard, though 19:03:47 structs are nice, though I usually just "define them" as a bunch of ( addr -- addr ) words with suggestive names, rather than any language support 19:05:21 I haven't looked at the standard in a while, I sometimes follow discussions on clf and /r/forth 19:06:34 Maybe I'm misrembering what they've added, or confusing what's in the standard with new stuff being discussed 19:07:22 I think the latter, though they might've dropped some stuff since ANS? idk tho 19:07:58 I've never implemented a standard compliant Forth, the closest I came was a 83S Forth a long time ago 19:09:34 The only reason for me to keep up with the standard, is to be able to understand what people are talking about in Forth discussions 19:09:45 I'm not fully standard-compliant, but I try to be "close enough" 19:10:34 I don't even try, I'm too far gone :) 19:11:42 Even my most basic words like VARIABLE are non-compliant. 19:11:59 what're you doing non-compliant there? 19:12:23 I take a size/alignment parameter 19:12:34 32-bit VARIABLE 19:12:43 16-bit VARIABLE 19:12:55 128 VARIABLE 19:13:04 oh, huh 19:13:20 I'm on ARM, so CREATE aligns for me 19:13:25 128 bytes on a 128 aligned boundary 19:13:48 My VARIABLE aligns on the size 19:14:10 64 VARIABLE 19:14:27 creates a 64 byte variable aligned on a 64 byte boundary 19:15:26 16-bit VARIABLE or 2 VARIABLE 19:15:29 huh, any particular reason for that? 19:15:48 creates a 2 byte variable aligned on a 2-byte boundary 19:16:42 The reason is that I used to have BVARIABLE, 16VARIABLE, 32VARIABLE, VARIABLE 19:16:59 then I decided it was just bad factoring to have it that way 19:17:22 I meant more for e.g. why 128 VARIABLE aligns to 128 19:17:30 instead of to your cell size 19:17:37 or some other convenient size 19:18:58 e.g. my CREATE aligns to 4 bytes, even though I've got a 64-bit cell size, because code only needs to be aligned to 4 bytes 19:19:24 (and the CPU I'm using does unaligned loads and stores, just not unaligned execution) 19:20:13 unaligned loads and stores are still slower, it also makes some other things more convenient 19:21:26 I also have an equivalent to CREATE that takes an alignment without alloting 19:22:04 it's only an extra cycle for me /shrug; I'll possibly change it later, but I've got lower-hanging fruit wrt efficiency 19:22:05 It's a factor of VARIABLE just as with typical Forth 19:23:49 It's a freebie, when I'm laying down data I usually know what alignment I'd like it to be at 19:24:24 (and what size) 19:25:38 My equiv 19:25:41 oops 19:25:56 My equivalent to CREATE is ALIGNED 19:26:09 yeah, I'd just personally make the alignment and size separate 19:26:26 I use ALIGNED for that 19:26:47 address aligned thingies 8 addresses allot 19:28:14 er, is that a code snippet? 19:28:25 (forth is the only lang I have to ask that of, heh) 19:28:45 yes, not a real one, just off the top of my head 19:30:11 but that's how I would do it in real code 19:31:53 that line creates an address aligned "thingies" and allots 8 addresses to it 19:33:18 addresses == bytes? 19:33:43 No it's the width of an address, 32 bits for example 19:33:58 oh, so "cells" in ANS 19:34:09 Not necessarily 19:34:43 It's quite common for a 64-bit Forth (i.e. cell is 8 bytes) to only use 32-bit addresses 19:35:19 @ fetches 64-bits 19:35:28 a@ fetches a 32-bit address 19:35:33 huh, I guess 19:35:42 I'm a fan of cheeky tricks with page tables, so 19:36:18 I usually keep the full width of addresses 19:37:03 My current host PC Forth has 64-bit cells but 32-bit addresses, I've no need at the moment for 64-bit addresses 19:37:57 It would just be overhead for my current needs 19:38:08 makes sense, yeah 19:38:42 especially since Forth's a language that's relatively immune to "what about when I need >4GB of memory for my program" arguments :) 19:38:54 right :) 19:39:20 So to define an address variable, I would do for example: 19:39:32 address variable thingy 19:40:17 that would give me an address-bits wide variable, aligned on an address-bits wide address 19:41:05 (not it's the address of the variable that's aligned, this has nothing to do with its actual contents) 19:41:14 *(note it's... 19:41:57 yeah 19:42:07 it basically accomplishes the same thing as: 19:42:20 address aligned thingy address allot 19:42:49 basically a size-aligned pointer variable 19:45:16 that would give me an address-bits wide variable, aligned 19:45:42 to an address-aligned address 19:46:24 (that's a more correct way of expressing it than what I said earlier) 19:49:32 gotta go, catch you later, nice chat. Keep on Forthin' :) 19:49:57 same to you! 19:55:07 --- quit: dave0 (Quit: dave's not here) 20:28:24 --- join: gravicappa joined #forth 20:30:32 --- join: iyzsong joined #forth 20:42:12 --- join: jsoft joined #forth 21:15:21 --- quit: jsoft (Ping timeout: 260 seconds) 22:09:57 --- quit: deesix (Ping timeout: 260 seconds) 22:10:01 --- quit: dddddd (Ping timeout: 240 seconds) 22:11:29 --- join: deesix joined #forth 23:59:59 --- log: ended forth/20.02.23