As always when I’m coding, I’m unsatisfied by the currently available choices. But for a change I’m taking the time to write about it.
Principles
Features for my dream languages:
-
Ruby-like syntax
-
Garbage collected
-
Static typing verified at compile time
-
Type inference
-
Low boilerplate
Rationale
I mostly write code in an IDE: I don’t like to look for things like signatures, precise names… but I want my tools to find them for me.
My current tool of choice is Ruby, I like it because code is concise yet readable, and the OO design is very flexible. On the other hand I love the capabilities provided by static typing: impact analysis, refactoring, and helpful IDE support.
In a nutshell, I’d like to have the benefits of Ruby with the level of tooling you can have in Java when you code with Intellij.
General syntax
pakage net.archiloque.thing
class MyClass < AnotherClass
# Method declaration includes types
def Array<Thing> find_things(Dictionary<Thang, Thung> parameters)
parameters.collect do |key, value|
# value is known to be a thung
value.method_of_thung_object
end
end
# Last value is returned by default
# type checking is done by the compiler
end
# By default types are not nullable
def Something? look_for_something()
# Type declaration is not mandatory, included for readability
SomethingElse? value = look_for_something_else
if value.nil?
value.get.tranform_into_something
else
nil
end
end
end
-
No semicolons
-
Type inference everywhere you can
-
Return last value by default
-
No parens for no-parameter method call
-
Ruby-like blocks syntax
-
Things are not nullable by default
-
Generics
Getters and setters
class MyClass
attr Integer @attribute get set
attr Integer @another_attribute
def constructor()
@attribute = MyOtherClass.new()
end
end
class MyOtherOtherClass
def nil a_method()
my_class_instance = MyClass.new()
# Call the setter
my_class_instance.attribute = 12
# Doesn't compile: no setter
my_class_instance.another_attribute = 12
end
end
-
Attributes are prefixed by
@
-
Attributes should be declared
-
Attributes are private
-
Getters and setters can be specified during declaration
-
Getters and setters have “direct attribute access” syntax
Arrays and Dictionnary
Arrays and dictionnary instanciation and manipulation is present everywhere, so it should use low boilerplate.
Array<Integer> integers = [1, 2, 3]
Dictionary<Integer, String> dictionnary = {1: "YOLO", 2: "YULU"}
Modules
Multi-inheritrance is a mess, so let’s have modules. Encapsulation is a nice principle, but the language should help you to do it and not force it.
module MyModule
attr Integer @attribute
def nil module_method()
end
end
class MyClass
include MyModule
# Make the module attribute available as a local attribute
attr Integer MyModule.attribute
# Expose the module method as a MyClass method
expose MyModule.module_method
def constructor()
end
end
Static duck-typing
The duck typing idea is nice: sometimes you don’t care that an object implements a specific class, but only that it implements a specific set of methods. In static typing languages like java, you can use interfaces, but interfaces must be predesigned, and can’t be retrofited in the stdlib or in external code.
But you could use another approach
class MyClass
def nil a_method()
end
def nil another_method()
end
end
interface MyInterface
interface nil a_method()
end
class MyOtherClass
def nil my_method(MyInterface my_interface)
# …
end
def nil my_other_method(MyClass my_class_object)
# work because even it MyClass doesn't
# explicitly implements MyInterface
# the declaration are matching
this.my_interface(my_class_object)
end
end
Enumerations
Typed enumerations are a nice tools when you have a state machine.
enum MyEnum
attr String @attribute get set
def constructor(String value)
@attribute = value
end
STATE_1 = MyEnum.new("lalala")
STATE_2 = MyEnum.new("lalala")
end
Metaprogramming
QQQQ