Recently Written · git

Forthe

Forth-like DSL.

git clone https://github.com/equwal/Forthe

Log | Files | Refs


README.org (3869 bytes)

1 #+TITLE: Forthe
2 #+AUTHOR: Spenser Truex
3 #+EMAIL: web@spensertruex.com
4 
5 #+BEGIN_QUOTE
6 Go Forth[e] and ye shall find.
7 #+END_QUOTE
8 
9 **** Version 0.0.2
10 
11 Docs available as: [[https://spensertruex.com/eforth][HTML]] | [[https://github.com/equwal/Forthe/blob/master/README.org][ORG-mode]]
12 
13 Code on [[https://github.com/equwal/Forthe][github]]
14 
15 This is an implementation of an elisp-based FORTH. This means that elisp
16 is used to write the function definitions. In fact, no FORTH function
17 definitions are provided at all to the Forthe macro from the library.
18 The main benefit comes from reducing the verbosity of elisp in a small
19 Domain Specific Language the programmer defines.
20 
21 #+BEGIN_SRC emacs-lisp :tangle no
22 (require 'forthe)
23 (defun 8pan ()
24   (interactive)
25   (forthe '((n (lambda () (switch-to-buffer nil)))
26             (d split-window-below)
27             (r split-window-right)
28             (wr windmove-right)
29             (wl windmove-left)
30             (wd windmove-down)
31             (wu windmove-up)
32             (del delete-other-windows)
33             (cf make-frame-command)
34             (nf other-frame))
35           (cf del r r wr wr r d wr d wl wl d wl d wr n
36               wr n wr n wl wl wl wd n wr n wr n wr n wl
37               wl wl wu nf)))
38 #+END_SRC
39 * How does a FORTH work?
40 Forth code is gone through by the pointer moving through the call stack. When a
41 non-function is found, it is added to the argument stack. When a function is
42 found, it uses up the argument stack if it has arguments, or just runs if it is
43 nullary. Nothing else is provided by the implementation.
44 * Why?
45 Needing to simulate a long set of keypresses to create an eight panel frame (37
46 in total), the best option seemeed to be obviously to create a miniature
47 language with 1 or 2 letter abbreviations for each. Any arguments to a function
48 can be passed before it in the list, and there is no need to define a return
49 stack.
50 
51 =M-x 8pan= will produce a new frame with eight panels (emacs-speak:
52 "windows"). Here is how it works:
53 
54 =forthe= is called with two arguments: the environment, name to function
55 bindings, and the Forthe code list. You can see in this example that
56 there are no arguments used, since all of these are nullary functions.
57 Here is how you might use arguments:
58 
59 #+BEGIN_SRC emacs-lisp :tangle no
60 (forthe '((ff . find-file)) ("~/some-file" ff))
61 #+END_SRC
62 
63 Here we ran =(find-file "~/some-file")=. If you need to reuse a FORTH,
64 just define an =*env*= variable:
65 
66 #+BEGIN_SRC emacs-lisp :tangle no
67 (defvar *env* '((>r . to-return-stack) ...))
68 (forthe *env* (forth code here ...))
69 #+END_SRC
70 
71 * Benefits
72 ** Concise code.
73 Elisp's convention of names like:
74 #+BEGIN_SRC emacs-lisp :tangle no
75 org--insert-structure-template-unique-keys
76 #+END_SRC
77 (a real function in the org mode) result in extremely verbose code. Using short,
78 lexical names can reduce code size by a large portion.
79 ** Compiles to Elisp.
80 Elisp is hated by many, and for good reason. It is an outdated and clunky lisp.
81 Many have tried and failed to port Emacs to Common Lisp, without success. Forth,
82 unlike modern lisps, is designed to be easy to implement. Writing a FORTH
83 compiler is in fact a trivial exercise.
84 
85 * Drawbacks
86 ** Elispers might not want to read your Forthe code
87 ** Forthe is not stable
88    FORTH is [[http://www.flownet.com/gat/jpl-lisp.html][space-age technology]], and Forthe is young. Send a pull request.
89 ** Isn't verbose code self-documenting?
90 NO. Documented code is documented. Using short names with the bindings handily
91 available in the same form is equally explicit as writing them out every time.
92 
93 * Contributing
94 Please make sure your contributions are  [[https://github.com/melpa/melpa/blob/master/CONTRIBUTING.org][melpa]]-friendly, and documented in the
95 README. You can use [[http://joostkremers.github.io/pandoc-mode/][pandoc-mode]] to transform the README.org into plaintext =;;;
96 Commentary:=.