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.
closed as not constructive by Yannis Rizos♦ Feb 25 '12 at 3:15As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.If this question can be reworded to fit the rules in the help center, please edit the question. |
|||||||||||||||||||||
|
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.
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. |
|||
|
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:
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. |
|||
|
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:
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:
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:
The 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 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. |
|||||||||||||||||||||
|
It would probably be a multi paradigm language, supporting the following:
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 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. |
|||||
|
A good language is a language which is:
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)
At the moment, the language closer to this list is probably Haskell, though:
|
|||
|
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:
I believe that these minimal changes to the pre-processor and compiler would make programming much simpler to non-English speakers. |
|||||||||||||
|
This is how my dream programming language would look like:
|
|||||||||||||||||||||
|
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. |
|||
|
Compiler hintsI'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. |
|||||
|
Well here's a list of features I'd put in: Lisp like syntaxLisp style Pros:
Cons:
Functional ProgrammingHaskell style Pros:
Cons:
Strong dynamic typingPython style Pros:
Implementation: Allow function overloading based on types, similar to CL's
Compilable and InterpretablePros:
Cons:
Systems programmingC style Pros:
Cons:
Hygienic macros (CL style and Scheme style)Pros:
Cons:
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. |
|||||||||
|
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 I think I like the idea of strong static typing, but I've never used it, so I can't really say. |
|||
|
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.
Here is an explanation:
and in 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. |
|||||
|
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. |
|||||||||||||||||||||
|
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:
|
|||||
|
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? |
|||||||||||||
|