If you had the time and will to create a new Language, what would it look like?
My attempt at a functional, yet object oriented language, without the retarded syntax of haskell and without the forced intendation of python:
import IO
import OS
import Text
// braces are only required when a function
// contains more than one statement
def printFmt $format ... = do
IO.WriteStr OS.Stdout (Text.Format $format ...)
// you can define an explicit return type by appending
// ':<TYPE>' to the end of the argument list
def fib $x :int = do
{
if $x > 3 then
{
return (fib (x - 1)) + (fib ($x - 2))
}
return 1
}
// just like in python, all class members are public
class App {
var $name
def App = do
// the 'nothing' keyword works like the 'pass' keyword -
// it does efficiently nothing, and immediately returns
// the default value of the specified returntype.
// example: if the function is returned as 'def foo :int',
// the returned value is 0.
nothing
def setName $n = do
// extra dollarsign is not needed when refering to
// class members.
// to add explicity, members have to be called through '$this'
$this.name = $n
def sayName = do
printLn "name is {0}" $this.name
}
/*
'var $num = 15' could be also written as
def $num = 15
since the last argument is returned on a function without
type specifier.
*/
var $num = 15
printLn "fib({0}) = {1}\n" $num (fib $num)
Name:
Anonymous2010-11-15 22:24
Also, the return type of a function is automatically calculated when an explicit type specifier is missing (calculated from the return statement or the returned type of the last statement).
Haven't really experienced this need in a long time, but there was a time when I did experience similar feelings. Usually when I find that the language doesn't quite express what I want, I just write myself a macro that does just that. This, of course means that I almost never bother inventing new syntax, instead opting for the use of plain S-Expressions (not because inventing or implementing syntax is hard in any way - no, it's easy, but because it usually just gets in the way).
Name:
Anonymous2010-11-16 1:14
It would either be a Lisp or a concatenative language. Anything else is worthless fucking around that will only bite you in the ass, correct?
Name:
Anonymous2010-11-16 1:24
import void # Handles all the standard library functions, classes, structs and cudders.
main = λ(char[][]) {
void.print("Hello, World!");
void.print(void.fact(5));
0; # every function returns the result of the last expression evaluated.
}
fun compose(f : Lambda[$Out, $Int], g : Lambda[Int, $In])=
MakeLambda[Out, In]{return f(g($x))}
expression $x in lambda body($x) uses to introduce argument x of type In(in Lambdas first template argument is output parameter, rest - input). In Lambda[$Out, $Int] it uses to introduce type. Code above is equivalent to
fun [Out, Int, In] //Template function arguments
compose(f : Lambda[Out, Int], g : Lambda[Int, In]) : Lambda[Out,In]
return Lambda[Out, In]{var $x : In; return f(g(x))}
here dollar sign in variable declaration $x : In tells compiler to use x as argument.
notice = after function declaration.
fun name(args) = expr is used to declare function with type = typeof(expr). in this case it's lambda.
fun rot13(in:String)
rvar out = in.map {
var base = match $x
| 'A'..'Z': 'A'.ord
| 'a'..'z': 'a'.ord
| else: return $x
var idx = ($x.ord - base + 13) % 26
return (base+idx).chr
}
rvar is shorthand for "return value variable". Function will have return type of variable out (String in this case).
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
ADT and non-context free grammar. Because of DRY grammar is not context free. Examples
adt Color
| Red
| Blue
| Green
var color0 = Color.Red
var color1 : Color = Red //we know that color1 is Color type, so compiler can tell that Red is actually Color.Red here.
// || is string concatenation
if color == Red //color is Color, therefore Red is Color.Red
printf "Color: " || Red //compiler error
printf "Color: " || Color.Red //ok
It would be assembly, except it would only have like 6 or 8 commands, however to make it Turing complete, and then an address command, which would take either an 8-bit character, or an extra 1-7 more of the same commands to address 16-64 bit values.
It would automatically translate to the bits for values 0-7 if it can be made during complete in that small, 0-15 if it can't, so you'd only need the first 4-bits of an 8-bit value, then more 4-bits to access a specific memory address.
it may be better to allow another character for a generic memory location that the system would dynamically designate, but keep constant, so 0 might refer to the first location in the ram, but 0 in the other setting would refer to the first position available in ram.
I think I would make mine with a huge trie and characters are read and used to move through the tree until a valid operator/function is found, which will also yield it's valency, so that the arguments can be read.
there would be no real difference between different character types, although i guess numbers would be set to their value by default if not overridden.
i think it could have the potential to allow some very nasty code.
Why can you do declare return types but not argument types? What the fuck is the point in declaring return types in the first place when your language isn't statically typed?
Ruby syntax
No forced data types (like pewrlr)
Operator overloading
Runs on a VM
An integrated SQL slang for reading text files
Auto-threading
Integrated DateTime types and calculations
Integrated testing features
Force comments, at least one line per function defined.
Compulsory "IDENTIFICATION DIVISION" (a-la Cobol)
>>13
Typo. The function was supposed to be printFmt, I just forgot to change the calls properly.
>>15
Never heard of functional languages? The type of the argument can be computed at compiletime, so it's statically typed even without adding type identifiers.
Higher and higher level languages get created, until one day we'll just have a robot that will code the app for us after we tell it what we want.
Of course, the next step after that is a robot that tells that robot what to code.Q
My language would have no concept of operator precedence. All operators would be left-associative and have an equal precedence and you'd have to use whitespace to change that, e.g.
# Specification:
# P91 (**) Knight's tour
# Another famous problem is this one: How can a knight jump on an NxN
# chessboard in such a way that it visits every square exactly once?
#
# Hints: Represent the squares by pairs of their coordinates of the form
# X/Y, where both X and Y are integers between 1 and N. (Note that '/'
# is just a convenient functor, not division!) Define the relation
# jump(N,X/Y,U/V) to express the fact that a knight can jump from X/Y to
# U/V on a NxN chessboard. And finally, represent the solution of our
# problem as a list of N*N knight positions (the knight's tour).
my $n = 5;
my $size = $n * $n;
my @track;
my @directions = (1, -1 X 2, -2), (2, -2 X 1, -1);
sub valid_moves($curr, @temp_track=@track) {
my @valid_squares = @directions.map(->$a,$b { ($curr.key + $a) => ($curr.value + $b) }).grep({0 <= all(.key, .value) < $n});
# exclude occupied squares. !eqv doesn't work yet.
@valid_squares.grep({ not $_ eqv any(@temp_track, $curr) });
}
sub knight($square) {
@track.push($square);
return 1 if @track.elems == $size;
# simple heuristic, for move ordering
my @possible_moves = valid_moves($square).sort: ->$a,$b {
valid_moves($a, [@track,$a]).elems <=> valid_moves($b, [@track, $b]).elems;
};
return unless @possible_moves.elems;
for @possible_moves -> $try {
my $result = knight($try);
if $result {
return 1;
} else {
@track.pop;
}
}
}
if knight(0 => 0) {
say "FOUND: " ~ @track.perl;
} else {
say "NOT FOUND";
}