|
My knowledge of functional programming is pretty much limited to
Haskell, Scheme, and a smattering of Common Lisp. Are there languages other than Haskell that explicitly use monads? How about "not so explicitly"? === Gregory Woodhouse [hidden email] "The universe is not required to be in perfect harmony with human ambition." --Carl Sagan _______________________________________________ Haskell-Cafe mailing list [hidden email] http://www.haskell.org/mailman/listinfo/haskell-cafe |
|
tor 2005-11-24 klockan 12:36 -0800 skrev Gregory Woodhouse:
> My knowledge of functional programming is pretty much limited to > Haskell, Scheme, and a smattering of Common Lisp. Are there languages > other than Haskell that explicitly use monads? How about "not so > explicitly"? > > === > Gregory Woodhouse > [hidden email] Lambda the Ultimate recently had a post where people discussed monads in different languages, I haven't looked closely myself though so I can't provide a summary: http://lambda-the-ultimate.org/node/view/1128 Regards Anders Höckersten _______________________________________________ Haskell-Cafe mailing list [hidden email] http://www.haskell.org/mailman/listinfo/haskell-cafe |
|
Shae Matijs Erisson wrote:
> Gregory Woodhouse <[hidden email]> writes: >>My knowledge of functional programming is pretty much limited to Haskell, >>Scheme, and a smattering of Common Lisp. Are there languages other than >>Haskell that explicitly use monads? How about "not so explicitly"? > > > Java http://www.ccs.neu.edu/home/dherman/code/monads/JavaMonads.tar.gz > Joy http://permalink.gmane.org/gmane.comp.lang.concatenative/1506 > OCaml https://mailman.rice.edu/pipermail/metaocaml-users-l/2005-March/000057.html > Perl http://sleepingsquirrel.org/monads/monads.html > Prolog http://logic.csci.unt.edu/tarau/research/PapersHTML/monadic.html > Python http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/439361 > Ruby http://moonbase.rydia.net/mental/writings/programming/monads-in-ruby/00introduction.html > Scheme http://www.ccs.neu.edu/home/dherman/research/tutorials/monads-for-schemers.txt Yes, there are plenty. But none of them capture it quite as well as Haskell, IMHO, because the Haskell overloading makes it look particularly nice and succinct. And the second question about "not so explicitly", you could say that any language uses an implicit monad. It's where you throw in all the effects. -- Lennart _______________________________________________ Haskell-Cafe mailing list [hidden email] http://www.haskell.org/mailman/listinfo/haskell-cafe |
|
In reply to this post by Shae Matijs Erisson
Shae Matijs Erisson wrote:
> Please respond with any language implementations I've missed. C++ http://www.cc.gatech.edu/~yannis/fc++/New1.5/lambda.html#monad Jim _______________________________________________ Haskell-Cafe mailing list [hidden email] http://www.haskell.org/mailman/listinfo/haskell-cafe |
|
In reply to this post by Lennart Augustsson
Lennart Augustsson:
> Shae Matijs Erisson wrote: >> Gregory Woodhouse <[hidden email]> writes: >>> My knowledge of functional programming is pretty much limited to >>> Haskell, >>> Scheme, and a smattering of Common Lisp. Are there languages other than >>> Haskell that explicitly use monads? How about "not so explicitly"? >> >> >> Java http://www.ccs.neu.edu/home/dherman/code/monads/JavaMonads.tar.gz >> Joy http://permalink.gmane.org/gmane.comp.lang.concatenative/1506 >> OCaml Nobody mentioned the most obvious example - the language which is most similar to Haskell, but whose authors simply prefer a bit lowel-level mechanisms, although monads *can* be used as well - if you wish. Clean http://www.cs.ru.nl/~clean/ Such Haskell-implemented monads as list/nondeterminism or Maybe, go without any changements. State/IO use the unique types. Jerzy Karczmarczuk _______________________________________________ Haskell-Cafe mailing list [hidden email] http://www.haskell.org/mailman/listinfo/haskell-cafe |
|
In reply to this post by Shae Matijs Erisson
Shae Matijs Erisson wrote:
> Gregory Woodhouse <[hidden email]> writes: > >> My knowledge of functional programming is pretty much limited to Haskell, >> Scheme, and a smattering of Common Lisp. Are there languages other than >> Haskell that explicitly use monads? How about "not so explicitly"? > > Java http://www.ccs.neu.edu/home/dherman/code/monads/JavaMonads.tar.gz > Joy http://permalink.gmane.org/gmane.comp.lang.concatenative/1506 > OCaml https://mailman.rice.edu/pipermail/metaocaml-users-l/2005-March/000057.html > Perl http://sleepingsquirrel.org/monads/monads.html > Prolog http://logic.csci.unt.edu/tarau/research/PapersHTML/monadic.html > Python http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/439361 > Ruby http://moonbase.rydia.net/mental/writings/programming/monads-in-ruby/00introduction.html > Scheme http://www.ccs.neu.edu/home/dherman/research/tutorials/monads-for-schemers.txt > > Please respond with any language implementations I've missed. The Java implementation is actually a little baroque because it doesn't make use of generics. In June when there was a question here at Penn about how critical type-classes were to the use of Monads, I put together this quick example: interface Monad<A> { public <B> Monad<B> unit(B e); public <B,C> Monad<C> bind(Monad<B> e, MonadBindFun<B,C> f); } interface MonadBindFun<A,B> { public Monad<B> fun(A x); } class OptionMonad<A> implements Monad<A> { public <B> Monad<B> unit(B e) { return new Some<B>(e); } public <B,C> Monad<C> bind(Monad<B> e, MonadBindFun<B,C> f) { if(e instanceof Some) { Some<B> eb = (Some<B>)e; return f.fun(eb.get()); } else if (e instanceof None) { return new None<C>(); } else { throw new Error(); } } } public class None<A> extends OptionMonad<A> implements Monad<A> { public None() { } } public class Some<A> extends OptionMonad<A> implements Monad<A> { A x = null; public Some(A x) { this.x = x; } public A get() { return x; } } Just a few minutes ago I wrote, but haven't tested the following: import java.util.*; public class ListMonad<A> implements Monad<A> { List<A> list = null; private ListMonad(List<A> list) { this.list = list; } public <B> ListMonad<B> unit(B e) { List<B> nlist = new LinkedList<B>(); nlist.add(e); return new ListMonad(nlist); } public <B,C> Monad<C> bind(Monad<B> e, MonadBindFun<B,C> f) { if(e instanceof ListMonad) { ListMonad<B> be = (ListMonad<B>)e; List<List<C>> reslists = new LinkedList<List<C>>(); for(B x : be.list) { Monad<C> res = f.fun(x); if(res instanceof ListMonad) { ListMonad<C> ce = (ListMonad<C>)res; reslists.add(ce.list); } else { throw new Error(); } } List<C> flat = new LinkedList<C>(); for(List<C> x : reslists) { flat.addAll(x); } return new ListMonad(flat); } else { throw new Error(); } } } I also threw together a slightly cleaner version of these examples using Scala, but I'm sure the Scala folks could do better than me. _______________________________________________ Haskell-Cafe mailing list [hidden email] http://www.haskell.org/mailman/listinfo/haskell-cafe |
|
Am Samstag, 26. November 2005 03:56 schrieb Geoffrey Alan Washburn:
> [lots of code] It's interesting to note how verbose Java is in comparison to Haskell, at least, concerning this monad stuff. Best wishes, Wolfgang _______________________________________________ Haskell-Cafe mailing list [hidden email] http://www.haskell.org/mailman/listinfo/haskell-cafe |
|
Wolfgang Jeltsch wrote:
> Am Samstag, 26. November 2005 03:56 schrieb Geoffrey Alan Washburn: >> [lots of code] > > It's interesting to note how verbose Java is in comparison to Haskell, at > least, concerning this monad stuff. I'd agree. However, my original point was that my version that uses generics is still significantly less verbose than the version without. I think much of the overhead is that Java simply doesn't do as much type inference for you. Scala can do much better still because it has first-class functions and algebraic data types ("case classes"). _______________________________________________ Haskell-Cafe mailing list [hidden email] http://www.haskell.org/mailman/listinfo/haskell-cafe |
|
Geoffrey Alan Washburn <[hidden email]> writes:
> Scala can do much better still because it has first-class functions and > algebraic data types ("case classes"). Comments on http://lambda-the-ultimate.org/node/view/1136 include links to Scala http://scala.epfl.ch/examples/files/simpleInterpreter.html and XSLT rumors http://www.biglist.com/lists/xsl-list/archives/200303/msg00422.html There's also Oleg's http://okmij.org/ftp/Computation/monadic-shell.html "at the level of UNIX programming, all i/o can be regarded monadic." -- Shae Matijs Erisson - http://www.ScannedInAvian.com/ - Sockmonster once said: You could switch out the unicycles for badgers, and the game would be the same. _______________________________________________ Haskell-Cafe mailing list [hidden email] http://www.haskell.org/mailman/listinfo/haskell-cafe |
|
--- Shae Matijs Erisson <[hidden email]> wrote:
> Geoffrey Alan Washburn <[hidden email]> writes: > > There's also Oleg's > http://okmij.org/ftp/Computation/monadic-shell.html > "at the level of UNIX programming, all i/o can be regarded monadic." Interesting. I had been thinking about I/O and operating systems as a different(?) framework for trying to explain the concept of monads: If you think about a write statement in an imperative language, it doesn't actually perform the requested operation, it just asks the OS to perform the action "later". With respect to pipes, remember that files are really fictions, too, and when you write to a pipe the data is stored somewhere (most likely in memory) and then read in lazy fashion. Maybe this is a different topic, but exploring concurrency in Haskell is definitely on my "to do" list, but this is really a bit of a puzzle. One thing I've been thinking lately is that in functional programming the process is really the wrong abstraction (computation is reduction, not a sequence of steps performed in temporal order). But what is concurrency if their are no processes to "run" concurrently? I've beren thinking about action systems and non-determinism, but am unsure how the pieces really fit together. === Gregory Woodhouse <[hidden email]> "Interaction is the mind-body problem of computing." --Philip Wadler _______________________________________________ Haskell-Cafe mailing list [hidden email] http://www.haskell.org/mailman/listinfo/haskell-cafe |
|
Greg Woodhouse <[hidden email]> writes:
> Maybe this is a different topic, but exploring concurrency in Haskell is > definitely on my "to do" list, but this is really a bit of a puzzle. One > thing I've been thinking lately is that in functional programming the process > is really the wrong abstraction (computation is reduction, not a sequence of > steps performed in temporal order). But what is concurrency if their are no > processes to "run" concurrently? I've beren thinking about action systems and > non-determinism, but am unsure how the pieces really fit together. Maybe dataflow languages like Lucid Synchrone, Esterel and Lustre? http://en.wikipedia.org/wiki/Dataflow_language http://en.wikipedia.org/wiki/Synchronous_programming_language For dataflow in Haskell, see Uustalu & Vene's comonads paper: http://lambda-the-ultimate.org/node/view/988 I do wish I could find the source code from this paper online, I'd rather not type it in by hand. Do researchers usually manually transcribe code? -- Shae Matijs Erisson - http://www.ScannedInAvian.com/ - Sockmonster once said: You could switch out the unicycles for badgers, and the game would be the same. _______________________________________________ Haskell-Cafe mailing list [hidden email] http://www.haskell.org/mailman/listinfo/haskell-cafe |
|
In reply to this post by Gregory Woodhouse
> Maybe this is a different topic, but exploring concurrency in Haskell
> is definitely on my "to do" list, but this is really a bit of a puzzle. > One thing I've been thinking lately is that in functional programming > the process is really the wrong abstraction (computation is reduction, > not a sequence of steps performed in temporal order). But what is > concurrency if their are no processes to "run" concurrently? I've beren > thinking about action systems and non-determinism, but am unsure how > the pieces really fit together. Concurrency in Haskell is handled by forking the execution of IO actions, which are indeed sequences of steps to be performed in a temporal order. There are some elegant constructions in that direction, not least of which is STM, a system for transactional thread communication, on top of which one can implement channels and various other concurrency abstractions. STM allows one to insist that certain restricted kinds of actions relating to thread communication (in the STM monad) occur atomically with respect to other threads. These transactions can create, read and write to a special kind of mutable variable called a TVar (transactional variable). They can also ask to block the thread they are in and be retried later when one of the TVars they observed changes. There is additionally an operator `orElse` where if a and b are STM transactions, then (a `orElse` b) is a transaction where if a is executed and if it retries, then b is attempted, and if it retries, then the whole transaction retries. The first transaction not to retry gets to return its value. The operator `orElse` is associative, and has retry as an identity. The paper describing STM in more detail is here: http://research.microsoft.com/Users/simonpj/papers/stm/index.htm Perhaps more related to what you were thinking about, with Parallel Haskell, there's a mechanism for parallel computation to be used in a similar fashion to seq called par. The expression x `par` (y `seq`(x + y)), when evaluated, will first spark a parallel process for evaluating x (up to the top level data constructor), while in the main task, y `seq` (x + y) is computed, so the evaluation of y proceeds, and the task potentially blocks until x finishes being computed, and then the sum is returned. Sparking x will create the potential for x to be computed in another thread on a separate processor, if one becomes idle, but if that doesn't happen, x will simply be computed on the same processor as y when it is needed for the sum. Hope this is somewhat interesting and perhaps somewhat answers your question :) - Cale _______________________________________________ Haskell-Cafe mailing list [hidden email] http://www.haskell.org/mailman/listinfo/haskell-cafe |
|
In reply to this post by Shae Matijs Erisson
Shae Matijs Erisson wrote:
> I do wish I could find the source code from this paper online, I'd rather not > type it in by hand. Do researchers usually manually transcribe code? Both Evince and Acrobat Reader can copy text. Jim _______________________________________________ Haskell-Cafe mailing list [hidden email] http://www.haskell.org/mailman/listinfo/haskell-cafe |
|
In reply to this post by Shae Matijs Erisson
On Sat, 2005-11-26 at 18:43 +0100, Shae Matijs Erisson wrote:
> Greg Woodhouse <[hidden email]> writes: > > > Maybe this is a different topic, but exploring concurrency in Haskell is > > definitely on my "to do" list, but this is really a bit of a puzzle. One > > thing I've been thinking lately is that in functional programming the process > > is really the wrong abstraction (computation is reduction, not a sequence of > > steps performed in temporal order). But what is concurrency if their are no > > processes to "run" concurrently? I've beren thinking about action systems and > > non-determinism, but am unsure how the pieces really fit together. > > Maybe dataflow languages like Lucid Synchrone, Esterel and Lustre? > http://en.wikipedia.org/wiki/Dataflow_language > http://en.wikipedia.org/wiki/Synchronous_programming_language I also think dataflow is a very nice model for concurrency in pure functional languages. You might want to look at some of the work done by Edward Lee's group in the EE Dept. at Berkeley. They developed a generalization of dataflow called "token flow" which is quite nice. It became one of the basic models supported by their heterogeneous simulation systems, Ptolemy and Ptolemy II. I seem to recall that one student at a Texas university did a PhD thesis on dataflow for Haskell and then went to work on token flow in Lee's group. The one downside I found to using dataflow was that most software people seem to be uncomfortable with the lack of identifiable processes doing significant bits of work. I guess if they they're not floundering around in mutual exclusion, semaphores, deadlock detection and all the other manifestations of unmanaged complexity, they don't feel they've *accomplished* anything (BTW I grew up on Dijkstra, Hoare and Hanson, so I can get away with saying this :-). Interestingly enough, and perhaps obvious in retrospect, I often found hardware designers to be very comfortable with dataflow computations. Does anyone know whether much research has been done on using dataflow for concurrency in pure functional computation? How does it mesh with evaluation strategies? And, of course, the flip side: has anyone looked at re-examining real-world problems, conventionally handled with coordinating/communicating processes, as dataflow computations? The latter consideration may be the toughest to deal with. I was working on a project to handle PHY level communication algorithms with dataflow, and I had a great deal of difficulty with the comma-detect function of XAUI. I made some progress, but I never found a satisfactory solution. On the other hand, I did work out a fairly nice dataflow algorithm for CRC32. -- Bill Wood _______________________________________________ Haskell-Cafe mailing list [hidden email] http://www.haskell.org/mailman/listinfo/haskell-cafe |
|
In reply to this post by Gregory Woodhouse
Hello Greg,
Saturday, November 26, 2005, 8:25:38 PM, you wrote: GW> Maybe this is a different topic, but exploring concurrency in Haskell GW> is definitely on my "to do" list, but this is really a bit of a puzzle. GW> One thing I've been thinking lately is that in functional programming GW> the process is really the wrong abstraction (computation is reduction, GW> not a sequence of steps performed in temporal order). But what is GW> concurrency if their are no processes to "run" concurrently? I've beren GW> thinking about action systems and non-determinism, but am unsure how GW> the pieces really fit together. for pure functional computations concurrency is just one of IMPLEMENTATION mechanisms, and it doesn't appear in abstractions DEFINITIONS -- Best regards, Bulat mailto:[hidden email] _______________________________________________ Haskell-Cafe mailing list [hidden email] http://www.haskell.org/mailman/listinfo/haskell-cafe |
|
In reply to this post by Bill Wood-3
Hello Bill,
Sunday, November 27, 2005, 1:25:59 AM, you wrote: BW> The one downside I found to using dataflow was that most software people BW> seem to be uncomfortable with the lack of identifiable processes doing BW> significant bits of work. I guess if they they're not floundering BW> around in mutual exclusion, semaphores, deadlock detection and all the BW> other manifestations of unmanaged complexity, they don't feel they've BW> *accomplished* anything (BTW I grew up on Dijkstra, Hoare and Hanson, so BW> I can get away with saying this :-). Interestingly enough, and perhaps BW> obvious in retrospect, I often found hardware designers to be very BW> comfortable with dataflow computations. dataflow computers was known at least from 60's as possible alternative to Neumann architecture with its bottleneck of only one operation executed each time. they are very natural for chip designers because real internal processor structure is dataflow, and for external users (assembler programmers) Neumann architecture is emulated -- Best regards, Bulat mailto:[hidden email] _______________________________________________ Haskell-Cafe mailing list [hidden email] http://www.haskell.org/mailman/listinfo/haskell-cafe |
|
In reply to this post by Bulat Ziganshin
Bulat Ziganshin:
> for pure functional computations concurrency is just one of > IMPLEMENTATION mechanisms, and it doesn't appear in abstractions > DEFINITIONS Well, there are formal aspects of the specification of concurrency as well. Do you claim that no language has the right to demand *abstractly* that evaluating runtwo (proc1) (proc2) mean: launch the two concurrently and process further the first outcome? Jerzy Karczmarczuk _______________________________________________ Haskell-Cafe mailing list [hidden email] http://www.haskell.org/mailman/listinfo/haskell-cafe |
|
Hello jerzy,
Sunday, November 27, 2005, 3:49:07 PM, you wrote: >> for pure functional computations concurrency is just one of >> IMPLEMENTATION mechanisms, and it doesn't appear in abstractions >> DEFINITIONS jkiuf> Well, there are formal aspects of the specification of concurrency as well. jkiuf> Do you claim that no language has the right to demand *abstractly* that jkiuf> evaluating jkiuf> runtwo (proc1) (proc2) jkiuf> mean: launch the two concurrently and process further the first outcome? for SPECIFICATION of pure functional computation? ;) -- Best regards, Bulat mailto:[hidden email] _______________________________________________ Haskell-Cafe mailing list [hidden email] http://www.haskell.org/mailman/listinfo/haskell-cafe |
|
In reply to this post by Bulat Ziganshin
--- Bulat Ziganshin <[hidden email]> wrote:
> Hello Greg, > > for pure functional computations concurrency is just one of > IMPLEMENTATION mechanisms, and it doesn't appear in abstractions > DEFINITIONS > I suppose it depends a bit on the question you're asking. A multiprocessor, considered as a whole, might be a platform upon which you wish to implement a functional language. And in a certain sense, what you do with those processors is an implementation issue. But what I'm after is compositionality. I have in mind message based physically distributed systems, where individual components can be thought of as having well-defined semantics from which the semantics of the system as a whole can be defined. It's not at all clear (to me, anyway) how to do this. In a physically distributed system, it seems natural to think of the other processors, together with the bus(es) or network interfaces as providing part of the environment, and this leads naturally to the idea of using a theoretical tool like monads or continuations to model one of these "components" -- but that doesn't (obviously, at least) lead to compositional semantics becsuse of the obvious asymmetry. By way of background, a project I had been working on (untitl the project was cancelled) was something I dubbed an "interface compiler". I had developed a number of HL7 interfaces in a traditional imperative language (HL7, or Health Level 7, is an application protocol used in healthcare). These "interfaces" were virtually identical in most respects, so I set out to build a generic engine that would abstract away from the details of each interface. I was successful and easily re-implemented the interfaces I had already written using the new engine. But a little reflection lead me to conclude that this template driven approach was really higher order programming in disguise (another factor leading to my renewed interest in functional programming). Okay, that's fine as far as it goes, but it suffers from a severe limitation: the computational model is a single network node communicvating with its environment. There is no obvious way (in functional terms, at least) to go from the semantics of the subsystems running on each node to the semantics of the system as a whole. An idea that I've considered, but not really attempted to elaborate, is to generate code for the whole system *as a unit*. In retrospect, I see that this is essentially an attempt to move to the setting you describe, in which concurrency is simply a design issue. I have not yet read Misra's monograph (I hope I got that right -- I'm visiting family and away from my library), but I'm attracted to the idea that concurrency should not be a design issue and, by extension(?), that the process is not fundamental. (After all, is it not an artifact of the operating system?) This strikes a chord with me, because computation in functional languages is a matter of reduction, not sequential execution of statements (commands, really). I've been attracted to reactive systems because they, too, seem to provide a path to moving beyond the process abstraction, and because I've been working on TCP/IP based applications for years, and find it all quite fascinating. But, in a fundamental sense, reactive systems seem to represent a step in the *opposite* direction. After all, the appropriate program logic here seems to be temporal logic -- hardly natural from a functional perspective! I should apologize (no longer in advance) for the "stream of consciousness" nature of this post. Think of it as an attempt to pull together a few seemingly (or maybe not so seemingly) unrelated threads from my earlier posts. === Gregory Woodhouse <[hidden email]> "Interaction is the mind-body problem of computing." --Philip Wadler _______________________________________________ Haskell-Cafe mailing list [hidden email] http://www.haskell.org/mailman/listinfo/haskell-cafe |
| Powered by Nabble | Edit this page |
