Beginning Factor – Introduction
I’ve been involved in the Factor programming language community for about a year now, and am constantly amazed with how productive its contributors are. Large improvements to the language and its libraries are made on a weekly (if not daily) basis, and it’s finally starting to attract some much-deserved attention from the programming community.
The problem is, the language is a huge departure from the norm for most developers and it can be overwhelming to someone just getting started. I would like to help ease that transition by posting on various topics that I know have been confusing to me over the past year.
Note that many topics are covered in the official FAQ — which is well worth a read — and I won’t spend time covering how to install Factor on the 14 or so platforms it supports, but beyond that, I’ll try to give enough information (from basic to advanced) to get you going.
The Basics of the Basics
First of all, Factor is a stack-based language, which means that it uses a stack to store all arguments and returned values from functions (called “words” in Factor). To put that another way, Factor words don’t receive arguments in the traditional manner; all input values that your word needs are expected to already exist on the top of the stack.
What is a Stack?
If you’re unfamiliar with the data structure called a stack, the concept is fairly simple. It centers around the idea of “Last In First Out” (LIFO), meaning the last item placed onto the stack is the first item that will you will get when you remove an item from the stack. You cannot get to the lower items until the all of the items above it have been removed.
I like to picture a stack like a tower of LEGOs. The only thing you can do with it are add another brick to the top (“push” an item onto the stack), or take the top brick off to use it for something else (“pop” an item off the stack). That’s all there is to stacks!
How to Use the Stack
So, now we know that Factor manages its input and output with a stack, but how do we actually use it? Well, when entering data into Factor’s listener, one of two things is happening:
- You are pushing a literal onto the stack
OR - You are calling a word which will consume literals from the stack
Things do get slightly more complicated than that, but for the most part those two rules hold true. The most simple example of this behavior is the ubiquitous hello world program, shown entered directly into Factor’s interactive listener environment:
(scratchpad) "Hello world!" print
Hello world!
To understand what is happening, you can just type the string first, and then execute the print
word later:
(scratchpad) "Hello world!"
--- Data stack:
"Hello world!"
(scratchpad) print
Hello world!
In this particular case, typing the literal string "Hello world!"
will push that value onto the stack; then the word print
, takes a single string off the stack and writes it to the output stream.
The same idea can be applied to simple arithmetic. Like strings, numbers are also literals, so you just have to type them in (separated by spaces) for them to be pushed onto the stack:
(scratchpad) 2 3
--- Data stack:
2
3
NOTE: the stack is displayed in the listener upside-down from the way you’d think, so the bottom number is actually the top of the stack.
…and if you want to add the top two numbers together, the +
word will simply pop two numbers off the stack, add them together, and push the result back onto the stack:
--- Data stack:
2
3
(scratchpad) +
--- Data stack:
5
A Few More Words
If you start messing around in the listener, odds are your stack is going to grow pretty quickly and become unmanageable. There are a few words that are essential to know in order to keep things under control:
drop
( x -- )- removes the top item from the stack and discards it
.
( obj -- )- takes the top item from the stack and prettyprints it
clear
( -- )- removes all items from the stack
(scratchpad) 2 3 -
--- Data stack:
-1
(scratchpad) drop
(scratchpad) 20 5 / .
4
(scratchpad) 2 3 + 6 7
--- Data stack:
5
6
7
(scratchpad) clear
(scratchpad)
Ramifications of Stack-Based Design
From these simple examples, we can observe a couple of important things about Factor:
-
Postfix Notation
When using a stack, passing data becomes implicit and we can assume that all input needed by words already exists on the stack. This naturally lends itself to using postfix notation because you have to push your data onto the stack before you can use it.
This also makes words more concise and unambiguous when compared to infix notation and eliminates the need for copious amounts of parentheses used by prefix notation languages, like Lisp or Scheme.
POSTFIX: 6 5 4 * + INFIX: 6 + 5 * 4 = PREFIX: (+ (* 4 5) 6)
With the infix example above, you’d have to know order of operations rules in order to get the correct answer (or use parentheses to force the matter). When using postfix notation, the fact that multiplication is done first becomes explicit. Prefix notation also gets rid of that ambiguity, but becomes messier and harder to type with the more nesting you add.
-
Calling Words is Implicit
You don’t have to specify that you’re calling a word, you simply use the word. This, combined with postfix syntax, means that you can easily nest words or cut and paste parts of definitions into new words without disrupting the flow of data. This lends to keeping code modular, short, easily testable, and readable.
Your First Word
If you’ve typed in the examples from above and messed around in the listener, then you might want to know how to write your own word rather than just using ones that are predefined. Drawing on what we already know, here’s how to write your first word:
: plus-two ( x -- y )
2 + ;
If you copy and paste that into your listener, than you can use the word plus-two
anywhere you would like to add two to a number on the top of the stack:
(scratchpad) 15 plus-two .
17
Not very exciting, but it gives us a couple more things to talk about…
Syntax Specifics
If you study the word definition, you’ll see that it’s made up of a few elements:
: plus-two ( x -- y )
2 + ;
- A colon (
:
) is used to start the definition of a word. This is required and must have a space after it. - Right after the opening colon is the name of your word, also required.
- Following the name of your word is its stack effect declaration, which is a list of the word’s inputs and outputs separated by
--
and surrounded by parentheses. All words must have a stack effect declaration unless it only pushes literals on the stack. The names of elements in the stack effect declaration don’t make a difference, only the number of elements. That means that( elt elt -- seq )
and( x y -- z )
are the same thing. There are some common conventions for these names, but don’t get caught up by it as I’ll talk more about them in a later article and it won’t change how your program runs. - Next comes the word definition itself, in this case
2 +
. - And the last item is a semicolon (
;
), used to end the word definition. This is required and must have a space before it.
The reason that everything must be surrounded by spaces is that there aren’t any syntax-only elements to Factor…everything is a word! The colon/semicolon, the parentheses, etc. are all just parsing words working together in order to create the syntax.
Next Time
Next time we’ll talk more about stack shufflers, quotations & combinators, details about more datatypes, and more…
If something is unclear or if you’re having any trouble, let me know and I’ll try to help out!
Comments Missing in WordPress Dashboard After 2.5.1 Upgrade
This article has been retired and will no longer be updated. Caveat emptor!
I just upgraded the WordPress installation for ElasticDog to version 2.5.1 and noticed that the Manage Comments page in the administrative Dashboard was not displaying any comments. I only noticed there was a problem when the interface kept telling me there were 9 comments awaiting moderation, yet it would not let me see them. Everything was displaying correctly on the publicly viewable blog pages, but no comments showed up when trying to access them via the Dashboard.
After searching for a bit and checking my sever logs, I found that the upgrade script did not add the proper index to the “comment_date_gmt” column in the comments table for my WordPress database:
Apr 25 18:22:17 php-cgi: WordPress database error Key 'comment_date_gmt' doesn't exist in table 'wp_comment' for query...
The Solution
If you don’t want to wait until the upgrade script gets fixed in a later WordPress release, you’ll have to add the missing index to the database table yourself to get things working again. I’ll demonstrate how to do that using the MySQL command line interface, however, if you’re more comfortable with using phpMyAdmin, see the steps outlined here.
Check for Proper Privileges
First of all, you must have the proper privileges on your WordPress database in order to add an index. To check that, follow these steps:
- Log in to MySQL with whatever account credentials you know.
$ mysql -u root -p Enter password: Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 59202 Server version: 5.0.51a Source distribution Type 'help;' or '\h' for help. Type '\c' to clear the buffer. mysql>
- Specify that you want to access the “mysql” database, then ensure that you do have the privileges to add indexes.
mysql> use mysql Database changed mysql> SELECT user, index_priv FROM user; +------------------+-----------------+ | user | index_priv | +------------------+-----------------+ | root | Y | | elasticdog | N | +------------------+-----------------+ 2 rows in set (0.00 sec)
As long as you see a ‘Y’ next to your username, then you should be good to go.
Add the Index to the Comments Table
Once you have access to an account that can add indexes, then follow these steps to add the missing index:
- Specify that you want to access your WordPress database. If you don’t know the name of your WordPress database, run
show databases;
to see a list of databases you have access to.
mysql> use elasticdog_wordpress Database changed
- Add the index. The table names for WordPress are fairly standard, but if you don’t have one named “wp_comments”, run
show tables;
to see a list of contenders and it should be easy to figure out.
mysql> CREATE INDEX comment_date_gmt ON wp_comments (comment_date_gmt); Query OK, 458 rows affected (0.14 sec) Records: 458 Duplicates: 0 Warnings: 0
- If want to verify that the index was created, run
SHOW INDEX FROM wp_comments;
to list all indexes, and then you can exit out.
If everything went as planned, all will be right in the world and your comments should be viewable through the dashboard once again!
HOWTO: Install WordPress on Nginx
A few years ago, I moved all of my sites from a cheap shared host to a shiny new VPS, and have never looked back. As long as you’re comfortable on the command line, running your own VPS gives you a great amount of flexibility since you have full root access on the server and can configure everything exactly how you want it. That said, it also means that if you want to maintain high performance, you have to keep your resource usage to a minimum.
Apache is a very well-establish web server that can handle just about any situation. Unfortunately, that flexibility comes at the cost of size and relatively high demands on server resources. Nginx (“engine x”) is a lightweight web server/reverse proxy that is very efficient and perfect for hosting WordPress. Read on to see how that can be done…
Step One: FastCGI
First off, Nginx does not provide FastCGI for you (FastCGI is what your web server uses to interact with WordPress’s PHP code), so you’ve got to have a way to spawn your own FastCGI processes. My preferred method is to use the spawn-fcgi
program provided by the lighttpd project. You can use PHP’s built-in FastCGI manager php-cgi
to do the same thing, but it’s not as straight-forward. Plus, if you learn how to use spawn-fcgi
, you can easily adapt it for use with other non-PHP web applications that require FastCGI.
Install spawn-fcgi
To download and install spawn-fcgi
, either use your native package manager (this would be the recommended approach), or run the following commands to install the package from source. All of the building happens in your current directory and the binary will be installed under /usr/local/bin/
with a man page under /usr/local/share/man/
.
$ wget https://www.lighttpd.net/download/spawn-fcgi-1.6.3.tar.bz2
$ tar xvjf spawn-fcgi-1.6.3.tar.bz2
$ cd spawn-fcgi-1.6.3/
$ ./configure
$ make
$ sudo make install
NOTE: If you’re following the steps above verbatim, you will need to have root privileges in order to perform the final installation step…everything else should work fine as a normal user. To gain root privileges, the program sudo
was used in the example above; you may or may not have access to sudo
on your machine.
After spawn-fcgi
has been installed, you can safely remove the build directory and original source file:
$ cd ..
$ rm -rf spawn-fcgi-1.6.3/
$ rm spawn-fcgi-1.6.3.tar.bz2
Run spawn-fcgi
This part will be fairly distribution-specific, but I’ll provide the basic command that you’ll need. What you want to do is find a way to run this command as part of your init scripts so the processes will be spawned automatically when you reboot your server.
/usr/local/bin/spawn-fcgi -a 127.0.0.1 -p 53217 -P /var/run/fastcgi-php.pid -- /usr/bin/php-cgi
-a <address>
→ the IP address to bind the processes to; in our case we want the localhost-p <port>
→ the port number to bind the processes to; pick whatever you want that won’t cause a conflict (technically it would be best to pick a random number between 49152 and 65535), just make sure to remember the number and use that same port for your Nginx configuration file later on-P <path>
→ the location where to save the process id file; you can use this file to easily kill the processes later-- <fcgiapp>
→ the absolute path of the fcgi-application to spawn; in our case we want “php-cgi”, which is provided by your distribution’s PHP package. If you don’t know where to find it, try runningwhich php-cgi
on the command line.
For better security, you can also spawn the processes as a non-privileged user by specifying the user/group with the -u
and -g
flags respectively. For more information on all the available options, run spawn-fcgi -h
or man spawn-fcgi
on the command line.
If you’re interested in seeing a complete example init script that I wrote for use with Arch Linux, you can download it here: fastcgi-php
Step Two: Complete 83.33% of the Famous 5-Minute Install
Next you should download the WordPress files and extract them to their final location on your server. Simply follow steps 1-5 of the Famous 5-Minute Install (the 6th and final step requires that your web server be up and running properly, so we’ll do it later). This guide will assume that you extracted the WordPress core files here: /srv/http/nginx/example.com/
Step Three: Nginx Configuration
To get the web server up and running properly, the file you need to edit is called “nginx.conf” and is installed in different places depending on your Linux distribution. If you install Nginx from source, the default location is /usr/local/nginx/conf/nginx.conf
, however yours may be somewhere else like /etc/nginx/conf/nginx.conf
.
Once you find that file, open it with your favorite text editor and add a server declaration that looks something like this (I’ll cover what each part means after posting the code):
server {
listen 192.0.32.10:80; # your server's public IP address
server_name example.com; # your domain name
root /srv/http/nginx/example.com/; # absolute path to your WordPress installation
try_files $uri $uri/ /index.php;
location ~ \.php$ {
include fastcgi_params;
fastcgi_pass localhost:53217;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
}
You will need to edit the configuration above using your own information. The first part is merely the server declaration where you define what your server’s publicly available IP address is, and what domain name that address is associated with. Next we add some default settings which point Nginx to the absolute path of the WordPress installation on your server.
After that, the try_files
directive automatically checks for the existence of files in order, and returns the first file that is found. The key part here is that WordPress uses the “Front Controller” design pattern, meaning that any request for a file that does not exist on the server should be handled by the main index.php file. So that’s exactly what we do…if the requested URI exists on our local filesystem (images, stylesheets, etc.), then we’ll serve it up directly; if the requested URI does not exist on the filesystem, we forward that request on to index.php.
Last, we add a location block that tells Nginx to dynamically forward PHP requests to the FastCGI processes we spawned earlier. You just have to make sure that the port number matches what we did above. That’s it!
Step Four: Finishing Up
Everything should be good to go…all you need to do now is start your Nginx server process (another distribution specific command), then complete the 6th step of the Famous 5-Minute Install and you should have WordPress up and running on Nginx!
If any of this needs further clarification or you’re just having trouble, drop me a line and I’ll see what I can do to help…