<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-1420318032431335295</id><updated>2011-11-28T10:16:54.103+11:00</updated><category term='Python'/><category term='Development'/><category term='list'/><category term='Euler'/><category term='Mac'/><category term='Erlang'/><title type='text'>From Java to Erlang via Python</title><subtitle type='html'>Thought and Idea covering Erlang, Python, Java in particular and Software Development in General</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://erlang-python-java.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1420318032431335295/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://erlang-python-java.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Anthony Kong</name><uri>http://www.blogger.com/profile/17663748615404465868</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>18</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-1420318032431335295.post-792671647504116220</id><published>2008-05-29T09:58:00.002+10:00</published><updated>2008-05-29T09:59:09.185+10:00</updated><title type='text'>Erlang - Parallel Programming without Pain</title><content type='html'>Joe Armstong's &lt;a href="http://www.infoq.com/presentations/erlang-software-for-a-concurrent-world"&gt;Lecture &lt;/a&gt;on InfoQ. Must watch.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1420318032431335295-792671647504116220?l=erlang-python-java.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://erlang-python-java.blogspot.com/feeds/792671647504116220/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1420318032431335295&amp;postID=792671647504116220' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1420318032431335295/posts/default/792671647504116220'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1420318032431335295/posts/default/792671647504116220'/><link rel='alternate' type='text/html' href='http://erlang-python-java.blogspot.com/2008/05/erlang-parallel-programming-without.html' title='Erlang - Parallel Programming without Pain'/><author><name>Anthony Kong</name><uri>http://www.blogger.com/profile/17663748615404465868</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1420318032431335295.post-6667541505586480474</id><published>2008-05-22T01:09:00.006+10:00</published><updated>2008-05-22T12:42:38.685+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Mac'/><title type='text'>My First Mac and Virtual Box Experience</title><content type='html'>I am officially a Mac convert.&lt;br /&gt;&lt;br /&gt;Still learning how to survive on one mouse button and use these fn, control, option and command keys. But so far so good. My MBP experience is absolutely positive.&lt;br /&gt;&lt;br /&gt;Before the purchase, I was slightly worried about if I may pay too much for a fine GUI. After last few days of hand-on experience, I think, as many MBP users has attested, the premium is well worth it.&lt;br /&gt;&lt;br /&gt;I, in particular, appreciate the BSD root of Mac OSX.  Whenever I cannot use the Mac OSX GUI to get thing done, I can always fall back to command line alternatives.&lt;br /&gt;&lt;br /&gt;Vista is a staggering failure of MS Corp in every sense (I have used Vista for a year). As Paul Graham puts it, Microsoft has &lt;a href="http://www.paulgraham.com/microsoft.html"&gt;ceased to be relevant&lt;/a&gt;. They still have market share, but it is a market share going to erode fast, under the attacks of Sun, Linux and FOSS. The unwillingness to waste any more time on Vista is my prime motivation to switch.&lt;br /&gt;&lt;br /&gt;The very first application I have downloaded is the &lt;a href="http://www.virtualbox.org/"&gt;VirtualBox&lt;/a&gt;. Basically within seconds I can start a new virtual instance of Ubuntu 8.04 beta. By default I can only &lt;span style="font-weight: bold;"&gt;ssh&lt;/span&gt; into the box via NAT. Will need to do some research to see how to get bridging done in Mac OSX.&lt;br /&gt;&lt;br /&gt;The second application I tried is, not surprisingly, &lt;a href="http://www.blacktree.com/"&gt;QuickSliver&lt;/a&gt;, an utility that warranted an hour of &lt;a href="http://www.youtube.com/watch?v=d4LkTstvUL4"&gt;Google Tech Talk&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1420318032431335295-6667541505586480474?l=erlang-python-java.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://erlang-python-java.blogspot.com/feeds/6667541505586480474/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1420318032431335295&amp;postID=6667541505586480474' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1420318032431335295/posts/default/6667541505586480474'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1420318032431335295/posts/default/6667541505586480474'/><link rel='alternate' type='text/html' href='http://erlang-python-java.blogspot.com/2008/05/my-first-mac-and-virtual-box-experience.html' title='My First Mac and Virtual Box Experience'/><author><name>Anthony Kong</name><uri>http://www.blogger.com/profile/17663748615404465868</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1420318032431335295.post-4108877290533417868</id><published>2008-05-10T04:04:00.008+10:00</published><updated>2008-05-22T12:42:54.935+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Development'/><title type='text'>The Importance of Being Nosy (Nosetests, Really)</title><content type='html'>&lt;span style="font-weight: bold;"&gt;Unit testing &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;One of a few important lessons I learn from Java development is the importance of unit test. It is of course not a silver bullet to the software reliability/quality problem, but the consequence not adopting it can only be more dire.&lt;br /&gt;&lt;br /&gt;I used only &lt;a href="http://www.junit.org/"&gt;JUnit &lt;/a&gt;to implement unit tests in Java (Since JUnit is "good enough", I never explore the alternative framework &lt;a href="http://testng.org/doc/index.html"&gt;TestNG&lt;/a&gt;.). Actually, problems in writing unit tests usually have very little to do with the frameworks themselves, but more with:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;A&lt;/span&gt;. The legacy code base you want to test against. For example, if the existing code base design is not modular enough, you have to go through some refactoring process to make unit testing possible. It is not the kind of luxury we can afford very often.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;B.&lt;/span&gt; Mock objects. &lt;a href="http://www.easymock.org/"&gt;EasyMock&lt;/a&gt; has made mocking a dependency easier, but maintaining the mock object codes still requires considerable effort.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Unit testing and Python&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I think unit testing is even more important for Python programmers.&lt;br /&gt;&lt;br /&gt;Since everything happens in runtime for Python, errors in your scripts, no matter syntactical or logical, will not be caught until you actually execute the line of code where the bug lives*.&lt;br /&gt;&lt;br /&gt;On top of it, a majority of commercial/in-house software contains so many features. The sheer number of possible combination of the execution pathways means thorough manual testing is simply unattainable, if not unrealistic.&lt;br /&gt;&lt;br /&gt;If at the end of the day, a production issue in your python software arises and it turns out to be "incorrect indentation", the managers and users will look down on you pretty hard ("Did you really test it?"). Unit test + coverage tools can help us to avoid these kind of situation.&lt;br /&gt;&lt;br /&gt;Besides, unit tests can be used to safeguard corner cases and exceptional conditions. For financial applications, one of those commonly-seen mistakes is that a program fails to perform properly when a certain event (e.g. rollover) happens on a public holiday. With unit testing, we can subject the relevant codes to different combination of date and instruments, so we can make sure it will, for instance, calculate accrual correctly no matter what.&lt;br /&gt;&lt;br /&gt;Comparing Java, I find it easier to do unit testing in Python because, with Python's "Duck Typing" capability, we do not have to worry about maintaining mock objects at all. Whenever you need to mimic a dependency's behavior, just write a dummy class with just enough attributes/methods the testee expects. End of story.&lt;br /&gt;&lt;br /&gt;No more record and play APIs, as in EasyMock.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Nosetests makes it easy &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;So, you can understand why I am so glad to find &lt;a href="http://www.somethingaboutorange.com/mrl/projects/nose/"&gt;nose&lt;/a&gt;. Nosetests is, in a nutshell, a unit test discovery tool. It can traverse down a python source code directory and pick up classes that extends &lt;a href="http://docs.python.org/lib/testcase-objects.html"&gt;unittest.Testcase&lt;/a&gt;, &lt;a href="http://docs.python.org/lib/module-doctest.html"&gt;doc test&lt;/a&gt;, and any classes/methods that follow the &lt;a href="http://www.somethingaboutorange.com/mrl/projects/nose/#writing-tests"&gt;default naming convention&lt;/a&gt;. I can now mix any testing styles depending on the task at hand.&lt;br /&gt;&lt;br /&gt;I usually use the following parameters with nosetests:&lt;br /&gt;&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;&lt;br /&gt;--verbosity=3 --with-doctest -s --exe&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;"--exe" is necessary because in &lt;a href="http://www.cygwin.com/"&gt;cygwin&lt;/a&gt;, my primary development environment, py files are usually set to be "executable".&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Feedback&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Do you have any tips and idea on unit testing/software quality assurance to share? Feel free.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;* It is not entirely true. If you want to catch syntactic error before run-time, you can use the &lt;a href="http://docs.python.org/lib/module-compiler.html"&gt;compiler &lt;/a&gt;module to parse each py file individually. It is useful when you try to refactor by renaming modules/variables using tools like sed. This allows to make sure the regex does not do anything stupid with your code.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1420318032431335295-4108877290533417868?l=erlang-python-java.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://erlang-python-java.blogspot.com/feeds/4108877290533417868/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1420318032431335295&amp;postID=4108877290533417868' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1420318032431335295/posts/default/4108877290533417868'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1420318032431335295/posts/default/4108877290533417868'/><link rel='alternate' type='text/html' href='http://erlang-python-java.blogspot.com/2008/05/importance-of-being-nosy-nosetests.html' title='The Importance of Being Nosy (Nosetests, Really)'/><author><name>Anthony Kong</name><uri>http://www.blogger.com/profile/17663748615404465868</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1420318032431335295.post-1587152077115150667</id><published>2008-04-16T00:39:00.012+10:00</published><updated>2008-05-01T00:43:02.724+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Python'/><title type='text'>Python in the Corporate World</title><content type='html'>Python is used widely in academia, open source projects and start-up. However, when it comes to the corporate world,   it seems to me it is not making a lot of inroad. At least this is true in the finance industry, which I am more familiar with.&lt;br /&gt;&lt;br /&gt;A quick check on the python.org's &lt;a href="http://www.python.org/about/success/"&gt;success stories&lt;/a&gt;, only two companies are listed as Fortune 500, and none of them is in the finance.&lt;br /&gt;&lt;br /&gt;Occasionally there are ads looking for people with python skill in the financial sector, but the positions are usually of support or operation nature, not application development.&lt;br /&gt;&lt;br /&gt;From first glimpse, it is a classic chicken-and-egg problem: there is not enough skillful python programmers out there to fill the jobs, it is difficult to start new projects in python. However, if python programming job market is weak, there is little incentives for students or programmers to pick up this non-mainstream language.&lt;br /&gt;&lt;br /&gt;But there is something more than just supply-demand. I believe a common perception that, somehow, dynamic scripting languages are &lt;span style="font-style: italic;"&gt;not for large scale projects&lt;/span&gt; and is &lt;span style="font-style: italic;"&gt;difficult to maintain&lt;/span&gt; also make people shy away from using Python.&lt;br /&gt;&lt;br /&gt;The &lt;span style="font-style: italic;"&gt;not for large scale projects&lt;/span&gt; argument is a not too hard to counter. We just need to find some good examples of high visibility. For example, &lt;a href="http://groups.google.com/"&gt;Google Groups&lt;/a&gt; and &lt;a href="http://www.selenic.com/mercurial/wiki/"&gt;mercurial.&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;However, there may not be a clean-cut answer to the question of maintainability. First of all, we have a generation of programmers who have used to statically typed languages and their accomplishing IDEs (such as Java and Eclipse). To this group of audience, the idea that one can build a full-fledged application using just API documentation, command line tools and vi/emacs is beyond imagination. It is easy to conclude that, without IDE support, it is difficult to refactor the code base, which is an essential step in keeping the application in good heath.&lt;br /&gt;&lt;br /&gt;Secondly past experience may still leave a bad taste. If you have done maintenance of legacy applications written in perl, some of them could make you feel like you have just visited a programmer's hell. Cryptic code and inconsistent style are everywhere. (But it'd still be way better than tcl. Luckily I have not come across any such programs yet). This bad memory certainly make people think twice before embracing dynamic scripting language in general, Python in particular.&lt;br /&gt;&lt;br /&gt;A disclaimer I must make: what I wrote above is based on my experience only, and your organization may be free of the above issues, especially if yours is relatively smaller in scale (so it is relatively easier to innovate) or relatively young (so there are less legacy applications). But today in most of the giant, multinational financial institutions that inspire to be a "financial supermarket" for all, the decision markers, especially the "professional manager" type, have a total different mind-set. First of all they will not be benefited much, personally, by giving green light to the use of non-mainstream technology/language that &lt;span style="font-style: italic;"&gt;promise &lt;/span&gt;better result and higher productivity. On the other hand, they have everything to lose if the brave decision does not deliver.  Java (or C# if it is a MS Window shop) is always a safe bet, even though it means one need an army of programmers to get thing done. In essence, it is an &lt;a href="http://en.wikipedia.org/wiki/Principal-agent_problem"&gt;agency problem&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1420318032431335295-1587152077115150667?l=erlang-python-java.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://erlang-python-java.blogspot.com/feeds/1587152077115150667/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1420318032431335295&amp;postID=1587152077115150667' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1420318032431335295/posts/default/1587152077115150667'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1420318032431335295/posts/default/1587152077115150667'/><link rel='alternate' type='text/html' href='http://erlang-python-java.blogspot.com/2008/04/python-in-corporate-world.html' title='Python in the Corporate World'/><author><name>Anthony Kong</name><uri>http://www.blogger.com/profile/17663748615404465868</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1420318032431335295.post-8010693451801110862</id><published>2008-04-09T13:02:00.011+10:00</published><updated>2008-04-11T21:36:51.491+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Python'/><title type='text'>Common Questions about Working as a Python Developer</title><content type='html'>I haven't posted much recently because I am starting a new job. It is the third time I switched language. Now, I am officially a Python Developer. Hurray!&lt;br /&gt;&lt;br /&gt;Since I have always kept myself busy by constantly picking up new computer languages, I know a dozen of odd and exotic languages. Therefore, after I landed on this job, I am surprised by some "interesting" questions about Python that people asked. And these people are no amateur. They are C or Java developers by profession.&lt;br /&gt;&lt;br /&gt;Here are the questions:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold; font-style: italic;"&gt;1) What is Python?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;Well, it is a dynamic scripting language. A good overview &lt;a href="http://www.python.org/about/"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;To emphasize that it is a &lt;span style="font-style: italic;"&gt;real &lt;/span&gt;programming language, I'd also add that Python is used very &lt;span style="font-style: italic;"&gt;extensively &lt;/span&gt;within Google.&lt;br /&gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;span style="font-weight: bold; font-style: italic;"&gt;2) Isn't Python an very old language?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;Oh, this question makes me feel like I am the last Eyak speaker!&lt;br /&gt;&lt;br /&gt;Python appeared in 1991 when the creator &lt;a href="http://www.python.org/%7Eguido/"&gt;Guido van Rossum&lt;/a&gt; released it to the public. It is actually a very young language.&lt;br /&gt;&lt;br /&gt;Let's compare other still active languages and the time of first appearance:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Ruby&lt;/span&gt; - 1995&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Java&lt;/span&gt; - 1995&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Visual Basic&lt;/span&gt; (VB4 to VB.Net) - 1995&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Lua&lt;/span&gt; - 1993&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Perl &lt;/span&gt;- 1987&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Erlang&lt;/span&gt; - 1987&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;C++&lt;/span&gt; - 1983&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;C &lt;/span&gt;- 1972&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Cobol&lt;/span&gt; - 1959&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Fortran&lt;/span&gt; - 1957&lt;br /&gt;&lt;br /&gt;The debut of Python is a rather recent event in the history of computer language chronologically.&lt;br /&gt;&lt;br /&gt;But another meaning implied by 'Old' is related to the vitality or dynamism of the language. A low public profile seems to indicates there is not much going on in this language.&lt;br /&gt;&lt;br /&gt;It is entirely a matter of perception.&lt;br /&gt;&lt;br /&gt;To me, python never feels old. The language is continuously improving and evolving. The community is healthy and the members on the mailing list are friendly, helpful and intelligent. The language users are willing to embrace &lt;a href="http://www.python.org/dev/peps/pep-3000"&gt;changes&lt;/a&gt; to make Python better.&lt;br /&gt;&lt;br /&gt;It is in stark contrast with Java. The discussion of the &lt;span style="font-style: italic;"&gt;Closure&lt;/span&gt; has highlighted the inertia of the Java language.&lt;br /&gt;&lt;br /&gt;But don't get me wrong: in other arena of Java eco-system, there are still a lot of energy and innovation such as &lt;a href="http://openjdk.java.net/"&gt;OpenJDK&lt;/a&gt;. OpenJDK may even eventually force the hand of Microsoft to open-source their CLR. (Hopefully)&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;span style="font-weight: bold; font-style: italic;"&gt;3) Is Python more powerful than Java?&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;blockquote&gt;Wow, it is a &lt;a href="http://en.wikipedia.org/wiki/Flamebait"&gt;dangerous questions&lt;/a&gt;! My &lt;a href="http://en.wikipedia.org/wiki/Political_correctness"&gt;PC&lt;/a&gt; answer is: they are designed for different tasks, and each of them have their distinct advantages in the problem domain that these languages are created to serve.&lt;br /&gt;&lt;br /&gt;Besides, everyone has their own notion of Powerfulness. We will end up comparing orange to apple.&lt;br /&gt;&lt;br /&gt;For me, power is only one of the consideration. Python's readability is another attractive feature. While Python cannot stop a programmer from writing cryptic code, at least it spares you the eyesore caused by bizarre programming styles that some 'gifted' programmers use.&lt;br /&gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;span style="font-weight: bold; font-style: italic;"&gt;4) Isn't Python dead?&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;blockquote&gt;&lt;span&gt;The news of Python's death is largely exaggerated.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;span style="font-style: italic;"&gt;Postscript&lt;/span&gt;:&lt;br /&gt;&lt;span style="font-weight: bold; font-style: italic;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;I think the latest announcement of &lt;a href="http://code.google.com/appengine"&gt;Google App Engine&lt;/a&gt; will make a wider audience aware of Python and how good it is.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Lately a lot of innovation in programming languages (groovy, python and erlang for example) have an European root. Is it a sign that US has under-invested in research in both public and private sections?&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1420318032431335295-8010693451801110862?l=erlang-python-java.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://erlang-python-java.blogspot.com/feeds/8010693451801110862/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1420318032431335295&amp;postID=8010693451801110862' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1420318032431335295/posts/default/8010693451801110862'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1420318032431335295/posts/default/8010693451801110862'/><link rel='alternate' type='text/html' href='http://erlang-python-java.blogspot.com/2008/04/common-questions-about-working-as.html' title='Common Questions about Working as a Python Developer'/><author><name>Anthony Kong</name><uri>http://www.blogger.com/profile/17663748615404465868</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1420318032431335295.post-5839983411439621941</id><published>2008-02-19T08:15:00.002+11:00</published><updated>2008-03-02T16:43:52.657+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='list'/><category scheme='http://www.blogger.com/atom/ns#' term='Erlang'/><title type='text'>Erlang Mailing List - String as List 3</title><content type='html'>This is the last installment of the digest of the topic of "String as List".&lt;br /&gt;&lt;span class="HcCDpe"&gt;&lt;span email="hasan.veldstra@gmail.com" class="EP8xU" style="color: rgb(204, 0, 96);"&gt;&lt;br /&gt;Hasan Veldstra&lt;/span&gt;&lt;/span&gt; opined that lack of library support make string operation difficult. He was working on an Erlang Unicode string library based on ICU (&lt;a href="http://www.icu-project.org/" target="_blank"&gt;http://www.icu-project.org/&lt;/a&gt;) for the past week, and expected to release an alpha version soon.&lt;br /&gt;&lt;br /&gt;&lt;span class="HcCDpe"&gt;&lt;span email="exta7@walla.com" class="EP8xU" style="color: rgb(0, 148, 134);"&gt;Zvi&lt;/span&gt;  &lt;span class="lDACoc"&gt;&lt;/span&gt;&lt;/span&gt;suggested that in the case of 64 bit implementation of Erlang, a "String as list" representation is wasteful.&lt;br /&gt;&lt;br /&gt;&lt;span class="HcCDpe"&gt;&lt;span email="ok@cs.otago.ac.nz" class="EP8xU" style="color: rgb(121, 6, 25);"&gt;Richard A. O'Keefe &lt;/span&gt; seems to be annoyed by this suggestion (and other comment on Lisp machine), and advocated that if space is a concern, the programmer can use an alternative representation such as binary.&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="HcCDpe"&gt;&lt;span email="rvirding@gmail.com" class="EP8xU" style="color: rgb(200, 137, 0);"&gt;Robert Virding &lt;/span&gt;&lt;/span&gt;clarify the leex (function token/2 and token/3) is re-entrant. However, yecc is not and must be fed with a completed list of token.&lt;br /&gt;&lt;br /&gt;&lt;span class="HcCDpe"&gt;&lt;span email="dmitriid@gmail.com" class="EP8xU" style="color: rgb(121, 6, 25);"&gt;Dmitrii 'Mamut' Dimandt &lt;/span&gt; &lt;/span&gt;gave an example of why "string as list" is bad idea, because:&lt;br /&gt;&lt;blockquote style="font-style: italic;"&gt;&lt;br /&gt;"This is only true for ASCII text. Non-ASCII gets screwed up badly.&lt;br /&gt;&lt;br /&gt;lists:reverse("text")     %% gives you "text"&lt;br /&gt;lists:reverse("текст")  %% Russian for text becomes [130,209,129,209,186,208,181&lt;div bgcolor="#ffffff" text="#000000"&gt;&lt;wbr&gt;,208,130,209] which is clearly not I wanted"&lt;/div&gt;&lt;/blockquote&gt;&lt;div bgcolor="#ffffff" text="#000000"&gt;&lt;br /&gt;&lt;/div&gt;  &lt;span class="HcCDpe"&gt;&lt;span email="chsu79@gmail.com" class="EP8xU" style="color: rgb(91, 16, 148);"&gt;Christian S&lt;/span&gt;  &lt;span class="lDACoc"&gt;has a solution to this problem:&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;blockquote style="font-style: italic;"&gt;"This is what you should have in your list:&lt;br /&gt;1&gt; Text = [16#442, 16#435, 16#43a, 16#441, 16#442].&lt;br /&gt;[1090,1077,1082,1089,1090]&lt;br /&gt;&lt;br /&gt;You can convert it to utf8 for output&lt;br /&gt;&lt;br /&gt;2&gt; xmerl_ucs:to_utf8(Text).&lt;br /&gt;[209,130,208,181,208,186,209&lt;div id="1fvf" class="ArwC7c ckChnd"&gt;&lt;wbr&gt;,129,209,130]&lt;br /&gt;&lt;br /&gt;And you can reverse it and convert that to utf8.&lt;br /&gt;&lt;br /&gt;3&gt; xmerl_ucs:to_utf8(lists&lt;wbr&gt;:reverse(Text)).&lt;br /&gt;[209,130,209,129,208,186,208&lt;wbr&gt;,181,209,130]"&lt;br /&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;div id="1fvf" class="ArwC7c ckChnd"&gt;&lt;br /&gt;A positive message from &lt;span class="HcCDpe"&gt;&lt;span email="bjorn@erix.ericsson.se" class="EP8xU" style="color: rgb(51, 0, 153);"&gt;Bjorn Gustavsson&lt;/span&gt;&lt;/span&gt;. He confirmed that is possible to use lists of Unicode characters easily. In Wings 3D, he have implemented a limited support for Unicode.&lt;br /&gt;&lt;br /&gt;&lt;span class="HcCDpe"&gt;&lt;span email="erlang@gmail.com" class="EP8xU" style="color: rgb(0, 131, 145);"&gt;Joe Armstrong&lt;/span&gt;&lt;/span&gt; weighted in on 19 Feb. He suggested "One problem with strings unicode, regexps etc. is how you input the string.". He proposed several new syntax to capture regex or xml string.&lt;br /&gt;&lt;br /&gt;Basically from this point onward the thread has shifted gear into forward looking mood. The discussion now focused on the best way to represent a string in Erlang.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1420318032431335295-5839983411439621941?l=erlang-python-java.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://erlang-python-java.blogspot.com/feeds/5839983411439621941/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1420318032431335295&amp;postID=5839983411439621941' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1420318032431335295/posts/default/5839983411439621941'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1420318032431335295/posts/default/5839983411439621941'/><link rel='alternate' type='text/html' href='http://erlang-python-java.blogspot.com/2008/02/erlang-mailing-list-string-as-list-3.html' title='Erlang Mailing List - String as List 3'/><author><name>Anthony Kong</name><uri>http://www.blogger.com/profile/17663748615404465868</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1420318032431335295.post-3796997893852752275</id><published>2008-02-19T04:09:00.012+11:00</published><updated>2008-02-19T08:19:25.094+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='list'/><category scheme='http://www.blogger.com/atom/ns#' term='Erlang'/><title type='text'>Erlang Mailing List - String as List 2</title><content type='html'>&lt;span class="HcCDpe"&gt;&lt;span email="exta7@walla.com" class="EP8xU" style="color: rgb(0, 148, 134);"&gt;Zvi&lt;/span&gt;&lt;span class="lDACoc"&gt; responded to &lt;/span&gt;&lt;/span&gt;&lt;span class="HcCDpe"&gt;&lt;span email="chsu79@gmail.com" class="EP8xU" style="color: rgb(91, 16, 148);"&gt;Christian S&lt;/span&gt;&lt;/span&gt;&lt;span class="HcCDpe"&gt;&lt;span class="lDACoc"&gt;'s "recommended large text mass handling modules". He said, if for efficiency we  represent  a string as binary, the code will become too verbose. For example,&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;blockquote style="font-style: italic;"&gt;&lt;span class="HcCDpe"&gt;&lt;span class="lDACoc"&gt;&lt;/span&gt;&lt;/span&gt;&lt;ul&gt;&lt;li&gt; &lt;&lt;"ABC"&gt;&gt;, instead of "ABC"&lt;/li&gt;&lt;li&gt; &lt;&lt;s1 s2="" bytes=""&gt;&lt; &lt;/s1&gt; S1 / bytes, S2 / bytes &lt;s1 s2="" bytes=""&gt;&gt;&gt; instead of S1++S2&lt;/s1&gt;&lt;/li&gt;&lt;li&gt; using file:delete(binary_to_list(Filename)) instead of file:delete(Filename)&lt;/li&gt;&lt;li&gt; xmerl and erlsom parse into lists and not binaries&lt;/li&gt;&lt;/ul&gt;&lt;/blockquote&gt;&lt;div id="1fhc" class="ArwC7c ckChnd"&gt;&lt;span class="HcCDpe"&gt;&lt;span email="dustin.whitney@gmail.com" class="EP8xU" style="color: rgb(185, 0, 56);"&gt;Dustin Whitney&lt;/span&gt;&lt;/span&gt; concurred the verboseness, and recommend a new string type.&lt;span class="HcCDpe"&gt;&lt;span email="vychodil.hynek@gmail.com" class="EP8xU" style="color: rgb(132, 102, 0);"&gt;&lt;/span&gt;&lt;span class="lDACoc"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="HcCDpe"&gt;&lt;span email="bjorn@erix.ericsson.se" class="EP8xU" style="color: rgb(51, 0, 153);"&gt;Bjorn Gustavsson&lt;/span&gt;&lt;/span&gt; responded to eariler &lt;span class="HcCDpe"&gt;&lt;span class="lDACoc"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="HcCDpe"&gt;&lt;span email="kevin@scaldeferri.com" class="EP8xU" style="color: rgb(204, 0, 96);"&gt;Kevin Scaldeferri&lt;/span&gt;&lt;/span&gt;'s opinion on list inefficiency. He suggested, in the case of appending:&lt;br /&gt;&lt;blockquote style="font-style: italic;"&gt;&lt;br /&gt;"You can append by building a deep list and only flatten it at the end.&lt;br /&gt;&lt;br /&gt;  NewString = [AListOfChars|AnotherListOfChars]&lt;br /&gt;&lt;div id="1fi4" class="ArwC7c ckChnd"&gt;&lt;br /&gt;or&lt;br /&gt;  NewString = [AListOfChars,ACharacter]&lt;br /&gt;&lt;br /&gt;Or you can simply do a recursion (not tail-recursion) and use&lt;br /&gt;the '++' operator. That will be efficient, because the recursion will&lt;br /&gt;ensure that the '++' operators are executed in a right-to-left order."&lt;/div&gt;&lt;/blockquote&gt;&lt;div id="1fi4" class="ArwC7c ckChnd"&gt;&lt;br /&gt;&lt;span class="HcCDpe"&gt;&lt;span email="chsu79@gmail.com" class="EP8xU" style="color: rgb(91, 16, 148);"&gt;Christian S  &lt;/span&gt;&lt;/span&gt;suggested an alternative to one of &lt;span class="HcCDpe"&gt;&lt;span email="exta7@walla.com" class="EP8xU" style="color: rgb(0, 148, 134);"&gt;Zvi&lt;/span&gt;&lt;span class="lDACoc"&gt;'s string-as-binary example ("&lt;/span&gt;&lt;/span&gt;  &lt;&lt;s1 s2="" bytes=""&gt;&lt;  &lt;/s1&gt; S1 / bytes, S2 / bytes &gt;&gt; &lt;s1 s2="" bytes=""&gt; instead of S1++S2")&lt;span class="HcCDpe"&gt;&lt;span class="lDACoc"&gt;:&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/s1&gt;&lt;blockquote style="font-style: italic;"&gt;"[S1,S2] and then do iolist_to_binary/1 if you need it flat."&lt;/blockquote&gt;&lt;br /&gt;Then focus of discussion shifted to a tool called Leex for a while.&lt;br /&gt;&lt;br /&gt;&lt;span class="HcCDpe"&gt;&lt;span email="ok@cs.otago.ac.nz" class="EP8xU" style="color: rgb(121, 6, 25);"&gt;Richard A. O'Keefe &lt;/span&gt;&lt;/span&gt;weighted in and expressed his opinion on a number of issues.&lt;br /&gt;&lt;br /&gt;First of all, the String as list should not be dismissed as "historical reason" only:&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;"it is simplicity (the preferred&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;sequence type in Erlang is lists, and strings are just sequences of&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;characters), power (because any time someone defines a function on&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;lists you get to use it on strings, and there are *lots* of useful&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;list functions), and processing efficiency (because working down&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;one character at a time doesn't require allocating *any* new storage,&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;not even for slices)."&lt;/span&gt;&lt;/blockquote&gt;He suggested the following rule of thumb for text handling&lt;br /&gt;&lt;blockquote style="font-style: italic;"&gt;&lt;br /&gt;"The guiding rule is&lt;br /&gt;- if you just want to hold onto a string for a while, use a binary&lt;br /&gt;- if you want to build or process a string, use a list (possibly in&lt;br /&gt;Erlang a deep list).&lt;br /&gt;- if you want to represent something that has structure, and you want&lt;br /&gt;your program to be aware of that structure, turn it into a&lt;br /&gt;structured&lt;br /&gt;data value and work with it in that form."&lt;/blockquote&gt;and some myth-busting on appending string performance issue:&lt;br /&gt;&lt;blockquote style="font-style: italic;"&gt;&lt;br /&gt;"Right, this is not efficient.  But it is spectacularly&lt;br /&gt;inefficient in programming languages with more conventional&lt;br /&gt;representations.&lt;br /&gt;It is O(n**2).  For example,&lt;br /&gt;  x = ""&lt;br /&gt;  for (i = 1; i &lt;= 100000; i++) x = x "a"  just took 30.5 seconds in awk on my machine, 62.2 seconds in Perl, and a massive 631 seconds in Java.  That was using gcj; I lost patience with the Sun SDK and killed it.  (AWK faster than Java?  Yes, it often is.) Building the same string in Erlang using        loop(100000, "") where        loop(0, S) -&gt; lists:reverse(S);&lt;br /&gt;  loop(N, S) -&gt; loop(N-1, "a"++S).&lt;br /&gt;takes 0.15 second on the same machine."&lt;/blockquote&gt;&lt;br /&gt;&lt;span class="HcCDpe"&gt;&lt;span email="masklinn@masklinn.net" class="EP8xU" style="color: rgb(121, 6, 25);"&gt;Masklinn&lt;/span&gt;  &lt;span class="lDACoc"&gt;pointed out later that Java benchmark is off because the example is not using StringBuffer.&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;End of Part 2&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;span class="HcCDpe"&gt;&lt;span email="chsu79@gmail.com" class="EP8xU" style="color: rgb(91, 16, 148);"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1420318032431335295-3796997893852752275?l=erlang-python-java.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://erlang-python-java.blogspot.com/feeds/3796997893852752275/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1420318032431335295&amp;postID=3796997893852752275' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1420318032431335295/posts/default/3796997893852752275'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1420318032431335295/posts/default/3796997893852752275'/><link rel='alternate' type='text/html' href='http://erlang-python-java.blogspot.com/2008/02/erlang-mailing-list-string-as-list-2.html' title='Erlang Mailing List - String as List 2'/><author><name>Anthony Kong</name><uri>http://www.blogger.com/profile/17663748615404465868</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1420318032431335295.post-263759057007670019</id><published>2008-02-19T03:30:00.006+11:00</published><updated>2008-02-19T08:15:33.127+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='list'/><category scheme='http://www.blogger.com/atom/ns#' term='Erlang'/><title type='text'>Erlang Mailing List - String as List 1</title><content type='html'>A discussion named "String as List" has been running, at the time of writing, for 6 days and 56 posts already. A lot of interesting idea and insight into Erlang were poured into this discussion. I simply want to write down some interesting technical points in this blog as a digest, as a reference. *&lt;br /&gt;&lt;br /&gt;It all started with a question from &lt;span class="HcCDpe"&gt;&lt;span email="tsuraan@gmail.com" class="EP8xU" style="color: rgb(0, 104, 28);"&gt;tsuraan&lt;/span&gt;:&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;blockquote style="font-style: italic;"&gt;"Why does erlang internally represent strings as lists?"&lt;/blockquote&gt;&lt;br /&gt;First response from &lt;span class="HcCDpe"&gt;&lt;span email="masklinn@masklinn.net" class="EP8xU" style="color: rgb(121, 6, 25);"&gt;Masklinn&lt;/span&gt;&lt;span class="lDACoc"&gt;, and actually many other contributors share the same idea:&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;blockquote style="font-style: italic;"&gt;&lt;span class="HcCDpe"&gt;&lt;span class="lDACoc"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;"A lot of functional languages represent strings as lists rather than&lt;br /&gt;arrays because lists are their basic collection datatype, and this allows the use of all the list-related functions on strings."&lt;/blockquote&gt;&lt;br /&gt;&lt;span class="HcCDpe"&gt;&lt;span email="chsu79@gmail.com" class="EP8xU" style="color: rgb(91, 16, 148);"&gt;Christian S &lt;/span&gt; put it in a shorter phrase: "historical reason". As he pointed out, "internal" is not right word in the question because string was not a special type or abstraction built on top of list. A string is a list.&lt;br /&gt;&lt;br /&gt;He then suggested the following module for handling large text:&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;span style="font-style: italic;"&gt;"- binaries (features representation that is 1:1 with the character&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;encoding itself, now also (R12B) with efficient scanning and&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;tail-construction)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;- iolists (features cheap concatenation of large texts)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;- list of words and a word-dictionary (features quicker scanning of words, efficient storage too)"&lt;/span&gt;&lt;span class="HcCDpe"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;span class="HcCDpe"&gt;&lt;span class="lDACoc"&gt;Then &lt;/span&gt;&lt;/span&gt;&lt;span class="HcCDpe"&gt;&lt;span email="kevin@scaldeferri.com" class="EP8xU" style="color: rgb(204, 0, 96);"&gt;Kevin Scaldeferri &lt;/span&gt;&lt;/span&gt;&lt;span class="HcCDpe"&gt;&lt;span class="lDACoc"&gt;throws in a different point: list is not a good representation because&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;blockquote&gt;&lt;span style="font-style: italic;" class="HcCDpe"&gt;&lt;span class="lDACoc"&gt;"&lt;/span&gt;&lt;/span&gt;&lt;span style="font-style: italic;"&gt;First off, I append to strings a lot more than I prepend to them.  Yeah, I&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt; could work with reversed strings, but that's a hack to deal with using the &lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;wrong data type.  Plus, I probably prefix match more often than suffix matching&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;(although this is less lopsided than append vs. prepend) ..."&lt;/span&gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;Now we have a diversion, &lt;span class="HcCDpe"&gt;&lt;span email="vlm@lionet.info" class="EP8xU" style="color: rgb(0, 131, 145);"&gt;Lev Walkin &lt;/span&gt;&lt;/span&gt;responded to earlier Robert's post about that list is an ideal string representation because it can easily accommodate UTF-16 and UTF-32.&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;span style="font-style: italic;"&gt;"Small correction: UTF-16 and UTF-32 are practically dead, you certainly&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;need to think in terms of UTF-8 nowadays."&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;span class="HcCDpe"&gt;Now we are going to have several threads going on under the same thread subject. Let's get to it in my next blog. But for now I will ignore UTF-8 vs UTF16/32 discussions in order to focus on Erlang features.&lt;br /&gt;&lt;br /&gt;End of Part 1&lt;br /&gt;&lt;span class="lDACoc"&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;* It is about summarization, so quote will be edited liberally for clarity, rather than reproduced word for word.&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1420318032431335295-263759057007670019?l=erlang-python-java.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://erlang-python-java.blogspot.com/feeds/263759057007670019/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1420318032431335295&amp;postID=263759057007670019' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1420318032431335295/posts/default/263759057007670019'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1420318032431335295/posts/default/263759057007670019'/><link rel='alternate' type='text/html' href='http://erlang-python-java.blogspot.com/2008/02/erlang-mailing-list-string-as-list-1.html' title='Erlang Mailing List - String as List 1'/><author><name>Anthony Kong</name><uri>http://www.blogger.com/profile/17663748615404465868</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1420318032431335295.post-8866917822435065934</id><published>2008-02-06T06:02:00.011+11:00</published><updated>2008-02-19T05:51:21.246+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Development'/><category scheme='http://www.blogger.com/atom/ns#' term='Erlang'/><title type='text'>Why I choose to learn Erlang?</title><content type='html'>Just think it may be worthwhile to commit it in writing for sharing.&lt;br /&gt;&lt;br /&gt;In summary, my decision is only partially based on the technical merit or language features.&lt;br /&gt;&lt;br /&gt;First take a look back at year 2001. Motivated by the desire to find a better, more reliable way to develop software, I learned and switched to Linux platform in this year. For anyone serious in learning unix family OS,  &lt;span style="font-style: italic;"&gt;bash&lt;/span&gt;, &lt;span style="font-style: italic;"&gt;awk&lt;/span&gt;, &lt;span style="font-style: italic;"&gt;sed &lt;/span&gt;and &lt;span style="font-style: italic;"&gt;perl &lt;/span&gt;scripting are literally the "basic dance steps".&lt;br /&gt;&lt;br /&gt;Then I moved on to Python (see my first blog if you have plenty of time to waste :-) ).&lt;br /&gt;&lt;br /&gt;Now fast forward a few years. From Python, I soon learn about these big names such as &lt;a href="http://www.python.org/%7Eguido/"&gt;Guido van Rossum&lt;/a&gt; and &lt;a href="http://norvig.com/"&gt;Peter Norvig&lt;/a&gt; etc, and for some reasons, stumbled upon  &lt;a href="http://www.paulgraham.com/"&gt;Paul Graham&lt;/a&gt; and his famous essays.&lt;br /&gt;&lt;br /&gt;One of his famous idea on computer language is: there are reasons why some languages are superior than other languages, and Lisp &lt;span style="font-style: italic;"&gt;is &lt;/span&gt;the most powerful among them. (Alright, I made the assertion for him, he probably never really put it exactly this way. Did he?)&lt;br /&gt;&lt;br /&gt;So, convinced by the argument that a language is key to a programmer's productivity, I decided to give Lisp a try. The syntax, or the lack of it, is indeed a challenge, but the concept of "code is data, data is code" is very powerful. &lt;a href="http://www.gigamonkeys.com/book/macros-standard-control-constructs.html"&gt;Macros&lt;/a&gt; and &lt;a href="http://www.gigamonkeys.com/book/object-reorientation-generic-functions.html"&gt;CLOS &lt;/a&gt;are effective techniques in Lisp programming.&lt;br /&gt;&lt;br /&gt;Fortunately there are a lot of resource.&lt;br /&gt;&lt;br /&gt;Actually I should put it this way: "too much resource".&lt;br /&gt;&lt;br /&gt;Indeed, if you look at variety in the implementations of mainstream Lisp, and its derivative, Scheme, you will find these choices: Common lisp (clisp), CMUCL (CMU lisp), Kawa (Scheme on JVM), PLT Scheme, Scheme 48 etc... The list goes on and on.&lt;br /&gt;&lt;br /&gt;It is the common phenomena of *nix world: the Fragmentation.&lt;br /&gt;&lt;br /&gt;As a result, for any partitioner in commercial software world, it becomes a hard problem: given limited free time for self-study, we are confronted with these choices:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;which language (Lisp or Scheme)?&lt;/li&gt;&lt;li&gt;which version (R5RS or R6RS or some subset, in the case of Scheme)?&lt;/li&gt;&lt;li&gt;which implementation of the language (the usual portability vs power/library issue)?&lt;/li&gt;&lt;/ul&gt;It makes my research long and tedious. If I bet on a wrong horse, I will lose a lot of valuable time, right? What if I am in a middle of a project and encounter a bug in the lisp/scheme interpreter I am using, will there be adequate community support? What if...&lt;br /&gt;&lt;br /&gt;Does the risks justify the potential gain from the use of Lisp/Scheme?&lt;br /&gt;&lt;br /&gt;Then I discovered Erlang.&lt;br /&gt;&lt;br /&gt;The following reasons make me think, form my particular situation and career need, Erlang is probably the safest  bet (or most cost-effective investment):&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;It has all the beauty and expressiveness of a functional language&lt;/li&gt;&lt;li&gt;You gain concurrency for free (built-in support in syntax and kernel)&lt;br /&gt;&lt;/li&gt;&lt;li&gt;You gain fault tolerance for free&lt;/li&gt;&lt;li&gt;You gain distributed processing for free&lt;/li&gt;&lt;li&gt;The language and library are robust and battle-tested in demanding Telecom industry.&lt;/li&gt;&lt;li&gt;It does not suffer from the implementation fragmentation of Lisp/Scheme.&lt;/li&gt;&lt;li&gt;The language evolution is well controlled (by Ericsson)&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;It is a pragmatic choice from a software builder's point of view.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1420318032431335295-8866917822435065934?l=erlang-python-java.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://erlang-python-java.blogspot.com/feeds/8866917822435065934/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1420318032431335295&amp;postID=8866917822435065934' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1420318032431335295/posts/default/8866917822435065934'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1420318032431335295/posts/default/8866917822435065934'/><link rel='alternate' type='text/html' href='http://erlang-python-java.blogspot.com/2008/02/why-i-choose-to-learn-erlang.html' title='Why I choose to learn Erlang?'/><author><name>Anthony Kong</name><uri>http://www.blogger.com/profile/17663748615404465868</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1420318032431335295.post-3625411911597323714</id><published>2008-02-02T17:56:00.001+11:00</published><updated>2008-02-15T14:59:41.799+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Euler'/><category scheme='http://www.blogger.com/atom/ns#' term='Erlang'/><category scheme='http://www.blogger.com/atom/ns#' term='Python'/><title type='text'>Little Erlang Exercise 6</title><content type='html'>Problem Definition: &lt;a href="http://projecteuler.net/index.php?section=problems&amp;amp;id=6"&gt;Euler Problem 6&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;This problem is very straight-forward.&lt;br /&gt;&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;&lt;br /&gt;"""&lt;br /&gt;The sum of the squares of the first ten natural numbers is,&lt;br /&gt;1+ 2^2 + ... + 10^2 = 385&lt;br /&gt;&lt;br /&gt;The square of the sum of the first ten natural numbers is,&lt;br /&gt;(1 + 2 + ... + 10)^2 = 55 = 3025&lt;br /&gt;&lt;br /&gt;Hence the difference between the sum of the squares of the first ten natural numbers and the square of the sum is 3025 - 385 = 2640.&lt;br /&gt;&lt;br /&gt;Find the difference between the sum of the squares of the first one hundred natural numbers and the square of the sum.&lt;br /&gt;"""&lt;br /&gt;&lt;br /&gt;if __name__ == "__main__":&lt;br /&gt;  Max = 100&lt;br /&gt;  SumOfSquare = sum([pow(X, 2) for X in xrange(1, Max + 1)])&lt;br /&gt;  SquareOfSum = pow(sum([X for X in xrange(1, Max + 1)]), 2)&lt;br /&gt;  print "%d" % (SquareOfSum - SumOfSquare)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Here is the corresponding erlang version.&lt;br /&gt;&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;&lt;br /&gt;-module(p6).&lt;br /&gt;-export([find_diff/1]).&lt;br /&gt;&lt;br /&gt;find_diff(Max)-&gt;&lt;br /&gt;  SumOfSq = lists:foldl(fun (X, Y) -&gt; X + Y end, 0, [X*X || X &lt;- lists:seq(1, Max)]),&lt;br /&gt;  SqOfSum = math:pow(&lt;br /&gt;              lists:foldl(fun (X, Y) -&gt; X + Y end, 0, [X || X &lt;- lists:seq(1, Max)]),&lt;br /&gt;              2),&lt;br /&gt;  SqOfSum - SumOfSq.&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Basically, both python and erlang offer very powerful list comprehension syntax.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1420318032431335295-3625411911597323714?l=erlang-python-java.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://erlang-python-java.blogspot.com/feeds/3625411911597323714/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1420318032431335295&amp;postID=3625411911597323714' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1420318032431335295/posts/default/3625411911597323714'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1420318032431335295/posts/default/3625411911597323714'/><link rel='alternate' type='text/html' href='http://erlang-python-java.blogspot.com/2008/02/little-erlang-exercise-6.html' title='Little Erlang Exercise 6'/><author><name>Anthony Kong</name><uri>http://www.blogger.com/profile/17663748615404465868</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1420318032431335295.post-2545374392026607944</id><published>2008-02-01T23:17:00.001+11:00</published><updated>2008-02-01T23:37:33.912+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Euler'/><category scheme='http://www.blogger.com/atom/ns#' term='Erlang'/><category scheme='http://www.blogger.com/atom/ns#' term='Python'/><title type='text'>Little Erlang Exercise 5</title><content type='html'>Problem Definition: &lt;a href="http://projecteuler.net/index.php?section=problems&amp;amp;id=5"&gt;Euler Problem 5&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I am rather happy with this python version because I can basically get it done in about 15 min in total. Some useful primitives have been developed in module p3 (See my previous post, &lt;a href="http://www.blogger.com/2008/01/little-erlange-exercise-3_29.html"&gt;little erlang exercise 3&lt;/a&gt;)&lt;br /&gt;&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;&lt;br /&gt;"""&lt;br /&gt;2520 is the smallest number that can be divided by each of the numbers from 1 to 10 without any remainder.&lt;br /&gt;&lt;br /&gt;What is the smallest number that is evenly divisible by all of the numbers from 1 to 20?&lt;br /&gt;"""&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;from p3 import isprime, factorise&lt;br /&gt;&lt;br /&gt;def product(x, y):&lt;br /&gt; return x * y&lt;br /&gt;&lt;br /&gt;if __name__ == "__main__":&lt;br /&gt; factors = dict()&lt;br /&gt; for l in [factorise(i) for i in xrange(2, 21)]:&lt;br /&gt;     tmp = dict()&lt;br /&gt;     # count them&lt;br /&gt;     for n in l:&lt;br /&gt;         tmp[n] = 1 + tmp.get(n, 0)&lt;br /&gt;     # reguster the max frequency of factor&lt;br /&gt;     for k, v in tmp.items():&lt;br /&gt;         factors[k] = max(factors.get(k, 0), v)&lt;br /&gt;&lt;br /&gt; print reduce(product, [pow(k, v) for k,v in factors.items()])&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;However, the erlang version took me a considerable time to complete. The problem is mainly to switch from a procedural mindset to a functional mindset.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;&lt;br /&gt;&lt;br /&gt;-module(p5).&lt;br /&gt;-import(p3).&lt;br /&gt;-export([main/0, get_factor_freq_lst/1]).&lt;br /&gt;&lt;br /&gt;%% run this to print the result&lt;br /&gt;main() -&gt;&lt;br /&gt;  L = [ p3:factorise(X) || X &lt;- lists:seq(1, 20)],   &lt;br /&gt;  io:format("~f~n", [product(get_factor_freq(L))]).   &lt;br /&gt;&lt;br /&gt;get_factor_freq(L) -&gt;&lt;br /&gt;  Dict = dict:new(),&lt;br /&gt;  get_factor_freq(L, Dict).&lt;br /&gt;&lt;br /&gt;%% spec: H, T are list of list of number&lt;br /&gt;%% e.g. [ [N1, N1, N2...], [N1, N2...], ...]&lt;br /&gt;get_factor_freq([H|T], Dict) -&gt;&lt;br /&gt;  Dist = get_factor_freq_lst(H),&lt;br /&gt;  D1 = dict:from_list(Dist),&lt;br /&gt;  D2 = dict:merge(fun(K, X, Y) -&gt; update_if_bigger(K, X, Y) end, D1, Dict),&lt;br /&gt;  get_factor_freq(T, D2);&lt;br /&gt;get_factor_freq([], Dict) -&gt;&lt;br /&gt;  dict:to_list(Dict).  %% has to convert to list&lt;br /&gt;&lt;br /&gt;%% Aux function&lt;br /&gt;update_if_bigger(_, Initial, NewValue) when Initial &lt; NewValue -&gt;&lt;br /&gt;  NewValue;&lt;br /&gt;update_if_bigger(_, Initial, _) -&gt;&lt;br /&gt;  Initial.&lt;br /&gt;&lt;br /&gt;%% This function assumes the list is sorted&lt;br /&gt;%% This function is to delinate a list of number&lt;br /&gt;%% into a list of {Key, Frequency}&lt;br /&gt;get_factor_freq_lst([A|T]) when is_integer(A) -&gt;&lt;br /&gt;  get_factor_freq_lst([{A, 1}|T]);&lt;br /&gt;get_factor_freq_lst([{A, N}, A|T]) when is_integer(A) -&gt;&lt;br /&gt;  get_factor_freq_lst([{A, N + 1}|T]);&lt;br /&gt;get_factor_freq_lst([{A, N}, B|T]) when is_integer(A), is_integer(B), A /= B -&gt;&lt;br /&gt;  get_factor_freq_lst([{B, 1}|T] ++ [{A, N}] );&lt;br /&gt;get_factor_freq_lst(L) -&gt;&lt;br /&gt;  L.&lt;br /&gt;&lt;br /&gt;%% find the product of a list of tuple {Base, Power)&lt;br /&gt;product(L) -&gt;&lt;br /&gt;  product(L, 1).&lt;br /&gt;product([], Sum) -&gt;&lt;br /&gt;  Sum;&lt;br /&gt;product([{Base, Power}|T], Sum) -&gt;&lt;br /&gt;  product(T, Sum * math:pow(Base, Power)).&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1420318032431335295-2545374392026607944?l=erlang-python-java.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://erlang-python-java.blogspot.com/feeds/2545374392026607944/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1420318032431335295&amp;postID=2545374392026607944' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1420318032431335295/posts/default/2545374392026607944'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1420318032431335295/posts/default/2545374392026607944'/><link rel='alternate' type='text/html' href='http://erlang-python-java.blogspot.com/2008/02/little-erlang-exercise-5.html' title='Little Erlang Exercise 5'/><author><name>Anthony Kong</name><uri>http://www.blogger.com/profile/17663748615404465868</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1420318032431335295.post-8422387224070078892</id><published>2008-01-31T21:37:00.000+11:00</published><updated>2008-01-31T21:57:30.595+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Euler'/><category scheme='http://www.blogger.com/atom/ns#' term='Erlang'/><category scheme='http://www.blogger.com/atom/ns#' term='Python'/><title type='text'>Little Erlang Exercise 4</title><content type='html'>Problem Definition: &lt;a href="http://projecteuler.net/index.php?section=problems&amp;amp;id=4"&gt;Euler Problem 4&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Through this exercise, I realised that I can reverse a string using a [::-1] operator. Really cryptic, but yet handy.&lt;br /&gt;&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;&lt;br /&gt;"""&lt;br /&gt;A palindromic number reads the same both ways. The largest palindrome&lt;br /&gt;made from the product of two 2-digit numbers is 9009 = 91 x 99.&lt;br /&gt;&lt;br /&gt;Find the largest palindrome made from the product of two 3-digit numbers.&lt;br /&gt;"""&lt;br /&gt;&lt;br /&gt;def isPalindromic(Num):&lt;br /&gt;  """&lt;br /&gt;    For string reversal, pls check this url:&lt;br /&gt;&lt;br /&gt;      http://www.python.org/doc/2.3.5/whatsnew/section-slices.html&lt;br /&gt;&lt;br /&gt;  """&lt;br /&gt;  N = str(Num)&lt;br /&gt;  l = len(N)&lt;br /&gt;  div, mod = divmod(l, 2)&lt;br /&gt;  if mod == 1: # odd&lt;br /&gt;    fh = N[0:l/2]&lt;br /&gt;    sh = N[1+l/2:]&lt;br /&gt;    # print "%s %s" % (fh, sh)&lt;br /&gt;  else:&lt;br /&gt;    fh = N[0:l/2]&lt;br /&gt;    sh = N[l/2:]&lt;br /&gt;  return fh == sh[::-1]&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;if __name__ == "__main__":&lt;br /&gt;  g = [ x * y for x in xrange(100, 999) for y in xrange(100, 999) ]&lt;br /&gt;  print max(filter(lambda x: isPalindromic(x), g))&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Here comes an erlang version. In this rare occasion, erlang runs faster than python. It is probably because, first of all, the list comprehension I used in erlang produces a smaller list. Secondly the test of palindromic is more straightforward in the erlang version. &lt;br /&gt;&lt;br /&gt;I will revisit the python version, later, when I get a bit more time.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;&lt;br /&gt;&lt;br /&gt;-module(p4).&lt;br /&gt;-export([findLargestProduct/0]).&lt;br /&gt;&lt;br /&gt;isPalindromic(N) when is_list(N) -&gt;&lt;br /&gt;  N == lists:reverse(N).&lt;br /&gt;&lt;br /&gt;findLargestProduct() -&gt;&lt;br /&gt;  List = [X * Y || X &lt;- lists:seq(100, 999),&lt;br /&gt;                   Y &lt;- lists:seq(100, 999),&lt;br /&gt;                   isPalindromic(integer_to_list(X * Y))],&lt;br /&gt;  lists:max(List).&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1420318032431335295-8422387224070078892?l=erlang-python-java.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://erlang-python-java.blogspot.com/feeds/8422387224070078892/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1420318032431335295&amp;postID=8422387224070078892' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1420318032431335295/posts/default/8422387224070078892'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1420318032431335295/posts/default/8422387224070078892'/><link rel='alternate' type='text/html' href='http://erlang-python-java.blogspot.com/2008/01/little-erlang-exercise-4.html' title='Little Erlang Exercise 4'/><author><name>Anthony Kong</name><uri>http://www.blogger.com/profile/17663748615404465868</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1420318032431335295.post-5132302946249986477</id><published>2008-01-29T22:09:00.001+11:00</published><updated>2008-01-29T22:30:37.343+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Euler'/><category scheme='http://www.blogger.com/atom/ns#' term='Erlang'/><category scheme='http://www.blogger.com/atom/ns#' term='Python'/><title type='text'>Little Erlang Exercise 3</title><content type='html'>Problem Definition: &lt;a href="http://projecteuler.net/index.php?section=problems&amp;amp;id=3"&gt;Euler Problem 3&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Obviously, these scripts did not actually implement the solution. The problem statement required to pick the largest factor, but I just realized I had not done it.&lt;br /&gt;&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;&lt;br /&gt;"""&lt;br /&gt;&lt;br /&gt;The prime factors of 13195 are 5, 7, 13 and 29.&lt;br /&gt;&lt;br /&gt;What is the largest prime factor of the number 317584931803?&lt;br /&gt;&lt;br /&gt;"""&lt;br /&gt;&lt;br /&gt;import sys&lt;br /&gt;&lt;br /&gt;primes = []&lt;br /&gt;&lt;br /&gt;def isprime(N):&lt;br /&gt;  """&lt;br /&gt;    Original version use xrange, but caused&lt;br /&gt;&lt;br /&gt;    "OverflowException: long int too large to convert to int"&lt;br /&gt;&lt;br /&gt;    when taking in a large number&lt;br /&gt;   &lt;br /&gt;    So, I have to use while loop to replace "for i in xrange(2, N):"&lt;br /&gt;&lt;br /&gt;    And in order to speed up the process, the prime calculation result&lt;br /&gt;    is cached&lt;br /&gt;  """&lt;br /&gt;  global primes&lt;br /&gt;&lt;br /&gt;  # we have already tested it&lt;br /&gt;  if N in primes:&lt;br /&gt;    return True&lt;br /&gt;&lt;br /&gt;  # use the prime results first &lt;br /&gt;  for i in primes:&lt;br /&gt;    if (N % i) == 0:&lt;br /&gt;      return False&lt;br /&gt;&lt;br /&gt;  # now computation is required&lt;br /&gt;  maxprime = 2&lt;br /&gt;  if len(primes) &gt; 0:&lt;br /&gt;    maxprime = primes[-1]&lt;br /&gt;&lt;br /&gt;  i = maxprime + 1&lt;br /&gt;  while i &lt; N:&lt;br /&gt;    if (N % i) == 0:&lt;br /&gt;      return False&lt;br /&gt;    i = i + 1&lt;br /&gt;&lt;br /&gt;  primes.append(N)&lt;br /&gt;  return True&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;def factorise(N):&lt;br /&gt;  """&lt;br /&gt;    to factorise a integer&lt;br /&gt;    &lt;br /&gt;  """&lt;br /&gt;  # short cut&lt;br /&gt;  global primes&lt;br /&gt;  res = []&lt;br /&gt;&lt;br /&gt;  if N in primes:&lt;br /&gt;    res.append(N)&lt;br /&gt;    return res&lt;br /&gt;&lt;br /&gt;  # original algorithm&lt;br /&gt;  idx = 2&lt;br /&gt;  while idx &lt;= N:&lt;br /&gt;    if isprime(idx):&lt;br /&gt;      div, mod = divmod(N, idx)&lt;br /&gt;      if mod == 0:&lt;br /&gt;        res.append(idx) &lt;br /&gt;        res.extend(factorise(div))&lt;br /&gt;        break&lt;br /&gt;    idx = idx + 1&lt;br /&gt;  return res      &lt;br /&gt;&lt;br /&gt;if __name__ == "__main__":  &lt;br /&gt;  print factorise(int(sys.argv[1]))&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Here comes the erlang version. There is some performance issue with this version. hopefully I would have some free time soon to improve the algorithm.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;&lt;br /&gt;&lt;br /&gt;-module(p3).&lt;br /&gt;-export([isprime/1, factorise/1]).&lt;br /&gt;&lt;br /&gt;%%&lt;br /&gt;%% prime means it is not divisible by any numbers other than 1 and itself.&lt;br /&gt;%%&lt;br /&gt;isprime(1) -&gt;&lt;br /&gt; false;&lt;br /&gt;&lt;br /&gt;isprime(2) -&gt;&lt;br /&gt; true;&lt;br /&gt;&lt;br /&gt;isprime(N) when N &gt; 2 -&gt;&lt;br /&gt; Pid = self(),&lt;br /&gt; C = lists:seq(2, N - 1),&lt;br /&gt; process_flag(trap_exit, true),&lt;br /&gt; lists:map(fun(Div) -&gt;&lt;br /&gt;               spawn_link(fun() -&gt;&lt;br /&gt;                   test_if_divisible(Pid, N, Div)&lt;br /&gt;                   end)&lt;br /&gt;               end, C),&lt;br /&gt; isprime_poll(length(C)).&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;%%&lt;br /&gt;%% Message loop: to listen and receive message from voters&lt;br /&gt;%%&lt;br /&gt;isprime_poll(0) -&gt;&lt;br /&gt; true;&lt;br /&gt;isprime_poll(NumVote) -&gt;&lt;br /&gt; receive&lt;br /&gt;   {nondivisible, _} -&gt;&lt;br /&gt;       isprime_poll(NumVote - 1);&lt;br /&gt;   {divisible, _} -&gt;&lt;br /&gt;       clean_mailbox(),&lt;br /&gt;       false&lt;br /&gt; end.&lt;br /&gt;&lt;br /&gt;%%&lt;br /&gt;%% To clear away any messages in mailbox&lt;br /&gt;%%&lt;br /&gt;clean_mailbox() -&gt;&lt;br /&gt; receive&lt;br /&gt;   _ -&gt;&lt;br /&gt;     clean_mailbox()&lt;br /&gt;   after 0 -&gt; ok&lt;br /&gt; end.&lt;br /&gt;&lt;br /&gt;%%&lt;br /&gt;%%&lt;br /&gt;%%&lt;br /&gt;test_if_divisible(Pid, N, Div) -&gt;&lt;br /&gt; case N rem Div of&lt;br /&gt;   0 -&gt; Pid ! {divisible, Div};&lt;br /&gt;   _ -&gt; Pid ! {nondivisible, Div}&lt;br /&gt; end.&lt;br /&gt;&lt;br /&gt;%%%&lt;br /&gt;%%% To factorise an integer - wrappers&lt;br /&gt;%%%&lt;br /&gt;factorise(N) when is_list(N) -&gt;&lt;br /&gt;   N1 = string:to_integer(N),&lt;br /&gt;   factorise(N1, 2, []);&lt;br /&gt;&lt;br /&gt;factorise(N) -&gt;&lt;br /&gt;   factorise(N, 2, []).&lt;br /&gt;&lt;br /&gt;%%%&lt;br /&gt;%%% To factorise an integer&lt;br /&gt;%%%&lt;br /&gt;factorise(N, Factor, Result) when Factor &lt; N+1  -&gt;&lt;br /&gt; case isprime(Factor) of&lt;br /&gt;   true -&gt;&lt;br /&gt;     if&lt;br /&gt;       (N rem Factor) == 0 -&gt;&lt;br /&gt;         %% io:format("Residual is 0 by Factor ~p~n", [Factor]),&lt;br /&gt;         factorise(N div Factor, 2, [Factor|Result]);&lt;br /&gt;       true -&gt;&lt;br /&gt;         factorise(N, Factor + 1, Result)&lt;br /&gt;     end;&lt;br /&gt;   false -&gt;&lt;br /&gt;       factorise(N, Factor + 1, Result)&lt;br /&gt; end;&lt;br /&gt;&lt;br /&gt;factorise(_, _, Result) -&gt;&lt;br /&gt; R = lists:reverse(Result),&lt;br /&gt; %% io:format("~p~n", [R]),&lt;br /&gt; R.&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1420318032431335295-5132302946249986477?l=erlang-python-java.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://erlang-python-java.blogspot.com/feeds/5132302946249986477/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1420318032431335295&amp;postID=5132302946249986477' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1420318032431335295/posts/default/5132302946249986477'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1420318032431335295/posts/default/5132302946249986477'/><link rel='alternate' type='text/html' href='http://erlang-python-java.blogspot.com/2008/01/little-erlange-exercise-3_29.html' title='Little Erlang Exercise 3'/><author><name>Anthony Kong</name><uri>http://www.blogger.com/profile/17663748615404465868</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1420318032431335295.post-1984766282269043435</id><published>2008-01-26T14:22:00.000+11:00</published><updated>2008-01-29T22:31:44.819+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Euler'/><category scheme='http://www.blogger.com/atom/ns#' term='Erlang'/><category scheme='http://www.blogger.com/atom/ns#' term='Python'/><title type='text'>Little Erlang Exercise 2</title><content type='html'>Problem Definition: &lt;a href="http://projecteuler.net/index.php?section=problems&amp;amp;id=2"&gt;Euler Problem 2&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;In order to solve this problem in python, I have used the yield keyword to implements a generator to provide a sequence of Fibonacci's numbers. I think I can do a better work in using list comprehension in the main routine to filter and add up the even numbers, but the current version is basically good enough.&lt;br /&gt;&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;"""&lt;br /&gt;&lt;br /&gt;Euler 2&lt;br /&gt;&lt;br /&gt;Each new term in the Fibonacci sequence is generated by adding the previous two terms.&lt;br /&gt;By starting with 1 and 2, the first 10 terms will be:&lt;br /&gt;&lt;br /&gt;1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ...&lt;br /&gt;&lt;br /&gt;Find the sum of all the even-valued terms in the sequence which&lt;br /&gt;do not exceed one million.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;"""&lt;br /&gt;def gen_fib_seq():&lt;br /&gt;a = 1&lt;br /&gt;b = 2&lt;br /&gt;yield a&lt;br /&gt;yield b&lt;br /&gt;try:&lt;br /&gt; while 1:&lt;br /&gt;   c = a + b&lt;br /&gt;   a, b = b, c&lt;br /&gt;   yield c&lt;br /&gt;except StopIteration:&lt;br /&gt; pass&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;if __name__ == "__main__":&lt;br /&gt;b = 0&lt;br /&gt;onemillion = 1000000&lt;br /&gt;for x in gen_fib_seq():&lt;br /&gt; if x % 2 == 0:&lt;br /&gt;   if b + x &amp;lt; onemillion:&lt;br /&gt;     b = b + x&lt;br /&gt;   else:&lt;br /&gt;     break&lt;br /&gt;print b&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The erlang turns out to be even simpler than I thought. First of all, because every object or operation can be abstracted as a process, I do not need special keyword 'yield' to create a special object - generator. Furthermore the guard clause of  function &lt;span style="font-weight: bold;"&gt;acc &lt;/span&gt;remove the need to put in any 'if' or 'break' to do, for example, the even number testing as in the python version.&lt;br /&gt;&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;-module(p2).&lt;br /&gt;-export([main/0]).&lt;br /&gt;&lt;br /&gt;start() -&amp;gt; spawn(fun() -&amp;gt; fib(0, 1) end).&lt;br /&gt;&lt;br /&gt;fib(N, M) -&amp;gt;&lt;br /&gt;receive&lt;br /&gt; {Pid, next} -&amp;gt;&lt;br /&gt;   Pid ! {self(), N + M},&lt;br /&gt;   fib(M, N+ M)&lt;br /&gt;end.&lt;br /&gt;&lt;br /&gt;get_next_fib(Pid) -&amp;gt;&lt;br /&gt;Pid ! {self(), next},&lt;br /&gt;receive&lt;br /&gt; {_, N} -&amp;gt;&lt;br /&gt;   %% io:format("~p~n", [N])&lt;br /&gt;   N&lt;br /&gt;end.&lt;br /&gt;&lt;br /&gt;%% accumulator&lt;br /&gt;acc(N, Pid, Acc) when (N rem 2) =:= 1 -&amp;gt;&lt;br /&gt; N1 = get_next_fib(Pid),&lt;br /&gt; acc(N1, Pid, Acc);&lt;br /&gt;acc(N, Pid, Acc) when N + Acc &amp;lt; 1000000 -&amp;gt;&lt;br /&gt; N1 = get_next_fib(Pid),&lt;br /&gt; acc(N1, Pid, Acc + N);&lt;br /&gt;acc(_, _, Acc) -&amp;gt;&lt;br /&gt; Acc.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;%%%&lt;br /&gt;%%% Program main()&lt;br /&gt;%%%&lt;br /&gt;main() -&amp;gt;&lt;br /&gt; Pid = start(),&lt;br /&gt; Acc = acc(1, Pid, 0),&lt;br /&gt; Acc.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1420318032431335295-1984766282269043435?l=erlang-python-java.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://erlang-python-java.blogspot.com/feeds/1984766282269043435/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1420318032431335295&amp;postID=1984766282269043435' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1420318032431335295/posts/default/1984766282269043435'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1420318032431335295/posts/default/1984766282269043435'/><link rel='alternate' type='text/html' href='http://erlang-python-java.blogspot.com/2008/01/little-erlange-exercise-2.html' title='Little Erlang Exercise 2'/><author><name>Anthony Kong</name><uri>http://www.blogger.com/profile/17663748615404465868</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1420318032431335295.post-4096780570486567751</id><published>2008-01-11T13:05:00.000+11:00</published><updated>2008-01-28T21:58:39.720+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Erlang'/><category scheme='http://www.blogger.com/atom/ns#' term='Python'/><title type='text'>Little Erlange Exercise 1</title><content type='html'>Problem definition: &lt;a href="http://projecteuler.net/index.php?section=problems&amp;amp;id=1"&gt;Euler Problem 1&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Python version&lt;br /&gt;&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;br /&gt;print reduce(lambda x, y : x + y,&lt;br /&gt; filter(lambda x: x % 3 == 0 or x % 5 == 0,&lt;br /&gt; range(1, 1001)))&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Erlang version&lt;br /&gt;&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;-module(p1).&lt;br /&gt;-export([pr_sum/0]). %% print sum&lt;br /&gt;&lt;br /&gt;pr_sum() -&gt;&lt;br /&gt;      L = lists:seq(1, 1000),&lt;br /&gt;      L1 = [ X ||X &lt;- L, (X rem 3) == 0 orelse (X rem 5) == 0],&lt;br /&gt;      sum(L1). &lt;br /&gt;&lt;br /&gt;sum(L) -&gt; sum(L, 0).&lt;br /&gt;sum([], Acc) -&gt; Acc;&lt;br /&gt;sum([H|T], Acc) -&gt; sum(T, Acc + H).&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1420318032431335295-4096780570486567751?l=erlang-python-java.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://erlang-python-java.blogspot.com/feeds/4096780570486567751/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1420318032431335295&amp;postID=4096780570486567751' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1420318032431335295/posts/default/4096780570486567751'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1420318032431335295/posts/default/4096780570486567751'/><link rel='alternate' type='text/html' href='http://erlang-python-java.blogspot.com/2008/01/little-erlange-exercise-1.html' title='Little Erlange Exercise 1'/><author><name>Anthony Kong</name><uri>http://www.blogger.com/profile/17663748615404465868</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1420318032431335295.post-7492504578198141841</id><published>2007-09-14T17:45:00.001+10:00</published><updated>2008-01-26T16:35:44.797+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Erlang'/><title type='text'>Erlang syntax 2 - Pattern matching and assignment</title><content type='html'>I think it is probably a typical experience for any beginner of Erlang: The equal sign in Erlang actually works differently comparing most other imperative mainstream application.  I were a little bit surprised when I first realized the subtle difference.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;In erlang, the equal sign is actually an pattern matching  operator.  For example,&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;[H|T] = [0, 1, 2, 3, 4]&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;In the case, H is actually matched with the head of the list [0..4]. Although it effectively initialised the values of variable H and T, it is fundamentally a different concept.&lt;br /&gt;&lt;br /&gt;Another application of this language feature is that it serves as a mean to enforce assertion. For example,&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;ok = module:func().&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;If func return an atom &lt;span style="font-weight: bold;"&gt;failure&lt;/span&gt; instead of &lt;span style="font-weight: bold;"&gt;ok&lt;/span&gt;, an exception will be automatically generated.&lt;br /&gt;&lt;br /&gt;Isn't it neat?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1420318032431335295-7492504578198141841?l=erlang-python-java.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://erlang-python-java.blogspot.com/feeds/7492504578198141841/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1420318032431335295&amp;postID=7492504578198141841' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1420318032431335295/posts/default/7492504578198141841'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1420318032431335295/posts/default/7492504578198141841'/><link rel='alternate' type='text/html' href='http://erlang-python-java.blogspot.com/2007/09/erlang-syntax-2-pattern-matching-and.html' title='Erlang syntax 2 - Pattern matching and assignment'/><author><name>Anthony Kong</name><uri>http://www.blogger.com/profile/17663748615404465868</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1420318032431335295.post-1589380066274908176</id><published>2007-09-14T17:44:00.000+10:00</published><updated>2008-01-11T11:55:30.918+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Erlang'/><title type='text'>Erlang Syntax 1</title><content type='html'>&lt;table style="color: rgb(51, 255, 51);font-family:courier new;background-color: rgb(0, 0, 0);"&gt;&lt;br /&gt;&lt;tr&gt;&lt;td&gt;&lt;br /&gt;1&gt; (list_to_atom("erlang")):(list_to_atom("now"))().&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;br /&gt;&lt;tr&gt;&lt;td&gt;&lt;br /&gt;{1189,752160,276431}&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;br /&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;This is equivalent to&lt;br /&gt;&lt;br /&gt;&lt;table style="color: rgb(51, 255, 51);font-family:courier new;background-color: rgb(0, 0, 0);"&gt;&lt;br /&gt;&lt;tr&gt;&lt;td&gt;&lt;br /&gt;1&gt; erlang:now().&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;br /&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;Very interesting syntax.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1420318032431335295-1589380066274908176?l=erlang-python-java.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://erlang-python-java.blogspot.com/feeds/1589380066274908176/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1420318032431335295&amp;postID=1589380066274908176' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1420318032431335295/posts/default/1589380066274908176'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1420318032431335295/posts/default/1589380066274908176'/><link rel='alternate' type='text/html' href='http://erlang-python-java.blogspot.com/2007/09/erlang-syntax-1.html' title='Erlang Syntax 1'/><author><name>Anthony Kong</name><uri>http://www.blogger.com/profile/17663748615404465868</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1420318032431335295.post-7037644796722456275</id><published>2007-08-12T23:27:00.001+10:00</published><updated>2007-08-12T23:31:36.635+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Erlang'/><title type='text'>Prologue</title><content type='html'>The last time I got excited about a programming language was around 5 years ago when I started to learn a scripting language called &lt;a href="http://python.org/"&gt;Python&lt;/a&gt;. At that point of time, I were looking for a language that is easier to use than &lt;a href="http://www.blogger.com/www.perl.org"&gt;Perl&lt;/a&gt;. Don't get me wrong: Perl is still great for throw-away scripting. Its regular-expression is indispensable tool. But to do OO development in perl is simply too painful for me.&lt;br /&gt;&lt;br /&gt;To me, Python is 'Perl done right'. It has the power of Perl, yet more readable and programmable. The use of space to indicate scope is simply a brilliant idea, despite feels a bit odd to begin with. By taking away some individual 'freedom' in this regard, it gives the whole community the advantage of uniformity of coding style. This actually makes Python an ideal language for enterprise environment, because,  unlike other scripting languages, Python programmers tends to write code in consistent Pythonic style. No more unmaintainable cryptic Perl or Tcl scripts.&lt;br /&gt;&lt;br /&gt;Python also introduces the idea of &lt;span style="font-weight: bold;"&gt;Lambda Function  &lt;/span&gt;and &lt;span style="font-weight: bold;"&gt;Closure&lt;/span&gt; to me. Without me knowing, I have picked up some functional programming concept!&lt;br /&gt;&lt;br /&gt;Functional programming is no alien to me. I have done Miranda in my first year of computer science, but I were not impressed at that time. I simply did not get it then. (Besides, it seemed to me that none got paid for doing FP professionally, so there is even less incentive to master the concepts)&lt;br /&gt;&lt;br /&gt;Now, I have come a full cycle. This year I "discovered" the language &lt;a href="http://erlang.org/"&gt;Erlang&lt;/a&gt;. After reading the concepts behind the language design and implementation, I am totally in awe. The impact is as if some mystical figure suddenly showed up and told me the answer of a riddle of which I have searching for an answer for years in wilderness.&lt;br /&gt;&lt;br /&gt;So, hopefully in this blog I can share with the public my (hopefully weekly) progress in mastering this new language, erlang, and along the way, my feeling/idea about Erlang, Python and Java. (Hence the title of this blog)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1420318032431335295-7037644796722456275?l=erlang-python-java.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://erlang-python-java.blogspot.com/feeds/7037644796722456275/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1420318032431335295&amp;postID=7037644796722456275' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1420318032431335295/posts/default/7037644796722456275'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1420318032431335295/posts/default/7037644796722456275'/><link rel='alternate' type='text/html' href='http://erlang-python-java.blogspot.com/2007/08/prologue.html' title='Prologue'/><author><name>Anthony Kong</name><uri>http://www.blogger.com/profile/17663748615404465868</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
