[OT] What should be in a programming language?

Yigal Chripun yigal100 at gmail.com
Sun Oct 25 00:39:20 PDT 2009


On 25/10/2009 06:26, Jason House wrote:

> 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!
>

isn't that similar in concept to code blocks?

>>>
>>>
>>>>
>>>> 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?
>
>
here's a Nemerle example:

macro PrintStage() {
   System.Console.WriteLine("This is executed during compilation");
   <[ System.Console.WriteLine("This is executed at run time") ]>
}

the first WriteLine is executed during compilation, and the macro 
returns the AST for the second WriteLine which will be executed at run 
time when this macro is called.

think of it like:
// hypothetical D syntax

macro print() {
    Stdout("Hello compile time world").newline;
    return q{ Stdout("Hello run time world").newline };
}

one important design goal is to clearly separate the stages, so this 
will go to a separate .d file and will be compiled into a lib.
to use this macro you simply specify
compiler --load-macro=myMacro sources.d

in user code you just use "print();"

>
>>>
>>>>
>>>> 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 :(
>

OK, here's an example:

class Foo {
int a;
void bar();
}

auto obj = new Foo;
obj.a = 42; // obj contains a
obj.bar();  // calls 'Foo.vtbl.bar

remember that 'Foo is the classinfo singelton for Foo

class Foo {
static a;
static void bar();
}

Foo.a = 42; // 'Foo contains a
Foo.bar(); // calls ''Foo.vtbl.bar

''Foo is the classinfo singelton for 'Foo

we get the following chain ("-->" means instance of)
obj --> Foo --> MetaFoo --> MetaClass --> Class

compared with C++/D/Java/etc:
obj --> Foo --> Class
>
>>>
>>>> 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?

that's a good question. I don't know yet.




More information about the Digitalmars-d mailing list