00:00:00 --- log: started forth/19.10.23 00:05:19 --- quit: X-Scale (Ping timeout: 276 seconds) 00:58:14 --- join: mtsd joined #forth 00:59:00 --- join: dys joined #forth 01:52:29 --- quit: tp (Remote host closed the connection) 01:52:56 --- join: tp joined #forth 02:22:52 --- quit: rdrop-exit (Quit: Lost terminal) 02:49:36 --- join: dddddd joined #forth 03:03:27 --- join: X-Scale joined #forth 04:52:20 --- quit: Croran (Ping timeout: 245 seconds) 04:55:08 --- join: Croran joined #forth 05:24:34 --- join: iyzsong joined #forth 06:15:20 --- join: warriors joined #forth 06:15:33 --- join: cartwright joined #forth 06:43:03 --- join: rdrop-exit joined #forth 06:47:52 --- join: xek__ joined #forth 06:49:29 --- join: xek_ joined #forth 06:52:52 --- quit: xek__ (Ping timeout: 276 seconds) 07:10:22 --- quit: rdrop-exit (Quit: Lost terminal) 07:25:08 --- quit: mtsd (Quit: Leaving) 07:35:14 --- quit: iyzsong (Quit: ZNC 1.7.1 - https://znc.in) 08:00:48 --- quit: dave0 (Quit: dave's not here) 08:06:27 --- quit: reepca (Remote host closed the connection) 08:07:02 --- join: reepca joined #forth 08:38:01 --- quit: reepca (Remote host closed the connection) 08:38:35 --- join: reepca joined #forth 08:45:36 --- quit: reepca (Remote host closed the connection) 08:46:11 --- join: reepca joined #forth 08:50:51 --- join: lisbeths joined #forth 08:51:30 --- join: ryke joined #forth 08:53:25 I'm coming very close to writing my forth in assembler. I started with a javascript forth and I've been whittling down the size of mu forth for 2 years. It is hard for a younger person like me because I did not grow up learning assembly. 08:54:57 I'd urge you to do exactly that. I've had a really good experieence writing in nasm. 08:55:21 It takes a while to get it to the point where it starts to "show itself off," but once you get there it moves along quite rapidly. 08:56:07 I started with the inner interpreter and worked out - pretty quickly you have the virtual machine working. Then it's kind of a long slog working up all the words to implement the outer interpreter. 08:57:48 something deep inside of me keeps telling me that the next step beyond forth is to use registers instead of stacks 08:58:40 --- quit: reepca (Remote host closed the connection) 08:58:46 nothing I've thought of is as nice as concatenative programming so far though 08:58:58 --- join: reepca joined #forth 09:10:01 --- quit: reepca (Ping timeout: 240 seconds) 09:20:15 Well, I don't think it would really "be Forth" unless there's stack *functionality*, but hardware stacks are always possible. 09:20:29 --- quit: tp (Remote host closed the connection) 09:20:32 The GForth guys have done a lot of investigations of using more than just TOS in a register cache. 09:20:54 --- join: tp joined #forth 09:21:12 You get a big payoff from putting that topmost stack element in a register, but then you don't get much for putting more, unless you do some really fancy stuff in the compiler to avoid having to shuffles the registers around for every maneuver. 09:21:51 Say you have the top three elements in rax, rbx, rcx (for example). 09:21:54 an address register can be useful as well 09:22:31 Then if the compiler is smart enough to see DROP and just say, ok, rax isn'g being used now - now top two elements are in rbx, rcx, then DROP has no run-time effect at all; it's handled at compile time. 09:22:43 But you wind up having to have multiple versions of a lot of primitives to make that work. 09:22:56 Yes, I agree re: an address register or two. 09:23:19 I use a lot of registers for the vm internals. 09:23:49 I use a register to point to the block of the running task, so changing tasks means re-loading that register. 09:24:07 And since I developed it first on the Mac, I also have a register that points to the base of the whole system, which is where my NEXT sits. 09:24:24 The Mac executable format requires relocatability, and that was how I chose to implement it. 09:24:37 So all of my address lists are offsets from that base, rather than hard addresses. 09:24:57 I also have a stack frame mechanism, and it has a register pointer. 09:25:17 Gives a way to reference stuff in the stack in a way that doesn't change with every stack maneuver. 09:26:12 My architecture wouldn't fit very well on a 32-bit processor; it requires the additional registers that come with the x64 arch. 09:26:35 I figured they were there - I'd use them as needed. 09:26:38 the x86 assembly version of my vm uses 8 registers: https://github.com/jmf/impexus/blob/master/kernel/x86/nga-x86.retro#L32 09:26:53 I don't use all 16, but 8 isn't quite enough. 09:27:10 I'd have to give one thing or another up to make 8 be enough. 09:28:00 I've got 1) base pointer, 2) task pointer, 3) IP, 4) SP, 5) RP, 6) frame pointer, 7) tos, 8) address reg 1, 9) address reg 2. 09:28:11 So I could drop the second addr reg and fit into 8. 09:28:44 But I'm always hesitant to use SP/RSP. 09:29:03 I just leave it alone completely. I guess I could use it if I needed to. 09:29:24 Then of course you need a couple of registers as scratch for an indirect threading system. 09:29:37 To get efficient NEXT and DOCOL. 09:30:46 a register forth has register shuffling words instead of stack shuffling words. that's one thing I think we can agree on. 09:31:57 a data stack simplifies the complexity of registers at the expense of speed 09:32:24 stacks aren't necessarily slower than registers 09:32:46 ^^ 09:33:11 my friend who is an electrical engineer swears up and down they are and I don't know who to believe frankly 09:33:15 I think it depends on the application to some degree, but right - it's not just an obvious given that registers are faster. 09:33:30 I'm an EE as well, for whatever that's worth. 09:33:36 It's popularly believed that registers are faster. 09:33:53 --- join: xek__ joined #forth 09:34:08 But in some ways the deck is stacked if you're talking about implement Forth via software on a register processor. 09:34:16 The proper comparison is against hardware designed for Forth. 09:34:21 Which could have hardware stacks. 09:36:40 --- quit: xek_ (Ping timeout: 276 seconds) 09:37:27 I'm not an EE I'm a hobbyist software guy so I have no choice but to target intel 09:37:38 so it is a harder case to make to other software guys 09:40:27 all the forth people I have met make hardware and it is hard to express to them in which ways things are different in software. bosses and customers have different needs than in hardware 09:46:58 one thing that is hard to explain to forth coders is that some software people will refuse to write their own forth. There has to be a common forth that lower tier coders can build off of. It took me a while to realize that on unix the best forth for that is probably jonesforth 09:49:58 I use forth, and don't make my own hardware 09:58:27 if you are software only you may rely on cloud virtual machines that almost exclusively run intel 09:58:58 I personally don't think: forth cant run in the cloud, is true 10:01:13 How could it be true? 10:02:24 cloud = someone else's computer :) 10:08:00 cloud computers work the same but bosses tend to have anal requirements. kind of like if you want to code aviation hardware the faa has anal reqs 10:08:27 --- join: newuser|10 joined #forth 10:24:32 cloud is high security environments because of the cost in dollars per second of downtime. Think of the value of the throughput of a critical server like the value of an expensive fluid travelling through pipes driven by a realtime controlled valve 10:28:10 --- quit: dys (Ping timeout: 245 seconds) 10:38:48 an unspoken requirement of cloud computing is you may not add a new compiler unless it is well tested or audited. cloud bosses do not like custom forths even though code written in your own forth runs faster. it sucks but its a real req. so I have to sell software guys on a 64 bit jonesforth 10:41:13 --- quit: ryke (Ping timeout: 240 seconds) 10:44:07 wouldnt you have better luck with eg gforth? 10:44:30 i always thought jonesforth was a learning exercise and not intended to be an actual complete forth (although i havent read the whole thing, i might be wrong) 10:45:52 gforth ia gpl3. gpl3 has hardware restrictions on it that many forth programmers dislike. it is better for hardware vendors to use some copyleft license that is less restrictive. using gpl3 i the hardware world can be like pulling teeth depending on your boss 10:46:05 also, does anyone know of any good forth-like unix shells? i found https://bitbucket.org/cowile/forsh/src/master/ and https://min-lang.org/ but i am wondering if there are others 10:46:21 lisbeths: ahh 10:47:00 --- quit: newuser|10 (Remote host closed the connection) 10:50:18 its funny you ask because the thing that lead me to forth was I was studying the unix way of peogramming and I was looking for a shell to replace unix shell that was more suitable for longer pieces of code and I came to the conclusion that both lisp and forth serve this purpose well 10:54:02 --- quit: lisbeths (Remote host closed the connection) 10:54:14 --- join: lisbeths joined #forth 10:54:24 yeah im looking for a replacement for bash 10:54:35 i find it unusable for anything more than one liners 10:54:53 its semantics are a mess and its scoping rules are incoherent and i could basically go on about it all day 10:55:17 so im thinking it would be nice if there was something simpler 10:55:23 and i think forth would work quite well for it 10:57:25 --- quit: lisbeths (Remote host closed the connection) 10:57:41 --- join: lisbeths joined #forth 10:59:17 a unix shell needs to be able to do a few things 10:59:30 --- join: ryke joined #forth 10:59:37 it must be able to launch programs and give them strings as parameters 11:00:09 it needs to be able to redirect the input of one program or file into the output of some other program or file 11:00:53 just those two things cover nearly all of what a shell should need to be able to do 11:03:14 I have developed a method to arbitrarily change the syntax of unix shell allowing for a concatenative syntax, at the expense of speed 11:04:18 alternately you would take a language like forth, factor, or lisp, and outfit them to launch programs and redirect their inputs and outputs in a concatenative way 11:04:54 for gforth there is a word called system thay takez a string from the stack and calls that string as a command to the system shell 11:05:08 this can be done in any other unix forth via a system call 11:06:14 in short, I think the ideal solution is to take your ideal forth, and outfit it to make system calls to linux, and then you can build a wordset that can do ***anything*** that a shell can do 11:07:44 ornxka: I hope that is a thorough answer of your question 11:17:51 seems to me like a problem of choosing the wrong tool for the job 11:19:09 lisbeths: yes it is very helpful! 11:20:43 i am less interested in "building a wordset" though and more in having a drop-in shell replacement, for example, i think that the word lookup procedure for this hypothetical forth shell should look in the wordlist for each word, and then if not found look in $PATH for it, and then call the unix program found in $PATH with each element of the stack as a token 11:21:01 thus not having to define a new word for every shell program you want to call 11:22:15 min looks very good although im not sure if it supports that 11:22:23 for it to be a "drop-in replacement" wouldn't it have to support all the features and misfeatures that make shell intolerable to you, though? 11:22:59 thats a good question 11:23:04 i dont know the answer to it :p 11:23:07 i am hoping it is "no" 11:23:47 and if it invokes an executable rather than a built-in word, assuming it uses forth's postfix notation, how would it know how many arguments to pass to the program? 11:24:42 ah, that i have an answer to - you could have a special delimiter token on the stack 11:25:02 then the thing that calls unix programs will pop off the stack until it reaches the end or that token 11:25:50 so you would write "this-doesnt-get-passed nor-does-this first-arg second-arg cp" or something 11:26:12 its a bit ugly but unfortunately unix programs dont tell the shell how many arguments they need/used so you either need to write wrappers or use hacks like this hypothetical delimiter token 11:26:21 yes exactly like that 11:28:08 (and, it also gives the option of defining wrappers later, which only pop what they need off the stack and dont need the delimiter at all) 11:30:17 just seems a lot simpler to me to just understand how and when to appropriately use shell 11:31:13 by "use shell" do you mean, use a standard unix shell interpreter like bash/ash/sh/csh/etc? 11:31:19 yeah 11:39:45 --- quit: lisbeths (Read error: Connection reset by peer) 11:39:56 I've done some playing around with shell in forth stuff, but don't mind using a standard shell alongside forth 11:39:56 --- join: lisbeths joined #forth 11:42:23 so the arguments to a c program are just strings 11:42:37 yes 11:43:17 so all you need is a word that looks for a file in /bin/bash or wherever, and passes it a list of strings 11:43:40 what 11:44:03 each positional parameter is a string that may or may not contain a space 11:44:05 --- join: reepca joined #forth 11:44:27 what does it mean to look for a file in /bin/bash? /bin/bash is a file 11:44:54 i think adding support for executing shell commands wouldnt be hard for any particular forth, but i think for a replacement for a shell it would have to be able to run new commands in $PATH without having to do any work at all 11:45:10 when you type awk into your shell your shell sees it is not an absolute path, and resolves it as /bin/awk 11:45:22 you can think of it like a regex 11:45:40 it looks in any folder in your "$path" to resolve it to a literal folder name 11:45:44 it's not at all like regex 11:45:47 you're talking nonsense 11:46:08 why did i let myself get sucked into this 11:46:13 bash resolves the program name to an absolute path 11:46:24 awk maps to /bin/awk 11:46:26 yeah, it's not even remotely like regex 11:46:49 I think if I replace one string with another string that is a subset of a regex 11:46:57 s/x/y 11:47:07 hey lisbeths did you ever figure out how immediate words work in forth? 11:47:36 I can do things like this: https://gist.github.com/crcx/937ae55a2883b9f0320f82cf2c4bf6da to run unix commands and capture output as a string 11:47:41 immediate words are used when you want compile time behavior. though I call it threading time hehavior 11:48:02 do you know how IF is implemented? 11:48:33 if in most languages conditionally execute an anonymous subroutine 11:48:53 how would you write the word IF in forth? 11:49:16 I think you are just trying to prove me dumb. but I have already admitted I am dumb ^.^ 11:49:34 i'm exposing you as a troll 11:50:36 I have invested two years of my life into learning forth, whittling my forth slowly down until it is small enough to be assembler. my github shows this 11:50:57 admittedly I am dumb so it takes me longer 11:51:58 I think you are upset because I referred to the process of replacing one string with another as "like a regex" 11:52:13 sorry if I upset you 11:53:29 i'm not upset. you're asserting opinions and answers about things as though they come from a place of knowledge, and i think the receipient of these things deserves to know the level of competancy behind them 11:53:59 if yoi can prove me wrong let me know :p 11:54:15 i think i've proven enough here 11:54:23 ok 12:04:28 --- quit: reepca (Ping timeout: 252 seconds) 12:25:46 --- part: lisbeths left #forth 12:44:59 --- quit: gravicappa (Ping timeout: 268 seconds) 13:23:22 --- join: DKordic joined #forth 13:47:57 --- join: jedb_ joined #forth 13:49:01 --- quit: xek__ (Remote host closed the connection) 13:49:19 --- join: xek__ joined #forth 13:50:25 --- quit: jedb__ (Ping timeout: 240 seconds) 13:52:15 --- quit: xek__ (Read error: Connection reset by peer) 13:52:27 --- join: xek_ joined #forth 14:44:49 --- join: lisbeths joined #forth 14:45:24 There are a couple of users in this channel who have accused me of being trolls, and I have written a rebuttal video to them: https://www.youtube.com/watch?v=0NCNYZrdVxg 14:46:59 I'll be honest, I was expecting Rick Astley 14:47:18 To be concise: If I come into the forth irc channel speaking clearly and concisely, avoiding any tomfoolery, respecting when other people's expertise outranks my own, and admitting when I am wrong, then I have comitted no infringement upon the channel. I argue that those who have called me a troll are gatekeepers who are toxic to the community and who desire to prevent young people from discussing forth here. 14:49:35 lisbeths, you dont seem like a troll to me, but you do seem overly sensitive to others on IRC. If you don't like someone just ignore them or put them on ignore. 14:50:05 no one here is a gatekeeper other than those with OP status 14:52:00 lisbeths, you probably won't meet more opinionated people than on a Forth channel, they have strong opinions, some are very smart and don't tolerate anyone they see as being a fool, but who cares, it's IRC 15:05:34 --- quit: cheater (Ping timeout: 276 seconds) 15:07:08 --- join: cheater joined #forth 15:19:40 --- join: WickedShell joined #forth 15:30:01 --- quit: ryke (Ping timeout: 240 seconds) 15:41:01 --- join: reepca joined #forth 16:03:02 Getting back to the idea of a Unix shell in forth, how would this look from a user’s perspective? (E.g., what would something like `find . -name '*.retro' -print0 | xargs -0 -n 1 retro $0 >>tags` become?) 16:03:51 --- join: jedb__ joined #forth 16:06:37 --- quit: jedb_ (Ping timeout: 265 seconds) 16:10:40 --- join: dave0 joined #forth 16:35:38 I think we can agree that linux is considered to be bloated by many forth programmers. But let's assume that you were forced to write an application on top of linux that made use of linux features. As far as I know the only actual way to inferface with the linux kerenal (and thus the hardware) is linux system calls. So I would argue you should write your own forth in assembler and then add in words that perform system calls. You should 16:35:38 then identify your problem, and identify the minimum and simplest system calls necessary to solve that problem. Then you should create a wordset that is a domain specific language that interfaces with just those calls and nothing else. 16:35:57 The linux kernel is already complicated and adding unix shell to it overcomplicates it even more. Everything possible on linux should be doable through system calls. 16:36:39 system calls is the lowest level 16:38:55 talking about smart yet friendly Forth programmers, hi crc and dave0 :) 16:41:02 dave0, I once wrote a GPL universal cpu and memory burner for Linux and used the parallel port addresses directly. A programmer I didn't know rewrote it with a driver and sent the new app back to me ! 16:41:16 lisbeths: I work with forth on Unix based systems every day; I find the user;ands to be bloated, but generally useful 16:41:53 dave0: no, you can get lower (write a kernel extension and talk to the hardware directly) 16:42:15 far out! 16:42:24 Part of the design of a forth shell would be that it would need to be more useful as a unix shell than unix shell is. Otherwise it would be more sensible to use unix shell. 16:42:51 dave0: I’ve done that in the past, but it’s really easy to screw things up 16:50:25 As far as I know 90% of what a shell even does is to launch programs with strings as positional parameters, and redirect the inputs and outputs of those programs. 16:50:49 That covers most of it 16:51:34 The reason you don't have to type /usr/bin/awk every time you want to use awk is because it has "$PATH" resolution. so I would argue to be as easy to use as unix shell, path resolution would be desired. 17:01:09 There can be a stack object called parameters that is a list of strings. After the parameters is a stack object called a path which is a string that contains the filepath to a command. These two objects together on the stack form the stack object called a "command." Words can be formed to manipulate "command objects" that allow the redirection of IO. The words that form and manipulate commands should be designed to be as simple as 17:01:09 possible with little boilerplate. 17:01:31 --- quit: cheater (Ping timeout: 268 seconds) 17:03:12 --- join: cheater joined #forth 17:04:03 --- join: tabemann joined #forth 17:06:34 My little shell library (wrapping some Unix tools, and providing basic pipes) is at http://forth.works/examples/shell.retro.html but this requires a regular shell to exist 17:11:55 The smallest posix compliant shell I know of is busybox sh which is gpl 3. Rob Landley is making his own version called toybox sh under BSD license. When that is released, that should be a short diagram of what system calls are needed for which pieces of unix shell. 17:14:51 --- quit: djinni (Quit: Leaving) 17:18:37 --- join: djinni joined #forth 17:20:33 isn't toybox already used by google for android? 17:22:35 Yes but not every piece of toybox is finished. Currently they use both busybox, and the pieces of toybox that are currently finished. 17:23:08 I could go into it in depth but toybox development and the busybox controversies are a bit off topic. 17:28:26 The v6 Thompson shell might be interesting to look at as a starting point if you don’t need posix compliance 17:29:27 I think posix does not include a concatenative language so when you make your own forth shell you essentially throw posix out the window. 17:32:26 im trying "min" now which isnt really a forth shell just a concatenative programming language that also lets you easily run programs 17:32:58 I don’t mind using a regular shell; it’s easy enough to blend shell and forth 17:35:09 A forth shell shouldn't be used unless it's simpler than unix shell. 17:35:35 So as of oct 2019 it's just a nice fantasy 17:41:52 there is https://bitbucket.org/cowile/forsh/src/master/ (for gforth) 17:45:02 --- quit: warriors (Quit: Connection closed for inactivity) 17:45:25 their >|, |, |>, f>| and so on are very similar to your :pipe> and :>pipe> and such. Fundimentally you need a consise way to build a command, and a consise way to direct the inputs and outputs of that command, and you've got a basic shell 17:51:52 In terms of information theory, you can't compress the code-length of an algorithm beyond a certain size untill you lose flexibility. Forth programs are an amazing sweet-spot between the flexibility of forth programs and the length that the user has to type. I would argue that a forth shell is slightly more verbose than a unix shell for small commmands; however, for larger scripts, forth is much more versatile than the shell. The shell 17:51:52 is less flexible than forth, because it is designed to be as concise as possible for one-liners. 17:54:06 I write programs mixing shell and forth. E.g., my tool to generate a `tags` file has a bit of shell code that uses find and carts to pass files into the forth part of the same program. 17:55:27 It might not be reasonable to try to make forth be a shell. It might be more reasonable for unix shells to stay the way they are forever. The question I ask myself is, "if aliens on another planet developed computers with command prompts, how similar would those command prompts be to unix shells." 17:57:01 Their prompts may very well have things like addition and subtraction, but they would not for example have something exactly identical to awk. They may have a regular expression program with a similar idea to awk, but their program probably would not have identical syntax to awk. What that line of reasoning shows is that it may be possible to design a regex program that does awk better than awk does it's own job. And that is why I think 17:57:01 it is possible that unix shell is not the end-all-be-all for shells. 17:57:30 Unix shell is great for Unix, not necessarily anything else 17:58:12 This is why i have spent so many years studying unix shell looking for a replacement. I would like the shell that comes with unix to be a much more useful programming language, that is much simpler to learn and use. 17:58:34 I think that forth embodies "the unix way of programming" better than unix shell does. 17:58:37 My shell stuff isn’t really for interactive use. I work primarily within editors; the shell bits are to let me run external things and capture the results for later use 18:00:09 If I am to replace unix shell, then my shell needs to to a better job than she shell does its job, for say 80+% of the users of unix shell. 18:00:26 But I would be satisfied if all that happened was more people learned about forth and played with it. 18:07:59 --- quit: tabemann (Ping timeout: 240 seconds) 18:15:39 --- join: ryke joined #forth 18:21:37 --- quit: xek_ (Ping timeout: 240 seconds) 18:33:03 --- join: warriors joined #forth 19:54:24 --- join: tabemann joined #forth 20:07:51 --- quit: dave0 (Quit: dave's not here) 20:25:20 --- join: imode joined #forth 20:33:06 are compiled forths welcome? 20:37:23 I think all forths are welcome ? 20:37:52 Forth isnt exactly a 'standard' itself I believe 20:38:42 neat. I have a queue-based forth that compiles to C. I'm wondering where to take it. 20:39:48 https://hatebin.com/evcwsyoqev a sample. 20:43:42 https://repl.it/repls/MulticoloredOverjoyedSequel an example, compiled to C via a preprocessor. 20:43:59 hopefully someone who understands it will comment. I'm a Forth using technician 20:44:26 so you get the problem of moving data around, then. 20:47:28 this was originally driven by a study in queue automata, but turned into something a little more practical. manipulating linear structures gets a lot easier when you swap your working stack for a queue. 20:48:26 holding strings on the stack is cumbersome, while with a queue I can do in-place processing without having to fiddle with external memory. 21:01:45 Trying to make forth work with a queue instead of a stack hurts my brain 21:01:52 I am very interested in how that concept works 21:02:12 it helps if you get to grips with the four manipulation words. 21:02:18 dup, swap, drop, and last. 21:04:13 say for example I have the code snippet `2 3 4`. this would enqueue 2, then 3, then 4, so if I used `+` to add two numbers together, I'd dequeue 2, then dequeue 3, add them together, and enqueue 5, ending up with `6 5`. 21:04:35 to recall the result, you'd use `last`. which takes an item from the rear of the queue and moves it to the front. 21:04:54 so `6 5 last` -> `5 6` 21:05:00 have you considered using a circular queue? 21:05:10 yeah, it's already circular. 21:05:33 `6 5 last last` -> `6 5` 21:05:47 So then last is your only way to re-arrange the contents of the queue? 21:06:12 there's dup, swap, drop and last. 21:06:37 `1 2 3 swap` -> `3 2 1` 21:06:49 takes two items from the head and enqueues them swapped. 21:07:15 what does 1 2 3 4 swap result in 21:07:27 1 2 3 4 swap -> 3 4 2 1 21:07:45 so then your swap function is more like a reverse function 21:08:07 not really, no. remember, we can only enqueue things and dequeue things. 21:08:16 in order to "recall" the result of a swap, we have to do `last last`. 21:08:31 so `1 2 3 4 swap last last` -> `2 1 3 4` 21:08:49 just like you'd have with a regular stack. 21:09:13 sorry, should specify: head of the queue is on the left, rear is on the right. 21:09:51 well swap clearly doesn't switch the next two items in the queue nor does it switch the last two items in the queue so that confuses me 21:10:18 --- join: rdrop-exit joined #forth 21:10:23 `x y z w swap -> z w y x` 21:10:45 it takes the first two items in the queue, dequeues them, swaps them around, and enqueues them. 21:11:02 that's weird but ok 21:11:21 * imode shrugs. 21:11:30 it's useful in a lot of situations. 21:11:56 for instance, moving data around in the queue. `pick` and `roll`, for example, can be implemented with these four operators. 21:12:08 well pick and roll is not so necessary on a small circular queue like you have 21:12:31 we can use it to hold larger and larger items, including arrays and strings, though. 21:12:47 Yes this is a common thing in forth too 21:12:49 I've built a prefix expression evaluator using only the queue as storage. 21:13:11 forth requires external memory to reference unless you treat the data and return stack as a queue. 21:13:14 or as a tape, I suppose. 21:13:16 I wonder if you can make a circular stack such that circular queue words also work on it 21:13:59 for example, you can't store a string on the stack and perform operations on it without resorting to another temporary storage area. 21:14:27 to seek to the "middle" of a string and not destroy the characters, you'd need to push characters between stacks or memory. 21:15:25 I have a feeling that a circular stack can be made to do very similar operations to your queue 21:15:50 what would a circular stack even look like. it sounds like a queue. 21:16:43 So by a circular queue of 8 items I mean that if all 8 items contain data and you push one more object, it overwrites the object at the beginning of the queue 21:16:57 By circular queue I mean one that wraps all the way around and doesn't have a checking for overflow 21:17:04 thus it rotates like a dial 21:17:19 right. a circular buffer. that's what I'm currently using. 21:17:24 My Forths use circular stacks 21:17:40 So do some of Chuck's chips 21:18:02 I guess the way for you to think about what I am saying is that I can take your circular queue and add a forth-swap and a forth-dup to it 21:18:10 A circular stack is just a simplification of a regular stack 21:18:12 And there should also be a head++ and a head-- to rotate the queue like a dial 21:18:51 a circular stack makes alot of sense if your stack is very small and lives near hte processor, as does a circular queue 21:19:13 1. it's already circular. 2. `head++` and `head--` are `roll` and `last`, the former of which can be implemented by the latter. 3. any queue operation can be turned into a stack operation by the addition of `last`. 21:19:35 for instance, `1 2 dup last` -> `1 1 2` 21:20:04 whereas `1 2 dup` -> `1 2 1` 21:20:38 I guess what i am arguing for is that dup last should be it's own discrete words so you get the advantages of both a stack and a queue 21:20:55 yeah, I usually define it as `dup$`. 21:21:11 which is just `: dup$ dup $ ;`, where $ is `: $ last ;` 21:21:44 `swap$` has something similar, which is just `: swap $ $ ;` 21:21:53 err, `: swap$ swap $ $ ;` 21:21:54 show me how you would define a function that takes a number and doubles that number 21:23:13 : double $2 * $ ; if you don't define `*` as `multiply last`. : double $2 * ; `if you do. 21:24:01 $2 is just 2 $. it's a syntax supported by my preprocessor (which generates C code). 21:24:58 I have been toying with a variant of forth that uses registers instead of a stack 21:25:07 to square a number would just be `: square dup$ * ;` or `: square dup$ * $ ;`. I like the former, though. math ops should behave as RPN-like by default, while shuffling ops should be queue-like. 21:25:21 I don't get the point 21:25:45 I think this fellow believes that the option of the last word makes circular queues more efficient than circular stacks 21:26:10 I argue that he can make his circular queue behave both as a queue and a stack 21:26:38 a queue enables you to deal with linear data far more easily than in traditional forths. 21:26:57 and.. I don't think you get the fact that I can do that with `last`. and if you bothered to look at my code you'd see that I'm doing that. 21:27:08 I think he's arguing that using a queue allows you to perform stack juggling more efficiently for certain functions 21:27:42 imode: relax not everyone has time to "bother to look at your code" 21:28:03 your technique is very intriguing to me, though 21:28:25 it's less about efficiency and more about possibility. you can't do much with a single stack, but you can do a lot with a queue. though honestly it's more of a two-way tape.. 21:28:44 well you said earlier you "can" do it but you have to store it in some cache or some other memory location. 21:29:02 right, so not a single stack alone. you have to have pointers to external storage and such. 21:29:56 So are you arguing that your version is easier to code in, yet less efficient, or are you arguing your version is easier to code in, and also more efficient (because it doesn't have to store in a separate memory locaiton) 21:30:01 You can always have any data structures you want running atop the Forth machine, but replacing the machine's stack with something else makes no sense to me 21:30:37 it's a little more flexible is what I'm arguing. 21:31:12 it also opens the door to parallelism. you can always segment a queue into 2 or more smaller queues with delimiters. 21:32:17 Like I said you can always implement whatever you want *atop* the stack machine 21:32:33 * imode shrugs. 21:34:16 Replacing one of the stacks of the machine itself wouldn't make sense IMO 21:34:31 perhaps it's because you're used to a stack. 21:37:18 It's because they are well suited to their role in the machine's architecture 21:37:35 I don't see a justification other than a historical one. 21:38:00 well first of all i would say that if the thing you are putting data into is circular, then it makes sense to have a stack-queue hybrid 21:38:38 but secondly I think you are incorrect in that it sounds like storing data to a cache or to external storage is more expensive than having a stack/queue juggling operation that eliminates it 21:39:13 I am no expert in assembler but what I have been told it is ideal to juggle if possible verses store to ram 21:39:31 --- part: imode left #forth 21:41:01 imode just design a soft chip on an FPGA to compare a stack machine vs your 'queue' machine 21:41:13 ideally any time you have to juggle a stack or queue, there are two things you are looking for: you prefer a juggle operation that is easier to work out in your mind, and you prefer a juggle operation that is faster in terms of machine instructions 21:41:20 so an ideal juggle is both easy to do and also fast 21:43:23 juggling is overhead, you have to compare that overhead to the overhead of alternatives, in speed, resource usage, complexity, etc... 21:44:47 engineering is all about the tradeoffs 21:45:38 I guess when I say juggling I am not talking about forth programmers who like to have very few stacks. I am referring to a situation where there is no choice but to re-arrange the stack 21:46:34 ideally you try to program so that as little juggling is necessary as possible, and so that when you do juggle that the juggling is minimal 21:48:42 Yes, you try to keep the top few entries of the stack 'hot', the stack machine model is predicated on that assumption 21:49:51 The data stack is an alternative to registers 21:51:37 On a stack machine the data stack need not be in addressable RAM 21:55:47 You can think of the data stack on a stack machine as another way to organize the chip's 'register space' 21:59:32 I have been thinking about trying to make a forth that is closer to assembly than modern forth. It would still be threaded inside of a dictionary, but it would use registers instead of a stack. 21:59:35 just like the SPARC's sliding window was another way 22:01:09 Closer to which chip's assembly? 22:06:04 --- join: gravicappa joined #forth 22:08:32 What improvements are you seeking? 22:20:57 bbl 22:30:07 It just seems to me that having 8 registers named a-h is a better way of doing things 22:35:30 --- quit: dddddd (Read error: Connection reset by peer) 22:58:53 It would take it much closer to a conventional register machine model than a stack machine model, whether that leads to a better way to accomplish your goals I can't say. 23:08:33 I guess what I am trying to express is that the part about forth that I find cool is not it's stacks, the part of forth I find cool is it's threaded dictionary 23:08:53 and I think a register based forth can have things like the next function 23:18:12 What confuses me is that in intel 64 bit for example there seem to be only 16 64 bit registers. The part about it that confuses me is first of all that some of these registers are "reserved" so that you are not supposed to mess with them. That means that different architectures will have different reserved registers. What also confuses me is how two programs who take turns using the core don't write over each other's registers 23:24:26 I guess what i am after is what are called "general purpose registers" that the user may use for whatever they want 23:25:02 --- quit: warriors (Quit: Connection closed for inactivity) 23:32:52 The only thing you need for a "threaded dictionary" is an explicit or implicit "call/jsr", NEXT is just a return from subroutine, a RET/RTS instruction at the real machine level, or equivalent at the virtual machine level. 23:38:26 call is the one that points to a forth word and jsr is the one that executes a primite written in asm, correct? 23:38:29 or is it the other way around 23:39:32 Their both different mnemonics for the same function, some ISAs call the instruction "call", some call it "jsr". 23:39:58 Same with "RET" and "RTS" 23:41:40 The way I think about a threaded dictionary is that once a word is on the call stack, each word inside the definition is called. When a word is called it is either a primative or complex word. If it is a primative word it runs some assembly instructions. If it is a complex word, that complex word is pushed onto the call stack. And that's like 50% of how forth works. 23:41:51 The other 50% being stacks 23:46:26 their are different mechanics to accomplish the threading e.g. STC, ITC, DTC, TTC, etc... 23:47:58 relative to the underlying real (or sometimes virtual) machine 23:48:22 They involve different trade-offs 23:49:46 https://en.wikipedia.org/wiki/Threaded_code 23:49:57 http://www.complang.tuwien.ac.at/forth/threaded-code.html#what 23:50:41 http://www.bradrodriguez.com/papers/moving1.htm 23:51:30 If threaded code is code that results in a sequence of subroutines to be executed, can I use assembly's op codes as the subroutine primatives? 23:54:54 If you're using subroutine-threading all code is composed of instructions of the underlying machine. STC is often combined with inlining as well for short definitions. 23:56:03 If you read those three articles, I think you'll understand the different threading architecures and their tradeoffs. 23:59:59 --- log: ended forth/19.10.23