Functional programming in D and some reflexion on the () optionality.
Mafi
mafi at example.org
Mon Aug 6 11:01:23 PDT 2012
On Monday, 6 August 2012 at 16:40:02 UTC, deadalnix wrote:
> It is known that some part of D are very dmd's implementation
> defined. One of the part is manipulation function as first
> class objects and implicitly calling them.
...
>
> To me, the first big failure of D to implement functional style
> is to not have first class functions. You get a function using
> & operator. But does it really make sense ? See code below :
>
> void foo(){}
> void bar(void function() buzz) {}
>
> void main() { bar(foo); } // This will execute foo, and so
> fail. Functions are not first class objects.
>
> void main() {
> auto bar = &foo;
> foo(); // Do something.
> bar(); // Do the same thing.
> auto buzz = &bar;
> (*buzz)(); // Do the same thing.
> }
This comes from the 'real' function type is 'void f()' whose
usage is deprecated in D except for any
function-/method-declaration:
Imagine a C-style declaration of the fuction type and you'll come
to the conclusion it's the way one defines functions in C/C++/D.
But this type has a big quirk: it's variable length because
different fuctions with the same signature can have a different
amount of machine instuctions. Therefore this can't be stored,
passed or returned. You can't have array of them. The only
exception is when you define a constant, then it's a funciton
definition. Now because of this there is a need for another type
equivalent to the function itself: its address. It's written
'void (*f)()' in C. This type is mostly reffered to as function
even though it's only its address. Now D wants to go away from C
declarations so the 'void function()' syntax was invented.
Regardless of its name it's only the pointer to the actual
functions even though D allows you to call it without
dereferencing.
>
> Functions don't behave the same way is they are variables or
> declared in the source code.
This is because the former a function pointer and the latter are
actual funtions.
> Worse, foo was before a function call. Now it isn't anymore.
> foo, as a expression have a different meaning depending on what
> is done on it. It would become very confusing if foo return a
> reference, so it is an lvalue and & is a valid operation on the
> function call.
Because any usage of a function except a call or address-taking
are complete non-sense, the functions is implicitly called if it
hasn't got any parameters.
> As D don't enforce purity like functional programing does, it
> can't be up to the compiler to decide when does the function
> get executed.
>
> Then come UFCS. UFCS allow for function calls with parameters.
> It is still inconsistent.
>
> void foo(T)(T t) {}
>
> a.foo; // foo is called with a as argument.
> &a.foo; // error : not an lvalue
Even though it's written like that, the function is not called
with the member calling convention. You can't create a
transperent delegate of it because the function does not expect
to get 'a' as a 'this'-parameter.
> Now let imagine that foo is a member function of a, &a.foo
> become a delegate. a.foo is still a function call. This is
> still quite inconsistent.
Maybe it is. But it comes from the fact that ufcs is an
afterthought.
> Implementing all this is almost impossible when you add
> @property into the already messy situation. Additionally, the
> current implement fails to provide the basics of functional
> programing, and break several abstraction provided by other
> languages features. C++ has proven that bad association of good
> language features lead to serious problems.
>
> This require to be formalized in some way and not based on
> dmd's implementation. Inevitably, the process will lead to code
> breakage (adding or removing some ()/&).
>
> Reading the @property thread, it seems that most people want to
> keep dmd's current behavior. Because code rely on it. This make
> sense, but if dmd's implement is the only goal, it means that
> other compiler are only to be reverse engineering dmd's
> behavior, and are guaranteed to lag behind. Considering this, I
> seriously wonder if it make sense to even try to follow dmd's
> behavior and decide whatever seems the right one when writing a
> D compiler, which will result in community split, or no
> alternative compiler produced for D.
I don't like authorative formal specs. It means most things are
set in stone and you have to write a new spec every once in a
while which slows down development of awesome language features.
> I also have some proposal to fix thing, even some that would
> allow a.map!(...).array() to still be available. But
> inevitably, some other construct will broke. At this point,
> what matter isn't really what solution is adopted, but do we
> still want to be dependent on dmd implementation for D features.
Mafi
More information about the Digitalmars-d
mailing list