News for hackers. Stuff that matters.
Re:Bootstrapping a Forth in 40 lines of Lua code (2008) by MaxBarraclough on Monday September 14, 2020 @02:09PM (#24473208)
I think I follow, but it seems rather fuzzy. Compile-time functionality doesn't strike me as really extending the language.

How about BOOST_SCOPE_EXIT in C++? [0] Is it extending the language, or just a trivial macro-based hack on RAII? What's the difference?

My other issue with it is that the major features of programming languages that people actually care about, aren't the kinds of things you can implement with clever macros. They tend to rely on serious engineering.

Even in a highly extensible language, you can't easily throw together features like industry-strength garbage collection, or a type system, or borrower-checking. (I considered listing formal verification but that would be unfair, it can't really be added to an existing language.) These things are implemented by compiler engineers, and always will be. (If I'm mistaken about that, and am underestimating anything, I'd be interested to know, but I don't think I am.)

What's the 'killer example' of LISP macros? I can see a pretty neat example at [1].

[0] https://www.boost.org/doc/libs/release/libs/scope_exit/doc/h...

[1] https://docs.racket-lang.org/guide/pattern-macros.html#%28pa...

Re:Bootstrapping a Forth in 40 lines of Lua code (2008) by kmill on Monday September 14, 2020 @04:07PM (#24474517)
You can add garbage collection to Forth, but for the trivial reason that Forth is a low-level virtual machine to which you can add instructions/words for managed objects, and then you can add some words to help you interact with them more ergonomically -- words that run at compile time to change how code is being compiled. I don't think it's right to think of Forth as a "language" per se, although it's true there is a certain language that Forth programs tend to be written in, the one people call reverse-polish and concatenative.

I can't say anything about adding a type system, because it's unclear what sort of type system would even apply here. But at least in Common Lisp (which incidentally already has a type system), I think the way you'd do it is create your own front-end that interprets and checks all the typing/borrowing information and then passes this to the usual compiler. There's a long tradition in Lisps to define interpreters that extend the base language in some way.

SBCL even lets you hook into the compiler, and I saw some article about someone adding vectorization to SBCL using only user-level code.

Regarding BOOST_SCOPE_EXIT, it's yes or no depending on what extending the language means to you. I think it's more useful to use a definition where the answer is 'yes.' It's true that C macros are not a very powerful interface for language extension, though.

Also, it seems like you're saying that "extensible" means "easily extended" or "doesn't take serious engineering." It just means you can extend it (and, I'd add, in a principled way). Writing good Lisp macros can take serious engineering, but also there are other ways to extend Lisp.

In Lisp, you can (and do) define pattern match destructuring and lvalue assignments entirely using macros. These are features that require a new edition of a language standard, usually.

Re:Bootstrapping a Forth in 40 lines of Lua code (2008) by MaxBarraclough on Monday September 14, 2020 @04:59PM (#24475086)
> You can add garbage collection to Forth

Sure, but to do this properly you'd need to get your hands dirty with the implementation. Garbage collection doesn't work well as a bolted-on library, it needs to be handled in the language implementation. Forth is no different from any other language in that regard.

> I can't say anything about adding a type system, because it's unclear what sort of type system would even apply here.

It's directly analogous to static type-checking in a 'normal' programming-language, except we use the stack for accepting parameters and for returning values.

It would ensure each word manipulates the stack in the expected way, ensuring that the appropriate number of elements are consumed and pushed, and that each element is treated as being the correct kind of data (type-checking should fail if you attempt to dereference an integer).

This has been done in the Kitten programming language. [0] Java bytecode verifiers do something similar.

> SBCL even lets you hook into the compiler, and I saw some article about someone adding vectorization to SBCL using only user-level code.

Neat. I like the idea of advanced optimisations as libraries, sounds like a good research topic.

> it seems like you're saying that "extensible" means "easily extended" or "doesn't take serious engineering." It just means you can extend it (and, I'd add, in a principled way)

Perhaps I seem dismissive, but it just doesn't seem to me like many serious language features can be done properly in extensible languages.

The latest major features in mainstream programming languages are await/async and borrower-checking. I imagine it might be possible to implement await/async using Lisp macros, but I really doubt the same goes for borrower-checking.

> In Lisp, you can (and do) define pattern match destructuring and lvalue assignments entirely using macros.

That's pretty impressive, but it still seems that there are plenty of useful language-extensions that can't practically be implemented in extensible languages.

[0] https://kittenlang.org/

Re:Bootstrapping a Forth in 40 lines of Lua code (2008) by kmill on Monday September 14, 2020 @05:55PM (#24475587)
You seem to be thinking about Forth-the-language, and I've tried to be clear that Forth is referring to a way of programming where you extend the machine, which seems to be what Chuck Moore has meant by Forth. Your program is a language implementation, defining a language in which you can describe the program in the best way. There is no avoiding getting your hands dirty with the implementation. No abstraction layers between your program and the machine.

You can add garbage collection because the Forth program is a language implementation. It probably won't look exactly like ANSI Forth in the end, but that's (theoretically though potentially not in practice) ok.

> It's directly analogous to static type-checking in a 'normal' programming-language, except we use the stack for accepting parameters and for returning values.

I'm familiar with type systems for stack languages, but the issue is that this only really could apply to a standardized Forth language. Forth is only incidentally concatenative and stack-based --- this just happens to have both a simple implementation and has good compositional properties. There is nothing stopping you from introducing new programming models in a Forth, and the article gives a few examples. You can add arbitrary bytecode interpreters to a Forth, for example, and easily make it interoperable with the threaded interpreter in the base Forth. Nothing stopping you from adding words so your Forth feels like a register machine, either. It's because of this that any sort of type system seems doomed (other than one that describes state transitions of the CPU...).

> Perhaps I seem dismissive ...

I sort of don't see the point of saying "it's not really extensible if I can't extend it in all possible ways." In any case, Forth and Lisp are, for trivial reasons, languages that let you embed arbitrary other languages within them (it's about as exciting as how Turing completeness seems to be easy to meet -- which is to say, not very). Worst case, the cost is implementing a whole compiler or interpreter for said language, but, still, it's possible. Common Lisp gives you many hooks to change low level behaviors, so there is usually a better way than this worst case.

Something like borrow checking, though, is a pervasive new feature. The issue is that everything needs to know about how ownership is transferred. It's no different from, even in C, changing some basic struct the whole application uses and then having to update everything to account for it. You could add borrow checking to Common Lisp, but it would have to be in demarcated areas in which borrow checking is being done, and, like Rust, you'd have to figure out an 'unsafe' to be able to use all the Lisp (respectively, C and C++) that's already out there.

> formal methods

Being able to bolt on embedded formal methods to a programming language is active research. I think it's unreasonable to expect this of any language right now, other than ones specifically designed for it :-) (Speaking as a Lean user.)

Forth doesn't really seem to be the kind of thing where practitioners would care about formal methods... It's very defensible to say, then, that Forth is wrong because of this (we depend quite a lot on software being correct!). But, I don't see anything about Forth that prevents you from defining words that check formal specifications -- and I don't mean this in the trivial adding-a-formally-checked-language-into-Forth way.

> extensibility

Anyway, I don't think it's good or bad to be extensible. It's just a property, and Forth and Common Lisp happen to be examples of languages that are much more extensible than usual. There are certainly engineering challenges either way when it comes to extensibility. And, with an extensible language, while you might be able to make bespoke solutions, you now have a bespoke (hopefully small) language to maintain, too. Language design ability and programming ability don't necessarily go hand-in-hand, either...

Re:Bootstrapping a Forth in 40 lines of Lua code (2008) by lxdesk on Monday September 14, 2020 @08:39PM (#24476716)
The kind of issue I see this thread getting at is what I call the "terrarium problem", which is, to make a whole software ecosystem like a language environment or API mechanisms bounded by a standard, one has to build a sufficiently large terrarium for it and maintain that. The largest, most flexible terrariums we use as developers tend to be operating system standards, browser standards, Internet protocols, etc.; in the case of Forth it's defined by the bootstrapping process, since the bootstrapping code can present a Forth that is near the hardware, or one that is embedded alongside another language environment like Lua. It is even relatively straightforward to have a Forth that generates Lua source code, which the Lua interpreter can then apply its own checks to and evaluate efficiently.

Extensibility by itself doesn't solve the terrarium problem because it doesn't define any standard, so there isn't anything to build on. When presented with extensibility, you still build the terrarium, it's just a customized one, and if you do it ground-up like Forth, you can potentially build it smaller and simpler. But in the end you still have a terrarium with assumed boundaries.

This has led me away from Forth-the-language in the last few months to explore the terrarium problem further, and I hit on the idea of treating this as an organizational issue solved at the level of the core UX. If the problem is defining boundaries in software, we should have better ways of doing that. At first I considered this in terms of selection - selection being one of the pillars of structured programming, and many of our improvements taking the form of easier selection metaphors. This gradually led me to explore the idea of document editing with a binder and sticky notes metaphor, with a supplemental compiler process taking the resulting complex, layered documents and processing them into a linear form for consumption. The presumption is that if I present a rich set of tools for defining types of divisions and groupings defined skeumorphically - pages, bins, tape, wire, guides, stickies, overlays - and then add a bit of labelling and indirection on top, a powerful "thinking tool" should emerge where the organization is easy and the compilation system makes it easy to query and traverse it in a customized way.

If I can finish designing it.

Re:Bootstrapping a Forth in 40 lines of Lua code (2008) by kmill on Monday September 14, 2020 @04:19PM (#24474652)
I should also say that what I'm saying Forth "is" seems to be contentious in the Forth community. This is touched upon in the article, where ANSI Forth is more Forth-the-language, but Chuck Moore Forth is more Forth-the-machine.