<?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-1008786629149528709</id><updated>2011-11-27T16:30:23.522-08:00</updated><category term='erlang'/><category term='named tuples'/><category term='records'/><category term='estone'/><category term='actioscript'/><category term='vm'/><category term='github'/><category term='pretty-printing'/><category term='memory'/><category term='syntax'/><category term='IDE'/><category term='flex'/><category term='beam'/><category term='comet'/><category term='webserver'/><category term='dojo'/><category term='filesystem'/><category term='stdin'/><category term='tls'/><category term='shell'/><category term='teeterl'/><category term='apr'/><category term='performance'/><category term='crypto'/><category term='json'/><title type='text'>Tao of Erlang</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://taooferlang.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1008786629149528709/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://taooferlang.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Maxim Kharchenko</name><uri>http://www.blogger.com/profile/14817460239103044233</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://bp0.blogger.com/_q0h9e6rTTO0/SIeAdGxPxnI/AAAAAAAAAAY/8ePhZVqwvX8/S220/blog_photo.JPG'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>16</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-1008786629149528709.post-455917846735165880</id><published>2009-12-25T17:53:00.000-08:00</published><updated>2009-12-29T10:11:33.392-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='named tuples'/><category scheme='http://www.blogger.com/atom/ns#' term='erlang'/><category scheme='http://www.blogger.com/atom/ns#' term='records'/><category scheme='http://www.blogger.com/atom/ns#' term='teeterl'/><category scheme='http://www.blogger.com/atom/ns#' term='syntax'/><title type='text'>teeterl fixes Erlang records</title><content type='html'>&lt;div&gt;I think Erlang records syntax is neat. Expressive, tight and consistent. A bit repetitive sometimes, yes. There is still a big problem with Erlang records. Not with the syntax but with record declarations shared between modules in .hrl files. This is fixed in teeterl.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;teeterl now supports (partially)  a new breed of records called 'named tuples'. Named tuples and records are very similar - at some point both are mapped to tagged tuples. The true difference is that named tuples are never declared. The inner structure of a named tuple is inferred from its use. No declarations, no .hrl files, no need to recompile.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Named tuple has a separate syntax from records but this is not of essence. Examples:&lt;/div&gt;&lt;div&gt;&lt;pre&gt;&lt;br /&gt;%% create a tuple named 'car' with fields 'model' and 'mpg'&lt;br /&gt;Car1 = {car#model &lt;- "Lexus", mpg &lt;- 30},&lt;br /&gt;&lt;br /&gt;%% create another tuple named 'car'; name is inferred&lt;br /&gt;%% from use in the previous line&lt;br /&gt;Car2 = {model &lt;- "Honda"},&lt;br /&gt;&lt;br /&gt;%% get index of the field in the tuple; needed for keyfind()&lt;br /&gt;%% and the likes&lt;br /&gt;Index = car#mpg,&lt;br /&gt;&lt;br /&gt;%% access named tuple field; again name is inferred,&lt;br /&gt;%% the alternative is Car1.car#mpg&lt;br /&gt;Mpg = Car1.mpg,&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Values:&lt;/div&gt;&lt;div&gt;Car1&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;= {car,"Lexus",30}&lt;/div&gt;&lt;div&gt;Car2&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;= {car,"Honda,undefined}&lt;/div&gt;&lt;div&gt;Index&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;= 3&lt;/div&gt;&lt;div&gt;Mpg&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;= 30&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The trick is that field offsets of a named tuple are assigned during module &lt;b&gt;loading&lt;/b&gt; not during preprocessing or some other compilation step. Thus the layout of a given named tuple may be different in different VMs.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Now if you need another field in a named tuple just assign a value to the field. Send the extended tuple to the old code and you will not break anything. Modules are compiled in complete isolation, no worry about record versions. Plus information about fields is accessible during runtime. And all these goodies come with no performance penalty. Named tuples work at exactly the same speed as conventional records.&lt;/div&gt;&lt;br /&gt;EDIT: the teeterl's source code is on &lt;a href="http://www.github.com/maximk/teeterl"&gt;GitHub&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1008786629149528709-455917846735165880?l=taooferlang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://taooferlang.blogspot.com/feeds/455917846735165880/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1008786629149528709&amp;postID=455917846735165880' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1008786629149528709/posts/default/455917846735165880'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1008786629149528709/posts/default/455917846735165880'/><link rel='alternate' type='text/html' href='http://taooferlang.blogspot.com/2009/12/teeterl-fixes-erlang-records.html' title='teeterl fixes Erlang records'/><author><name>Maxim Kharchenko</name><uri>http://www.blogger.com/profile/14817460239103044233</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://bp0.blogger.com/_q0h9e6rTTO0/SIeAdGxPxnI/AAAAAAAAAAY/8ePhZVqwvX8/S220/blog_photo.JPG'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1008786629149528709.post-5756571995550436060</id><published>2009-11-29T07:08:00.000-08:00</published><updated>2009-11-29T10:01:40.364-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='erlang'/><category scheme='http://www.blogger.com/atom/ns#' term='estone'/><category scheme='http://www.blogger.com/atom/ns#' term='github'/><category scheme='http://www.blogger.com/atom/ns#' term='beam'/><category scheme='http://www.blogger.com/atom/ns#' term='teeterl'/><title type='text'>New teeterl; 4x faster</title><content type='html'>&lt;div style="text-align: justify;"&gt;Three months ago I decided to give teeterl a once over. The goal was to make it faster, order of magnitude faster. Today, the new teeterl version has become mature enough to run estone_SUITE and produce meaningful performance measurement printout. The result: it is almost 4 times faster than earlier teeterl. Not 10x, but definitely on the right track. BEAM is still a distant performance star boasting more than 2 times more estones.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;The new version of teeterl has a goodish bit under the hood. The most noticeable are the new partial, generation-aware garbage collector and the fact that teeterl VM is now register-based.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;The new teeterl can not do much more than run a few test suites now. Nevertheless I will release the source of github as soon I figure out how to push it into existing 'teeterl' repo without destroying the previous version.&lt;/div&gt;&lt;div style="text-align: justify;"&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/1008786629149528709-5756571995550436060?l=taooferlang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://taooferlang.blogspot.com/feeds/5756571995550436060/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1008786629149528709&amp;postID=5756571995550436060' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1008786629149528709/posts/default/5756571995550436060'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1008786629149528709/posts/default/5756571995550436060'/><link rel='alternate' type='text/html' href='http://taooferlang.blogspot.com/2009/11/new-teeterl-4x-faster.html' title='New teeterl; 4x faster'/><author><name>Maxim Kharchenko</name><uri>http://www.blogger.com/profile/14817460239103044233</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://bp0.blogger.com/_q0h9e6rTTO0/SIeAdGxPxnI/AAAAAAAAAAY/8ePhZVqwvX8/S220/blog_photo.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1008786629149528709.post-7074853404013842309</id><published>2009-11-29T07:06:00.000-08:00</published><updated>2009-11-29T10:36:51.210-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='stdin'/><category scheme='http://www.blogger.com/atom/ns#' term='comet'/><category scheme='http://www.blogger.com/atom/ns#' term='erlang'/><category scheme='http://www.blogger.com/atom/ns#' term='pretty-printing'/><category scheme='http://www.blogger.com/atom/ns#' term='teeterl'/><title type='text'>stdin/stdout in Erlang</title><content type='html'>&lt;div style="text-align: justify;"&gt;Erlang blogs and message boards are littered with messages expressing dissatisfaction with Erlang syntax, the language's handling of strings, verbosity of records etc. Members of the discontented crowd usually stop short when specifics are requested. I will try to make my small rant about Erlang as specific as possible.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;My grudge is about stdin/stdout. Why would modern software need these? Existence of stdin/stdout assumes that Erlang is started from a text-based shell. These days it usually not the case. Why io:format() pretty-printing is crafted to output text on a screen of 80 columns? Erlang is all about non-blocking input/output and then there is io:get_line() getting text from nowhere. I am aware of Elang's telecom heritage and RS-232 interface. But this kind of thing definitely slows the adoption of Erlang in today's world of World-Wide Web.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;The new version of teeterl does not have io module as it does not have stdin/stdout concept. On the other hand the new teeterl has had an embedded web server with comet functionality from day one. All input/output in the new teeterl is done through a socket and HTTP. Instead of io:format() there is format:to_json() call and all actual formatting including pretty-printing is done on the client side with jQuery/Javascript. Well, a printout still may appear on stderr but only as an epitaph on the tomb of init process.&lt;/div&gt;&lt;div style="text-align: justify;"&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/1008786629149528709-7074853404013842309?l=taooferlang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://taooferlang.blogspot.com/feeds/7074853404013842309/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1008786629149528709&amp;postID=7074853404013842309' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1008786629149528709/posts/default/7074853404013842309'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1008786629149528709/posts/default/7074853404013842309'/><link rel='alternate' type='text/html' href='http://taooferlang.blogspot.com/2009/11/stdinstdout-in-erlang.html' title='stdin/stdout in Erlang'/><author><name>Maxim Kharchenko</name><uri>http://www.blogger.com/profile/14817460239103044233</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://bp0.blogger.com/_q0h9e6rTTO0/SIeAdGxPxnI/AAAAAAAAAAY/8ePhZVqwvX8/S220/blog_photo.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1008786629149528709.post-5963679674699885637</id><published>2009-11-29T06:54:00.000-08:00</published><updated>2009-11-29T09:40:05.486-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='performance'/><category scheme='http://www.blogger.com/atom/ns#' term='vm'/><category scheme='http://www.blogger.com/atom/ns#' term='erlang'/><title type='text'>Laying out VM vitals</title><content type='html'>&lt;div style="text-align: justify;"&gt;The teeterl's &lt;a href="http://taooferlang.blogspot.com/2009/04/teeterls-performance-more-than-modest.html"&gt;poor performance&lt;/a&gt; felt like a cold shower to me. And at the opportune moment I decided to have a closer look at why it is so bad. By then I had a scaffold implementation of a register-based teeterl VM. The new version was already churning out primes numbers in spadefuls without a hitch. But I decided to take two steps back and measure if the decisions I made were of any merit. It happened many of them did more harm than good.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;For about a week I was rewriting my shiny new VM into a new application, cleverly named &lt;span style="font-style:italic;"&gt;teepad&lt;/span&gt;, that was doing nothing but creating random stack frames, touching various memory locations, allocating chunks of memory from the heap, a dispatching random instructions from a dozens of garbage modules. It weighs heavily on a fellow's mind to write a simulation software of the sort. When someone laboriously develop a sizable do-nothing system for a long time, thoughts start to creep in. I am lucky it did not take too long. Now I have speed readings of the garbage mincer and can make a few observations.&lt;/div&gt;&lt;div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;span style="font-weight:bold;"&gt;Do not reenter VM's main function&lt;/span&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;As everybody knows the main function of a VM is where the huge switch statement is. I was toying with the idea of reentering the routine on every Erlang function call. Thus register values will be instantaneously back to existence after return. Well, Erlang process should yield from time to time, and I added a separate stack which was filled in when the process was yielding. Boy, it is probably the worst stack management scheme out there. &lt;i&gt;teepad&lt;/i&gt; was able to dispatch 2.5 times more commands if such nastiness is avoided.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;span style="font-weight:bold;"&gt;Keep the number of opcodes moderate&lt;/span&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;With &lt;i&gt;teepad &lt;/i&gt;it was possible to boost the number of different opcodes to a sizable number increasing the number of cases in the master switch statement accordingly. I thought it would be neat to have an opcode for, say, 'move r1, r2' and another opcode for 'move r2, r3'. I was quite wrong again. &lt;i&gt;teepad &lt;/i&gt;experiments showed that twice as many opcodes means 15% less throughput, 5 times - shaves 25% from performance.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;span style="font-weight:bold;"&gt;Packing/unpacking of arguments does not matter&lt;/span&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;These days of multi-layered caches you may do any number of bitwise operations on a value already retrieved from memory. Take highest 6 bits, mask out 3 lower bits, add 7 to the result, do it on every dispatch and you won't tax your performance noticeably. Bitwise operations help to reduce the memory footprint of a VM and thus stimulate a better cache behavior that more than offset the additional CPU cycles burn of bit fiddling.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;span style="font-weight:bold;"&gt;More details for someone who care&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;1. Instruction set generated from the types below:&lt;br /&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;th style="text-align: left;"&gt;Type&lt;/th&gt;&lt;th&gt;Prob&lt;/th&gt;&lt;th&gt;#variants&lt;/th&gt;&lt;th&gt;#args&lt;/th&gt;&lt;th style="text-align: left;"&gt;Options&lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;test&lt;/td&gt;&lt;td style="text-align: right;"&gt;0.2&lt;/td&gt;&lt;td style="text-align: right;"&gt;10&lt;/td&gt;&lt;td style="text-align: center;"&gt;1-3&lt;/td&gt;&lt;td&gt;[branches]&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;enter&lt;/td&gt;&lt;td style="text-align: right;"&gt;0.05&lt;/td&gt;&lt;td style="text-align: right;"&gt;1&lt;/td&gt;&lt;td style="text-align: center;"&gt;1-1&lt;/td&gt;&lt;td&gt;[reduce,jumps]&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;enterf&lt;/td&gt;&lt;td style="text-align: right;"&gt;0.01&lt;/td&gt;&lt;td style="text-align: right;"&gt;2&lt;/td&gt;&lt;td style="text-align: center;"&gt;3-4&lt;/td&gt;&lt;td&gt;[reduce,jumps,intermodule]&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;call&lt;/td&gt;&lt;td style="text-align: right;"&gt;0.02&lt;/td&gt;&lt;td style="text-align: right;"&gt;1&lt;/td&gt;&lt;td style="text-align: center;"&gt;1-1&lt;/td&gt;&lt;td&gt;[reduce,calls]&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;callf&lt;/td&gt;&lt;td style="text-align: right;"&gt;0.01&lt;/td&gt;&lt;td style="text-align: right;"&gt;2&lt;/td&gt;&lt;td style="text-align: center;"&gt;3-4&lt;/td&gt;&lt;td&gt;[reduce,calls,intermodule]&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;bif&lt;/td&gt;&lt;td style="text-align: right;"&gt;0.01&lt;/td&gt;&lt;td style="text-align: right;"&gt;8&lt;/td&gt;&lt;td style="text-align: center;"&gt;2-3&lt;/td&gt;&lt;td&gt;[reduce,heap]&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;move&lt;/td&gt;&lt;td style="text-align: right;"&gt;0.3&lt;/td&gt;&lt;td style="text-align: right;"&gt;10&lt;/td&gt;&lt;td style="text-align: center;"&gt;0-2&lt;/td&gt;&lt;td&gt;[]&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;make&lt;/td&gt;&lt;td style="text-align: right;"&gt;0.1&lt;/td&gt;&lt;td style="text-align: right;"&gt;10&lt;/td&gt;&lt;td style="text-align: center;"&gt;1-3&lt;/td&gt;&lt;td&gt;[heap]&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;select&lt;/td&gt;&lt;td style="text-align: right;"&gt;0.1&lt;/td&gt;&lt;td style="text-align: right;"&gt;5&lt;/td&gt;&lt;td style="text-align: center;"&gt;1-3&lt;/td&gt;&lt;td&gt;[heap]&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;compute&lt;/td&gt;&lt;td style="text-align: right;"&gt;0.1&lt;/td&gt;&lt;td style="text-align: right;"&gt;20&lt;/td&gt;&lt;td style="text-align: center;"&gt;2-3&lt;/td&gt;&lt;td&gt;[]&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;apply&lt;/td&gt;&lt;td style="text-align: right;"&gt;0.01&lt;/td&gt;&lt;td style="text-align: right;"&gt;2&lt;/td&gt;&lt;td style="text-align: center;"&gt;1-2&lt;/td&gt;&lt;td&gt;[reduce,jumps]&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;'receive'&lt;/td&gt;&lt;td style="text-align: right;"&gt;0.001&lt;/td&gt;&lt;td style="text-align: right;"&gt;1&lt;/td&gt;&lt;td style="text-align: center;"&gt;1-1&lt;/td&gt;&lt;td&gt;[yields,messages]&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;error&lt;/td&gt;&lt;td style="text-align: right;"&gt;0.0001&lt;/td&gt;&lt;td style="text-align: right;"&gt;1&lt;/td&gt;&lt;td style="text-align: center;"&gt;1-1&lt;/td&gt;&lt;td&gt;[exits]&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Implementation of each opcode is randomly generated using Options column, e.g. 'receive' instruction has 1 variant and appears once per each 1000 instructions. Its implementation may include unpacking its arguments, touching the mailbox memory and faking a context switch.&lt;/div&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;2. Modules are generated from instruction set using probabilities of commands of given type&lt;/div&gt;&lt;div&gt;&lt;br /&gt;# of modules is 10.&lt;br /&gt;Module size ranges between 1000 and 100000.&lt;br /&gt;Reductions before yield is, obviously, 1000.&lt;br /&gt;Instruction arguments are packed (4 arguments into 1 word).&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="text-align: justify;"&gt;3. Generated program is compiled, run for 5sec and the number of instructions dispatched is reported.&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;The source code of &lt;i&gt;teepad&lt;/i&gt; and raw measurement data are gladly provided upon an e-mail inquiry.&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1008786629149528709-5963679674699885637?l=taooferlang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://taooferlang.blogspot.com/feeds/5963679674699885637/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1008786629149528709&amp;postID=5963679674699885637' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1008786629149528709/posts/default/5963679674699885637'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1008786629149528709/posts/default/5963679674699885637'/><link rel='alternate' type='text/html' href='http://taooferlang.blogspot.com/2009/11/laying-out-vm-vitals.html' title='Laying out VM vitals'/><author><name>Maxim Kharchenko</name><uri>http://www.blogger.com/profile/14817460239103044233</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://bp0.blogger.com/_q0h9e6rTTO0/SIeAdGxPxnI/AAAAAAAAAAY/8ePhZVqwvX8/S220/blog_photo.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1008786629149528709.post-8228079285164385990</id><published>2009-07-27T06:43:00.000-07:00</published><updated>2009-07-27T06:56:39.212-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='erlang'/><category scheme='http://www.blogger.com/atom/ns#' term='memory'/><category scheme='http://www.blogger.com/atom/ns#' term='apr'/><title type='text'>apr_pool_t with counter</title><content type='html'>Lack of tracking of the total size of all allocations made from a given apr_pool_t is a big pain for teeterl. I had to introduce yet another layer of indirection by adding xpool_t structure which is no more than a counter and apr_pool_t reference. Now most of the time the size of allocations are added up neatly to check when the threshold is reached and gc should kick in.&lt;br /&gt;Recently I transgressed to the point of putting the size counting inside apr_pool_t thus producing a custom version of APR. Yes, it did make teeterl a bit smaller and cleaner and auxilliary allotments were counted better. On the other hand, the impure act of meddling with APR code made the installation of teeterl much longer and trickier. I still do not have a single person who managed to build and run teeterl on his/her machine and the recent change make the possibility even more remote. I am rolling everything back to xpool_t's.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1008786629149528709-8228079285164385990?l=taooferlang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://taooferlang.blogspot.com/feeds/8228079285164385990/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1008786629149528709&amp;postID=8228079285164385990' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1008786629149528709/posts/default/8228079285164385990'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1008786629149528709/posts/default/8228079285164385990'/><link rel='alternate' type='text/html' href='http://taooferlang.blogspot.com/2009/07/aprpoolt-with-counter.html' title='apr_pool_t with counter'/><author><name>Maxim Kharchenko</name><uri>http://www.blogger.com/profile/14817460239103044233</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://bp0.blogger.com/_q0h9e6rTTO0/SIeAdGxPxnI/AAAAAAAAAAY/8ePhZVqwvX8/S220/blog_photo.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1008786629149528709.post-5841423234804252797</id><published>2009-04-23T11:37:00.000-07:00</published><updated>2009-04-23T12:24:32.386-07:00</updated><title type='text'>teeterl's performance; more than modest</title><content type='html'>Every compiler or a runtime system should come with an all-encompassing testing suite. Not so for teeterl. There used to be no testing suite at all and the only indication that the system is working as it would be capable of compiling itself and producing a still working copy. Many aspects of the system were this way left outside of spotlight. Such as binary construction and matching as compiler does not do a lot of binary construction and matching when producing code.&lt;br /&gt;&lt;br /&gt;Then, teeterl was released to the public and I decided to clean it a bit to expel many a bug still haunting dark corners of the system. OTP test_server and emulator test suites came handy here.&lt;br /&gt;&lt;br /&gt;Today teeterl runs many test suites from OTP emulator testing set. Of course, many test suites appeared not relevant for teeterl, such as dynamic driver loading or port commands. These are implemented in teeterl in very unorthodox way. Others, such as binary or list manipulations tests  helped to weed a few overlooked bugs.&lt;br /&gt;&lt;br /&gt;One of the test suites was - estone_SUITE. It is a performance test suite and the rest of the post is devoted to its output for teeterl. I would not have published the results if only Richard Feynman's address on cargo cult science convinced me to do otherwise. So, here are all results of estone tests even those that talk not in teeterl's favor at all.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;Run #1. teeterl (not optimized meaning -ggdb option to gcc)&lt;br /&gt;&lt;br /&gt;**** CPU speed UNKNOWN MHz ****&lt;br /&gt;**** Total time 106.752 seconds ****&lt;br /&gt;**** ESTONES = 9612 ****&lt;br /&gt;&lt;br /&gt;    Title                            Millis        Estone&lt;br /&gt;&lt;br /&gt;list manipulation                    2522            602&lt;br /&gt;small messages                       38336           80&lt;br /&gt;medium messages                      38806           156&lt;br /&gt;huge messages                        860             576&lt;br /&gt;pattern matching                     1234            628&lt;br /&gt;traverse                             1673            296&lt;br /&gt;Work with large dataset              608             459&lt;br /&gt;Work with large local dataset        441             633&lt;br /&gt;Alloc and dealloc                    184             672&lt;br /&gt;Bif dispatch                         244             3176&lt;br /&gt;Binary handling                      2698            183&lt;br /&gt;Generic server (with timeout)        16953           148&lt;br /&gt;Small Integer arithmetics            750             372&lt;br /&gt;Float arithmetics                    141             219&lt;br /&gt;Function calls                       631             1228&lt;br /&gt;Timers                               672             184&lt;br /&gt;&lt;br /&gt;Run #2. teeterl (fully optimized, -O3 -fast options to gcc)&lt;br /&gt;&lt;br /&gt;**** CPU speed UNKNOWN MHz ****&lt;br /&gt;**** Total time 82.6701 seconds ****&lt;br /&gt;**** ESTONES = 12654 ****&lt;br /&gt;&lt;br /&gt;    Title                            Millis        Estone&lt;br /&gt;&lt;br /&gt;list manipulation                    1826            831&lt;br /&gt;small messages                       28284           109&lt;br /&gt;medium messages                      28563           212&lt;br /&gt;huge messages                        623             796&lt;br /&gt;pattern matching                     937             827&lt;br /&gt;traverse                             1061            467&lt;br /&gt;Work with large dataset              607             459&lt;br /&gt;Work with large local dataset        763             365&lt;br /&gt;Alloc and dealloc                    127             972&lt;br /&gt;Bif dispatch                         184             4210&lt;br /&gt;Binary handling                      5901            84&lt;br /&gt;Generic server (with timeout)        12354           203&lt;br /&gt;Small Integer arithmetics            459             607&lt;br /&gt;Float arithmetics                    100             309&lt;br /&gt;Function calls                       398             1946&lt;br /&gt;Timers                               481             257&lt;br /&gt;&lt;br /&gt;Run #3. Erlang/OTP, emulator version 5.6.5&lt;br /&gt;&lt;br /&gt;**** CPU speed UNKNOWN MHz ****&lt;br /&gt;**** Total time 2.697552 seconds ****&lt;br /&gt;**** ESTONES = 69058 ****&lt;br /&gt;&lt;br /&gt;    Title                            Millis        Estone&lt;br /&gt;&lt;br /&gt;list manipulation                    292             5204&lt;br /&gt;small messages                       594             5218&lt;br /&gt;medium messages                      1068            5687&lt;br /&gt;huge messages                        315             1573&lt;br /&gt;pattern matching                     104             7456&lt;br /&gt;traverse                             243             2043&lt;br /&gt;Work with large dataset              -490            -569&lt;br /&gt;Work with large local dataset        -634            -439&lt;br /&gt;Alloc and dealloc                    56              2227&lt;br /&gt;Bif dispatch                         36              21695&lt;br /&gt;Binary handling                      228             2171&lt;br /&gt;Generic server (with timeout)        461             5447&lt;br /&gt;Small Integer arithmetics            127             2192&lt;br /&gt;Float arithmetics                    17              1820&lt;br /&gt;Function calls                       118             6572&lt;br /&gt;Timers                               163             761&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;It looks like teeterl is way slower than out-of-the-box Erlang/OTP even if all optimizations are enabled in C compiler. The results are especially startling for message passing. teeterl takes 50x more time to pass messages. For other tests the figure is close to 2-3x. Something is very very wrong with teeterl's message passing. One possibility is that process yields to scheduler every time it sends a message. This should not be done.&lt;br /&gt;&lt;br /&gt;I do not wear hats but if I would wear one I would definitely have taken it off before Erlang/OTP team who produced such a fast system.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1008786629149528709-5841423234804252797?l=taooferlang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://taooferlang.blogspot.com/feeds/5841423234804252797/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1008786629149528709&amp;postID=5841423234804252797' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1008786629149528709/posts/default/5841423234804252797'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1008786629149528709/posts/default/5841423234804252797'/><link rel='alternate' type='text/html' href='http://taooferlang.blogspot.com/2009/04/teeterls-performance-more-than-modest.html' title='teeterl&apos;s performance; more than modest'/><author><name>Maxim Kharchenko</name><uri>http://www.blogger.com/profile/14817460239103044233</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://bp0.blogger.com/_q0h9e6rTTO0/SIeAdGxPxnI/AAAAAAAAAAY/8ePhZVqwvX8/S220/blog_photo.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1008786629149528709.post-8595767545950982964</id><published>2009-03-25T09:47:00.000-07:00</published><updated>2009-03-25T10:03:01.630-07:00</updated><title type='text'>X Erlang is now teeterl; released under BSD license</title><content type='html'>I decided to rebrand X Erlang. Now it is called 'teeterl'. Previous name sounded too old-fashioned. The new one emphasizes the toy nature of the system.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;And, by the way, everything teeterl is in public access on github (&lt;a href="http://github.com/maximk/teeterl"&gt;http://github.com/maximk/teeterl&lt;/a&gt;).&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;To gain interactive access to the internals of the running system, you will need another project too. It is called spurl (&lt;a href="http://github.com/maximk/spurl"&gt;http://github.com/maximk/spurl&lt;/a&gt;).&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I am fascinated to learn that someone else was  successful in building and running teeterl (and spurl).&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1008786629149528709-8595767545950982964?l=taooferlang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://taooferlang.blogspot.com/feeds/8595767545950982964/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1008786629149528709&amp;postID=8595767545950982964' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1008786629149528709/posts/default/8595767545950982964'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1008786629149528709/posts/default/8595767545950982964'/><link rel='alternate' type='text/html' href='http://taooferlang.blogspot.com/2009/03/x-erlang-is-now-teeterl-released-under.html' title='X Erlang is now teeterl; released under BSD license'/><author><name>Maxim Kharchenko</name><uri>http://www.blogger.com/profile/14817460239103044233</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://bp0.blogger.com/_q0h9e6rTTO0/SIeAdGxPxnI/AAAAAAAAAAY/8ePhZVqwvX8/S220/blog_photo.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1008786629149528709.post-1574090916474584055</id><published>2009-01-23T00:52:00.000-08:00</published><updated>2009-01-23T03:37:55.924-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='crypto'/><category scheme='http://www.blogger.com/atom/ns#' term='erlang'/><category scheme='http://www.blogger.com/atom/ns#' term='tls'/><title type='text'>TLS 1.0 in Erlang, no OpenSSL</title><content type='html'>&lt;div style="text-align: justify;"&gt;I was borrowing ideas from Erlang/OTP for my X Erlang implementation as a matter of routine. Sometimes the shortcut did not work because I would not understand Erlang/OTP sources or would think they are too convoluted.&lt;br /&gt;&lt;br /&gt;Erlang/OTP approach to crypto functions is a disappoinment. It uses external OpenSSL library through a port driver. Erlang has nice binary parsing, big numbers, hash function BIFs etc and all these are replicated in OpenSSL. Plus OpenSSL itlself is three times bigger than whole X Erlang.&lt;br /&gt;&lt;br /&gt;Now I have a working TLS library with all cryptographic primitives implemented in Erlang. No OpenSSL or anything of its ilk. The exception are MD5 and SHA1 functions which are BIFs done in C. I barely believe when my TLS server makes its way through a jungle of TLS handshake calculations and starts shoveling application data.&lt;br /&gt;&lt;br /&gt;I tesify, and give my oath, that TLS is implementable using RFC 2246 and RFC 2104 (and, of course, Wikipedia).&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1008786629149528709-1574090916474584055?l=taooferlang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://taooferlang.blogspot.com/feeds/1574090916474584055/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1008786629149528709&amp;postID=1574090916474584055' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1008786629149528709/posts/default/1574090916474584055'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1008786629149528709/posts/default/1574090916474584055'/><link rel='alternate' type='text/html' href='http://taooferlang.blogspot.com/2009/01/tls-10-in-erlang-no-openssl.html' title='TLS 1.0 in Erlang, no OpenSSL'/><author><name>Maxim Kharchenko</name><uri>http://www.blogger.com/profile/14817460239103044233</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://bp0.blogger.com/_q0h9e6rTTO0/SIeAdGxPxnI/AAAAAAAAAAY/8ePhZVqwvX8/S220/blog_photo.JPG'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1008786629149528709.post-6939355701390022006</id><published>2009-01-18T22:08:00.000-08:00</published><updated>2009-01-23T03:39:38.511-08:00</updated><title type='text'>Actionscript talks Erlang</title><content type='html'>&lt;div style="text-align: justify;"&gt;Continuing the &lt;a href="http://taooferlang.blogspot.com/2008/12/javascript-talks-erlang.html"&gt;discussion &lt;/a&gt;on how to make Erlang more Ajax friendly, I would like to share the format I use for representation of Erlang terms in my Flex/Actionscript-based X Erlang IDE.&lt;br /&gt;The format codenamed as ASON (just like JSON, but for Actionscript) allows representation of every possible Erlang term in Actionscript (again funs are somewhat of a hassle) and is built upon Actonscript's support for inline XML syntax (e4x).&lt;br /&gt;&lt;br /&gt;1. Atoms, numbers and strings encoded similarily&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;&amp;lt;value atom="abc" /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;&amp;lt;value string="def" /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;&amp;lt;value number="123" /&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;1. Lists and tuples use XML nesting&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;&amp;lt;list&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 153);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;&amp;lt;value numbe="1" /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 153);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;&amp;lt;value numbe="2" /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 153);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;&amp;lt;value numbe="3" /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;&amp;lt;/list&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;&amp;lt;list /&gt;&lt;/span&gt;&lt;br /&gt;// []&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;&amp;lt;tuple&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;&amp;lt;value numbe="1" /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;&amp;lt;value numbe="2" /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;&amp;lt;value numbe="3" /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;&amp;lt;/tuple&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;3. Binaries use XML text entity&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;&amp;lt;binary&gt;010203ff&amp;lt;/binary&gt;&lt;/span&gt;&lt;br /&gt;// means &lt;&lt;1,2,3,255&gt;&gt;&lt;br /&gt;&lt;br /&gt;4. Pids, ports and references are alikes&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;&amp;lt;pid node="local" serial="1" creation="0" /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;&amp;lt;port node="local" serial="1" creation="0" /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;&amp;lt;ref node="local" serial="1" creation="0" /&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Now, I can call an Erlang function from Actionscript like this:&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;Erlang.apply("lists:nth", &amp;lt;list&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;&amp;lt;value number="2" /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;  &amp;lt;list&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;&amp;lt;value atom="a" /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;&amp;lt;value atom="b" /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;&amp;lt;value atom="c" /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;&amp;lt;/list&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;&amp;lt;/list&gt;, onResult);&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;function onResult(success:Number, result:XML):void&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;  Alert.show("lists:nth(2, [a,b,c]) returns "+result.@atom+".");&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 153);"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Of course, there are easier ways to retrieve the second element of the list in Actionscript.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1008786629149528709-6939355701390022006?l=taooferlang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://taooferlang.blogspot.com/feeds/6939355701390022006/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1008786629149528709&amp;postID=6939355701390022006' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1008786629149528709/posts/default/6939355701390022006'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1008786629149528709/posts/default/6939355701390022006'/><link rel='alternate' type='text/html' href='http://taooferlang.blogspot.com/2009/01/continuing-discussion-on-how-to-make.html' title='Actionscript talks Erlang'/><author><name>Maxim Kharchenko</name><uri>http://www.blogger.com/profile/14817460239103044233</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://bp0.blogger.com/_q0h9e6rTTO0/SIeAdGxPxnI/AAAAAAAAAAY/8ePhZVqwvX8/S220/blog_photo.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1008786629149528709.post-3193606750443867515</id><published>2009-01-18T21:27:00.000-08:00</published><updated>2009-01-18T22:06:26.756-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='flex'/><category scheme='http://www.blogger.com/atom/ns#' term='IDE'/><category scheme='http://www.blogger.com/atom/ns#' term='actioscript'/><category scheme='http://www.blogger.com/atom/ns#' term='erlang'/><category scheme='http://www.blogger.com/atom/ns#' term='dojo'/><title type='text'>Moved to Flex/Actionscript</title><content type='html'>&lt;div style="text-align: justify;"&gt;Why it was never mentioned that &lt;a href="http://www.dojotoolkit.org/"&gt;dojo toolkit&lt;/a&gt; is reimplementation of Flex framework? It would probably saved me many months of poking in dark corners of Javascript with mediocre &lt;a href="http://taooferlang.blogspot.com/2008/11/web-based-ide-for-x-erlang.html"&gt;results&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Today, one month after the 'discovery' my X Erlang IDE has a syntax highlighting editor,  a build system, a process viewer, an Erlang console, etc running in Flash Player:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_q0h9e6rTTO0/SXQUjSqmLbI/AAAAAAAAABQ/NVsTEQFEFaA/s1600-h/xide2.png"&gt;&lt;img style="cursor: pointer; width: 400px; height: 292px;" src="http://2.bp.blogspot.com/_q0h9e6rTTO0/SXQUjSqmLbI/AAAAAAAAABQ/NVsTEQFEFaA/s400/xide2.png" alt="" id="BLOGGER_PHOTO_ID_5292878058605653426" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;What I am still missing sorely is function call completion. The exact positioning of a small floating window near the cursor is nearly impossible to implement reliably in Javascript. Flex/Actionscript does this and many other things elegantly,  is identical in all browsers and is present in 90% of computers around the globe.&lt;br /&gt;&lt;br /&gt;I have to mention that it is not possible to process right mouse button click with Flex/Actionscript. There is always, they say, something.&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/1008786629149528709-3193606750443867515?l=taooferlang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://taooferlang.blogspot.com/feeds/3193606750443867515/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1008786629149528709&amp;postID=3193606750443867515' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1008786629149528709/posts/default/3193606750443867515'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1008786629149528709/posts/default/3193606750443867515'/><link rel='alternate' type='text/html' href='http://taooferlang.blogspot.com/2009/01/moved-to-flexactionscript.html' title='Moved to Flex/Actionscript'/><author><name>Maxim Kharchenko</name><uri>http://www.blogger.com/profile/14817460239103044233</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://bp0.blogger.com/_q0h9e6rTTO0/SIeAdGxPxnI/AAAAAAAAAAY/8ePhZVqwvX8/S220/blog_photo.JPG'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_q0h9e6rTTO0/SXQUjSqmLbI/AAAAAAAAABQ/NVsTEQFEFaA/s72-c/xide2.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1008786629149528709.post-7224300213937239472</id><published>2008-12-11T08:14:00.000-08:00</published><updated>2008-12-11T08:58:44.696-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='erlang'/><category scheme='http://www.blogger.com/atom/ns#' term='json'/><category scheme='http://www.blogger.com/atom/ns#' term='dojo'/><title type='text'>Javascript talks Erlang</title><content type='html'>When extending my web-based IDE for X Erlang I stumbled on the fact that I am doing much the same thing over and over again adding a small snippets of code on the server and corresponding integration-only additions to Javascript on the client. Many times the obtained result would be an Erlang term represented by opaque string for the user (me) not the software to understand and interpret.&lt;div&gt;&lt;br /&gt;&lt;div&gt;The next big step was standardizing the way Javascript (JSON) objects are generated from a subset of possible Erlang terms. For instance, [{name:"Judas"}, {occupation:"priest"}] would be converted to { name: 'Judas', occupation: 'priest' } on the Javascript side. So far so good, but the encoding scheme would work only in one direction - from Erlang-based server to the web browser.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The enligtment came later when I recognized that it is not at all necessary to add a new server stub for each request the web application may want to send. The web application may just call Erlang functions directly by their names, provide properly-encoded parameters and expect results as JSON messages. The question was the two-way encoding between Erlang terms and JSON objects. Here comes the scheme:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;1. Erlang strings, including empty string "", are represented by Javascript strings&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 204, 204);"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 204, 204);"&gt;""&lt;/span&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 204, 204);"&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 204, 204);"&gt;-&gt;&lt;/span&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 204, 204);"&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 204, 204);"&gt;""&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 204, 204);"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 204, 204);"&gt;abc"&lt;/span&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 204, 204);"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 204, 204);"&gt;-&gt;&lt;/span&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 204, 204);"&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 204, 204);"&gt;"abc"&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;2. Atom 'true' and 'false' become Javascript boolean values&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 204, 204);"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 204, 204);"&gt;'true'&lt;/span&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 204, 204);"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 204, 204);"&gt;-&gt;&lt;/span&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 204, 204);"&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 204, 204);"&gt;true&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 204, 204);"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 204, 204);"&gt;'false'&lt;/span&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 204, 204);"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 204, 204);"&gt;-&gt;&lt;/span&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 204, 204);"&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 204, 204);"&gt;false&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;3. Numbers are just numbers&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 204, 204);"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 204, 204);"&gt;123&lt;/span&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 204, 204);"&gt;  &lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 204, 204);"&gt;-&gt;&lt;/span&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 204, 204);"&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 204, 204);"&gt;123&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 204, 204);"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 204, 204);"&gt;123.5&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 204, 204);"&gt;-&gt;&lt;/span&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 204, 204);"&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 204, 204);"&gt;123.5&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;4. Erlang atoms become objects with a single property "atom"&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 204, 204);"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 204, 204);"&gt;'abc'&lt;/span&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 204, 204);"&gt;   &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 204, 204);"&gt;-&gt;&lt;/span&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 204, 204);"&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 204, 204);"&gt;{atom: "abc"}&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;5. Erlang binaries become similar objects with a single property, this time named "binary"&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 204, 204);"&gt;&lt;&lt;1,2,255&gt;&gt;&lt;/span&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 204, 204);"&gt; &lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 204, 204);"&gt;-&gt;&lt;/span&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 204, 204);"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 204, 204);"&gt;{binary: "0102ff"}&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;Binary data is encoded into string, each byte represented by two hex digits&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;(more compact representations can be imagined)&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;6. PIDs, References and Ports are encoded as objects too&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 204, 204);"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 204, 204);"&gt;#Ref&lt;1.2.3&gt;&lt;/span&gt;&lt;span class="Apple-tab-span" style="white-space: pre; "&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 204, 204);"&gt;   &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 204, 204);"&gt;-&gt;&lt;/span&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 204, 204);"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 204, 204);"&gt;{reference: 2, node: 1, creation: 3}&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 204, 204);"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 204, 204);"&gt;#Port&lt;1.2.3&gt;&lt;/span&gt;&lt;span class="Apple-tab-span" style="white-space: pre; "&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 204, 204);"&gt;   &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 204, 204);"&gt;-&gt;&lt;/span&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 204, 204);"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 204, 204);"&gt;{port: 2, node: 1, creation: 3}&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 204, 204);"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 204, 204);"&gt;&lt;1.2.3&gt;&lt;/span&gt;&lt;span class="Apple-tab-span" style="white-space: pre; "&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 204, 204);"&gt;     &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 204, 204);"&gt;-&gt;&lt;/span&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 204, 204);"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 204, 204);"&gt;{pid: 2, node: 1, creation: 3}&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;7. Tuples become objects with integer field names&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 204, 204);"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 204, 204);"&gt;{T1,T2,T3}&lt;/span&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 204, 204);"&gt;  &lt;span class="Apple-tab-span" style="white-space:pre"&gt;  &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 204, 204);"&gt;-&gt;&lt;/span&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 204, 204);"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 204, 204);"&gt;{1: T1, 2: T2, 3: T3}&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;8. Lists (which happened not to be strings) are the easiest&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 204, 204);"&gt;[T1,T2,T3]&lt;/span&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 204, 204);"&gt;   &lt;span class="Apple-tab-span" style="white-space:pre"&gt;  &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="color: rgb(0, 204, 204);"&gt;-&gt; [T1, T2, T3]&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The described encoding allows to represent any Erlang term as a Javascript value (but not vice-versa). The small open is funs. Today, they are encoded as {fun: name} but this representation is not reversible. Besides it dificult to understand how to reconstract fun object in Erlang (binary_to_term()?).&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The additional sugar to the above scheme is record descriptions. For known records, the representation of tuples could be made simpler and more manageable. For instance, the record 'req' is known to have 'module', 'function' and 'args' fields. Then, the Erlang tuple {req,Mod,Fun,Args} is represented by more concise Javascript object with explicit field names: {record: "req", module: Mod, function: Fun, args: Args}. Record description work both ways, during encoding and decoding.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The implementation of the described representation allowed my dojo-based web client to call Erlang functions on the server and pass complex structures back and forth with little or no hassle.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Now, the Erlang console which evaluated expressions using erl_parse and erl_eval stores the resulting bindings on the client as Javascript objects and passes them to subsequent calls as a context not heeding their alien nature.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1008786629149528709-7224300213937239472?l=taooferlang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://taooferlang.blogspot.com/feeds/7224300213937239472/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1008786629149528709&amp;postID=7224300213937239472' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1008786629149528709/posts/default/7224300213937239472'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1008786629149528709/posts/default/7224300213937239472'/><link rel='alternate' type='text/html' href='http://taooferlang.blogspot.com/2008/12/javascript-talks-erlang.html' title='Javascript talks Erlang'/><author><name>Maxim Kharchenko</name><uri>http://www.blogger.com/profile/14817460239103044233</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://bp0.blogger.com/_q0h9e6rTTO0/SIeAdGxPxnI/AAAAAAAAAAY/8ePhZVqwvX8/S220/blog_photo.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1008786629149528709.post-5017332514473388780</id><published>2008-11-13T01:43:00.000-08:00</published><updated>2008-11-13T02:16:46.918-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='IDE'/><category scheme='http://www.blogger.com/atom/ns#' term='filesystem'/><category scheme='http://www.blogger.com/atom/ns#' term='erlang'/><title type='text'>Web-based IDE for X Erlang</title><content type='html'>In one of my previous &lt;a href="http://taooferlang.blogspot.com/2008/07/x-erlang-shell-application.html"&gt;posts&lt;/a&gt; I described a console application that allows the user to interact with X Erlang instance. As the logical next step I wanted to make it more a 'Visual Studio' than a 'DOS prompt'.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;After two months of petty bickering I finally settled to use &lt;a href="http://www.dojotoolkit.org/"&gt;dojo&lt;/a&gt; for portability among browsers and ready-to-go widget goodies. Currently, the application allows management of the in-memory filesystem, editing of Erlang code using CodeMirror control and compilation of the code. It even jumps to the correct line in the source &lt;/div&gt;&lt;div&gt;code when the error message is clicked in the compiler output pane!&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The progress is stalled by the capabilities of the X Erlang itself. Now it is not possible to 'pause' a process to observe its internals.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The current version looks like this:&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;img src="http://3.bp.blogspot.com/_q0h9e6rTTO0/SRv-UjrT4SI/AAAAAAAAABI/IrikCaqmI8s/s400/mite3.png" style="cursor:pointer; cursor:hand;width: 400px; height: 293px;" border="0" alt="" id="BLOGGER_PHOTO_ID_5268083818267664674" /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1008786629149528709-5017332514473388780?l=taooferlang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://taooferlang.blogspot.com/feeds/5017332514473388780/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1008786629149528709&amp;postID=5017332514473388780' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1008786629149528709/posts/default/5017332514473388780'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1008786629149528709/posts/default/5017332514473388780'/><link rel='alternate' type='text/html' href='http://taooferlang.blogspot.com/2008/11/web-based-ide-for-x-erlang.html' title='Web-based IDE for X Erlang'/><author><name>Maxim Kharchenko</name><uri>http://www.blogger.com/profile/14817460239103044233</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://bp0.blogger.com/_q0h9e6rTTO0/SIeAdGxPxnI/AAAAAAAAAAY/8ePhZVqwvX8/S220/blog_photo.JPG'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_q0h9e6rTTO0/SRv-UjrT4SI/AAAAAAAAABI/IrikCaqmI8s/s72-c/mite3.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1008786629149528709.post-1461253684986321409</id><published>2008-07-23T12:29:00.000-07:00</published><updated>2008-07-23T12:57:35.478-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='webserver'/><category scheme='http://www.blogger.com/atom/ns#' term='erlang'/><category scheme='http://www.blogger.com/atom/ns#' term='shell'/><title type='text'>X Erlang shell application</title><content type='html'>To demonstrate X Erlang system I quickly put together a simple web server which serves static files and runs scripts. On top of it I implemented a simple shell application which allows to enter and evaluate arbitrary Erlang expressions from a web browser window. First I put the system running on an Amazon EC2 server but then I put it down after all my friend had a look at how it works.&lt;br /&gt;&lt;br /&gt;The typical shell session looks like this:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;X Erlang v0.2 is here, type '?' for help&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;&lt;span style="color:#3366ff;"&gt;&gt; test:primes(100).&lt;br /&gt;&lt;/span&gt;[2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73, 79,83,89,97]&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;&lt;span style="color:#3366ff;"&gt;&gt; [{X,Y} X &lt;- test:primes(100), Y &lt;- test:primes(100), Y =:= X+2].&lt;br /&gt;&lt;/span&gt;[{3,5}, {5,7}, {11,13}, {17,19}, {29,31}, {41,43}, {59,61}, {71,73}]&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;&lt;span style="color:#3366ff;"&gt;&gt; code:all_loaded().&lt;/span&gt;&lt;br /&gt;[lists,test,dict,orddict,queue,sets,erl_parse,regexp,gen_tcp,inet,io_lib_format,erl_lint,dashboard,stdio,gb_sets, io_lib,erlang,io,packages,io_lib_pretty,prim_erlang,code,erl_eval,string,init,erl_internal,files,ordsets,efile, erl_scan,spur,error_handler,x_internal]&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;$_&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The blue characters are entered by the user, the rest is the output of the system. The first&lt;br /&gt;request is to calculate a few prime numbers. Every programming language is demonstrated using prime number routine. Why should I be different? The second request is trickier. The entered expression finds all 'twin primes' less than 100. As you noticed X Erlang supports list comprehensions (but not yet binary comprehensions). The last expression is a maintenance job. It shows which modules are loaded.&lt;br /&gt;&lt;br /&gt;Nothing to fancy but it works. It took me a day or two to program a robust shell application on top of a web server. It may take even less for other programmers using other versions of Erlang.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1008786629149528709-1461253684986321409?l=taooferlang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://taooferlang.blogspot.com/feeds/1461253684986321409/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1008786629149528709&amp;postID=1461253684986321409' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1008786629149528709/posts/default/1461253684986321409'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1008786629149528709/posts/default/1461253684986321409'/><link rel='alternate' type='text/html' href='http://taooferlang.blogspot.com/2008/07/x-erlang-shell-application.html' title='X Erlang shell application'/><author><name>Maxim Kharchenko</name><uri>http://www.blogger.com/profile/14817460239103044233</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://bp0.blogger.com/_q0h9e6rTTO0/SIeAdGxPxnI/AAAAAAAAAAY/8ePhZVqwvX8/S220/blog_photo.JPG'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1008786629149528709.post-424969933342666967</id><published>2008-07-23T11:41:00.000-07:00</published><updated>2008-07-23T12:28:53.106-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='filesystem'/><category scheme='http://www.blogger.com/atom/ns#' term='erlang'/><title type='text'>X Erlang as a userland OS</title><content type='html'>Erlang system has many features of an operating system. The most obvious is processes, the more subtle is modules.&lt;br /&gt;&lt;br /&gt;X Erlang takes a few steps further to the autonomous userland OS than OTP does. In X Erlang the operating system is never searched when the system needs to load a module. Two dozens of modules are 'embedded' into the X Erlang executable. There is also an internal storage for module images. These images may be loaded on request. If the referenced module is not embedded and it is not found in the internal storage then {undef,...} is thrown. The file system of the underlying OS is never touched in the process.&lt;br /&gt;&lt;br /&gt;To calm down the readers I need to ascertain them that there is a file system in X Erlang. It is internal and in-memory, simplistic, yet hierarchical. In X Erlang file:write_file("temp1.txt", &lt;&lt;1,2,3&gt;&gt;) creates an in-memory 'file' (or rather a named binary). The external file system of the underlying OS is still accessible though 'efile' interface. Compiler works on files and emits output files to the internal file system only.&lt;br /&gt;&lt;br /&gt;In X Erlang you need exactly one executable file copied to a freshly installed operating system to launch your application. No runtime, no libraries, a single file typically of less than 2 MB size.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1008786629149528709-424969933342666967?l=taooferlang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://taooferlang.blogspot.com/feeds/424969933342666967/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1008786629149528709&amp;postID=424969933342666967' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1008786629149528709/posts/default/424969933342666967'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1008786629149528709/posts/default/424969933342666967'/><link rel='alternate' type='text/html' href='http://taooferlang.blogspot.com/2008/07/x-erlang-as-userland-os.html' title='X Erlang as a userland OS'/><author><name>Maxim Kharchenko</name><uri>http://www.blogger.com/profile/14817460239103044233</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://bp0.blogger.com/_q0h9e6rTTO0/SIeAdGxPxnI/AAAAAAAAAAY/8ePhZVqwvX8/S220/blog_photo.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1008786629149528709.post-2225270893266989537</id><published>2008-07-22T10:06:00.000-07:00</published><updated>2008-07-22T12:25:04.822-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='erlang'/><category scheme='http://www.blogger.com/atom/ns#' term='memory'/><category scheme='http://www.blogger.com/atom/ns#' term='apr'/><title type='text'>APR means tough life for garbage collector</title><content type='html'>X &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;Erlang&lt;/span&gt; is designed to be as portable as possible and a few things would have been done differently, probably, improving performance along the way. I decided not to do this and stick to the original rule. When it comes to memory management the rule is this: use memory pools provided by APR (&lt;a href="http://apr.apache.org/"&gt;Apache Portable &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;Runtime&lt;/span&gt;&lt;/a&gt;) only.&lt;br /&gt;&lt;br /&gt;If you played with APR than you should be aware that the library uses a specific memory model which makes a lot of sense to the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;web server&lt;/span&gt; environment. Most of the time it prevents memory leaks. Memory is allocated extremely fast from "memory pools". Internally the allocation is just incrementing a a free memory pointer. However, freeing up memory is not that easy. It can be done by destroying the whole memory pool at once.&lt;br /&gt;&lt;br /&gt;So far so good. Following the rule X &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;Erlang&lt;/span&gt; creates an APR memory pool per process and quickly allocates the values from it. When it comes to garbage collection reachable values are copied to a a new pool and the original pool is destroyed. It means that, yes, X &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;Erlang&lt;/span&gt; uses stop-the-world garbage collection and &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_5"&gt;VM&lt;/span&gt; is stalled until all garbage is collected for the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_6"&gt;overgrown&lt;/span&gt; process.&lt;br /&gt;&lt;br /&gt;There are two points to watch here.&lt;br /&gt;&lt;br /&gt;The first is that in many cases variables reference the same locations in memory in X Erlang. If values are immutable there is no reason to copy them around. Thus during garbage collection we should discern the values which were already copied to the new pool. This would have been easy if APR had a way to say that a given pointer was allocated from a given pool. Unfortunately, this can not be done in APR. The approach adopted by X &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_7"&gt;Erlang&lt;/span&gt; is to substitute the value in the current pool with a special structure (I call it a 'grave') with a special tag (a 'cross') and a 'buried' pointer to the copy of value in the new pool. The 'grave' structure occupies 4 bytes and the whole scheme works because all referenced values are at least 4 bytes long. In addition, APR by default aligns allocated memory on 8&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_8"&gt;th&lt;/span&gt; boundary but this behavior can be changed.&lt;br /&gt;&lt;br /&gt;The second is that is not easy to determine the 'size' of a memory pool. There is just no function for this. Technically, there is such a function in a debug version of the library but it determines the size of the pool by scanning it element by element - no use for the high-performance virtual machine :-). Thus X &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_9"&gt;Erlang&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_10"&gt;VM&lt;/span&gt; has to add up sizes of all allocations to keep track of the size of the current memory pool. It is ugly but there seems no other way around.&lt;br /&gt;&lt;br /&gt;The garbage collection may not recover any memory at all. The size of the new pool may well be larger than the current one. This happens quite often in X &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_11"&gt;Erlang&lt;/span&gt; (and &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_12"&gt;OTP&lt;/span&gt; too?) and results in immediate termination of the process grown out of proportion.&lt;br /&gt;&lt;br /&gt;There is also a lot to be said about handling literal values but it will be a subject matter of another post.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1008786629149528709-2225270893266989537?l=taooferlang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://taooferlang.blogspot.com/feeds/2225270893266989537/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1008786629149528709&amp;postID=2225270893266989537' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1008786629149528709/posts/default/2225270893266989537'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1008786629149528709/posts/default/2225270893266989537'/><link rel='alternate' type='text/html' href='http://taooferlang.blogspot.com/2008/07/apr-means-tough-life-for-garbage.html' title='APR means tough life for garbage collector'/><author><name>Maxim Kharchenko</name><uri>http://www.blogger.com/profile/14817460239103044233</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://bp0.blogger.com/_q0h9e6rTTO0/SIeAdGxPxnI/AAAAAAAAAAY/8ePhZVqwvX8/S220/blog_photo.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1008786629149528709.post-6275665044978206175</id><published>2008-07-21T23:23:00.000-07:00</published><updated>2008-07-22T12:22:22.905-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='erlang'/><title type='text'>Erlang reimplemented</title><content type='html'>For several years I was tinkering with various tools and languages trying to find the best mix for the software I was interested in (peer-to-peer). Many times such quest ends up with a desire to write your own programming language. The resultant ugly duckling was a strange cross between C and IDL. And it was a dead end.&lt;br /&gt;&lt;br /&gt;The light at the end of tunnel was Joe Armstrong's paper describing exactly the problems I was fighting with and his elegant solution - Erlang. I started to learn the language by taking the wrong path again - by reimplementing it.&lt;br /&gt;&lt;br /&gt;A handful of major versions and a year and a half later to my surprise I created a usable Erlang-based system. It starts, it runs, it even compiles itself.&lt;br /&gt;&lt;br /&gt;The implementation is based on a simple stack-based virtual machine and, most probably, suboptimal especially when compared to OTP. But it is very portable and it is small. I call it X Erlang.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1008786629149528709-6275665044978206175?l=taooferlang.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://taooferlang.blogspot.com/feeds/6275665044978206175/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1008786629149528709&amp;postID=6275665044978206175' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1008786629149528709/posts/default/6275665044978206175'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1008786629149528709/posts/default/6275665044978206175'/><link rel='alternate' type='text/html' href='http://taooferlang.blogspot.com/2008/07/erlang-reimplemented.html' title='Erlang reimplemented'/><author><name>Maxim Kharchenko</name><uri>http://www.blogger.com/profile/14817460239103044233</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://bp0.blogger.com/_q0h9e6rTTO0/SIeAdGxPxnI/AAAAAAAAAAY/8ePhZVqwvX8/S220/blog_photo.JPG'/></author><thr:total>0</thr:total></entry></feed>
