Go to file
Brian Picciano 98bc79a653 add goals
2014-10-01 17:52:13 -04:00
.gitignore initial commit, parser is a go, but the data structures generating aren't actually interesting in any way 2013-05-27 00:16:03 -04:00
README.md add goals 2014-10-01 17:52:13 -04:00

Ginger

A lisp-like language built on the go programming language. The ideas are still a work-in-progress, and this repo is where I'm jotting down my notes.

Goals

I have some immediate goals I'm trying to achieve with this syntax:

  • Everything is strings (except numbers, functions, and data structures). There is no symbol type, atom type, keyword type, etc... they're all just strings.

  • There is no defmacro. Macro creation and usage is simply an inherent feature of the language syntax.

Walkthrough

This is a number which evalutates to 5:

5

This is a string, as it contains no whitespace:

ImJustAString

This is also a string, it can contain anything:

"! I'm the king of the world !"

This is a list. It evaluates to a linked-list of four strings:

(a b c d)

This is a vector of those same elements. It's like a list, but has some slightly different properties. We'll mostly be using lists:

[a b c d]

This is a string

+

: is the evaluator. This evaluates to a function which adds its arguments:

:+

This evaluates to list whose elements are a function and two numbers:

(:+ 1 2)

This evaluates to the number 5:

:(:+ 1 2)

The fn function can be used to define a new function. This evaluates to an anonymous function which adds one to its argument and returns it:

:(:fn [x]
    :(:+ :x 1))

The def function can be used to bind some value to a new variable:

:(:def foo bar)
# Now :foo will evaluate to the string bar

:(:def incr
    (:fn [x]
        :(:+ :x 1)))
# Now :incr will evaulate to a function which adds 1 to its argument

#defn is a shortcut for the above
:(:defn incr [x]
    :(:+ :x 1))

There are also maps. A map's keys can be any value(?). A map's values can be any value. This evaluates to a map with 2 key/val pairs:

{ foo :foo
  bar (:incr 4) }

. is the half-evaluator. It only works on lists, and runs the function given in the first argument with the unevaluated arguments (even if they have : in front). You can generate new code to run on the fly (macros) using the normal fn. This evaluates to a let-like function, except it forces you to use the capitalized variable names in the body (utterly useless):

:(:defn caplet [mapping body...]
    # elem-map maps over every element in a list, embedded or otherwise
    ::(:elem-map
        :(:fn [x]
            :(:if (mapping :(:slice :x 1))
                (capitalize :x)
                :x))
        :body))

#Usage
.(:caplet [foo "this is foo"
           dog "this is dog"]
    :(:println :Foo)
    :(:println :Dog))