[Question]
  [
What general tips do you have for golfing in [Factor](http://factorcode.org)? I'm looking for ideas that can be applied to code golf problems in general that are at least somewhat specific to Factor (e.g. "remove comments" is not an answer).
  
[Answer]
# math.unicode
this thing is a golfing jewel. <http://docs.factorcode.org/content/vocab-math.unicode.html>
Here, I should let it speak for itself.
```
Word    Stack effect    Equivalent   (Byte  Char) Savings (best case)
¬¨       ( obj -- ? )    not           1     2
¬≤       ( m -- n )      2 ^ , 2^      1     2
¬≥       ( m -- n )      3 ^           1     2  
¬π       ( m -- n )      1 ^           1     2
¬º       ( -- value )    1/4 , 1 4 /   1     2
¬Ω       ( -- value )    1/2           1     2
¬æ       ( -- value )    3/4           1     2
√ó       ( x y -- z )    *             -1    0
√∑       ( x y -- z )    /             -1    0
Œ†       ( seq -- n )    product       5     6
Œ£       ( seq -- n )    sum           1     2
œÄ       ( -- pi )       pi            0     0
œÜ       ( -- n )        phi           1     2
‚Ä∞       ( m -- n )      1000 /        4     5
‚Ä±       ( m -- n )      10000 /       5     6
‚Åø       ( x y -- z )    ^             -1    0
‚Öì       ( -- value )    1/3           1     2
‚Öî       ( -- value )    2/3           1     2
‚Öï       ( -- value )    1/5           1     2
‚Öñ       ( -- value )    2/5           1     2
‚Öó       ( -- value )    3/5           1     2
‚Öò       ( -- value )    4/5           1     2
‚Öô       ( -- value )    1/6           1     2
‚Öö       ( -- value )    5/6           1     2 
‚Öõ       ( -- value )    1/8           1     2
‚Öú       ( -- value )    3/8           1     2 
‚Öù       ( -- value )    5/8           1     2 
‚Öû       ( -- value )    7/8           1     2 
```
Those are the simple constants. Now for the functions:
```
Word    Stack effect        Equivalent  (Byte  Char) Savings (best case)
‚àÄ       ( seq quot -- ? )   all?         1    3
‚àÉ       ( seq quot -- ? )   any?         1    3
‚àÑ       ( seq quot -- ? )   none?        2    4
‚àà       ( elt seq -- ? )    member?      4    6
‚àâ       ( elt seq -- y )    ‚àà ¬¨          3    2    
‚àã       ( seq elt -- ? )    swap member? 9    11  
‚àå       ( seq elt -- y )    ‚àã ¬¨          3    2
‚àí       ( x y -- z )        -            -1   0
‚àï       ( x y -- z )        /            -1   0
‚àñ       ( s1 s2 -- set )    diff         1    3
‚àö       ( x -- y )          sqrt         1    3
‚àõ       ( x -- y )          ‚Öì ^          2    2    
‚àú       ( x -- y )          ¬º ^          2    2
‚àû       ( -- value )        1/0.         1    3
‚àß       ( o1 o2 -- ? )      and          0    2 
‚à®       ( o1 o2 -- ? )      or           -1   1
‚à©       ( s1 s2 -- set )    intersect    6    8
‚à™       ( s1 s2 -- set )    union        2    4
‚â†       ( o1 o2 -- ? )      = ¬¨          1    2
‚â§       ( x y -- ? )        <=           -1   1 
‚â•       ( x y -- ? )        >=           -1   1
‚äÇ       ( s1 s2 -- ? )      subset?      4    6     
‚äÉ       ( s1 s2 -- ? )      superset?    6    8
‚äÑ       ( s1 s2 -- ? )      ‚äÇ ¬¨          3    2
‚äÖ       ( s1 s2 -- ? )      ‚äÉ ¬¨          3    2
‚äº       ( o1 o2 -- ? )      ‚àß ¬¨          3    2
‚äΩ       ( o1 o2 -- ? )      or ¬¨         2    3
‚åà       ( x -- y )          floor        2    4
‚åä       ( x -- y )          ceiling      4    6
```
Yes, I did make that table by hand, and yes, I did the math in my head, so there might be some, er, wrong numbers. I'll go write a program to do it for me, now :P
[Answer]
## Treasure trove vocabularies
During my time golfing with Factor, these are the non- auto-use vocabularies that have been the most indispensable to me.
* [grouping.extras](https://docs.factorcode.org/content/vocab-grouping.extras.html) - Group sequences in various ways.
* [math.unicode](https://docs.factorcode.org/content/vocab-math.unicode.html) - Shorter names for math functions, set operations, and useful combinators.
* [math.combinatorics](https://docs.factorcode.org/content/vocab-math.combinatorics.html) - Any time you need to get all the combinations or permutations of something, this is your vocab. Comes with tons of great combinators like `filter-permutations` for even more brevity. `nCk` and `inverse-permutation` come in handy sometimes too.
* [math.primes](https://docs.factorcode.org/content/vocab-math.primes.html) - Useful for prime number questions.
* [math.primes.factors](https://docs.factorcode.org/content/vocab-math.primes.factors.html) - Get the divisors and prime factors of a number.
* [math.matrices](https://docs.factorcode.org/content/vocab-math.matrices.html) - Matrix arithmetic, combinators and other operations.
* [lists.lazy](https://docs.factorcode.org/content/vocab-lists.lazy.html) - Working with infinite lists is sometimes terser than the alternative.
* [sequences.merged](https://docs.factorcode.org/content/vocab-sequences.merged.html) - ~~Mostly for `2merge`, which interleaves two sequences.~~ Use `vmerge` in `math.vectors` instead, since it's an auto-use vocabulary.
* [math.text.utils](https://docs.factorcode.org/content/vocab-math.text.utils.html) - ~~Shortest way to get a sequence of digits from a number.~~ This is no longer true since `>dec` was added to the language. Now `>dec 48 v-n` is the shortest way.
* [math.extras](https://docs.factorcode.org/content/vocab-math.extras.html) - Lots of specialized math words. You may not need them often, but when the task calls for it, there might be a built-in for it in here.
* [spelling](https://docs.factorcode.org/content/vocab-spelling.html) - For the `ALPHABET` word, which is the shortest way to get the alphabet on the stack.
* [english](https://docs.factorcode.org/content/vocab-english.html) - Words for natural language processing.
* [qw](https://docs.factorcode.org/content/vocab-qw.html) - Shorten literal sequences of strings.
* [pair-rocket](https://docs.factorcode.org/content/vocab-pair-rocket.html) - Shorten literal pairs and by extension literal assocs.
* [project-euler.common](https://docs.factorcode.org/content/vocab-project-euler.common.html) - Words commonly needed to solve [Project Euler](https://projecteuler.net/) problems. Don't sleep on the individual problem vocabularies either! I've recently used [project-euler.014](https://docs.factorcode.org/content/vocab-project-euler.014.html) and [project-euler.026](https://docs.factorcode.org/content/vocab-project-euler.026.html) for the `collatz` and `period-length` words.
#### Some useful auto-use vocabularies you may have overlooked
* [math.vectors](https://docs.factorcode.org/content/vocab-math.vectors.html) - A gem of a vocabulary. This lets you do arithmetic with a number and a sequence or two sequences. Plenty of other good stuff in here too. If you find yourself reaching for `2map`, look in here first.
* [math.statistics](https://docs.factorcode.org/content/vocab-.html) - Statistics comes up a lot in golf. `histogram`, `cum-sum`, `differences`, `mean`, and `std` are some of my most oft-used words. There's plenty of other great stuff in there too.
* [combinators](https://docs.factorcode.org/content/vocab-combinators.html) - Mostly for `to-fixed-point`, which applies a quotation to something until it stops changing. Avoid `case` and `cond`, as they are far too verbose.
* [combinators.random](https://docs.factorcode.org/content/vocab-combinators.random.html) - Conditional words based on probability instead of booleans. Extremely useful when called for.
* [generalizations](https://docs.factorcode.org/content/vocab-generalizations.html) - Allows you to shuffle the stack in a general way. `dupn` and `repeat` have been especially helpful in golf.
* [sequences.generalizations](https://docs.factorcode.org/content/vocab-sequences.generalizations.html) - Words that can apply to any number of sequences. `narray` is also very useful for golf at times.
* [sequences.extras](https://docs.factorcode.org/content/vocab-sequences.extras.html) - Words here can shorten your code compared to composing `sequence` words.
* [sequences.deep](https://docs.factorcode.org/content/vocab-sequences.deep.html) - Traverse and flatten nested sequences.
* [assocs.extras](https://docs.factorcode.org/content/vocab-assocs.extras.html) - Excellent words for working with assocs.
* [interpolate](https://docs.factorcode.org/content/vocab-interpolate.html) - This can sometimes be shorter than `formatting` words like `printf`.
#### And for those just getting started
* [kernel](https://docs.factorcode.org/content/vocab-kernel.html) - Stack shuffling, loops, conditionals, data flow combinators, and other critical functionality. This is the core of the language. Start here.
* [math](https://docs.factorcode.org/content/vocab-math.html) - Arithmetic.
* [sequences](https://docs.factorcode.org/content/vocab-sequences.html) - Collections. Factor takes the approach of having different implementations all fall under the same `sequence` type, hence the words in this vocabulary will work on most types of collections.
* [formatting](https://docs.factorcode.org/content/vocab-formatting.html) - String interpolation.
* [assocs](https://docs.factorcode.org/content/vocab-assocs.html) - Associative arrays (dictionaries).
With just these five vocabs, you'll get a starting point similar to what most other languages give you.
[Answer]
Factor is impossible to golf. If you're set on winning, don't use it.
---
I don't just mean it's verbose, like Java or C# or Scala. I mean, because of its functional style, there's a small number of ways to write a given program, and `words are long` and `whitespace is not your friend`, so it's a bad target, worse than LISP.
Factor's power is in its object model, which is highly verbose. I golf in it because I think it's a cool language, and I enjoy learning it. 
---
The `::` and `M::` words replace the normal compile word `:`, so that a function has access to lexical variables. 
[The docs on lexical vars](http://docs.factorcode.org/content/article-locals-examples.html).
Why use these over `:`? Because often, referring to variables by name will be shorter than stack-shuffling with `dup swap rot drop over nip etc`.
[Answer]
## You are free to trash stdout and stack under the top...
... as long as your submission is a function and the result is returned on the top of the stack.
### Simple example
`.` is shorter than `drop`, and `. .` is shorter than `2drop`. (Almost) any object that you will encounter while golfing is printable via `.`, and it has the effect of removing the top item of the stack.
### A real-golfing example
(a solution for [Is this number a factorial?](https://codegolf.stackexchange.com/questions/121731/is-this-number-a-factorial), found by golfing [user's answer](https://codegolf.stackexchange.com/a/220863/78410))
```
[ 1 0 [ 1 + 3dup * 3dup > ] loop . = ]
```
[Try it online!](https://tio.run/##JYxLD4IwEITv/Io5a0J4@QhGr4YLF@PJcGjqIo2lraUciPG31wKH@XayOzst405bf79V9bVEz1y3IG6XvWBywECfkRSnAcaSc5OxQjm8ySqSkJrPmdZO659l6hWSQuMUVXUJJ3QUfZEiQ44CO@xxwBFZgTRLglL8/COcE8zcIn@OBpt1XNCEfm0Q44zG92x2XBKz/g8 "Factor ‚Äì Try It Online")
This is an extreme use of `3dup`s. It stuffs up a lot of stack items every time it is called, but it is valid (because the desired result is at the top of the stack) and correct (because it keeps the loop invariant for top three items).
Loop invariant:
```
( x prod idx )
1 +
( x prod idx+1 )
3dup *
( x prod idx+1 x prod' )  ! prod' = prod * (idx + 1)
3dup >
( x prod idx+1 x prod' idx+1 x>prod' )
```
Since `loop` consumes the boolean at the top on each iteration, the top three items at the start of the next iteration are `( x prod' idx+1 )`.
[Answer]
When converting between numbers and strings, the
```
string>number
number>string
```
words can be shortened to:
```
dec>
>dec
```
respectively (thanks, chunes, again!).
There are also:
* `bin>` and `>bin` for binary
* `oct>` and `>oct` for octal
* `hex>` and `>hex` for hexadecimal
that are all shorter than `n base>`, if they happen to suit your needs!
And if you need integers, use `1 /i` instead of `>integer`:
```
5 3 /i
5 3 / >integer   = .
=> t
5.77 1 /i
5.77 >integer    = .
=> t
```
---
EDIT:
If it's about printing, keep an eye on these too:
```
.b ! prints a number in binary
.o ! prints a number in octal
.h ! prints a number in hexadecimal
```
[Answer]
## Inline whatever you can.
All words need ***correct*** stack effect declarations in order to compile.
```
: hello ( -- ) "Hello, World!" print ;
```
These are *long*, even if you use single-char identifiers.
```
: m ( a b c d -- e f ) dup [ asd? ] bi swap = ;
```
Unless you use something so often that the benefits outwiegh the costs, inlining is often shorter, and `: p ( a -- ) print ;` aliasing doesn't save bytes.
[Answer]
# string literals are special
I never realised this before, but `"strings"` are rather special to the parser.
```
"asd""abc"
```
is equivalent to:
```
"asd" "abc"
```
and
```
URL" a"split
```
is the same as
```
URL" a" split
```
This is perhaps the only time whitespace isn't necessary in Factor, and also works for `URL" "`, `DLL" "`, `P" "`, `SBUF" "` and the others handled by `parse-string`, as pointed out by @fedes. in the comments.
**Note well** that the opening quote-like marker *must* be preceded by whitespace.
The following are considered one word:
```
filter"asdasd"map
filter"asdasd"
```
And you will get a `No word <blah> found in current vocabulary search path` error.
[Answer]
# Get used to multiple ways to write things
Usually this means to write something using high-level combinators vs. low-level combinators and/or stack shuffle words. In some cases the former wins, in others the latter wins. Therefore, in order to push Factor golf to the limits, it is good to know both and pick the one that turns out shorter.
### (Re-)Using values in the stack
For reusing single value, shuffle words usually win (because [Factor has a large variety of them](https://docs.factorcode.org/content/vocab-kernel.html)):
```
( n -- np nq) [ p ] [ q ] bi
( n -- np nq) dup p swap q
( n -- np nq nr ) [ p ] [ q ] [ r ] tri
( n -- np nq nr ) dup p over q rot r
( n -- np nq nr ns ) { [ p ] [ q ] [ r ] [ s ] } cleave
( n -- np nq nr ns ) [ p ] [ q ] [ [ r ] [ s ] bi ] tri
( n -- np nq nr ns ) dup p over q pick r roll s
```
But the situation is somewhat different for two or more values, because [spread](https://docs.factorcode.org/content/article-spread-combinators.html) and [apply combinators](https://docs.factorcode.org/content/article-apply-combinators.html) can save a copy or shuffle:
```
( m n -- mp nq ) [ p ] [ q ] bi*
( m n -- mp nq ) [ p ] dip q
( m n -- mp nq ) q swap p swap
( m n -- mnp mnq ) [ p ] [ q ] 2bi
( m n -- mnp mnq ) [ p ] 2keep q
( m n -- mnp mnq ) 2dup p -rot q
```
I can't list all possible combinations here, and one or two shuffle words can be optimized out depending on context. The lesson here is to find out multiple expressions that do the same thing stack-effect-wise.
### Conditionals and loops
Factor has many ways to express some variation of [if](https://docs.factorcode.org/content/article-conditionals.html), [while](https://docs.factorcode.org/content/article-looping-combinators.html), and [boolean logic](https://docs.factorcode.org/content/article-booleans.html). But it also has higher-level combinators to express various common patterns: [`sequences`](https://docs.factorcode.org/content/article-sequences-combinators.html) has `map`, `map-index`, `reduce`, `filter`, `partition` (I believe these are self-explanatory), `accumulate` (cumulative reduce), `replicate` (run n times and collect intermediate values), and `produce` (run until false and collect intermediate results). [`combinators.to-fixed-point`](https://docs.factorcode.org/content/word-to-fixed-point,combinators.html) runs until fixed point is reached. [`math.times`](https://docs.factorcode.org/content/word-times%2Cmath.html) repeats a lambda for the given number of times.
Check if some of these high-level combinators work for the task given. If so, try to use them. Otherwise, use the simplest construct: `?` or one-branch variations of `if` for a conditional, `loop` for an unbounded loop, `times` for simple repetition (not involving a sequence or range).
### Bonus: Minimize stack item duplications and reorders
When using shuffle words, every time a shuffle word is used, you get +4~6 bytes. Try to minimize their use by duplicating multiple items at once (`2dup`, `3dup`) and reordering inputs and intermediate states. Sometimes multiple library words do the same job but with different input order (e.g. `each` vs. `reduce`); exploit them when possible.
[Answer]
# `split` doesn't need a `string` sequence as an argument
Or, more accurately / generally:
# Factor strings are really just sequences of character values
Meaning string operations work on sequences of chars too
... which is important because, for instance, `" " split` will split a char-array on the number 32.
More directly, this:
```
>string " " split
```
is exactly equivalent to
```
" " split
```
While being 8 chars longer.
[Answer]
# quotations are lambdas, abuse them
Most challenges can be solved with one word definition because of Factor's functional, applicative nature.
I just had the sudden realisation that `[ quoting ]` code is the equivalent of a lambda definition in other languages.
I don't know why I didn't think of this before...
A normal word definition:
```
: f ( a c -- b ) asd asd ;
```
Lamba'd:
```
[ asd asd ]
```
You can do everything inside a `[ quotation ]` that you can inside a `:` word.
[Answer]
The [`infix` vocabulary](http://docs.factorcode.org/content/article-infix.html) is pretty cool.
It allows for infix notation math, which sounds lame since Factor's RPN, but:
```
IN: scratchpad USE: infix
IN: scratchpad [infix 5-40/10*2 infix] .
-3
```
For longer expressions it's much shorter than RPN because of whitespace, but you'll need to overcome the `[infix` syntax's length.
It also allows Python-style slicing:
> 
> 
> ```
> USING: arrays locals infix ;
> [let "foobar" :> s [infix s[0:3] infix] ] . 
> "foo"
> 
> ```
> 
> Additionally, you can step through sequences with seq[from:to:step]
>  notation. 
> 
> 
> 
> ```
> USING: arrays locals infix ; 
> [let "reverse" :> s [infix s[::-1] infix] ] . 
> "esrever" 
> 
> USING: arrays locals infix ; 
> [let "0123456789" :> s [infix s[::2] infix] ] . 
> "02468"
> 
> ```
> 
> 
[Answer]
# Take advantage of auto-use
Some people were already implicitly using this to discount imports. Now [it is official](https://codegolf.meta.stackexchange.com/a/20514/78410) (unless the consensus changes). No more `USING: kernel math math.functions sequences ;` -- you can exclude most commonly used library imports from byte count.
Caveats:
* Actually check that the code does work with auto-use enabled. It can't load obscure libraries (e.g. `xxx.private`), and it cannot load if the word is found in multiple libraries.
* If you don't have Factor installed on your machine, you can still check by entering your submission in the code section [on this TIO](https://tio.run/##qyrO@J@cWKJgp1Cnr5eWmFySX6RblKxgY6Pg6u/GFRrsaqVQkFhUnFqkkFhakq9bWpzKBZKAaSnOLy1KToVqhOr6b6ig9x@kSD@/oEQfIgWl0HX8BwA). (Make sure the entire code has no stack effect, i.e. `( -- )`.) If it runs without error, your submission is valid.
[Answer]
## Use linked lists when appropriate
Using [linked lists](https://docs.factorcode.org/content/vocab-lists.html) is shorter than using arrays when the code involves a lot of dissection at the start (and you don't need sophisticated sequence operations):
```
first (5)              > car (3)
rest (4)               > cdr (3)
second (6) > 1 nth (5) > cadr (4)
prefix (6)             > cons (4)
swap prefix (11)       > swons (5)
unclip (6)             = uncons (6)
unclip swap (11)       > unswons (7)
```
Note that you don't need `USE: lists` because it is `auto-use`d by default.
If you see a good Haskell answer which uses pattern matching on a list, there is a good chance that a linked-list based solution is shorter in Factor too.
[Answer]
## Use fried quotations to build sequence literals
Occasionally, you may need to build sequences with a mix of arguments and constants. It's shorter to do this
`'[ 1 _ 1 ]`
than this:
`1 1 swapd 3array`.
`quotation` is an instance of `immutable-sequence`. All sequence words work on them as long as they do not mutate. For instance, you can do the following, no problem:
`4 '[ 1 _ 1 ] { 3 4 5 } v+`
Keep in mind many words use the type of the first argument (as is the case with `v+`) as an exemplar for what type the result should be. This is usually unimportant but may occasionally be useful to know.
Here is a real-world example of when this was useful in a golf: <https://codegolf.stackexchange.com/a/226034/97916>
[Answer]
# Dip > Swap... so make a call
Idiomatic code uses quotations and `dip`, but short code uses `swap`. Look, you can have an extra swap per two `dip`s.
```
[ dip ] [ dip ] [ dip ] [ dip ] [ dip ]
swap swap swap swap swap swap swap swap
```
However, sometimes trading `swap` for `dip` makes the code longer in other places, so it's a bit of a re**Factor**ing job.
[Answer]
# find all the higher-order functions and use them, often
Factor is *full* of higher-order functions that take `[ quotations ]` or `other-words` and work on sequences / other data.
For example, to take an IP address as a string and sum its fields, you could do:
```
"." split [ 10 >base ] [ + ] map-reduce 10 base>
"." split [ 10 >base ] map 0 + reduce 10 base>
"." split [ 10 >base ] map sum 10 base>
```
Notice that fancy `map-reduce` is actually longest here because of `[ quotation ]` syntax, but there's already a `sum` word for that anyways, which is far shorter.
Here's a place `map-reduce` is shorter:
```
[ "." split [ 10 base> ] [ [ 256 * ] dip + ] map-reduce ] bi@ - abs 1 + ]
[ "." split [ 10 base> ] map 0 [ [ 256 * ] dip + ] reduce ] bi@ - abs 1 + ]
```
Can't use `sum` there.
[Answer]
The following are equivalent
```
[ 1 2 3 ] [ 1 + ] map V{ } clone-like
[ 1 2 3 ] [ 1 + ] V{ } map-as
```
It's just `map-as` and the other `-as` words (`zip-as`, `map-as`, `accumulate-as`, etc) are usually shorter than an `obj clone-like` if you're going to use them anyways.
[Answer]
The following are equivalent:
```
1 '[ _ blah ]
1 [ blah ] curry
```
It's just that the top one is shorter by three bytes.
]