4 ms·
This is wrong. Because of the way pointers are used, Forth is both compiled and not compiled. > After the fetch and store operations are redefined for the cod
by pyinstallwoes 4y ago
This is wrong.
Because of the way pointers are used, Forth is both compiled and not compiled.
> After the fetch and store operations are redefined for the code space, the compiler, assembler, etc. are recompiled using the new definitions of fetch and store. This effectively reuses all the code of the compiler and interpreter. Then, the Forth system's code is compiled, but this version is stored in the buffer. The buffer in memory is written to disk, and ways are provided to load it temporarily into memory for testing. When the new version appears to work, it is written over the previous version.
- terminalcommand 4y agoWhat is the difference between a runtime and an interpreter? I still believe forth is interpreted. Forth uses a small set of functions in assembly as its runtime/interpeter. Your quote looks like its about bootstrapping the Forth ecosystem. After writing fetch and store operations in native assembly, you can bootstrap the forth system that is logical. This is the way Chuck Moore first used Forth anyways. He had no interpreter/compiler back than, he wrote some functions to aid him circumvent assembly and make his code portable. It is genius, but I think it's still interpreted. You can compile python to bytecode and run it in python's vm, does this mean your python code is compiled. IMHO no, it is compiled for the python vm and python vm interprets it. Same thing applies to Forth. Forth is interpreted, even if you compile and package it in a standalone executable binary.
- Jtsummers 4y agoAn interpreter interprets, typically either a byte code or textual representation version of a program or some other intermediate form (for instance, parsing to an AST and then evaluating/interpreting that versus line-by-line or token-by-token). A runtime could include an interpreter, but doesn't have to. Go includes its own runtime which handles things like scheduling goroutines and garbage collection, but it is not interpreted nor does it include an interpreter.
- terminalcommand 4y agoThis is exactly what I'm talking about. Go is a statically typed C-like compiled language. It can convert the code much or less in its entirety to machine code. Lisp and forth on the other hand cannot, I think. They need some kind of interpretation at runtime to function so dynamically. If this is not the case, please prove me wrong. The distinction between compile time vs run time bugs me a lot. I think it is easier to say forth is closer to compiled. I can kind of imagine each user defined word being translated into assembly. With lisp I am speechles.
- Jtsummers 4y agoLisp can be ahead of time compiled, being dynamically typed doesn't impact that. It does impact what gets generated by the compiler. Compiled CL code is usually "generic", it has logic inside that helps it dispatch based on the dynamic types during the runtime but this is not interpretation (in the sense meant by TCL, Python, and others). You can also specify the types and a compiler can, optionally, make (or use) more specific code which should error on a type mismatch but can run faster if you give it the correct, restricted types. As to your speechlessness regarding compiled Lisp, here's a quick example: CL-USER> (defun foo (n) (+ 1 n)) FOO CL-USER> (disassemble #'foo) ; disassembly for FOO ; Size: 35 bytes. Origin: #x53641724 ; FOO ; 24: 498B4510 MOV RAX, [R13+16] ; thread.binding-stack-pointer ; 28: 488945F8 MOV [RBP-8], RAX ; 2C: BF02000000 MOV EDI, 2 ; 31: 488BD3 MOV RDX, RBX ; 34: FF14250001A052 CALL QWORD PTR [#x52A00100] ; SB-VM::GENERIC-+ ; 3B: 488B5DF0 MOV RBX, [RBP-16] ; 3F: 488BE5 MOV RSP, RBP ; 42: F8 CLC ; 43: 5D POP RBP ; 44: C3 RET ; 45: CC10 INT3 16 ; Invalid argument count trap NIL CL-USER> (SBCL was used for the above)
- terminalcommand 4y agoI know that lisp compilers compile compute heavy trivial functions directly to machine code. But how is the output of a program containing a lisp macro for example. Let's say define a lisp macro don't call it and generate its assembly. What is the machine code output? This is the part I'm speechless about. "The logic inside that helps dispatch based on the dynamic types at runtime" is the interpreter part IMHO. Plus you need logic to add the metaprogramming elements that require you to change the code after it has been written. We need to generate an example of something we can't do in C, something which requires evaluation at runtime.