Most programmers, at some point, daydream about writing their own programming language. This one's mine.
Segment is a dynamic, interpreted language in the spirit of Ruby and Python. It's a little closer to Smalltalk than Ruby: notably, general-purpose blocks are a first-class concept, and it has no built-in control structures or keywords.
Dependency management is a central concept, used to version the standard library. Method lookup is dependent on receiver class and lexical scope, both preventing "dependency hell" - two packages can depend on different versions of a common dependency without conflict - and offering a class extension facility similar to Ruby's refinements.
Considering that the interpreter doesn't even have a main
yet, this is all pure speculation.
- Proper keyword arguments.
- Inheritance by mixin, which, okay, I'm basically lifting wholesale from Ruby. Although I did have some thoughts about isolating instance variables within each mixin, and I'm going to try to keep conventional subclassing out of the language, if I can.
- No
null
,nil
, ornothing
! There will be anOptional
mixin in the core library, included in theSome
andNone
classes, with handy methods for dealing with presence or absence, or iterating like a one-element collection. - Define your own operators and operator-like methods. Operator methods end with one of the standard
*
,+
,/
operator characters and have the precedence of their trailing character. This will let me write anint/
method, for example. - More standard data structures than
Hash
andArray
. I'll likely steal something like Scala's map construction syntax. - Unicode support from the get-go, because it's a giant pain to roll it in later.
- Garbage collection with a proper generational garbage collector, because I've always wanted to write one. Statistics and functionality exposed through an in-language API.
- Maybe JIT compilation with LLVM.
Define classes and methods with the class
and method
methods:
class :Box {
constructor { |value|
@value = value
}
def :value { @value }
# Which is really just a method call:
# self.def(:value, { @value })
}
%box = Box.new(10)
puts %box.value() # => 10
# The %-sigil is for temporary variables.
# It closes that weird Ruby syntax hole where:
#
# foo = 10
#
# ... could mean either "assign 10 to foo", or "call self.foo=(10)".
if (%box.value() == 10) then: {
puts "Hooray!"
} else: {
puts "Oh no!"
}
# Which is really the method call:
self.if(%box.value().==(10), { puts("Hooray!") }, { puts("Oh no!") })
See the examples directory for more samples of what it'll look like.
If you're on a Mac with Homebrew, or a Linux box with apt, you can clone it and run:
script/bootstrap
If you don't have those things, script/bootstrap
is good documentation on what dependencies you'll need to install on your platform of choice. I'm using lemon as a parser generator and ragel for the lexer.
Once you've got that, build it with:
make
...and watch it break. 😉