April 05, 2008
On Sat, 05 Apr 2008 02:03:29 +0200, Bill Baxter <dnewsgroup@billbaxter.com> wrote:

> Simen Kjaeraas wrote:
>> On Sat, 05 Apr 2008 01:09:14 +0200, Jason House <jason.james.house@gmail.com> wrote:
>>
>>> bearophile wrote:
>>>> P. 31: >writeln(i);<
>>>>
>>>> Can you put (temporary) debugging writeln/putr inside a pure function?
>>>
>>> That's always bothered me about this stuff.  I don't want to lose
>>> debugging/logging ability!
>>   Just use multiple return types, and have the caller do the printing.
>>  --Simen
>
>
> Monads!
>
> Or at least I think that's what I read somewhere.  I can't understand the buggers for the life of me.  I think maybe it's just a fancy word for "loophole".  If someone here has a good explanation for what a monad is and how it allows mutable state in FP without making thing non-FP, I'd love to hear it.  Because I just don't get it.
>
> --bb

I read a bit on Wikipedia about monads, and they seem to me to be a fancy way to do multiple return values. I'm not sure if they're usable (hackable) in D at the moment, or if we need to wait for AST macros before we can use them as they should. But one example, the 'maybe' monad, seems to me a bit like this:

struct Maybe(T)
{
  bool Nothing;
  T data;

  static Maybe!(U) opCall(U)(lazy U u)
  {
    typeof(return) tmp;

    try
    {
      data = u();
      tmp.Nothing = false;
    }
    catch (object o)
    {
      tmp.Nothing = true; // something went wrong, data is invalid
    }
  }

  T opAdd(T rhs)
  {
    if (Nothing)
      return rhs; // act as if data is nonexistant
    else
      return data + rhs;
  }

  // other operators overloaded in similar ways
}


Disclaimer: This might or might not work. It might contain some value of truth, and it might not. It is merely my understanding after a half-hour of reading at 2:30 in the morning, and so should be sanity-checked before use.

-- Simen
April 05, 2008
bearophile wrote:
> Sean Kelly:
> 
>> It's unfortunate that he won't talk to any of us about this.

Yes. But the way he got treated here, who can blame him.

> Through that document he is talking to you. There are just less ways
> to push information the opposite direction :-)

What I really wish, is for him to write down the main points in the slide show, maybe along the lines I recently wrote here in "What is pure and what is not pure". Walter might post a copy of it here?

That would help a lot, especially since I can't say I really understood too much of the slide show.
April 05, 2008
Georg Wrede Wrote:

> bearophile wrote:
> > Sean Kelly:
> > 
> >> It's unfortunate that he won't talk to any of us about this.
> 
> Yes. But the way he got treated here, who can blame him.

Huh? What happened?



> 
> > Through that document he is talking to you. There are just less ways to push information the opposite direction :-)
> 
> What I really wish, is for him to write down the main points in the slide show, maybe along the lines I recently wrote here in "What is pure and what is not pure". Walter might post a copy of it here?
> 
> That would help a lot, especially since I can't say I really understood too much of the slide show.

April 05, 2008
"Bill Baxter" <dnewsgroup@billbaxter.com> wrote in message news:ft6fkf$1m9v$1@digitalmars.com...
> Simen Kjaeraas wrote:
>> On Sat, 05 Apr 2008 01:09:14 +0200, Jason House <jason.james.house@gmail.com> wrote:
>>
>>> bearophile wrote:
>>>> P. 31: >writeln(i);<
>>>>
>>>> Can you put (temporary) debugging writeln/putr inside a pure function?
>>>
>>> That's always bothered me about this stuff.  I don't want to lose debugging/logging ability!
>>
>>
>> Just use multiple return types, and have the caller do the printing.
>>
>> --Simen
>
>
> Monads!
>
> Or at least I think that's what I read somewhere.  I can't understand the buggers for the life of me.  I think maybe it's just a fancy word for "loophole".  If someone here has a good explanation for what a monad is and how it allows mutable state in FP without making thing non-FP, I'd love to hear it.  Because I just don't get it.
>
> --bb

I'm not one to be listened to, but I think the idea behind monads is to wrap an inherently impure action (like IO) in a functional shell.  In an imperative language, you do something like:

print("Enter your name: ")
name = readLine()
print("Hi, ", name)

Each of those function calls is impure, as they change the state of the computer.  A "pure" way of doing it is:

// we start with state defined at the beginning of the program
state = print(state, "Enter your name: ")
(state, name) = readLine(state)
state = print(state, "Hi, ", name)

(readLine returns two values.)

This creates an ordering of the execution of statements, which is one part of the "imperative" problem that monads solve (since functional code does not have any set ordering of execution).

I think a monad basically wraps up the ugliness of getting and passing the state into a nicer-looking syntax, i.e.

do
    putStr "Enter your name: "
    name <- readLine -- this isn't named this, I don't think..
    putStr "Hi, "
    putStrLn name

which, in Haskell, is really just syntactic sugar which hides all the horrible IO Monad manipulation.

But again, I'm not one to be listened to ;)


April 05, 2008
"Georg Wrede" <georg@nospam.org> wrote in message news:47F6D1A2.70300@nospam.org...
> bearophile wrote:
>> Sean Kelly:
>>
>>> It's unfortunate that he won't talk to any of us about this.
>
> Yes. But the way he got treated here, who can blame him.

He shouldn't ignore all of us just because of one hot head with a chip on his shoulder.

-Craig 

April 05, 2008
On Fri, 04 Apr 2008 14:46:26 -0700, Walter Bright wrote:

> Andrei Alexandrescu's talk just given at ACCU:
> 
> http://www.digitalmars.com/d/2.0/accu-functional.pdf

I'm going to get grilled for this post.

D is a great imperative language.
D is a terrible functional language.

This might sound harsh, but it's true. Functional languages need a lot of
special features to be what they are. They need to have statements that
work as expressions, unique data structures like chained lists, the
ability to heavily compress statements so as to prevent using temporary
values that us imperative programmers do enjoy so very much. Some
functional languages (in fact, arguably the 'cleanest' functional
languages like forth and joy) require the use of a special 'stack' to
manage data.
D does not have these features, and unless you want to completely change
what D is, D cannot have these features.

Now, I'm all for the non-breaking things that functional languages have
graced us: map, filter and range, tail recursion optimization, even
simple forms of 'pure' functions are nice as well.
But this whole const and pure thing is looking pretty ugly.
Imperative programmers use const/invariant datasets as a contract; a way
to set out guidelines for how their data should be used. Functional
languages take it a step further and force all data to be immutable,
making it a rule, not a guideline to use immutable data.
The meaning of const changes between these two paradigms, and I think
it's going to cause a lot of problems within D when they mix, especially
when functional languages keep all this immutable stuff conveniently
hidden away inside lists and stacks that the programmer doesn't have to
worry about.

I guess what I'm trying to say is functional languages are good at what
they do because they are functional languages. D is not a functional
language, and as such trying to use it as one is probably just going to
end up painful. If you want D to work like a functional language, turn it
into a functional language Walter. Force all data to be immutable by
default, all functions to be pure unless they prove otherwise, add native
support for lists and tuples and add a bunch of list manipulation
functions..
Heck, why not make a functional dialect of D? Call it "D flat" and have
it compile alongside D or something. No need to mix the two.

The current imperative/OO style of D is brilliant, fun to use, flexible and just packed with lovely features. Please don't go killing it on me by trying to make it an ugly jack of all trades.
April 05, 2008
Jason House Wrote:

> bearophile wrote:
> > P. 31: >writeln(i);<
> > 
> > Can you put (temporary) debugging writeln/putr inside a pure function?
> 
> That's always bothered me about this stuff.  I don't want to lose debugging/logging ability!

This seems like a non-issue to me. Even Haskell, one of the "purest of the pure", so to speak, has the unsafePerformIO "back door" to allow just these kind of idempotent side effects. I'm sure D will have the same. The trade-off, of course, is that once you decide to sneak in the back door, it's up to you to verify that your debug statements or whatever truly don't have any affect on the rest of the application, because at that point you've given up all compiler promises.

D would probably implement it as a simple "cast" on functions from non-pure to pure, much of the issues that arise in Haskell's back door don't apply to D because of lazy vs. eager evaluation, etc.
April 05, 2008
Jarrod wrote:
> On Fri, 04 Apr 2008 14:46:26 -0700, Walter Bright wrote:

> Heck, why not make a functional dialect of D? Call it "D flat" and have it compile alongside D or something. No need to mix the two.

Nooooo!  That's what I called my D library with Flexible Linear Algebra Types.

--bb
April 05, 2008
On Sat, 05 Apr 2008 14:52:47 +0900, Bill Baxter wrote:

> Jarrod wrote:
>> Heck, why not make a functional dialect of D? Call it "D flat" and have it compile alongside D or something. No need to mix the two.
> 
> Nooooo!  That's what I called my D library with Flexible Linear Algebra Types.
> 
> --bb

Aw, I liked D flat.
How about FunkyD?
DFunct?
D++?
April 05, 2008
On 05/04/2008, Jarrod <qwerty@ytre.wq> wrote:
>  Heck, why not make a functional dialect of D? Call it "D flat"

You do realise that D flat is the same thing as C sharp?*

I suppose there is some ironic humor in that.

J

----
*To be precise, in contemporary Western music, D flat is enharmonically equivalent to C sharp, but there are other tuning systems in which that is not so.