idk-lang 2
Let's see some code!
The code samples I've provided here are subject to not be valid in
any future implementation of this language. I'm still trying to figure
everything out, and it's hard to go back and change
everywhere where I stated something about this language. So, I don't
think things will change much, but they will be left here to preserve
a record of progress, so I can see what this language really started
out as.
Literals
Here's what the literals look like:
1
# Num
2.0
# Fractional
3e4
# Fractional
5i
# Complex
True
# Bool
False
# Bool
(1, True, "a")
# (Num, Bool, String)
[1,
2,
3]
# [Num] or List<Num>
{1,
2,
3}
# {Num} or Set<Num>
{"a": 1
"b": 2}
# {String: Num} or Dict<String, Num>
"Hello, World!"
# String
Notice the types on the right of each literal expression.
Num,
Complex, and
Fractional are all traits. The type of these
literals is similar to Haskell's typeclasses of the same name. They
represent the most general type that this literal can be. We'll talk
about traits in more detail in a later section.
Bool
is a type with two constructors that take no arguments,
True and
False.
Lists and
Sets are
heterogenous, that is, they only hold objects of the same type. Lastly,
String is
not a trait like
Num and friends, it is a proper class. It can be
instantiated, and cannot be inherited from, unlike traits. We'll talk
about classes in more detail in a later section.
Binary Operators
Here are some basic operators:
1 + 1
# 2
1 - 1
# 0
2 * 2
# 4
1 / 2
# 0.5
3 ^ 2
# 9
Even though we haven't talked about idk-lang's type language yet, we
will use it here for a quick showcase of some of the features of this
language. The type of
+ is
Addable a => a -> a -> a. That is,
+ takes in two objects of the same type
a where the type
a must
inherit the trait
Addable. Since
Num and
String both inherit
Addable, the following expressions are both
valid,
10213674 + 7868297
# 18081971
"Hello, " +
"World!"
# "Hello, World!"
This shows one of the many advantages to using traits in a statically
typed environment. It prevents the creation of over-engineered
syntax to handle the “overloading” of operators on different
types.
Boolean Operators
Lastly, we have the boolean operators:
not True
# False
True and False
# False
True or False
# True
The operator
not has type
Bool -> Bool.
The operators
and and
or both have type
Bool -> Bool -> Bool. These work as expected,
and because of how strict this language is, there is never an implicit
cast or coercion to any type, so these functions only work on booleans.
Comparison Operators
We've seen some basic binary operators:
+ - / * ^. A
valid type for all of these operators is
Num a => a -> a
-> a. That is, they take in two objects of the same type
a that implement the trait
Num,
and return an object of type
a that also implements
that
Num. These are called
Numeric operators.
There is another group of operators called
Comparison operators.
They all have type
a -> a -> Bool. That is,
they take in two objects, both of type
a and the
and they return a
Bool. Now,
a
are
type variables, they represent any possible type.
For example, the following operators are
Comparison operators
1 = 1
# True (structural equality)
1 < 2
# True
1 > 2
# False
1 /= 1
# False
What is special about these operators is that they can be chained for
greater expressive power. For example, this is a valid use of these
operators,
1 < 2
< 3
# True
1 < 2
> 3
# False
1 = 1
< 3
# True
These chains are equivalent to checking that every adjacent pair of
arguments to each operator returns
True. In the
case of function calls inside chains, they are only executed once
per chain.
Partial(ly applied) operators
Another cool feature of operators is that they can be partially
applied, esentially equivalent to Haskell's
operator sections
except without any iterated section support. For example,
(<0)
# A function that returns True if the input is less than
0
(=1)
# A function that returns True if the input is equal to
1
(2*)
# A function that multiplies its input by 2
These can be really expressive when using maps or filters.
The next section is on
forms, where we'll talk about assignment,
if expressions, and
where
expressions.