tag:blogger.com,1999:blog-1445545651031573301.comments2022-04-27T00:11:58.467-07:00Ambassador to the ComputersJake Donhamhttp://www.blogger.com/profile/04768087689799941690noreply@blogger.comBlogger42125tag:blogger.com,1999:blog-1445545651031573301.post-11403063721563738772014-04-20T06:21:40.178-07:002014-04-20T06:21:40.178-07:00Hi Jake,
you might be interested in the Hopac lib...Hi Jake,<br /><br />you might be interested in the <a href="https://github.com/VesaKarvonen/Hopac" rel="nofollow">Hopac</a> library for F# that I recently open-sourced and that provides a very similar programming model, namely cooperative lightweight threads and CML style synchronous abstractions. In addition, it also runs those lightweight threads in parallel using a work distributing scheduler. I originally developed the library for a project I maintain at work, but decided to open-source the library as I thought it might interest others.<br />Anonymoushttps://www.blogger.com/profile/13094113896977200610noreply@blogger.comtag:blogger.com,1999:blog-1445545651031573301.post-54448292975642561192014-04-20T06:10:49.009-07:002014-04-20T06:10:49.009-07:00Could you elaborate on why you believe that CML an...Could you elaborate on why you believe that CML and synchronization primitives in general are "too much preemptive specific"?<br /><br />My experience is different. I have programmed with a few systems that provide cooperative threads and I've found it easy to use similar synchronization abstractions (ranging from atomic operations, mutexes and condition variables to CML style selective synchronous abstractions) with cooperative threads as with traditional threads. This is especially so when cooperative threads are combined with parallel execution and you can no longer assume that there is only one thread running.<br /><br />Combining lighweight cooperative threads (no preemption) and parallelism can be very effective for performance reasons as it can sometimes improve the asymptotic space complexity of parallel algorithms when compared to preemptive models.Anonymoushttps://www.blogger.com/profile/13094113896977200610noreply@blogger.comtag:blogger.com,1999:blog-1445545651031573301.post-68100249837863414382014-02-07T12:20:41.118-08:002014-02-07T12:20:41.118-08:00Hi Jake -- Thank you for writing this series of ar...Hi Jake -- Thank you for writing this series of articles. Far better than anything else out there!<br />TimTimothyhttps://www.blogger.com/profile/14810777981680842172noreply@blogger.comtag:blogger.com,1999:blog-1445545651031573301.post-9378725931194662832013-04-28T06:14:15.479-07:002013-04-28T06:14:15.479-07:00Interesting. Well done!
Interesting. Well done!<br />Christophe Meudechttps://www.blogger.com/profile/13388313598917388910noreply@blogger.comtag:blogger.com,1999:blog-1445545651031573301.post-55833952129357268052013-04-09T02:33:00.674-07:002013-04-09T02:33:00.674-07:00re building it -- fwiw i've recently packaged ...re building it -- fwiw i've recently packaged Froc up for opam, and it's now in the main repo. seemed to build just fine using ocaml 4.00.1 and 4.01.0dev+trunk, modulo the Makefile patches i had to include in the opam package. thought you might be interested...morthttps://www.blogger.com/profile/12200457619167911747noreply@blogger.comtag:blogger.com,1999:blog-1445545651031573301.post-37005057340560811702013-03-28T04:22:55.409-07:002013-03-28T04:22:55.409-07:00FROC is now available in OPAM via `opam install fr...FROC is now available in OPAM via `opam install froc`Anil Madhavapeddyhttps://www.blogger.com/profile/12639201598014663735noreply@blogger.comtag:blogger.com,1999:blog-1445545651031573301.post-10433035139500057752013-03-15T20:11:14.878-07:002013-03-15T20:11:14.878-07:00Cool, nice to see someone using it. Unfortunately ...Cool, nice to see someone using it. Unfortunately I don't do OCaml for work any more and I have no opportunity to use or improve froc at the moment, so it is dormant.<br /><br />I think froc is usable as it stands (although I have not tried building it with a recent OCaml), but there is certainly more that could be done with it. One direction I'd like to go is support for "traceable" data structures as in<br /><br /> http://www.umut-acar.org/publications/pldi2010.pdf<br /><br />or some other efficient way to handle small changes to large data structures.<br />Jake Donhamhttps://www.blogger.com/profile/04768087689799941690noreply@blogger.comtag:blogger.com,1999:blog-1445545651031573301.post-34875632709499796452013-03-15T06:55:21.942-07:002013-03-15T06:55:21.942-07:00Hello! Noting that Froc updates are 2 years old, i...Hello! Noting that Froc updates are 2 years old, is Froc dormant, or do you use it and it simply is a completed product without need of fixes or extensions? I've written about Froc and implemented a Flows module modeled after "Deprecating the Observer Pattern with Scala.React" paper, in lecture 10 at http://www.ii.uni.wroc.pl/~lukstafi/pmwiki/index.php?n=Functional.Functional#curlectureLukasz Stafiniakhttps://www.blogger.com/profile/13429327869433289392noreply@blogger.comtag:blogger.com,1999:blog-1445545651031573301.post-91926906903735359712013-02-04T17:06:41.165-08:002013-02-04T17:06:41.165-08:00Thanks for the comment, I'm glad you are enjoy...Thanks for the comment, I'm glad you are enjoying froc.<br /><br />1) You are right, thanks for the fix.<br /><br />2) Only successful values are propagated via bind, not exceptions. If you want to attach a notifier which receives exceptions you can use notify_result_b, which for an 'a behavior passes an 'a result (i.e. Value of 'a | Fail of exn) to the notification function. You could also use try_bind, catch, etc. to handle exceptions.<br /><br />2bis) For notifications set with notify_b_cancel you are returned a cancellation handle; call Froc.cancel on it to cancel the notification. Other kinds of attachment (bind, notify_b, etc.) are cancelled automatically when their enclosing scope is cleaned up.<br /><br />3) Timestamps are allocated in order as evaluation proceeds; calls to bind force an evaluation order. So in the second example, 100/x is bound to x within the bind of b, so its node has a later timestamp.<br /><br />4) One way to accomplish it is to fire a single event consisting of the tuple of values you want, then take the tuple apart in an event handler and pass the parts where you need them.Jake Donhamhttps://www.blogger.com/profile/04768087689799941690noreply@blogger.comtag:blogger.com,1999:blog-1445545651031573301.post-37276849168460181602013-02-04T09:45:47.495-08:002013-02-04T09:45:47.495-08:00Hello Jake,
Thanks for your excellent froc librar...Hello Jake,<br /><br />Thanks for your excellent froc library, i had given up learning frp until I came across your blog entry and library.<br /><br /><br />1) <br />In the example, the definition of y should be :<br />let y = bind2 b n0 (fun b _ -> if b then return 0 else n0) <br /><br />2)<br />I am baffled by the following code :<br /><br />let print_nl s = print_string s; print_newline()<br /><br />let u,send_u = make_cell 1<br />let v,send_v = make_cell 1 <br />let x = blift2 u v (fun u v -> u/v)<br />let y = blift2 u v (fun u v -> u*v) <br /><br />let x' = blift x (fun _ -> print_nl "x changed") <br />let y' = blift y (fun _ -> print_nl "y changed") <br /><br />Now in the toplevel :<br />send_v 2;;<br />x changed<br />y changed<br />- : unit = ()<br /><br />so far so good, but when I set v to 0 :<br /><br />send_v 0;;<br />y changed<br />- : unit = ()<br /><br /><br />Does froc "holds and hides" the Division_by_zero exception and only exposes it only when I do "Froc.sample x" ?<br />If so, why isn't the x' notifier never get triggered for that value, even when I do an explicit sample ?<br /><br /><br />2bis)<br />In the example above, is there any way to "unbind" the x' behavior so that any subsequent update of x wont trigger the print_nl "callback"<br />I guess the cleanup function is what I need, it would be great if you could provide me an example.<br /><br /><br /><br />3)<br />In the ddg section, you explain the timestamp update mechanism. Yet, if the "b" node had an initial timestamp value of 1 and "n0" a ts value of 0, this wouldnt work.<br /><br />Does Frog somehow (seems impossible to me since it would require statical code analysis) figures out that the "b node" determines the control flow and hence gets allocated a lesser timestamp than the n0 node ?<br />Or is it simply because we defined the b behavior before n0 ? (it dont think so because i switched the order and didnt observe a different result)<br />Or because the same phenomenon as in 2) occurs ?<br /><br /><br />4) <br />Is there any controlled way to fire n events simultaneously <br />(so that everything gets treated within the same update cycle ) ?<br /><br />let's consider the behavior u = f(v,w,x,y,z) above. I want to change<br />"atomically" (within the same update cycle) the 4 inputs without trigering 4 distinct update cycles.<br /><br /> <br />Thanks in advance and sorry for this long comment <br />Jeanhttps://www.blogger.com/profile/02392879304315949917noreply@blogger.comtag:blogger.com,1999:blog-1445545651031573301.post-79459443251839724612012-06-20T01:42:42.664-07:002012-06-20T01:42:42.664-07:00Hi Frank,
I use OCaML 3.12.1 on Fedora 17 i686 an...Hi Frank,<br /><br />I use OCaML 3.12.1 on Fedora 17 i686 and build with dynlink.cma as suggested by Shawnessy, and I get no error.<br /><br />Jake, could you attach the file variant.ml to make it easier for readers of this excellent introduction to camlp4 to build it?Anonymoushttps://www.blogger.com/profile/01727741166389456059noreply@blogger.comtag:blogger.com,1999:blog-1445545651031573301.post-58411528341923223272012-03-30T14:03:16.851-07:002012-03-30T14:03:16.851-07:00Hi Jake.
Thanks for posting this article. I co...Hi Jake. <br /><br />Thanks for posting this article. I could not find any other tutorial that provides the detail that you have. I currently get the following error when running the example.<br /><br />File "variant.ml", line 16, characters 4-158:<br />Error: This expression has type Camlp4.PreCast.Ast.ctyp<br /> but an expression was expected of type Camlp4.PreCast.Ast.str_item<br /><br /><br />I am currently using 3.12.1. Was something new introduced to break your example?Frank Whitehttps://www.blogger.com/profile/10953677334879976506noreply@blogger.comtag:blogger.com,1999:blog-1445545651031573301.post-42020169228415771792011-05-10T21:32:23.064-07:002011-05-10T21:32:23.064-07:00Wonderful series! Thanks for taking the time to w...Wonderful series! Thanks for taking the time to write (and code) about this generalized search & backtracking implementation.Alex Boisverthttps://www.blogger.com/profile/15673966086206028049noreply@blogger.comtag:blogger.com,1999:blog-1445545651031573301.post-26192854506512810232011-05-02T19:30:43.614-07:002011-05-02T19:30:43.614-07:00Thanks for the correction.
Here's more on ran...Thanks for the correction.<br /><br />Here's more on rank-2 polymorphism in Scala:<br /><br /> http://apocalisp.wordpress.com/2010/07/02/higher-rank-polymorphism-in-scala/<br /><br />It's not very deep, just finding a place to write the quantifier that you can't put into an ordinary function type.Jake Donhamhttps://www.blogger.com/profile/04768087689799941690noreply@blogger.comtag:blogger.com,1999:blog-1445545651031573301.post-19220036282616113782011-04-29T23:51:48.242-07:002011-04-29T23:51:48.242-07:00"For map things are simpler, since f(a) retur...<i>"For <b>map</b> things are simpler, since f(a) returns a single value rather than a choice of alternatives: we succeed immediately with the returned value."</i><br /><br />Do you mean <b>apply</b> here?<br /><br />The encoding of higher-ranked polymorphism as what looks like a Command pattern is interesting -- is there a reference that discusses the encoding process? Also, I'm going to have to read that Reynolds paper on defunctionalization.Forrest Norvellhttps://www.blogger.com/profile/04541481708123561220noreply@blogger.comtag:blogger.com,1999:blog-1445545651031573301.post-10150178002837384482011-04-24T20:15:42.649-07:002011-04-24T20:15:42.649-07:00Hey, nice, thanks for the tip! I will amend the po...Hey, nice, thanks for the tip! I will amend the post.Jake Donhamhttps://www.blogger.com/profile/04768087689799941690noreply@blogger.comtag:blogger.com,1999:blog-1445545651031573301.post-37499187791589623482011-04-24T12:20:59.473-07:002011-04-24T12:20:59.473-07:00Excellent post! This was a lot of fun.
The abstra...Excellent post! This was a lot of fun.<br /><br />The abstract type can indeed escape the module (as in OCaml), but in this example the abstract type is also a dependent type: it depends on Bridge's "Logic" value. For the abstract type to escape the module, the "logic" value can't be private. If you make Bridge's Logic public:<br /><br /> class Bridge(val Logic: Logic) { ... }<br /><br />then Bridge's methods can have return types of Logic.T[List[State]]Jorge Ortizhttps://www.blogger.com/profile/14454965475839432618noreply@blogger.comtag:blogger.com,1999:blog-1445545651031573301.post-76104244773203910082011-04-11T09:50:44.378-07:002011-04-11T09:50:44.378-07:00You are right, but at the top of the chain somebod...You are right, but at the top of the chain somebody (other than the implementation of Logic) needs to know the type, which should be hidden from everybody inside the implementation of Logic.Jake Donhamhttps://www.blogger.com/profile/04768087689799941690noreply@blogger.comtag:blogger.com,1999:blog-1445545651031573301.post-77170528137566853152011-04-11T09:44:43.942-07:002011-04-11T09:44:43.942-07:00A great post, thanks very much! The one thing I fo...A great post, thanks very much! The one thing I found confusing at the end was this comment: "with a type parameter, they can, but the type is no longer abstract."<br /><br />Don't the clients have the choice whether the type can remain abstract or not? It seems to me that a client could have the form:<br /><br />class Bridge[T[_]](l: Logic[T]) {...}<br /><br />and so up the chain of clients; the type only needs to be fixed at the last possible moment.Kris Nuttycombehttps://www.blogger.com/profile/06347383351250086727noreply@blogger.comtag:blogger.com,1999:blog-1445545651031573301.post-44772135600458884552011-03-16T14:59:06.046-07:002011-03-16T14:59:06.046-07:00Very nice post! It must have been quite a bit of w...Very nice post! It must have been quite a bit of work, Thank You. I'm still reading it. Nice that you bring up FRP.<br /><br />BTW I've been watching recently Channel9 lectures involving monads: http://channel9.msdn.com/Tags/ralf-laemmel and http://channel9.msdn.com/Tags/greg+meredith -- rather basic material but very entertaining.Lukasz Stafiniakhttps://www.blogger.com/profile/13429327869433289392noreply@blogger.comtag:blogger.com,1999:blog-1445545651031573301.post-5745798449577274412010-10-08T10:25:33.431-07:002010-10-08T10:25:33.431-07:00You beat me to it :). I just checked in a revised ...You beat me to it :). I just checked in a revised example without ocamlfind at<br /><br /> http://github.com/jaked/ambassadortothecomputers.blogspot.com/tree/master/_code/camlp4-filters/<br /><br />I changed to revised syntax quotations since the code above doesn't quite work in 3.12.x.<br /><br />The -I to ocamlc.opt is for the Camlp4 module reference in the code, but you can say -I +camlp4 instead. You can omit the various parser flags and call camlp4oof/camlp4orf instead of camlp4 (which have the appropriate modules loaded for original and revised syntax quotations, respectively). You can discover what a flag adds to the loaded modules with -loaded-modules, although for some reason camlp4oof/camlp4orf don't show the quotation modules.<br /><br />As to why you need all these parsers, it's just because the parser is built up incrementally: the original syntax parser extends the revised syntax parser, then quotations extend the base parser with a common quotation module and one specific to the flavor of quotations (original or revised).Jake Donhamhttps://www.blogger.com/profile/04768087689799941690noreply@blogger.comtag:blogger.com,1999:blog-1445545651031573301.post-68288152470048398392010-10-08T09:56:56.812-07:002010-10-08T09:56:56.812-07:00Yikes!
ocamlc.opt -c -I /loc/of/camlp4 -pp "...Yikes!<br /><br />ocamlc.opt -c -I /loc/of/camlp4 -pp "camlp4 -parser op -printer p -parser Camlp4QuotationCommon -parser Camlp4OCamlOriginalQuotationExpander" pt5.ml<br /><br />There are 3 parsers required to compile this. Is there a good reason it's this complex?<br /><br />Thanks!<br /><br />SeanShawnessyhttps://www.blogger.com/profile/16613856603034221042noreply@blogger.comtag:blogger.com,1999:blog-1445545651031573301.post-58744920135692302862010-10-07T16:22:39.603-07:002010-10-07T16:22:39.603-07:00Hi Jake,
I generally don't like to use auto...Hi Jake,<br /><br /> I generally don't like to use automated things like ocamlfind I don't understand. I can't figure out the regular ocamlc call to make though. I tried ocamlfind ocamlc -verbose and it gave me a horribly long command with a bunch of paths, etc. Can you write out the command I need to compile to_of_string.ml?<br /><br />Thanks!<br /><br />SeanShawnessyhttps://www.blogger.com/profile/16613856603034221042noreply@blogger.comtag:blogger.com,1999:blog-1445545651031573301.post-55017650599649037592010-10-01T07:24:32.503-07:002010-10-01T07:24:32.503-07:00Thanks, yes, that's since 3.11.x I think; dynl...Thanks, yes, that's since 3.11.x I think; dynlink.cma used to be packaged with camlp4lib.cma.Jake Donhamhttps://www.blogger.com/profile/04768087689799941690noreply@blogger.comtag:blogger.com,1999:blog-1445545651031573301.post-75710486282977838832010-10-01T07:17:06.996-07:002010-10-01T07:17:06.996-07:00Hi Jake,
I needed to change the build rule to
v...Hi Jake,<br /><br />I needed to change the build rule to <br /><br />variant: variant.ml<br /> ocamlc \<br /> -pp camlp4of -I +camlp4 \<br /> -o variant dynlink.cma camlp4lib.cma variant.ml<br /><br />The dynlink module must be new.Shawnessyhttps://www.blogger.com/profile/16613856603034221042noreply@blogger.com