
Show HN: A Lispy, embedded Forth - codr4life
https://github.com/codr4life/vicsydev/blob/master/lispy_forth.md
======
simplify
I strongly believe concatenative languages – particularly statically typed
ones – are one paradigm of programming that have not been explored nearly
enough. It's good to see more activity in this area :)

Here's another interesting concatenative language in development that I'm
following: [http://kittenlang.org/](http://kittenlang.org/)

~~~
chubot
I dunno, it feels like Factor kind of exhausted it several years ago? I think
the problem is that concatenative programming is super elegant for some
things, and then falls on its face for others.

In particular the object/class system of Factor was baffling to me. The
paradigms just don't fit together well.

I also think Lisp has an awkward object system(s). If you want that paradigm,
I think a dedicated language is better.

~~~
aidenn0
Somewhat OT, but I'm curious what you think is awkward about CLOS?

~~~
cronjobber
Simple member access like

    
    
        object.foo.bar
    

is apt to read more like this:

    
    
        (class2-bar-of (class1-foo-of object))

~~~
junke
Why not use simpler names?

    
    
        (bar (foo object))
    

I mean, I understand that "a.foo" (class A) does not represent the same name
as "b.foo" (class B) due to scoping rules, and so logically you would have to
use (a-foo a) and (b-foo b) if you wanted to replicate the same in CLOS. But
on the other hand, FOO can be generic and applied to different types of
objects. You might even have a mixin providing the FOO slot, which classes A
and B inherit from.

I find the notation fine, it looks like regular function application (some
people prefer threading macros, I personally don't care).

Note also that CLOS allows you to add code "between the dots" by specializing
accessors on qualifiers (:before, :after, :around), which can be useful to add
orthogonal things like logging, persistency, ...

~~~
cronjobber
That could work within a single, well coordinated project. Beyond that, the
Common Lisp package system doesn't cooperate the way you'd like it to, so
you're back at

    
    
        (libraryA:bar (libraryB:foo object))
    

Since the package system is not hierarchical and doesn't allow local aliases,
if you're unlucky you get fully qualified Java-convention package names and
end up writing:

    
    
        (com.myfavoritecorp.dept1a.project7.subprojectX:bar
           (com.biggercorp.dept32.project2.subprojectE:foo
              object)

~~~
kazinator
The CL package system allows local aliases. How do you think you can be in the
default _cl-user_ package yet refer to _cl:cons_ as just _cons_?

Firstly, the exported symbols in one package can be made visible in another
package through package use. Secondly, a symbol from package A can actually be
made present in package B via _import_ :
[http://clhs.lisp.se/Body/f_import.htm](http://clhs.lisp.se/Body/f_import.htm)

~~~
cronjobber
The context was: "FOO can be generic and applied to different types of
objects." That only works if everybody uses the _same_ symbol FOO. Library:FOO
is a different symbol and won't be combined automatically, so you must
package-qualify.

(Regarding local aliases, I was talking about local package name aliases,
which could make it somewhat less awkward.)

~~~
kazinator
Of course. Why would LOTTERY:DRAW and GRAPHICS:DRAW be smashed together?

~~~
aidenn0
but now you're back to (lottery:draw x) which isn't any shorter than (lottery-
draw x), so the point about names not being namespaced to the object they are
applied to remains.

~~~
kazinator
If I have inherited both, I cannot use the symbol DRAW to refer to both; at
most one of them can be just DRAW.

------
ioddly
That's cool! I actually tried something like this myself, but ended up with a
less conventional syntax.

I'm not really familiar with Forth, but my impression from writing a little
bit of postfix code was that some pattern matching would make e.g. writing a
large conditional much easier.

~~~
codr4life
Forth is trivial to learn but takes serious effort to master, like Lisp and C.
I'm a humble beginner myself when it comes to Forth. A match operator is a
possibility, but too much of that will ruin all that's good about Forth. I
already added word scoped variables, and I already feel like I'm balancing
near the point of negative return.

------
kazinator
> _I 've been craving for a trivial, embedded scripting language that feels
> just right for a long, long time; something I can quickly drop into any
> project that needs scripting without too much ceremony._

How are you quickly and casually going to drop in a scripting language into
any project, if it requires Common Lisp?

Maybe this means "into any CL project". But why would you need a scripting
language in a CL project.

~~~
codr4life
The idea doesn't really require Common Lisp; the same thing could be
implemented in C with a bit more effort. But for me, any project mostly means
Common Lisp as that's the first tool I reach for. I need a scripting language
because exposing the full host language is not really scripting, pretending so
is a cop out that always comes with unintended consequences. Given the right
definitions, Forth reads like the kind of pseudo code most non-programmers
would write; and the lack of syntactic fluff makes it a viable alternative for
scenarios involving sequential processing, templating etc.

------
mondoshawan
So, serious question: if the property of a concatenative language is the
ability to pass outputs to inputs of a function without specifying parameters,
could Iolang or Smalltalk also be described as concatenative? Ie:

    
    
      Transcript show: 'foo'; cr.
    

In this case the output of "Transcript show:" is the Transcript object, which
is used as the sender for cr.

~~~
yorwba
The property of concatenative languages is not the ability to compose
functions without specifying parameters, but that this in the _only_ way of
building programs.

Your Smalltalk example has a lot more special syntax going on, in a stack-
based concatenative syntax it might be written as

    
    
        Transcript ' foo' show cr
    

assuming appropriate primitive programs "Transcript", "'" (for literal
quoting), "show" and "cr"

------
tluyben2
That is a bit too exciting this early in the morning...

~~~
codr4life
Sorry about that :) Time zones...I strongly prefer Lisping and Forthing after
midnight, too much noise on all levels during days.

~~~
tluyben2
Yep, I live in the EU but I am in Cambodia now and I love three languages the
most; Lisp, Forth and APL. So you know what to do to make me cry and have
eternal enlightenment...

Edit; I use Lisp in the form of Clojure daily as well as Forth for embedded.
When writing embedded code, instead of assembly (check my profile, the stuff
we use definitely has no room for Node but often not even C) I usually port a
Forth if one is not available, at least for testing but usually it is good for
production too.

~~~
jessaustin
What resources would you recommend for getting started with Forth?

~~~
tluyben2
Charles Moore Thinking Forth is excellent if you want to work with resource
limited systems.

~~~
astrobe_
The author of Thinking Forth is Leo Brodie.

From Chuck Moore, the father of Forth, "1X Forth" (
[http://www.ultratechnology.com/1xforth.htm](http://www.ultratechnology.com/1xforth.htm)
) is worth reading _before and after_ Thinking Forth.

~~~
tluyben2
You are absolutely right. Got my authors mixed up. Both are great reads.

------
0xdeadbeefbabe
I've been wondering if they called the hp48g's forth ui lisp to avoid
lawsuits.

------
childintime
actually I'd like to see a (~16 bit) Forth backend for LLVM... so I don't have
to "think RPN" myself.

just load the binary into serial flash, point the interpreter at it, and of it
goes.

------
agumonkey
reminds me of jvtoups emacs-lisp stacking monad (IIRC)

------
aesir
abc

