42

If you were to design a programming language, how would you do it? What features would you put in? What would you leave out? Statically or dynamically typed? Strongly or weakly typed? Compiled or interpreted? Justify your answers.

10
  • 13
    This question is too vague. Language features can't really be discussed until the purpose of the language is determined.
    – blucz
    Sep 25, 2010 at 9:04
  • 1
    If you can vote and think this is a useful question or it have useful answers below, please vote up. StackExchange sites need votes to build a good community. You can give 30 votes per day, don't waste them. Specially users with high reputation and low counting votes given please read this: meta.programmers.stackexchange.com/questions/393/…
    – Maniero
    Oct 5, 2010 at 22:24
  • 3
    I would create a very high-level language with one method: public void DoWhatIMeant();
    – Dave
    Oct 6, 2010 at 18:16
  • 6
    the ideal programming language?... I would get the compiler to read my mind and generate a program exactly how i want it..:) might take a while but it would be worth it.
    – WalterJ89
    Oct 7, 2010 at 17:05
  • 2
    Compilation and interpretation are traits of ... well, the compiler or interpreter (duh), not the language. All languages can be implemented by a compiler or an interpreter. And in fact, pretty much all of them are. There are compilers for Ruby, Python, ECMAScript, PHP, there are interpreters for C, C++, Java, Haskell, ... Jun 7, 2011 at 23:51

15 Answers 15

55
  • I definitely think that functional programming languages will catch on, so my language will be functional. See Taming Effects with Functional Programming

  • I think the CPUs soon will have hundreads of cores, and threads will he a hell to manage. So the Actor Model is a must instead of threads. See Erlang - software for a concurrent world

  • I also think that OOP has failed, the communication between objects was assumed to be asynchronous. So I think we need message passing, with immutable messages. Send and Forget. As in the Actor model. See Object Oriented Programming: The Wrong Path?

  • I think that it would be good to have static typing, so errors are catched earlier in the development cycle. But I would use type inference as in Haskell, so that the developer don't need to write the type everywhere in the code as in C, C# and Java. See Learn You A Haskell for Great Good

  • I would also design a great UI library, with declarative layout, as in WPF and Android. But I would like to have it as in Functional Reactive Programming.

So my language would be like the concurrency in Erlang but with the typing as in Haskell and a GUI framework as in WPF.NET.

11
  • 4
    sounds like Scala, actually, except for maybe the great UI library.
    – Ape-inago
    Dec 6, 2010 at 8:03
  • I thought scala had message passing and actors. I guess I don't how that relates to OOP.
    – Ape-inago
    Dec 6, 2010 at 13:07
  • @Jonas: looks great :) I don't know much about the Actor Model, is it similar to what Go did with the goroutines ? Dec 20, 2010 at 12:08
  • 1
    The only thing I'm skeptical about is static typing. I'd definitely prefer strong instead of weak typing, but sometimes static typing is too restrictive. But I'm not familiar with Haskell, and I've heard only good things about its typing system :)
    – sakisk
    Jan 29, 2012 at 19:24
  • 1
    OOP's failure, frankly, is that hardly any "object oriented" language actually implements it. Most simply shoehorn an object model into a procedural language and call it a day. I do wish Smalltalk had caught on more itself, rather than prompting every procedural-language weenie to say "Eh, we can do something kinda-sorta-maybe like that" and manage to miss the point of OOP entirely.
    – cHao
    Dec 16, 2014 at 21:38
21

Note: I've used C-like syntax to describe features in this post, but I'm not picky about the syntax itself as long as it's not something ridiculous like all keywords being CAPS.

1. Typing system

The number one feature that I would want in a language is static typing with optional dynamic typing. The reason is that static typing allows you to a) catch errors early rather than late and b) most code is implicitly statically typed, whether or not the language makes the distinction. However, there are several use-cases where dynamic typing is extremely useful. For example, when reading data from a file, you often have fields of varying types, and dynamic typing makes heterogeneous containers easy. So, my ideal language would have something like this:

//variable declarations
int anInt = 42 //anInt is now irrevocably an integer and assigning another type to it is an error
vartype aVariable = 42 //aVariable is currently an integer, but any type can be assigned to it in the future

//function definitions
int countElements(Collection c)
{
  return c.count();
} 

//c HAS to be a collection, since countElements doesn't make sense otherwise

void addToCollection(Collection& c, vartype v) 
{
  c.append(v)
}

//c is passed by reference here

2. Compiled vs. Interpreted

I'd like the language to be either compiled ahead of time, or JIT compiled, but not purely interpreted, speed being the reason. This ties in to point 1, since an optimising compiler/jitter will have a much easier time optimising statically typed code, and dynamically typed code could simply be left as-is.

3. Closures

The language must support functional programming constructs, and functions should be first-class objects.

4. Object-oriented

The language should allow you to write object-oriented code, but simple imperative code should be allowed too. i.e., it should be possible to write a hello world program like so:

int main(string<> args=null)
{
  printf("hello, world"); 
  return 0;
}

// this code also demonstrates two other features,
// default arguments for functions (not explained further)
// and immutable lists like string<> (see 6. Built-in datatypes)

5. Namespaces

Namespaces are a good thing. Very little stuff should go into the global namespace. But if you must put stuff in the global namespace, you can (ala C++).

6. Built-in datatypes

The language must have, as built-in datatypes, the following constructs:

  • An int datatype or types. If there is only one int type, it should have unlimited range. If there are more, there should be implicit upcasting into the smallest type capable of holding the result of a computation, with the unlimited range type being the largest.
  • A single built-in binary float type, which is equivalent to an IEEE 754 double
  • A mutable list type which is implemented as either a doubly linked list or a block of contiguous memory holding pointers to each element
  • An immutable list type that acts like an array but whose size cannot be changed after creation
  • Mutable and immutable string types, with the default being immutable.
  • A map or dict type that is mutable, and holds immutable keys and mutable and/or immutable values.
  • The built-in collection types should be homogeneous typed by default, but can be vartyped if required
  • A boolean type
  • A null or none type that can be assigned to a variable of any type.
  • Mutable and immutable set types
  • A decimal type which implements decimal floating point variables
  • A fixed type, that implements a fixed-point number

The decimal, float and fixed types should share the exact same public interface (either via inheritance or duck typing), allowing them to be transparently passed to and returned from functions. The parent type could be called real.

7. Call by value and by reference

You should be able to call functions by both value and reference, with the default being value (i.e., a copy of the argument is made and operated upon in the function).

8. Pointers

The language should have pointers and allow pointer arithmetic. Pointers can only be statically typed (to avoid the nightmare that is a void*). vartype pointers are explicitly disallowed. Having pointers and pointer arithmetic allows the language to be seriously used as a systems programming language.

9. Inline assembly

In connection with 8., The language should allow inline assembly language code for those situations where it is necessary.

10. Safety

The language should be mostly safe to use, supporting exception handling etc. Pointer arithmetic and inline assembly can be relegated to portions of the code explicitly marked as unsafe. Unsafe code is allowed, but strongly discouraged.

11. Undefined behaviour

The language standard should specify how the program is to behave under all circumstances except in code explicitly marked unsafe, i.e., there should be no undefined behaviour outside of unsafe blocks. This allows the language to be used as a viable application development language, while still allowing you to say, write an OS in it.

That's all I can think of at the moment, but I'll edit/update the post as I think of more things.

11
  • 5
    Take a look of "D Programming Language": digitalmars.com/d
    – Wizard79
    Sep 2, 2010 at 18:14
  • As far as I can remember, D doesn't have optional dynamic typing or a built-in unlimited range integer type. The integer type isn't so much of a problem, but the lack of optional dynamic typing makes it quite unattractive. Sep 2, 2010 at 19:36
  • 1
    I would really add a decimal type here. Sep 22, 2010 at 0:47
  • 3
    “A null or none type that can be assigned to a variable of any type.” — Including boolean? :-p
    – Timwi
    Oct 3, 2010 at 18:36
  • 1
    I don't see "flexible" in the original post. Inline Assembler would not pop into my mind as top requirement for a programming language. Maybe that's according to the Felix von Leitner nowadays writing Assembler mostly gives you slow incorrect results. Dec 20, 2010 at 12:46
7

This is how my dream programming language would look like:

  • A powerful static type system with some support for dependent typing.
  • Optional dynamic typing.
  • Numeric Tower a la Lisp but statically typed.
  • Macros a la Lisp.
  • Primarily a Functional Programming language with basic support for imperative programming (like ML family).
  • Garbage collection.
  • Type inference.
  • Continuations.
  • Optional lazy semantics.
  • All the control constructs would be provided in the form of library functions. (This can be made possible using last two features.)
  • Minimal syntax (not as little as Lisps, but something of the sort of Ioke/Seph.)
10
  • Sounds good. I haven't really seen a good way to do statically type-safe macros, though. Dec 6, 2010 at 2:42
  • @Jörg: Nemerle? Dec 6, 2010 at 4:04
  • In Smalltalk all the control structures are actually methods, and it doesn't use continuations in their implementation. One is not needed for the other.
    – Oak
    Jan 29, 2012 at 9:42
  • @Oak, can you implement's Python's yield in Smalltalk? Should be as clean to use. Jan 29, 2012 at 9:46
  • A yield-like mechanism is already implemented in smalltalk as a library method, without continuations.
    – Oak
    Feb 2, 2012 at 11:03
6

I would have designed it pretty much like C#, but Microsoft beat me to it. :)

(Except of course that mine would have been less well thought through and more amateur.)

I don’t mind much whether it is compiled or interpreted, so I don’t need to justify that bit.

As regards to strong static typing, I find it hard to appreciate why this even requires justification. Static typing is a feature which catches bugs during compile-time. Dynamic typing is the lack of that feature and defers the bugs until runtime. In my personal experience I had few use-cases where dynamic dispatch made sense and was useful, so the convolutions I had to go through in C# before 4.0 to get it were easily justified then. With C# 4.0 I don’t even need to justify that anymore because we have dynamic dispatch now.

However, I probably would have created a new syntax instead of sticking as religiously to old C syntax as C# did. The switch statement is particularly horrible, and I also dislike the cast syntax (it is the wrong way around). I don’t make a big fuss about the details of syntax though, so I don’t need to justify it in detail, except that I wouldn’t want it as verbose as Visual Basic.

What else would you like me to justify?

3
  • +1 Good answer! I'll post up one of my own later as well. Sep 2, 2010 at 16:56
  • 4
    C# is a powerful language, but the syntax is often messy. I think this is because so many of these features weren't in the original design.
    – Casebash
    Sep 2, 2010 at 21:16
  • Hence "4.0", I guess.
    – Mark C
    Oct 3, 2010 at 18:08
5

Well here's a list of features I'd put in:


Lisp like syntax

Lisp style

Pros:

  • Easily extendable syntax. Ever tried to implement a foreach loop in C? It's not exactly easy. (Mind you, I have done it).
  • Homoiconicity. You can simply (eval "your data files")

Cons:

  • Nested polish notation is often hard to read

Functional Programming

Haskell style

Pros:

  • Easy concurrency, all code is thread safe.

Cons:

  • Difficult to implement side effects in pure functional code, though monads seem to do a good job.

Strong dynamic typing

Python style

Pros:

  • Dynamic typing makes clean readable code, Strong typing can eliminate type errors

Implementation:

Allow function overloading based on types, similar to CL's defgeneric:

(define (+ (a <int>) (b <int>))
  (ints-add a b))

(define (+ (a <string>) (b <string>))
  (string-concat a b))

(define (+ a b)
  (add-generic a b))

Compilable and Interpretable

Pros:

  • Performance boost if compiled (usually true, not always)

Cons:

  • Can limit features in the language, llvm would be a good backed though.

Systems programming

C style

Pros:

  • Appeals to a, very slightly, wider range of users.
  • Easier for applications, kernel and device drivers to interact if they're all written in the same language

Cons:

  • Limits the abstractions in the language, dynamic typing is often not suitable.

Hygienic macros (CL style and Scheme style)

Pros:

  • Easy to extend the language, especially with Lispy™ syntax
  • I've said this before, haven't I?

Cons:

  • Not many if done with Lispy™ syntax

Come to think of it, this more or less defines scheme, except for the compilation and systems programming bit. That can be worked around by using libguile and writing those bits in C.

2
  • 1
    Take a look at Ioke and Seph. It's amazing how much more easily readable a language can get by adding just a teensy amount of syntax compared to S-Expressions and still have the full macro capabilities. (Basically, instead of "every function call is a list and lists are first-class" it's "everything is a message send and message chains are first class". Instead of a list whose car is the function and cdr is the arguments, you have an object whose name field is the method and whose arguments field is the arguments. And instead of nesting, you have prev and next pointer fields.) Dec 6, 2010 at 2:41
  • Sounds pretty much exactly like Clojure (assuming you use Mjolnir for native code generaltion on LLVM for the systems programming part - github.com/halgari/mjolnir)
    – mikera
    Oct 22, 2013 at 1:30
3

There are several languages out there that I consider pretty damn good (C# being my current favorite). Since this is my fantasy language, here's what I really want it to have:

  • Kick-ass official api documentation. The Java API is good like this, and C#/.NET is pretty good. Ruby/Rails is pretty terrible here.
  • Kick-ass official general documentation (how-to's, common uses, lots of example code). C#/.Net is good for this.
  • A huge community of blog-based documenters and StackOverflow problem solvers to help me out of tough spots
  • A wide range of well-supported, well-documented, and powerful plugins/libraries/extensions (Ruby/Rails has 'powerful' but neither of the other two).
  • Is reasonably stable- no changing everything to break most existing code on an annual basis (looking at you, Ruby/Rails).
  • Isn't too stable- is able to adapt to advances in language design (looking at you, c++)
1
  • 2
    "Kick-ass documentation" points should include PHP :D
    – Corey
    Dec 25, 2010 at 6:30
3

Compiler hints

I'm talkin out of me bum since I don't know that much about language design, but I think the feature I'm talking about is called hints in other languages. Compiler hints, maybe?

I don't know if I read this in a Perl6 draft or was just high at the time, but I imagine a language where everything by default is loosy goosy and automagical. But if you wanted to really crank out performance and say, hey, this value is always an integer or it's never null, or this can be parallel, or this is stateless, things like that... That the compiler could automatically go to town on these specifically marked areas.

E: I'd appreciate comments clarifying what I'm asking for or citing examples where this already exists.

1
  • 1
    You can do some of this in Common Lisp. For example, you can tell the compiler that i is a reasonably-sized integer. One useful thing is that, by varying the safety and speed values, you can often either have the compiler check and enforce (to find problems) or assume what you say is true (and compile faster code). Oct 7, 2010 at 20:11
2

To try new ideas:

I would make a dynamic-typed functional programming language, it allows you to do all the statement expression tricks and the simplest lambda syntax with pattern matching. Off-side rule enabled.

// a view pattern (or Active Pattern in F#)
default = \def val: !!val.Type val def

// usage of the pattern
greet = \name<(default "world") `and` hasType Str>:
  p "Hello, \{name}!"

(p "Enter your name", .input).greet // (, ) is a sequence expression, returning the last value

Here is an explanation:

default = sets the storage, \def val begins a curried function with two arguments, val.Type is same as Type[val], !! converts to boolean, and boolean can be applied, so val and def are after it.

f x = f[x] = x.f .f = f[]

and in greet, it used name<(default "world")andhasType Str>, it means the pattern default "world" will be used and bound to name. The default pattern specifies a default value. and is another pattern that chains two patterns together. the default pattern can't fail while hasType can fail. In that case, it throws an exception.

Variables are actually storages, which can be functionally passed, and storage tables can be references, created and destroyed as scopes change.

Hashes and such will be like in Lua and JavaScript's.

If I'm going to make a compiled language, I'm going to make an F# for Java, with Haskell-like features. It's a pure functional language, except there is a feature that mixes Quotations and Comp Exprs together to achieve imperative programming by writing pseudocode-like blocks.

1
  • 1
    It sounds a little bit like Erlang, a dynamic typed functional programming language and added to that a quite unique concurrent language constructs.
    – Jonas
    Sep 24, 2010 at 14:49
2

Bearing in mind that the only languages I know are PHP and javascript, and that I really should learn a few more before designing a language:

Syntax: Think carefully about function names and argument order (i.e., be less messy than PHP).

Features: Have a set of string functions, which operate on variables as a series of bytes, but don't understand text, and a set of text functions, which understand lots of encodings and can operate on UTF-8 and other multibyte strings. (And have encoding sanity checks built into the language, with a function like text.isValidEncoding(text, encoding) which will tell you if a byte sequence is malformed and unsafe to treat as text.

I think I like the idea of strong static typing, but I've never used it, so I can't really say.

2

Before designing a programming language, I would find a good answer to the question: why do we need yet another programming language? Rosetta Code at the time of this writing lists 344 languages. If none of those met my needs, the specifics of why they didn't would determine the starting point (languages that come the closest) and what would be added to it.

If I won the lottery and for some reason had nothing better to do, I would start with Liskell and make it a full-fledged language as opposed to a GHC front-end, then make FFI easier (and automated) so I could use any C/C++ library.

2

A good language is a language which is:

  • easy to reason about (no obscure syntax)
  • let you express your ideas with minimum distortion
  • hide the nitty gritty details from you (optimization / resources management)
  • easily parallelizable (multiple cores, distributed computing)

It's pretty hard to turn this into a list of features, but I think Functional Programming, despite not feeling natural, is closer to this than imperative programming (especially in hiding the nitty gritty details)

  • C-interfacing: C is the lingua franca of programming languages and the number of libraries developped in C is amazing. By having an easy interface (like Python) to C, the language automatically benefits from all those libraries and it also allows to send heavy-tasks that could not be optimized enough to a close to metal language.
  • Distributed: I like Go's take at multi-threading, with lightweight routines that the runtime dispatches on threads depending on their activity. Such a language encourages the programmer to reason about tasks and to isolate them from one another.
  • Garbage Collection: goes without saying nowadays ;)
  • Immutable: much easier to reason about something that can never mutate, much easier to implement multithreading / distributed computing too (you only need synchronization to handle the lifetime, which is the compiler task)
  • Lambdas: goes with first class functions I guess
  • Message Passing: immutability means no mutex, therefore we follow Tony Hoares' suggestion
  • Modules: somewhat similar to namespaces, but with better encapsulation
  • Reflexion: distributed computation requires serialization, which should be left to the compiler, and deserialization is more easily achieved with some form of reflexion.
  • Static Strong Typing: the earlier an error is detected, the least it costs

At the moment, the language closer to this list is probably Haskell, though:

  • it lacks Routines: I have not seen a natural way to express parallelism in Haskell yet (though it may be my ignorance...)
  • it's got an Obscure Syntax: somehow it looks like Haskell programmers thrive on using weird operators rather than words. It may seem slick, but it doesn't help much to understand what's going on.
2

To your first question, "how would you do it" - short answer, I wouldn't. I don't have enough parser/compiler theory to pull that off. But I have been programming for 25 years, so I do have some ideas and opinions to share.

First off, I would try to come up with an OOP approach that lets you create truly connected models. What I mean by that is, models are one of the most important things in almost any kind of programming project - it's always a lot of grunt-work and continuous refactoring to get it right, and I blame that on a lack of real connectivity in OO languages.

Permit me to demonstrate. Let's say a class House has a Door property.

var door = house.Door;

You now have a local variable with a reference to the Door instance.

But consider what just happened: You just ripped the Door off the House, and now you're quite happy passing the Door around, and the rest of your code is ignorant of the fact that this Door is actually attached to a House.

To me, this is fundamentally wrong.

And yes, I know, this is "easily" fixed on a case-by-case basis - in this case by maintaining a reverse reference from every Door to the House it's currently attached to. This of course opens your model to errors, since it's now your duty to accurately maintain two reverse references, so you make the House.Doors and Door.House properties private, and you add methods like House.AddDoor(), House.RemoveDoor(), Door.SetHouse() etc. and wire it all up, and unit-test it to make sure it actually works.

Isn't this starting to sound like a lot of work to model such a straight-forward relationship? A lot of code to maintain? A lot of code to refactor as the model evolves?

The problem is pointers. Every OO language I've seen, inherently suffers from the fact that an object-reference is really a pointer, because that's what computers use.

Pointers are not a good way to model the real world. Regardless of what world you're trying to model, it's almost guaranteed that any relationships in that world are going to be two-way relationships. Pointers point in one direction only.

I would like to see a language where the fundamental data-model is a graph - where all relationships, by default, have two ends. This would almost certainly provide a much more natural fit for modeling the real world, which is really the only thing we need computers for in the first place. (that and video games.)

I have no idea what syntax for such a language would look like, or whether it can even conceivably be expressed using text. (I've wondered if such a language would have to be graphical, somehow...)

I would also like to see all forms of accidental state eliminated.

For example, in web-development, we spend a lot of time shaping data from databases, into business-models, into view-models for presentation... then some of that data is presented on forms, which is really just another transformation... and state comes back from form-posts, and then we reshape that data and project it back onto the view-model, e.g. view-model binders and such... we then project from the view-model back onto the business-model... we then use object-relational mappers (or grunt work) to transform the data from the view-model and project it onto a relational database...

Is this starting to sound redundant? At what point during all of this madness did we really accomplish anything useful? And by useful I mean, something tangible - something the end-user can understand and cares about. At the end of the day, the hours you spent actually building something the users can even understand, are really the only hours well spent. Everything else is side-effects.

I would want a highly dynamic language. The write/compile/run-cycle is a tedious waste of time. Ideally, the language should just figure out what changed, and compile/load transparently, in the background, as needed.

Ideally, you shouldn't even have to hit "run" - things should happen on-screen, as you make changes, immediately reflecting the changes you make. The problem with the write/compile/run-cycle, or even for that matter the more direct write/run-cycle, is that you're too disconnected from what you're doing - in order to feel connected with our work, we need immediate feedback, instant results. Any wait is too long!

Again, I don't even know if this could be accomplished with a traditional IDE, or if this would require an entirely new kind of interface.

You should be able to use a mix of weak and strong typing, whatever is most suitable for the problem you're working on.

State in general should be something the language fully manages for you. Why should you need to rely on a database for persistence? Ideally, I'd like to be able to simply specify the life-term of any variable in the model: one web-request, one session, 24 hours, permanently.

Why do we have to choose between a whole array of storage solutions for different media and life-terms? - not to mention transforming and shaping the data to fit each media; browser cache, database, memory, disk, who cares! Data is data. Where you store your data (and for how long) should be a simple choice, not a battle against the Gods!

Well, good luck with that.

1

It would probably be a multi paradigm language, supporting the following:

  • Structured/procedural programming
  • Object oriented programming
  • Functional programming

Why these? Object oriented because it is a great way to organize large programs, especially for organizing the data. Structured because you don't always want/need that (OOP), people should have choice. Functional because it makes it easy for programmers to debug and it makes programs more clear.

I would use Python's model with indented blocks to mark code blocks. It is very clen and nice to read.

I would steal quite many ideas from Python actually because Python is a very nice language. I would take it's for statement and I would copy its maps, list and tuples.

Now, I would probably not take the dynamic concepts from Python: for one thing, it would probably be explictly and statically typed. I think programs become more clear with that. The variables would probably all be objects with methods, then you could do something like str.length() to get the length of a string. In function definitions, you would have to specify the return type and the types of the arguments (supporting some kind of generic types as well).

Let's go back to copying from Python ;-). I love it's way to have optional procedure arguments so I would probably have that. Python doesn't however support procedure overloading, I would want that.

Let's look at classes, I would ditch multiple inheritance; to easy to abuse. I would implement private and similar scopes and I would probably implement that the way it is done in C++. I would also have abstract classes and interfaces; I don't believe Python has that.

It would support inner classes, in fact, I would want a very powerful object oriented language.

It would probably be interpreted. It is possible to get it really fast using good JIT compilation (I would want a fast language, though programmer productivity would come first) and compilation is just bad for productivity at many times. Interpreted languages also promote platform independance, something which matters more and more for each day.

It would have builtin Unicode support; these days internationalization matters a lot.

It would definitely be garbage collected. Damn I hate doing the memory management myself; not good for productivity either.

Finally, it would have a good standard library.

Wow, just realized how much I really love Python.

1
  • Why Interpreted languages also promote platform independance? I guess there are more cross-platform interpreters rather compilers (percentage), but couldn't figure out why this sentence should be true? I think there is no difference between them at all, regarding cross-platform abilities.
    – Mahdi
    Oct 17, 2012 at 12:00
1

First of all, I would buy a few books on compilers, a few standards, and take a course or two in languages and compilers. I'd contribute PEPs and visit C++ standards committee meetings. I'd contribute patches to the compilers I use, hopefully both for features and bugs.

Then I'd go back and look in horror at this list that I've come up now, which is of what directions I'd go in with a language if I started right now:

  • Functional, because I currently am not well-versed in any functional languages and making one would be a great way to learn one. In case it doesn't follow directly: everything is constant.
  • I'd fill it with as much Type Inference as I could fit in it, but with the option to specify interfaces explicitly. Not sure about other types. This doubles up as all functions being generic by default.
  • As you may have guessed, with Interfaces; that is, with types that only provide promises on available operations.
  • Saying whether the language is strongly or weakly typed isn't very meaningful in this case, as far as I can tell. I would call it strongly typed, as things never change what interfaces they implement.
  • It would have a lot of Design by Contract support. Again, as much as I can fit: preconditions and postconditions are a must; I don't know how much invariants matter when it comes to functional programming.
  • While I'm at it, I'd take a look at languages where you can formally prove correctness and see if I can pick up anything from there.
  • I would go out and write an awesome testing library. Even in case I fail to make it awesome, I'll at least spend a considerable amount of time working on it as I think it's something every language should have.
  • As for the syntax, the language would either have significant whitespace and look a lot like Python, or it would be based on Lojban and sharing a lot of the grammar and vocabulary. In the first case, I would do my absolute best to make the grammar as close to a CFG as possible.
  • I would not care whether people who implemented the language would compile it beforehand, JIT it, interpret it, chant it at campfires, or pay college kids to execute it for them. My own implementation would probably start out as an interpreter or a C compiler, and eventually move towards a JITter.

Seeing as even these fairly broad points would probably quickly change if I started implementing the language, so I think that going into further detail is unnecessary.

0

If I had the time, I would design a localizable programming language that is based on Scala, so it would have most of its features, except probably for XML. My goal is to make a language that reads almost naturally in languages with a different structure than English, such as Arabic (my mother-tongue). I am thinking of the following features:

  • A pre-processor #lang directive, used to inform the pre-processor of the human language used for programming. For example: #lang ar would allow the use of the word فئة instead of class, عرف instead of def, and so on. The human-language-specific keywords would be defined in standard preprocessor files.
  • The pre-processor would remove some optional keywords whose sole purpose is to add clarity to the code. For example, it would remove "is composed of" in class MyClass is composed of { to become class MyClass {, and remove "as" in def MyMethod(x: Int) as { to become def MyMethod(x: Int) {. In some (human) languages, this would make the code much more easier to understand, especially for students.
  • The compiler would allow the use of prefix notation for property access. This might not make sense for most Latin-based language speakers, but for some other languages it makes perfect sense. For example, property access in Arabic is normally prefix, as in اعرض طول اسم محمد, which is equivalent to print(length(name(Mohammad))) in programming-English. (The parenthesis are for clarity.)

I believe that these minimal changes to the pre-processor and compiler would make programming much simpler to non-English speakers.

3
  • 5
    Microsoft (and some others before) made localized versions of VBA (Visual Basic for Office applications). It was a mess. While it is nice for newbies, young people and non-English people to read code in their mother tongue, it makes very hard to share code with people outside of your country. In our Internet days, working in isolation isn't very productive. If I have to rely only on French sources (blog articles, books, etc.) to learn Scala (as I do currently), I would miss lot of useful information. Not to mention the difficulty/amount of work to localize the libraries...
    – PhiLho
    Dec 20, 2010 at 10:28
  • 1
    @PhiLho: You're certainly right. But my main purpose of creating such a language is to be able to introduce programming to a much wider audience, including K-12 students and elderly people who may not be proficient in English. At the introductory level, they probably don't need to use external libraries, and creating localized wrappers for some small ones (e.g. print) wouldn't hurt.
    – Hosam Aly
    Dec 20, 2010 at 10:50
  • 1
    The other point is that many people already use their native languages for class and method names. It doesn't help them that keywords are in English, nor does it make a difference to other people, since keywords are not enough to understand non-English code. Nevertheless, the pre-processor can always replace the keywords back to English, and then to any other language if needed.
    – Hosam Aly
    Dec 20, 2010 at 10:54

Not the answer you're looking for? Browse other questions tagged or ask your own question.