Re: Ceylon language

2011-05-05 Thread Max Klyga

On 2011-05-06 00:54:34 +0300, Cristi Cobzarenco said:

Currying is well established name as well, especially for people coming 
from a functional programming background.


Current implementation does not curry the function, it partialy applies it.

Currying is converting a function that takes multiple arguments to a 
function that takes first argument and returns a function that takes 
the second argument and do on.


Curry ((a, b) -> c) -> a -> b -> c
Uncurry (a -> b -> c) -> (a, b) -> c

(Cristi Cobzarenco)
Profile: http://www.google.com/profiles/cristi.cobzarenco


On 4 May 2011 23:40, bearophile  wrote:
Lutger Blijdestijn:

> partial application is getting a new function out of an existing one where
> one of the arguments is fixed / bound. More or less what std.functional
> curry does, confusingly.
> [...]

A simple and good explanation.
Regarding the name of std.functional.curry(), since some time I have 
suggested to rename it "partial".


Bye,
bearophile




Re: Ceylon language

2011-05-05 Thread Cristi Cobzarenco
Currying is well established name as well, especially for people coming from
a functional programming background.

(Cristi Cobzarenco)
Profile: http://www.google.com/profiles/cristi.cobzarenco


On 4 May 2011 23:40, bearophile  wrote:

> Lutger Blijdestijn:
>
> > partial application is getting a new function out of an existing one
> where
> > one of the arguments is fixed / bound. More or less what std.functional
> > curry does, confusingly.
> > [...]
>
> A simple and good explanation.
> Regarding the name of std.functional.curry(), since some time I have
> suggested to rename it "partial".
>
> Bye,
> bearophile
>


Re: Ceylon language

2011-05-04 Thread bearophile
Lutger Blijdestijn:

> partial application is getting a new function out of an existing one where 
> one of the arguments is fixed / bound. More or less what std.functional 
> curry does, confusingly.
> [...]

A simple and good explanation.
Regarding the name of std.functional.curry(), since some time I have suggested 
to rename it "partial".

Bye,
bearophile


Re: Ceylon language

2011-05-04 Thread Lutger Blijdestijn
Nick Sabalausky wrote:

> "spir"  wrote in message
> news:mailman.3497.1302788057.4748.digitalmar...@puremagic.com...
>> On 04/13/2011 02:34 PM, bearophile wrote:
>>
>>>
>>> If a value of type T can be null, it must be declared as type
>>> Optional, which may be abbreviated to T?
>>>
>>> String? name = process.args.first;
>>> if (exists name) {
>>>  writeLine("Hello " name "!");
>>> }
>>> else {
>>>  writeLine("Hello World!");
>>> }
>>>
>>> Use of an optional value must be guarded by the if (exists ... )
>>> construct. Therefore, NullPointerExceptions are impossible.
>>>
>>> This is exactly what I suggested for D in a enhancement request.
>>> It seems this kind of stuff is becoming a standard in new languages.
>>
>> +++
>>
>> But I guess optionality could, and should, extend to non-ref types; thus,
>> null is just a particular case of non-existence. And this would apply
>> especially on function parameters:
>>void f (int i?) {...}
>>
> 
> Oh absolutely. Haxe has nullable-primatives which really comes in handly
> at times (it often prevents the need for a separate bool to keep track
> of). Only problem is that in Haxe, not only is nullable the default, but
> it doesn't even *have* any non-nullables at all, for any type.
> 
> 
>>
>> I don't get the diff between currying & partial app. And find this
>> feature much complication for close to uselessness.
>>
> 
> I'm not certain either, but I *think* partial application is just like
> currying except there's some sort of arbitrary limitaion on what
> combination(s) of paramaters you can choose to specify or not specify. And
> that limitation is based purely on what order the function defines its
> parameters. So basically, my understanding is that partial application is
> an arbitrarily-gimped currying.
> 

partial application is getting a new function out of an existing one where 
one of the arguments is fixed / bound. More or less what std.functional 
curry does, confusingly.

currying however doesn't involve specifying parameters at all, it means to 
get a function with one parameter out of a function with more than one 
parameter. This new function returns a function with one parameter, and so 
on and so forth until there is nothing left to curry. An example is clearer:

int foo(int a, int b, int c) {
return a + b + c;
}

auto curriedFoo(int a) {
return (int b) {
return (int c) {
return foo(a, b, c);
};
};
}

assert( curriedFoo(1)(2)(3) == 6 );


Whereas partial application could be something like:

auto partialApply(F)(int x, F fun) {
return (ParameterTypeTuple!(F)[1..$] args) {
return fun(x, args);
};
}

assert( partialApply(1, &foo)(2,3) == 6);



Re: Ceylon language

2011-05-03 Thread Bruno Medeiros

On 13/04/2011 13:34, bearophile wrote:

The first description of the Ceylon language, designed for business computing 
(for large teams developing multi-user applications) and meant to replace Java, 
from Red Hat, that will run on the Java Virtual Machine itself:
http://blog.talawah.net/2011/04/gavin-king-unviels-red-hats-top-secret.html

About the language (very slow download):
http://www.qconbeijing.com/download/Gavin%20keynote.pdf
About the its type system:
http://www.qconbeijing.com/download/Gavin%20session.pdf



Hum, I saw this Ceylon stuff posted on Slashdot, and I've finally gotten 
around to taking a look at it. I don't have yet an opinion of the 
language as a whole, but I do like some of things they did or are 
thinking about. Namely, that they are extending or changing the type 
system, and not just to put in non-nullable types (which is quite simple 
to do), but going much further than that: looking at generics, 
covariance in generics  (and in the process placing the immutability of 
collections in the type system instead of the runtime), being able to 
specify all possible subclasses of a class, union types, etc. 
Interesting ideas.



--
Bruno Medeiros - Software Engineer


Re: Ceylon language

2011-04-16 Thread David Nadlinger

On 4/15/11 8:19 PM, Andrej Mitrovic wrote:

[…] My biggest issue is that
I can't modify variables at compile time. I wish there was some
special CTFE int type which is only visible at compile-time and which
we can use however we want. That way I could keep count of things, for
example I could generate a list of indexes that can then be mixed in
as a string.
[…]
I dunno, CTFE overall seems like a buggy thing where I have to guesswhether 
something will work or not. It's very stress-inducing.


Correct me if I'm wrong, but might it be that you are conflating 
templates and CTFE, which are – although they are both used for 
metaprogramming – two entirely different concepts?


Maybe it helps to think of calling a function at compile time as a gate 
into a parallel universe. In this other world, you can modify variables, 
call functions, etc. as you please, just as if you were executing code 
at runtime (well, inside the more or less implementation-defined 
boundaries of CTFE). The only restriction is that you can only return a 
single value through the gate, there is no other way to influence the 
»compiler« universe from inside the functions you call. More 
specifically, there is no way to manipulate types in the compiler 
universe – although you can instantiate templates in CTFE functions just 
like normal, you will never be able to »return« them back to the outside 
world. Also, be aware of the fact that a CTFE function can just work on 
_values_, like every other runtime function, not on types.


So much for CTFE. Templates, on the other hand, are basically just named 
scopes with a few extra features which happen to make a Turing complete 
language. As such, there will never be something like a runtime variable 
modifiable at compile time in templates, as you asked (at least I hope 
so). The interesting thing about templates is that they allow you to 
work with types themselves. Due to the absence of mutable state, you are 
generally limited to functional techniques, though, which can be 
uncomfortably similar to the proverbial Turing tarpit in some cases 
(although it's surprising how easy it is to write certain algorithms in 
a functional manner once you got the hang of it).


However, there are ways to combine templates and CTFE to your advantage. 
Without any concrete question, it's obviously hard to give a good 
suggestion, but an example would be to use template functions called at 
compile time to produce string mixins:


---
string generateCode(T...)() {
string code;
[… construct a string containing some declarations …]
return code;
}

template Foo(T...) {
alias DoSomethingWithATypeTuple!(T) U;
mixin(generateCode(U));
}
---

You can also shorten this by using delegate literals:
---
template Foo(T...) {
alias DoSomethingWithATypeTuple!(T) U;
mixin({
[…]
return "";
}());
}
---

Another small template metaprogramming example showing a way to process 
a list of types without needing mutable state. Specifically, it aliases 
a new type tuple to Result which doesn't contain any items where 
Exp.numerator is 0 (you can do the same with eponymous templates). 
TypeTuples are automatically flattened, which allows for a concise 
implementation here.


---
template Process(T...) {
static if (T.length == 0) {
alias TypeTuple!() Result;
} else {
alias T[0] A;
static if (A.Exp.numerator == 0) {
alias Process!(T[1..$]).Result Result;
} else {
alias TypeTuple!(A, Process!(T[1..$]).Result) Result;
}
}
}
---

As for constructing lists of indices and then generating code of them: 
If you need to work on types for generating the list, you could e.g. use 
some recursive template to construct a type tuple of integer literals 
(that name really doesn't fit well), and then process it via CTFE to 
generate code to be mixed in – or whatever you need in your specific 
case. Feel free to ask about any specific problems in d.D.learn.


David


Re: Ceylon language

2011-04-15 Thread Dmitry Olshansky

On 15.04.2011 22:24, KennyTM~ wrote:

On Apr 16, 11 00:29, Andrej Mitrovic wrote:

I've also tried to create a some sort of 'bind' function which could
let you bind arguments to specific parameters of a function. If I had
it working it would really help (me) out in coding for  e.g. the
Windows API. For example you might have a WinAPI function such as (I'm
pseudocoding here):

CreateWindow(int x, int y, int w, int h, int* opt1, int* opt2, int*
opt3, char* name);

And if you want to create a certain type of window with some
parameters which are always the same, you could create an alias that
binds certain arguments to this function:

alias bind!CreateWindow(void, void, width, height, null, null, null,
void) myWindow;

Here 'void' would designate arguments that you would have to fill in
when calling myWindow.

You would call it like:
myWindow(posX, posY, "MyWindowName");

which would translate the call to:
CreateWindow(posX, posY, width, height, null, null, null, 
"MyWindowName");


I don't see the point reviving the std.bind module*. In your case a 
new function name 'myWindow' needs to be defined, which makes it 
easier to just create a wrapper function


auto myWindow(int x, int y, char* name) {
   return CreateWindow(x, y, width, height, null, null, null, name);
}

*: http://www.digitalmars.com/d/2.0/phobos/std_bind.html


I absolutely agree, also creating delegate in place solves pretty much 
all of std.bind use cases.


--
Dmitry Olshansky



Re: Ceylon language

2011-04-15 Thread KennyTM~

On Apr 16, 11 00:29, Andrej Mitrovic wrote:

I've also tried to create a some sort of 'bind' function which could
let you bind arguments to specific parameters of a function. If I had
it working it would really help (me) out in coding for  e.g. the
Windows API. For example you might have a WinAPI function such as (I'm
pseudocoding here):

CreateWindow(int x, int y, int w, int h, int* opt1, int* opt2, int*
opt3, char* name);

And if you want to create a certain type of window with some
parameters which are always the same, you could create an alias that
binds certain arguments to this function:

alias bind!CreateWindow(void, void, width, height, null, null, null,
void) myWindow;

Here 'void' would designate arguments that you would have to fill in
when calling myWindow.

You would call it like:
myWindow(posX, posY, "MyWindowName");

which would translate the call to:
CreateWindow(posX, posY, width, height, null, null, null, "MyWindowName");


I don't see the point reviving the std.bind module*. In your case a new 
function name 'myWindow' needs to be defined, which makes it easier to 
just create a wrapper function


auto myWindow(int x, int y, char* name) {
   return CreateWindow(x, y, width, height, null, null, null, name);
}

*: http://www.digitalmars.com/d/2.0/phobos/std_bind.html


Re: Ceylon language

2011-04-15 Thread Andrej Mitrovic
Oh and the reason I used a struct and opCall inside the template is
because this somehow allowed me to use foreach for some things. I
dunno, CTFE overall seems like a buggy thing where I have to guess
whether something will work or not. It's very stress-inducing.


Re: Ceylon language

2011-04-15 Thread Andrej Mitrovic
Here's a hardcoded example:

http://codepad.org/klr8S1hi

I've tried numerous ways of automatically creating the appropriate
call to fun in the bind template, but I've been unsuccessful. Maybe
using some form of string mixin would work.. My biggest issue is that
I can't modify variables at compile time. I wish there was some
special CTFE int type which is only visible at compile-time and which
we can use however we want. That way I could keep count of things, for
example I could generate a list of indexes that can then be mixed in
as a string.


Re: Ceylon language

2011-04-15 Thread bearophile
Andrej Mitrovic:

> alias bind!CreateWindow(void, void, width, height, null, null, null,
> void) myWindow;

How do you give a void argument to a function, in D2? This doesn't work, 
despite having templated void arguments seems potentially useful:

void foo(T)(T x) {}
void bar() {}
void main() {
foo(bar());
}


> But I've had zero luck with CTFE and
> templates. Perhaps Don's upcoming CTFE revamp could make this
> possible.

Don has changed mostly how CT functions manage their memory.

Bye,
bearophile


Re: Ceylon language

2011-04-15 Thread Andrej Mitrovic
I've recently made an attempt to make a curry alternative which can
take any number of parameters (currently the curry implementation only
works with 1 parameter). I've put my implementation in bugzilla, it is
extremely simple (and maybe buggy :p)
http://d.puremagic.com/issues/show_bug.cgi?id=5829.

I've also tried to create a some sort of 'bind' function which could
let you bind arguments to specific parameters of a function. If I had
it working it would really help (me) out in coding for  e.g. the
Windows API. For example you might have a WinAPI function such as (I'm
pseudocoding here):

CreateWindow(int x, int y, int w, int h, int* opt1, int* opt2, int*
opt3, char* name);

And if you want to create a certain type of window with some
parameters which are always the same, you could create an alias that
binds certain arguments to this function:

alias bind!CreateWindow(void, void, width, height, null, null, null,
void) myWindow;

Here 'void' would designate arguments that you would have to fill in
when calling myWindow.

You would call it like:
myWindow(posX, posY, "MyWindowName");

which would translate the call to:
CreateWindow(posX, posY, width, height, null, null, null, "MyWindowName");

WinAPI is full of functions which take optional parameters which need
to be set to null if they're not to be used, so this kind of 'bind'
function could be pretty useful. But I've had zero luck with CTFE and
templates. Perhaps Don's upcoming CTFE revamp could make this
possible.


Re: Ceylon language

2011-04-15 Thread Pelle

On 04/15/2011 03:23 AM, Nick Sabalausky wrote:

I'm not certain either, but I *think* partial application is just like
currying except there's some sort of arbitrary limitaion on what
combination(s) of paramaters you can choose to specify or not specify. And
that limitation is based purely on what order the function defines its
parameters. So basically, my understanding is that partial application is an
arbitrarily-gimped currying.


In my understanding they are, while related, distinct like so:

int foo(int x, int y, int z);

int delegate(int, int) p = partiallyApply(&foo, 3);
int delegate(int) delegate(int) delegate(int) c = curry(&foo);

assert (p(4,5) == foo(3,4,5));
assert (c(3)(4)(5) == foo(3,4,5));


Re: Distinction of null and empty [was Re: Ceylon language]

2011-04-14 Thread Kagamin
Nick Sabalausky Wrote:

> I've thought about that and I don't know how I feel about it. On one hand, I 
> can certainly image cases where the distiction between null and empty would 
> be useful. But OTOH, after having to put up with the nightmare of VB6's "One 
> million distinct ways to have a string that doesn't contain anything", I'm 
> hesitent at embracing extra ways to have "ain't nuthin' here".
> 

In our project we use

if(string.IsNullOrEmpty(str)){...}

almost everywhere
only in two places null matters.

T__T


Re: Distinction of null and empty [was Re: Ceylon language]

2011-04-14 Thread Nick Sabalausky
"Jesse Phillips"  wrote in message 
news:io7oov$21d8$1...@digitalmars.com...
> spir Wrote:
>
>> This also leads to actual distinction of null and [] or "" for arrays &
>> strings. Just dreaming...
>
> Really? You want this? I really like that a null array is equal to an 
> empty array.
>

I've thought about that and I don't know how I feel about it. On one hand, I 
can certainly image cases where the distiction between null and empty would 
be useful. But OTOH, after having to put up with the nightmare of VB6's "One 
million distinct ways to have a string that doesn't contain anything", I'm 
hesitent at embracing extra ways to have "ain't nuthin' here".




Re: Ceylon language

2011-04-14 Thread Nick Sabalausky
"bearophile"  wrote in message 
news:io7gk3$1jea$1...@digitalmars.com...
> spir:
>
>> But I guess optionality could, and should, extend to non-ref types; thus, 
>> null
>> is just a particular case of non-existence. And this would apply 
>> especially on
>> function parameters:
>>void f (int i?) {...}
>
> From C# experience it seems non-ref nullable types are not so useful (and 
> it's not hard to implement them with the language itself).
>

My experience indicates it's hard to implement useful generics in C# at all. 
(Ex: Missing IArithmetic, anyone?)




Re: Ceylon language

2011-04-14 Thread Nick Sabalausky
"spir"  wrote in message 
news:mailman.3497.1302788057.4748.digitalmar...@puremagic.com...
> On 04/13/2011 02:34 PM, bearophile wrote:
>
>>
>> If a value of type T can be null, it must be declared as type 
>> Optional, which may be abbreviated to T?
>>
>> String? name = process.args.first;
>> if (exists name) {
>>  writeLine("Hello " name "!");
>> }
>> else {
>>  writeLine("Hello World!");
>> }
>>
>> Use of an optional value must be guarded by the if (exists ... ) 
>> construct. Therefore, NullPointerExceptions are impossible.
>>
>> This is exactly what I suggested for D in a enhancement request.
>> It seems this kind of stuff is becoming a standard in new languages.
>
> +++
>
> But I guess optionality could, and should, extend to non-ref types; thus, 
> null is just a particular case of non-existence. And this would apply 
> especially on function parameters:
>void f (int i?) {...}
>

Oh absolutely. Haxe has nullable-primatives which really comes in handly at 
times (it often prevents the need for a separate bool to keep track of). 
Only problem is that in Haxe, not only is nullable the default, but it 
doesn't even *have* any non-nullables at all, for any type.


>
> I don't get the diff between currying & partial app. And find this feature 
> much complication for close to uselessness.
>

I'm not certain either, but I *think* partial application is just like 
currying except there's some sort of arbitrary limitaion on what 
combination(s) of paramaters you can choose to specify or not specify. And 
that limitation is based purely on what order the function defines its 
parameters. So basically, my understanding is that partial application is an 
arbitrarily-gimped currying.


>>
>> A class or interface satisfies zero or more interfaces
>>
>> shared class Character(Natural utf16)
>>  extends Object()
>>  satisfies Ordinal&  Comparable  {
>>  ...
>> }
>>
>> The syntax X&Y represents the intersection of two types. The syntax X|Y 
>> represents the union of two types.
>
> Too bad, they got it wrong, like D. Should instead rip Go interfaces, 
> which are structural & implicite, while still fully compile-time 
> type-safe:
>
> struct File inStream {
> ...
> void write (string s) {...};
> }
> ...
> interface Writer {
> void write (string s);
> }
> File is *also* a Writer, thus one can call the following on a specimen of 
> File:
> void formatWrite (Writer w, string s, string format) {...}
>
> More generally, any type can satisfy any number of interfaces, wherever 
> and whenever they are defined (eg years after, in user code). The 
> obligation of explicitely declaring interface satisfaction is both useless 
> and blocking.
>
> Free interfaces even provide some kind of simple generics for free (like 
> in above example). And there is no need for
>  ... if (is(...))
> or
>  ... if (isWriter!T)
>

I think Go's implicit interfaces are horrible. It's literally nothing more 
than duck-typing at compile time (ie, static duck-typing) and fully inherits 
duck-typing's downfalls (notably that it's sloppy and conflates 
name/signature with semantics - which is an entirely false connection). Of 
course, I guess this argument doesn't hold if you're a duck-typing fan ;)


> Too bad its base for imrovement is Java (there is no way to get light & 
> flexible coding from there, you'd have to change everything ;-),

Yup. This is one of the reasons I don't buy the claims of "Java's fast now, 
really!". In fact, the article I'm [trying to] write for the article 
competition relates to this. Basically, code can't be fast *and* flexible 
*and* maintable without real metaprogramming (and class-based generics don't 
count), and Java AFAIK just doesn't have metaprogramming. Although I suppose 
you might be able to hack it by using a pre-processor, but pre-processors 
have their downsides. And even if you did use one, Java's requirement that 
every aggregate type be a class can be a real hinderance. Of course, the 
JVM's advanced class/object optimizations may be able to help - but only to 
a point, and you still can't reliably prevent situations that would hinder 
the JVM's ability to do the necessary optimizations.





Distinction of null and empty [was Re: Ceylon language]

2011-04-14 Thread Jesse Phillips
spir Wrote:

> This also leads to actual distinction of null and [] or "" for arrays & 
> strings. Just dreaming...

Really? You want this? I really like that a null array is equal to an empty 
array.

If you really care to find out if a string is null

if(str is null)


Re: Ceylon language

2011-04-14 Thread spir

On 04/14/2011 09:06 PM, bearophile wrote:

But I guess optionality could, and should, extend to non-ref types; thus, null
>  is just a particular case of non-existence. And this would apply especially 
on
>  function parameters:
>  void f (int i?) {...}

 From C# experience it seems non-ref nullable types are not so useful (and it's 
not hard to implement them with the language itself).


Dunno C# at all.
But I find optionality far more useful for non-ref types, since in the general 
case there is no truelly special or invalid value like null. What value means 
undefined/inexistent/non-provided, for an int? a bool? Unlike for ref'ed types 
(actual pointers/classes/arrays) we simply cannot express this without language 
support.
This also leads to actual distinction of null and [] or "" for arrays & 
strings. Just dreaming...


Denis
--
_
vita es estrany
spir.wikidot.com



Re: Ceylon language

2011-04-14 Thread bearophile
spir:

> But I guess optionality could, and should, extend to non-ref types; thus, null
> is just a particular case of non-existence. And this would apply especially on
> function parameters:
>void f (int i?) {...}

>From C# experience it seems non-ref nullable types are not so useful (and it's 
>not hard to implement them with the language itself).


> Also, they should reuse '?' to mean 'exists', possibly '!?' meaning the 
> opposite:
> void f (int i?) {
> if (? i) doWithI(i);
> if (!? i) doWithoutI();
> ...
> }

Better to keep the language less perlish.


> great! get rid of new in D as well

This was discussed a lot. I don't have much interest in this change.


>> We may define a class method "by reference":
>>
>> void hello(String name) = hello;
>
> ???

The second hello is a function reference. Nothing so interesting to see here.


> I don't get the diff between currying & partial app.

Take a look at the wikipedia pages, the difference is small, they are quite 
related things, their difference is no so important:
http://en.wikipedia.org/wiki/Currying
http://en.wikipedia.org/wiki/Partial_application


> And find this feature much complication for close to uselessness.

In functional-style programming it's useful to be able to curry (or partially 
applicate) functions, it helps keep the code shorter and less noisy.


> examples?

See the first PDF at those pages. In the meantime people have mirrored those 
PDFs, see the Reddit thread.


> Yo; and while you're at "typestating", extend the feature to any type (not 
> only
> pointers).

For this you may need to look for a language (Rust) designed for the ground up 
for this feature.

Bye,
bearophile


Re: Ceylon language

2011-04-14 Thread spir

On 04/13/2011 07:06 PM, bearophile wrote:

Kagamin:


>  How will it work on this code?
>
>  String? name = process.args.first;
>  myLibCustomEnforce(exists name);
>  writeLine("Hello " name "!");

If you want to implement the feature well, then the compiler has to manage a bit of type state too. 
The state of the type of the (here immutable) variable "name" before myLibCustomEnforce() 
is different from the state of the type of "name" after that call.


Yo; and while you're at "typestating", extend the feature to any type (not only 
pointers).


Denis
--
_
vita es estrany
spir.wikidot.com



Re: Ceylon language

2011-04-14 Thread spir

On 04/13/2011 02:34 PM, bearophile wrote:


-

Ceylon does not support method overloading (or any other kind of overloading).


How to survive? Named args and default values somewhat mitigate this lack, but 
still...

I read (somewhere) this only for /operator/ overloading.


-

If a value of type T can be null, it must be declared as type Optional, 
which may be abbreviated to T?

String? name = process.args.first;
if (exists name) {
 writeLine("Hello " name "!");
}
else {
 writeLine("Hello World!");
}

Use of an optional value must be guarded by the if (exists ... ) construct. 
Therefore, NullPointerExceptions are impossible.

This is exactly what I suggested for D in a enhancement request.
It seems this kind of stuff is becoming a standard in new languages.


+++

But I guess optionality could, and should, extend to non-ref types; thus, null 
is just a particular case of non-existence. And this would apply especially on 
function parameters:

   void f (int i?) {...}

Also, they should reuse '?' to mean 'exists', possibly '!?' meaning the 
opposite:
   void f (int i?) {
   if (? i) doWithI(i);
   if (!? i) doWithoutI();
   ...
}


-

Attributes and local variables are immutable by default. Assignable values must 
be annotated variable:

variable Natural count := 0;


Immutability should be the default for locals (especialy params) in all 
languages.

'Natural' is great ;-)


-

A getter looks like a method without a parameter list:

shared Natural currentValue {
 return count;
 }
}


good


Attributes are polymorphic. A subclass may override a superclass attribute. It 
may even override a simple attribute with a getter or vice versa!

This means there is no need for explicit getter/setters until you are ready for 
them. This is nice.


very good

I often miss this in D. The fact that subtyping in D applies only to methods 
forces to add fake data members in supertypes (which are thus present in all 
subtypes...). I find this design crazy !!!
Same note for mixins: why do they hold only methods? A "role" to be mixed-in 
often requires both data & methods.



-

There is no new keyword:

Counter c = Counter();


great! get rid of new in D as well

coll = (new Coll(cap)).fill(data);
==>
coll = Coll(cap).fill(data);


-

Assignment to a variable value or attribute setter is done using the := 
operator. The = specifier is used only for specifying immutable values:

shared assign currentValue {
 count := currentValue;
}


If I understand you correctly, this is wrong. The operators should instead make 
distinct *creation* versus *change*:

   variable Natural count = 0;  // create
   count := 3;  // change
   local Natural i = 1; // cannot be changed


-

We may define a class method "by reference":

void hello(String name) = hello;


???


-

A method may declare multiple lists of parameters. The method body is executed 
after arguments have been supplied to all parameter lists:

Float add(Float x)(Float y) {
 return x+y;
}

This is a kind of user defined and safe partial application, it's a cute idea.

Providing arguments to just one parameter list produces a method reference:

Float addOne(Float y) = add(1.0);
Float three = addOne(2.0);

(The point of all this is that we are able to provide all the functionality of 
first-class and higher-order functions without needing to resort to unnatural 
syntactic constructs inspired by the lambda calculus notation.)


I don't get the diff between currying & partial app. And find this feature much 
complication for close to uselessness.



-

There is a Named argument syntax.


A true programmer uses named args in half of all method calls; meaning, 
everywhere args' meanings are not absolutely obvious.


 They use it for a syntax trick: A named argument invocation is enclosed in 

braces, and non-vararg arguments are listed using the name=value; syntax.


This seems one of the most peculiar and refined parts of the syntax of this 
language. See slides 34-37 in the first PDF.


examples?


-

A class or interface satisfies zero or more interfaces

shared class Character(Natural utf16)
 extends Object()
 satisfies Ordinal&  Comparable  {
 ...
}

The syntax X&Y represents the intersection of two types. The syntax X|Y 
represents the union of two types.


Too bad, they got it wrong, like D. Should instead rip Go interfaces, which are 
structural & implicite, while still fully compile-time type-safe:


struct File inStream {
...
void write (string s) {...};
}
...
interface Writer {
void write (string s);
}
File is *also* a Writer, thus one can call the following on a specimen of File:
void formatWrite (Writer w, string s, string format) {...}

More generally, any type can satisfy any number of interfaces, wherever and 
whenever they 

Re: Ceylon language

2011-04-13 Thread Walter Bright

On 4/13/2011 2:14 PM, bearophile wrote:

I agree it's just a high level discussion, there are not enough details yet.
But a similar feature is present in Spec# and probably will be present in
Rust. It seems several new languages want to solve this problem. How and how
well is to be seen.



I don't know about Rust, but as we've discovered and discussed before, Spec# is 
a language with lofty goals that doesn't actually work and doesn't seem to have 
much of any user base. Hence a feature existing in Spec# is not much evidence 
that it is valid and useful.




Re: Ceylon language

2011-04-13 Thread bearophile
> template fs(alias f) {
> auto fs(Range)(Range s) {
> return map!f(s);
> }
> }

And by the way, this is similar to the "manual" partial application of Ceylon, 
just with a worse syntax.

Bye,
bearophile


Re: Ceylon language

2011-04-13 Thread bearophile
Kagamin:

> Do you describe, how Ceylon can work hypotetically or how it actually works?

There is no Ceylon implementation yet, and even its authors probably will have 
to change some of their ideas during the implementation phase, so there is not 
much real about what I have written. I have just interpreted the first 
documents they have released. Sorry for not being sufficiently explicit about 
this.

(From what I've seen in the development of Scala, the Java VM allows to create 
a first language implementation in a not so much time.)

-

Nick Sabalausky:

>That really stikes me as a completly wrong way to do currying. Granted, I've 
>never really used currying, but it seems it would only be appropriate for 
>*outside* code to choose which to specify and not specify.<

Here we are talking about a special case of partial function application, it's 
not currying. I have used partial application in Haskell, and it's very nice 
and very handy. If you have a function foo(x,y), in Haskell you are able to 
write things like:

map (foo 5) somelist
foo5 = foo 5
map foo5 somelist
map (5 +) [0 .. 10]

Partial application is nice for template arguments too.

This is a little Rosettacode task to use partial application:
http://rosettacode.org/wiki/Partial_function_application

The Task:
- Create a function fs( f, s ) that takes a function, f( n ), of one value and 
a sequence of values s.
- Function fs should return an ordered sequence of the result of applying 
function f to every value of s in turn. 
- Create function f1 that takes a value and retuns it multiplied by 2.
- Create function f2 that takes a value and returns it squared. 
- Partially apply f1 to fs to form function fsf1( s )
- Partially apply f2 to fs to form function fsf2( s ) 
-Test fsf1 and fsf2 by evaluating them with s being the sequence of integers 
from 0 to 3 inclusive and then the sequence of even integers from 2 to 8 
inclusive. 

The Haskell version is very very simple:

fs f s = map f s
f1 value = value * 2
f2 value = value ^ 2

fsf1 = fs f1
fsf2 = fs f2

main = do
  print $ fsf1 [0, 1, 2, 3]
  print $ fsf2 [0, 1, 2, 3]
  print $ fsf1 [2, 4, 6, 8]
  print $ fsf2 [2, 4, 6, 8]


D has a partial applicator in std.functional, but I think it can't be used 
here, this is a not so good implementation:


import std.stdio, std.algorithm, std.range;
 
template fs(alias f) {
auto fs(Range)(Range s) {
return map!f(s);
}
}
 
auto f1(T)(T x) { return x * 2; }
auto f2(T)(T x) { return x * x; }
 
void main() {
alias fs!f1 fsf1;
alias fs!f2 fsf2;
 
auto d1 = iota(0, 4);
writeln(fsf1(d1));
writeln(fsf2(d1));
 
auto d2 = iota(2, 9, 2);
writeln(fsf1(d2));
writeln(fsf2(d2));
}


The problems I see with unrestricted partial application as in Haskell are:
- I see this feature as possible source of bugs. If you don't give all 
arguments you generate a function instead of a result. I am not sure of this.
- In some situations it's not immediately easy to understand code and what it 
is doing. Ceylon is targeted to commercial applications, and they are clearly 
trying to design a simple language, much simpler than Haskell and simpler than 
D too.

So I presume they have found a compromise between "wild" Haskell-style partial 
application and no partial application at all as in C/C++/Java. They let the 
person that write the function to define what partial applications are allowed. 
This explicit design is how some higher order functions in Phobos are designed. 
map!(to!string)([1, 2, 3]) works thanks to nested templates, this is a way to 
manually specify what partial application there is in the template arguments.

I don't know if this Ceylon design is good, but it looks like an interesting 
idea that I have not seen before.

--

Andrei:

>Also, without more details I can't really say, but if the type of the checked 
>variable doesn't automagically change from T? to T inside the guarded code, a 
>lot of subsequent uses (pass down to functions etc.) would have to repeat the 
>check. Also, if the variable is reassigned it would have to change back the 
>type from T to T?, which makes program understanding by both human and 
>compiler (e.g. "do I need a test here?") a bitch.<

I agree it's just a high level discussion, there are not enough details yet. 
But a similar feature is present in Spec# and probably will be present in Rust. 
It seems several new languages want to solve this problem. How and how well is 
to be seen.

Bye,
bearophile


Re: Ceylon language

2011-04-13 Thread Andrei Alexandrescu

On 4/13/11 3:03 PM, Nick Sabalausky wrote:

"bearophile"  wrote in message
news:io458e$elr$1...@digitalmars.com...


Ceylon does not support method overloading (or any other kind of
overloading).



Eewww. Haxe is like that and it's nothing but a royal pain in the ass.



If a value of type T can be null, it must be declared as type Optional,
which may be abbreviated to T?

String? name = process.args.first;
if (exists name) {
writeLine("Hello " name "!");
}
else {
writeLine("Hello World!");
}

Use of an optional value must be guarded by the if (exists ... )
construct. Therefore, NullPointerExceptions are impossible.

This is exactly what I suggested for D in a enhancement request.
It seems this kind of stuff is becoming a standard in new languages.



Yes, I'd *love* to see that in D, too.


I think you'd be hasty. As Kagamin mentioned, this ad-hoc guarding works 
straight against modularity. Also, without more details I can't really 
say, but if the type of the checked variable doesn't automagically 
change from T? to T inside the guarded code, a lot of subsequent uses 
(pass down to functions etc.) would have to repeat the check. Also, if 
the variable is reassigned it would have to change back the type from T 
to T?, which makes program understanding by both human and compiler 
(e.g. "do I need a test here?") a bitch.


I'm highly skeptical of this feature in particular. I'm even more so 
because it's the kind of ad-hoc feature with many fuzzy corners that 
needs solid real-world validation, which... ("You can’t write code in 
the language just yet!") doesn't exist.



Andrei



Re: Ceylon language

2011-04-13 Thread Nick Sabalausky
"bearophile"  wrote in message 
news:io458e$elr$1...@digitalmars.com...
>
> Ceylon does not support method overloading (or any other kind of 
> overloading).
>

Eewww. Haxe is like that and it's nothing but a royal pain in the ass.

>
> If a value of type T can be null, it must be declared as type Optional, 
> which may be abbreviated to T?
>
> String? name = process.args.first;
> if (exists name) {
>writeLine("Hello " name "!");
> }
> else {
>writeLine("Hello World!");
> }
>
> Use of an optional value must be guarded by the if (exists ... ) 
> construct. Therefore, NullPointerExceptions are impossible.
>
> This is exactly what I suggested for D in a enhancement request.
> It seems this kind of stuff is becoming a standard in new languages.
>

Yes, I'd *love* to see that in D, too.

>
> A method may declare multiple lists of parameters. The method body is 
> executed after arguments have been supplied to all parameter lists:
>
> Float add(Float x)(Float y) {
>return x+y;
> }
>
> This is a kind of user defined and safe partial application, it's a cute 
> idea.
>
> Providing arguments to just one parameter list produces a method 
> reference:
>
> Float addOne(Float y) = add(1.0);
> Float three = addOne(2.0);
>
> (The point of all this is that we are able to provide all the 
> functionality of first-class and higher-order functions without needing to 
> resort to unnatural syntactic constructs inspired by the lambda calculus 
> notation.)
>

That really stikes me as a completly wrong way to do currying. Granted, I've 
never really used currying, but it seems it would only be appropriate for 
*outside* code to choose which to specify and not specify. Having the callee 
decide that seems to completely defeat the whole point. Although I guess it 
could be sometimes be useful as a really ugly hack to work around the lack 
of overloading.





Re: Ceylon language

2011-04-13 Thread Kagamin
bearophile Wrote:

> > How will it work on this code?
> > 
> > String? name = process.args.first;
> > myLibCustomEnforce(exists name);
> > writeLine("Hello " name "!");
> 
> If you want to implement the feature well, then the compiler has to manage a 
> bit of type state too. The state of the type of the (here immutable) variable 
> "name" before myLibCustomEnforce() is different from the state of the type of 
> "name" after that call.
> 

Do you describe, how Ceylon can work hypotetically or how it actually works?


Re: Ceylon language

2011-04-13 Thread bearophile
Kagamin:

> How will it work on this code?
> 
> String? name = process.args.first;
> myLibCustomEnforce(exists name);
> writeLine("Hello " name "!");

If you want to implement the feature well, then the compiler has to manage a 
bit of type state too. The state of the type of the (here immutable) variable 
"name" before myLibCustomEnforce() is different from the state of the type of 
"name" after that call.


>> shared class Character(Natural utf16)
>> extends Object()
>> satisfies Ordinal & Comparable {
>> ...
>> }
>>
>> The syntax X&Y represents the intersection of two types. The syntax X|Y 
>> represents the union of two types.
>
> What does it mean?

Those Ordinal and Comparable seem interfaces, and each of them has a 
certain number of methods. If you use Ordinal | Comparable I persume 
the Character class must implement the methods of both interfaces (as in D), 
while with "&" you need to implement just the methods present in both 
interfaces. I don't have enough experience about this to tell how much useful 
this feature is. But it's not at the top of the things I look for.


> Haha, finally properly scoped switch statement, but it goes java too much. 
> Braces are required?

Ceylon is meant to be a very regular and safe language designed for not expert 
programmers too, so I presume they are required here.

Bye,
bearophile


Re: Ceylon language

2011-04-13 Thread Kagamin
bearophile Wrote:

> String? name = process.args.first;
> if (exists name) {
> writeLine("Hello " name "!");
> }
> else {
> writeLine("Hello World!");
> }
> 
> Use of an optional value must be guarded by the if (exists ... ) construct. 
> Therefore, NullPointerExceptions are impossible.
> 

How will it work on this code?

String? name = process.args.first;
myLibCustomEnforce(exists name);
writeLine("Hello " name "!");

> A class or interface satisfies zero or more interfaces
> 
> shared class Character(Natural utf16) 
> extends Object()
> satisfies Ordinal & Comparable {
> ...
> }
> 
> The syntax X&Y represents the intersection of two types. The syntax X|Y 
> represents the union of two types.
> 

What does it mean?

> Node node = ... ;
> switch (node)
> case (is Leaf) { 
> leaf(node.value); 
> }
> case (is Branch) { 
> branch(node.left, node.right); 
> }
> else {
> somethingElse(node);
> }

Haha, finally properly scoped switch statement, but it goes java too much. 
Braces are required?


Ceylon language

2011-04-13 Thread bearophile
The first description of the Ceylon language, designed for business computing 
(for large teams developing multi-user applications) and meant to replace Java, 
from Red Hat, that will run on the Java Virtual Machine itself:
http://blog.talawah.net/2011/04/gavin-king-unviels-red-hats-top-secret.html

About the language (very slow download):
http://www.qconbeijing.com/download/Gavin%20keynote.pdf
About the its type system:
http://www.qconbeijing.com/download/Gavin%20session.pdf


Some of the Java things they are frustrated by:
- non-typesafety of null values
- the dangerous synchronized keyword
- clumsy annotation syntax
- verbose constructor syntax
- all Java objects are semaphores?!
- SE SDK overuses stateful (mutable) objects


The following parts are from the PDF documents, plus few comments of mine.

-

Ceylon does not support method overloading (or any other kind of overloading).

-

If a value of type T can be null, it must be declared as type Optional, 
which may be abbreviated to T?  

String? name = process.args.first;
if (exists name) {
writeLine("Hello " name "!");
}
else {
writeLine("Hello World!");
}

Use of an optional value must be guarded by the if (exists ... ) construct. 
Therefore, NullPointerExceptions are impossible.

This is exactly what I suggested for D in a enhancement request.
It seems this kind of stuff is becoming a standard in new languages. 

-

Attributes and local variables are immutable by default. Assignable values must 
be annotated variable:

variable Natural count := 0;

-

A getter looks like a method without a parameter list:

shared Natural currentValue { 
return count; 
}
}


Attributes are polymorphic. A subclass may override a superclass attribute. It 
may even override a simple attribute with a getter or vice versa!

This means there is no need for explicit getter/setters until you are ready for 
them. This is nice.

-

There is no new keyword:

Counter c = Counter();

-


The local keyword may be used in place of a type for block-local declarations:

local c = Counter();

-

Assignment to a variable value or attribute setter is done using the := 
operator. The = specifier is used only for specifying immutable values:

shared assign currentValue {
count := currentValue;
}

-

We may define a class method "by reference":

void hello(String name) = hello;

-

A method may declare multiple lists of parameters. The method body is executed 
after arguments have been supplied to all parameter lists:

Float add(Float x)(Float y) {
return x+y;
}

This is a kind of user defined and safe partial application, it's a cute idea.

Providing arguments to just one parameter list produces a method reference:

Float addOne(Float y) = add(1.0);
Float three = addOne(2.0);

(The point of all this is that we are able to provide all the functionality of 
first-class and higher-order functions without needing to resort to unnatural 
syntactic constructs inspired by the lambda calculus notation.)

-

There is a Named argument syntax. They use it for a syntax trick: A named 
argument invocation is enclosed in braces, and non-vararg arguments are listed 
using the name=value; syntax.

This seems one of the most peculiar and refined parts of the syntax of this 
language. See slides 34-37 in the first PDF.

-

A class or interface satisfies zero or more interfaces

shared class Character(Natural utf16) 
extends Object()
satisfies Ordinal & Comparable {
...
}

The syntax X&Y represents the intersection of two types. The syntax X|Y 
represents the union of two types.

-

The "actual" annotation specifies that a member refines a supertype member:

shared class Character(Natural utf16) 
extends Object()
satisfies Ordinal & Comparable {

Natural nat = utf16;

shared actual Comparison compare(T that) {
return this.nat <=> that.nat;
}


The <=> operator is called "compare". It's just a shortcut for the method 
compare() of Comparable.

-

Type narrowing, "Switching" by type

Type narrowing is often frowned upon in object-oriented programming

Unfortunately, Java exacerbates the problem:
- the compiler does not inform us when addition of a new subtype breaks the 
list of cases


Node node = ... ;
switch (node)
case (is Leaf) { 
leaf(node.value); 
}
case (is Branch) { 
branch(node.left, node.right); 
}
else {
somethingElse(node);
}

The compiler forces the switch statement to contain an else clause to handle 
other subtypes.

-

Enumerated subtypes

A class or interface may specify an explicitly enumerated list of subtypes. The 
functional programming community calls this an algebraic datatype:

abstract class Node(String name)