# A new concatenative language -- FACTOR

## Slava Pestov — 2004-04-16 04:17:18

    Hi all,

    For the last 7 months, I have been developing a concatenative language

    called FACTOR. It is hosted on the Java virtual machine, supporting both

    compiled and interpreted execution.

    Download it from http://slava.kicks-ass.org/slava/Factor.jar. It

    requires Java 2 version 1.4 or later to run. The JAR file includes

    source and binaries, under a BSD-style license. Enter 'help' in the

    interpreter to get an idea of some useful commands.

    Right now, the available documentation is sparse:

    http://slava.kicks-ass.org/slava/ftut.html

    http://slava.kicks-ass.org/slava/fcom.html

    (It is used for scripting in a game I'm working on, which will be

    released later. The game uses Java OpenGL bindings is about 40 KLOC of

    Java and 10 KLOC of factor code at the moment. But that is not the

    subject of the e-mail.)

    The main features of Factor are:

    - Lisp-like cons cells are a central part of the language

    - Control structures are Joy-like combinators; 'code quotations' are

    passed on the stack

    - Explicit access to the return stack, as in Forth

    - Shuffle definitions: ~<< swap a b -- b a >>~ etc.

    - Stack effect inference for simple, conditional and recursive forms

    - Continuations!

    - Compiler for (some) forms (basically those whose stack effect can be

    inferred) targetting JVM bytecode; everything else is interpreted

    - Big number, ratio, integer, float arithmetic with automatic coercions

    - Dynamically-scoped nested 'namespaces' for holding variables

    - Reasonably small and elegant core

    - (Somewhat incomplete but already comprehensive) test suite

    - Full reflective inspection of interpreter state

    - 3 front-ends:

      - http server

      - text mode console

      !!! GUI with hyperlinked inspection of source and variables, etc

    This language owes a lot to Joy and Lisp, and to a lesser extent, Forth.

    I'd like to thank the inventor of Joy especially for leading me to see

    the elegance and simplicity of concatenative languages.

    I'd love to write a bit more but it is getting late. If anybody gets a

    chance to play around with this, I'd appreciate some feedback.

    --

    Slava Pestov

## andrew cooke — 2004-04-16 12:29:43

    how have you implememented continuations?  in otuto i have two stacks -

    one for pending operations and one for values (i think the first of these

    is the same as your call stack; apologies for not knowing the standard

    terminology).  a continuation is then the copying of a chunk of the

    operations stack to the value stack (which is possible because, like joy

    and factor, operations can be added to the value stack too).

    also, how similar is your "stack effect deduction" to static typing?  i

    intend to add (hindley miller -like) typing to otuto - i think it is

    possible using an approach like ocaml (i can't remember the details, but

    iirc it has extensible records, which would be used for the stack, since

    you obviously canot treat them like homogenous lists).

    two other differences between factor and otuto that i can see are that you

    seem to treat the operations and values stacks equally (in otuto you can

    only match the head of the operations stack; continuations require

    additional semantics) and you use joy's list-as-quoting (which i convinced

    myself was a mistake - otuto has separate quoting and lists).  also otuto

    has lazy evaluation if required, but that's just because i'm a haskell fan

    :o)

    sorry to talk in terms of a language that doesn't exist and that no-one

    uses - i was just surprised by how close the two are.  i guess that's

    encouraging if you find that it works! (it may also just be beginnners

    enthusiasm - maybe these are things that all concatenative languages

    have).

    cheers,

    andrew

    ps also, out of curiousity, what ava parser generator did you use (i've

    used sablecc and javacc in the past - always curious to know people's

    experiences with others)?

    Slava Pestov said:

     > Hi all,

    >

    > For the last 7 months, I have been developing a concatenative language

    > called FACTOR. It is hosted on the Java virtual machine, supporting both

    > compiled and interpreted execution.

    >

    > Download it from http://slava.kicks-ass.org/slava/Factor.jar. It

    > requires Java 2 version 1.4 or later to run. The JAR file includes

    > source and binaries, under a BSD-style license. Enter 'help' in the

    > interpreter to get an idea of some useful commands.

    >

    > Right now, the available documentation is sparse:

    >

    > http://slava.kicks-ass.org/slava/ftut.html

    > http://slava.kicks-ass.org/slava/fcom.html

    >

    > (It is used for scripting in a game I'm working on, which will be

    > released later. The game uses Java OpenGL bindings is about 40 KLOC of

    > Java and 10 KLOC of factor code at the moment. But that is not the

    > subject of the e-mail.)

    >

    > The main features of Factor are:

    >

    > - Lisp-like cons cells are a central part of the language

    > - Control structures are Joy-like combinators; 'code quotations' are

    > passed on the stack

    > - Explicit access to the return stack, as in Forth

    > - Shuffle definitions: ~<< swap a b -- b a >>~ etc.

    > - Stack effect inference for simple, conditional and recursive forms

    > - Continuations!

    > - Compiler for (some) forms (basically those whose stack effect can be

    > inferred) targetting JVM bytecode; everything else is interpreted

    > - Big number, ratio, integer, float arithmetic with automatic coercions

    > - Dynamically-scoped nested 'namespaces' for holding variables

    > - Reasonably small and elegant core

    > - (Somewhat incomplete but already comprehensive) test suite

    > - Full reflective inspection of interpreter state

    > - 3 front-ends:

    >   - http server

    >   - text mode console

    >   !!! GUI with hyperlinked inspection of source and variables, etc

    >

    > This language owes a lot to Joy and Lisp, and to a lesser extent, Forth.

    > I'd like to thank the inventor of Joy especially for leading me to see

    > the elegance and simplicity of concatenative languages.

    >

    > I'd love to write a bit more but it is getting late. If anybody gets a

    > chance to play around with this, I'd appreciate some feedback.

    > --

    > Slava Pestov

    >

    >

    >

    >

    > Yahoo! Groups Links

    >

    >

    >

    >

    >

    >

     --

    ` __ _ __ ___  ___| |_____   work web site: http://www.ctio.noao.edu/~andrew

     / _` / _/ _ \/ _ \ / / -_)  personal web site: http://www.acooke.org/andrew

     \__,_\__\___/\___/_\_\___|  personal gallery: http://www.acooke.org/pancito

## stevan apter — 2004-04-16 12:56:47

    it's wonderful to hear that there is activity on these fronts.

    i have no idea how many people are lurking, and working on their

    own ideas, but i worry that low activity on the list might discourage

    further efforts along these lines.

    andrew, slava:  please report back on your progress, and (possibly?)

    give us urls where we can keep abreast.

    best

    sa

     ----- Original Message -----

    From: "andrew cooke" <andrew@...>

    To: <concatenative@yahoogroups.com>

    Sent: Friday, April 16, 2004 8:29 AM

    Subject: Re: [stack] A new concatenative language -- FACTOR

    >

    > how have you implememented continuations?  in otuto i have two stacks -

    > one for pending operations and one for values (i think the first of these

    > is the same as your call stack; apologies for not knowing the standard

    > terminology).  a continuation is then the copying of a chunk of the

    > operations stack to the value stack (which is possible because, like joy

    > and factor, operations can be added to the value stack too).

    >

    > also, how similar is your "stack effect deduction" to static typing?  i

    > intend to add (hindley miller -like) typing to otuto - i think it is

    > possible using an approach like ocaml (i can't remember the details, but

    > iirc it has extensible records, which would be used for the stack, since

    > you obviously canot treat them like homogenous lists).

    >

    > two other differences between factor and otuto that i can see are that you

    > seem to treat the operations and values stacks equally (in otuto you can

    > only match the head of the operations stack; continuations require

    > additional semantics) and you use joy's list-as-quoting (which i convinced

    > myself was a mistake - otuto has separate quoting and lists).  also otuto

    > has lazy evaluation if required, but that's just because i'm a haskell fan

    > :o)

    >

    > sorry to talk in terms of a language that doesn't exist and that no-one

    > uses - i was just surprised by how close the two are.  i guess that's

    > encouraging if you find that it works! (it may also just be beginnners

    > enthusiasm - maybe these are things that all concatenative languages

    > have).

    >

    > cheers,

    > andrew

    >

    > ps also, out of curiousity, what ava parser generator did you use (i've

    > used sablecc and javacc in the past - always curious to know people's

    > experiences with others)?

    >

    > Slava Pestov said:

    > > Hi all,

    > >

    > > For the last 7 months, I have been developing a concatenative language

    > > called FACTOR. It is hosted on the Java virtual machine, supporting both

    > > compiled and interpreted execution.

    > >

    > > Download it from http://slava.kicks-ass.org/slava/Factor.jar. It

    > > requires Java 2 version 1.4 or later to run. The JAR file includes

    > > source and binaries, under a BSD-style license. Enter 'help' in the

    > > interpreter to get an idea of some useful commands.

    > >

    > > Right now, the available documentation is sparse:

    > >

    > > http://slava.kicks-ass.org/slava/ftut.html

    > > http://slava.kicks-ass.org/slava/fcom.html

    > >

    > > (It is used for scripting in a game I'm working on, which will be

    > > released later. The game uses Java OpenGL bindings is about 40 KLOC of

    > > Java and 10 KLOC of factor code at the moment. But that is not the

    > > subject of the e-mail.)

    > >

    > > The main features of Factor are:

    > >

    > > - Lisp-like cons cells are a central part of the language

    > > - Control structures are Joy-like combinators; 'code quotations' are

    > > passed on the stack

    > > - Explicit access to the return stack, as in Forth

    > > - Shuffle definitions: ~<< swap a b -- b a >>~ etc.

    > > - Stack effect inference for simple, conditional and recursive forms

    > > - Continuations!

    > > - Compiler for (some) forms (basically those whose stack effect can be

    > > inferred) targetting JVM bytecode; everything else is interpreted

    > > - Big number, ratio, integer, float arithmetic with automatic coercions

    > > - Dynamically-scoped nested 'namespaces' for holding variables

    > > - Reasonably small and elegant core

    > > - (Somewhat incomplete but already comprehensive) test suite

    > > - Full reflective inspection of interpreter state

    > > - 3 front-ends:

    > >   - http server

    > >   - text mode console

    > >   !!! GUI with hyperlinked inspection of source and variables, etc

    > >

    > > This language owes a lot to Joy and Lisp, and to a lesser extent, Forth.

    > > I'd like to thank the inventor of Joy especially for leading me to see

    > > the elegance and simplicity of concatenative languages.

    > >

    > > I'd love to write a bit more but it is getting late. If anybody gets a

    > > chance to play around with this, I'd appreciate some feedback.

    > > --

    > > Slava Pestov

    > >

    > >

    > >

    > >

    > > Yahoo! Groups Links

    > >

    > >

    > >

    > >

    > >

    > >

    >

    >

    > --

    > ` __ _ __ ___  ___| |_____   work web site: http://www.ctio.noao.edu/~andrew

    >  / _` / _/ _ \/ _ \ / / -_)  personal web site: http://www.acooke.org/andrew

    >  \__,_\__\___/\___/_\_\___|  personal gallery: http://www.acooke.org/pancito

    >

    >

    >

    >

    >

    > Yahoo! Groups Links

    >

    >

    >

    >

    >

## andrew cooke — 2004-04-16 13:47:21

    the only url i have that's relevant to otuto is notes in my diary.  it's

    only rough notes, and not corrected when things change, so the information

    is inaccurate, incomplete and out of date!  anyway, last entry is at

    http://www.acooke.org/andrew/diary/2004/apr/15.html (and already out of

    date because i'm adding error handling).  earlier entries by clicking on

    the left arrow, top right of the screen.  again, this is really intended

    more for personal use and for my family (i live in s america, they are all

    in the uk, so it's a way for them to see that i'm still alive...) so don't

    expect anything very useful.

    cheers,

    andrew

    ps apologies - the year and month links on those pages don't work.  i'm

    supposed to be working on auto-generating indices, but, well, don't have

    the time...

    pps similarly to factor, the aim is to implement a scripting language for

    a larger project (a program that plays go).

    stevan apter said:

     > it's wonderful to hear that there is activity on these fronts.

    >

    > i have no idea how many people are lurking, and working on their

    > own ideas, but i worry that low activity on the list might discourage

    > further efforts along these lines.

    >

    > andrew, slava:  please report back on your progress, and (possibly?)

    > give us urls where we can keep abreast.

    >

    > best

    >

    > sa

     --

    ` __ _ __ ___  ___| |_____   work web site: http://www.ctio.noao.edu/~andrew

     / _` / _/ _ \/ _ \ / / -_)  personal web site: http://www.acooke.org/andrew

     \__,_\__\___/\___/_\_\___|  personal gallery: http://www.acooke.org/pancito

## Tanksley, William D. Jr. — 2004-04-16 14:21:54

    From: andrew cooke [mailto:andrew@...]

     >how have you implememented continuations?  in otuto i have two

    >stacks - one for pending operations and one for values (i

    >think the first of these is the same as your call stack;

    >apologies for not knowing the standard terminology).  a

    >continuation is then the copying of a chunk of the operations

    >stack to the value stack (which is possible because, like joy

    >and factor, operations can be added to the value stack too).

     That sounds correct to me; Forth works the same way.

    As for terminology: the only language I know of which exposes two stacks is

    Forth, and it calls them the "data stack" and the "return stack".

     >also, how similar is your "stack effect deduction" to static

    >typing?  i intend to add (hindley miller -like) typing to

    >otuto - i think it is possible using an approach like ocaml (i

    >can't remember the details, but iirc it has extensible

    >records, which would be used for the stack, since you

    >obviously canot treat them like homogenous lists).

     For some good info on type enforcement in a concatenative language, check

    out strongForth. Ooops, it's gone from the web!!! Oh no.

    Er...

    Well, at any rate, strongForth manages to perform strong static type

    checking with type polymorphism in linear time. It takes clever advantage of

    concatenativity. Its problem is that, as a proof of concept and working

    program, it was made compatible with the ANSI Forth, which wasn't made for

    strong static typing; the result is something of a hodgepodge (although it

    works surprisingly well). A language designed for that sort of thing from

    the start would be much more impressive.

    The problem with doing strong static typechecking is that you can't have

    variable stack effects. IMO the solution is to replace the variable stack

    effect support with variable length array support (such support is seen in

    cK). If you're willing to be REALLY daring, you could try to replace all

    explicit iteration with array-driven implicit iteration (again, cK handles

    implicit iteration, although it also provides all the explicit combinators).

     >two other differences between factor and otuto that i can see

    >are that you seem to treat the operations and values stacks

    >equally (in otuto you can only match the head of the

    >operations stack; continuations require additional semantics)

     Hmm. I'll have to spend some time looking at this. I like the idea.

     >and you use joy's list-as-quoting (which i convinced myself

    >was a mistake - otuto has separate quoting and lists).

     I agree with otuto :-).

     >  also

    >otuto has lazy evaluation if required, but that's just because

    >i'm a haskell fan :o)

     What would lazy evaluation mean to a concatenative language? For an

    applicative language, lazy evaluation means that parameters to functions are

    bound without being evaluated; but for a concatenative language, you can't

    bind parameters to functions, so what CAN you do?

     >(it may also just be beginnners enthusiasm - maybe these are

    >things that all concatenative languages have).

     Yes, all concatenative languages have beginner's enthusiasm :-).

    No, the combination of these features is really distinct and interesting.

    I'm certainly interested in both of your work.

     >andrew

     -Billy

## andrew cooke — 2004-04-16 15:17:11

    Tanksley, William D. Jr. said:

     > From: andrew cooke [mailto:andrew@...]

     [...]

     > As for terminology: the only language I know of which exposes two stacks

    > is Forth, and it calls them the "data stack" and the "return stack".

     thanks.

    [...]

     > The problem with doing strong static typechecking is that you can't have

    > variable stack effects. IMO the solution is to replace the variable stack

    > effect support with variable length array support (such support is seen in

    > cK). If you're willing to be REALLY daring, you could try to replace all

    > explicit iteration with array-driven implicit iteration (again, cK handles

    > implicit iteration, although it also provides all the explicit

    > combinators).

     variable stack effects?  i don't know what that means, but my idea was to

    describe the type of an operation as a transformation from the list of

    types on the data stack before to the list of types after.  you only

    specify the list to some depth, because after that it's irrelevant (not

    used).  this is like "tuples" in a "normal" functional language, but with

    "..." on the right.  (this is one reason why otuto doesn't match the

    return stack, apart from the head element - the type of the head element

    of the return stack is the type of the operation) (i may have return and

    data stacks mixed up - you didn't say which was which!)

    [...]

     > What would lazy evaluation mean to a concatenative language? For an

    > applicative language, lazy evaluation means that parameters to functions

    > are

    > bound without being evaluated; but for a concatenative language, you can't

    > bind parameters to functions, so what CAN you do?

     yeah, i asked the same question.  :o)

    http://www.acooke.org/andrew/diary/2004/apr/10.html is a sketch of what

    went on in my head at the time.  the following is an example of an

    infinite list (modified to the current syntax of otuto):

    {from | 'n} => { | 'n $(from + 'n 1) }

    $ indicates lazy evaluation (see below for how this is evaluated).

    so evaluating "{x} 7 from p p p" where p prints the top value on the data

    stack gives (i'm writing return stack to the left of "|", extending

    leftwards, and data stack to the right of "|" extending rightwards:

    { p p p from 7 {x} | )         (* {} is quoting, x is not used below *)

    { p p p from 7 | x }

    { p p p from | 7 x }           (* numbers evaluate to themselves *)

    { p p p | 7 $(from + 7 1) x }  (* definition of from, above *)

    { p p p | 7 $from $+ $7 $1 x } (* $(...) is sugar for $.$.$. *)

    7

    { p p | $from $+ $7 $1 x }     (* p tries to access thunk *)

      { from | $+ $7 $1 x }        (* so evaluate thunk, hitting another *)

        { + | $7 $1 x }            (* and another *)

          { 7 | $1 x }             (* number evaluates to self *)

        { + | 7 $1 x }             (* + takes two args, second a thunk, so.. *)

          { 1 | x }

        { + | 7 1 x }              (* can finaly evaluate this thunk *)

      { from | 8 x }               (* and this one *)

      { | 8 $(from + 8 1) x }      (* looks familiar! *)

    { p p | 8 $(from + 8 1) x }    (* and continue with p *)

    8

    { p | $(from + 8 1) x }

    etc

    i'm not 100% sure about this.  i think it's more useful that that example

    because pattern matching means that thunks can be evaluated in sub-lists,

    which lets them be "looked past" at times (a thunk directly on the data

    stack is going to be evaluated by any pattern that goes that deep or

    further, but in a list the pattern may not require evaluation).

    for example, consider applying

    { swap | 'a 'b } => { | 'b 'a }

    to a case like

    { swap | 1 [$thunk]}

    { | [$thunk] 1 }

    - the thunk hasn't been evaluated because its contents were not pattern

    matched.

    does that make sense!?

    since i haven't got this thing working yet i have no idea how useful it

    will be.  it's also possible that it makes the language much more complex

    to implement (the sub-evaluation implies some kind of "hidden" return

    stack; it's still not clear to me whether this makes everything a mess or

    not)

    cheers,

    andrew

    --

    ` __ _ __ ___  ___| |_____   work web site: http://www.ctio.noao.edu/~andrew

     / _` / _/ _ \/ _ \ / / -_)  personal web site: http://www.acooke.org/andrew

     \__,_\__\___/\___/_\_\___|  personal gallery: http://www.acooke.org/pancito

## Slava Pestov — 2004-04-16 15:18:31

    On Fri, 2004-04-16 at 08:29, andrew cooke wrote:

     > how have you implememented continuations?  in otuto i have two stacks -

    > one for pending operations and one for values (i think the first of these

    > is the same as your call stack; apologies for not knowing the standard

    > terminology).  a continuation is then the copying of a chunk of the

    > operations stack to the value stack (which is possible because, like joy

    > and factor, operations can be added to the value stack too).

     Indeed, this is pretty much how I do it.

    A continuation is captured by the callcc word; it is given a quotation,

    and it applies the quotation to the captured continuation. A captured

    continuation is another quotation that when called, restores execution

    to the point *after* the callcc call. So:

    ... code ... [ do something with continuation X ] callcc ... more ...

                                                           |

                   Calling X will restore execution here ---

    Note that continuations are never compiled; this is ensured by giving

    the primitives involved (see the definition of callcc) indeterminate

    stack effects.

     > also, how similar is your "stack effect deduction" to static typing?  i

    > intend to add (hindley miller -like) typing to otuto - i think it is

    > possible using an approach like ocaml (i can't remember the details, but

    > iirc it has extensible records, which would be used for the stack, since

    > you obviously canot treat them like homogenous lists).

     I intend to apply it to the problem of type inference later on; however

    this will not be for error checking, but rather for efficiency; if the

    types of operands can be inferred, the compiled JVM bytecode has less

    casting operations and runs faster. If they cannot be inferred, well, it

    will still execute...

     > and you use joy's list-as-quoting (which i convinced

    > myself was a mistake - otuto has separate quoting and lists).

     Why do you think this is a mistake? Efficiency is not an issue since the

    compiler can deduce which quotations end up being executed, and compile

    those directly.

     > ps also, out of curiousity, what ava parser generator did you use (i've

    > used sablecc and javacc in the past - always curious to know people's

    > experiences with others)?

     I wrote my own parser. It is hand-coded, but extensible. It has three

    main components:

    - read table: maps characters to types (symbol constituent, whitespace,

    special dispatch)

    - scanner: splits up input stream into discrete tokens using read table

    - parsing words: given a scanner instance, they read some form of

    syntactic structure (for example, [ ] : ; and so on are parsing words).

    - reader: uses a scanner to invoke parse words when necessary and build

    a parse tree (really, a set of nested linked lists and other objects).

    Everything is customizable by user code, eg to change the brackets from

    [ ] to { } you can use something like:

    #=[ [ $parsing ] bind #={ [ @parsing ] bind

    #=] [ $parsing ] bind #=} [ @parsing ] bind

    { "Hello world" } print

    #=XXX pushes a word literally without executing it (in fact #= is a

    parsing word that simply expands to "XXX" intern)

    --

    Slava Pestov

## andrew cooke — 2004-04-16 15:37:04

    Slava Pestov said:

    [...]

     >> and you use joy's list-as-quoting (which i convinced

    >> myself was a mistake - otuto has separate quoting and lists).

    >

    > Why do you think this is a mistake? Efficiency is not an issue since the

    > compiler can deduce which quotations end up being executed, and compile

    > those directly.

     not a big mistake - i just found it confusing.  my main sticking point was

    that i couldn't see how to get a single operator on the data stack

    directly, yet it could occur by manipulating the stack (maybe what you use

    #= for below?)

    [...]

     > Everything is customizable by user code, eg to change the brackets from

    > [ ] to { } you can use something like:

     does this mean that in factor you can define new words at run-time?  if

    you can modify the parser can you not introduce mutable state?  maybe you

    define x to parse as 5, then later as 7...

    i don't know if this worries you - it is one reason why i am keeping

    compile and run-time completely separate.  but i am impressed by the

    flexibility of your solution (the other reason they are separate in my

    case is laziness!)

    cheers,

    andrew

    ps no more email from me for a while - i must write code!  i have only a

    few days before i am back on shift...

    --

    ` __ _ __ ___  ___| |_____   work web site: http://www.ctio.noao.edu/~andrew

     / _` / _/ _ \/ _ \ / / -_)  personal web site: http://www.acooke.org/andrew

     \__,_\__\___/\___/_\_\___|  personal gallery: http://www.acooke.org/pancito

## Slava Pestov — 2004-04-16 22:56:20

    On Fri, 2004-04-16 at 11:37, andrew cooke wrote:

     > does this mean that in factor you can define new words at run-time? if

    > you can modify the parser can you not introduce mutable state?  maybe you

    > define x to parse as 5, then later as 7...

     One of the inspirations for Factor's is SmallTalk. Both are imperitive

    languages at the core, but also very dynamic...

    : square dup * ; is just syntax sugar for "square" [ dup * ] define.

    If you evaluate this:

     "Enter your first name: " print

     read

     "Enter your last name: "  print

     read

     unit define

    And enter "andrew" then "cooke", evaluating

    andrew

    Will push the string "cooke" on the stack.

    The language has explicit support for variables, in fact nested

    namespaces of variables.

        2] 5 @x

        3] $x .

    5

        4] 7 @x

        5] $x .

    7

    In fact $x is syntax for "x" $, and @x is syntax for "x" @...

    Another non-FP aspect is mutable data structures, for example, compare:

    !!! Classic FP list append that copies the first list (non-destructive)

        18] [ 1 2 3 ] @list

        19] $list [ 4 5 6 ] append .

    [ 1 2 3 4 5 6 ]

        20] $list .

    [ 1 2 3 ]

    !!! What a Java or C programmer is used to:

        21] $list [ 4 5 6 ] nappend .

    [ 1 2 3 4 5 6 ]

        22] $list .

    [ 1 2 3 4 5 6 ]

    Use of the latter is discouraged! In fact, I can only think of a few

    instances where destructive list operations are used. However, where

    they are used, they prove *very* useful.

    Just because the language *lets* you do something does not mean that its

    always good style to do so.

    In the game, I use a very functional style of programming, using

    variables mostly for constants.

    Pretty much the only factor code that does runtime introspection is the

    "IDE"; the prettyprinter, namespace inspector, and (what little there is

    of) the debugger.

    --

    Slava Pestov

## andrew cooke — 2004-04-16 23:46:29

    now i can see where 7 months went :o)

    you should document this more - the web pages don't do it justice.

    thanks,

    andrew

    Slava Pestov said:

     > On Fri, 2004-04-16 at 11:37, andrew cooke wrote:

    >> does this mean that in factor you can define new words at run-time? if

    >> you can modify the parser can you not introduce mutable state?  maybe

    >> you

    >> define x to parse as 5, then later as 7...

    >

    > One of the inspirations for Factor's is SmallTalk. Both are imperitive

    > languages at the core, but also very dynamic...

    >

    > : square dup * ; is just syntax sugar for "square" [ dup * ] define.

    >

    > If you evaluate this:

    >

    >  "Enter your first name: " print

    >  read

    >  "Enter your last name: "  print

    >  read

    >  unit define

    >

    > And enter "andrew" then "cooke", evaluating

    >

    > andrew

    >

    > Will push the string "cooke" on the stack.

    >

    > The language has explicit support for variables, in fact nested

    > namespaces of variables.

    >

    >     2] 5 @x

    >     3] $x .

    > 5

    >     4] 7 @x

    >     5] $x .

    > 7

    >

    > In fact $x is syntax for "x" $, and @x is syntax for "x" @...

    >

    > Another non-FP aspect is mutable data structures, for example, compare:

    >

    > !!! Classic FP list append that copies the first list (non-destructive)

    >     18] [ 1 2 3 ] @list

    >     19] $list [ 4 5 6 ] append .

    > [ 1 2 3 4 5 6 ]

    >     20] $list .

    > [ 1 2 3 ]

    >

    > !!! What a Java or C programmer is used to:

    >     21] $list [ 4 5 6 ] nappend .

    > [ 1 2 3 4 5 6 ]

    >     22] $list .

    > [ 1 2 3 4 5 6 ]

    >

    > Use of the latter is discouraged! In fact, I can only think of a few

    > instances where destructive list operations are used. However, where

    > they are used, they prove *very* useful.

    >

    > Just because the language *lets* you do something does not mean that its

    > always good style to do so.

    >

    > In the game, I use a very functional style of programming, using

    > variables mostly for constants.

    >

    > Pretty much the only factor code that does runtime introspection is the

    > "IDE"; the prettyprinter, namespace inspector, and (what little there is

    > of) the debugger.

    > --

    > Slava Pestov

    >

    >

    >

    > Yahoo! Groups Links

    >

    >

    >

    >

    >

    >

     --

    ` __ _ __ ___  ___| |_____   work web site: http://www.ctio.noao.edu/~andrew

     / _` / _/ _ \/ _ \ / / -_)  personal web site: http://www.acooke.org/andrew

     \__,_\__\___/\___/_\_\___|  personal gallery: http://www.acooke.org/pancito

## phimvt@lurac.latrobe.edu.au — 2004-04-30 07:52:31

    On Fri, 16 Apr 2004, stevan apter wrote:

     > it's wonderful to hear that there is activity on these fronts.

     Yes, indeed. I very much welcome experimentations with

    concatenative languages.

     > i have no idea how many people are lurking, and working on their

    > own ideas, but i worry that low activity on the list might discourage

    > further efforts along these lines.

     I myself have not contributed at all lately. I have been rather

    unwell for quite some time, but seem to be getting better somewhat.

    So you'll see a bit more of me, I hope.

    [..]

      - Manfred

## Heiko.Kuhrt@t-online.de — 2004-04-30 14:45:24

    ...

     > I myself have not contributed at all lately. I have been rather

    > unwell for quite some time, but seem to be getting better somewhat.

     ...

    I'm sorry to read that. I have had a lot of fun with Joy and your papers

    about it.

    Gute Besserung!!  		[ well bettering ]

    --Heiko

     >   - Manfred

## Ben — 2004-04-30 15:27:44

    phimvt@... wrote:

     > On Fri, 16 Apr 2004, stevan apter wrote:

    >>it's wonderful to hear that there is activity on these fronts.

    >

    > Yes, indeed. I very much welcome experimentations with

    > concatenative languages.

        Speaking of experimenting with concatenative languages, I've been

    playing around with writing dc(1) macros lately and got to wondering if

    anyone else has any thoughts about it as a concatenative language -

    starting, I suppose, with whether or not it /is/ one.

     >>i have no idea how many people are lurking, and working on their

    >>own ideas, but i worry that low activity on the list might discourage

    >>further efforts along these lines.

        I've been lurking for a long time and will probably re-enter that

    mode hereafter. The level of erudition on this list is both fascinating

    and intimidating.

     > I myself have not contributed at all lately. I have been rather

    > unwell for quite some time, but seem to be getting better somewhat.

    > So you'll see a bit more of me, I hope.

        I'm sorry to hear that you've been feeling unwell, though glad that

    it's passing. Get well soon! I look forward to your future writings.

    	Ben

## Nick Forde — 2004-04-30 21:07:08

    Ben wrote:

     >    Speaking of experimenting with concatenative languages, I've been

    > playing around with writing dc(1) macros lately and got to wondering if

    > anyone else has any thoughts about it as a concatenative language -

    > starting, I suppose, with whether or not it /is/ one.

     Hi Ben,

    I'm not sure I should admit to this but in my early Unix days I used

    dc a lot and got to quite like it. Well at least I liked the RPN

    notation and ability to write scripts.

    I'm not sure whether it classifies as a concatenative language but if

    my memory serves me correctly it does has an evaluation command 'x' and

    the ability to define macros. I think very limited function composition

    is also possible but only through the definition of nested macros. So

    maybe it is? Early implementations of the bc(1) calculator, which

    uses a c like syntax, simply compiled bc scripts into dc format.

    Here are a couple of my very old scripts which illustrate what is

    possible. The first draws a Mandelbrot set and the second Sierpinskis

    gasket.

    #!/usr/bin/dc

    [[nickf@nospam_.com]n17lc+sc0.6375la+sa]sR[lpan]sP[2lx*ly*lb+si]sK

    [0sr0si0snlCx46lm-splPx0.03750la+salc1+scll12=Qlc80>O]sO[lc40=R]sQ

    [lnsmlIxlKxlJxln1+snln15>C]sC[15sn]sD[lrsxlisylxlx*lyly*-la+sr]sI#

    [lxlx*lyly*+4<D]sJ[_2sa0sclOx0.096lb+sbll1+slll25>L]sL_1.2sb0sllLx

    #!/usr/bin/dc

    [li1+sili;cPlsli2-<p]sp[lzsilz80+sslpx[]p]sP[32li:cli1+si160li<j]sj

    [88lx80+lz-:c]su[32lx80+lz-:c]st[lzlx+1-;clzlx1++;c-0!=ulzlx+1-;clz

    lx1++;c-0=tlx1-sx0lx>X]sX[lPx77sxlXx80lz-szld1-sd_1ld>K]sK[0dsiszlj

    x0si0 79:c88 39:c31sdlKx]dsmx

    Joy examples of both of these have been discussed on this list in the

    past. Of course the Joy versions are much more elegant, and certainly

    easier to maintain :-)

     >    I'm sorry to hear that you've been feeling unwell, though glad that

    > it's passing. Get well soon! I look forward to your future writings.

     Yes, get well soon Manfred. I'm missing your insightful comments.

    Best regards,

    Nick.

## Ben — 2004-04-30 21:36:37

    Nick Forde wrote:

     > Ben wrote:

    >

    >>   Speaking of experimenting with concatenative languages, I've been

    >>playing around with writing dc(1) macros lately and got to wondering if

    >>anyone else has any thoughts about it as a concatenative language -

    >>starting, I suppose, with whether or not it /is/ one.

    >

    >

    > Hi Ben,

    >

    > I'm not sure I should admit to this but in my early Unix days I used

    > dc a lot and got to quite like it. Well at least I liked the RPN

    > notation and ability to write scripts.

        In that case I probably shouldn't admit that I really quite enjoy

    scripting in dc and wrote a short introductory article[1] about it as I

    found my footing in the language!

     > I'm not sure whether it classifies as a concatenative language but if

    > my memory serves me correctly it does has an evaluation command 'x' and

    > the ability to define macros. I think very limited function composition

    > is also possible but only through the definition of nested macros. So

    > maybe it is?

        My main stumbling point is that it doesn't seem possible for

    functions to return other functions, since dc has - as far as this

    neophyte can tell - extremely impoverished string-handling capabilities

    (and there doesn't seem to be any meaningful distinction between strings

    and macros).

       The only idea I had to circumvent this was a dc program that

    constructs programs by manipulating a numeric representation of itself

    plus the newly-defined function, then invokes a new instance of dc and

    feeds it that environment and the additional program.

     > Early implementations of the bc(1) calculator, which uses a c like

    > syntax, simply compiled bc scripts into dc format.

        I've heard that from many sources, but so far I haven't been able to

    track down any open-source implementation of bc with this execution

    model. I've read through the source code for GNU bc and dc and

    discovered nothing revelatory. I feel rather silly asking this, but can

    anyone point me toward the source for a bc implementation that /does/

    compile down to dc, and/or a the source for a non-GNU dc so I can

    compare and contrast?

       James P. Howard claims to have implemented a version of dc based

    around the gmp library, but I cannot find the source to it anywhere;

    Greg Ubben implemented dc in sed, but reading that is an exercise in

    masochism.

       I want to write a front-end to dc to allow the definition of

    functions and variables with names longer than a single character

    (written, of course, in dc), but so far I've been stymied by the

    aforementioned string awkwardness.

     > Here are a couple of my very old scripts which illustrate what is

    > possible. The first draws a Mandelbrot set and the second Sierpinskis

    > gasket.

     [snip]

       /Nifty/! Thank you kindly for the fascinating examples!

     > Joy examples of both of these have been discussed on this list in the

    > past. Of course the Joy versions are much more elegant, and certainly

    > easier to maintain :-)

        Wholeheartedly agreed!  :)

       Thanks for your response and pointers; they've been interesting and

    helpful!

    	Ben

    -

    [1]:

    http://cpe000103c34069-cm014300001653.cpe.net.cable.rogers.com/weblogs/ben/programming/dc/Prime-Sieve-in-DC.writeback

    --

## John Cowan — 2004-05-01 13:49:48

    Ben scripsit:

     > > Early implementations of the bc(1) calculator, which uses a c like

    > > syntax, simply compiled bc scripts into dc format.

    >

    >    I've heard that from many sources, but so far I haven't been able to

    > track down any open-source implementation of bc with this execution

    > model. I've read through the source code for GNU bc and dc and

    > discovered nothing revelatory. I feel rather silly asking this, but can

    > anyone point me toward the source for a bc implementation that /does/

    > compile down to dc, and/or a the source for a non-GNU dc so I can

     You want the 7th Edition source (now available under a close variant

    of the BSD license), which is online in many places.  One of them is

    http://mirror.cc.vt.edu/pub/projects/Ancient_Unix/PDP-11/Trees/V7/usr/src/cmd/bc.y

    The Caldera (now SCO Group) license is at

    http://www.tuhs.org/Archive/Caldera-license.pdf .

    Note that it's Yacc source with embedded C.  To get it running on modern

    Unix, I needed to make these changes:

    	Change all calls to exit() to exit(0)

    	Change "int in;" in line 19 to "FILE* in;"

    So after "yacc bc.y; gcc -o my-bc y.tab.c; ./my-bc -c" I could type in

    bc statements and watch it spew the corresponding dc code!

    The man page is at

    http://mirror.cc.vt.edu/pub/projects/Ancient_Unix/PDP-11/Trees/V7/usr/man/man1/bc.1

    as you might expect.

    --

    "They tried to pierce your heart                John Cowan

    with a Morgul-knife that remains in the         http://www.ccil.org/~cowan

    wound.  If they had succeeded, you would        http://www.reutershealth.com

    become a wraith under the domination of the Dark Lord."         --Gandalf