# Factor Introduction

### by "Blag" - Senior Developer Evangelist ## Basic Concepts

### Comments start with an "!" but they must be followed by a whitespace...

```
! This a comment in Factor

```

```
1 2 3 4 5
```

```
. . . . .
```
```
5 4 3 2 1
```

## Basic Arithmetics

### In Factor...we use the Polish Reversed Notation...

```5 4 + .
9
```

```5 4 + 2 - .
7
```

## Stack Manipulation

### Working with the stack it's not easy...that's why we have some nice and useful functions...

```5 dup * .  ! duplicates the top of the stack
25
```

```3 8 swap - . ! swaps the top with the second item
5
```
```1 2 3 rot . . . ! rotates the top 2 elements
1 3 2
```

```3 5 drop 2 + . ! removes the top item
5
```

```1 2 3 nip .s ! removes the second item
1 3
```

## Advanced Stack Manipulation

```1 2 3 pick .s ! duplicates the last item into the
! top slot )
1 2 3 1
```

```1 2 3 over .s ! duplicates the second item into the
--top slot )
1 2 3 2
```

## Seeing double

### This operations handle the stack in pairs...actually they even go up to 4X

```1 2 3 2dup
1 2 3 2 3
```

```1 2 3 4 2nip
1 4
```
```1 2 3 2over
1 2 3 2 1
```

```1 2 3 4 2drop
1 2
```

## Variables

### In Factor, everything should be kept on the stack...so variables are not exactly the way to go...this is how you create a global variable...

```SYMBOL: name
"Blag" name set-global
name get-global .

"Blag"
```

## Words

### Words are like functions...and they help us to not only organize but to control execution...

```! This word will read two elements from the
! stack (x and y) and will return the sum (z)
: sum_nums ( x y -- z ) + ;
```

```! This word will read two elements from the
! stack (x and y) and will return the sum (z)
! taking from the stack
: sum_nums ( x y -- ) + . ;
```

```4 5 sum_nums

9
```

```1 2 3 sum_nums

--- Data stack:
1
5
```

## Quotations

### Something really cool about Factors are "Quotations" which basically are pieces of code pushed on the stack...

```[ 2 + ]

4 swap call .

6
```

## Lists

### When we create lists, they go to the stack as one element...

```{ 1 2 3 }

--- Data stack:
{ 1 2 3 }
```

### We can access each element of the list, but...we loose the other values...

```{ 1 2 3 }

0 swap nth .

1

--- Data stack:
```

### Or we can access all elements...

```{ 1 2 3 } [ 2 * . ] each

2
4
6
```

```{ 1 2 3 } [ 2 * ] map

--- Data stack:
{ 2 4 6 }
```

## Conditionals

### The only conditionals are IF...and CASE...although CASE doesn't make too much sense for me...

```25

20 > [ "Too big!" print ] [ "Too small!" print ] if

"Too big!"
```

## Loops

### Loops will repeat a command...

```3 [ "Factor!" print ] times

Factor!
Factor!
Factor!
```

### Here's a more complicate and naive way of doing a loop...

```0 [ dup 3 < ] [ 1 + dup "Factor!" print ] produce 2drop

Factor!
Factor!
Factor!
```

## While

### Yep...we can use While as well...

```0 [ dup 3 < ] [ 1 + "Factor!" print ] while drop

Factor!
Factor!
Factor!
```

## Fibonacci List

### Load up the Listener and type the following...

```USE: tools.scaffold

"fibo" scaffold-work  ! You might get an error saying
! that "fibo" doesn't exist...
! ignore that -:)
```

### Edit the "fibo.factor" file that was generated...

```! Copyright (C) 2018 Blag.
! See http://factorcode.org/license.txt for BSD license.
USING: math prettyprint kernel io math.parser command-line
namespaces sequences ;
IN: fibo

<PRIVATE

: ask-number ( -- ) "Enter a number: " print ;

: read-number ( -- n ) readln string>number ;

: list_fibo ( x -- )
1 0
pick 1 + [ dup . over over + rot drop ] times 3drop ;

PRIVATE>
```
```: fibo ( -- ) ask-number read-number list_fibo ;

: fibo-run ( -- ) fibo ;

MAIN: fibo-run
```

### "list_fibo" Let's explain this in parts...using 5 as input...

```5 1 0 pick 1 +

--- Data stack:
5
1
0
6 ! pick grabs 5 and then adds 1
```

### 6 will used as a parameter for the loop that follows...meaning, it will be executed 6 times...and of course this 6 will dissapear from the stack...

```dup . over over + rot drop
```

### Here we duplicate and print the first value from the stack. "Over" grabs the middle value and duplicates it, and we call it twice to then sum the values. "rot" will rotate the top two elements and finally "drop" get rids of the last value...

```times 3drop
```

## Making an LED Number App

### Use "led_numbers" scaffold-work

```! Copyright (C) 2018 Blag.
! See http://factorcode.org/license.txt for BSD license.
USING: prettyprint kernel io math math.functions
sequences generalizations math.parser
command-line namespaces ;
IN: led_numbers
```
```<PRIVATE

: first_line ( x -- )
dup 0 = [ " _  " write ] [ ] if dup 1 = [ "  " write ] [ ] if
dup 2 = [ " _  " write ] [ ] if dup 3 = [ "_  " write ] [ ] if
dup 4 = [ "    " write ] [ ] if dup 5 = [ " _  " write ] [ ] if
dup 6 = [ " _  " write ] [ ] if dup 7 = [ "_   " write ] [ ] if
dup 8 = [ " _  " write ] [ ] if dup 9 = [ " _  " write ] [ ] if
drop ;

: second_line ( x -- )
dup 0 = [ "| | " write ] [ ] if dup 1 = [ "| " write ] [ ] if
dup 2 = [ " _| " write ] [ ] if dup 3 = [ "_| " write ] [ ] if
dup 4 = [ "|_| " write ] [ ] if dup 5 = [ "|_  " write ] [ ] if
dup 6 = [ "|_  " write ] [ ] if dup 7 = [ " |  " write ] [ ] if
dup 8 = [ "|_| " write ] [ ] if dup 9 = [ "|_| " write ] [ ] if
drop ;
```
```: third_line ( x -- )
dup 0 = [ "|_| " write ] [ ] if dup 1 = [ "| " write ] [ ] if
dup 2 = [ "|_  " write ] [ ] if dup 3 = [ "_| " write ] [ ] if
dup 4 = [ "  | " write ] [ ] if dup 5 = [ " _| " write ] [ ] if
dup 6 = [ "|_| " write ] [ ] if dup 7 = [ " |  " write ] [ ] if
dup 8 = [ "|_| " write ] [ ] if dup 9 = [ " _| " write ] [ ] if
drop ;

: numdigits ( x -- x ) log10 1 + 1 /i ;

: split ( x -- x ) dup numdigits [ 10 /mod ] replicate swap drop ;

: lines ( x x x -- ) [ first_line ] each "" print
[ second_line ] each "" print
[ third_line ] each "\n" print ;
```
```: leds ( x -- ) split reverse dup dup lines ;

: ask-number ( -- ) "Enter a number: " print ;

: read-number ( -- n ) readln string>number ;

PRIVATE>

: led_numbers-run ( -- ) ask-number read-number leds ;

MAIN: led_numbers-run
```

## Decimal to Romans

### USE "romans" SCAFFOLD-WORK

```! Copyright (C) 2019 Blag.

! See http://factorcode.org/license.txt for BSD license.

USING: math prettyprint kernel io math.parser

command-line namespaces sequences ;

IN: romans
```
```<PRIVATE

CONSTANT: roman_values { 1000 900 500 400 100 90 50 40 10 9 5 4 1 }

CONSTANT: roman_keys { "M" "CM" "D" "CD" "C" "XC" "L" "XL" "X" "IX"

"V" "IV" "I" }

: ask-number ( -- ) "Enter a number: " print ;
: read-number ( -- n ) readln string>number ;
: get-values ( x -- x ) roman_values [ /mod swap ] map swap drop ;
: get-keys ( x -- ) roman_keys [ <repetition> concat ]
2map "" concat-as . ;

PRIVATE>
```
```: romans-run ( -- ) ask-number read-number get-values get-keys ;

MAIN: romans-run
```