<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
		>
<channel>
	<title>Comments on: Erlang warts</title>
	<atom:link href="http://rcoder.net/content/erlang-warts/feed" rel="self" type="application/rss+xml" />
	<link>http://rcoder.net/content/erlang-warts</link>
	<description>Code, food, pinball, beer, and bikes. It&#039;s hard living in a place this awesome.</description>
	<lastBuildDate>Sat, 23 Jan 2010 11:37:40 -0800</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
		<item>
		<title>By: crooney</title>
		<link>http://rcoder.net/content/erlang-warts/comment-page-1#comment-433</link>
		<dc:creator>crooney</dc:creator>
		<pubDate>Wed, 06 May 2009 08:16:14 +0000</pubDate>
		<guid isPermaLink="false">http://rcoder.net/?p=234#comment-433</guid>
		<description>Standalone functions in the REPL can be done in the following way:

12&gt; F = fun (A,B) -&gt; A&gt;B end.
#Fun
13&gt; F(2,1).
true
14&gt; 

If you&#039;re using emacs there are functions to throw all the boilerplate for many different types of files, including author/date stuff, and automatically naming the module after the file.  If you&#039;re not using emacs, you probably won&#039;t like erlang very much in the short or long term.

Agreed, making the arity part of the func name is terrible. (Insofar as the programmer needs to constantly type it. I don&#039;t know enough to know if I&#039;d be opposed to c++-style name rewriting.)

I&#039;ve only been fooling a couple days, but I like the atom tagged tuple and pattern matching idion so far.

Jeez, just noticed how old this post is, but I&#039;ve already typed it, so I&#039;m aposting int.

Chau</description>
		<content:encoded><![CDATA[<p>Standalone functions in the REPL can be done in the following way:</p>
<p>12&gt; F = fun (A,B) -&gt; A&gt;B end.<br />
#Fun<br />
13&gt; F(2,1).<br />
true<br />
14&gt; </p>
<p>If you&#8217;re using emacs there are functions to throw all the boilerplate for many different types of files, including author/date stuff, and automatically naming the module after the file.  If you&#8217;re not using emacs, you probably won&#8217;t like erlang very much in the short or long term.</p>
<p>Agreed, making the arity part of the func name is terrible. (Insofar as the programmer needs to constantly type it. I don&#8217;t know enough to know if I&#8217;d be opposed to c++-style name rewriting.)</p>
<p>I&#8217;ve only been fooling a couple days, but I like the atom tagged tuple and pattern matching idion so far.</p>
<p>Jeez, just noticed how old this post is, but I&#8217;ve already typed it, so I&#8217;m aposting int.</p>
<p>Chau</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Anders Conbere</title>
		<link>http://rcoder.net/content/erlang-warts/comment-page-1#comment-223</link>
		<dc:creator>Anders Conbere</dc:creator>
		<pubDate>Tue, 09 Sep 2008 23:23:21 +0000</pubDate>
		<guid isPermaLink="false">http://rcoder.net/?p=234#comment-223</guid>
		<description>@Lennon - I think you&#039;ll find that in most production erlang code spawn are receive are very often abstracted away from the implementation. I the case of Ejabberd they make great use of the OTP framework. Try looking for gen_server of gen_fsm in their code base.</description>
		<content:encoded><![CDATA[<p>@Lennon &#8211; I think you&#8217;ll find that in most production erlang code spawn are receive are very often abstracted away from the implementation. I the case of Ejabberd they make great use of the OTP framework. Try looking for gen_server of gen_fsm in their code base.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: lennon</title>
		<link>http://rcoder.net/content/erlang-warts/comment-page-1#comment-221</link>
		<dc:creator>lennon</dc:creator>
		<pubDate>Sat, 06 Sep 2008 19:01:53 +0000</pubDate>
		<guid isPermaLink="false">http://rcoder.net/?p=234#comment-221</guid>
		<description>@Robert: fault handling is a part of the language I haven&#039;t really had a chance to explore yet, and one of the things that I still hold out some hope will really &quot;click&quot; and make me stick around.

If I think of Erlang more as a virtualized operating system, rather than a simple programming language, it starts to make more sense. The limitations placed on the language are no more severe than those imposed on kernel-space C code, for example, and the concurrency and error-handling tools are far more sophisticated.

@Jeremy: I&#039;m not sure I follow the transition from &quot;embarassingly parallelizable&quot; into heterogenous; parallel tasks can be highly diverse in terms of the units of work done within each process. I&#039;m also not convinced that ejabberd is a great example of a system that uses the language to its full advantage -- I count all of 22 uses of &#039;spawn&#039; in the sources, and only nine calls to &#039;receive&#039;. 

Regardless, my problem is not that the syntax is difficult -- I find C++ to be much more &quot;noisy&quot; and difficult to scan. The language simply provides such an impoverished set of abstraction mechanisms that I find myself reading the same code over and over again. Dynamic typing without polymorphism leads to a lot of manual type-checking and case-switch pattern matching.</description>
		<content:encoded><![CDATA[<p>@Robert: fault handling is a part of the language I haven&#8217;t really had a chance to explore yet, and one of the things that I still hold out some hope will really &#8220;click&#8221; and make me stick around.</p>
<p>If I think of Erlang more as a virtualized operating system, rather than a simple programming language, it starts to make more sense. The limitations placed on the language are no more severe than those imposed on kernel-space C code, for example, and the concurrency and error-handling tools are far more sophisticated.</p>
<p>@Jeremy: I&#8217;m not sure I follow the transition from &#8220;embarassingly parallelizable&#8221; into heterogenous; parallel tasks can be highly diverse in terms of the units of work done within each process. I&#8217;m also not convinced that ejabberd is a great example of a system that uses the language to its full advantage &#8212; I count all of 22 uses of &#8217;spawn&#8217; in the sources, and only nine calls to &#8216;receive&#8217;. </p>
<p>Regardless, my problem is not that the syntax is difficult &#8212; I find C++ to be much more &#8220;noisy&#8221; and difficult to scan. The language simply provides such an impoverished set of abstraction mechanisms that I find myself reading the same code over and over again. Dynamic typing without polymorphism leads to a lot of manual type-checking and case-switch pattern matching.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Jeremy Bowers</title>
		<link>http://rcoder.net/content/erlang-warts/comment-page-1#comment-220</link>
		<dc:creator>Jeremy Bowers</dc:creator>
		<pubDate>Sat, 06 Sep 2008 15:11:44 +0000</pubDate>
		<guid isPermaLink="false">http://rcoder.net/?p=234#comment-220</guid>
		<description>And I&#039;m not following the claim that Erlang only helps with embarrassingly parallel problems. ejabberd is not embarrassingly parallel, it&#039;s the exact opposite, it&#039;s fantastically heterogeneous. It might look homogeneous if you look at it from a distance (oh, yeah, route message, route message, route message, how hard is that?) but that would be true of any task. Get up close and into the program and it actually does all kinds of things that interact with other bits of state in every basic multithreading way you can imagine.

Erlang actually shines on these highly heterogeneous tasks; it&#039;s the embarrassingly parallel tasks that are easy in any language where it&#039;s not worth your time to learn Erlang.

It&#039;s worth reading ejabberd&#039;s source if you&#039;re getting into Erlang, because it&#039;s amazing what it accomplishes with such directness and simplicity. You can get so caught up in the code that you never actually notice how there&#039;s no synchronization code. It&#039;s hard for any other language to match that.

(Which makes it a pity that the syntax is so difficult.)</description>
		<content:encoded><![CDATA[<p>And I&#8217;m not following the claim that Erlang only helps with embarrassingly parallel problems. ejabberd is not embarrassingly parallel, it&#8217;s the exact opposite, it&#8217;s fantastically heterogeneous. It might look homogeneous if you look at it from a distance (oh, yeah, route message, route message, route message, how hard is that?) but that would be true of any task. Get up close and into the program and it actually does all kinds of things that interact with other bits of state in every basic multithreading way you can imagine.</p>
<p>Erlang actually shines on these highly heterogeneous tasks; it&#8217;s the embarrassingly parallel tasks that are easy in any language where it&#8217;s not worth your time to learn Erlang.</p>
<p>It&#8217;s worth reading ejabberd&#8217;s source if you&#8217;re getting into Erlang, because it&#8217;s amazing what it accomplishes with such directness and simplicity. You can get so caught up in the code that you never actually notice how there&#8217;s no synchronization code. It&#8217;s hard for any other language to match that.</p>
<p>(Which makes it a pity that the syntax is so difficult.)</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Robert Virding</title>
		<link>http://rcoder.net/content/erlang-warts/comment-page-1#comment-219</link>
		<dc:creator>Robert Virding</dc:creator>
		<pubDate>Sat, 06 Sep 2008 13:35:50 +0000</pubDate>
		<guid isPermaLink="false">http://rcoder.net/?p=234#comment-219</guid>
		<description>I just want to second what Ulf wrote about implementing actor-based concurrency primitives. It easy to implement a simple package for most language, we did a few before Erlang as experiments, but to make a *good*, well-integrated package is extremely difficult. Erlang&#039;s concurrency primitives are not something which has been stuck on later but are an integral part of the language.

Another point not mentioned so far is error-handling. To build a fault-tolerant system you need to be able to detect and handle errors is a controlled way. This is *not* the same as sticking checks for error returns everywhere and handling them locally which very quickly makes the code illegible and fault-prone. Erlang&#039;s error handling mechanisms are an integral part of the language.

It is this integration between concurrency, error handling and the rest of the language which provides Erlang with much of its power. It is also this integration which is difficult to do.

The compilation unit of code in Erlang is the module. All functions are part of a module. It is also modules which are the base of code handling. It is therefore not surprising that you cannot define functions in the shell, which module would they be a part of? It is possible to define funs in the shell but they can&#039;t be saved.</description>
		<content:encoded><![CDATA[<p>I just want to second what Ulf wrote about implementing actor-based concurrency primitives. It easy to implement a simple package for most language, we did a few before Erlang as experiments, but to make a *good*, well-integrated package is extremely difficult. Erlang&#8217;s concurrency primitives are not something which has been stuck on later but are an integral part of the language.</p>
<p>Another point not mentioned so far is error-handling. To build a fault-tolerant system you need to be able to detect and handle errors is a controlled way. This is *not* the same as sticking checks for error returns everywhere and handling them locally which very quickly makes the code illegible and fault-prone. Erlang&#8217;s error handling mechanisms are an integral part of the language.</p>
<p>It is this integration between concurrency, error handling and the rest of the language which provides Erlang with much of its power. It is also this integration which is difficult to do.</p>
<p>The compilation unit of code in Erlang is the module. All functions are part of a module. It is also modules which are the base of code handling. It is therefore not surprising that you cannot define functions in the shell, which module would they be a part of? It is possible to define funs in the shell but they can&#8217;t be saved.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Ulf Wiger</title>
		<link>http://rcoder.net/content/erlang-warts/comment-page-1#comment-218</link>
		<dc:creator>Ulf Wiger</dc:creator>
		<pubDate>Fri, 05 Sep 2008 08:29:44 +0000</pubDate>
		<guid isPermaLink="false">http://rcoder.net/?p=234#comment-218</guid>
		<description>Uhm, I don&#039;t follow how Erlang would only help with problems that don&#039;t require preemption. Erlang scheduling is preemptive - conceptually so with only one CPU (the current scheduler uses highly predictable reduction counting, but relying on this has always been strongly discouraged), but in the SMP version you have multiple scheduler threads which are preemptively scheduled. Then you have true preemption, with the exception of thread-safety guarantees given by the runtime system and core libraries.</description>
		<content:encoded><![CDATA[<p>Uhm, I don&#8217;t follow how Erlang would only help with problems that don&#8217;t require preemption. Erlang scheduling is preemptive &#8211; conceptually so with only one CPU (the current scheduler uses highly predictable reduction counting, but relying on this has always been strongly discouraged), but in the SMP version you have multiple scheduler threads which are preemptively scheduled. Then you have true preemption, with the exception of thread-safety guarantees given by the runtime system and core libraries.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Ulf Wiger</title>
		<link>http://rcoder.net/content/erlang-warts/comment-page-1#comment-217</link>
		<dc:creator>Ulf Wiger</dc:creator>
		<pubDate>Fri, 05 Sep 2008 08:21:20 +0000</pubDate>
		<guid isPermaLink="false">http://rcoder.net/?p=234#comment-217</guid>
		<description>@lennon:

You certainly have a point. It could be that many of us who have made our living building complex and massively concurrent applications for so long, forget that there is a vast array of problem domains where concurrency is mainly seen to have marginal influence at best.

What I would like to suggest then, is that you explore the idea of Concurrency Oriented Programming as a modeling paradigm in its own right, which offers a powerful alternative to OO. One example of this is the error handling principles in Erlang, where the concurrency features are mainly used for supervision and isolation. YMMV, but so it does with OO and FP in general.

As for your claims about Erlang being weak in exploratory programming, I&#039;d have to take a deeper dive into the alternatives in order to find out whether or not I agree. It could be as with Erlang&#039;s error messages - lovely if you come from C++, appalling if you come from Python. ;-)  (Although there is good reason not to waste time pretty-printing error messages in an unattended real-time system, there are also some bits of information missing.)

I certainly agree that there is nothing magical about Erlang. It was a language project driven in an industrial environment, which is unusual, but by no means unique. There is lots of good engineering in there, and tons of domain knowledge. Some of that domain knowledge works in other domains as well - some of it doesn&#039;t.</description>
		<content:encoded><![CDATA[<p>@lennon:</p>
<p>You certainly have a point. It could be that many of us who have made our living building complex and massively concurrent applications for so long, forget that there is a vast array of problem domains where concurrency is mainly seen to have marginal influence at best.</p>
<p>What I would like to suggest then, is that you explore the idea of Concurrency Oriented Programming as a modeling paradigm in its own right, which offers a powerful alternative to OO. One example of this is the error handling principles in Erlang, where the concurrency features are mainly used for supervision and isolation. YMMV, but so it does with OO and FP in general.</p>
<p>As for your claims about Erlang being weak in exploratory programming, I&#8217;d have to take a deeper dive into the alternatives in order to find out whether or not I agree. It could be as with Erlang&#8217;s error messages &#8211; lovely if you come from C++, appalling if you come from Python. <img src='http://rcoder.net/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' />   (Although there is good reason not to waste time pretty-printing error messages in an unattended real-time system, there are also some bits of information missing.)</p>
<p>I certainly agree that there is nothing magical about Erlang. It was a language project driven in an industrial environment, which is unusual, but by no means unique. There is lots of good engineering in there, and tons of domain knowledge. Some of that domain knowledge works in other domains as well &#8211; some of it doesn&#8217;t.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: lennon</title>
		<link>http://rcoder.net/content/erlang-warts/comment-page-1#comment-216</link>
		<dc:creator>lennon</dc:creator>
		<pubDate>Thu, 04 Sep 2008 23:07:39 +0000</pubDate>
		<guid isPermaLink="false">http://rcoder.net/?p=234#comment-216</guid>
		<description>@Ulf:

My point is not that there isn&#039;t value to the Erlang approach (there is!) or that there&#039;s a single language runtime out there with all its desirable features (though others have nice features of their own, like the ability to directly call C functions, or use traditional side-effects). There isn&#039;t anything magical about Erlang&#039;s approach, though -- it&#039;s a natural design given the strict limitations on the language itself.

By disallowing use of traditional threading primitives, Erlang programs are protected from many of the deadlock and resource-contention issues that make multiprocessing programs so notoriously difficult to implement properly. However, the model also only helps with those problems that a) are embarrassingly paralellizable, and b) can be implemented efficiently using cooperative multitasking (i.e., don&#039;t require preemption).

Erlang has its place in that niche, but its limited exploratory programming support and lack of polymorphism probably means it won&#039;t be the first tool I reach for when I&#039;m looking to start work on a new project, unless I know from the beginning that massive concurrency is going to be a core component of the application&#039;s requirements.</description>
		<content:encoded><![CDATA[<p>@Ulf:</p>
<p>My point is not that there isn&#8217;t value to the Erlang approach (there is!) or that there&#8217;s a single language runtime out there with all its desirable features (though others have nice features of their own, like the ability to directly call C functions, or use traditional side-effects). There isn&#8217;t anything magical about Erlang&#8217;s approach, though &#8212; it&#8217;s a natural design given the strict limitations on the language itself.</p>
<p>By disallowing use of traditional threading primitives, Erlang programs are protected from many of the deadlock and resource-contention issues that make multiprocessing programs so notoriously difficult to implement properly. However, the model also only helps with those problems that a) are embarrassingly paralellizable, and b) can be implemented efficiently using cooperative multitasking (i.e., don&#8217;t require preemption).</p>
<p>Erlang has its place in that niche, but its limited exploratory programming support and lack of polymorphism probably means it won&#8217;t be the first tool I reach for when I&#8217;m looking to start work on a new project, unless I know from the beginning that massive concurrency is going to be a core component of the application&#8217;s requirements.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Ulf Wiger</title>
		<link>http://rcoder.net/content/erlang-warts/comment-page-1#comment-215</link>
		<dc:creator>Ulf Wiger</dc:creator>
		<pubDate>Thu, 04 Sep 2008 21:27:08 +0000</pubDate>
		<guid isPermaLink="false">http://rcoder.net/?p=234#comment-215</guid>
		<description>&gt; The #1 most interesting feature, Actor-based concurrency,
&gt; can be trivially implemented in any language with lightweight
&gt; object serialization and robust TCP/IP support,

...and yet (or exactly because people think this), project after
project run into a brick wall of poorly implemented concurrency
support. If I had $100 for every time someone has said &quot;how hard
can it be?&quot; only to be proven wrong when reality hits, I wouldn&#039;t
have to work anymore. ;-)

(Although I&#039;ve come to believe that many don&#039;t even understand 
then that it&#039;s the poor concurrency support that causes their 
problems, because they haven&#039;t learned to recognize the symptoms,
or don&#039;t even know there&#039;s a better way to do it.)

There are very few implementations of &quot;erlang-style concurrency&quot; that can really compare to the &quot;real thing&quot;. And most of those are hampered by coexisting legacy concurrency models (Scala), zero user base and zero support (Termite) or a staggering learning curve (Mozart). Glasgow Distributed Haskell is an interesting entry, but also lacks user base and commercial appeal, and is less flexible than Erlang in some ways. For now, I&#039;d view it as an alternative for elite programmers only, though.

Messing up concurrency can be a project killer - one of the best there is. At least with Erlang, you get a consistent and fairly safe approach and an active user community where lots of people &quot;get&quot; concurrency and are willing to share their knowledge. For those who have this need and have found a home there, a few warts here and there is nothing. Why, most other langs out there aren&#039;t even starters by comparison. ;-)

&gt; and robust multiprocessing can be accomplished via a
&gt; number of methods.

And yet people keep calling wondering about the rumours of painless multiprocessing, when they&#039;re stuck with a Java or C++ program that doesn&#039;t scale, and the best advice they can get from the experts is basically to rewrite large parts of their app.

Yeah, you can do this in other languages, but in my experience, practically noone ever does in real products. Your experience may differ from mine. I&#039;d love to hear about counter-examples.</description>
		<content:encoded><![CDATA[<p>&gt; The #1 most interesting feature, Actor-based concurrency,<br />
&gt; can be trivially implemented in any language with lightweight<br />
&gt; object serialization and robust TCP/IP support,</p>
<p>&#8230;and yet (or exactly because people think this), project after<br />
project run into a brick wall of poorly implemented concurrency<br />
support. If I had $100 for every time someone has said &#8220;how hard<br />
can it be?&#8221; only to be proven wrong when reality hits, I wouldn&#8217;t<br />
have to work anymore. <img src='http://rcoder.net/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>
<p>(Although I&#8217;ve come to believe that many don&#8217;t even understand<br />
then that it&#8217;s the poor concurrency support that causes their<br />
problems, because they haven&#8217;t learned to recognize the symptoms,<br />
or don&#8217;t even know there&#8217;s a better way to do it.)</p>
<p>There are very few implementations of &#8220;erlang-style concurrency&#8221; that can really compare to the &#8220;real thing&#8221;. And most of those are hampered by coexisting legacy concurrency models (Scala), zero user base and zero support (Termite) or a staggering learning curve (Mozart). Glasgow Distributed Haskell is an interesting entry, but also lacks user base and commercial appeal, and is less flexible than Erlang in some ways. For now, I&#8217;d view it as an alternative for elite programmers only, though.</p>
<p>Messing up concurrency can be a project killer &#8211; one of the best there is. At least with Erlang, you get a consistent and fairly safe approach and an active user community where lots of people &#8220;get&#8221; concurrency and are willing to share their knowledge. For those who have this need and have found a home there, a few warts here and there is nothing. Why, most other langs out there aren&#8217;t even starters by comparison. <img src='http://rcoder.net/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>
<p>&gt; and robust multiprocessing can be accomplished via a<br />
&gt; number of methods.</p>
<p>And yet people keep calling wondering about the rumours of painless multiprocessing, when they&#8217;re stuck with a Java or C++ program that doesn&#8217;t scale, and the best advice they can get from the experts is basically to rewrite large parts of their app.</p>
<p>Yeah, you can do this in other languages, but in my experience, practically noone ever does in real products. Your experience may differ from mine. I&#8217;d love to hear about counter-examples.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: lennon</title>
		<link>http://rcoder.net/content/erlang-warts/comment-page-1#comment-214</link>
		<dc:creator>lennon</dc:creator>
		<pubDate>Thu, 04 Sep 2008 07:06:14 +0000</pubDate>
		<guid isPermaLink="false">http://rcoder.net/?p=234#comment-214</guid>
		<description>I don&#039;t disagree with you about wanting clear delineation between active and passive objects, or even liking the agility of a language without compile-time type checking. My point is simply that the overuse of tagged tuples (where the atom in the first tuple position basically serves as a type flag) leads to a lot of need to repeat yourself, where a proper polymorphic type system (whether via object orientation, or via the Hindley-Milner inferential route) allows you to &quot;say what you mean,&quot; and let the compiler and/or runtime handle the rest.

Regardless, I think Erlang &lt;em&gt;does&lt;/em&gt; feel like a lot more like a scripting language, which in the end makes it far less interesting to me. The #1 most interesting feature, Actor-based concurrency, can be trivially implemented in any language with lightweight object serialization and robust TCP/IP support, and robust multiprocessing can be accomplished via a number of methods. Erlang&#039;s bunding of those tools in the language itself does inform a certain design aesthetic, but I don&#039;t know that it outweighs the awkwardness of the language itself.</description>
		<content:encoded><![CDATA[<p>I don&#8217;t disagree with you about wanting clear delineation between active and passive objects, or even liking the agility of a language without compile-time type checking. My point is simply that the overuse of tagged tuples (where the atom in the first tuple position basically serves as a type flag) leads to a lot of need to repeat yourself, where a proper polymorphic type system (whether via object orientation, or via the Hindley-Milner inferential route) allows you to &#8220;say what you mean,&#8221; and let the compiler and/or runtime handle the rest.</p>
<p>Regardless, I think Erlang <em>does</em> feel like a lot more like a scripting language, which in the end makes it far less interesting to me. The #1 most interesting feature, Actor-based concurrency, can be trivially implemented in any language with lightweight object serialization and robust TCP/IP support, and robust multiprocessing can be accomplished via a number of methods. Erlang&#8217;s bunding of those tools in the language itself does inform a certain design aesthetic, but I don&#8217;t know that it outweighs the awkwardness of the language itself.</p>
]]></content:encoded>
	</item>
</channel>
</rss>
