
The Joy programming language - autocorr
http://www.kevinalbrecht.com/code/joy-mirror/joy.html
======
richard_shelton
So called concatenative language is also a combinator-oriented language in a
somewhat restricted form. Here are some historic examples of combinator-
oriented languages: APL family and Backus's FP/FL (direct inspiration for the
author of Joy). The fact that you denote composition of the functions with a
white spaces is just a syntactic sugar. In the case of combinator-oriented
language you work with various functional forms -- combinators, not just with
composition, so you need to use more symbols to denote that. And in practice
it's hard to find a concatenative language which would be used seriously, not
just in a few hobby projects. In the same time there are impressive examples
of modern combinator-oriented languages like Faust [1] and Spiral [2].

Still, the whole "concatenative" movement is interesting as a try to formalize
the semantics and "improve" Forth language. See also Postscript and Henry
Backer's articles [3].

[1] [http://faust.grame.fr/](http://faust.grame.fr/)

[2] [http://www.spiral.net/](http://www.spiral.net/)

[3]
[http://home.pipeline.com/~hbaker1/ForthStack.html](http://home.pipeline.com/~hbaker1/ForthStack.html)

~~~
baruchel
> And in practice it's hard to find a concatenative language which would be
> used seriously, not just in a few hobby projects.

One could argue that piping commands in the shell is a very serious use of
concatenative syntax.

~~~
richard_shelton
In a general sense, yes, of course. Here are more examples.

1\. BNF notation. Yes, it could be surprising, but in a BNF-like language we
use function-level representation and white spaces here denote sequential
composition of functions -- nonterminals.

2\. In a some Lisp-like language one may use spaces to describe "abstract"
composition. So, for sequential composition: "(seq func1 func2 func3)". And
for parallel composition, for example: "(par func1 func2 func3)".

But in the case of real concatenative programming, which has its origin in
Forth, you mostly deal with stacks and stack machines.

------
cutler
Please relabel this as: "The Joy programming language (2005)"

------
dvh
Quadratic formula in joy:

    
    
        DEFINE
        quadratic-3  ==                                # a b c => [root1 root2 ]
            [] cons cons cons                          # list of parameters
            [ [ [ [dup * swap] dip * 4 * - sqrt ]      # radical
                [ pop 0 swap - ]                       # minusb
                [ 2 * ] ]                              # divisor
              [i] map ]
            infra first
            [ [ [ + swap / ]                           # root1
                [ - swap / ] ]                         # root2
              [i] map ]
            infra first.

~~~
geocar
That doesn't seem very... joyful.

In q it's just {(q%x),z%q:-.5 _y+signum[y]_ sqrt(y _y)-4_ x _z}

This is easy to see is correct.

How do you know that Joy is correct?

I'm trying to mentally execute this. I know I haven't seen Joy before, but
I've used Forth, Postscript and Lisp, so I feel like I have a lot to stand on:

\- cons seems to have the same meaning in lisp, so x y cons -> (x . y) or in
Erlangish, [x|y] right?

\- x [y] dip seems to be y x

\- [x] [y] infra seems to be the same as [x y]

\- swap, first, pop, sqrt all seem reasonable

\- wouldn't [] cons cons cons _dup* be better than the extra list with [i] map
] infra first? it's not really clear to me what [i] map is doing... I see how
the values have to flow, but it feels like it should be redundant.

I feel like it's immediately a lot more (mental) work. It reminds me of
tracing forth code before I just gave in and started using variables like a
normal person.

Is this really the best way to be introduced to Joy? Is this a typical problem
that Joy programmers feel is the right way to program (and the right
solution?) Am I missing something here?

~~~
exikyut
Formatting note:

It will look a bit messier for the

    
    
      things*involving*asterisks
    

to be on their own line (indented two spaces), but that way Arc won't chew
them. I'm mentioning this because I can't determine the original text myself.

~~~
geocar
Yeah, can't edit now.

    
    
        {(q%x),z%q:-.5*y+signum[y]*sqrt(y*y)-4*x*z}

------
carapace
I've been working on a dialect of Joy recently.[1] It's implemented in Python,
in the Continuation-Passing Style. I've implemented type inference[2] and I'm
almost done with a compiler (to Python for now.)

Joy combines the best features of Forth and Lisp.

It also makes "Categorical Programming" easy.[3] You can get a variety of
valid computations by instantiating the same code over different categories.
For example, the Joy type inferencer is an interpreter that operates on stack
effect representations rather than e.g. numbers and strings. The same Joy
expression that, when run on the normal interpreter gives the calculation,
gives the stack effect of the expression when run on the inferencer. A subset
of functions has to be overridden to make this work, but then you're good-to-
go.

The mental models that you have to adopt to develop in Joy are _better_ than
those for other languages. There's a purity and elegance in the Joy notation
that continues to be very exciting and interesting. For example, check out
"Recursion Combinators"[4] which is loosely based on the first part of the
"Bananas, Lenses, & Barbed Wire" paper[5].

My interest is binary: 1.) Joy is a notation and semantics that normal
everyday people can easily understand and use; I've developed a user interface
based on Joy as the unifying, uh, interface (both GUI and text interaction
result in a stream of Joy commands) and I'm going to be setting up "encounter
groups" and live user testing starting this month. I'm going to put normal
people in front of a raspberry pi that's configured as a kind of Joy kiosk and
see what happens.

2.) Joy is an excellent vehicle for developing proven-correct code. Most Joy
development is more akin to deriving mathematical proofs than "regular"
programming. Joy delivers on the promise of Functional Programming: making
software by doing math. In Joy it's easy. I can write parsers that translate
existing code into Joy-as-AST and then do refactoring and simplification.
Recently, (the last couple of days) I've been playing with Prolog to represent
Joy code. This has worked really well. It should be easy to make powerful code
transformation tools.

Anyhow, to sum up: Joy is _really_ cool. It's enormously simple and oh so
elegant. Y'all should check it out.

[1] Thun [http://joypy.osdn.io/](http://joypy.osdn.io/)

[2]
[http://joypy.osdn.io/notebooks/Types.html](http://joypy.osdn.io/notebooks/Types.html)

[3] [http://conal.net/papers/compiling-to-
categories/](http://conal.net/papers/compiling-to-categories/)

[4]
[http://joypy.osdn.io/notebooks/Recursion_Combinators.html](http://joypy.osdn.io/notebooks/Recursion_Combinators.html)

[5]
[http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.41.1...](http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.41.125)

------
FullyFunctional
Joy has come up a few times. A powerful language built on a few clever
principles is alluring, but I found it impossible to read, sadly (but I feel
somewhat similar about Forth).

