www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Archetype language

reply bearophile <bearophileHUGS lycos.com> writes:
Through I've found a link to a language I didn't know, named Archetype. This
blog post contains some pointers and references about the language:
http://dvanderboom.wordpress.com/2010/04/26/new-language-code-named-archetype/

Some comments and quotations and notes about the language. Some of the things I
write are already translated to a D-like syntax.




Archetype looks designed to make handy practical/industrial high level coding
with GUIs, databases, etc. Archetype seems to contain many pre-built high level

features that you combine in many more ways.

----------------------------------

The idea of optional curly braces for functions with 1 expression inside (just
a return):
int foo(int x) return x * x;
Instead of:
int foo(int x) { return x * x; }

It is similar to a syntax like:
foreach (x; 0 .. 10) y *= x;
Instead of:
foreach (x; 0 .. 10) { y *= x; }

------------------------


you add two delegates, they get chained. When you call the result of the sum,
both get called, in sequence. Probably this is handy to attach chains of
callbacks to GUI elements.

------------------------

Imports inside functions, etc.:

void foo(int x) {
    import std.stdio;
    writeln(x * x);
}

------------------------

There is a very short syntax to perform the simplest loops, here translated to
D-like:

foreach(10) {
}

------------------------

In Archetype, the exclamation point can be placed before the parentheses. It is
the only part of the condition that can appear outside the parentheses.

if !(expression)
    statement;

------------------------

There is a form of pattern matching:


var x = 1;
var number = 4;
match (number) {
  x -> number += 3;
  3 | 5 -> number++;
  2 | 4 | 6..10 -> {
    number–;
    Log("Numbers are getting too big");
  }
}

------------------------

In Archetype if you have an Color enum, in some situations you don't need to
write Color.Green, you are allowed to use just Green.

------------------------

There are nullable types:

int? x = 4;
auto x? = 4;

------------------------

There are tuples, used like this:

(int, int) getMouseLocation() {
    return (100, 50);
}


Or with named fields too:

(x int, y int) getMouseLocation() {
    return (100, 50);
}


At the call site:

auto (x, y) = getMouseLocation();

------------------------

It has "Streams", that are iterators, very similar to the yield syntax sugar I
have suggested:
http://d.puremagic.com/issues/show_bug.cgi?id=5660


yield(int) Numbers() {
  yield 1, 2, 3;

}

Or even (I have kept the Archetype syntax here):

yield(int) Numbers() {
  yield 0..100 skip 5;
}

----------------------

It has Pascal/Ada-style ranged numbers (I have kept the Archetype syntax here):

// an int that can only have a value from 0 to 105
type ValidAge int in [0..105];


An anonymous subrange type, when you don't need to define the type:
Age int in [0..105];

----------------------

It has List Comprehensions (I have kept the Archetype syntax here):

var FirstHundred = [ 1..100 ];

var FirstHundred = from x in [ 1..100 ] where x*x > 3 select x*2;


In my opinion the map/filter/reduce of Phobos2 have almost failed because their
syntax is too much noisy and heavy, I don't want to see them used a lot in
production code. Even in Python code map/filter/reduce are uncommon. Modern
Python programmers use mostly lazy/eager sequence comprehensions. But I don't
like the List Comprehensions syntax of Archetype.

----------------------

In Ruby arrays (lists) support the - infix operator too, to remove the first
item equal to the one given on the right of the minus sign (similar to the
list.remove() method in Python). But this operator is not present yet in
Archetype design.

----------------------

A cute quote:

In my study of linguistics, I learned that legends like Noam Chomsky could
learn hundreds of langauges; the previous librarian at the Vatican could read
97.<
---------------------- There are ways to define infix binary operators (this is dangerous/troubled stuff): // "ABC" dup 3 == "ABCABCABC" binary dup string (left string, right int) return string.Repeat(left, right) Even infix spaces that mean something (there was a C++0x joke about this): // "123" "45" == "12345" binary adjacent string (left string, right string) return left + right; And just suffixes: // 12 minutes == TimeSpan.FromMinutes(12) unary suffix minutes TimeSpan (short, int) return TimeSpan.FromMinutes((int)value); ---------------------- If not specified there is a default constructor, ad in D structs: class Foo { string x; int y; } void main() { Foo f = new Foo("hello", 10); } Is this going to cause problems in D? ---------------------- I have omitted several other things. (Just to be sure: with this post I am not proposing to add all that stuff to D2/D3. I like only part of the things I've shown.) Bye, bearophile
Mar 20 2011
next sibling parent reply Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
On 3/20/11, bearophile <bearophileHUGS lycos.com> wrote:
 The idea of optional curly braces for functions with 1 expression inside
 (just a return):
 int foo(int x) return x * x;
 Instead of:
 int foo(int x) { return x * x; }
Cute. Nice reason to keep the semicolon.
 It is similar to a syntax like:
 foreach (x; 0 .. 10) y *= x;
 Instead of:
 foreach (x; 0 .. 10) { y *= x; }
Not so cute (to me). I'd prefer that syntax only in one-liner function definitions.

 When you add two delegates, they get chained. When you call the result of
 the sum, both get called, in sequence. Probably this is handy to attach
 chains of callbacks to GUI elements.
How is this different from an array of delegates? void GUIDoSomething(int delegate(int, int) delegates[]) { int _x, _y; foreach (deleg; delegates) { deleg(_x, _y); } } void main() { int delegate(int x, int y)[] delegates; delegates ~= (int x, int y) { return x + y;}; delegates ~= (int x, int y) { return x - y;}; GUIDoSomething(delegates); } Granted you can't do `deleg1 ~ deleg2`. But a delegate should be a single quantity, not a hidden sequence of multiple delegates. That's what arrays are for (or even rages).
 Imports inside functions, etc.:

 void foo(int x) {
     import std.stdio;
     writeln(x * x);
 }
I think this would be a little cumbersome to maintain. Maybe it would even complicate the linking stage, but I'm not sure.
 In Archetype, the exclamation point can be placed before the parentheses. It
 is the only part of the condition that can appear outside the parentheses.

 if !(expression)
     statement;
This is nice. Currently I have to add another pair of parenthesis, and it doesn't look nice: if (!(isFile(name) && getExt(name) == "d")) continue; // not a file, or not a .d file vs. if !(isFile(name) && getExt(name) == "d") continue; // not a file, or not a .d file
 There are tuples, used like this:

 (int, int) getMouseLocation() {
     return (100, 50);
 }


 Or with named fields too:

 (x int, y int) getMouseLocation() {
     return (100, 50);
 }


 At the call site:

 auto (x, y) = getMouseLocation();
Maybe D3 would have these, who knows.. Do you use tuple return values often, e.g. in Python?
Mar 20 2011
parent reply bearophile <bearophileHUGS lycos.com> writes:
Andrej Mitrovic:

 Not so cute (to me). I'd prefer that syntax only in one-liner function
 definitions.
Of course. The example was just to show that with foreach you are allowed to spare the brackets. So in theory the same thing is doable with single-expression functions. And indeed Scala language too does this.
 But a delegate should be a
 single quantity, not a hidden sequence of multiple delegates. That's
 what arrays are for (or even rages).
don't agree with you.
 Maybe D3 would have these, who knows..
Thinks don't just happen :-) If you want something, you have to work a lot, to grow enough consensus of people that like it, to design it well, find corner cases, and then implement it or find people willing to implment it, etc.
 Do you use tuple return values often, e.g. in Python?
Not in every line of code, but they are quite useful. Tuples are useful for other purposes too, like: for a,b in zip((1, 2, 3), "abc"): Here a,b is a 2-tuple that Python automatically unpack from the result of the zip, that in Python2 is a list (array) of 2-tuples. So there are some other usages of tuples beside the normal ones. Phobos already has a tuple type. It doesn't have syntax sugar for the unpacking (and maybe better syntax for the tuple literals, but this is less important). Bye, bearophile
Mar 20 2011
parent spir <denis.spir gmail.com> writes:
On 03/20/2011 10:11 PM, bearophile wrote:
 Do you use tuple return values often, e.g. in Python?
Not in every line of code, but they are quite useful. Tuples are useful for other purposes too, like: for a,b in zip((1, 2, 3), "abc"): Here a,b is a 2-tuple that Python automatically unpack from the result of the zip, that in Python2 is a list (array) of 2-tuples.
Typical example, I guess: for line in File("contacts.dat"): (name,phone,email) = line.split(';') Denis -- _________________ vita es estrany spir.wikidot.com
Mar 20 2011
prev sibling next sibling parent reply spir <denis.spir gmail.com> writes:
On 03/20/2011 06:36 PM, bearophile wrote:
 Through I've found a link to a language I didn't know, named Archetype. This
blog post contains some pointers and references about the language:
 http://dvanderboom.wordpress.com/2010/04/26/new-language-code-named-archetype/
Very interesting!
 Some comments and quotations and notes about the language. Some of the things
I write are already translated to a D-like syntax.



Too bad! A language built on top of a privative (proprietary) one, which itself targets a privative platform is definitely unusable for me. (This is not a joke.)
 Archetype looks designed to make handy practical/industrial high level coding
with GUIs, databases, etc. Archetype seems to contain many pre-built high level

features that you combine in many more ways.
... which does not exclude studying it and ripping good points and ideas ;-)
 ----------------------------------

 The idea of optional curly braces for functions with 1 expression inside (just
a return):
 int foo(int x) return x * x;
 Instead of:
 int foo(int x) { return x * x; }

 It is similar to a syntax like:
 foreach (x; 0 .. 10) y *= x;
 Instead of:
 foreach (x; 0 .. 10) { y *= x; }
Very good. They should also let down ';' noise, like Go.
 ------------------------


you add two delegates, they get chained. When you call the result of the sum,
both get called, in sequence. Probably this is handy to attach chains of
callbacks to GUI elements.
Good idea, but (1) mostly imperative langs very rarely need func composition (2) '+' is a very bad choice of operator for this.
 ------------------------

 Imports inside functions, etc.:

 void foo(int x) {
      import std.stdio;
      writeln(x * x);
 }
Bad, imo. Imports should be obvious.
 ------------------------

 There is a very short syntax to perform the simplest loops, here translated to
D-like:

 foreach(10) {
 }
Only looks like nice. But in practice one often needs the index. Which leads to eg: foreach(i ; 10) {...} Then, one is close to D's: foreach(i ; 0..10) {...} which is more poweful by indicating start index.
 ------------------------

 In Archetype, the exclamation point can be placed before the parentheses. It
is the only part of the condition that can appear outside the parentheses.

 if !(expression)
      statement;
Nice, but introduces syntactic exception for rare cases.
 ------------------------

 There is a form of pattern matching:


 var x = 1;
 var number = 4;
 match (number) {
    x ->  number += 3;
    3 | 5 ->  number++;
    2 | 4 | 6..10 ->  {
      number–;
      Log("Numbers are getting too big");
    }
 }
May be good.
 ------------------------

 In Archetype if you have an Color enum, in some situations you don't need to
write Color.Green, you are allowed to use just Green.
Ditto.
 ------------------------

 There are nullable types:

 int? x = 4;
 auto x? = 4;
Great! Does this mean non-nullable is the standard case in Archetype?
 ------------------------

 There are tuples, used like this:

 (int, int) getMouseLocation() {
      return (100, 50);
 }


 Or with named fields too:

 (x int, y int) getMouseLocation() {
      return (100, 50);
 }


 At the call site:

 auto (x, y) = getMouseLocation();
Great as well!
 ------------------------

 It has "Streams", that are iterators, very similar to the yield syntax sugar I
have suggested:
 http://d.puremagic.com/issues/show_bug.cgi?id=5660


 yield(int) Numbers() {
    yield 1, 2, 3;

 }

 Or even (I have kept the Archetype syntax here):

 yield(int) Numbers() {
    yield 0..100 skip 5;
 }
Such things should not be a feature; instead be at the core of the language. Else, one ends up with "gas usine" messes like with D ranges (and their types) (and tons of required features around) (that end up with syntax blow-up).
 ----------------------

 It has Pascal/Ada-style ranged numbers (I have kept the Archetype syntax here):

 // an int that can only have a value from 0 to 105
 type ValidAge int in [0..105];


 An anonymous subrange type, when you don't need to define the type:
 Age int in [0..105];
I'm now shared on this point. Feels great when coding in Pascal or Module, but do we really miss it? ... even Oberon (of the Pascal line) let this feature down.
 ----------------------

 It has List Comprehensions (I have kept the Archetype syntax here):

 var FirstHundred = [ 1..100 ];

 var FirstHundred = from x in [ 1..100 ] where x*x>  3 select x*2;


 In my opinion the map/filter/reduce of Phobos2 have almost failed because
their syntax is too much noisy and heavy, I don't want to see them used a lot
in production code. Even in Python code map/filter/reduce are uncommon. Modern
Python programmers use mostly lazy/eager sequence comprehensions. But I don't
like the List Comprehensions syntax of Archetype.
Python's comprehension syntax is broken as well: [expr for x in coll if cond] [expr for x in coll] This weirdness, because 'in' is also an operator, so that "x in call" would be misinterpreted by the parser. To save *one* keyword in the language, python's designers introduced a broken syntax for comprehensions. Funny, ain't it?
 ----------------------

 In Ruby arrays (lists) support the - infix operator too, to remove the first
item equal to the one given on the right of the minus sign (similar to the
list.remove() method in Python). But this operator is not present yet in
Archetype design.
Far too ambiguous. And exceptional.
 ----------------------

 A cute quote:

 In my study of linguistics, I learned that legends like Noam Chomsky could
learn hundreds of langauges; the previous librarian at the Vatican could read
97.<
???
 ----------------------

 There are ways to define infix binary operators (this is dangerous/troubled
stuff):

 // "ABC" dup 3 == "ABCABCABC"
 binary dup string (left string, right int)
 return string.Repeat(left, right)


 Even infix spaces that mean something (there was a C++0x joke about this):

 // "123" "45" == "12345"
 binary adjacent string (left string, right string)
 return left + right;


 And just suffixes:

 // 12 minutes == TimeSpan.FromMinutes(12)
 unary suffix minutes TimeSpan (short, int)
 return TimeSpan.FromMinutes((int)value);
Requires much care, thought, and design talent, to be well used. (Just like the talent of a PL designer, IMO)
 ----------------------

 If not specified there is a default constructor, ad in D structs:

 class Foo {
    string x;
    int y;
 }
 void main() {
    Foo f = new Foo("hello", 10);
 }

 Is this going to cause problems in D?
I want this for D!
 ----------------------

 I have omitted several other things.

 (Just to be sure: with this post I am not proposing to add all that stuff to
D2/D3. I like only part of the things I've shown.)

 Bye,
 bearophile
Thank for the info, Denis -- _________________ vita es estrany spir.wikidot.com
Mar 20 2011
parent reply bearophile <bearophileHUGS lycos.com> writes:
spir:

 They should also let down ';' noise, like Go.
My experience so far has shown me that there are two options: 1) You design the whole language syntax on the fact that most times you don't use semicolons (see Python and Haskell. Or even Delight); 2) You keep the semicolons obligatory (see D). Most of the other options I've seen (JavaScript, Go) are train wrecks :-)
 Nice, but introduces syntactic exception for rare cases.
I agree. On the other hand it makes the code less noisy and its semantics is clear. So overall I'm weakly against it.
 May be good.
I think pattern matching was considered for D2 too. It introduces a significant amount of complexity, but it's also powerful (this shows one example: http://rosettacode.org/wiki/Pattern_matching ), expecially if you have algebraic data types. Scala language has a decent implementation of pattern matching, despite it's partiall an object oriented language.
 Ditto.
A related shortening feature for enums was proposed for D too.
 Great! Does this mean non-nullable is the standard case in Archetype?
I don't remember, but I presume so.
 Great as well!
Tuples are very useful.
 I'm now shared on this point. Feels great when coding in Pascal or Module, but
 do we really miss it? ... even Oberon (of the Pascal line) let this feature
down.
They are quite useful. Recently there was a discussion (coming from a type that's limited on the range of month days only) of an implementation in D of a ranged type (so not a built-in). Maybe a library implementation will be good enough, there's no need for lot of syntax here.
 Python's comprehension syntax is broken as well:
It's less "broken" than every other list comp syntax I've even seen, including Haskell one :-) In my opinion if you change it just a bit, you produce something significantly worse.


Yes, for uniformity, this is not so bad.


Your logic is broken.
 This weirdness, because 'in' is also an operator, so that "x in call" would be
 misinterpreted by the parser. To save *one* keyword in the language, python's
 designers introduced a broken syntax for comprehensions. Funny, ain't it?
Nope, you are mistaken, I think.
 Far too ambiguous. And exceptional.
It's normal operator overloading, and there is no ambiguity. It has caused me no problems in the little amount of Ruby code I have written.
 I want this for D!
I am willing to write an enhancement request on this. But first I'd like to know about negative side effects of it.
 Thank for the info,
You are welcome. Bye, bearophile
Mar 20 2011
next sibling parent reply spir <denis.spir gmail.com> writes:
On 03/20/2011 09:44 PM, bearophile wrote:


Your logic is broken.
I don't think so ;-) This is something I discussed on Python's design mailing list ("ideas"). The only reason why this is not possible to implement in python is that 'in' is also the membership operator. So that [x in coll] evaluates to [true] or [false]. Just replace 'in' by another keyword in the expression of list comprehensions, and, I guess, you won't find it broken: negs = [x across coll if x<1] instead of negs = [x for x in coll if x<1] What's really weird is that mapping without filter is indeed possible; one is not forced to write: squares = [x*x for x in coll if true] lol! Denis -- _________________ vita es estrany spir.wikidot.com
Mar 20 2011
parent bearophile <bearophileHUGS lycos.com> writes:
spir:

 Just replace 'in' by another keyword in the expression of 
 list comprehensions, and, I guess, you won't find it broken:

 	negs = [x across coll if x<1]
It increases language complexity for a minimal saving. Not good. Bye, bearophile
Mar 20 2011
prev sibling parent reply spir <denis.spir gmail.com> writes:
On 03/20/2011 09:44 PM, bearophile wrote:
 They should also let down ';' noise, like Go.
My experience so far has shown me that there are two options: 1) You design the whole language syntax on the fact that most times you don't use semicolons (see Python and Haskell. Or even Delight); 2) You keep the semicolons obligatory (see D). Most of the other options I've seen (JavaScript, Go) are train wrecks :-)
You'd have to support such as assertion with some material, I guess ;-) Lua also lives very well without ';' (except, like Python & Go, for multi-statement lines). And I don't see what your point 1) actually means. Ones just need to let down ';', e basta. There is no syntactic issue with treating newline as a statement separator or terminator in place of ';'. Denis -- _________________ vita es estrany spir.wikidot.com
Mar 20 2011
parent reply KennyTM~ <kennytm gmail.com> writes:
On Mar 21, 11 05:21, spir wrote:
 On 03/20/2011 09:44 PM, bearophile wrote:
 They should also let down ';' noise, like Go.
My experience so far has shown me that there are two options: 1) You design the whole language syntax on the fact that most times you don't use semicolons (see Python and Haskell. Or even Delight); 2) You keep the semicolons obligatory (see D). Most of the other options I've seen (JavaScript, Go) are train wrecks :-)
You'd have to support such as assertion with some material, I guess ;-) Lua also lives very well without ';' (except, like Python & Go, for multi-statement lines).
Python is designed to use \n as the separator. I believe Lua too. D is not.
 And I don't see what your point 1) actually means. Ones just need to let
 down ';', e basta. There is no syntactic issue with treating newline as
 a statement separator or terminator in place of ';'.

 Denis
No, you may break existing code by replacing all \n with ; auto g = longExpression .readln(); // auto g = longExpression.readln(); ? // auto g = longExpression; .readln(); ? if (b) return a (c.methodPtr)(d); // if (b) return a; (c.methodPtr)(d); ? // if (b) return a(c.methodPtr)(d); ?
Mar 20 2011
parent spir <denis.spir gmail.com> writes:
On 03/20/2011 11:56 PM, KennyTM~ wrote:
 On Mar 21, 11 05:21, spir wrote:
 On 03/20/2011 09:44 PM, bearophile wrote:
 They should also let down ';' noise, like Go.
My experience so far has shown me that there are two options: 1) You design the whole language syntax on the fact that most times you don't use semicolons (see Python and Haskell. Or even Delight); 2) You keep the semicolons obligatory (see D). Most of the other options I've seen (JavaScript, Go) are train wrecks :-)
You'd have to support such as assertion with some material, I guess ;-) Lua also lives very well without ';' (except, like Python & Go, for multi-statement lines).
Python is designed to use \n as the separator. I believe Lua too. D is not.
 And I don't see what your point 1) actually means. Ones just need to let
 down ';', e basta. There is no syntactic issue with treating newline as
 a statement separator or terminator in place of ';'.

 Denis
No, you may break existing code by replacing all \n with ; auto g = longExpression .readln();
Indeed, I don't mean you can replace ';' by newline in D without breaking code! Denis -- _________________ vita es estrany spir.wikidot.com
Mar 20 2011
prev sibling next sibling parent reply KennyTM~ <kennytm gmail.com> writes:
On Mar 21, 11 01:36, bearophile wrote:
 Through I've found a link to a language I didn't know, named Archetype. This
blog post contains some pointers and references about the language:
 http://dvanderboom.wordpress.com/2010/04/26/new-language-code-named-archetype/

 Some comments and quotations and notes about the language. Some of the things
I write are already translated to a D-like syntax.




 Archetype looks designed to make handy practical/industrial high level coding
with GUIs, databases, etc. Archetype seems to contain many pre-built high level

features that you combine in many more ways.

 ----------------------------------

 The idea of optional curly braces for functions with 1 expression inside (just
a return):
 int foo(int x) return x * x;
 Instead of:
 int foo(int x) { return x * x; }

 It is similar to a syntax like:
 foreach (x; 0 .. 10) y *= x;
 Instead of:
 foreach (x; 0 .. 10) { y *= x; }

 ------------------------


you add two delegates, they get chained. When you call the result of the sum,
both get called, in sequence. Probably this is handy to attach chains of
callbacks to GUI elements.
This is a standard CLI feature. It supports -= also. No + is not supported.
 ------------------------

 Imports inside functions, etc.:

 void foo(int x) {
      import std.stdio;
      writeln(x * x);
 }
I don't think such fine-grained level of import scoping would bring many benefits. Module-level import is good enough. Well maybe allow import inside unittest{} block, but we have version(unittest).
 ------------------------

 There is a very short syntax to perform the simplest loops, here translated to
D-like:

 foreach(10) {
 }
Cute, but 'foreach(_; 0..10)' isn't really that long. And this change makes integers look like they are iterable, like map!"a*a"(10) should work?!
 ------------------------

 In Archetype, the exclamation point can be placed before the parentheses. It
is the only part of the condition that can appear outside the parentheses.

 if !(expression)
      statement;
This makes 'if' looks like a template :p.
 ------------------------

 There is a form of pattern matching:


 var x = 1;
 var number = 4;
 match (number) {
    x ->  number += 3;
    3 | 5 ->  number++;
    2 | 4 | 6..10 ->  {
      number–;
      Log("Numbers are getting too big");
    }
 }
This is not pattern matching. This is only a regular 'switch' that does not fall-through. switch(number) { default: number += 3; break; case 3, 5: number ++; break; case 2, 4: case 6: .. case 9: number --; Log("Numbers are getting too big"); break; } Functional language's pattern matching is useful because of built-in algebraic types, and that they fill in the fields for you.
 ------------------------

 In Archetype if you have an Color enum, in some situations you don't need to
write Color.Green, you are allowed to use just Green.

 ------------------------

 There are nullable types:

 int? x = 4;
 auto x? = 4;
useful for value types to provide an extra value, 'null'. Reference types can take 'null' no matter that '?' is present or not. This is just the same situation in D where structs are non-nullable.
 ------------------------

 There are tuples, used like this:

 (int, int) getMouseLocation() {
      return (100, 50);
 }


 Or with named fields too:

 (x int, y int) getMouseLocation() {
      return (100, 50);
 }


 At the call site:

 auto (x, y) = getMouseLocation();
Yeah this was tried once and becomes a mess in detail :) http://www.digitalmars.com/d/archives/digitalmars/D/Re_Tuple_literal_syntax_Tuple_assignment_118601.html So how Archetype deals with 0 and 1-tuple?
 ------------------------

 It has "Streams", that are iterators, very similar to the yield syntax sugar I
have suggested:
 http://d.puremagic.com/issues/show_bug.cgi?id=5660


 yield(int) Numbers() {
    yield 1, 2, 3;

 }

 Or even (I have kept the Archetype syntax here):

 yield(int) Numbers() {
    yield 0..100 skip 5;
 }
'yield' is gogreatod. Most of the time an input range is sufficient, where a generator expresses it very nicely. Not sure about the comprehensive version in Archetype though. This can be easily rewritten to foreach(i; 0..100 skip 5) yield i; Often you can yield an unmodified list comprehension, you could just return it. There isn't much benefit in complicating the 'yield' syntax.
 ----------------------

 It has Pascal/Ada-style ranged numbers (I have kept the Archetype syntax here):

 // an int that can only have a value from 0 to 105
 type ValidAge int in [0..105];


 An anonymous subrange type, when you don't need to define the type:
 Age int in [0..105];
This could be a library type (as proposed before?) alias Bounded!(0, 105, int) ValidAge; the problem is to let the compiler knows the value-range in the propagation.
 ----------------------

 It has List Comprehensions (I have kept the Archetype syntax here):

 var FirstHundred = [ 1..100 ];

 var FirstHundred = from x in [ 1..100 ] where x*x>  3 select x*2;


 In my opinion the map/filter/reduce of Phobos2 have almost failed because
their syntax is too much noisy and heavy, I don't want to see them used a lot
in production code. Even in Python code map/filter/reduce are uncommon. Modern
Python programmers use mostly lazy/eager sequence comprehensions. But I don't
like the List Comprehensions syntax of Archetype.
Yes. Maybe the Python/Javascript 1.7-like syntax a = (f(x,y,z) foreach(x,y; it) if(cond(x,y)) foreach(z; it2) ...) we also need to be careful not to turn an invalid statement to valid. v = f(1,2,3) // <-- foreach(x, y; it); // <-- perform(x,y);
 ----------------------

 In Ruby arrays (lists) support the - infix operator too, to remove the first
item equal to the one given on the right of the minus sign (similar to the
list.remove() method in Python). But this operator is not present yet in
Archetype design.
Since this is an O(N) operation I don't see any reason an operator-based syntax will be allowed, given 'in' is rejected for this reason.
 ----------------------

 A cute quote:

 In my study of linguistics, I learned that legends like Noam Chomsky could
learn hundreds of langauges; the previous librarian at the Vatican could read
97.<
Hundreds could be >> 100 :)
 ----------------------

 There are ways to define infix binary operators (this is dangerous/troubled
stuff):

 // "ABC" dup 3 == "ABCABCABC"
 binary dup string (left string, right int)
 return string.Repeat(left, right)


 Even infix spaces that mean something (there was a C++0x joke about this):

 // "123" "45" == "12345"
 binary adjacent string (left string, right string)
 return left + right;


 And just suffixes:

 // 12 minutes == TimeSpan.FromMinutes(12)
 unary suffix minutes TimeSpan (short, int)
 return TimeSpan.FromMinutes((int)value);
"ABC".dup(3) 12.minutes // with UFCS (Well the did author said by defining these tokens as unary suffix operators, we can eliminate even the dot operator and make it that much more fluent and natural to type (without losing any syntactic precision). I don't think it matters.)
 ----------------------

 If not specified there is a default constructor, ad in D structs:

 class Foo {
    string x;
    int y;
 }
 void main() {
    Foo f = new Foo("hello", 10);
 }

 Is this going to cause problems in D?

 ----------------------

 I have omitted several other things.

 (Just to be sure: with this post I am not proposing to add all that stuff to
D2/D3. I like only part of the things I've shown.)

 Bye,
 bearophile
Mar 20 2011
parent reply bearophile <bearophileHUGS lycos.com> writes:
KennyTM~:

 And this change makes integers look like they are iterable,
That's not so good, I agree :-)
 This makes 'if' looks like a template :p.
I agree, that may cause troubles in D. Not good.
 Yeah this was tried once and becomes a mess in detail :)
I remember part of the discussion, and I think it's a not so messy situation. I think it's doable.
 So how Archetype deals with 0 and 1-tuple?
I don't know, I presume as Python. In that discussion I said to Walter than the 1-tuple cause problems in Python. In the meantime I have changed my mind a bit: 1-tuple syntax in Python is not great, but it's much better than not having tuple syntax :-)
 'yield' is gogreatod.
I have no idea what 'gogreatod' means, sorry :-)
 This could be a library type (as proposed before?)
Right.
 the problem is to let the compiler knows the value-range in the propagation.
Right...
 Yes. Maybe the Python/Javascript 1.7-like syntax
      a = (f(x,y,z) foreach(x,y; it) if(cond(x,y)) foreach(z; it2) ...)
Yes please. Plus the eager version too that produces an array: [f(x,y,z) foreach(x,y; it) if(cond(x,y)) foreach(z; it2) ...]
 Since this is an O(N) operation I don't see any reason an operator-based
 syntax will be allowed, given 'in' is rejected for this reason.
I don't agree. "in" was refused for the linear search because elsewhere the D "in" is known to be O(1). But D operators are generally allowed to perform O(n) operations too, think about the "a[]-10" vector operation.
 Hundreds could be >> 100 :)
Noam Chomsky is a genius and you must listen to him even when he's drunk :-) Bye, bearophile
Mar 20 2011
parent KennyTM~ <kennytm gmail.com> writes:
On Mar 21, 11 07:41, bearophile wrote:
 KennyTM~:

 And this change makes integers look like they are iterable,
That's not so good, I agree :-)
 This makes 'if' looks like a template :p.
I agree, that may cause troubles in D. Not good.
 Yeah this was tried once and becomes a mess in detail :)
I remember part of the discussion, and I think it's a not so messy situation. I think it's doable.
 So how Archetype deals with 0 and 1-tuple?
I don't know, I presume as Python. In that discussion I said to Walter than the 1-tuple cause problems in Python. In the meantime I have changed my mind a bit: 1-tuple syntax in Python is not great, but it's much better than not having tuple syntax :-)
I agree.
 'yield' is gogreatod.
I have no idea what 'gogreatod' means, sorry :-)
An attempt to replace 'good' with 'great' which failed ;)
 This could be a library type (as proposed before?)
Right.
 the problem is to let the compiler knows the value-range in the propagation.
Right...
 Yes. Maybe the Python/Javascript 1.7-like syntax
       a = (f(x,y,z) foreach(x,y; it) if(cond(x,y)) foreach(z; it2) ...)
Yes please. Plus the eager version too that produces an array: [f(x,y,z) foreach(x,y; it) if(cond(x,y)) foreach(z; it2) ...]
 Since this is an O(N) operation I don't see any reason an operator-based
 syntax will be allowed, given 'in' is rejected for this reason.
I don't agree. "in" was refused for the linear search because elsewhere the D "in" is known to be O(1). But D operators are generally allowed to perform O(n) operations too, think about the "a[]-10" vector operation.
Though they have a [] to signify it's a vectorized operation. I mean bare operation like 'a - 1'. (Also, using '-' makes it confusable with 'a[] - 1', the reason why '~' was created instead of overloading '+')
 Hundreds could be>>  100 :)
Noam Chomsky is a genius and you must listen to him even when he's drunk :-) Bye, bearophile
Mar 20 2011
prev sibling next sibling parent Daniel Gibson <metalcaedes gmail.com> writes:
Am 20.03.2011 18:36, schrieb bearophile:
 It has List Comprehensions (I have kept the Archetype syntax here):

 var FirstHundred = [ 1..100 ];

 var FirstHundred = from x in [ 1..100 ] where x*x>  3 select x*2;
rest isn't, I think.
 In my opinion the map/filter/reduce of Phobos2 have almost failed because
their syntax is too much noisy and heavy, I don't want to see them used a lot
in production code. Even in Python code map/filter/reduce are uncommon. Modern
Python programmers use mostly lazy/eager sequence comprehensions. But I don't
like the List Comprehensions syntax of Archetype.
Having something like LINQ as syntactic sugar for (algorithms on) Ranges in D would be cool. Cheers, - Daniel
Mar 20 2011
prev sibling parent Jacob Carlborg <doob me.com> writes:
On 2011-03-20 18:36, bearophile wrote:
 Through I've found a link to a language I didn't know, named Archetype. This
blog post contains some pointers and references about the language:
 http://dvanderboom.wordpress.com/2010/04/26/new-language-code-named-archetype/

 Some comments and quotations and notes about the language. Some of the things
I write are already translated to a D-like syntax.




 Archetype looks designed to make handy practical/industrial high level coding
with GUIs, databases, etc. Archetype seems to contain many pre-built high level

features that you combine in many more ways.

 ----------------------------------

 The idea of optional curly braces for functions with 1 expression inside (just
a return):
 int foo(int x) return x * x;
 Instead of:
 int foo(int x) { return x * x; }
Like it.
 It is similar to a syntax like:
 foreach (x; 0 .. 10) y *= x;
 Instead of:
 foreach (x; 0 .. 10) { y *= x; }

 ------------------------


you add two delegates, they get chained. When you call the result of the sum,
both get called, in sequence. Probably this is handy to attach chains of
callbacks to GUI elements.
 ------------------------

 Imports inside functions, etc.:

 void foo(int x) {
      import std.stdio;
      writeln(x * x);
 }
Like it.
 ------------------------

 There is a very short syntax to perform the simplest loops, here translated to
D-like:

 foreach(10) {
 }

 ------------------------

 In Archetype, the exclamation point can be placed before the parentheses. It
is the only part of the condition that can appear outside the parentheses.

 if !(expression)
      statement;
Weird.
 ------------------------

 There is a form of pattern matching:


 var x = 1;
 var number = 4;
 match (number) {
    x ->  number += 3;
    3 | 5 ->  number++;
    2 | 4 | 6..10 ->  {
      number–;
      Log("Numbers are getting too big");
    }
 }

 ------------------------

 In Archetype if you have an Color enum, in some situations you don't need to
write Color.Green, you are allowed to use just Green.

 ------------------------

 There are nullable types:

 int? x = 4;
 auto x? = 4;

 ------------------------

 There are tuples, used like this:

 (int, int) getMouseLocation() {
      return (100, 50);
 }


 Or with named fields too:

 (x int, y int) getMouseLocation() {
      return (100, 50);
 }
Like it.
 At the call site:

 auto (x, y) = getMouseLocation();

 ------------------------

 It has "Streams", that are iterators, very similar to the yield syntax sugar I
have suggested:
 http://d.puremagic.com/issues/show_bug.cgi?id=5660


 yield(int) Numbers() {
    yield 1, 2, 3;

 }

 Or even (I have kept the Archetype syntax here):

 yield(int) Numbers() {
    yield 0..100 skip 5;
 }
Like it.
 ----------------------

 It has Pascal/Ada-style ranged numbers (I have kept the Archetype syntax here):

 // an int that can only have a value from 0 to 105
 type ValidAge int in [0..105];


 An anonymous subrange type, when you don't need to define the type:
 Age int in [0..105];

 ----------------------

 It has List Comprehensions (I have kept the Archetype syntax here):

 var FirstHundred = [ 1..100 ];

 var FirstHundred = from x in [ 1..100 ] where x*x>  3 select x*2;


 In my opinion the map/filter/reduce of Phobos2 have almost failed because
their syntax is too much noisy and heavy, I don't want to see them used a lot
in production code. Even in Python code map/filter/reduce are uncommon. Modern
Python programmers use mostly lazy/eager sequence comprehensions. But I don't
like the List Comprehensions syntax of Archetype.

 ----------------------

 In Ruby arrays (lists) support the - infix operator too, to remove the first
item equal to the one given on the right of the minus sign (similar to the
list.remove() method in Python). But this operator is not present yet in
Archetype design.

 ----------------------

 A cute quote:

 In my study of linguistics, I learned that legends like Noam Chomsky could
learn hundreds of langauges; the previous librarian at the Vatican could read
97.<
---------------------- There are ways to define infix binary operators (this is dangerous/troubled stuff): // "ABC" dup 3 == "ABCABCABC" binary dup string (left string, right int) return string.Repeat(left, right) Even infix spaces that mean something (there was a C++0x joke about this): // "123" "45" == "12345" binary adjacent string (left string, right string) return left + right; And just suffixes: // 12 minutes == TimeSpan.FromMinutes(12) unary suffix minutes TimeSpan (short, int) return TimeSpan.FromMinutes((int)value); ---------------------- If not specified there is a default constructor, ad in D structs: class Foo { string x; int y; } void main() { Foo f = new Foo("hello", 10); } Is this going to cause problems in D? ---------------------- I have omitted several other things. (Just to be sure: with this post I am not proposing to add all that stuff to D2/D3. I like only part of the things I've shown.) Bye, bearophile
-- /Jacob Carlborg
Mar 21 2011