The more I use Elixir, Javascript, and Coffeescript and expirement with languages like Go and Scala the more I think about what an ideal programming language would look like. I would like to see a language with...
- Mostly explicit syntax that is similar to JS/Lua
- Minimal surface area like Go
- Compiles to Erlang and Javascript
- Immutable "JSON-like" data structures... Map, List, Number, String, Null
- Functional only
- Loosely typed
- Implicit lexical scope a la Coffeescript
- Modules like Elm/JS that are per-file and require types (for tools/package mgmgt)
- Built in package manager, build tool, licensing, config, and formatting tools (like mix/go-fmt/etc)
- Obvious, but not seamless, JS/Erlang interop
- Uses dot notation as an equivalentish to Elixir pipe operator like Luna
- No macros or namespace dumping magic
- Elegant pattern matching
- Uses Github as package repo and Elm-like auto-semantic versioning
- Nearly non-existent standard library (but "official" libs published to GH/Gitlab)
- Snake cased
- Actor model concurrency (with CSP-like libs e.g. Task in Elixir)
- Single quoted string that act like template string with #{} interpolation
- Implicit returns
- Constant case for global constants automatically filled with environment variables
- First-class inline docs, tests, examples etc. like Elixir with IDE integration like Wallaby.js
- Function tags @pure, @doc, @spec, etc.
- GraphQL language built-in? Or is that too Scala w/ builtin XML
Might look something like this...
import each, map, last from @lang/enum
import reduce from @lang/array
###
Splits the string into a list of characters
@public (string) -> [string]
@spec
chars("Apple") == ['A', 'p', 'p', 'l', 'e']
###
chars = (str) ->
str.map((char) -> char)
###
Adds two strings together
@public (string, string) -> string
@spec
"Apple".concat("Banana") == "AppleBanana"
###
concat = (str, add_str) ->
all_chars = str.chars
add_str.chars.each((char) -> all_chars.push(char))
all_chars
to_array = (str) ->
str.map((char) -> char)
split = (str, splitter) ->
str.to_array.reduce((char, memo) ->
case char
when splitter then memo.concat(char)
else memo.concat(char)
)
import model, field from lib/model
import col, find_one, to_array from lib/database
###
Resolver function for an artist given an artwork
@public (map) -> map
@spec
import @craigspaeth/mongo_lang as mongo
mongo:connect()
mongo:insert({ name: "Andy Warhol" })
artist = resolve_artist({ artist_id: objectid() })
artist:name == "Andy Warhol"
###
resolve_artist = (artwork) ->
col('artists').find_one({ _id: artwork:artist_id })
resolve = (args) ->
col('artworks').find_one({ _id: args:_id }).to_array()
###
GraphQL schema metadata
@public -> map
###
metadata ->
{
args: {
id: 'string'
}
fields: {
title: {
type: 'string'
},
artist: {
type: 'artist',
resolve: resolve_artist
}
}
}
import @graphql/server as graphql
import lib/schemas/artwork as artwork
server = graphql:new({ artwork })
server:listen(5000)