[OT] What should be in a programming language?

Jason House jason.james.house at gmail.com
Sat Oct 24 21:26:08 PDT 2009


Yigal Chripun Wrote:

> On 23/10/2009 19:50, Jason House wrote:
> > Yigal Chripun Wrote:
> <snip>
> >> transitive const and everything is const by default, immutable as
> >> part of the concurrency ownership design, functions would be
> >> defined as in ML: they take one tuple argument and return one tuple
> >> argument
> >
> > I like scala's concept of multiple input tuples, and the freedom to
> > use () or {} when specifying a tuple. I might be slightly stricter
> > with how each tuple is used such that the library writer says which
> > form is allowed. This has the awesome side effects of making
> > libraries look like part of the language.
> i don't know about this specific feature of Scala. 

My web search and some PDF's didn't turn up a handy example. You can do things in scala like define your own foreach loop. If foreach had the form form foreach(x){y} then x would be one set of arguments and y would be another set. It makes for pretty use of library functions. They look built in!

> in D you can pass a 
> (type) tuple to a function and it is auto flattened to the arg list.
> i.e.
> void foo(int, int);
> Tuple!(int, int) a = ...;
> foo(a);
> in ML, the arg list *is* a tuple so there's no need for an auto-flatten. 
> you can always nest tuples so it's trivial to have multiple tuples as 
> arguments.
> 
> example (not tested):
> 
> fun foo (a, (b, c)) = a*b + a*c
> let bar = foo(3, (4, 5))
> 
> foo's signature would be: ('a, ('a, 'a)) -> ('a)

Sounds reasonable


> >
> >
> >>
> >> i don't like the #if, etc idea and would prefer a proper AST macro
> >> system with proper hygiene
> >
> >
> > The AST macro stuff predates my participation on this list. Have any
> > good links explaining how it works? I've been thinking of allowing
> > expressions, statements (and friends) as object types and then
> > allowing mixing in of those objects...
> >
> > #var declareX = Statement ("int x=3"); #mixin declareX;
> >
> > ... or something along those lines...
> >
> http://en.wikipedia.org/wiki/Nemerle
> http://en.wikipedia.org/wiki/Hygienic_macro
> 
> here's a quick summary of how it should work/look like:
> macros are written in the same language, no #if, no static if.
> you write regular looking functions in plain code. those macros are 
> compiled separately into loadable libs that you can specify for the 
> compiler to load. the language has syntax to [de]compose AST.

I looked over the links (quickly). I must admit I don't get it yet. It takes me a while to digest lisp fragments... Can you give a D-ish example of what it'd look like?


 
> >
> >>
> >> I'd remove static from the language completely and instead would
> >> have metaclasses.
> >
> > I agree with no statics. What are metaclasses? I like how scala
> > defines singletons for statics (object in scala type declaration)
> 
> there are different models for this and this also relates to the macro 
> system above. here's one model (used in smalltalk)
> class Foo {
> int a;
> void foo();
> }
> the compiler will generate for Foo a singleton of the type 'Foo which 
> contains all the information about Foo. for example, it'll contain the 
> list of functions for Foo instances. this is the same as in D - in D we 
> have Typeinfo structs that contain vtables.
> 
> class Bar {
> int a;
> static void foo();
> }
> in compiled languages (c++/d) this is done statically (foo is a global 
> function in the assembly)
> 
> in smalltalk the previous mechanism is [re]used:
> we have class Bar which defines it's instances
> we have class 'Bar that defines Bar
> we have class ''Bar that defines 'Bar
> we have class Class that defines ''Bar
> total of 5 levels which are required to have class shared functions/state

That seems strange. I'm also missing something important :(

 
> >
> >> other OOP changes - better separation between sub-typing and
> >> sub-classing:
> >>
> >> type interfaceA extends interfaceB, interfaceC {} implementation
> >> implA extends implB, implC implements interfaceA, interfaceD{}
> >>
> >> auto obj = interfaceA.new(); // returns an implementation, e.g.
> >> implA
> >>
> >> ionstead of the classic: class A {} class B: A {}
> >>
> >> we'll have: type A {} type B extends A {} implementation A
> >> implements A{} implementation B extends implementation A implements
> >> B {}
> >
> > There seems to be redundency here. Why would you/others want that?
> > Super verbose code makes it tough to attract users.
> I was trying to convey semantics here rather than syntax. deriving a 
> class from a base class is a poor way to design code and I want to 
> separate two orthogonal issues -
> a. subtyping and polymorphism
> b. reuse of code/ implementation

That's a good goal. What should it look like in code?

> >> everything is an object and no special treatment for specific
> >> types
> >
> > I don't think "everything is an object" works under the hood, but I
> > do like making that transparent. A lot of the items allow transparent
> > use of reference and value types (scope by default unless explicitly
> > marked/allocated, and transitive const by default unless passed by
> > ref)
> 
> c style built in types expose an implementation detail that should be 
> encapsulated and hidden under the hood as you say.
> there should be no syntactic difference between an int and a user 
> defined type.
> for example I should be able to do:
> struct foo : int {}
> 

I agree 




More information about the Digitalmars-d mailing list