Archived

This topic is now archived and is closed to further replies.

Feedback on: a perfect programming language

This topic is 5420 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

Recommended Posts

I think it would be interesting to hold a discussion on an optimal programming language. I am using the term "perfect" loosely in this case. Essentially: what constructs, instructions, data types and uses, programming paradigms, syntax, et cetera; would best be seen in a programming language, if you [we] were to design our own? For a formal discussion it would be nice to get more than four replies, so I hope this is effective enough. To keep things organized:
    * Using /source or /code tags, highlight key features, or general syntax of a language you have in mind.
* Reply to what others' have posted, discussing the pros and cons of what they included in the discussion.
If you truly like someone's concepts, make it known, to bring their feature into a more noted state.
* Don't forget the simple stuff. Discussing super advanced metamorphical templated
vector monoliths does not have to be your only point.
There are looping constructs and text display and variable allocation and memory
managing and very basic syntax to think about too.
* Possibly one could discuss compiler features, libraries, and other subcategories of such a language.

And so on. Please comment on what other people say as well. Thus, we can really get down to what is good and what is not good in a programming language of our design. This should be fun and interesting. Please don't be shy to get a good forum discussion going of more than a few replies, that actually has anything to do with the computer world. So, if you were to design a language, how would we do it? [edited by - khaos on October 22, 2003 7:23:53 AM]

Share on other sites
Strongly typed
A good IDE (don''t underestimate this one)
Optional reflective capabilities
Type inference
Lets you make every decision concerning it
Integrated, but optional garbage collector
Functions as first class objects
Small runtime
Intuitive syntax
Good library support
Namespaces/packages
Discourages Hungarian notation through compiler warning (just kidding, that will get some responses)

I can post code snippets later

Share on other sites
Constructs

Obvious ones are for-each; switch statements that accept more than just integers and can do comparisons. Break and continue with a labelled construct (ala perl) is essential.

for (x) = (list)  doSomethingTo(x);switch (string){  case < "bar":    ...  case > "foo":    ...  case else:    ...}

Lambda expressions, higher order functions (functions that return functions) and partial application are also dead nifty:

  // Lambda && higher order functions...  template  T(T) makeAddFunctor (T a)  {    return lambda (int x) { return a+x; };  }  int(int) add_to_12 = makeAddFunctor(12);    // Partial application  int(const char*) theCmp = strcmp("hello", @0);  for (char* x) = (string_list)  {    if (!theCmp(x))    {      printf("Match found");      return;    }  }

Data types

Support for rationals would be nice, as well as complex numbers. Resizable arrays and trivial hashes.

  int a[];  a.append(5);    int a[string];  a["foo"] = 69;  a["bar"] = 42;

Type inference is also nice: something which C++ partially supports via templates, but which many functional languages do automatically.

A unified type system is terribly useful. One can use ''boxing and unboxing'' to pretend that the primitive types are varieties of lang.Object.

Regular expressions are also good. Inline XML might be nifty, also:

  dom.Node myDoc = <foo>text<bar>more text</bar></foo>;

Genericity is necessary. ''Nuff said.

OOP is excellent. Everything must be an object, including the classes themselves. Double dispatch is nice.

In-language support for events.

State-based programming allows a class to customize the behaviour of its functions according to the situation, with little additional overhead at call-time:

class Matrix{  state Translation:    float[3] apply (float[3] vec)    { /* apply simple translation */ }  state Complex:    float[3] apply (float[3] vec)    { /* apply complex generic transformation */ }};

Lazy evaluation and delayed evaluation are rather nifty, also.

// Lazy maybe. Evaluates its argument 50% of the time.templatevoid maybe(lazy T v){  if (rand % 2)    v;}// Delayed repeat, evaluates its second argument TIMES times.templatevoid repeat(int times, lazy T expr){  for (times)    expr;}

Tail-recursion is highly desirable.

Garbage collection is required by standard. Options to control/disable for certain classes or during certain parts of the program.

Exolanguage wise, an IDE with debugger is essential. Tools for the language like lexer and parser generators, and documentation generators, are dead good.

Share on other sites
quote:
Original post by antareus
Lets you make every decision concerning it.

How do you mean?
quote:

Good library support

This could mean one of two things. Either that the language needs a good library of its own, or that it needs to be able to use other libraries without unreasonable difficulty. I agree with both.

At the very least, it should be able to use C libraries.
quote:

Namespaces/packages

Very nifty.

On the topic of namespaces, enums should be supported, and an enum have a namespace:

enum MyEnum{  FOO, BAR, BAZ;};

Here the elements should be MyEnum::FOO, MyEnum::BAR and MyEnum::BAZ.

Sometimes enums aren''t used in the disjoint way that is intended. Enums are often used to declare related flags that can be combined. Enums should be enforced, and a new construct provided for grouping flags:

flagset MyFlags{  FLAG1, FLAG2, FLAG3;}

quote:

Discourages Hungarian notation through compiler warning (just kidding, that will get some responses)

Too right.

I''ll also risk some responses of my own by saying it definately should support multiple inheritance.

Share on other sites
No more #pragma, nor the preprocessor! No more compiler dependency - ie - no more porting code from one compiler to another. Thus - only one (open source) compiler (with IDE).

Oxyd.

---
Unreadable code is code written on a piece of paper, but not the one, in which its programmer is using a space in place you don''''t.

Share on other sites
-C/C++/Java syntax is fine , all the classic statements + foreach
-classes,Interfaces.
-all classic Java/C# types
-built in dynamic arrays and maps(tables)
-maps can be hased with any type except null
-higher order functions
-coroutines or continuations
-variant type
-components are natively supported(not a bounch of zipped classes)
-do not allow exposing classes thrugh components, just interfaces.
-generics(safe macros ala Java 1.5)
-no garbage collection, refcounting with cycle detection (+the compiler detects runtime what really needs refcounting), in alternative some sort of efficient ''linearity''.
-autoboxing
-small runtime(around 100-200k)
-fast register based virtual machine
-a good compiler

BTW I''m gonna implement this language as soon I''m done with the current one...I''ll call it "Solid Hamster"

ciao
Alberto

-----------------------------
The programming language Squirrel
http://squirrel.sourceforge.net

Share on other sites
Mayrel: choices over whether GC can be used, and if it is used, choices over whether object destruction is deterministic, perhaps some subsets of the language that make it suitable for demanding roles such as hard real-time tasks or looser tasks such as AI

On the libraries, I meant both, apologies for being vague.

fagiano: you'll like C#, it has a great majority of those things you listed.

Here are some more:
* partial evaluation/currying (lets you 'build' function calls)
* pointer usage is rare, not the norm (C++ is especially guilty of this)
* passing by reference requires function caller to acknowledge that it is passing by reference:
void f(ref int i){ i++;}// some functionf(ref i)

* embedded documentation generation that doesn't rely on ugly tokens in comments
* MI support
* More than double dispatch...multiple dispatch (proposal for C++ to support this thru n-dimensional jump tables)
* closures (construct an entire function call with args and call it at a later time (ties in with what I said earlier but its still important, I think Delphi has them)

What I get from the gist of all the comments is *some* sort of runtime system is needed. C++ is pretty close to as far as we can go with simply letting the compiler do the dirty work for us. But a tiny runtime would probably be more beneficial than not with all these language capabilities.

[edited by - antareus on October 22, 2003 2:03:01 PM]

Share on other sites
I think a good starting point would be a language as versatile as Lisp. While it is a good language, I think it could be made somewhat better by adding in support for lower level programming (things like pointers etc). Most people that know Lisp know that is a good language for many purposes, but it can''t do everything well yet(things like writing a driver - why be forced to choose abstraction OR hardware access?).

"You are my friends if you do what I command you."
[edited by - Big Brother on January 1, 1984 12:00:00 AM]

Share on other sites
quote:
Original post by Extrarius
I think a good starting point would be a language as versatile as Lisp. While it is a good language, I think it could be made somewhat better by adding in support for lower level programming (things like pointers etc). Most people that know Lisp know that is a good language for many purposes, but it can''t do everything well yet(things like writing a driver - why be forced to choose abstraction OR hardware access?).

scheme! scheme! scheme!

...Anyway.

The major issue I have with LISP-esque languages is the syntax. Genius as it may be, I find that the proliferation of parantheses makes it difficult to discern structure. I''d recommend following Dylan''s example and transforming an easier-to-read syntax into an underlying LISP format.

antareus:

Hmm, my understanding was that ''double dispatch'' was the official term for anything that wasn''t single dispatch. I always call it ''multiple dispatch'' in my head, and usually correct it as it comes out.

For my toy language, I have documentation embedded as XML as so:

import std.io.*;@<fun name="main" type="int">  <arg name="args" type="char[][]" text="Arguments"/>  This program does blah, blah, blah.</fun>int main (char[][] args){  out.print(1 + @<note>This is seven, for no particular reason</note> 7);  return 0;}

fagiano: Assuming I understand you correctly, you suggest no garbage collection or reference counting? I don''t know what "linearity" means here, could you clarify?

Share on other sites
Rather than LISP, start off with python...

• Multiple paradigm support (imperative/OO/functional) yep
• Strongly typed hmm, no, it does have some implicit conversions.
• A good IDE (don't underestimate this one) well, it *does* have IDEs.
• Optional reflective capabilities it's built-in
• Type inference dynamic typing, baby!
• Lets you make every decision concerning it metaclasses !
• Integrated, but optional garbage collector gc.disable()
• Functions as first class objects *everything* is an object
• Small runtime well, it's smaller than java
• Intuitive syntax check ! (try it before you bash it)
• Good library support check - excellent standard lib
• Namespaces/packages check
• foreach check
• case nope, use if/elif/else
• lambda check
• partial application/currying not built-in, but has been done - transparently
• rationals nope
• complex check
• dynamic arrays built-in
• hash check - that's arguably Python's core type; every nonmutable type (for obvious reasons) can be used as a hash key
• unified type system check - everything is an object
• type inference dynamic typing
• regular expressions check
• inline XML nope - there's an XML parsing lib, though
• genericity dynamic typing
• multiple dispatch not really
• "state-based" programming classes are modifiabke objects
• lazy evaluation no. generators provide 'lazy list' functionality though.
• tail recursion no
• use of C libraries need to write bindings, but can then be used as native python entities
• multiple inheritance check, the method resolution order is open to introspection.
• enums an enum metaclass exists (see Python Cookbook)
• portable check
• open-source check
• coroutines/continuations yes, in the 'Stackless' implementation, otherwise, generators do the job
• variant type dynamic typing
• components vs. interfaces dynamic typing - adding interface testing is being discussed
• refcounting with cycle detection check, with caveats for classes with destructors (there is no general algorithm to determine how to break a cycle and which object to delete first - the programmer must decide)
• small runtime python23.lib is 175K - non-builtin library elements can add to that (script files - can be zipped).
• pointers none, the C API let you muck around, though (e.g. numarray module for efficient C-style arrays).
• references *everything* is passed by reference
• embedded document generation yes, PyDoc relies on introspection and docstrings.
• deterministic gc gc.collect()
• fast VM err... well... err... not really...
• good compiler the 'psyco' module gives you JIT compiling
• closures yes, though a bit clunky, imho

There you go

[ Start Here ! | How To Ask Smart Questions | Recommended C++ Books | C++ FAQ Lite | Function Ptrs | CppTips Archive ]
[ Header Files | File Format Docs | LNK2001 | C++ STL Doc | STLPort | Free C++ IDE | Boost C++ Lib | MSVC6 Lib Fixes ]

[edited by - Fruny on October 22, 2003 4:44:01 PM]

1. 1
2. 2
3. 3
Rutin
17
4. 4
khawk
14
5. 5
frob
12

• 9
• 11
• 11
• 23
• 12
• Forum Statistics

• Total Topics
633660
• Total Posts
3013218
×