Syntactic Sugar in Dyvil v0.6.0
The Problem
Every Java developer knows how tedious the language can get. Did you ever want to make a factorial method? Well, you know how it works:
You declare it like this:
class Math
{
public static int factorial(int i) { ... }
}
And use it like this at the call site (without taking care of import
declarations and such):
int factorial = Math.factorial(10)
In mathematics, the same thing is a dozen times more concise and easier to write:
10 !
The same applies for pretty much every other (mathematical) operation, e.g. with BigInteger
s:
BigInteger i = BigInteger.valueOf("10000")
BigInteger j = BigInteger.valueOf("100")
BigInteger result = i.multiply(j)
The next problem in Java is generics: We all know this kind of situation:
Map<String, Integer> map = new HashMap();
map.put("abc", 10)
map.put("def", 20)
for (Entry<String, Integer> entry : map.entrySet())
{
System.out.println(entry.getKey() + " -> " + entry.getValue());
}
Long story short: Java is really verbose. This might have some benefits (clarity), but it is mostly just annoying.
The Solution
Ladies and Gentlemen, I give you: Dyvil : fully configurable - infinitely variable.
Dyvil is, like Java, a JVM-based programming language. It has, like Java, a C-like declaration syntax and shares almost all language features with it. However, Dyvil also adds several new features to your favorite programming language. Let’s revisit the examples from above:
1. Operators
One of the main features of Dyvil is it’s ability to treat operators like identifiers and the possibility to define
new operators. Creating the postfix !
is a simply as declaring it like this:
postfix operator !
This allows you use it correctly in expressions without conflicts. The factorial
method can now be written like this:
postfix int !(int i) = ...
The postfix
method modifier is really important in this example: It allows you to call the !
method as if it was a
member of the int
class:
int result1 = 10 !
int value = 12
int result2 = value !
This does not only work for postfix operators - you can also define custom infix and prefix operators as well!
infix operator +- { precedence 120, associativity none }
infix int +-(int i, int j) = i + -j
int result = 1 +- j
You can do this for every type is existence, even standard Java library types like String
:
postfix operator ~~~
postfix int ~~~(String s) = s.length
int result = "abc" ~~~
2. Type Inference
Have you ever caught yourself having to write the same type over and over again? Well, Dyvil’s got you covered with local type inference in the good ol’ C++ style:
auto result = 1 + 1 // inferred to int
auto result = "abc" // inferred to String
This works for arbitrary expressions, even for your beloved Java-8 Lambdas:
auto fun = (int i) => i + 1 // inferred to int => int
auto result = fun(1) // inferred to int
As you can see, Dyvil also supports function literals in the form (type1, type2, ..., typeN) => returnType
or
type1 => returnType
.
Furthermore, you can also use the built-in Tuple syntax:
auto tuple = (1, 2, "abc", false) // inferred to (int, int, String, boolean)
auto tuple_3 = tuple._3 // inferred to String
More about Types in Dyvil can be found in the Wiki.
3. Apply, Update, Subscript and Subscript_=
Methods with the names apply
, update
, subscript
and subscript_=
can be called with a special syntax:
auto fun = (int i) => i + 1
fun(1) // fun.apply(1)
x(1) = "abc" // x.update(1, "abc")
auto map = [ "abc": 1, "def": 2 ] // [String:int], or dyvil.collection.Map[String, int]
auto result = map["abc"] // map.subscript("abc")
map["ghi"] = 3 // map.subscript_=("ghi", 3)
auto list = [ 1, 2, 3 ] as List
auto result2 = list[0]
This is used heavily in the built-in Function types and the Dyvil Collection Framework.
As you can see in the above example, Dyvil also supports Map and List literals as well as primitives in generics.
4. Other Gems
The language features presented here are nothing compared to the full potential of the language. Dyvil also employs a very well-defined Header system as well as dynamic typing, (dynamic) extension methods, case classes, properties, bytecode literals, automatic literal conversion and pattern matching, all of which can be read about in the Wiki.